21#include "llvm/ADT/StringRef.h"
22#include "llvm/Support/Casting.h"
23#include "llvm/Support/Compiler.h"
24#include "llvm/Support/raw_ostream.h"
35template <
int>
class MacroInfoSizeChecker {
37 [[maybe_unused]]
constexpr static bool AsExpected =
true;
39template <>
class MacroInfoSizeChecker<8> {
41 [[maybe_unused]]
constexpr static bool AsExpected =
45static_assert(MacroInfoSizeChecker<
sizeof(
void *)>::AsExpected,
46 "Unexpected size of MacroInfo");
51 : Location(DefLoc), IsDefinitionLengthCached(
false), IsFunctionLike(
false),
54 IsAllowRedefinitionsWithoutWarning(
false), IsWarnIfUnused(
false),
55 UsedForHeaderGuard(
false) {}
57unsigned MacroInfo::getDefinitionLengthSlow(
const SourceManager &
SM)
const {
58 assert(!IsDefinitionLengthCached);
59 IsDefinitionLengthCached =
true;
62 if (ReplacementTokens.empty())
63 return (DefinitionLength = 0);
65 const Token &firstToken = ReplacementTokens.front();
66 const Token &lastToken = ReplacementTokens.back();
70 assert((macroStart.
isFileID() || firstToken.
is(tok::comment)) &&
71 "Macro defined in macro?");
72 assert((macroEnd.
isFileID() || lastToken.
is(tok::comment)) &&
73 "Macro defined in macro?");
74 std::pair<FileID, unsigned>
75 startInfo =
SM.getDecomposedExpansionLoc(macroStart);
76 std::pair<FileID, unsigned>
77 endInfo =
SM.getDecomposedExpansionLoc(macroEnd);
78 assert(startInfo.first == endInfo.first &&
79 "Macro definition spanning multiple FileIDs ?");
80 assert(startInfo.second <= endInfo.second);
81 DefinitionLength = endInfo.second - startInfo.second;
82 DefinitionLength += lastToken.
getLength();
84 return DefinitionLength;
95 bool Syntactically)
const {
96 bool Lexically = !Syntactically;
111 if (*I != *OI)
return false;
115 for (
unsigned i = 0; i != NumReplacementTokens; ++i) {
116 const Token &A = ReplacementTokens[i];
153 llvm::raw_ostream &Out = llvm::errs();
156 Out <<
"MacroInfo " <<
this;
157 if (IsBuiltinMacro) Out <<
" builtin";
158 if (IsDisabled) Out <<
" disabled";
159 if (IsUsed) Out <<
" used";
160 if (IsAllowRedefinitionsWithoutWarning)
161 Out <<
" allow_redefinitions_without_warning";
162 if (IsWarnIfUnused) Out <<
" warn_if_unused";
163 if (UsedForHeaderGuard) Out <<
" header_guard";
165 Out <<
"\n #define <macro>";
166 if (IsFunctionLike) {
168 for (
unsigned I = 0; I != NumParameters; ++I) {
170 Out << ParameterList[I]->
getName();
172 if (IsC99Varargs || IsGNUVarargs) {
173 if (NumParameters && IsC99Varargs) Out <<
", ";
183 if (
First || Tok.hasLeadingSpace())
189 else if (Tok.isLiteral() && Tok.getLiteralData())
190 Out << StringRef(Tok.getLiteralData(), Tok.getLength());
191 else if (
auto *II = Tok.getIdentifierInfo())
192 Out << II->getName();
194 Out << Tok.getName();
201 std::optional<bool> isPublic;
204 return DefInfo(DefMD, UndefLoc, !isPublic || *isPublic);
207 UndefLoc = UndefMD->getLocation();
216 return DefInfo(
nullptr, UndefLoc, !isPublic || *isPublic);
222 assert(L.
isValid() &&
"SourceLocation is invalid.");
224 if (Def.getLocation().isInvalid() ||
225 SM.isBeforeInTranslationUnit(Def.getLocation(), L))
226 return (!Def.isUndefined() ||
227 SM.isBeforeInTranslationUnit(L, Def.getUndefLocation()))
234 llvm::raw_ostream &Out = llvm::errs();
237 case MD_Define: Out <<
"DefMacroDirective";
break;
238 case MD_Undefine: Out <<
"UndefMacroDirective";
break;
239 case MD_Visibility: Out <<
"VisibilityMacroDirective";
break;
244 Out <<
" prev " << Prev;
247 if (isa<VisibilityMacroDirective>(
this))
248 Out << (
IsPublic ?
" public" :
" private");
250 if (
auto *DMD = dyn_cast<DefMacroDirective>(
this)) {
251 if (
auto *Info = DMD->getInfo()) {
265 return new (Mem)
ModuleMacro(OwningModule, II, Macro, Overrides);
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.