clang: lib/Lex/MacroInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

21#include "llvm/Support/Compiler.h"

22#include "llvm/Support/raw_ostream.h"

23#include

24#include

25#include

26

27using namespace clang;

28

29namespace {

30

31

32

33template <int> class MacroInfoSizeChecker {

34public:

35 [[maybe_unused]] constexpr static bool AsExpected = true;

36};

37template <> class MacroInfoSizeChecker<8> {

38public:

39 [[maybe_unused]] constexpr static bool AsExpected =

41};

42

43static_assert(MacroInfoSizeChecker<sizeof(void *)>::AsExpected,

44 "Unexpected size of MacroInfo");

45

46}

47

49 : Location(DefLoc), IsDefinitionLengthCached(false), IsFunctionLike(false),

50 IsC99Varargs(false), IsGNUVarargs(false), IsBuiltinMacro(false),

52 IsAllowRedefinitionsWithoutWarning(false), IsWarnIfUnused(false),

53 UsedForHeaderGuard(false) {}

54

55unsigned MacroInfo::getDefinitionLengthSlow(const SourceManager &SM) const {

56 assert(!IsDefinitionLengthCached);

57 IsDefinitionLengthCached = true;

58

60 if (ReplacementTokens.empty())

61 return (DefinitionLength = 0);

62

63 const Token &firstToken = ReplacementTokens.front();

64 const Token &lastToken = ReplacementTokens.back();

68 assert((macroStart.isFileID() || firstToken.is(tok::comment)) &&

69 "Macro defined in macro?");

70 assert((macroEnd.isFileID() || lastToken.is(tok::comment)) &&

71 "Macro defined in macro?");

72 std::pair<FileID, unsigned>

73 startInfo = SM.getDecomposedExpansionLoc(macroStart);

74 std::pair<FileID, unsigned>

75 endInfo = SM.getDecomposedExpansionLoc(macroEnd);

76 assert(startInfo.first == endInfo.first &&

77 "Macro definition spanning multiple FileIDs ?");

78 assert(startInfo.second <= endInfo.second);

79 DefinitionLength = endInfo.second - startInfo.second;

80 DefinitionLength += lastToken.getLength();

81

82 return DefinitionLength;

83}

84

85

86

87

88

89

90

91

93 bool Syntactically) const {

94 bool Lexically = !Syntactically;

95

96

102 return false;

103

104 if (Lexically) {

105

108 I != E; ++I, ++OI)

109 if (*I != *OI) return false;

110 }

111

112

113 for (unsigned i = 0; i != NumReplacementTokens; ++i) {

114 const Token &A = ReplacementTokens[i];

115 const Token &B = Other.ReplacementTokens[i];

117 return false;

118

119

120

121 if (i != 0 &&

124 return false;

125

126

129 continue;

130 if (Lexically)

131 return false;

132

133

135 if (AArgNum == -1)

136 return false;

138 return false;

139 continue;

140 }

141

142

144 return false;

145 }

146

147 return true;

148}

149

151 llvm::raw_ostream &Out = llvm::errs();

152

153

154 Out << "MacroInfo " << this;

155 if (IsBuiltinMacro) Out << " builtin";

156 if (IsDisabled) Out << " disabled";

157 if (IsUsed) Out << " used";

158 if (IsAllowRedefinitionsWithoutWarning)

159 Out << " allow_redefinitions_without_warning";

160 if (IsWarnIfUnused) Out << " warn_if_unused";

161 if (UsedForHeaderGuard) Out << " header_guard";

162

163 Out << "\n #define ";

164 if (IsFunctionLike) {

165 Out << "(";

166 for (unsigned I = 0; I != NumParameters; ++I) {

167 if (I) Out << ", ";

168 Out << ParameterList[I]->getName();

169 }

170 if (IsC99Varargs || IsGNUVarargs) {

171 if (NumParameters && IsC99Varargs) Out << ", ";

172 Out << "...";

173 }

174 Out << ")";

175 }

176

177 bool First = true;

179

180

181 if (First || Tok.hasLeadingSpace())

182 Out << " ";

184

186 Out << Punc;

187 else if (Tok.isLiteral() && Tok.getLiteralData())

188 Out << StringRef(Tok.getLiteralData(), Tok.getLength());

