[preprocessing record] Have PPEntityID be independent of the size of the
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 5 Oct 2012 00:22:28 +0000 (00:22 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 5 Oct 2012 00:22:28 +0000 (00:22 +0000)
loaded entities vector, otherwise its meaning will change when a module
is imported and the vector size changes.

llvm-svn: 165278

clang/include/clang/Lex/PreprocessingRecord.h
clang/lib/Lex/PreprocessingRecord.cpp

index a569575..f0cbc63 100644 (file)
@@ -352,14 +352,21 @@ namespace clang {
     /// 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.
@@ -428,7 +435,7 @@ namespace clang {
       /// 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;
@@ -439,11 +446,15 @@ namespace clang {
       
       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) {
@@ -634,11 +645,10 @@ namespace clang {
     /// 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;
index 05fbde4..01f3665 100644 (file)
@@ -60,8 +60,7 @@ PreprocessingRecord::getPreprocessedEntitiesInRange(SourceRange Range) {
                           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;
@@ -96,12 +95,12 @@ bool PreprocessingRecord::isEntityInFileID(iterator PPEI, FileID FID) {
   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);
 
@@ -119,15 +118,15 @@ bool PreprocessingRecord::isEntityInFileID(iterator PPEI, FileID FID) {
                                           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()));
@@ -320,14 +319,19 @@ void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
 
 /// \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.