clang  6.0.0svn
MacroInfo.cpp
Go to the documentation of this file.
1 //===--- MacroInfo.cpp - Information about #defined identifiers -----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the MacroInfo interface.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/Lex/MacroInfo.h"
15 #include "clang/Lex/Preprocessor.h"
16 using namespace clang;
17 
18 MacroInfo::MacroInfo(SourceLocation DefLoc)
19  : Location(DefLoc),
20  ParameterList(nullptr),
21  NumParameters(0),
22  IsDefinitionLengthCached(false),
23  IsFunctionLike(false),
24  IsC99Varargs(false),
25  IsGNUVarargs(false),
26  IsBuiltinMacro(false),
27  HasCommaPasting(false),
28  IsDisabled(false),
29  IsUsed(false),
30  IsAllowRedefinitionsWithoutWarning(false),
31  IsWarnIfUnused(false),
32  UsedForHeaderGuard(false) {
33 }
34 
35 unsigned MacroInfo::getDefinitionLengthSlow(const SourceManager &SM) const {
36  assert(!IsDefinitionLengthCached);
37  IsDefinitionLengthCached = true;
38 
39  if (ReplacementTokens.empty())
40  return (DefinitionLength = 0);
41 
42  const Token &firstToken = ReplacementTokens.front();
43  const Token &lastToken = ReplacementTokens.back();
44  SourceLocation macroStart = firstToken.getLocation();
45  SourceLocation macroEnd = lastToken.getLocation();
46  assert(macroStart.isValid() && macroEnd.isValid());
47  assert((macroStart.isFileID() || firstToken.is(tok::comment)) &&
48  "Macro defined in macro?");
49  assert((macroEnd.isFileID() || lastToken.is(tok::comment)) &&
50  "Macro defined in macro?");
51  std::pair<FileID, unsigned>
52  startInfo = SM.getDecomposedExpansionLoc(macroStart);
53  std::pair<FileID, unsigned>
54  endInfo = SM.getDecomposedExpansionLoc(macroEnd);
55  assert(startInfo.first == endInfo.first &&
56  "Macro definition spanning multiple FileIDs ?");
57  assert(startInfo.second <= endInfo.second);
58  DefinitionLength = endInfo.second - startInfo.second;
59  DefinitionLength += lastToken.getLength();
60 
61  return DefinitionLength;
62 }
63 
64 /// \brief Return true if the specified macro definition is equal to
65 /// this macro in spelling, arguments, and whitespace.
66 ///
67 /// \param Syntactically if true, the macro definitions can be identical even
68 /// if they use different identifiers for the function macro parameters.
69 /// Otherwise the comparison is lexical and this implements the rules in
70 /// C99 6.10.3.
72  bool Syntactically) const {
73  bool Lexically = !Syntactically;
74 
75  // Check # tokens in replacement, number of args, and various flags all match.
76  if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
77  getNumParams() != Other.getNumParams() ||
78  isFunctionLike() != Other.isFunctionLike() ||
79  isC99Varargs() != Other.isC99Varargs() ||
80  isGNUVarargs() != Other.isGNUVarargs())
81  return false;
82 
83  if (Lexically) {
84  // Check arguments.
85  for (param_iterator I = param_begin(), OI = Other.param_begin(),
86  E = param_end();
87  I != E; ++I, ++OI)
88  if (*I != *OI) return false;
89  }
90 
91  // Check all the tokens.
92  for (unsigned i = 0, e = ReplacementTokens.size(); i != e; ++i) {
93  const Token &A = ReplacementTokens[i];
94  const Token &B = Other.ReplacementTokens[i];
95  if (A.getKind() != B.getKind())
96  return false;
97 
98  // If this isn't the first first token, check that the whitespace and
99  // start-of-line characteristics match.
100  if (i != 0 &&
101  (A.isAtStartOfLine() != B.isAtStartOfLine() ||
102  A.hasLeadingSpace() != B.hasLeadingSpace()))
103  return false;
104 
105  // If this is an identifier, it is easy.
106  if (A.getIdentifierInfo() || B.getIdentifierInfo()) {
107  if (A.getIdentifierInfo() == B.getIdentifierInfo())
108  continue;
109  if (Lexically)
110  return false;
111  // With syntactic equivalence the parameter names can be different as long
112  // as they are used in the same place.
113  int AArgNum = getParameterNum(A.getIdentifierInfo());
114  if (AArgNum == -1)
115  return false;
116  if (AArgNum != Other.getParameterNum(B.getIdentifierInfo()))
117  return false;
118  continue;
119  }
120 
121  // Otherwise, check the spelling.
122  if (PP.getSpelling(A) != PP.getSpelling(B))
123  return false;
124  }
125 
126  return true;
127 }
128 
129 LLVM_DUMP_METHOD void MacroInfo::dump() const {
130  llvm::raw_ostream &Out = llvm::errs();
131 
132  // FIXME: Dump locations.
133  Out << "MacroInfo " << this;
134  if (IsBuiltinMacro) Out << " builtin";
135  if (IsDisabled) Out << " disabled";
136  if (IsUsed) Out << " used";
137  if (IsAllowRedefinitionsWithoutWarning)
138  Out << " allow_redefinitions_without_warning";
139  if (IsWarnIfUnused) Out << " warn_if_unused";
140  if (UsedForHeaderGuard) Out << " header_guard";
141 
142  Out << "\n #define <macro>";
143  if (IsFunctionLike) {
144  Out << "(";
145  for (unsigned I = 0; I != NumParameters; ++I) {
146  if (I) Out << ", ";
147  Out << ParameterList[I]->getName();
148  }
149  if (IsC99Varargs || IsGNUVarargs) {
150  if (NumParameters && IsC99Varargs) Out << ", ";
151  Out << "...";
152  }
153  Out << ")";
154  }
155 
156  bool First = true;
157  for (const Token &Tok : ReplacementTokens) {
158  // Leading space is semantically meaningful in a macro definition,
159  // so preserve it in the dump output.
160  if (First || Tok.hasLeadingSpace())
161  Out << " ";
162  First = false;
163 
164  if (const char *Punc = tok::getPunctuatorSpelling(Tok.getKind()))
165  Out << Punc;
166  else if (Tok.isLiteral() && Tok.getLiteralData())
167  Out << StringRef(Tok.getLiteralData(), Tok.getLength());
168  else if (auto *II = Tok.getIdentifierInfo())
169  Out << II->getName();
170  else
171  Out << Tok.getName();
172  }
173 }
174 
176  MacroDirective *MD = this;
177  SourceLocation UndefLoc;
178  Optional<bool> isPublic;
179  for (; MD; MD = MD->getPrevious()) {
180  if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
181  return DefInfo(DefMD, UndefLoc,
182  !isPublic.hasValue() || isPublic.getValue());
183 
184  if (UndefMacroDirective *UndefMD = dyn_cast<UndefMacroDirective>(MD)) {
185  UndefLoc = UndefMD->getLocation();
186  continue;
187  }
188 
189  VisibilityMacroDirective *VisMD = cast<VisibilityMacroDirective>(MD);
190  if (!isPublic.hasValue())
191  isPublic = VisMD->isPublic();
192  }
193 
194  return DefInfo(nullptr, UndefLoc,
195  !isPublic.hasValue() || isPublic.getValue());
196 }
197 
200  assert(L.isValid() && "SourceLocation is invalid.");
201  for (DefInfo Def = getDefinition(); Def; Def = Def.getPreviousDefinition()) {
202  if (Def.getLocation().isInvalid() || // For macros defined on the command line.
203  SM.isBeforeInTranslationUnit(Def.getLocation(), L))
204  return (!Def.isUndefined() ||
205  SM.isBeforeInTranslationUnit(L, Def.getUndefLocation()))
206  ? Def : DefInfo();
207  }
208  return DefInfo();
209 }
210 
211 LLVM_DUMP_METHOD void MacroDirective::dump() const {
212  llvm::raw_ostream &Out = llvm::errs();
213 
214  switch (getKind()) {
215  case MD_Define: Out << "DefMacroDirective"; break;
216  case MD_Undefine: Out << "UndefMacroDirective"; break;
217  case MD_Visibility: Out << "VisibilityMacroDirective"; break;
218  }
219  Out << " " << this;
220  // FIXME: Dump SourceLocation.
221  if (auto *Prev = getPrevious())
222  Out << " prev " << Prev;
223  if (IsFromPCH) Out << " from_pch";
224 
225  if (isa<VisibilityMacroDirective>(this))
226  Out << (IsPublic ? " public" : " private");
227 
228  if (auto *DMD = dyn_cast<DefMacroDirective>(this)) {
229  if (auto *Info = DMD->getInfo()) {
230  Out << "\n ";
231  Info->dump();
232  }
233  }
234  Out << "\n";
235 }
236 
238  IdentifierInfo *II, MacroInfo *Macro,
239  ArrayRef<ModuleMacro *> Overrides) {
240  void *Mem = PP.getPreprocessorAllocator().Allocate(
241  sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(),
242  alignof(ModuleMacro));
243  return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides);
244 }
llvm::BumpPtrAllocator & getPreprocessorAllocator()
Definition: Preprocessor.h:740
param_iterator param_begin() const
Definition: MacroInfo.h:174
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)) {...
Definition: Token.h:95
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.
Definition: MacroInfo.h:419
const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const
Find macro definition active in the specified source location.
Definition: MacroInfo.cpp:199
static const NamedDecl * getDefinition(const Decl *D)
Definition: SemaDecl.cpp:2512
const MacroDirective * getPrevious() const
Get previous definition of the macro with the same name.
Definition: MacroInfo.h:321
tok::TokenKind getKind() const
Definition: Token.h:90
One of these records is kept for each identifier that is lexed.
Represents a macro directive exported by a module.
Definition: MacroInfo.h:476
A directive for a defined macro or a macro imported from a module.
Definition: MacroInfo.h:397
void dump() const
Definition: MacroInfo.cpp:129
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
Describes a module or submodule.
Definition: Module.h:57
A directive for setting the module visibility of a macro.
Definition: MacroInfo.h:433
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 &#39;spelling&#39; of the token at the given location; does not go up to the spelling location or ...
const FormatToken & Tok
bool isPublic() const
Determine whether this macro is part of the public API of its module.
Definition: MacroInfo.h:442
unsigned getNumParams() const
Definition: MacroInfo.h:176
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Definition: Token.h:124
Defines the clang::Preprocessor interface.
DefInfo getDefinition()
Traverses the macro directives history and returns the next macro definition directive along with inf...
Definition: MacroInfo.cpp:175
const char * getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple punctuation tokens like &#39;!&#39; or &#39;&#39;, and returns NULL for literal and...
Definition: TokenKinds.cpp:32
const SourceManager & SM
Definition: Format.cpp:1308
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Definition: MacroInfo.h:286
#define false
Definition: stdbool.h:33
Encodes a location in the source.
IdentifierInfo *const * param_iterator
Parameters - The list of parameters for a function-like macro.
Definition: MacroInfo.h:172
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:177
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
Definition: Token.h:266
bool isC99Varargs() const
Definition: MacroInfo.h:199
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isFunctionLike() const
Definition: MacroInfo.h:193
unsigned getLength() const
Definition: Token.h:127
Encapsulates the data about a macro definition (e.g.
Definition: MacroInfo.h:34
static ModuleMacro * create(Preprocessor &PP, Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro *> Overrides)
Definition: MacroInfo.cpp:237
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
Definition: MacroInfo.h:183
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:71
bool isGNUVarargs() const
Definition: MacroInfo.h:200
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:896
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
Definition: Token.h:270
This class handles loading and caching of source files into memory.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:98