22 #include "llvm/ADT/Optional.h" 23 #include "llvm/ADT/StringRef.h" 24 #include "llvm/Support/Casting.h" 25 #include "llvm/Support/Compiler.h" 26 #include "llvm/Support/raw_ostream.h" 30 using namespace clang;
33 : Location(DefLoc), IsDefinitionLengthCached(
false), IsFunctionLike(
false),
36 IsAllowRedefinitionsWithoutWarning(
false), IsWarnIfUnused(
false),
37 UsedForHeaderGuard(
false) {}
39 unsigned MacroInfo::getDefinitionLengthSlow(
const SourceManager &
SM)
const {
40 assert(!IsDefinitionLengthCached);
41 IsDefinitionLengthCached =
true;
43 if (ReplacementTokens.empty())
44 return (DefinitionLength = 0);
46 const Token &firstToken = ReplacementTokens.front();
47 const Token &lastToken = ReplacementTokens.back();
51 assert((macroStart.
isFileID() || firstToken.
is(tok::comment)) &&
52 "Macro defined in macro?");
53 assert((macroEnd.
isFileID() || lastToken.
is(tok::comment)) &&
54 "Macro defined in macro?");
55 std::pair<FileID, unsigned>
57 std::pair<FileID, unsigned>
59 assert(startInfo.first == endInfo.first &&
60 "Macro definition spanning multiple FileIDs ?");
61 assert(startInfo.second <= endInfo.second);
62 DefinitionLength = endInfo.second - startInfo.second;
63 DefinitionLength += lastToken.
getLength();
65 return DefinitionLength;
76 bool Syntactically)
const {
77 bool Lexically = !Syntactically;
80 if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
92 if (*I != *OI)
return false;
96 for (
unsigned i = 0, e = ReplacementTokens.size(); i != e; ++i) {
97 const Token &A = ReplacementTokens[i];
98 const Token &B = Other.ReplacementTokens[i];
134 llvm::raw_ostream &Out = llvm::errs();
137 Out <<
"MacroInfo " <<
this;
138 if (IsBuiltinMacro) Out <<
" builtin";
139 if (IsDisabled) Out <<
" disabled";
140 if (IsUsed) Out <<
" used";
141 if (IsAllowRedefinitionsWithoutWarning)
142 Out <<
" allow_redefinitions_without_warning";
143 if (IsWarnIfUnused) Out <<
" warn_if_unused";
144 if (UsedForHeaderGuard) Out <<
" header_guard";
146 Out <<
"\n #define <macro>";
147 if (IsFunctionLike) {
149 for (
unsigned I = 0; I != NumParameters; ++I) {
151 Out << ParameterList[I]->getName();
153 if (IsC99Varargs || IsGNUVarargs) {
154 if (NumParameters && IsC99Varargs) Out <<
", ";
161 for (
const Token &
Tok : ReplacementTokens) {
164 if (First ||
Tok.hasLeadingSpace())
170 else if (
Tok.isLiteral() &&
Tok.getLiteralData())
171 Out << StringRef(
Tok.getLiteralData(),
Tok.getLength());
172 else if (
auto *II =
Tok.getIdentifierInfo())
173 Out << II->getName();
175 Out <<
Tok.getName();
185 return DefInfo(DefMD, UndefLoc,
186 !isPublic.hasValue() || isPublic.getValue());
189 UndefLoc = UndefMD->getLocation();
194 if (!isPublic.hasValue())
198 return DefInfo(
nullptr, UndefLoc,
199 !isPublic.hasValue() || isPublic.getValue());
204 assert(L.
isValid() &&
"SourceLocation is invalid.");
206 if (Def.getLocation().isInvalid() ||
208 return (!Def.isUndefined() ||
216 llvm::raw_ostream &Out = llvm::errs();
219 case MD_Define: Out <<
"DefMacroDirective";
break;
220 case MD_Undefine: Out <<
"UndefMacroDirective";
break;
221 case MD_Visibility: Out <<
"VisibilityMacroDirective";
break;
225 if (
auto *Prev = getPrevious())
226 Out <<
" prev " << Prev;
227 if (IsFromPCH) Out <<
" from_pch";
229 if (isa<VisibilityMacroDirective>(
this))
230 Out << (IsPublic ?
" public" :
" private");
232 if (
auto *DMD = dyn_cast<DefMacroDirective>(
this)) {
233 if (
auto *Info = DMD->getInfo()) {
247 return new (Mem)
ModuleMacro(OwningModule, II, Macro, Overrides);
llvm::BumpPtrAllocator & getPreprocessorAllocator()
param_iterator param_begin() const
static ClassTemplateDecl * getDefinition(ClassTemplateDecl *D)
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)) {...
Defines the SourceManager interface.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
Defines the clang::MacroInfo and clang::MacroDirective classes.
A directive for an undefined macro.
const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const
Find macro definition active in the specified source location.
const MacroDirective * getPrevious() const
Get previous definition of the macro with the same name.
tok::TokenKind getKind() const
One of these records is kept for each identifier that is lexed.
Represents a macro directive exported by a module.
A directive for a defined macro or a macro imported from a module.
Token - This structure provides full information about a lexed token.
Describes a module or submodule.
A directive for setting the module visibility of a macro.
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
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 ...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
IdentifierInfo *const * param_iterator
Parameters - The list of parameters for a function-like macro.
bool isPublic() const
Determine whether this macro is part of the public API of its module.
unsigned getNumParams() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines the clang::Preprocessor interface.
DefInfo getDefinition()
Traverses the macro directives history and returns the next macro definition directive along with inf...
const char * getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple punctuation tokens like '!' or '', and returns NULL for literal and...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Encodes a location in the source.
IdentifierInfo * getIdentifierInfo() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isC99Varargs() const
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isFunctionLike() const
unsigned getLength() const
Encapsulates the data about a macro definition (e.g.
static ModuleMacro * create(Preprocessor &PP, Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro *> Overrides)
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
Defines the clang::TokenKind enum and support functions.
Defines the clang::SourceLocation class and associated facilities.
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 isGNUVarargs() const
static Decl::Kind getKind(const Decl *D)
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
This class handles loading and caching of source files into memory.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.