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.

rdar://problem/19104245

This reapplies r230044 with a fixed configure+make build and updated
dependencies.

llvm-svn: 230067
This commit is contained in:
Adrian Prantl 2015-02-20 21:53:12 +00:00
parent 338d0bdc96
commit b59bc1a528
32 changed files with 398 additions and 64 deletions

View File

@ -65,6 +65,9 @@ be included at the beginning of the translation unit. The extensions to the
AST file format required for modules are discussed in the section on
:ref:`modules <pchinternals-modules>`.
Clang's AST files are Mach-O, ELF, or COFF containers that contain a
``__clangast`` section which holds the AST bitstream.
Clang's AST files are designed with a compact on-disk representation, which
minimizes both creation time and the time required to initially load the AST
file. The AST file itself contains a serialized representation of Clang's

View File

@ -0,0 +1,34 @@
//===--- CodeGen/ModuleContainerGenerator.h - Emit .pcm files ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_CODEGEN_MODULE_CONTAINER_H
#define LLVM_CLANG_CODEGEN_MODULE_CONTAINER_H
#include "ModuleBuilder.h"
#include <string>
namespace llvm {
class raw_ostream;
}
namespace clang {
class PCHGenerator;
class TargetOptions;
/// \brief Create a CodeGenerator instance.
/// It is the responsibility of the caller to call delete on
/// the allocated CodeGenerator instance.
CodeGenerator *CreateModuleContainerGenerator(
DiagnosticsEngine &Diags, const std::string &ModuleName,
const CodeGenOptions &CGO, const TargetOptions &TO, const LangOptions &LO,
llvm::raw_ostream *OS, PCHGenerator *PCHGen);
}
#endif

View File

@ -69,6 +69,14 @@ protected:
StringRef InFile) override;
};
/// \brief Emits the output of a GeneratePCHAction or GenerateModuleAction into
/// a Mach-O/ELF/COFF container.
class GeneratePCMContainerAction : public FrontendAction {
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;
};
class GeneratePCHAction : public ASTFrontendAction {
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,

View File

@ -1127,6 +1127,10 @@ private:
public:
void ResolveImportedPath(ModuleFile &M, std::string &Filename);
static void ResolveImportedPath(std::string &Filename, StringRef Prefix);
/// \brief Initialize a BitstreamReader with the `__clangast` section from an
/// object file container found in Buffer.
static void InitStreamFileWithModule(llvm::MemoryBufferRef Buffer,
llvm::BitstreamReader &StreamFile);
private:
struct ImportedModule {

View File

@ -823,10 +823,13 @@ class PCHGenerator : public SemaConsumer {
std::string OutputFile;
clang::Module *Module;
std::string isysroot;
raw_ostream *Out;
Sema *SemaPtr;
SmallVector<char, 128> Buffer;
// This buffer is always large, but BitstreamWriter really wants a
// SmallVectorImpl<char>.
SmallVector<char, 0> Buffer;
llvm::BitstreamWriter Stream;
std::function<void(SmallVectorImpl<char>*)>
SerializationFinishedCallback;
ASTWriter Writer;
bool AllowASTWithErrors;
bool HasEmittedPCH;
@ -836,16 +839,21 @@ protected:
const ASTWriter &getWriter() const { return Writer; }
public:
PCHGenerator(const Preprocessor &PP, StringRef OutputFile,
PCHGenerator(const Preprocessor &PP,
StringRef OutputFile,
clang::Module *Module,
StringRef isysroot, raw_ostream *Out,
StringRef isysroot,
bool AllowASTWithErrors = false);
~PCHGenerator();
void InitializeSema(Sema &S) override { SemaPtr = &S; }
void HandleTranslationUnit(ASTContext &Ctx) override;
ASTMutationListener *GetASTMutationListener() override;
ASTDeserializationListener *GetASTDeserializationListener() override;
/// \brief Register a callback to be invoked when the serialization is done.
void RegisterSerializationFinishedCallback(
const std::function<void(SmallVectorImpl<char>*)> Fn) {
SerializationFinishedCallback = Fn;
}
bool hasEmittedPCH() const { return HasEmittedPCH; }
};

View File

@ -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

View File

@ -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.
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);
}

View File

@ -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

View File

@ -45,6 +45,7 @@ add_clang_library(clangFrontend
LINK_LIBS
clangAST
clangBasic
clangCodeGen
clangDriver
clangEdit
clangLex

View File

@ -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());
}

