22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Bitcode/BitstreamReader.h"
24 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
25 #include "llvm/IR/Constants.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/IR/LLVMContext.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/Object/COFF.h"
30 #include "llvm/Object/ObjectFile.h"
31 #include "llvm/Support/TargetRegistry.h"
33 using namespace clang;
35 #define DEBUG_TYPE "pchcontainer"
40 const std::string MainFileName;
47 std::unique_ptr<llvm::LLVMContext> VMContext;
48 std::unique_ptr<llvm::Module> M;
49 std::unique_ptr<CodeGen::CodeGenModule>
Builder;
50 raw_pwrite_stream *OS;
51 std::shared_ptr<PCHBuffer> Buffer;
57 const LangOptions &LO,
const std::string &MainFileName,
58 const std::string &OutputFileName,
59 raw_pwrite_stream *OS,
60 std::shared_ptr<PCHBuffer> Buffer)
61 : Diags(diags), HeaderSearchOpts(HSO), PreprocessorOpts(PPO),
62 TargetOpts(TO), LangOpts(LO), OS(OS), Buffer(Buffer) {
65 CodeGenOpts.CodeModel =
"default";
66 CodeGenOpts.ThreadModel =
"single";
68 CodeGenOpts.SplitDwarfFile = OutputFileName;
71 virtual ~PCHContainerGenerator() {}
75 VMContext.reset(
new llvm::LLVMContext());
76 M.reset(
new llvm::Module(MainFileName, *VMContext));
77 M->setDataLayout(Ctx->getTargetInfo().getTargetDescription());
79 PreprocessorOpts, CodeGenOpts, *M,
80 M->getDataLayout(), Diags));
84 void HandleTranslationUnit(
ASTContext &Ctx)
override {
85 assert(M && VMContext &&
Builder);
87 std::unique_ptr<llvm::LLVMContext> VMContext = std::move(this->VMContext);
88 std::unique_ptr<llvm::Module> M = std::move(this->M);
89 std::unique_ptr<CodeGen::CodeGenModule>
Builder = std::move(this->Builder);
91 if (Diags.hasErrorOccurred())
104 if (!llvm::TargetRegistry::lookupTarget(Triple.getTriple(),
Error))
105 llvm::report_fatal_error(Error);
108 assert(Buffer->IsComplete &&
"serialization did not complete");
109 auto &SerializedAST = Buffer->Data;
110 auto Size = SerializedAST.size();
111 auto Int8Ty = llvm::Type::getInt8Ty(*VMContext);
112 auto *Ty = llvm::ArrayType::get(Int8Ty, Size);
113 auto *Data = llvm::ConstantDataArray::getString(
114 *VMContext, StringRef(SerializedAST.data(), Size),
116 auto *ASTSym =
new llvm::GlobalVariable(
120 ASTSym->setAlignment(8);
123 if (Triple.isOSBinFormatMachO())
124 ASTSym->setSection(
"__CLANG,__clangast");
126 else if (Triple.isOSBinFormatCOFF())
127 ASTSym->setSection(
"clangast");
129 ASTSym->setSection(
"__clangast");
134 llvm::raw_svector_ostream OS(Buffer);
139 llvm::dbgs() << Buffer;
152 SerializedAST = std::move(Empty);
158 std::unique_ptr<ASTConsumer>
159 ObjectFilePCHContainerWriter::CreatePCHContainerGenerator(
162 const LangOptions &LO,
const std::string &MainFileName,
163 const std::string &OutputFileName, llvm::raw_pwrite_stream *OS,
164 std::shared_ptr<PCHBuffer> Buffer)
const {
165 return llvm::make_unique<PCHContainerGenerator>(
166 Diags, HSO, PPO, TO, LO, MainFileName, OutputFileName, OS, Buffer);
169 void ObjectFilePCHContainerReader::ExtractPCH(
170 llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile)
const {
171 if (
auto OF = llvm::object::ObjectFile::createObjectFile(Buffer)) {
172 auto *Obj = OF.get().get();
173 bool IsCOFF = isa<llvm::object::COFFObjectFile>(Obj);
175 for (
auto &Section : OF->get()->sections()) {
177 Section.getName(Name);
178 if ((!IsCOFF && Name ==
"__clangast") ||
179 ( IsCOFF && Name ==
"clangast")) {
181 Section.getContents(Buf);
182 StreamFile.init((
const unsigned char *)Buf.begin(),
183 (
const unsigned char *)Buf.end());
190 StreamFile.init((
const unsigned char *)Buffer.getBufferStart(),
191 (
const unsigned char *)Buffer.getBufferEnd());
Defines the clang::ASTContext interface.
Emit human-readable LLVM assembly.
Options for controlling the target.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, StringRef TDesc, llvm::Module *M, BackendAction Action, raw_pwrite_stream *OS)
const TargetInfo & getTargetInfo() const
Concrete class used by the front-end to report problems and issues.
Emit native object files.
const char * getTargetDescription() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Defines the Diagnostic-related interfaces.
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
BoundNodesTreeBuilder *const Builder
Defines the clang::TargetInfo interface.
Generate complete debug info.