]> granicus.if.org Git - clang/commitdiff
Removed storing inode and device number in TranslationUnit.
authorTed Kremenek <kremenek@apple.com>
Wed, 19 Dec 2007 19:27:38 +0000 (19:27 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 19 Dec 2007 19:27:38 +0000 (19:27 +0000)
Added "SourceFile" string to TranslationUnit to record corresponding
source file.

Updated serialization of TranslationUnits and logic in the driver to
correctly pass the source file information to the serializer.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45211 91177308-0d34-0410-b5e6-96231b3b80d8

AST/TranslationUnit.cpp
Driver/ASTConsumers.cpp
Driver/ASTConsumers.h
Driver/SerializationTest.cpp
Driver/clang.cpp
include/clang/AST/TranslationUnit.h

index 7cf398b0afac2d652a56881f35861e2d12e9c070..41d9c79f89a32e5294192b7e236e6a33f15d9809 100644 (file)
 
 #include <stdio.h>
 
-namespace {
-  enum { BasicMetadataBlock = 1,
-         ASTContextBlock = 2,
-         DeclsBlock = 3 };
-}
-
 using namespace clang;
 
+enum { BasicMetadataBlock = 1,
+       ASTContextBlock = 2,
+       DeclsBlock = 3 };
+
+
 bool clang::EmitASTBitcodeFile(const TranslationUnit& TU, 
                                const llvm::sys::Path& Filename) {  
 
@@ -101,6 +100,10 @@ void TranslationUnit::Emit(llvm::Serializer& Sezr) const {
   // around to the block for the Selectors during deserialization.
   Sezr.EnterBlock();
   
+  // Emit the name of the source file.
+  Sezr.EmitCStr(SourceFile.c_str());
+  Sezr.FlushRecord();
+  
   // Emit the SourceManager.
   Sezr.Emit(Context->getSourceManager());
   
@@ -182,6 +185,12 @@ TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr,
   
   FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock);
   assert (FoundBlock);
+  
+  { // Read the SourceFile.
+    char* SName = Dezr.ReadCStr(NULL,0,true);
+    TU->SourceFile = SName;
+    delete [] SName;
+  }
 
   // Read the SourceManager.
   SourceManager::CreateAndRegister(Dezr,FMgr);
index 184f29a6061fd3f609f1f2c4287d8aaaefaf62f9..202e030419fce6fb4e2b12924d66398fd06bc192 100644 (file)
@@ -614,10 +614,10 @@ namespace {
     TranslationUnit TU;
     const llvm::sys::Path FName;
   public:
-    ASTSerializer(const llvm::sys::Path& F, Diagnostic &diags,
+    ASTSerializer(const std::string& SourceFile,
+                  const llvm::sys::Path& F, Diagnostic &diags,
                   const LangOptions &LO)
-    : Diags(diags), TU(LO), FName(F) {}
-
+    : Diags(diags), TU(SourceFile,LO), FName(F) {}
     
     virtual void Initialize(ASTContext &Context, unsigned MainFileID) {
       TU.setContext(&Context);
@@ -637,20 +637,24 @@ namespace {
 } // end anonymous namespace
 
 
-ASTConsumer* clang::CreateASTSerializer(const std::string& InFile,
+ASTConsumer* clang::CreateASTSerializer(const std::string& SourceFile,
                                         Diagnostic &Diags,
                                         const LangOptions &Features) {
-    
+  // FIXME: If the translation unit we are serializing came was itself
+  //        deserialized from disk, we may overwrite that file.  This
+  //        is only a temporary bug, since the code in this function will
+  //        be completely replaced momentarily.
+  
   // FIXME: This is a hack: "/" separator not portable.
-  std::string::size_type idx = InFile.rfind("/");
+  std::string::size_type idx = SourceFile.rfind("/");
   
-  if (idx != std::string::npos && idx == InFile.size()-1)
+  if (idx != std::string::npos && idx == SourceFile.size()-1)
     return NULL;
   
   std::string TargetPrefix( idx == std::string::npos ?
-                           InFile : InFile.substr(idx+1));
+                           SourceFile : SourceFile.substr(idx+1));
   
   llvm::sys::Path FName = llvm::sys::Path((TargetPrefix + ".ast").c_str());
   
-  return new ASTSerializer(FName, Diags, Features);
+  return new ASTSerializer(SourceFile, FName, Diags, Features);
 }
index 05473b155852be7c00abfb718bb2ecb45b335e54..44f763e0ec5144152739c538cc2d762b4773c03b 100644 (file)
@@ -34,10 +34,11 @@ ASTConsumer *CreateDeadStoreChecker(Diagnostic &Diags);
 ASTConsumer *CreateUnitValsChecker(Diagnostic &Diags);
 ASTConsumer *CreateLLVMEmitter(Diagnostic &Diags, const LangOptions &Features);
 ASTConsumer *CreateCodeRewriterTest(Diagnostic &Diags);
-ASTConsumer *CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr, 
+ASTConsumer *CreateSerializationTest(const std::string& SourceFile,
+                                     Diagnostic &Diags, FileManager& FMgr, 
                                      const LangOptions &LOpts);
   
-ASTConsumer *CreateASTSerializer(const std::string& InFile,
+ASTConsumer *CreateASTSerializer(const std::string& SourceFile,
                                  Diagnostic &Diags, const LangOptions &LOpts);
 
 } // end clang namespace
index 59b36e75a8c0aff5da96c5f8a1876e766392ba20..acb91642d32d43c90553882e4834c02e24fb7a7a 100644 (file)
@@ -37,8 +37,9 @@ class SerializationTest : public ASTConsumer {
   Diagnostic &Diags;
   FileManager &FMgr;  
 public:  
-  SerializationTest(Diagnostic &d, FileManager& fmgr, const LangOptions& LOpts)
-                    : TU(LOpts), Diags(d), FMgr(fmgr) {}
+  SerializationTest(const std::string& SourceFile, Diagnostic &d,
+                    FileManager& fmgr, const LangOptions& LOpts)
+                    : TU(SourceFile, LOpts), Diags(d), FMgr(fmgr) {}
   
   ~SerializationTest();
 
@@ -49,6 +50,7 @@ public:
   virtual void HandleTopLevelDecl(Decl *D) {
     TU.AddTopLevelDecl(D);
   }
+  
 private:
   bool Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
   bool Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
@@ -57,9 +59,9 @@ private:
 } // end anonymous namespace
 
 ASTConsumer*
-clang::CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr,
-                               const LangOptions &LOpts) {  
-  return new SerializationTest(Diags,FMgr,LOpts);
+clang::CreateSerializationTest(const std::string& SourceFile, Diagnostic &Diags,
+                               FileManager& FMgr, const LangOptions &LOpts) {  
+  return new SerializationTest(SourceFile,Diags,FMgr,LOpts);
 }
 
 
index 8afd71833fd3f7696bbba431d1d20805555d5093..dc435f945a34b0bcd421dfc0cc6a53ee9ddc2251 100644 (file)
@@ -39,6 +39,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/System/Signals.h"
 #include "llvm/Config/config.h"
+#include "llvm/ADT/scoped_ptr.h"
 #include <memory>
 using namespace clang;
 
@@ -887,7 +888,7 @@ static void ParseFile(Preprocessor &PP, MinimalAction *PA, unsigned MainFileID){
 /// CreateASTConsumer - Create the ASTConsumer for the corresponding program
 ///  action.  These consumers can operate on both ASTs that are freshly
 ///  parsed from source files as well as those deserialized from Bitcode.
-static ASTConsumer* CreateASTConsumer(const std::string& InFile,
+static ASTConsumer* CreateASTConsumer(const std::string& SourceFile,
                                       Diagnostic& Diag, FileManager& FileMgr, 
                                       const LangOptions& LangOpts) {
   switch (ProgAction) {
@@ -917,14 +918,14 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
       return CreateUnitValsChecker(Diag);
       
     case TestSerialization:
-      return CreateSerializationTest(Diag, FileMgr, LangOpts);
+      return CreateSerializationTest(SourceFile, Diag, FileMgr, LangOpts);
       
     case EmitLLVM:
       return CreateLLVMEmitter(Diag, LangOpts);
       
     case SerializeAST:
       // FIXME: Allow user to tailor where the file is written.
-      return CreateASTSerializer(InFile, Diag, LangOpts);
+      return CreateASTSerializer(SourceFile, Diag, LangOpts);
       
     case RewriteTest:
       return CreateCodeRewriterTest(Diag);
@@ -934,7 +935,7 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
 /// ProcessInputFile - Process a single input file with the specified state.
 ///
 static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
-                             const std::string &InFile,
+                             const std::string &SourceFile,
                              TextDiagnostics &OurDiagnosticClient) {
 
   ASTConsumer* Consumer = NULL;
@@ -942,7 +943,7 @@ static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
   
   switch (ProgAction) {
   default:
-    Consumer = CreateASTConsumer(InFile, PP.getDiagnostics(),
+    Consumer = CreateASTConsumer(SourceFile, PP.getDiagnostics(),
                                  PP.getFileManager(),
                                  PP.getLangOptions());
     
@@ -1005,7 +1006,7 @@ static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
   }
   
   if (Stats) {
-    fprintf(stderr, "\nSTATISTICS FOR '%s':\n", InFile.c_str());
+    fprintf(stderr, "\nSTATISTICS FOR '%s':\n", SourceFile.c_str());
     PP.PrintStats();
     PP.getIdentifierTable().PrintStats();
     PP.getHeaderSearchInfo().PrintStats();
@@ -1036,7 +1037,7 @@ static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
     exit (1);
   }
   
-  TranslationUnit* TU = ReadASTBitcodeFile(Filename,FileMgr);
+  llvm::scoped_ptr<TranslationUnit> TU(ReadASTBitcodeFile(Filename,FileMgr));
   
   if (!TU) {
     fprintf(stderr, "error: file '%s' could not be deserialized\n", 
@@ -1044,8 +1045,11 @@ static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
     exit (1);
   }
   
-  ASTConsumer* Consumer = CreateASTConsumer(InFile,Diag,
-                                            FileMgr,TU->getLangOpts());
+  // Observe that we use the source file name stored in the deserialized
+  // translation unit, rather than InFile.
+  llvm::scoped_ptr<ASTConsumer>
+    Consumer(CreateASTConsumer(TU->getSourceFile(), Diag, FileMgr,
+                               TU->getLangOpts()));
   
   if (!Consumer) {      
     fprintf(stderr, "Unsupported program action with serialized ASTs!\n");
@@ -1053,12 +1057,10 @@ static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
   }
   
   // FIXME: only work on consumers that do not require MainFileID.
-  Consumer->Initialize(*TU->getContext(),0);
+  Consumer->Initialize(*TU->getContext(), 0);
   
   for (TranslationUnit::iterator I=TU->begin(), E=TU->end(); I!=E; ++I)
     Consumer->HandleTopLevelDecl(*I);
-
-  delete Consumer;
 }
 
 
index 40c8d1c5754c15cda9f2e72a08fac64b8fe0c90a..40034b7b83d311e4480130cabc58e6b851a2db8d 100644 (file)
@@ -17,6 +17,7 @@
 #include "llvm/Bitcode/SerializationFwd.h"
 #include "llvm/System/Path.h"
 #include <vector>
+#include <string>
 
 namespace clang {
  
@@ -30,30 +31,24 @@ class Decl;
 class FileEntry;
   
 class TranslationUnit {
-  // Information to help uniquely identify a translation unit on disk.
-  // We may also incorporate a UUID in the future.
-  uint64_t ino;
-  uint64_t dev;
-  const char* SourceFile;
-  
-  // The actual data of the translation unit.  
+  std::string SourceFile;
   LangOptions LangOpts;
   ASTContext* Context;
   std::vector<Decl*> TopLevelDecls;
 
   // The default ctor is only invoked during deserialization.
-  explicit TranslationUnit() : SourceFile(NULL), Context(NULL) {}
+  explicit TranslationUnit() : Context(NULL) {}
   
 public:
-  explicit TranslationUnit(const LangOptions& lopt)
-    : LangOpts(lopt), Context(NULL) {}
+  explicit TranslationUnit(const std::string& sourcefile, 
+                           const LangOptions& lopt)
+    : SourceFile(sourcefile), LangOpts(lopt), Context(NULL) {}
+  
   
-  explicit TranslationUnit(const LangOptions& lopt, ASTContext& context)
-    : LangOpts(lopt), Context(&context) {}
-
   void setContext(ASTContext* context) { Context = context; }
   ASTContext* getContext() const { return Context; }
   const LangOptions& getLangOpts() const { return LangOpts; }
+  const std::string& getSourceFile() const { return SourceFile; }
   
   /// Emit - Emit the translation unit to an arbitray bitcode stream.
   void Emit(llvm::Serializer& S) const;