View File

@ -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> &

View File

@ -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,

View File

@ -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,8 +3906,9 @@ 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' ||
@ -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.

View File

@ -1,5 +1,6 @@
set(LLVM_LINK_COMPONENTS
BitReader
Object
Support
)

View File

@ -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;
}

View File

@ -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.

View File

@ -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"
@ -136,9 +137,9 @@ 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) {

View File

@ -58,7 +58,7 @@ set(CLANG_TEST_PARAMS
if( NOT CLANG_BUILT_STANDALONE )
list(APPEND CLANG_TEST_DEPS
llvm-config
llc opt FileCheck count not llvm-symbolizer llvm-profdata
llc opt FileCheck count not llvm-symbolizer llvm-profdata llvm-objdump
)
endif()

View File

@ -0,0 +1,14 @@
@import DependsOnModule;
// REQUIRES: x86-registered-target
// RUN: rm -rf %t-MachO %t-ELF %t-COFF
// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fmodules -fdisable-module-hash -fmodules-cache-path=%t-MachO -F %S/Inputs %s
// RUN: %clang_cc1 -triple=x86_64-linux-elf -fmodules -fdisable-module-hash -fmodules-cache-path=%t-ELF -F %S/Inputs %s
// RUN: %clang_cc1 -triple=x86_64-windows-coff -fmodules -fdisable-module-hash -fmodules-cache-path=%t-COFF -F %S/Inputs %s
// RUN: llvm-objdump -section-headers %t-MachO/DependsOnModule.pcm %t-ELF/DependsOnModule.pcm %t-COFF/DependsOnModule.pcm | FileCheck %s
// CHECK: file format Mach-O 64-bit x86-64
// CHECK: __clangast {{[0-9a-f]+}} {{[0-9a-f]+}} DATA
// CHECK: file format ELF64-x86-64
// CHECK: __clangast {{[0-9a-f]+}} {{[0-9a-f]+}} DATA
// CHECK: file format COFF-x86-64
// CHECK: clangast {{[0-9a-f]+}} {{[0-9a-f]+}}

View File

@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple mips64-none-linux-gnu -emit-pch -o %t %s
// REQUIRES: mips-registered-target
// RUN: %clang_cc1 -x ast -ast-print %t | FileCheck %s
// Make sure the semantics of FloatingLiterals are stored correctly in

View File

@ -17,8 +17,9 @@ TOOL_NO_EXPORTS = 1
NO_INSTALL = 1
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
USEDLIBS = clangARCMigrate.a clangRewrite.a \
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter \
instrumentation mc objcarcopts option support
USEDLIBS = clangARCMigrate.a clangRewrite.a clangCodeGen.a \
clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
clangSema.a clangEdit.a clangAnalysis.a clangAST.a clangLex.a \
clangBasic.a

View File

@ -22,12 +22,14 @@ TOOL_NO_EXPORTS = 1
# LINK_COMPONENTS before including Makefile.rules
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter \
instrumentation support mc objcarcopts option
# Note that 'USEDLIBS' must include all of the core clang libraries
# when -static is given to linker on cygming.
USEDLIBS = clang.a \
clangIndex.a clangFormat.a clangRewrite.a \
clangCodeGen.a \
clangFrontend.a clangDriver.a \
clangTooling.a \
clangToolingCore.a \

View File

@ -15,9 +15,10 @@ TOOLNAME = clang-check
TOOL_NO_EXPORTS = 1
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter \
instrumentation mc option objcarcopts support
USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a \
clangTooling.a clangParse.a clangSema.a \
clangCodeGen.a clangTooling.a clangParse.a clangSema.a \
clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
clangStaticAnalyzerCore.a clangAnalysis.a clangRewriteFrontend.a \
clangRewrite.a clangEdit.a clangAST.a clangLex.a clangBasic.a

View File

@ -40,6 +40,7 @@ set(SOURCES
set(LIBS
clangAST
clangBasic
clangCodeGen
clangFrontend
clangIndex
clangLex

View File

@ -16,11 +16,13 @@ LINK_LIBS_IN_SHARED = 1
SHARED_LIBRARY = 1
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := AsmParser BitReader Core MC MCParser Option Support
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter core \
instrumentation mc mcparser objcarcopts option support
USEDLIBS = clangIndex.a clangARCMigrate.a \
clangRewriteFrontend.a \
clangFormat.a \
clangTooling.a clangToolingCore.a \
clangCodeGen.a \
clangFrontend.a clangDriver.a \
clangSerialization.a \
clangParse.a clangSema.a \

View File

@ -10,9 +10,10 @@
CLANG_LEVEL = ../..
TESTNAME = AST
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter \
instrumentation mc option objcarcopts support
USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
clangRewrite.a clangRewriteFrontend.a \
clangCodeGen.a clangRewrite.a clangRewriteFrontend.a \
clangParse.a clangSema.a clangAnalysis.a \
clangEdit.a clangAST.a clangASTMatchers.a clangLex.a clangBasic.a

View File

@ -11,10 +11,11 @@ CLANG_LEVEL = ../../..
TESTNAME = DynamicASTMatchers
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
clangRewrite.a clangRewriteFrontend.a clangParse.a clangSema.a \
clangAnalysis.a clangEdit.a clangAST.a clangASTMatchers.a \
clangLex.a clangBasic.a clangDynamicASTMatchers.a
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter \
instrumentation mc option objcarcopts support
USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
clangCodeGen.a clangRewrite.a clangRewriteFrontend.a clangParse.a \
clangSema.a clangAnalysis.a clangEdit.a clangAST.a \
clangASTMatchers.a clangLex.a clangBasic.a clangDynamicASTMatchers.a
include $(CLANG_LEVEL)/unittests/Makefile

View File

@ -13,9 +13,10 @@ PARALLEL_DIRS = Dynamic
TESTNAME = ASTMatchers
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter \
instrumentation mc option objcarcopts support
USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
clangRewrite.a clangRewriteFrontend.a \
clangCodeGen.a clangRewrite.a clangRewriteFrontend.a \
clangParse.a clangSema.a clangAnalysis.a \
clangEdit.a clangAST.a clangASTMatchers.a clangLex.a clangBasic.a

View File

@ -10,8 +10,8 @@
CLANG_LEVEL = ../..
TESTNAME = CodeGen
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader mc option \
profiledata support
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter \
instrumentation mc option objcarcopts profiledata support
USEDLIBS = clangCodeGen.a clangFrontend.a clangSerialization.a \
clangDriver.a \
clangParse.a clangSema.a clangAnalysis.a \

View File

@ -10,7 +10,8 @@
CLANG_LEVEL = ../..
TESTNAME = Frontend
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter \
instrumentation mc option objcarcopts support
USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \
clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \

View File

@ -10,9 +10,10 @@
CLANG_LEVEL = ../..
TESTNAME = Sema
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter \
instrumentation mc option objcarcopts support
USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
clangRewrite.a clangRewriteFrontend.a \
clangCodeGen.a clangRewrite.a clangRewriteFrontend.a \
clangParse.a clangSema.a clangAnalysis.a \
clangEdit.a clangAST.a clangASTMatchers.a clangLex.a clangBasic.a

View File

@ -10,9 +10,10 @@
CLANG_LEVEL = ../..
TESTNAME = Tooling
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter \
instrumentation mc option objcarcopts support
USEDLIBS = clangTooling.a clangToolingCore.a clangFrontend.a \
clangSerialization.a clangDriver.a \
clangCodeGen.a clangSerialization.a clangDriver.a \
clangParse.a clangRewrite.a clangRewriteFrontend.a \
clangSema.a clangAnalysis.a clangEdit.a \
clangAST.a clangASTMatchers.a clangLex.a clangBasic.a