17 #include "llvm/Support/Capacity.h"
18 #include "llvm/Support/ErrorHandling.h"
20 using namespace clang;
26 bool InQuotes,
bool ImportedModule,
29 Kind(Kind), ImportedModule(ImportedModule), File(File) {
30 char *Memory = (
char *)PPRec.
Allocate(FileName.size() + 1,
alignof(char));
31 memcpy(Memory, FileName.data(), FileName.size());
32 Memory[FileName.size()] = 0;
33 this->FileName = StringRef(Memory, FileName.size());
38 ExternalSource(nullptr) {
43 llvm::iterator_range<PreprocessingRecord::iterator>
48 if (CachedRangeQuery.Range == Range) {
49 return llvm::make_range(
iterator(
this, CachedRangeQuery.Result.first),
50 iterator(
this, CachedRangeQuery.Result.second));
53 std::pair<int, int> Res = getPreprocessedEntitiesInRangeSlow(Range);
55 CachedRangeQuery.Range =
Range;
56 CachedRangeQuery.Result = Res;
58 return llvm::make_range(
iterator(
this, Res.first),
88 if (
unsigned(-Pos-1) >= LoadedPreprocessedEntities.size()) {
89 assert(0 &&
"Out-of bounds loaded preprocessed entity");
92 assert(ExternalSource &&
"No external source to load from");
93 unsigned LoadedIndex = LoadedPreprocessedEntities.size()+Pos;
101 if (IsInFile.hasValue())
102 return IsInFile.getValue();
107 getLoadedPreprocessedEntity(LoadedIndex),
111 if (
unsigned(Pos) >= PreprocessedEntities.size()) {
112 assert(0 &&
"Out-of bounds local preprocessed entity");
122 PreprocessingRecord::getPreprocessedEntitiesInRangeSlow(
SourceRange Range) {
126 std::pair<unsigned, unsigned>
127 Local = findLocalPreprocessedEntitiesInRange(Range);
131 return std::make_pair(Local.first, Local.second);
133 std::pair<unsigned, unsigned>
137 if (Loaded.first == Loaded.second)
138 return std::make_pair(Local.first, Local.second);
140 unsigned TotalLoaded = LoadedPreprocessedEntities.size();
143 if (Local.first == Local.second)
144 return std::make_pair(
int(Loaded.first)-TotalLoaded,
145 int(Loaded.second)-TotalLoaded);
148 return std::make_pair(
int(Loaded.first)-TotalLoaded, Local.second);
151 std::pair<unsigned, unsigned>
152 PreprocessingRecord::findLocalPreprocessedEntitiesInRange(
155 return std::make_pair(0,0);
158 unsigned Begin = findBeginLocalPreprocessedEntity(Range.
getBegin());
159 unsigned End = findEndLocalPreprocessedEntity(Range.
getEnd());
160 return std::make_pair(Begin, End);
165 template <SourceLocation (SourceRange::*getRangeLoc)() const>
166 struct PPEntityComp {
189 return (Range.*getRangeLoc)();
195 unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity(
200 size_t Count = PreprocessedEntities.size();
202 std::vector<PreprocessedEntity *>::const_iterator
203 First = PreprocessedEntities.begin();
204 std::vector<PreprocessedEntity *>::const_iterator
I;
213 std::advance(I, Half);
218 Count = Count - Half - 1;
223 return First - PreprocessedEntities.begin();
226 unsigned PreprocessingRecord::findEndLocalPreprocessedEntity(
231 std::vector<PreprocessedEntity *>::const_iterator
232 I = std::upper_bound(PreprocessedEntities.begin(),
233 PreprocessedEntities.end(),
235 PPEntityComp<&SourceRange::getBegin>(SourceMgr));
236 return I - PreprocessedEntities.begin();
239 PreprocessingRecord::PPEntityID
244 if (isa<MacroDefinitionRecord>(Entity)) {
245 assert((PreprocessedEntities.empty() ||
248 PreprocessedEntities.back()->getSourceRange().getBegin())) &&
249 "a macro definition was encountered out-of-order");
250 PreprocessedEntities.push_back(Entity);
251 return getPPEntityID(PreprocessedEntities.size()-1,
false);
255 if (PreprocessedEntities.empty() ||
257 PreprocessedEntities.back()->getSourceRange().getBegin())) {
258 PreprocessedEntities.push_back(Entity);
259 return getPPEntityID(PreprocessedEntities.size()-1,
false);
274 typedef std::vector<PreprocessedEntity *>::iterator pp_iter;
279 for (pp_iter RI = PreprocessedEntities.end(),
280 Begin = PreprocessedEntities.begin();
281 RI != Begin && count < 4; --RI, ++count) {
285 (*I)->getSourceRange().getBegin())) {
286 pp_iter insertI = PreprocessedEntities.insert(RI, Entity);
287 return getPPEntityID(insertI - PreprocessedEntities.begin(),
293 pp_iter I = std::upper_bound(PreprocessedEntities.begin(),
294 PreprocessedEntities.end(),
296 PPEntityComp<&SourceRange::getBegin>(SourceMgr));
297 pp_iter insertI = PreprocessedEntities.insert(I, Entity);
298 return getPPEntityID(insertI - PreprocessedEntities.begin(),
304 assert(!ExternalSource &&
305 "Preprocessing record already has an external source");
306 ExternalSource = &Source;
309 unsigned PreprocessingRecord::allocateLoadedEntities(
unsigned NumEntities) {
310 unsigned Result = LoadedPreprocessedEntities.size();
311 LoadedPreprocessedEntities.resize(LoadedPreprocessedEntities.size()
316 void PreprocessingRecord::RegisterMacroDefinition(
MacroInfo *Macro,
318 MacroDefinitions[Macro] = Def;
324 unsigned Index = -PPID.ID - 1;
325 assert(Index < LoadedPreprocessedEntities.size() &&
326 "Out-of bounds loaded preprocessed entity");
327 return getLoadedPreprocessedEntity(Index);
332 unsigned Index = PPID.ID - 1;
333 assert(Index < PreprocessedEntities.size() &&
334 "Out-of bounds local preprocessed entity");
335 return PreprocessedEntities[Index];
340 PreprocessingRecord::getLoadedPreprocessedEntity(
unsigned Index) {
341 assert(Index < LoadedPreprocessedEntities.size() &&
342 "Out-of bounds loaded preprocessed entity");
343 assert(ExternalSource &&
"No external source to load from");
356 llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *>::iterator Pos =
357 MacroDefinitions.find(MI);
358 if (Pos == MacroDefinitions.end())
364 void PreprocessingRecord::addMacroExpansion(
const Token &Id,
394 void PreprocessingRecord::Defined(
const Token &MacroNameTok,
403 void PreprocessingRecord::SourceRangeSkipped(
SourceRange Range) {
404 SkippedRanges.push_back(Range);
407 void PreprocessingRecord::MacroExpands(
const Token &Id,
414 void PreprocessingRecord::MacroDefined(
const Token &Id,
421 MacroDefinitions[MI] = Def;
424 void PreprocessingRecord::MacroUndefined(
const Token &Id,
430 void PreprocessingRecord::InclusionDirective(
437 StringRef SearchPath,
438 StringRef RelativePath,
443 case tok::pp_include:
451 case tok::pp_include_next:
455 case tok::pp___include_macros:
460 llvm_unreachable(
"Unknown include directive kind");
467 EndLoc = FilenameRange.
getEnd();
480 return BumpAlloc.getTotalMemory()
481 + llvm::capacity_in_bytes(MacroDefinitions)
482 + llvm::capacity_in_bytes(PreprocessedEntities)
483 + llvm::capacity_in_bytes(LoadedPreprocessedEntities);
SourceLocation getEnd() const
SourceLocation getBegin() const
Defines the clang::MacroInfo and clang::MacroDirective classes.
A description of the current definition of a macro.
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...
virtual PreprocessedEntity * ReadPreprocessedEntity(unsigned Index)=0
Read a preallocated preprocessed entity from the external source.
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.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
Records the presence of a preprocessor directive.
Iteration over the preprocessed entities.
Record the location of a macro definition.
Token - This structure provides full information about a lexed token.
Describes a module or submodule.
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
llvm::iterator_range< iterator > getPreprocessedEntitiesInRange(SourceRange R)
Returns a range of preprocessed entities that source range R encompasses.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
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...
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location...
bool isLoadedSourceLocation(SourceLocation Loc) const
Returns true if Loc came from a PCH/Module.
detail::InMemoryDirectory::const_iterator I
virtual ~ExternalPreprocessingRecordSource()
Records the location of a macro expansion.
PreprocessingRecord(SourceManager &SM)
Construct a new preprocessing record.
A GNU #include_next directive.
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.
Represents a character-granular source range.
SourceLocation getEnd() const
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID, SourceManager &SM)
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Record the location of an inclusion directive, such as an #include or #import statement.
InclusionKind
The kind of inclusion directives known to the preprocessor.
InclusionDirective(PreprocessingRecord &PPRec, InclusionKind Kind, StringRef FileName, bool InQuotes, bool ImportedModule, const FileEntry *File, SourceRange Range)
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Encodes a location in the source.
Cached information about one file (either on disk or in the virtual file system). ...
void forAllDefinitions(Fn F) const
An abstract class that should be subclassed by any external source of preprocessing record entries...
SourceLocation getDefinitionEndLoc() const
Return the location of the last token in the macro.
SourceLocation getBegin() const
bool isEntityInFileID(iterator PPEI, FileID FID)
Returns true if the preprocessed entity that PPEI iterator points to is coming from the file FID...
A Clang #__include_macros directive.
bool isLocalSourceLocation(SourceLocation Loc) const
Returns true if Loc did not come from a PCH/Module.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
const MacroInfo * getMacroInfo() const
Encapsulates the data about a macro definition (e.g.
PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity)
Add a new preprocessed entity to this record.
An Objective-C #import directive.
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
size_t getTotalMemory() const
MacroDefinitionRecord * findMacroDefinition(const MacroInfo *MI)
Retrieve the macro definition that corresponds to the given MacroInfo.
void SetExternalSource(ExternalPreprocessingRecordSource &Source)
Set the external source for preprocessed entities.
A trivial tuple used to represent a source range.
This class handles loading and caching of source files into memory.
IdentifierInfo * getIdentifierInfo() const
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.