[cfe-commits] r45232 - in /cfe/trunk/Driver: ASTConsumers.cpp ASTConsumers.h

Ted Kremenek kremenek at apple.com
Wed Dec 19 15:49:37 PST 2007


Author: kremenek
Date: Wed Dec 19 17:49:37 2007
New Revision: 45232

URL: http://llvm.org/viewvc/llvm-project?rev=45232&view=rev
Log:
Split serialization ASTConsumers into two consumers: SingleFileSerializer and
BuildSerializer. The former serializes a single translation unit to a
corresponding .ast file. The second serializes ASTs to a common emission
direction.  The latter is not fully implemented yet.

Modified:
    cfe/trunk/Driver/ASTConsumers.cpp
    cfe/trunk/Driver/ASTConsumers.h

Modified: cfe/trunk/Driver/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.cpp?rev=45232&r1=45231&r2=45232&view=diff

==============================================================================
--- cfe/trunk/Driver/ASTConsumers.cpp (original)
+++ cfe/trunk/Driver/ASTConsumers.cpp Wed Dec 19 17:49:37 2007
@@ -587,7 +587,8 @@
       } else {
         assert(isa<TypeDecl>(D) && "Only expected type decls here");
         // don't codegen for now, eventually pass down for debug info.
-        //std::cerr << "Read top-level typedef decl: '" << D->getName() << "'\n";
+        //std::cerr << "Read top-level typedef decl: '"
+        //    << D->getName() << "'\n";
       }
     }
     
@@ -601,7 +602,8 @@
   }; 
 } // end anonymous namespace
 
-ASTConsumer *clang::CreateLLVMEmitter(Diagnostic &Diags, const LangOptions &Features) {
+ASTConsumer *clang::CreateLLVMEmitter(Diagnostic &Diags, 
+                                      const LangOptions &Features) {
   return new LLVMEmitter(Diags, Features);
 }
 
@@ -609,51 +611,87 @@
 // AST Serializer
 
 namespace {
-  class ASTSerializer : public ASTConsumer {
-    Diagnostic &Diags;
-    TranslationUnit TU;
-    const llvm::sys::Path FName;
-  public:
-    ASTSerializer(const llvm::sys::Path& F, Diagnostic &diags,
-                  const LangOptions &LO)
-    : Diags(diags), TU(LO), FName(F) {}
+
+class ASTSerializer : public ASTConsumer {
+protected:
+  Diagnostic &Diags;
+  TranslationUnit TU;
+public:
+  ASTSerializer(Diagnostic& diags, const LangOptions& LO)
+    : Diags(diags), TU(LO) {}
+  
+  virtual void Initialize(ASTContext &Context) {
+    TU.setContext(&Context);
+  }
+  
+  virtual void HandleTopLevelDecl(Decl *D) {
+    if (Diags.hasErrorOccurred())
+      return;
     
-    virtual void Initialize(ASTContext &Context) {
-      TU.setContext(&Context);
-    }
+    TU.AddTopLevelDecl(D);
+  }
+};
     
-    virtual void HandleTopLevelDecl(Decl *D) {
-      // If an error occurred, stop code generation, but continue parsing and
-      // semantic analysis (to ensure all warnings and errors are emitted).
-      if (Diags.hasErrorOccurred())
-        return;
-      
-      TU.AddTopLevelDecl(D);
-    }
-    
-    ~ASTSerializer() { EmitASTBitcodeFile(TU,FName); }
-  }; 
+class SingleFileSerializer : public ASTSerializer {
+  const llvm::sys::Path FName;
+public:
+  SingleFileSerializer(const llvm::sys::Path& F, Diagnostic &diags,
+                          const LangOptions &LO)
+  : ASTSerializer(diags,LO), FName(F) {}    
+  
+  ~SingleFileSerializer() {
+    EmitASTBitcodeFile(TU,FName);
+  }
+};
+
+class BuildSerializer : public ASTSerializer {
+  llvm::sys::Path EmitDir;  
+public:
+  BuildSerializer(const llvm::sys::Path& dir, Diagnostic &diags,
+                  const LangOptions &LO)
+  : ASTSerializer(diags,LO), EmitDir(dir) {}
+  
+  ~BuildSerializer() { assert (false && "not implemented."); }
+};
+  
+  
 } // end anonymous namespace
 
 
 ASTConsumer* clang::CreateASTSerializer(const std::string& InFile,
+                                        const std::string& OutputFile,
                                         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("/");
-  
-  if (idx != std::string::npos && idx == InFile.size()-1)
-    return NULL;
   
-  std::string TargetPrefix( idx == std::string::npos ?
-                           InFile : InFile.substr(idx+1));
-  
-  llvm::sys::Path FName = llvm::sys::Path((TargetPrefix + ".ast").c_str());
+  if (OutputFile.size()) {
+    // The user specified an AST-emission directory.  Determine if the path
+    // is absolute.    
+    llvm::sys::Path EmitDir(OutputFile);
+    
+    if (!EmitDir.isAbsolute()) {
+      llvm::cerr << 
+        "error: Output directory for --serialize must be an absolute path.\n";
+      
+      return NULL;
+    }
+    
+    // Create the directory if it does not exist.
+    EmitDir.createDirectoryOnDisk(true);
+    if (!EmitDir.canWrite() || !EmitDir.isDirectory()) {
+      llvm::cerr <<
+        "error: Could not create output directory for --serialize.\n";
+      
+      return NULL;
+    }
+    
+    return new BuildSerializer(EmitDir, Diags, Features);
+  }
+
+  // The user did not specify an output directory for serialized ASTs.
+  // Serialize the translation to a single file whose name is the same
+  // as the input file with the ".ast" extension appended.
   
-  return new ASTSerializer(FName, Diags, Features);
+  llvm::sys::Path FName(InFile.c_str());
+  FName.appendComponent("ast");
+  return new SingleFileSerializer(FName, Diags, Features);  
 }

Modified: cfe/trunk/Driver/ASTConsumers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.h?rev=45232&r1=45231&r2=45232&view=diff

==============================================================================
--- cfe/trunk/Driver/ASTConsumers.h (original)
+++ cfe/trunk/Driver/ASTConsumers.h Wed Dec 19 17:49:37 2007
@@ -47,7 +47,8 @@
                                      FileManager& FMgr, 
                                      const LangOptions &LOpts);
   
-ASTConsumer *CreateASTSerializer(const std::string& InFile, 
+ASTConsumer *CreateASTSerializer(const std::string& InFile,
+                                 const std::string& EmitDir,
                                  Diagnostic &Diags,
                                  const LangOptions &LOpts);
 





More information about the cfe-commits mailing list