189 else if (auto *II = Tok.getIdentifierInfo())

190 Out << II->getName();

191 else

192 Out << Tok.getName();

193 }

194}

195

199 std::optional isPublic;

202 return DefInfo(DefMD, UndefLoc, !isPublic || *isPublic);

203

205 UndefLoc = UndefMD->getLocation();

206 continue;

207 }

208

210 if (!isPublic)

211 isPublic = VisMD->isPublic();

212 }

213

214 return DefInfo(nullptr, UndefLoc, !isPublic || *isPublic);

215}

216

220 assert(L.isValid() && "SourceLocation is invalid.");

222 if (Def.getLocation().isInvalid() ||

223 SM.isBeforeInTranslationUnit(Def.getLocation(), L))

224 return (!Def.isUndefined() ||

225 SM.isBeforeInTranslationUnit(L, Def.getUndefLocation()))

227 }

229}

230

232 llvm::raw_ostream &Out = llvm::errs();

233

235 case MD_Define: Out << "DefMacroDirective"; break;

236 case MD_Undefine: Out << "UndefMacroDirective"; break;

237 case MD_Visibility: Out << "VisibilityMacroDirective"; break;

238 }

239 Out << " " << this;

240

242 Out << " prev " << Prev;

243 if (IsFromPCH) Out << " from_pch";

244

245 if (isa(this))

246 Out << (IsPublic ? " public" : " private");

247

248 if (auto *DMD = dyn_cast(this)) {

249 if (auto *Info = DMD->getInfo()) {

250 Out << "\n ";

251 Info->dump();

252 }

253 }

254 Out << "\n";

255}

256

263 return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides);

264}

Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::MacroInfo and clang::MacroDirective classes.

Defines the clang::Preprocessor interface.

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

Defines the clang::TokenKind enum and support functions.

A directive for a defined macro or a macro imported from a module.

One of these records is kept for each identifier that is lexed.

StringRef getName() const

Return the actual identifier string.

DefInfo getPreviousDefinition()

Encapsulates changes to the "macros namespace" (the location where the macro name became active,...

const MacroDirective * getPrevious() const

Get previous definition of the macro with the same name.

const DefInfo findDirectiveAtLoc(SourceLocation L, const SourceManager &SM) const

Find macro definition active in the specified source location.

unsigned IsPublic

Whether the macro has public visibility (when described in a module).

unsigned IsFromPCH

True if the macro directive was loaded from a PCH file.

DefInfo getDefinition()

Traverses the macro directives history and returns the next macro definition directive along with inf...

Encapsulates the data about a macro definition (e.g.

bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const

Return true if the specified macro definition is equal to this macro in spelling, arguments,...

bool isC99Varargs() const

bool isFunctionLike() const

param_iterator param_begin() const

unsigned getNumTokens() const

Return the number of tokens that this macro expands to.

unsigned getNumParams() const

IdentifierInfo *const * param_iterator

Parameters - The list of parameters for a function-like macro.

param_iterator param_end() const

ArrayRef< Token > tokens() const

int getParameterNum(const IdentifierInfo *Arg) const

Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...

bool isGNUVarargs() const

Represents a macro directive exported by a module.

static ModuleMacro * create(Preprocessor &PP, Module *OwningModule, const IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro * > Overrides)

Describes a module or submodule.

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

llvm::BumpPtrAllocator & getPreprocessorAllocator()

StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const

Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

This class handles loading and caching of source files into memory.

Token - This structure provides full information about a lexed token.

IdentifierInfo * getIdentifierInfo() const

SourceLocation getLocation() const

Return a source location identifier for the specified offset in the current file.

unsigned getLength() const

bool is(tok::TokenKind K) const

is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....

tok::TokenKind getKind() const

bool isAtStartOfLine() const

isAtStartOfLine - Return true if this token is at the start of a line.

bool hasLeadingSpace() const

Return true if this token has whitespace before it.

A directive for an undefined macro.

A directive for setting the module visibility of a macro.

bool isPublic() const

Determine whether this macro is part of the public API of its module.

const char * getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE

Determines the spelling of simple punctuation tokens like '!' or '', and returns NULL for literal and...

The JSON file list parser is used to communicate input to InstallAPI.

@ Other

Other implicit parameter.