[cfe-commits] r63010 - in /cfe/trunk: include/clang/Basic/SourceManager.h lib/Basic/SourceManager.cpp lib/Lex/PPDirectives.cpp

Chris Lattner sabre at nondot.org
Sun Jan 25 23:57:50 PST 2009


Author: lattner
Date: Mon Jan 26 01:57:50 2009
New Revision: 63010

URL: http://llvm.org/viewvc/llvm-project?rev=63010&view=rev
Log:
start plumbing together the line table information.  So far we just
unique the Filenames in #line directives, assigning them UIDs.

Modified:
    cfe/trunk/include/clang/Basic/SourceManager.h
    cfe/trunk/lib/Basic/SourceManager.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp

Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=63010&r1=63009&r2=63010&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Mon Jan 26 01:57:50 2009
@@ -31,6 +31,7 @@
 class FileManager;
 class FileEntry;
 class IdentifierTokenInfo;
+class LineTableInfo;
 
 /// SrcMgr - Public enums and private classes that are part of the
 /// SourceManager implementation.
@@ -224,7 +225,6 @@
       return E;
     }
   };
-  
 }  // end SrcMgr namespace.
 } // end clang namespace
 
@@ -275,6 +275,10 @@
   /// is very common to look up many tokens from the same file.
   mutable FileID LastFileIDLookup;
   
+  /// LineTable - This holds information for #line directives.  It is referenced
+  /// by indices from SLocEntryTable.
+  LineTableInfo *LineTable;
+  
   /// LastLineNo - These ivars serve as a cache used in the getLineNumber
   /// method which is used to speedup getLineNumber calls to nearby locations.
   mutable FileID LastLineNoFileIDQuery;
@@ -292,23 +296,13 @@
   explicit SourceManager(const SourceManager&);
   void operator=(const SourceManager&);  
 public:
-  SourceManager() : NumLinearScans(0), NumBinaryProbes(0) {
+  SourceManager() : LineTable(0), NumLinearScans(0), NumBinaryProbes(0) {
     clearIDTables();
   }
-  ~SourceManager() {}
+  ~SourceManager();
+  
+  void clearIDTables();
   
-  void clearIDTables() {
-    MainFileID = FileID();
-    SLocEntryTable.clear();
-    LastLineNoFileIDQuery = FileID();
-    LastLineNoContentCache = 0;
-    LastFileIDLookup = FileID();
-    
-    // Use up FileID #0 as an invalid instantiation.
-    NextOffset = 0;
-    createInstantiationLoc(SourceLocation(), SourceLocation(), 1);
-  }
-
   //===--------------------------------------------------------------------===//
   // MainFileID creation and querying methods.
   //===--------------------------------------------------------------------===//
@@ -553,6 +547,15 @@
   }
   
   //===--------------------------------------------------------------------===//
+  // Line Table Manipulation Routines
+  //===--------------------------------------------------------------------===//
+  
+  /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
+  /// 
+  unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
+  
+  
+  //===--------------------------------------------------------------------===//
   // Other miscellaneous methods.
   //===--------------------------------------------------------------------===//
   

Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=63010&r1=63009&r2=63010&view=diff

==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Mon Jan 26 01:57:50 2009
@@ -59,9 +59,85 @@
 }
 
 //===--------------------------------------------------------------------===//
+// Line Table Implementation
+//===--------------------------------------------------------------------===//
+
+namespace clang {
+/// LineTableInfo - This class is used to hold and unique data used to
+/// represent #line information.
+class LineTableInfo {
+  /// FilenameIDs - This map is used to assign unique IDs to filenames in
+  /// #line directives.  This allows us to unique the filenames that
+  /// frequently reoccur and reference them with indices.  FilenameIDs holds
+  /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
+  /// to string.
+  llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
+  std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
+public:
+  LineTableInfo() {
+  }
+  
+  void clear() {
+    FilenameIDs.clear();
+    FilenamesByID.clear();
+  }
+  
+  ~LineTableInfo() {}
+  
+  unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
+
+};
+} // namespace clang
+
+
+
+
+unsigned LineTableInfo::getLineTableFilenameID(const char *Ptr, unsigned Len) {
+  // Look up the filename in the string table, returning the pre-existing value
+  // if it exists.
+  llvm::StringMapEntry<unsigned> &Entry = 
+    FilenameIDs.GetOrCreateValue(Ptr, Ptr+Len, ~0U);
+  if (Entry.getValue() != ~0U)
+    return Entry.getValue();
+  
+  // Otherwise, assign this the next available ID.
+  Entry.setValue(FilenamesByID.size());
+  FilenamesByID.push_back(&Entry);
+  return FilenamesByID.size()-1;
+}
+
+/// getLineTableFilenameID - Return the uniqued ID for the specified filename.
+/// 
+unsigned SourceManager::getLineTableFilenameID(const char *Ptr, unsigned Len) {
+  if (LineTable == 0)
+    LineTable = new LineTableInfo();
+  return LineTable->getLineTableFilenameID(Ptr, Len);
+}
+
+
+//===--------------------------------------------------------------------===//
 // Private 'Create' methods.
 //===--------------------------------------------------------------------===//
 
