diff options
Diffstat (limited to 'clang/tools')
-rw-r--r-- | clang/tools/clang-cc/ASTConsumers.cpp | 141 | ||||
-rw-r--r-- | clang/tools/clang-cc/ASTConsumers.h | 7 | ||||
-rw-r--r-- | clang/tools/clang-cc/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/tools/clang-cc/SerializationTest.cpp | 226 | ||||
-rw-r--r-- | clang/tools/clang-cc/clang-cc.cpp | 82 |
5 files changed, 1 insertions, 456 deletions
diff --git a/clang/tools/clang-cc/ASTConsumers.cpp b/clang/tools/clang-cc/ASTConsumers.cpp index 52aafd35c02..b0f06fad244 100644 --- a/clang/tools/clang-cc/ASTConsumers.cpp +++ b/clang/tools/clang-cc/ASTConsumers.cpp @@ -1000,144 +1000,3 @@ public: ASTConsumer *clang::CreateInheritanceViewer(const std::string& clsname) { return new InheritanceViewer(clsname); } - -//===----------------------------------------------------------------------===// -// AST Serializer - -namespace { - -class ASTSerializer : public ASTConsumer { -protected: - Diagnostic& Diags; - -public: - ASTSerializer(Diagnostic& diags) : Diags(diags) {} -}; - -class SingleFileSerializer : public ASTSerializer { - const llvm::sys::Path FName; -public: - SingleFileSerializer(const llvm::sys::Path& F, Diagnostic& diags) - : ASTSerializer(diags), FName(F) {} - - virtual void HandleTranslationUnit(ASTContext &Ctx) { - if (Diags.hasErrorOccurred()) - return; - - // Reserve 256K for bitstream buffer. - std::vector<unsigned char> Buffer; - Buffer.reserve(256*1024); - - Ctx.EmitASTBitcodeBuffer(Buffer); - - // Write the bits to disk. - if (FILE* fp = fopen(FName.c_str(),"wb")) { - fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp); - fclose(fp); - } - } -}; - -class BuildSerializer : public ASTSerializer { - llvm::sys::Path EmitDir; -public: - BuildSerializer(const llvm::sys::Path& dir, Diagnostic& diags) - : ASTSerializer(diags), EmitDir(dir) {} - - virtual void HandleTranslationUnit(ASTContext &Ctx); -}; -} // end anonymous namespace - - -void BuildSerializer::HandleTranslationUnit(ASTContext &Ctx) { - if (Diags.hasErrorOccurred()) - return; - - SourceManager& SourceMgr = Ctx.getSourceManager(); - FileID ID = SourceMgr.getMainFileID(); - assert(!ID.isInvalid() && "MainFileID not set!"); - const FileEntry* FE = SourceMgr.getFileEntryForID(ID); - assert(FE && "No FileEntry for main file."); - - // FIXME: This is not portable to Windows. - // FIXME: This logic should probably be moved elsewhere later. - - llvm::sys::Path FName(EmitDir); - - std::vector<char> buf; - buf.reserve(strlen(FE->getName())+100); - - sprintf(&buf[0], "dev_%llx", (unsigned long long) FE->getDevice()); - FName.appendComponent(&buf[0]); - FName.createDirectoryOnDisk(true); - if (!FName.canWrite() || !FName.isDirectory()) { - assert (false && "Could not create 'device' serialization directory."); - return; - } - - sprintf(&buf[0], "%s-%llX.ast", FE->getName(), - (unsigned long long) FE->getInode()); - FName.appendComponent(&buf[0]); - - - // Reserve 256K for bitstream buffer. - std::vector<unsigned char> Buffer; - Buffer.reserve(256*1024); - - Ctx.EmitASTBitcodeBuffer(Buffer); - - // Write the bits to disk. - if (FILE* fp = fopen(FName.c_str(),"wb")) { - fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp); - fclose(fp); - } - - // Now emit the sources. - -} - - -ASTConsumer* clang::CreateASTSerializer(const std::string& InFile, - const std::string& OutputFile, - Diagnostic &Diags) { - - if (OutputFile.size()) { - if (InFile == "-") { - llvm::cerr << - "error: Cannot use --serialize with -o for source read from STDIN.\n"; - return NULL; - } - - // 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; - } - - // FIXME: We should probably only allow using BuildSerializer when - // the ASTs come from parsed source files, and not from .ast files. - return new BuildSerializer(EmitDir, Diags); - } - - // 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. - - llvm::sys::Path FName(InFile.c_str()); - FName.appendSuffix("ast"); - return new SingleFileSerializer(FName, Diags); -} diff --git a/clang/tools/clang-cc/ASTConsumers.h b/clang/tools/clang-cc/ASTConsumers.h index 7c37266e46e..13fd4f4ed82 100644 --- a/clang/tools/clang-cc/ASTConsumers.h +++ b/clang/tools/clang-cc/ASTConsumers.h @@ -61,13 +61,6 @@ ASTConsumer *CreateBackendConsumer(BackendAction Action, ASTConsumer* CreateHTMLPrinter(const std::string &OutFile, Diagnostic &D, Preprocessor *PP, PreprocessorFactory *PPF); -ASTConsumer *CreateSerializationTest(Diagnostic &Diags, - FileManager &FMgr); - -ASTConsumer *CreateASTSerializer(const std::string &InFile, - const std::string &EmitDir, - Diagnostic &Diags); - ASTConsumer *CreatePCHGenerator(const Preprocessor &PP, const std::string &OutFile); diff --git a/clang/tools/clang-cc/CMakeLists.txt b/clang/tools/clang-cc/CMakeLists.txt index 6485e221c0d..4ebebb74f5a 100644 --- a/clang/tools/clang-cc/CMakeLists.txt +++ b/clang/tools/clang-cc/CMakeLists.txt @@ -37,6 +37,5 @@ add_clang_executable(clang-cc RewriteMacros.cpp RewriteObjC.cpp RewriteTest.cpp - SerializationTest.cpp Warnings.cpp ) diff --git a/clang/tools/clang-cc/SerializationTest.cpp b/clang/tools/clang-cc/SerializationTest.cpp deleted file mode 100644 index 708328db77d..00000000000 --- a/clang/tools/clang-cc/SerializationTest.cpp +++ /dev/null @@ -1,226 +0,0 @@ -//===--- SerializationTest.cpp - Experimental Object Serialization --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements prototype code for serialization of objects in clang. -// It is not intended yet for public use, but simply is a placeholder to -// experiment with new serialization features. Serialization will eventually -// be integrated as a proper component of the clang libraries. -// -//===----------------------------------------------------------------------===// - -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/CFG.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclGroup.h" -#include "clang-cc.h" -#include "ASTConsumers.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/Support/Streams.h" -#include "llvm/System/Path.h" -#include <fstream> -#include <cstring> -using namespace clang; - -//===----------------------------------------------------------------------===// -// Driver code. -//===----------------------------------------------------------------------===// - -namespace { - -class SerializationTest : public ASTConsumer { - Diagnostic &Diags; - FileManager &FMgr; -public: - SerializationTest(Diagnostic &d, FileManager& fmgr) - : Diags(d), FMgr(fmgr) {} - - ~SerializationTest() {} - - virtual void HandleTranslationUnit(ASTContext &C); - -private: - bool Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint, - ASTContext &Ctx); - - bool Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint); -}; - -} // end anonymous namespace - -ASTConsumer* -clang::CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr) { - return new SerializationTest(Diags, FMgr); -} - - -bool SerializationTest::Serialize(llvm::sys::Path& Filename, - llvm::sys::Path& FNameDeclPrint, - ASTContext &Ctx) { - { - // Pretty-print the decls to a temp file. - std::string Err; - llvm::raw_fd_ostream DeclPP(FNameDeclPrint.c_str(), true, Err); - assert (Err.empty() && "Could not open file for printing out decls."); - llvm::OwningPtr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP)); - - TranslationUnitDecl *TUD = Ctx.getTranslationUnitDecl(); - for (DeclContext::decl_iterator I = TUD->decls_begin(Ctx), - E = TUD->decls_end(Ctx); - I != E; ++I) - FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I)); - } - - // Serialize the translation unit. - - // Reserve 256K for bitstream buffer. - std::vector<unsigned char> Buffer; - Buffer.reserve(256*1024); - - Ctx.EmitASTBitcodeBuffer(Buffer); - - // Write the bits to disk. - if (FILE* fp = fopen(Filename.c_str(),"wb")) { - fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp); - fclose(fp); - return true; - } - - return false; -} - -bool SerializationTest::Deserialize(llvm::sys::Path& Filename, - llvm::sys::Path& FNameDeclPrint) { - - // Deserialize the translation unit. - ASTContext *NewCtx; - - { - // Create the memory buffer that contains the contents of the file. - llvm::OwningPtr<llvm::MemoryBuffer> - MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str())); - - if (!MBuffer) - return false; - - NewCtx = ASTContext::ReadASTBitcodeBuffer(*MBuffer, FMgr); - } - - if (!NewCtx) - return false; - - { - // Pretty-print the deserialized decls to a temp file. - std::string Err; - llvm::raw_fd_ostream DeclPP(FNameDeclPrint.c_str(), true, Err); - assert (Err.empty() && "Could not open file for printing out decls."); - llvm::OwningPtr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP)); - - TranslationUnitDecl *TUD = NewCtx->getTranslationUnitDecl(); - for (DeclContext::decl_iterator I = TUD->decls_begin(*NewCtx), - E = TUD->decls_end(*NewCtx); - I != E; ++I) - FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I)); - } - - delete NewCtx; - - return true; -} - -namespace { - class TmpDirJanitor { - llvm::sys::Path& Dir; - public: - explicit TmpDirJanitor(llvm::sys::Path& dir) : Dir(dir) {} - - ~TmpDirJanitor() { - llvm::cerr << "Removing: " << Dir.c_str() << '\n'; - Dir.eraseFromDisk(true); - } - }; -} - -void SerializationTest::HandleTranslationUnit(ASTContext &Ctx) { - - std::string ErrMsg; - llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg); - - if (Dir.isEmpty()) { - llvm::cerr << "Error: " << ErrMsg << "\n"; - return; - } - - TmpDirJanitor RemoveTmpOnExit(Dir); - - llvm::sys::Path FNameDeclBefore = Dir; - FNameDeclBefore.appendComponent("test.decl_before.txt"); - - if (FNameDeclBefore.makeUnique(true, &ErrMsg)) { - llvm::cerr << "Error: " << ErrMsg << "\n"; - return; - } - - llvm::sys::Path FNameDeclAfter = Dir; - FNameDeclAfter.appendComponent("test.decl_after.txt"); - - if (FNameDeclAfter.makeUnique(true, &ErrMsg)) { - llvm::cerr << "Error: " << ErrMsg << "\n"; - return; - } - - llvm::sys::Path ASTFilename = Dir; - ASTFilename.appendComponent("test.ast"); - - if (ASTFilename.makeUnique(true, &ErrMsg)) { - llvm::cerr << "Error: " << ErrMsg << "\n"; - return; - } - - // Serialize and then deserialize the ASTs. - bool status = Serialize(ASTFilename, FNameDeclBefore, Ctx); - assert (status && "Serialization failed."); - status = Deserialize(ASTFilename, FNameDeclAfter); - assert (status && "Deserialization failed."); - - // Read both pretty-printed files and compare them. - - using llvm::MemoryBuffer; - - llvm::OwningPtr<MemoryBuffer> - MBufferSer(MemoryBuffer::getFile(FNameDeclBefore.c_str())); - - if(!MBufferSer) { - llvm::cerr << "ERROR: Cannot read pretty-printed file (pre-pickle).\n"; - return; - } - - llvm::OwningPtr<MemoryBuffer> - MBufferDSer(MemoryBuffer::getFile(FNameDeclAfter.c_str())); - - if(!MBufferDSer) { - llvm::cerr << "ERROR: Cannot read pretty-printed file (post-pickle).\n"; - return; - } - - const char *p1 = MBufferSer->getBufferStart(); - const char *e1 = MBufferSer->getBufferEnd(); - const char *p2 = MBufferDSer->getBufferStart(); - const char *e2 = MBufferDSer->getBufferEnd(); - - if (MBufferSer->getBufferSize() == MBufferDSer->getBufferSize()) - for ( ; p1 != e1 ; ++p1, ++p2 ) - if (*p1 != *p2) break; - - if (p1 != e1 || p2 != e2 ) - llvm::cerr << "ERROR: Pretty-printed files are not the same.\n"; - else - llvm::cerr << "SUCCESS: Pretty-printed files are the same.\n"; -} diff --git a/clang/tools/clang-cc/clang-cc.cpp b/clang/tools/clang-cc/clang-cc.cpp index 37233134dad..af8b5b62437 100644 --- a/clang/tools/clang-cc/clang-cc.cpp +++ b/clang/tools/clang-cc/clang-cc.cpp @@ -180,13 +180,11 @@ enum ProgActions { EmitLLVM, // Emit a .ll file. EmitBC, // Emit a .bc file. EmitLLVMOnly, // Generate LLVM IR, but do not - SerializeAST, // Emit a .ast file. EmitHTML, // Translate input source into HTML. ASTPrint, // Parse ASTs and print them. ASTDump, // Parse ASTs and dump them. ASTView, // Parse ASTs and view them in Graphviz. PrintDeclContext, // Print DeclContext and their Decls. - TestSerialization, // Run experimental serialization code. ParsePrintCallbacks, // Parse and print each callback. ParseSyntaxOnly, // Parse and perform semantic analysis. ParseNoop, // Parse with noop callbacks. @@ -234,8 +232,6 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore, "Generate pre-tokenized header file"), clEnumValN(GeneratePCH, "emit-pch", "Generate pre-compiled header file"), - clEnumValN(TestSerialization, "test-pickling", - "Run prototype serialization code"), clEnumValN(EmitAssembly, "S", "Emit native assembly code"), clEnumValN(EmitLLVM, "emit-llvm", @@ -244,8 +240,6 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore, "Build ASTs then convert to LLVM, emit .bc file"), clEnumValN(EmitLLVMOnly, "emit-llvm-only", "Build ASTs and convert to LLVM, discarding output"), - clEnumValN(SerializeAST, "serialize", - "Build ASTs and emit .ast file"), clEnumValN(RewriteTest, "rewrite-test", "Rewriter playground"), clEnumValN(RewriteObjC, "rewrite-objc", @@ -262,7 +256,7 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore, static llvm::cl::opt<std::string> OutputFile("o", llvm::cl::value_desc("path"), - llvm::cl::desc("Specify output file (for --serialize, this is a directory)")); + llvm::cl::desc("Specify output file")); //===----------------------------------------------------------------------===// @@ -1559,9 +1553,6 @@ static ASTConsumer *CreateASTConsumer(const std::string& InFile, case InheritanceView: return CreateInheritanceViewer(InheritanceViewCls); - case TestSerialization: - return CreateSerializationTest(Diag, FileMgr); - case EmitAssembly: case EmitLLVM: case EmitBC: @@ -1582,12 +1573,7 @@ static ASTConsumer *CreateASTConsumer(const std::string& InFile, InFile, OutputFile); } - case SerializeAST: - // FIXME: Allow user to tailor where the file is written. - return CreateASTSerializer(InFile, OutputFile, Diag); - case GeneratePCH: - assert(PP && "Generate PCH doesn't work from serialized file yet"); return CreatePCHGenerator(*PP, OutputFile); case RewriteObjC: @@ -1841,70 +1827,9 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, Consumer.take(); } -static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag, - FileManager& FileMgr) { - - if (VerifyDiagnostics) { - fprintf(stderr, "-verify does not yet work with serialized ASTs.\n"); - exit (1); - } - - llvm::sys::Path Filename(InFile); - - if (!Filename.isValid()) { - fprintf(stderr, "serialized file '%s' not available.\n",InFile.c_str()); - exit (1); - } - - llvm::OwningPtr<ASTContext> Ctx; - - // Create the memory buffer that contains the contents of the file. - llvm::OwningPtr<llvm::MemoryBuffer> - MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str())); - - if (MBuffer) - Ctx.reset(ASTContext::ReadASTBitcodeBuffer(*MBuffer, FileMgr)); - - if (!Ctx) { - fprintf(stderr, "error: file '%s' could not be deserialized\n", - InFile.c_str()); - exit (1); - } - - // Observe that we use the source file name stored in the deserialized - // translation unit, rather than InFile. - llvm::OwningPtr<ASTConsumer> - Consumer(CreateASTConsumer(InFile, Diag, FileMgr, Ctx->getLangOptions(), - 0, 0)); - - if (!Consumer) { - fprintf(stderr, "Unsupported program action with serialized ASTs!\n"); - exit (1); - } - - Consumer->Initialize(*Ctx); - - // FIXME: We need to inform Consumer about completed TagDecls as well. - TranslationUnitDecl *TUD = Ctx->getTranslationUnitDecl(); - for (DeclContext::decl_iterator I = TUD->decls_begin(*Ctx), - E = TUD->decls_end(*Ctx); - I != E; ++I) - Consumer->HandleTopLevelDecl(DeclGroupRef(*I)); -} - - static llvm::cl::list<std::string> InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input files>")); -static bool isSerializedFile(const std::string& InFile) { - if (InFile.size() < 4) - return false; - - const char* s = InFile.c_str()+InFile.size()-4; - return s[0] == '.' && s[1] == 'a' && s[2] == 's' && s[3] == 't'; -} - - int main(int argc, char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); @@ -1991,11 +1916,6 @@ int main(int argc, char **argv) { for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) { const std::string &InFile = InputFilenames[i]; - if (isSerializedFile(InFile)) { - ProcessSerializedFile(InFile,Diags,FileMgr); - continue; - } - /// Create a SourceManager object. This tracks and owns all the file /// buffers allocated to a translation unit. if (!SourceMgr) |