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

26using namespace clang;

27

28namespace {

29

30

31

32template <int> class MacroInfoSizeChecker {

33public:

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

35};

36template <> class MacroInfoSizeChecker<8> {

37public:

38 [[maybe_unused]] constexpr static bool AsExpected =

39 sizeof(MacroInfo) == (32 + sizeof(SourceLocation) * 2);

40};

41

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

43 "Unexpected size of MacroInfo");

44

45}

46

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

49 IsC99Varargs(false), IsGNUVarargs(false), IsBuiltinMacro(false),

51 IsAllowRedefinitionsWithoutWarning(false), IsWarnIfUnused(false),

52 UsedForHeaderGuard(false) {}

53

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

55 assert(!IsDefinitionLengthCached);

56 IsDefinitionLengthCached = true;

57

58 ArrayRef ReplacementTokens = tokens();

59 if (ReplacementTokens.empty())

60 return (DefinitionLength = 0);

61

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

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

64 SourceLocation macroStart = firstToken.getLocation();

65 SourceLocation macroEnd = lastToken.getLocation();

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

68 "Macro defined in macro?");

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

70 "Macro defined in macro?");

71 FileIDAndOffset startInfo = SM.getDecomposedExpansionLoc(macroStart);

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

74 "Macro definition spanning multiple FileIDs ?");

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

76 DefinitionLength = endInfo.second - startInfo.second;

77 DefinitionLength += lastToken.getLength();

78

79 return DefinitionLength;

80}

81

82

83

84

85

86

87

88

90 bool Syntactically) const {

91 bool Lexically = !Syntactically;

92

93

99 return false;

100

101 if (Lexically) {

102

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

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

107 }

108

109

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

111 const Token &A = ReplacementTokens[i];

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

114 return false;

115

116

117

118 if (i != 0 &&

121 return false;

122

123

126 continue;

127 if (Lexically)

128 return false;

129

130

132 if (AArgNum == -1)

133 return false;

135 return false;

136 continue;

137 }

138

139

141 return false;

142 }

143

144 return true;

145}

146

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

149

150

151 Out << "MacroInfo " << this;

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

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

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

155 if (IsAllowRedefinitionsWithoutWarning)

156 Out << " allow_redefinitions_without_warning";

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

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

159

160 Out << "\n #define ";

161 if (IsFunctionLike) {

162 Out << "(";

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

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

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

166 }

167 if (IsC99Varargs || IsGNUVarargs) {

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

169 Out << "...";

170 }

171 Out << ")";

172 }

173

174 bool First = true;

176

177

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

179 Out << " ";

181

183 Out << Punc;

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

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

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

187 Out << II->getName();

188 else

189 Out << Tok.getName();

190 }

191}

192

196 std::optional isPublic;

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

200

202 UndefLoc = UndefMD->getLocation();

203 continue;

204 }

205

207 if (!isPublic)

208 isPublic = VisMD->isPublic();

209 }

210

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

212}

213

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

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

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

221 return (!Def.isUndefined() ||

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

224 }

226}

227

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

230

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

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

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

235 }

236 Out << " " << this;

237

239 Out << " prev " << Prev;

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

241

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

244

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

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

247 Out << "\n ";

248 Info->dump();

249 }

250 }

251 Out << "\n";

252}

253

258 sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(),

259 alignof(ModuleMacro));

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

261}

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.

DefInfo getPreviousDefinition()

void dump() const

Definition MacroInfo.cpp:228

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.

Definition MacroInfo.cpp:215

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.

MacroDirective(Kind K, SourceLocation Loc)

DefInfo getDefinition()

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

Definition MacroInfo.cpp:193

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

friend class Preprocessor

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,...

Definition MacroInfo.cpp:89

bool isC99Varargs() const

bool isFunctionLike() const

param_iterator param_begin() const

unsigned getNumTokens() const

Return the number of tokens that this macro expands to.

void dump() const

Definition MacroInfo.cpp:147

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

friend class Preprocessor

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

Definition MacroInfo.cpp:254

Describes a module or submodule.

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 '!

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

bool isa(CodeGen::Address addr)

std::pair< FileID, unsigned > FileIDAndOffset

U cast(CodeGen::Address addr)

@ Other

Other implicit parameter.