diff options
author | Adrian Prantl <aprantl@apple.com> | 2015-02-25 01:31:45 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2015-02-25 01:31:45 +0000 |
commit | 8bf7af3de80fe746cb39fe03b19e6e736183c1d8 (patch) | |
tree | 3631796942b357f01d486a34631e918d05db7b86 /clang/lib | |
parent | b6396eaef90c9f3dee42d8af918b93b6628b9f4a (diff) | |
download | bcm5719-llvm-8bf7af3de80fe746cb39fe03b19e6e736183c1d8.tar.gz bcm5719-llvm-8bf7af3de80fe746cb39fe03b19e6e736183c1d8.zip |
Wrap clang module files in a Mach-O, ELF, or COFF container.
This is a necessary prerequisite for debugging with modules.
The .pcm files become containers that hold the serialized AST which allows
us to store debug information in the module file that can be shared by all
object files that were built importing the module.
This reapplies r230044 with a fixed configure+make build and updated
dependencies and testcase requirements. Over the last iteration this
version adds
- missing target requirements for testcases that specify an x86 triple,
- a missing clangCodeGen.a dependency to libClang.a in the make build.
rdar://problem/19104245
llvm-svn: 230423
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CMakeLists.txt | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModuleContainer.cpp | 150 | ||||
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Frontend/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/Frontend/ChainedIncludesSource.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 40 | ||||
-rw-r--r-- | clang/lib/Frontend/MultiplexConsumer.cpp | 27 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 34 | ||||
-rw-r--r-- | clang/lib/Serialization/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/Serialization/GeneratePCH.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Serialization/GlobalModuleIndex.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Serialization/ModuleManager.cpp | 9 |
12 files changed, 285 insertions, 36 deletions
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index 18f505d8c59..dae14bd3b1c 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} Analysis BitReader BitWriter @@ -63,6 +64,7 @@ add_clang_library(clangCodeGen CodeGenAction.cpp CodeGenFunction.cpp CodeGenModule.cpp + CodeGenModuleContainer.cpp CodeGenPGO.cpp CodeGenTBAA.cpp CodeGenTypes.cpp diff --git a/clang/lib/CodeGen/CodeGenModuleContainer.cpp b/clang/lib/CodeGen/CodeGenModuleContainer.cpp new file mode 100644 index 00000000000..0cc825b6712 --- /dev/null +++ b/clang/lib/CodeGen/CodeGenModuleContainer.cpp @@ -0,0 +1,150 @@ +//===--- CodeGenModuleContainer.cpp - Emit .pcm files ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/CodeGen/CodeGenModuleContainer.h" +#include "CodeGenModule.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/Expr.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/CodeGen/BackendUtil.h" +#include "clang/Frontend/CodeGenOptions.h" +#include "clang/Serialization/ASTWriter.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/TargetRegistry.h" +#include <memory> +using namespace clang; + +namespace { +class ModuleContainerGenerator : public CodeGenerator { + DiagnosticsEngine &Diags; + std::unique_ptr<const llvm::DataLayout> TD; + ASTContext *Ctx; + const CodeGenOptions CodeGenOpts; + const TargetOptions TargetOpts; + const LangOptions LangOpts; + llvm::LLVMContext VMContext; + std::unique_ptr<llvm::Module> M; + std::unique_ptr<CodeGen::CodeGenModule> Builder; + raw_ostream *OS; + SmallVectorImpl<char> *SerializedASTBuffer; + +public: + ModuleContainerGenerator(DiagnosticsEngine &diags, + const std::string &ModuleName, + const CodeGenOptions &CGO, const TargetOptions &TO, + const LangOptions &LO, raw_ostream *OS, + PCHGenerator *PCHGen) + : Diags(diags), CodeGenOpts(CGO), TargetOpts(TO), LangOpts(LO), + M(new llvm::Module(ModuleName, VMContext)), OS(OS) { + PCHGen->RegisterSerializationFinishedCallback( + [&](SmallVectorImpl<char> *Buf){ + SerializedASTBuffer = Buf; + }); + } + + virtual ~ModuleContainerGenerator() {} + llvm::Module *GetModule() override { return M.get(); } + llvm::Module *ReleaseModule() override { return M.release(); } + + /// Lifted from ModuleBuilder. + const Decl *GetDeclForMangledName(StringRef MangledName) override { + GlobalDecl Result; + if (!Builder->lookupRepresentativeDecl(MangledName, Result)) + return nullptr; + const Decl *D = Result.getCanonicalDecl().getDecl(); + if (auto FD = dyn_cast<FunctionDecl>(D)) { + if (FD->hasBody(FD)) + return FD; + } else if (auto TD = dyn_cast<TagDecl>(D)) { + if (auto Def = TD->getDefinition()) + return Def; + } + return D; + } + + void Initialize(ASTContext &Context) override { + Ctx = &Context; + M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple()); + M->setDataLayout(Ctx->getTargetInfo().getTargetDescription()); + TD.reset(new llvm::DataLayout(Ctx->getTargetInfo().getTargetDescription())); + Builder.reset( + new CodeGen::CodeGenModule(Context, CodeGenOpts, *M, *TD, Diags)); + } + + /// Emit a container holding the serialized AST. + void HandleTranslationUnit(ASTContext &Ctx) override { + if (Diags.hasErrorOccurred()) { + if (Builder) + Builder->clear(); + M.reset(); + return; + } + + // Finalize the Builder. + if (Builder) + Builder->Release(); + + // Initialize the backend if we haven't done so already. + LLVMInitializeAllTargetInfos(); + LLVMInitializeAllTargets(); + LLVMInitializeAllAsmPrinters(); + LLVMInitializeAllTargetMCs(); + + // Ensure the target exists. + std::string Error; + auto Triple = Ctx.getTargetInfo().getTriple(); + if (!llvm::TargetRegistry::lookupTarget(Triple.getTriple(), Error)) + llvm::report_fatal_error(Error); + + // Emit the serialized Clang AST into its own section. + auto Size = SerializedASTBuffer->size(); + auto Int8Ty = llvm::Type::getInt8Ty(VMContext); + auto *Ty = llvm::ArrayType::get(Int8Ty, Size); + auto *Data = llvm::ConstantDataArray::getString(VMContext, + StringRef(SerializedASTBuffer->data(), Size), /*AddNull=*/false); + auto *ASTSym = new llvm::GlobalVariable(*M, Ty, /*constant*/ true, + llvm::GlobalVariable::InternalLinkage, Data, "__clang_ast"); + ASTSym->setAlignment(8); + if (Triple.isOSBinFormatMachO()) + // Include Mach-O segment name. + ASTSym->setSection("__CLANG,__clangast"); + else if (Triple.isOSBinFormatCOFF()) + // Adhere to COFF eight-character limit. + ASTSym->setSection("clangast"); + else + ASTSym->setSection("__clangast"); + + // Use the LLVM backend to emit the pcm. + clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, + Ctx.getTargetInfo().getTargetDescription(), M.get(), + BackendAction::Backend_EmitObj, OS); + + // Make sure the module container hits disk now. + OS->flush(); + + // Free up some memory, in case the process is kept alive. + SerializedASTBuffer->clear(); + } +}; +} + +CodeGenerator *clang::CreateModuleContainerGenerator( + DiagnosticsEngine &Diags, const std::string &ModuleName, + const CodeGenOptions &CGO, const TargetOptions &TO, const LangOptions &LO, + llvm::raw_ostream *OS, PCHGenerator *PCHGen) { + return + new ModuleContainerGenerator(Diags, ModuleName, CGO, TO, LO, OS, PCHGen); +} diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index bfb1efe3522..58a5f980085 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -914,13 +914,20 @@ class PrecompilePreambleConsumer : public PCHGenerator { unsigned &Hash; std::vector<Decl *> TopLevelDecls; PrecompilePreambleAction *Action; + raw_ostream *Out; + SmallVectorImpl<char> *SerializedASTBuffer; public: PrecompilePreambleConsumer(ASTUnit &Unit, PrecompilePreambleAction *Action, const Preprocessor &PP, StringRef isysroot, raw_ostream *Out) - : PCHGenerator(PP, "", nullptr, isysroot, Out, /*AllowASTWithErrors=*/true), - Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action) { + : PCHGenerator(PP, "", nullptr, isysroot, /*AllowASTWithErrors=*/true), + Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action), + Out(Out) { + RegisterSerializationFinishedCallback( + [&](SmallVectorImpl<char> *Buf){ + SerializedASTBuffer = Buf; + }); Hash = 0; } @@ -941,6 +948,13 @@ public: void HandleTranslationUnit(ASTContext &Ctx) override { PCHGenerator::HandleTranslationUnit(Ctx); if (hasEmittedPCH()) { + // Write the generated bitstream to "Out". + Out->write((char *)&SerializedASTBuffer->front(), + SerializedASTBuffer->size()); + // Make sure it hits disk now. + Out->flush(); + SerializedASTBuffer->clear(); + // Translate the top-level declarations we captured during // parsing into declaration IDs in the precompiled // preamble. This will allow us to deserialize those top-level diff --git a/clang/lib/Frontend/CMakeLists.txt b/clang/lib/Frontend/CMakeLists.txt index 7c5fca54d1e..6c9085d65dc 100644 --- a/clang/lib/Frontend/CMakeLists.txt +++ b/clang/lib/Frontend/CMakeLists.txt @@ -45,6 +45,7 @@ add_clang_library(clangFrontend LINK_LIBS clangAST clangBasic + clangCodeGen clangDriver clangEdit clangLex diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp index cb260b4f4c6..1ecc0bfc6b4 100644 --- a/clang/lib/Frontend/ChainedIncludesSource.cpp +++ b/clang/lib/Frontend/ChainedIncludesSource.cpp @@ -156,11 +156,13 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( &Clang->getPreprocessor()); Clang->createASTContext(); - SmallVector<char, 256> serialAST; - llvm::raw_svector_ostream OS(serialAST); - auto consumer = - llvm::make_unique<PCHGenerator>(Clang->getPreprocessor(), "-", nullptr, - /*isysroot=*/"", &OS); + auto consumer = llvm::make_unique<PCHGenerator>(Clang->getPreprocessor(), + "-", nullptr, /*isysroot=*/""); + SmallVectorImpl<char> *serialAST; + consumer->RegisterSerializationFinishedCallback( + [&](SmallVectorImpl<char> *Buf){ + serialAST = Buf; + }); Clang->getASTContext().setASTMutationListener( consumer->GetASTMutationListener()); Clang->setASTConsumer(std::move(consumer)); @@ -197,7 +199,9 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( ParseAST(Clang->getSema()); Clang->getDiagnosticClient().EndSourceFile(); - SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str())); + SerialBufs.push_back(llvm::MemoryBuffer:: + getMemBufferCopy(StringRef(serialAST->data(), serialAST->size()))); + serialAST->clear(); source->CIs.push_back(Clang.release()); } diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index a55a3257851..3e0f525e653 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -10,10 +10,13 @@ #include "clang/Frontend/FrontendActions.h" #include "clang/AST/ASTConsumer.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/CodeGen/CodeGenModuleContainer.h" #include "clang/Frontend/ASTConsumers.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Frontend/MultiplexConsumer.h" #include "clang/Frontend/Utils.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Pragma.h" @@ -85,8 +88,23 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { if (!CI.getFrontendOpts().RelocatablePCH) Sysroot.clear(); - return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile, - nullptr, Sysroot, OS); + + std::vector<std::unique_ptr<ASTConsumer>> Consumers; + Consumers.push_back(llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), + OutputFile, nullptr, + Sysroot)); + + auto CGOpts = CI.getCodeGenOpts(); + // The debug info emitted by ModuleContainerGenerator is not affected by the + // optimization level. + CGOpts.OptimizationLevel = 0; + CGOpts.setDebugInfo(CodeGenOptions::LimitedDebugInfo); + Consumers.push_back(std::unique_ptr<ASTConsumer>( + CreateModuleContainerGenerator(CI.getDiagnostics(), "PCH", CGOpts, + CI.getTargetOpts(), CI.getLangOpts(), OS, + cast<PCHGenerator>(Consumers[0].get())))); + + return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); } bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI, @@ -122,8 +140,22 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS)) return nullptr; - return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile, - Module, Sysroot, OS); + std::vector<std::unique_ptr<ASTConsumer>> Consumers; + Consumers.push_back(llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), + OutputFile, Module, + Sysroot)); + + auto CGOpts = CI.getCodeGenOpts(); + // The debug info emitted by ModuleContainerGenerator is not affected by the + // optimization level. + CGOpts.OptimizationLevel = 0; + CGOpts.setDebugInfo(CodeGenOptions::LimitedDebugInfo); + Consumers.push_back( + std::unique_ptr<ASTConsumer>(CreateModuleContainerGenerator( + CI.getDiagnostics(), Module->getFullModuleName(), CGOpts, + CI.getTargetOpts(), CI.getLangOpts(), OS, + cast<PCHGenerator>(Consumers[0].get())))); + return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); } static SmallVectorImpl<char> & diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index 3c4fed1d18e..bb9c907b2e3 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -33,11 +33,14 @@ public: void ReaderInitialized(ASTReader *Reader) override; void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override; + void MacroRead(serialization::MacroID ID, MacroInfo *MI) override; void TypeRead(serialization::TypeIdx Idx, QualType T) override; void DeclRead(serialization::DeclID ID, const Decl *D) override; void SelectorRead(serialization::SelectorID iD, Selector Sel) override; void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinition *MD) override; + void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override; + private: std::vector<ASTDeserializationListener*> Listeners; }; @@ -59,6 +62,12 @@ void MultiplexASTDeserializationListener::IdentifierRead( Listeners[i]->IdentifierRead(ID, II); } +void MultiplexASTDeserializationListener::MacroRead( + serialization::MacroID ID, MacroInfo *MI) { + for (auto &Listener : Listeners) + Listener->MacroRead(ID, MI); +} + void MultiplexASTDeserializationListener::TypeRead( serialization::TypeIdx Idx, QualType T) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) @@ -83,6 +92,12 @@ void MultiplexASTDeserializationListener::MacroDefinitionRead( Listeners[i]->MacroDefinitionRead(ID, MD); } +void MultiplexASTDeserializationListener::ModuleRead( + serialization::SubmoduleID ID, Module *Mod) { + for (auto &Listener : Listeners) + Listener->ModuleRead(ID, Mod); +} + // This ASTMutationListener forwards its notifications to a set of // child listeners. class MultiplexASTMutationListener : public ASTMutationListener { @@ -98,11 +113,13 @@ public: const VarTemplateSpecializationDecl *D) override; void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, const FunctionDecl *D) override; + void ResolvedExceptionSpec(const FunctionDecl *FD) override; void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override; void CompletedImplicitDefinition(const FunctionDecl *D) override; void StaticDataMemberInstantiated(const VarDecl *D) override; void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, const ObjCInterfaceDecl *IFD) override; + void FunctionDefinitionInstantiated(const FunctionDecl *D) override; void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, const ObjCPropertyDecl *OrigProp, const ObjCCategoryDecl *ClassExt) override; @@ -149,6 +166,11 @@ void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->AddedCXXTemplateSpecialization(TD, D); } +void MultiplexASTMutationListener::ResolvedExceptionSpec( + const FunctionDecl *FD) { + for (auto &Listener : Listeners) + Listener->ResolvedExceptionSpec(FD); +} void MultiplexASTMutationListener::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) @@ -170,6 +192,11 @@ void MultiplexASTMutationListener::AddedObjCCategoryToInterface( for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD); } +void MultiplexASTMutationListener::FunctionDefinitionInstantiated( + const FunctionDecl *D) { + for (auto &Listener : Listeners) + Listener->FunctionDefinitionInstantiated(D); +} void MultiplexASTMutationListener::AddedObjCPropertyInClassExtension( const ObjCPropertyDecl *Prop, const ObjCPropertyDecl *OrigProp, diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 0ee2b2b2215..dd73bbae378 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -46,6 +46,8 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Object/COFF.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" @@ -632,6 +634,27 @@ void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) { // AST reader implementation //===----------------------------------------------------------------------===// +void ASTReader::InitStreamFileWithModule(llvm::MemoryBufferRef Buffer, + llvm::BitstreamReader &StreamFile) { + if (auto OF = llvm::object::ObjectFile::createObjectFile(Buffer)) { + bool IsCOFF = isa<llvm::object::COFFObjectFile>(OF.get().get()); + // Find the clang AST section in the container. + for (auto &Section : OF->get()->sections()) { + StringRef Name; + Section.getName(Name); + if ((!IsCOFF && Name == "__clangast") || + ( IsCOFF && Name == "clangast")) { + StringRef Buf; + Section.getContents(Buf); + return StreamFile.init((const unsigned char*)Buf.begin(), + (const unsigned char*)Buf.end()); + } + } + } + StreamFile.init((const unsigned char *)Buffer.getBufferStart(), + (const unsigned char *)Buffer.getBufferEnd()); +} + void ASTReader::setDeserializationListener(ASTDeserializationListener *Listener, bool TakeOwnership) { DeserializationListener = Listener; @@ -3883,9 +3906,10 @@ ASTReader::ReadASTCore(StringRef FileName, ModuleFile &F = *M; BitstreamCursor &Stream = F.Stream; + InitStreamFileWithModule(F.Buffer->getMemBufferRef(), F.StreamFile); Stream.init(&F.StreamFile); - F.SizeInBits = F.Buffer->getBufferSize() * 8; - + F.SizeInBits = F.StreamFile.getBitcodeBytes().getExtent() * 8; + // Sniff for the signature. if (Stream.Read(8) != 'C' || Stream.Read(8) != 'P' || @@ -4174,8 +4198,7 @@ std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName, // Initialize the stream llvm::BitstreamReader StreamFile; - StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(), - (const unsigned char *)(*Buffer)->getBufferEnd()); + InitStreamFileWithModule((*Buffer)->getMemBufferRef(), StreamFile); BitstreamCursor Stream(StreamFile); // Sniff for the signature. @@ -4270,8 +4293,7 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, // Initialize the stream llvm::BitstreamReader StreamFile; - StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(), - (const unsigned char *)(*Buffer)->getBufferEnd()); + InitStreamFileWithModule((*Buffer)->getMemBufferRef(), StreamFile); BitstreamCursor Stream(StreamFile); // Sniff for the signature. diff --git a/clang/lib/Serialization/CMakeLists.txt b/clang/lib/Serialization/CMakeLists.txt index d885db22975..a1a5ad4abe7 100644 --- a/clang/lib/Serialization/CMakeLists.txt +++ b/clang/lib/Serialization/CMakeLists.txt @@ -1,5 +1,6 @@ set(LLVM_LINK_COMPONENTS BitReader + Object Support ) diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp index b5031fdf92a..0cd01dc6f3e 100644 --- a/clang/lib/Serialization/GeneratePCH.cpp +++ b/clang/lib/Serialization/GeneratePCH.cpp @@ -19,7 +19,6 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Sema/SemaConsumer.h" #include "llvm/Bitcode/BitstreamWriter.h" -#include "llvm/Support/raw_ostream.h" #include <string> using namespace clang; @@ -28,10 +27,11 @@ PCHGenerator::PCHGenerator(const Preprocessor &PP, StringRef OutputFile, clang::Module *Module, StringRef isysroot, - raw_ostream *OS, bool AllowASTWithErrors) + bool AllowASTWithErrors) : PP(PP), OutputFile(OutputFile), Module(Module), - isysroot(isysroot.str()), Out(OS), - SemaPtr(nullptr), Stream(Buffer), Writer(Stream), + isysroot(isysroot.str()), + SemaPtr(nullptr), Stream(Buffer), + Writer(Stream), AllowASTWithErrors(AllowASTWithErrors), HasEmittedPCH(false) { } @@ -52,14 +52,8 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { assert(SemaPtr && "No Sema?"); Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot, hasErrors); - // Write the generated bitstream to "Out". - Out->write((char *)&Buffer.front(), Buffer.size()); - - // Make sure it hits disk now. - Out->flush(); - - // Free up some memory, in case the process is kept alive. - Buffer.clear(); + if (SerializationFinishedCallback) + SerializationFinishedCallback(&Buffer); HasEmittedPCH = true; } diff --git a/clang/lib/Serialization/GlobalModuleIndex.cpp b/clang/lib/Serialization/GlobalModuleIndex.cpp index 47913880454..68a23ea870d 100644 --- a/clang/lib/Serialization/GlobalModuleIndex.cpp +++ b/clang/lib/Serialization/GlobalModuleIndex.cpp @@ -15,6 +15,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Serialization/ASTBitCodes.h" +#include "clang/Serialization/ASTReader.h" #include "clang/Serialization/GlobalModuleIndex.h" #include "clang/Serialization/Module.h" #include "llvm/ADT/DenseMap.h" @@ -501,8 +502,8 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // Initialize the input stream llvm::BitstreamReader InStreamFile; - InStreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(), - (const unsigned char *)(*Buffer)->getBufferEnd()); + ASTReader::InitStreamFileWithModule((*Buffer)->getMemBufferRef(), + InStreamFile); llvm::BitstreamCursor InStream(InStreamFile); // Sniff for the signature. diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index ac98ca0b872..8f1473f3a3a 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/ModuleMap.h" +#include "clang/Serialization/ASTReader.h" #include "clang/Serialization/GlobalModuleIndex.h" #include "clang/Serialization/ModuleManager.h" #include "llvm/Support/MemoryBuffer.h" @@ -135,10 +136,10 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, New->Buffer = std::move(*Buf); } - - // Initialize the stream - New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(), - (const unsigned char *)New->Buffer->getBufferEnd()); + + // Initialize the stream. + ASTReader::InitStreamFileWithModule(New->Buffer->getMemBufferRef(), + New->StreamFile); } if (ExpectedSignature) { |