+SourceManager::~SourceManager() {
+  delete LineTable;
+}
+
+void SourceManager::clearIDTables() {
+  MainFileID = FileID();
+  SLocEntryTable.clear();
+  LastLineNoFileIDQuery = FileID();
+  LastLineNoContentCache = 0;
+  LastFileIDLookup = FileID();
+  
+  if (LineTable)
+    LineTable->clear();
+  
+  // Use up FileID #0 as an invalid instantiation.
+  NextOffset = 0;
+  createInstantiationLoc(SourceLocation(), SourceLocation(), 1);
+}
+
 /// getOrCreateContentCache - Create or return a cached ContentCache for the
 /// specified file.
 const ContentCache *

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=63010&r1=63009&r2=63010&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Mon Jan 26 01:57:50 2009
@@ -621,6 +621,7 @@
   if (LineNo >= LineLimit)
     Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
   
+  int FilenameID = -1;
   Token StrTok;
   Lex(StrTok);
 
@@ -633,6 +634,18 @@
     DiscardUntilEndOfDirective();
     return;
   } else {
+    // Parse and validate the string, converting it into a unique ID.
+    StringLiteralParser Literal(&StrTok, 1, *this);
+    assert(!Literal.AnyWide && "Didn't allow wide strings in");
+    if (Literal.hadError)
+      return DiscardUntilEndOfDirective();
+    if (Literal.Pascal) {
+      Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
+      return DiscardUntilEndOfDirective();
+    }
+    FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString(),
+                                                  Literal.GetStringLength());
+    
     // Verify that there is nothing after the string, other than EOM.
     CheckEndOfDirective("#line");
   }
@@ -671,6 +684,7 @@
   // We must have 3 if there are still flags.
   if (FlagVal != 3) {
     PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
+    PP.DiscardUntilEndOfDirective();
     return true;
   }
   
@@ -684,6 +698,7 @@
   // We must have 4 if there is yet another flag.
   if (FlagVal != 4) {
     PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
+    PP.DiscardUntilEndOfDirective();
     return true;
   }
   
@@ -694,6 +709,7 @@
 
   // There are no more valid flags here.
   PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
+  PP.DiscardUntilEndOfDirective();
   return true;
 }
 
@@ -717,22 +733,32 @@
   
   bool IsFileEntry = false, IsFileExit = false;
   bool IsSystemHeader = false, IsExternCHeader = false;
-  
+  int FilenameID = -1;
+
   // If the StrTok is "eom", then it wasn't present.  Otherwise, it must be a
   // string followed by eom.
   if (StrTok.is(tok::eom)) 
     ; // ok
   else if (StrTok.isNot(tok::string_literal)) {
     Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
-    DiscardUntilEndOfDirective();
-    return;
+    return DiscardUntilEndOfDirective();
   } else {
+    // Parse and validate the string, converting it into a unique ID.
+    StringLiteralParser Literal(&StrTok, 1, *this);
+    assert(!Literal.AnyWide && "Didn't allow wide strings in");
+    if (Literal.hadError)
+      return DiscardUntilEndOfDirective();
+    if (Literal.Pascal) {
+      Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
+      return DiscardUntilEndOfDirective();
+    }
+    FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString(),
+                                                  Literal.GetStringLength());
+    
     // If a filename was present, read any flags that are present.
     if (ReadLineMarkerFlags(IsFileEntry, IsFileExit, 
-                            IsSystemHeader, IsExternCHeader, *this)) {
-      DiscardUntilEndOfDirective();
+                            IsSystemHeader, IsExternCHeader, *this))
       return;
-    }
   }
   
   // FIXME: do something with the #line info.





More information about the cfe-commits mailing list