| //===--- 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/ASTConsumers.h" |
| #include "clang/Frontend/PCHWriter.h" |
| #include "clang/Sema/SemaConsumer.h" |
| #include "clang/AST/ASTContext.h" |
| #include "clang/AST/ASTConsumer.h" |
| #include "clang/Lex/Preprocessor.h" |
| #include "clang/Basic/FileManager.h" |
| #include "llvm/Bitcode/BitstreamWriter.h" |
| #include "llvm/Support/raw_ostream.h" |
| #include <string> |
| |
| using namespace clang; |
| |
| namespace { |
| class PCHGenerator : public SemaConsumer { |
| const Preprocessor &PP; |
| const char *isysroot; |
| llvm::raw_ostream *Out; |
| Sema *SemaPtr; |
| MemorizeStatCalls *StatCalls; // owned by the FileManager |
| |
| public: |
| explicit PCHGenerator(const Preprocessor &PP, |
| const char *isysroot, |
| llvm::raw_ostream *Out); |
| virtual void InitializeSema(Sema &S) { SemaPtr = &S; } |
| virtual void HandleTranslationUnit(ASTContext &Ctx); |
| }; |
| } |
| |
| PCHGenerator::PCHGenerator(const Preprocessor &PP, |
| const char *isysroot, |
| llvm::raw_ostream *OS) |
| : PP(PP), isysroot(isysroot), Out(OS), SemaPtr(0), StatCalls(0) { |
| |
| // Install a stat() listener to keep track of all of the stat() |
| // calls. |
| StatCalls = new MemorizeStatCalls; |
| PP.getFileManager().addStatCache(StatCalls, /*AtBeginning=*/true); |
| } |
| |
| void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { |
| if (PP.getDiagnostics().hasErrorOccurred()) |
| return; |
| |
| // Write the PCH contents into a buffer |
| std::vector<unsigned char> Buffer; |
| llvm::BitstreamWriter Stream(Buffer); |
| PCHWriter Writer(Stream); |
| |
| // Emit the PCH file |
| assert(SemaPtr && "No Sema?"); |
| Writer.WritePCH(*SemaPtr, StatCalls, isysroot); |
| |
| // Write the generated bitstream to "Out". |
| Out->write((char *)&Buffer.front(), Buffer.size()); |
| |
| // Make sure it hits disk now. |
| Out->flush(); |
| } |
| |
| ASTConsumer *clang::CreatePCHGenerator(const Preprocessor &PP, |
| llvm::raw_ostream *OS, |
| const char *isysroot) { |
| return new PCHGenerator(PP, isysroot, OS); |
| } |