clang  9.0.0svn
PreprocessingRecord.cpp
Go to the documentation of this file.
1 //===- PreprocessingRecord.cpp - Record of Preprocessing ------------------===//
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 PreprocessingRecord class, which maintains a record
10 // of what occurred during preprocessing, and its helpers.
11 //
12 //===----------------------------------------------------------------------===//
13 
16 #include "clang/Basic/LLVM.h"
19 #include "clang/Basic/TokenKinds.h"
20 #include "clang/Lex/MacroInfo.h"
21 #include "clang/Lex/Token.h"
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/Optional.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/ADT/iterator_range.h"
26 #include "llvm/Support/Capacity.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include <algorithm>
30 #include <cassert>
31 #include <cstddef>
32 #include <cstring>
33 #include <iterator>
34 #include <utility>
35 #include <vector>
36 
37 using namespace clang;
38 
40  default;
41 
43  InclusionKind Kind, StringRef FileName,
44  bool InQuotes, bool ImportedModule,
45  const FileEntry *File, SourceRange Range)
46  : PreprocessingDirective(InclusionDirectiveKind, Range), InQuotes(InQuotes),
47  Kind(Kind), ImportedModule(ImportedModule), File(File) {
48  char *Memory = (char *)PPRec.Allocate(FileName.size() + 1, alignof(char));
49  memcpy(Memory, FileName.data(), FileName.size());
50  Memory[FileName.size()] = 0;
51  this->FileName = StringRef(Memory, FileName.size());
52 }
53 
55 
56 /// Returns a pair of [Begin, End) iterators of preprocessed entities
57 /// that source range \p Range encompasses.
58 llvm::iterator_range<PreprocessingRecord::iterator>
60  if (Range.isInvalid())
61  return llvm::make_range(iterator(), iterator());
62 
63  if (CachedRangeQuery.Range == Range) {
64  return llvm::make_range(iterator(this, CachedRangeQuery.Result.first),
65  iterator(this, CachedRangeQuery.Result.second));
66  }
67 
68  std::pair<int, int> Res = getPreprocessedEntitiesInRangeSlow(Range);
69 
70  CachedRangeQuery.Range = Range;
71  CachedRangeQuery.Result = Res;
72 
73  return llvm::make_range(iterator(this, Res.first),
74  iterator(this, Res.second));
75 }
76 
78  SourceManager &SM) {
79  assert(FID.isValid());
80  if (!PPE)
81  return false;
82 
83  SourceLocation Loc = PPE->getSourceRange().getBegin();
84  if (Loc.isInvalid())
85  return false;
86 
87  return SM.isInFileID(SM.getFileLoc(Loc), FID);
88 }
89 
90 /// Returns true if the preprocessed entity that \arg PPEI iterator
91 /// points to is coming from the file \arg FID.
92 ///
93 /// Can be used to avoid implicit deserializations of preallocated
94 /// preprocessed entities if we only care about entities of a specific file
95 /// and not from files \#included in the range given at
96 /// \see getPreprocessedEntitiesInRange.
98  if (FID.isInvalid())
99  return false;
100 
101  int Pos = std::distance(iterator(this, 0), PPEI);
102  if (Pos < 0) {
103  if (unsigned(-Pos-1) >= LoadedPreprocessedEntities.size()) {
104  assert(0 && "Out-of bounds loaded preprocessed entity");
105  return false;
106  }
107  assert(ExternalSource && "No external source to load from");
108  unsigned LoadedIndex = LoadedPreprocessedEntities.size()+Pos;
109  if (PreprocessedEntity *PPE = LoadedPreprocessedEntities[LoadedIndex])
110  return isPreprocessedEntityIfInFileID(PPE, FID, SourceMgr);
111 
112  // See if the external source can see if the entity is in the file without
113  // deserializing it.
114  Optional<bool> IsInFile =
115  ExternalSource->isPreprocessedEntityInFileID(LoadedIndex, FID);
116  if (IsInFile.hasValue())
117  return IsInFile.getValue();
118 
119  // The external source did not provide a definite answer, go and deserialize
120  // the entity to check it.
122  getLoadedPreprocessedEntity(LoadedIndex),
123  FID, SourceMgr);
124  }
125 
126  if (unsigned(Pos) >= PreprocessedEntities.size()) {
127  assert(0 && "Out-of bounds local preprocessed entity");
128  return false;
129  }
130  return isPreprocessedEntityIfInFileID(PreprocessedEntities[Pos],
131  FID, SourceMgr);
132 }
133 
134 /// Returns a pair of [Begin, End) iterators of preprocessed entities
135 /// that source range \arg R encompasses.
136 std::pair<int, int>
137 PreprocessingRecord::getPreprocessedEntitiesInRangeSlow(SourceRange Range) {
138  assert(Range.isValid());
139  assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
140 
141  std::pair<unsigned, unsigned>
142  Local = findLocalPreprocessedEntitiesInRange(Range);
143 
144  // Check if range spans local entities.
145  if (!ExternalSource || SourceMgr.isLocalSourceLocation(Range.getBegin()))
146  return std::make_pair(Local.first, Local.second);
147 
148  std::pair<unsigned, unsigned>
149  Loaded = ExternalSource->findPreprocessedEntitiesInRange(Range);
150 
151  // Check if range spans local entities.
152  if (Loaded.first == Loaded.second)
153  return std::make_pair(Local.first, Local.second);
154 
155  unsigned TotalLoaded = LoadedPreprocessedEntities.size();
156 
157  // Check if range spans loaded entities.
158  if (Local.first == Local.second)
159  return std::make_pair(int(Loaded.first)-TotalLoaded,
160  int(Loaded.second)-TotalLoaded);
161 
162  // Range spands loaded and local entities.
163  return std::make_pair(int(Loaded.first)-TotalLoaded, Local.second);
164 }
165 
166 std::pair<unsigned, unsigned>
167 PreprocessingRecord::findLocalPreprocessedEntitiesInRange(
168  SourceRange Range) const {
169  if (Range.isInvalid())
170  return std::make_pair(0,0);
171  assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
172 
173  unsigned Begin = findBeginLocalPreprocessedEntity(Range.getBegin());
174  unsigned End = findEndLocalPreprocessedEntity(Range.getEnd());
175  return std::make_pair(Begin, End);
176 }
177 
178 namespace {
179 
180 template <SourceLocation (SourceRange::*getRangeLoc)() const>
181 struct PPEntityComp {
182  const SourceManager &SM;
183 
184  explicit PPEntityComp(const SourceManager &SM) : SM(SM) {}
185 
186  bool operator()(PreprocessedEntity *L, PreprocessedEntity *R) const {
187  SourceLocation LHS = getLoc(L);
188  SourceLocation RHS = getLoc(R);
189  return SM.isBeforeInTranslationUnit(LHS, RHS);
190  }
191 
192  bool operator()(PreprocessedEntity *L, SourceLocation RHS) const {
193  SourceLocation LHS = getLoc(L);
194  return SM.isBeforeInTranslationUnit(LHS, RHS);
195  }
196 
197  bool operator()(SourceLocation LHS, PreprocessedEntity *R) const {
198  SourceLocation RHS = getLoc(R);
199  return SM.isBeforeInTranslationUnit(LHS, RHS);
200  }
201 
202  SourceLocation getLoc(PreprocessedEntity *PPE) const {
203  SourceRange Range = PPE->getSourceRange();
204  return (Range.*getRangeLoc)();
205  }
206 };
207 
208 } // namespace
209 
210 unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity(
211  SourceLocation Loc) const {
212  if (SourceMgr.isLoadedSourceLocation(Loc))
213  return 0;
214 
215  size_t Count = PreprocessedEntities.size();
216  size_t Half;
217  std::vector<PreprocessedEntity *>::const_iterator
218  First = PreprocessedEntities.begin();
219  std::vector<PreprocessedEntity *>::const_iterator I;
220 
221  // Do a binary search manually instead of using std::lower_bound because
222  // The end locations of entities may be unordered (when a macro expansion
223  // is inside another macro argument), but for this case it is not important
224  // whether we get the first macro expansion or its containing macro.
225  while (Count > 0) {
226  Half = Count/2;
227  I = First;
228  std::advance(I, Half);
229  if (SourceMgr.isBeforeInTranslationUnit((*I)->getSourceRange().getEnd(),
230  Loc)){
231  First = I;
232  ++First;
233  Count = Count - Half - 1;
234  } else
235  Count = Half;
236  }
237 
238  return First - PreprocessedEntities.begin();
239 }
240 
241 unsigned PreprocessingRecord::findEndLocalPreprocessedEntity(
242  SourceLocation Loc) const {
243  if (SourceMgr.isLoadedSourceLocation(Loc))
244  return 0;
245 
246  std::vector<PreprocessedEntity *>::const_iterator
247  I = std::upper_bound(PreprocessedEntities.begin(),
248  PreprocessedEntities.end(),
249  Loc,
250  PPEntityComp<&SourceRange::getBegin>(SourceMgr));
251  return I - PreprocessedEntities.begin();
252 }
253 
254 PreprocessingRecord::PPEntityID
256  assert(Entity);
257  SourceLocation BeginLoc = Entity->getSourceRange().getBegin();
258 
259  if (isa<MacroDefinitionRecord>(Entity)) {
260  assert((PreprocessedEntities.empty() ||
261  !SourceMgr.isBeforeInTranslationUnit(
262  BeginLoc,
263  PreprocessedEntities.back()->getSourceRange().getBegin())) &&
264  "a macro definition was encountered out-of-order");
265  PreprocessedEntities.push_back(Entity);
266  return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false);
267  }
268 
269  // Check normal case, this entity begin location is after the previous one.
270  if (PreprocessedEntities.empty() ||
271  !SourceMgr.isBeforeInTranslationUnit(BeginLoc,
272  PreprocessedEntities.back()->getSourceRange().getBegin())) {
273  PreprocessedEntities.push_back(Entity);
274  return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false);
275  }
276 
277  // The entity's location is not after the previous one; this can happen with
278  // include directives that form the filename using macros, e.g:
279  // "#include MACRO(STUFF)"
280  // or with macro expansions inside macro arguments where the arguments are
281  // not expanded in the same order as listed, e.g:
282  // \code
283  // #define M1 1
284  // #define M2 2
285  // #define FM(x,y) y x
286  // FM(M1, M2)
287  // \endcode
288 
289  using pp_iter = std::vector<PreprocessedEntity *>::iterator;
290 
291  // Usually there are few macro expansions when defining the filename, do a
292  // linear search for a few entities.
293  unsigned count = 0;
294  for (pp_iter RI = PreprocessedEntities.end(),
295  Begin = PreprocessedEntities.begin();
296  RI != Begin && count < 4; --RI, ++count) {
297  pp_iter I = RI;
298  --I;
299  if (!SourceMgr.isBeforeInTranslationUnit(BeginLoc,
300  (*I)->getSourceRange().getBegin())) {
301  pp_iter insertI = PreprocessedEntities.insert(RI, Entity);
302  return getPPEntityID(insertI - PreprocessedEntities.begin(),
303  /*isLoaded=*/false);
304  }
305  }
306 
307  // Linear search unsuccessful. Do a binary search.
308  pp_iter I = std::upper_bound(PreprocessedEntities.begin(),
309  PreprocessedEntities.end(),
310  BeginLoc,
311  PPEntityComp<&SourceRange::getBegin>(SourceMgr));
312  pp_iter insertI = PreprocessedEntities.insert(I, Entity);
313  return getPPEntityID(insertI - PreprocessedEntities.begin(),
314  /*isLoaded=*/false);
315 }
316 
319  assert(!ExternalSource &&
320  "Preprocessing record already has an external source");
321  ExternalSource = &Source;
322 }
323 
324 unsigned PreprocessingRecord::allocateLoadedEntities(unsigned NumEntities) {
325  unsigned Result = LoadedPreprocessedEntities.size();
326  LoadedPreprocessedEntities.resize(LoadedPreprocessedEntities.size()
327  + NumEntities);
328  return Result;
329 }
330 
331 unsigned PreprocessingRecord::allocateSkippedRanges(unsigned NumRanges) {
332  unsigned Result = SkippedRanges.size();
333  SkippedRanges.resize(SkippedRanges.size() + NumRanges);
334  SkippedRangesAllLoaded = false;
335  return Result;
336 }
337 
338 void PreprocessingRecord::ensureSkippedRangesLoaded() {
339  if (SkippedRangesAllLoaded || !ExternalSource)
340  return;
341  for (unsigned Index = 0; Index != SkippedRanges.size(); ++Index) {
342  if (SkippedRanges[Index].isInvalid())
343  SkippedRanges[Index] = ExternalSource->ReadSkippedRange(Index);
344  }
345  SkippedRangesAllLoaded = true;
346 }
347 
348 void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
349  MacroDefinitionRecord *Def) {
350  MacroDefinitions[Macro] = Def;
351 }
352 
353 /// Retrieve the preprocessed entity at the given ID.
354 PreprocessedEntity *PreprocessingRecord::getPreprocessedEntity(PPEntityID PPID){
355  if (PPID.ID < 0) {
356  unsigned Index = -PPID.ID - 1;
357  assert(Index < LoadedPreprocessedEntities.size() &&
358  "Out-of bounds loaded preprocessed entity");
359  return getLoadedPreprocessedEntity(Index);
360  }
361 
362  if (PPID.ID == 0)
363  return nullptr;
364  unsigned Index = PPID.ID - 1;
365  assert(Index < PreprocessedEntities.size() &&
366  "Out-of bounds local preprocessed entity");
367  return PreprocessedEntities[Index];
368 }
369 
370 /// Retrieve the loaded preprocessed entity at the given index.
372 PreprocessingRecord::getLoadedPreprocessedEntity(unsigned Index) {
373  assert(Index < LoadedPreprocessedEntities.size() &&
374  "Out-of bounds loaded preprocessed entity");
375  assert(ExternalSource && "No external source to load from");
376  PreprocessedEntity *&Entity = LoadedPreprocessedEntities[Index];
377  if (!Entity) {
378  Entity = ExternalSource->ReadPreprocessedEntity(Index);
379  if (!Entity) // Failed to load.
380  Entity = new (*this)
382  }
383  return Entity;
384 }
385 
388  llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *>::iterator Pos =
389  MacroDefinitions.find(MI);
390  if (Pos == MacroDefinitions.end())
391  return nullptr;
392 
393  return Pos->second;
394 }
395 
396 void PreprocessingRecord::addMacroExpansion(const Token &Id,
397  const MacroInfo *MI,
398  SourceRange Range) {
399  // We don't record nested macro expansions.
400  if (Id.getLocation().isMacroID())
401  return;
402 
403  if (MI->isBuiltinMacro())
404  addPreprocessedEntity(new (*this)
406  else if (MacroDefinitionRecord *Def = findMacroDefinition(MI))
407  addPreprocessedEntity(new (*this) MacroExpansion(Def, Range));
408 }
409 
410 void PreprocessingRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok,
411  const MacroDefinition &MD) {
412  // This is not actually a macro expansion but record it as a macro reference.
413  if (MD)
414  addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
415  MacroNameTok.getLocation());
416 }
417 
418 void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok,
419  const MacroDefinition &MD) {
420  // This is not actually a macro expansion but record it as a macro reference.
421  if (MD)
422  addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
423  MacroNameTok.getLocation());
424 }
425 
426 void PreprocessingRecord::Defined(const Token &MacroNameTok,
427  const MacroDefinition &MD,
428  SourceRange Range) {
429  // This is not actually a macro expansion but record it as a macro reference.
430  if (MD)
431  addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
432  MacroNameTok.getLocation());
433 }
434 
435 void PreprocessingRecord::SourceRangeSkipped(SourceRange Range,
436  SourceLocation EndifLoc) {
437  assert(Range.isValid());
438  SkippedRanges.emplace_back(Range.getBegin(), EndifLoc);
439 }
440 
441 void PreprocessingRecord::MacroExpands(const Token &Id,
442  const MacroDefinition &MD,
443  SourceRange Range,
444  const MacroArgs *Args) {
445  addMacroExpansion(Id, MD.getMacroInfo(), Range);
446 }
447 
448 void PreprocessingRecord::MacroDefined(const Token &Id,
449  const MacroDirective *MD) {
450  const MacroInfo *MI = MD->getMacroInfo();
452  MacroDefinitionRecord *Def =
453  new (*this) MacroDefinitionRecord(Id.getIdentifierInfo(), R);
455  MacroDefinitions[MI] = Def;
456 }
457 
458 void PreprocessingRecord::MacroUndefined(const Token &Id,
459  const MacroDefinition &MD,
460  const MacroDirective *Undef) {
461  MD.forAllDefinitions([&](MacroInfo *MI) { MacroDefinitions.erase(MI); });
462 }
463 
464 void PreprocessingRecord::InclusionDirective(
465  SourceLocation HashLoc,
466  const Token &IncludeTok,
467  StringRef FileName,
468  bool IsAngled,
469  CharSourceRange FilenameRange,
470  const FileEntry *File,
471  StringRef SearchPath,
472  StringRef RelativePath,
473  const Module *Imported,
474  SrcMgr::CharacteristicKind FileType) {
476 
477  switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
478  case tok::pp_include:
480  break;
481 
482  case tok::pp_import:
484  break;
485 
486  case tok::pp_include_next:
488  break;
489 
490  case tok::pp___include_macros:
492  break;
493 
494  default:
495  llvm_unreachable("Unknown include directive kind");
496  }
497 
498  SourceLocation EndLoc;
499  if (!IsAngled) {
500  EndLoc = FilenameRange.getBegin();
501  } else {
502  EndLoc = FilenameRange.getEnd();
503  if (FilenameRange.isCharRange())
504  EndLoc = EndLoc.getLocWithOffset(-1); // the InclusionDirective expects
505  // a token range.
506  }
508  new (*this) clang::InclusionDirective(*this, Kind, FileName, !IsAngled,
509  (bool)Imported, File,
510  SourceRange(HashLoc, EndLoc));
512 }
513 
515  return BumpAlloc.getTotalMemory()
516  + llvm::capacity_in_bytes(MacroDefinitions)
517  + llvm::capacity_in_bytes(PreprocessedEntities)
518  + llvm::capacity_in_bytes(LoadedPreprocessedEntities)
519  + llvm::capacity_in_bytes(SkippedRanges);
520 }
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
Defines the SourceManager interface.
bool isLocalSourceLocation(SourceLocation Loc) const
Returns true if Loc did not come from a PCH/Module.
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 description of the current definition of a macro.
Definition: MacroInfo.h:564
Indicates a problem trying to load the preprocessed entity.
Base class that describes a preprocessed entity, which may be a preprocessor directive or macro expan...
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range that covers this entire preprocessed entity.
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Definition: SourceManager.h:77
Records the presence of a preprocessor directive.
SourceLocation getBegin() const
Iteration over the preprocessed entities.
Record the location of a macro definition.
Token - This structure provides full information about a lexed token.
Definition: Token.h:34
Describes a module or submodule.
Definition: Module.h:64
bool isInvalid() const
llvm::iterator_range< iterator > getPreprocessedEntitiesInRange(SourceRange R)
Returns a range of preprocessed entities that source range R encompasses.
A record of the steps taken while preprocessing a source file, including the various preprocessing di...
virtual std::pair< unsigned, unsigned > findPreprocessedEntitiesInRange(SourceRange Range)=0
Returns a pair of [Begin, End) indices of preallocated preprocessed entities that Range encompasses...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
Records the location of a macro expansion.
PreprocessingRecord(SourceManager &SM)
Construct a new preprocessing record.
A GNU #include_next directive.
bool isValid() const
std::pair< int, int > Result
virtual Optional< bool > isPreprocessedEntityInFileID(unsigned Index, FileID FID)
Optionally returns true or false if the preallocated preprocessed entity with index Index came from f...
bool isInFileID(SourceLocation Loc, FileID FID, unsigned *RelativeOffset=nullptr) const
Given a specific FileID, returns true if Loc is inside that FileID chunk and sets relative offset (of...
void * Allocate(unsigned Size, unsigned Align=8)
Allocate memory in the preprocessing record.
SourceLocation End
Represents a character-granular source range.
int Id
Definition: ASTDiff.cpp:190
static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID, SourceManager &SM)
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
Definition: MacroArgs.h:29
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Definition: Token.h:123
SourceLocation Begin
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
bool isInvalid() const
Record the location of an inclusion directive, such as an #include or #import statement.
InclusionKind
The kind of inclusion directives known to the preprocessor.
SourceLocation getEnd() const
InclusionDirective(PreprocessingRecord &PPRec, InclusionKind Kind, StringRef FileName, bool InQuotes, bool ImportedModule, const FileEntry *File, SourceRange Range)
const SourceManager & SM
Definition: Format.cpp:1489
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Definition: MacroInfo.h:290
Kind
Encodes a location in the source.
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:176
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:59
An abstract class that should be subclassed by any external source of preprocessing record entries...
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location...
bool isEntityInFileID(iterator PPEI, FileID FID)
Returns true if the preprocessed entity that PPEI iterator points to is coming from the file FID...
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
A Clang #__include_macros directive.
const MacroInfo * getMacroInfo() const
Definition: MacroInfo.h:390
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
static bool isInvalid(LocType Loc, bool *Invalid)
Dataflow Directional Tag Classes.
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
bool isMacroID() const
Encapsulates the data about a macro definition (e.g.
Definition: MacroInfo.h:39
PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity)
Add a new preprocessed entity to this record.
An Objective-C #import directive.
SourceLocation getEnd() const
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
Definition: MacroInfo.h:123
Defines the clang::TokenKind enum and support functions.
SourceLocation getDefinitionEndLoc() const
Return the location of the last token in the macro.
Definition: MacroInfo.h:129
Defines the clang::SourceLocation class and associated facilities.
bool isValid() const
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
Definition: MacroInfo.h:215
MacroDefinitionRecord * findMacroDefinition(const MacroInfo *MI)
Retrieve the macro definition that corresponds to the given MacroInfo.
void forAllDefinitions(Fn F) const
Definition: MacroInfo.h:600
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
Definition: MacroInfo.h:580
void SetExternalSource(ExternalPreprocessingRecordSource &Source)
Set the external source for preprocessed entities.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
This class handles loading and caching of source files into memory.