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"
37 using namespace clang;
44 bool InQuotes,
bool ImportedModule,
49 char *Memory = (
char *)PPRec.
Allocate(FileName.size() + 1,
alignof(char));
50 memcpy(Memory, FileName.data(), FileName.size());
51 Memory[FileName.size()] = 0;
52 this->FileName = StringRef(Memory, FileName.size());
59 llvm::iterator_range<PreprocessingRecord::iterator>
64 if (CachedRangeQuery.Range ==
Range) {
65 return llvm::make_range(
iterator(
this, CachedRangeQuery.Result.first),
66 iterator(
this, CachedRangeQuery.Result.second));
69 std::pair<int, int> Res = getPreprocessedEntitiesInRangeSlow(
Range);
71 CachedRangeQuery.Range =
Range;
72 CachedRangeQuery.Result = Res;
74 return llvm::make_range(
iterator(
this, Res.first),
88 return SM.isInFileID(
SM.getFileLoc(Loc), FID);
104 if (
unsigned(-Pos-1) >= LoadedPreprocessedEntities.size()) {
105 assert(0 &&
"Out-of bounds loaded preprocessed entity");
108 assert(ExternalSource &&
"No external source to load from");
109 unsigned LoadedIndex = LoadedPreprocessedEntities.size()+Pos;
118 return IsInFile.getValue();
123 getLoadedPreprocessedEntity(LoadedIndex),
127 if (
unsigned(Pos) >= PreprocessedEntities.size()) {
128 assert(0 &&
"Out-of bounds local preprocessed entity");
138 PreprocessingRecord::getPreprocessedEntitiesInRangeSlow(
SourceRange Range) {
142 std::pair<unsigned, unsigned>
143 Local = findLocalPreprocessedEntitiesInRange(
Range);
147 return std::make_pair(Local.first, Local.second);
149 std::pair<unsigned, unsigned>
153 if (Loaded.first == Loaded.second)
154 return std::make_pair(Local.first, Local.second);
156 unsigned TotalLoaded = LoadedPreprocessedEntities.size();
159 if (Local.first == Local.second)
160 return std::make_pair(
int(Loaded.first)-TotalLoaded,
161 int(Loaded.second)-TotalLoaded);
164 return std::make_pair(
int(Loaded.first)-TotalLoaded, Local.second);
167 std::pair<unsigned, unsigned>
168 PreprocessingRecord::findLocalPreprocessedEntitiesInRange(
171 return std::make_pair(0,0);
181 template <SourceLocation (SourceRange::*getRangeLoc)() const>
182 struct PPEntityComp {
190 return SM.isBeforeInTranslationUnit(LHS, RHS);
195 return SM.isBeforeInTranslationUnit(LHS, RHS);
200 return SM.isBeforeInTranslationUnit(LHS, RHS);
205 return (
Range.*getRangeLoc)();
211 unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity(
216 size_t Count = PreprocessedEntities.size();
218 std::vector<PreprocessedEntity *>::const_iterator
219 First = PreprocessedEntities.begin();
220 std::vector<PreprocessedEntity *>::const_iterator I;
234 Count = Count -
Half - 1;
239 return First - PreprocessedEntities.begin();
243 PreprocessingRecord::findEndLocalPreprocessedEntity(
SourceLocation Loc)
const {
247 auto I = llvm::upper_bound(PreprocessedEntities, Loc,
248 PPEntityComp<&SourceRange::getBegin>(SourceMgr));
249 return I - PreprocessedEntities.begin();
252 PreprocessingRecord::PPEntityID
257 if (isa<MacroDefinitionRecord>(Entity)) {
258 assert((PreprocessedEntities.empty() ||
261 PreprocessedEntities.back()->getSourceRange().getBegin())) &&
262 "a macro definition was encountered out-of-order");
263 PreprocessedEntities.push_back(Entity);
264 return getPPEntityID(PreprocessedEntities.size()-1,
false);
268 if (PreprocessedEntities.empty() ||
270 PreprocessedEntities.back()->getSourceRange().getBegin())) {
271 PreprocessedEntities.push_back(Entity);
272 return getPPEntityID(PreprocessedEntities.size()-1,
false);
287 using pp_iter = std::vector<PreprocessedEntity *>::iterator;
292 for (pp_iter RI = PreprocessedEntities.end(),
293 Begin = PreprocessedEntities.begin();
294 RI !=
Begin && count < 4; --RI, ++count) {
298 (*I)->getSourceRange().getBegin())) {
299 pp_iter insertI = PreprocessedEntities.insert(RI, Entity);
300 return getPPEntityID(insertI - PreprocessedEntities.begin(),
307 llvm::upper_bound(PreprocessedEntities, BeginLoc,
308 PPEntityComp<&SourceRange::getBegin>(SourceMgr));
309 pp_iter insertI = PreprocessedEntities.insert(I, Entity);
310 return getPPEntityID(insertI - PreprocessedEntities.begin(),
316 assert(!ExternalSource &&
317 "Preprocessing record already has an external source");
318 ExternalSource = &Source;
321 unsigned PreprocessingRecord::allocateLoadedEntities(
unsigned NumEntities) {
322 unsigned Result = LoadedPreprocessedEntities.size();
323 LoadedPreprocessedEntities.resize(LoadedPreprocessedEntities.size()
328 unsigned PreprocessingRecord::allocateSkippedRanges(
unsigned NumRanges) {
329 unsigned Result = SkippedRanges.size();
330 SkippedRanges.resize(SkippedRanges.size() + NumRanges);
331 SkippedRangesAllLoaded =
false;
335 void PreprocessingRecord::ensureSkippedRangesLoaded() {
336 if (SkippedRangesAllLoaded || !ExternalSource)
338 for (
unsigned Index = 0; Index != SkippedRanges.size(); ++Index) {
342 SkippedRangesAllLoaded =
true;
345 void PreprocessingRecord::RegisterMacroDefinition(
MacroInfo *Macro,
347 MacroDefinitions[
Macro] = Def;
353 unsigned Index = -PPID.ID - 1;
354 assert(Index < LoadedPreprocessedEntities.size() &&
355 "Out-of bounds loaded preprocessed entity");
356 return getLoadedPreprocessedEntity(Index);
361 unsigned Index = PPID.ID - 1;
362 assert(Index < PreprocessedEntities.size() &&
363 "Out-of bounds local preprocessed entity");
364 return PreprocessedEntities[Index];
369 PreprocessingRecord::getLoadedPreprocessedEntity(
unsigned Index) {
370 assert(Index < LoadedPreprocessedEntities.size() &&
371 "Out-of bounds loaded preprocessed entity");
372 assert(ExternalSource &&
"No external source to load from");
385 llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *>::iterator Pos =
386 MacroDefinitions.find(MI);
387 if (Pos == MacroDefinitions.end())
393 void PreprocessingRecord::addMacroExpansion(
const Token &
Id,
397 if (
Id.getLocation().isMacroID())
432 const Token &MacroNameTok,
440 void PreprocessingRecord::Defined(
const Token &MacroNameTok,
449 void PreprocessingRecord::SourceRangeSkipped(
SourceRange Range,
455 void PreprocessingRecord::MacroExpands(
const Token &
Id,
462 void PreprocessingRecord::MacroDefined(
const Token &
Id,
469 MacroDefinitions[MI] = Def;
472 void PreprocessingRecord::MacroUndefined(
const Token &
Id,
478 void PreprocessingRecord::InclusionDirective(
480 const Token &IncludeTok,
485 StringRef SearchPath,
486 StringRef RelativePath,
509 llvm_unreachable(
"Unknown include directive kind");
516 EndLoc = FilenameRange.
getEnd();
523 (
bool)Imported, File,
529 return BumpAlloc.getTotalMemory()
530 + llvm::capacity_in_bytes(MacroDefinitions)
531 + llvm::capacity_in_bytes(PreprocessedEntities)
532 + llvm::capacity_in_bytes(LoadedPreprocessedEntities)
533 + llvm::capacity_in_bytes(SkippedRanges);