31#include "llvm/ADT/ScopeExit.h"
32#include "llvm/Bitcode/BitcodeReader.h"
33#include "llvm/IR/DebugInfo.h"
34#include "llvm/IR/DiagnosticInfo.h"
35#include "llvm/IR/GlobalValue.h"
36#include "llvm/IR/LLVMContext.h"
37#include "llvm/IR/LLVMRemarkStreamer.h"
38#include "llvm/IR/Module.h"
39#include "llvm/IR/PassTimingInfo.h"
40#include "llvm/IR/Verifier.h"
41#include "llvm/IRReader/IRReader.h"
42#include "llvm/LTO/LTOBackend.h"
44#include "llvm/Support/LibraryOptionsContext.h"
45#include "llvm/Support/ManagedStatic.h"
46#include "llvm/Support/MemoryBuffer.h"
47#include "llvm/Support/Mutex.h"
48#include "llvm/Support/SourceMgr.h"
49#include "llvm/Support/TimeProfiler.h"
50#include "llvm/Support/Timer.h"
51#include "llvm/Support/ToolOutputFile.h"
52#include "llvm/Transforms/Utils/Cloning.h"
58#define DEBUG_TYPE "codegenaction"
61llvm::ManagedStatic<llvm::sys::SmartMutex<true>> TimePassesMutex;
70 [&](
const LLVMRemarkSetupFileError &E) {
71 Diags.
Report(diag::err_cannot_open_file)
74 [&](
const LLVMRemarkSetupPatternError &E) {
75 Diags.
Report(diag::err_drv_optimization_remark_pattern)
78 [&](
const LLVMRemarkSetupFormatError &E) {
79 Diags.
Report(diag::err_drv_optimization_remark_format)
89 std::unique_ptr<raw_pwrite_stream> OS,
91 llvm::Module *CurLinkModule)
92 : CI(CI), Diags(CI.getDiagnostics()), CodeGenOpts(CI.getCodeGenOpts()),
93 TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),
94 AsmOutStream(
std::move(OS)), FS(VFS), Action(Action),
96 LinkModules(
std::move(LinkModules)), DiagConsumer(Diags, CodeGenOpts) {
97 DiagConsumer.setCurLinkModule(CurLinkModule);
98 TimerIsEnabled = CodeGenOpts.TimePasses;
100 llvm::sys::SmartScopedLock<true> Lock(*TimePassesMutex);
101 llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses;
102 llvm::TimePassesPerRun = CodeGenOpts.TimePassesPerRun;
104 if (CodeGenOpts.TimePasses)
105 LLVMIRGeneration.init(
"irgen",
"LLVM IR generation", CI.getTimerGroup());
109 return Gen->GetModule();
113 return std::unique_ptr<llvm::Module>(Gen->ReleaseModule());
125 assert(!Context &&
"initialized multiple times");
131 LLVMIRGeneration.startTimer();
133 Gen->Initialize(Ctx);
136 LLVMIRGeneration.stopTimer();
141 Context->getSourceManager(),
142 "LLVM IR generation of declaration");
145 if (TimerIsEnabled && !LLVMIRGenerationRefCount++)
146 CI.getFrontendTimer().yieldTo(LLVMIRGeneration);
148 Gen->HandleTopLevelDecl(D);
150 if (TimerIsEnabled && !--LLVMIRGenerationRefCount)
151 LLVMIRGeneration.yieldTo(CI.getFrontendTimer());
158 Context->getSourceManager(),
159 "LLVM IR generation of inline function");
161 CI.getFrontendTimer().yieldTo(LLVMIRGeneration);
163 Gen->HandleInlineFunctionDefinition(D);
166 LLVMIRGeneration.yieldTo(CI.getFrontendTimer());
175 return linkInModules(*M, LinkModules, CodeGenOpts, LangOpts, TargetOpts,
181 llvm::TimeTraceScope TimeScope(
"Frontend");
182 PrettyStackTraceString CrashInfo(
"Per-file LLVM IR generation");
183 if (TimerIsEnabled && !LLVMIRGenerationRefCount++)
184 CI.getFrontendTimer().yieldTo(LLVMIRGeneration);
186 Gen->HandleTranslationUnit(
C);
188 if (TimerIsEnabled && !--LLVMIRGenerationRefCount)
189 LLVMIRGeneration.yieldTo(CI.getFrontendTimer());
196 LLVMContext &Ctx =
getModule()->getContext();
197 std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler =
198 Ctx.getDiagnosticHandler();
199 llvm::scope_exit RestoreDiagnosticHandler(
200 [&]() { Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler)); });
203 Ctx.setDefaultTargetCPU(TargetOpts.CPU);
204 Ctx.setDefaultTargetFeatures(llvm::join(TargetOpts.Features,
","));
207 setupLLVMOptimizationRemarks(
208 Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
209 CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
210 CodeGenOpts.DiagnosticsHotnessThreshold);
212 if (
Error E = OptRecordFileOrErr.takeError()) {
217 LLVMRemarkFileHandle OptRecordFile = std::move(*OptRecordFileOrErr);
219 if (OptRecordFile && CodeGenOpts.getProfileUse() !=
220 llvm::driver::ProfileInstrKind::ProfileNone)
221 Ctx.setDiagnosticsHotnessRequested(
true);
223 if (CodeGenOpts.MisExpect) {
224 Ctx.setMisExpectWarningRequested(
true);
227 if (CodeGenOpts.DiagnosticsMisExpectTolerance) {
228 Ctx.setDiagnosticsMisExpectTolerance(
229 CodeGenOpts.DiagnosticsMisExpectTolerance);
236 for (
auto &F :
getModule()->functions()) {
237 if (
const Decl *FD = Gen->GetDeclForMangledName(F.getName())) {
238 auto Loc = FD->getASTContext().getFullLoc(FD->getLocation());
239 DiagConsumer.addFunctionSourceLocation(F.getName(), Loc);
243 if (CodeGenOpts.ClearASTBeforeBackend) {
244 LLVM_DEBUG(llvm::dbgs() <<
"Clearing AST...\n");
252 C.getAllocator().Reset();
258 std::move(AsmOutStream),
this);
261 OptRecordFile->keep();
266 Context->getSourceManager(),
267 "LLVM IR generation of declaration");
268 Gen->HandleTagDeclDefinition(D);
272 Gen->HandleTagDeclRequiredDefinition(D);
276 Gen->CompleteTentativeDefinition(D);
280 Gen->CompleteExternalDeclaration(D);
284 Gen->AssignInheritanceModel(RD);
288 Gen->HandleVTable(RD);
291void BackendConsumer::anchor() { }
295std::unique_ptr<llvm::DiagnosticHandler>
297 return DiagConsumer.createDiagnosticHandler();
301 : Act(_Act), VMContext(_VMContext ? _VMContext : new LLVMContext),
302 OwnsVMContext(!_VMContext) {}
324 return std::move(TheModule);
328 OwnsVMContext =
false;
343static std::unique_ptr<raw_pwrite_stream>
360 llvm_unreachable(
"Invalid action!");
363std::unique_ptr<ASTConsumer>
385 InFile, std::move(OS), CoverageInfo));
390 if (CI.
getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo &&
392 std::unique_ptr<PPCallbacks> Callbacks =
393 std::make_unique<MacroPPCallbacks>(
BEConsumer->getCodeGenerator(),
400 std::vector<std::unique_ptr<ASTConsumer>> Consumers(2);
401 Consumers[0] = std::make_unique<ReducedBMIGenerator>(
404 Consumers[1] = std::move(
Result);
405 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
411std::unique_ptr<llvm::Module>
412CodeGenAction::loadModule(MemoryBufferRef MBRef) {
416 auto DiagErrors = [&](
Error E) -> std::unique_ptr<llvm::Module> {
419 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
429 VMContext->enableDebugTypeODRUniquing();
431 Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef);
433 return DiagErrors(BMsOrErr.takeError());
434 BitcodeModule *Bm = llvm::lto::findThinLTOModule(*BMsOrErr);
440 auto M = std::make_unique<llvm::Module>(
"empty", *VMContext);
444 Expected<std::unique_ptr<llvm::Module>> MOrErr =
445 Bm->parseModule(*VMContext);
447 return DiagErrors(MOrErr.takeError());
448 return std::move(*MOrErr);
456 llvm::SMDiagnostic Err;
457 if (std::unique_ptr<llvm::Module> M = parseIR(MBRef, Err, *VMContext)) {
460 std::string VerifierErr;
461 raw_string_ostream VerifierErrStream(VerifierErr);
462 if (llvm::verifyModule(*M, &VerifierErrStream)) {
472 Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef);
473 if (BMsOrErr && BMsOrErr->size()) {
474 std::unique_ptr<llvm::Module> FirstM;
475 for (
auto &BM : *BMsOrErr) {
476 Expected<std::unique_ptr<llvm::Module>> MOrErr =
477 BM.parseModule(*VMContext);
479 return DiagErrors(MOrErr.takeError());
481 LinkModules.push_back({std::move(*MOrErr),
false,
484 FirstM = std::move(*MOrErr);
491 consumeError(BMsOrErr.takeError());
497 if (Err.getLineNo() > 0) {
498 assert(Err.getColumnNo() >= 0);
500 Err.getLineNo(), Err.getColumnNo() + 1);
504 StringRef Msg = Err.getMessage();
505 Msg.consume_front(
"error: ");
525 std::unique_ptr<raw_pwrite_stream> OS =
536 TheModule = loadModule(*MainFile);
541 if (TheModule->getTargetTriple().str() != TargetOpts.
Triple) {
542 Diagnostics.Report(
SourceLocation(), diag::warn_fe_override_module)
544 TheModule->setTargetTriple(Triple(TargetOpts.
Triple));
547 llvm::ExceptionHandling ExceptionModel =
549 if (ExceptionModel != llvm::ExceptionHandling::Default) {
550 StringRef ModelName = llvm::getExceptionModelName(ExceptionModel);
551 if (
auto *Existing = cast_or_null<llvm::MDString>(
552 TheModule->getModuleFlag(
"exception-model"))) {
553 if (Existing->getString() != ModelName) {
554 Diagnostics.Report(diag::err_fe_exception_model_mismatch)
555 << ModelName << Existing->getString();
559 TheModule->addModuleFlag(
560 llvm::Module::Error,
"exception-model",
561 llvm::MDString::get(TheModule->getContext(), ModelName));
569 LLVMContext &Ctx = TheModule->getContext();
575 std::unique_ptr<DiagnosticHandler> PrevHandler = Ctx.getDiagnosticHandler();
576 ~RAII() { Ctx.setDiagnosticHandler(std::move(PrevHandler)); }
582 std::move(LinkModules),
"",
nullptr,
nullptr,
586 if (!CodeGenOpts.LinkBitcodePostopt &&
Result.LinkInModules(&*TheModule))
590 Ctx.setDiscardValueNames(CodeGenOpts.DiscardValueNames);
591 Ctx.setDiagnosticHandler(
Result.createDiagnosticHandler());
593 Ctx.setDefaultTargetCPU(TargetOpts.
CPU);
594 Ctx.setDefaultTargetFeatures(llvm::join(TargetOpts.
Features,
","));
597 setupLLVMOptimizationRemarks(
598 Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
599 CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
600 CodeGenOpts.DiagnosticsHotnessThreshold);
602 if (
Error E = OptRecordFileOrErr.takeError()) {
606 LLVMRemarkFileHandle OptRecordFile = std::move(*OptRecordFileOrErr);
612 OptRecordFile->keep();
617void EmitAssemblyAction::anchor() { }
621void EmitBCAction::anchor() { }
625void EmitLLVMAction::anchor() { }
629void EmitLLVMOnlyAction::anchor() { }
633void EmitCodeGenOnlyAction::anchor() { }
637void EmitObjAction::anchor() { }
Defines the clang::ASTContext interface.
static std::unique_ptr< raw_pwrite_stream > GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::FileManager interface and associated types.
Defines the clang::Preprocessor interface.
Defines the SourceManager interface.
virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D)
HandleCXXStaticMemberVarInstantiation - Tell the consumer that this.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
llvm::Module * getModule() const
void CompleteExternalDeclaration(DeclaratorDecl *D) override
CompleteExternalDeclaration - Callback invoked at the end of a translation unit to notify the consume...
void HandleVTable(CXXRecordDecl *RD) override
Callback involved at the end of a translation unit to notify the consumer that a vtable for the given...
void HandleTagDeclDefinition(TagDecl *D) override
HandleTagDeclDefinition - This callback is invoked each time a TagDecl (e.g.
bool HandleTopLevelDecl(DeclGroupRef D) override
HandleTopLevelDecl - Handle the specified top-level declaration.
void Initialize(ASTContext &Ctx) override
Initialize - This is called to initialize the consumer, providing the ASTContext.
void HandleInlineFunctionDefinition(FunctionDecl *D) override
This callback is invoked each time an inline (method or friend) function definition in a class is com...
void HandleTagDeclRequiredDefinition(const TagDecl *D) override
This callback is invoked the first time each TagDecl is required to be complete.
void HandleInterestingDecl(DeclGroupRef D) override
HandleInterestingDecl - Handle the specified interesting declaration.
void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override
HandleCXXStaticMemberVarInstantiation - Tell the consumer that this.
std::unique_ptr< llvm::DiagnosticHandler > createDiagnosticHandler()
Create an llvm::DiagnosticHandler that routes LLVM backend diagnostics through this consumer's clang ...
std::unique_ptr< llvm::Module > takeModule()
void AssignInheritanceModel(CXXRecordDecl *RD) override
Callback invoked when an MSInheritanceAttr has been attached to a CXXRecordDecl.
void HandleTranslationUnit(ASTContext &C) override
HandleTranslationUnit - This method is called when the ASTs for entire translation unit have been par...
void CompleteTentativeDefinition(VarDecl *D) override
CompleteTentativeDefinition - Callback invoked at the end of a translation unit to notify the consume...
bool LinkInModules(llvm::Module *M)
CodeGenerator * getCodeGenerator()
BackendConsumer(CompilerInstance &CI, BackendAction Action, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, llvm::LLVMContext &C, SmallVector< LinkModule, 4 > LinkModules, StringRef InFile, std::unique_ptr< raw_pwrite_stream > OS, CoverageSourceInfo *CoverageInfo, llvm::Module *CurLinkModule=nullptr)
Represents a C++ struct/union/class.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
CodeGenerator * getCodeGenerator() const
void EndSourceFileAction() override
Callback at the end of processing a single input.
bool BeginSourceFileAction(CompilerInstance &CI) override
Callback at the start of processing a single input.
~CodeGenAction() override
CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext=nullptr)
Create a new code generation action.
llvm::LLVMContext * takeLLVMContext()
Take the LLVM context used by this action.
BackendConsumer * BEConsumer
bool hasIRSupport() const override
Does this action support use with IR files?
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
std::unique_ptr< llvm::Module > takeModule()
Take the generated LLVM module, for use after the action has been run.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string OptRecordFile
The name of the file to which the backend should save YAML optimization records.
static llvm::ExceptionHandling toExceptionHandling(ExceptionHandlingKind Kind)
Translate a clang ExceptionHandlingKind into the corresponding LLVM ExceptionHandling model.
std::string OptRecordPasses
The regex that filters the passes that should be saved to the optimization records.
std::string ThinLTOIndexFile
Name of the function summary index file to use for ThinLTO function importing.
std::string OptRecordFormat
The format used for serializing remarks (default: YAML)
static CoverageSourceInfo * setUpCoverageCallbacks(Preprocessor &PP)
The primary public interface to the Clang code generator.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
std::unique_ptr< raw_pwrite_stream > createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="", bool RemoveFileOnSignal=true, bool CreateMissingDirectories=false, bool ForceUseTemporary=false, bool SetOnlyIfDifferent=false)
Create the default output file (from the invocation's options) and add it to the list of tracked outp...
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
FileManager & getFileManager() const
Return the current file manager to the caller.
ModuleCache & getModuleCache() const
Preprocessor & getPreprocessor() const
Return the current preprocessor.
const llvm::cl::LibraryOptionsContext & getLibraryOptions() const
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
TargetOptions & getTargetOpts()
std::unique_ptr< llvm::raw_pwrite_stream > takeOutputStream()
FrontendOptions & getFrontendOpts()
llvm::vfs::FileSystem & getVirtualFileSystem() const
LangOptions & getLangOpts()
CodeGenOptions & getCodeGenOpts()
SourceManager & getSourceManager() const
Return the current source manager.
std::unique_ptr< raw_pwrite_stream > createNullOutputFile()
Stores additional source code information like skipped ranges which is required by the coverage mappi...
Decl - This represents one declaration (or definition), e.g.
Represents a ValueDecl that came out of a declarator.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
EmitAssemblyAction(llvm::LLVMContext *_VMContext=nullptr)
EmitBCAction(llvm::LLVMContext *_VMContext=nullptr)
EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext=nullptr)
EmitLLVMAction(llvm::LLVMContext *_VMContext=nullptr)
EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext=nullptr)
EmitObjAction(llvm::LLVMContext *_VMContext=nullptr)
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
InputKind getCurrentFileKind() const
virtual bool BeginSourceFileAction(CompilerInstance &CI)
Callback at the start of processing a single input.
CompilerInstance & getCompilerInstance() const
virtual void EndSourceFileAction()
Callback at the end of processing a single input.
StringRef getCurrentFileOrBufferName() const
unsigned GenReducedBMI
Whether to generate reduced BMI for C++20 named modules.
std::string ModuleOutputPath
Output Path for module output file.
Represents a function declaration or definition.
@ CMK_ModuleInterface
Compiling a C++ modules interface unit.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
PrettyStackTraceDecl - If a crash occurs, indicate that it happened when doing something to a specifi...
Encodes a location in the source.
This class handles loading and caching of source files into memory.
FileID getMainFileID() const
Returns the FileID of the main source file.
SourceLocation translateFileLineCol(const FileEntry *SourceFile, unsigned Line, unsigned Col) const
Get the source location for the given file:line:col triplet.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
Represents the declaration of a struct/union/class/enum.
Options for controlling the target.
std::string Triple
The name of the target triple to compile for.
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings starting...
std::string CPU
If given, the name of the target CPU to generate code for.
Represents a variable declaration or definition.
Defines the clang::TargetInfo interface.
Top level wrappers for InstallAPI frontend operations.
static void reportOptRecordError(Error E, DiagnosticsEngine &Diags, const CodeGenOptions &CodeGenOpts)
@ Result
The result type of a method or function.
bool linkInModules(llvm::Module &M, llvm::SmallVectorImpl< LinkModule > &LinkModules, const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts, const TargetOptions &TargetOpts, BackendDiagnosticConsumer &DiagConsumer)
Link every module in LinkModules into M, propagating default function attributes and internalizing as...
void EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::vfs::FileSystem &VFS, DiagnosticsEngine &Diags)
void emitBackendOutput(CompilerInstance &CI, CodeGenOptions &CGOpts, llvm::Module *M, BackendAction Action, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::unique_ptr< raw_pwrite_stream > OS, BackendConsumer *BC=nullptr)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
@ Backend_EmitAssembly
Emit native assembly files.
@ Backend_EmitLL
Emit human-readable LLVM assembly.
@ Backend_EmitBC
Emit LLVM bitcode files.
@ Backend_EmitObj
Emit native object files.
@ Backend_EmitMCNull
Run CodeGen, but don't emit anything.
@ Backend_EmitNothing
Don't emit anything (benchmarking mode)
std::unique_ptr< CodeGenerator > CreateLLVMCodeGen(const CompilerInstance &CI, llvm::StringRef ModuleName, llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo=nullptr)
CreateLLVMCodeGen - Create a CodeGenerator instance.
bool loadLinkModules(CompilerInstance &CI, llvm::LLVMContext &Ctx, llvm::SmallVectorImpl< LinkModule > &LinkModules)
Load every bitcode file listed in CodeGenOpts.LinkBitcodeFiles into LinkModules.
Diagnostic wrappers for TextAPI types for error reporting.