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