diff options
Diffstat (limited to 'clang/tools/clang-cc')
-rw-r--r-- | clang/tools/clang-cc/ASTConsumers.h | 5 | ||||
-rw-r--r-- | clang/tools/clang-cc/GeneratePCH.cpp | 78 | ||||
-rw-r--r-- | clang/tools/clang-cc/clang-cc.cpp | 23 |
3 files changed, 106 insertions, 0 deletions
diff --git a/clang/tools/clang-cc/ASTConsumers.h b/clang/tools/clang-cc/ASTConsumers.h index 970dfecada0..e7bc962bd92 100644 --- a/clang/tools/clang-cc/ASTConsumers.h +++ b/clang/tools/clang-cc/ASTConsumers.h @@ -68,6 +68,11 @@ ASTConsumer *CreateASTSerializer(const std::string& InFile, const std::string& EmitDir, Diagnostic &Diags); +ASTConsumer *CreatePCHGenerator(Diagnostic &Diags, + const LangOptions &Features, + const std::string& InFile, + const std::string& OutFile); + ASTConsumer *CreateBlockRewriter(const std::string& InFile, const std::string& OutFile, Diagnostic &Diags, diff --git a/clang/tools/clang-cc/GeneratePCH.cpp b/clang/tools/clang-cc/GeneratePCH.cpp new file mode 100644 index 00000000000..a2333487188 --- /dev/null +++ b/clang/tools/clang-cc/GeneratePCH.cpp @@ -0,0 +1,78 @@ +//===--- GeneratePCH.cpp - AST Consumer for PCH Generation ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the CreatePCHGenerate function, which creates an +// ASTConsume that generates a PCH file. +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/PCHWriter.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTConsumer.h" +#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/System/Path.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Streams.h" +#include <string> + +using namespace clang; +using namespace llvm; + +namespace { + class VISIBILITY_HIDDEN PCHGenerator : public ASTConsumer { + Diagnostic &Diags; + std::string OutFile; + + public: + explicit PCHGenerator(Diagnostic &Diags, const std::string &OutFile) + : Diags(Diags), OutFile(OutFile) { } + + virtual void HandleTranslationUnit(ASTContext &Ctx); + }; +} + +void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { + if (Diags.hasErrorOccurred()) + return; + + // Write the PCH contents into a buffer + std::vector<unsigned char> Buffer; + BitstreamWriter Stream(Buffer); + PCHWriter Writer(Stream); + + // Emit the PCH file + Writer.WritePCH(Ctx); + + // Open up the PCH file. + std::string ErrMsg; + llvm::raw_fd_ostream Out(OutFile.c_str(), true, ErrMsg); + + if (!ErrMsg.empty()) { + llvm::errs() << "PCH error: " << ErrMsg << "\n"; + return; + } + + // Write the generated bitstream to "Out". + Out.write((char *)&Buffer.front(), Buffer.size()); + + // Make sure it hits disk now. + Out.flush(); +} + +namespace clang { + +ASTConsumer *CreatePCHGenerator(Diagnostic &Diags, + const LangOptions &Features, + const std::string& InFile, + const std::string& OutFile) { + return new PCHGenerator(Diags, OutFile); +} + +} diff --git a/clang/tools/clang-cc/clang-cc.cpp b/clang/tools/clang-cc/clang-cc.cpp index b10323ab735..f8c44d6f7dc 100644 --- a/clang/tools/clang-cc/clang-cc.cpp +++ b/clang/tools/clang-cc/clang-cc.cpp @@ -29,6 +29,7 @@ #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/InitHeaderSearch.h" #include "clang/Frontend/PathDiagnosticClients.h" +#include "clang/Frontend/PCHReader.h" #include "clang/Frontend/TextDiagnosticBuffer.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Analysis/PathDiagnostic.h" @@ -194,6 +195,7 @@ enum ProgActions { DumpRawTokens, // Dump out raw tokens. RunAnalysis, // Run one or more source code analyses. GeneratePTH, // Generate pre-tokenized header. + GeneratePCH, // Generate pre-compiled header. InheritanceView // View C++ inheritance for a specified class. }; @@ -229,6 +231,8 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore, "Print DeclContexts and their Decls"), clEnumValN(GeneratePTH, "emit-pth", "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", @@ -975,6 +979,10 @@ static llvm::cl::opt<std::string> ImplicitIncludePTH("include-pth", llvm::cl::value_desc("file"), llvm::cl::desc("Include file before parsing")); +static llvm::cl::opt<std::string> +ImplicitIncludePCH("include-pch", llvm::cl::value_desc("file"), + llvm::cl::desc("Include precompiled header file")); + // Append a #define line to Buf for Macro. Macro should be of the form XXX, // in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit // "#define XXX Y z W". To get a #define with no value, use "XXX=". @@ -1516,6 +1524,9 @@ static ASTConsumer *CreateASTConsumer(const std::string& InFile, // FIXME: Allow user to tailor where the file is written. return CreateASTSerializer(InFile, OutputFile, Diag); + case GeneratePCH: + return CreatePCHGenerator(Diag, LangOpts, InFile, OutputFile); + case RewriteObjC: return CreateCodeRewriterTest(InFile, OutputFile, Diag, LangOpts); @@ -1683,6 +1694,18 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, PP.getSelectorTable(), /* FreeMemory = */ !DisableFree)); + if (!ImplicitIncludePCH.empty()) { + // The user has asked us to include a precompiled header. Load + // the precompiled header into the AST context. + llvm::OwningPtr<PCHReader> Reader( + new clang::PCHReader(*ContextOwner.get())); + if (Reader->ReadPCH(ImplicitIncludePCH)) + return; + + llvm::OwningPtr<ExternalASTSource> Source(Reader.take()); + ContextOwner->setExternalSource(Source); + } + ParseAST(PP, Consumer.get(), *ContextOwner.get(), Stats); if (FixItRewrite) |