/// Negative values are used to indicate preprocessed entities
/// loaded from the external source while non-negative values are used to
/// indicate preprocessed entities introduced by the current preprocessor.
- /// If M is the number of loaded preprocessed entities, value -M
- /// corresponds to element 0 in the loaded entities vector, position -M+1
- /// corresponds to element 1 in the loaded entities vector, etc.
- typedef int PPEntityID;
-
- PPEntityID getPPEntityID(unsigned Index, bool isLoaded) const {
- return isLoaded ? PPEntityID(Index) - LoadedPreprocessedEntities.size()
- : Index;
+ /// Value -1 corresponds to element 0 in the loaded entities vector,
+ /// value -2 corresponds to element 1 in the loaded entities vector, etc.
+ /// Value 0 is an invalid value, the index to local entities is 1-based,
+ /// value 1 corresponds to element 0 in the local entities vector,
+ /// value 2 corresponds to element 1 in the local entities vector, etc.
+ class PPEntityID {
+ int ID;
+ explicit PPEntityID(int ID) : ID(ID) {}
+ friend class PreprocessingRecord;
+ public:
+ PPEntityID() : ID(0) {}
+ };
+
+ static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) {
+ return isLoaded ? PPEntityID(-int(Index)-1) : PPEntityID(Index+1);
}
/// \brief Mapping from MacroInfo structures to their definitions.
/// corresponds to element 0 in the loaded entities vector, position -M+1
/// corresponds to element 1 in the loaded entities vector, etc. This
/// gives us a reasonably efficient, source-order walk.
- PPEntityID Position;
+ int Position;
public:
typedef PreprocessedEntity *value_type;
iterator() : Self(0), Position(0) { }
- iterator(PreprocessingRecord *Self, PPEntityID Position)
+ iterator(PreprocessingRecord *Self, int Position)
: Self(Self), Position(Position) { }
value_type operator*() const {
- return Self->getPreprocessedEntity(Position);
+ bool isLoaded = Position < 0;
+ unsigned Index = isLoaded ?
+ Self->LoadedPreprocessedEntities.size() + Position : Position;
+ PPEntityID ID = Self->getPPEntityID(Index, isLoaded);
+ return Self->getPreprocessedEntity(ID);
}
value_type operator[](difference_type D) {
/// query.
struct {
SourceRange Range;
- std::pair<PPEntityID, PPEntityID> Result;
+ std::pair<int, int> Result;
} CachedRangeQuery;
- std::pair<PPEntityID, PPEntityID>
- getPreprocessedEntitiesInRangeSlow(SourceRange R);
+ std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R);
friend class ASTReader;
friend class ASTWriter;
iterator(this, CachedRangeQuery.Result.second));
}
- std::pair<PPEntityID, PPEntityID>
- Res = getPreprocessedEntitiesInRangeSlow(Range);
+ std::pair<int, int> Res = getPreprocessedEntitiesInRangeSlow(Range);
CachedRangeQuery.Range = Range;
CachedRangeQuery.Result = Res;
if (FID.isInvalid())
return false;
- PPEntityID PPID = PPEI.Position;
- if (PPID < 0) {
- assert(unsigned(-PPID-1) < LoadedPreprocessedEntities.size() &&
+ int Pos = PPEI.Position;
+ if (Pos < 0) {
+ assert(unsigned(-Pos-1) < LoadedPreprocessedEntities.size() &&
"Out-of bounds loaded preprocessed entity");
assert(ExternalSource && "No external source to load from");
- unsigned LoadedIndex = LoadedPreprocessedEntities.size()+PPID;
+ unsigned LoadedIndex = LoadedPreprocessedEntities.size()+Pos;
if (PreprocessedEntity *PPE = LoadedPreprocessedEntities[LoadedIndex])
return isPreprocessedEntityIfInFileID(PPE, FID, SourceMgr);
FID, SourceMgr);
}
- assert(unsigned(PPID) < PreprocessedEntities.size() &&
+ assert(unsigned(Pos) < PreprocessedEntities.size() &&
"Out-of bounds local preprocessed entity");
- return isPreprocessedEntityIfInFileID(PreprocessedEntities[PPID],
+ return isPreprocessedEntityIfInFileID(PreprocessedEntities[Pos],
FID, SourceMgr);
}
/// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
/// that source range \arg R encompasses.
-std::pair<PreprocessingRecord::PPEntityID, PreprocessingRecord::PPEntityID>
+std::pair<int, int>
PreprocessingRecord::getPreprocessedEntitiesInRangeSlow(SourceRange Range) {
assert(Range.isValid());
assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
/// \brief Retrieve the preprocessed entity at the given ID.
PreprocessedEntity *PreprocessingRecord::getPreprocessedEntity(PPEntityID PPID){
- if (PPID < 0) {
- assert(unsigned(-PPID-1) < LoadedPreprocessedEntities.size() &&
+ if (PPID.ID < 0) {
+ unsigned Index = -PPID.ID - 1;
+ assert(Index < LoadedPreprocessedEntities.size() &&
"Out-of bounds loaded preprocessed entity");
- return getLoadedPreprocessedEntity(LoadedPreprocessedEntities.size()+PPID);
+ return getLoadedPreprocessedEntity(Index);
}
- assert(unsigned(PPID) < PreprocessedEntities.size() &&
+
+ if (PPID.ID == 0)
+ return 0;
+ unsigned Index = PPID.ID - 1;
+ assert(Index < PreprocessedEntities.size() &&
"Out-of bounds local preprocessed entity");
- return PreprocessedEntities[PPID];
+ return PreprocessedEntities[Index];
}
/// \brief Retrieve the loaded preprocessed entity at the given index.