1ffd1746dSEd Schouten //===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===//
2ffd1746dSEd Schouten //
3ffd1746dSEd Schouten // The LLVM Compiler Infrastructure
4ffd1746dSEd Schouten //
5ffd1746dSEd Schouten // This file is distributed under the University of Illinois Open Source
6ffd1746dSEd Schouten // License. See LICENSE.TXT for details.
7ffd1746dSEd Schouten //
8ffd1746dSEd Schouten //===----------------------------------------------------------------------===//
9ffd1746dSEd Schouten
1020e90f04SDimitry Andric #include "clang/CodeGen/CodeGenAction.h"
1120e90f04SDimitry Andric #include "CodeGenModule.h"
1239d628a0SDimitry Andric #include "CoverageMappingGen.h"
1320e90f04SDimitry Andric #include "MacroPPCallbacks.h"
14ffd1746dSEd Schouten #include "clang/AST/ASTConsumer.h"
15ffd1746dSEd Schouten #include "clang/AST/ASTContext.h"
1659d1ed5bSDimitry Andric #include "clang/AST/DeclCXX.h"
1739d628a0SDimitry Andric #include "clang/AST/DeclGroup.h"
18139f7f9bSDimitry Andric #include "clang/Basic/FileManager.h"
19139f7f9bSDimitry Andric #include "clang/Basic/SourceManager.h"
20139f7f9bSDimitry Andric #include "clang/Basic/TargetInfo.h"
21ffd1746dSEd Schouten #include "clang/CodeGen/BackendUtil.h"
22ffd1746dSEd Schouten #include "clang/CodeGen/ModuleBuilder.h"
23ffd1746dSEd Schouten #include "clang/Frontend/CompilerInstance.h"
24ffd1746dSEd Schouten #include "clang/Frontend/FrontendDiagnostic.h"
2539d628a0SDimitry Andric #include "clang/Lex/Preprocessor.h"
2644290647SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h"
2720e90f04SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
2859d1ed5bSDimitry Andric #include "llvm/IR/DebugInfo.h"
2959d1ed5bSDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
3059d1ed5bSDimitry Andric #include "llvm/IR/DiagnosticPrinter.h"
3120e90f04SDimitry Andric #include "llvm/IR/GlobalValue.h"
32139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h"
33139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
34139f7f9bSDimitry Andric #include "llvm/IRReader/IRReader.h"
3559d1ed5bSDimitry Andric #include "llvm/Linker/Linker.h"
36139f7f9bSDimitry Andric #include "llvm/Pass.h"
37ffd1746dSEd Schouten #include "llvm/Support/MemoryBuffer.h"
38ffd1746dSEd Schouten #include "llvm/Support/SourceMgr.h"
39ffd1746dSEd Schouten #include "llvm/Support/Timer.h"
4044290647SDimitry Andric #include "llvm/Support/ToolOutputFile.h"
4144290647SDimitry Andric #include "llvm/Support/YAMLTraits.h"
4220e90f04SDimitry Andric #include "llvm/Transforms/IPO/Internalize.h"
4320e90f04SDimitry Andric
4459d1ed5bSDimitry Andric #include <memory>
45ffd1746dSEd Schouten using namespace clang;
46ffd1746dSEd Schouten using namespace llvm;
47ffd1746dSEd Schouten
482754fe60SDimitry Andric namespace clang {
499a199699SDimitry Andric class BackendConsumer;
509a199699SDimitry Andric class ClangDiagnosticHandler final : public DiagnosticHandler {
519a199699SDimitry Andric public:
ClangDiagnosticHandler(const CodeGenOptions & CGOpts,BackendConsumer * BCon)529a199699SDimitry Andric ClangDiagnosticHandler(const CodeGenOptions &CGOpts, BackendConsumer *BCon)
539a199699SDimitry Andric : CodeGenOpts(CGOpts), BackendCon(BCon) {}
549a199699SDimitry Andric
559a199699SDimitry Andric bool handleDiagnostics(const DiagnosticInfo &DI) override;
569a199699SDimitry Andric
isAnalysisRemarkEnabled(StringRef PassName) const579a199699SDimitry Andric bool isAnalysisRemarkEnabled(StringRef PassName) const override {
589a199699SDimitry Andric return (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
599a199699SDimitry Andric CodeGenOpts.OptimizationRemarkAnalysisPattern->match(PassName));
609a199699SDimitry Andric }
isMissedOptRemarkEnabled(StringRef PassName) const619a199699SDimitry Andric bool isMissedOptRemarkEnabled(StringRef PassName) const override {
629a199699SDimitry Andric return (CodeGenOpts.OptimizationRemarkMissedPattern &&
639a199699SDimitry Andric CodeGenOpts.OptimizationRemarkMissedPattern->match(PassName));
649a199699SDimitry Andric }
isPassedOptRemarkEnabled(StringRef PassName) const659a199699SDimitry Andric bool isPassedOptRemarkEnabled(StringRef PassName) const override {
669a199699SDimitry Andric return (CodeGenOpts.OptimizationRemarkPattern &&
679a199699SDimitry Andric CodeGenOpts.OptimizationRemarkPattern->match(PassName));
689a199699SDimitry Andric }
699a199699SDimitry Andric
isAnyRemarkEnabled() const709a199699SDimitry Andric bool isAnyRemarkEnabled() const override {
719a199699SDimitry Andric return (CodeGenOpts.OptimizationRemarkAnalysisPattern ||
729a199699SDimitry Andric CodeGenOpts.OptimizationRemarkMissedPattern ||
739a199699SDimitry Andric CodeGenOpts.OptimizationRemarkPattern);
749a199699SDimitry Andric }
759a199699SDimitry Andric
769a199699SDimitry Andric private:
779a199699SDimitry Andric const CodeGenOptions &CodeGenOpts;
789a199699SDimitry Andric BackendConsumer *BackendCon;
799a199699SDimitry Andric };
809a199699SDimitry Andric
81ffd1746dSEd Schouten class BackendConsumer : public ASTConsumer {
8220e90f04SDimitry Andric using LinkModule = CodeGenAction::LinkModule;
8320e90f04SDimitry Andric
84dff0c46cSDimitry Andric virtual void anchor();
856122f3e6SDimitry Andric DiagnosticsEngine &Diags;
86ffd1746dSEd Schouten BackendAction Action;
8795ec533aSDimitry Andric const HeaderSearchOptions &HeaderSearchOpts;
88ffd1746dSEd Schouten const CodeGenOptions &CodeGenOpts;
89ffd1746dSEd Schouten const TargetOptions &TargetOpts;
9017a519f9SDimitry Andric const LangOptions &LangOpts;
91e7145dcbSDimitry Andric std::unique_ptr<raw_pwrite_stream> AsmOutStream;
92ffd1746dSEd Schouten ASTContext *Context;
93ffd1746dSEd Schouten
94ffd1746dSEd Schouten Timer LLVMIRGeneration;
9544290647SDimitry Andric unsigned LLVMIRGenerationRefCount;
9644290647SDimitry Andric
9744290647SDimitry Andric /// True if we've finished generating IR. This prevents us from generating
9844290647SDimitry Andric /// additional LLVM IR after emitting output in HandleTranslationUnit. This
9944290647SDimitry Andric /// can happen when Clang plugins trigger additional AST deserialization.
10044290647SDimitry Andric bool IRGenFinished = false;
101ffd1746dSEd Schouten
10259d1ed5bSDimitry Andric std::unique_ptr<CodeGenerator> Gen;
103ffd1746dSEd Schouten
10420e90f04SDimitry Andric SmallVector<LinkModule, 4> LinkModules;
1050623d748SDimitry Andric
1060623d748SDimitry Andric // This is here so that the diagnostic printer knows the module a diagnostic
1070623d748SDimitry Andric // refers to.
1080623d748SDimitry Andric llvm::Module *CurLinkModule = nullptr;
109ffd1746dSEd Schouten
110ffd1746dSEd Schouten public:
BackendConsumer(BackendAction Action,DiagnosticsEngine & Diags,const HeaderSearchOptions & HeaderSearchOpts,const PreprocessorOptions & PPOpts,const CodeGenOptions & CodeGenOpts,const TargetOptions & TargetOpts,const LangOptions & LangOpts,bool TimePasses,const std::string & InFile,SmallVector<LinkModule,4> LinkModules,std::unique_ptr<raw_pwrite_stream> OS,LLVMContext & C,CoverageSourceInfo * CoverageInfo=nullptr)11120e90f04SDimitry Andric BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
1123dac3a9bSDimitry Andric const HeaderSearchOptions &HeaderSearchOpts,
11320e90f04SDimitry Andric const PreprocessorOptions &PPOpts,
11420e90f04SDimitry Andric const CodeGenOptions &CodeGenOpts,
11520e90f04SDimitry Andric const TargetOptions &TargetOpts,
11620e90f04SDimitry Andric const LangOptions &LangOpts, bool TimePasses,
11720e90f04SDimitry Andric const std::string &InFile,
11820e90f04SDimitry Andric SmallVector<LinkModule, 4> LinkModules,
119e7145dcbSDimitry Andric std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C,
12039d628a0SDimitry Andric CoverageSourceInfo *CoverageInfo = nullptr)
12195ec533aSDimitry Andric : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
12295ec533aSDimitry Andric CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
123e7145dcbSDimitry Andric AsmOutStream(std::move(OS)), Context(nullptr),
12444290647SDimitry Andric LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
12544290647SDimitry Andric LLVMIRGenerationRefCount(0),
1263dac3a9bSDimitry Andric Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
12720e90f04SDimitry Andric CodeGenOpts, C, CoverageInfo)),
12820e90f04SDimitry Andric LinkModules(std::move(LinkModules)) {
1294ba319b5SDimitry Andric FrontendTimesIsEnabled = TimePasses;
130ffd1746dSEd Schouten llvm::TimePassesIsEnabled = TimePasses;
131ffd1746dSEd Schouten }
getModule() const132e7145dcbSDimitry Andric llvm::Module *getModule() const { return Gen->GetModule(); }
takeModule()133e7145dcbSDimitry Andric std::unique_ptr<llvm::Module> takeModule() {
134e7145dcbSDimitry Andric return std::unique_ptr<llvm::Module>(Gen->ReleaseModule());
135e7145dcbSDimitry Andric }
13620e90f04SDimitry Andric
getCodeGenerator()13720e90f04SDimitry Andric CodeGenerator *getCodeGenerator() { return Gen.get(); }
138dff0c46cSDimitry Andric
HandleCXXStaticMemberVarInstantiation(VarDecl * VD)13959d1ed5bSDimitry Andric void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
140dff0c46cSDimitry Andric Gen->HandleCXXStaticMemberVarInstantiation(VD);
141dff0c46cSDimitry Andric }
142ffd1746dSEd Schouten
Initialize(ASTContext & Ctx)14359d1ed5bSDimitry Andric void Initialize(ASTContext &Ctx) override {
1440623d748SDimitry Andric assert(!Context && "initialized multiple times");
14533956c43SDimitry Andric
146ffd1746dSEd Schouten Context = &Ctx;
147ffd1746dSEd Schouten
1484ba319b5SDimitry Andric if (FrontendTimesIsEnabled)
149ffd1746dSEd Schouten LLVMIRGeneration.startTimer();
150ffd1746dSEd Schouten
151ffd1746dSEd Schouten Gen->Initialize(Ctx);
152ffd1746dSEd Schouten
1534ba319b5SDimitry Andric if (FrontendTimesIsEnabled)
154ffd1746dSEd Schouten LLVMIRGeneration.stopTimer();
155ffd1746dSEd Schouten }
156ffd1746dSEd Schouten
HandleTopLevelDecl(DeclGroupRef D)15759d1ed5bSDimitry Andric bool HandleTopLevelDecl(DeclGroupRef D) override {
158ffd1746dSEd Schouten PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
159ffd1746dSEd Schouten Context->getSourceManager(),
160ffd1746dSEd Schouten "LLVM IR generation of declaration");
161ffd1746dSEd Schouten
16244290647SDimitry Andric // Recurse.
1634ba319b5SDimitry Andric if (FrontendTimesIsEnabled) {
16444290647SDimitry Andric LLVMIRGenerationRefCount += 1;
16544290647SDimitry Andric if (LLVMIRGenerationRefCount == 1)
166ffd1746dSEd Schouten LLVMIRGeneration.startTimer();
16744290647SDimitry Andric }
168ffd1746dSEd Schouten
169ffd1746dSEd Schouten Gen->HandleTopLevelDecl(D);
170ffd1746dSEd Schouten
1714ba319b5SDimitry Andric if (FrontendTimesIsEnabled) {
17244290647SDimitry Andric LLVMIRGenerationRefCount -= 1;
17344290647SDimitry Andric if (LLVMIRGenerationRefCount == 0)
174ffd1746dSEd Schouten LLVMIRGeneration.stopTimer();
17544290647SDimitry Andric }
176dff0c46cSDimitry Andric
177dff0c46cSDimitry Andric return true;
178ffd1746dSEd Schouten }
179ffd1746dSEd Schouten
HandleInlineFunctionDefinition(FunctionDecl * D)180e7145dcbSDimitry Andric void HandleInlineFunctionDefinition(FunctionDecl *D) override {
18159d1ed5bSDimitry Andric PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
18259d1ed5bSDimitry Andric Context->getSourceManager(),
183e7145dcbSDimitry Andric "LLVM IR generation of inline function");
1844ba319b5SDimitry Andric if (FrontendTimesIsEnabled)
18559d1ed5bSDimitry Andric LLVMIRGeneration.startTimer();
18659d1ed5bSDimitry Andric
187e7145dcbSDimitry Andric Gen->HandleInlineFunctionDefinition(D);
18859d1ed5bSDimitry Andric
1894ba319b5SDimitry Andric if (FrontendTimesIsEnabled)
19059d1ed5bSDimitry Andric LLVMIRGeneration.stopTimer();
19159d1ed5bSDimitry Andric }
19259d1ed5bSDimitry Andric
HandleInterestingDecl(DeclGroupRef D)19344290647SDimitry Andric void HandleInterestingDecl(DeclGroupRef D) override {
19444290647SDimitry Andric // Ignore interesting decls from the AST reader after IRGen is finished.
19544290647SDimitry Andric if (!IRGenFinished)
19644290647SDimitry Andric HandleTopLevelDecl(D);
19744290647SDimitry Andric }
19844290647SDimitry Andric
19920e90f04SDimitry Andric // Links each entry in LinkModules into our module. Returns true on error.
LinkInModules()20020e90f04SDimitry Andric bool LinkInModules() {
20120e90f04SDimitry Andric for (auto &LM : LinkModules) {
20220e90f04SDimitry Andric if (LM.PropagateAttrs)
20320e90f04SDimitry Andric for (Function &F : *LM.Module)
20420e90f04SDimitry Andric Gen->CGM().AddDefaultFnAttrs(F);
20520e90f04SDimitry Andric
20620e90f04SDimitry Andric CurLinkModule = LM.Module.get();
20720e90f04SDimitry Andric
20820e90f04SDimitry Andric bool Err;
20920e90f04SDimitry Andric if (LM.Internalize) {
21020e90f04SDimitry Andric Err = Linker::linkModules(
21120e90f04SDimitry Andric *getModule(), std::move(LM.Module), LM.LinkFlags,
21220e90f04SDimitry Andric [](llvm::Module &M, const llvm::StringSet<> &GVS) {
21320e90f04SDimitry Andric internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) {
21420e90f04SDimitry Andric return !GV.hasName() || (GVS.count(GV.getName()) == 0);
21520e90f04SDimitry Andric });
21620e90f04SDimitry Andric });
21720e90f04SDimitry Andric } else {
21820e90f04SDimitry Andric Err = Linker::linkModules(*getModule(), std::move(LM.Module),
21920e90f04SDimitry Andric LM.LinkFlags);
22020e90f04SDimitry Andric }
22120e90f04SDimitry Andric
22220e90f04SDimitry Andric if (Err)
22320e90f04SDimitry Andric return true;
22420e90f04SDimitry Andric }
22520e90f04SDimitry Andric return false; // success
22620e90f04SDimitry Andric }
22720e90f04SDimitry Andric
HandleTranslationUnit(ASTContext & C)22859d1ed5bSDimitry Andric void HandleTranslationUnit(ASTContext &C) override {
229ffd1746dSEd Schouten {
230ffd1746dSEd Schouten PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
2314ba319b5SDimitry Andric if (FrontendTimesIsEnabled) {
23244290647SDimitry Andric LLVMIRGenerationRefCount += 1;
23344290647SDimitry Andric if (LLVMIRGenerationRefCount == 1)
234ffd1746dSEd Schouten LLVMIRGeneration.startTimer();
23544290647SDimitry Andric }
236ffd1746dSEd Schouten
237ffd1746dSEd Schouten Gen->HandleTranslationUnit(C);
238ffd1746dSEd Schouten
2394ba319b5SDimitry Andric if (FrontendTimesIsEnabled) {
24044290647SDimitry Andric LLVMIRGenerationRefCount -= 1;
24144290647SDimitry Andric if (LLVMIRGenerationRefCount == 0)
242ffd1746dSEd Schouten LLVMIRGeneration.stopTimer();
243ffd1746dSEd Schouten }
244ffd1746dSEd Schouten
24544290647SDimitry Andric IRGenFinished = true;
24644290647SDimitry Andric }
24744290647SDimitry Andric
248ffd1746dSEd Schouten // Silently ignore if we weren't initialized for some reason.
249e7145dcbSDimitry Andric if (!getModule())
250ffd1746dSEd Schouten return;
251ffd1746dSEd Schouten
252ffd1746dSEd Schouten // Install an inline asm handler so that diagnostics get printed through
253ffd1746dSEd Schouten // our diagnostics hooks.
254e7145dcbSDimitry Andric LLVMContext &Ctx = getModule()->getContext();
2552754fe60SDimitry Andric LLVMContext::InlineAsmDiagHandlerTy OldHandler =
2562754fe60SDimitry Andric Ctx.getInlineAsmDiagnosticHandler();
257ffd1746dSEd Schouten void *OldContext = Ctx.getInlineAsmDiagnosticContext();
2582754fe60SDimitry Andric Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this);
259ffd1746dSEd Schouten
2609a199699SDimitry Andric std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler =
26159d1ed5bSDimitry Andric Ctx.getDiagnosticHandler();
2629a199699SDimitry Andric Ctx.setDiagnosticHandler(llvm::make_unique<ClangDiagnosticHandler>(
2639a199699SDimitry Andric CodeGenOpts, this));
264a580b014SDimitry Andric Ctx.setDiagnosticsHotnessRequested(CodeGenOpts.DiagnosticsWithHotness);
265a580b014SDimitry Andric if (CodeGenOpts.DiagnosticsHotnessThreshold != 0)
266a580b014SDimitry Andric Ctx.setDiagnosticsHotnessThreshold(
267a580b014SDimitry Andric CodeGenOpts.DiagnosticsHotnessThreshold);
26844290647SDimitry Andric
2699a199699SDimitry Andric std::unique_ptr<llvm::ToolOutputFile> OptRecordFile;
27044290647SDimitry Andric if (!CodeGenOpts.OptRecordFile.empty()) {
27144290647SDimitry Andric std::error_code EC;
2729a199699SDimitry Andric OptRecordFile = llvm::make_unique<llvm::ToolOutputFile>(
2739a199699SDimitry Andric CodeGenOpts.OptRecordFile, EC, sys::fs::F_None);
27444290647SDimitry Andric if (EC) {
27544290647SDimitry Andric Diags.Report(diag::err_cannot_open_file) <<
27644290647SDimitry Andric CodeGenOpts.OptRecordFile << EC.message();
27744290647SDimitry Andric return;
27844290647SDimitry Andric }
27944290647SDimitry Andric
28044290647SDimitry Andric Ctx.setDiagnosticsOutputFile(
28144290647SDimitry Andric llvm::make_unique<yaml::Output>(OptRecordFile->os()));
28244290647SDimitry Andric
28344290647SDimitry Andric if (CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone)
284a580b014SDimitry Andric Ctx.setDiagnosticsHotnessRequested(true);
28544290647SDimitry Andric }
28659d1ed5bSDimitry Andric
28720e90f04SDimitry Andric // Link each LinkModule into our module.
28820e90f04SDimitry Andric if (LinkInModules())
2890623d748SDimitry Andric return;
2900623d748SDimitry Andric
291e7145dcbSDimitry Andric EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef());
292e7145dcbSDimitry Andric
29395ec533aSDimitry Andric EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
29495ec533aSDimitry Andric LangOpts, C.getTargetInfo().getDataLayout(),
295e7145dcbSDimitry Andric getModule(), Action, std::move(AsmOutStream));
296ffd1746dSEd Schouten
297ffd1746dSEd Schouten Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
29859d1ed5bSDimitry Andric
2999a199699SDimitry Andric Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
30044290647SDimitry Andric
30144290647SDimitry Andric if (OptRecordFile)
30244290647SDimitry Andric OptRecordFile->keep();
303ffd1746dSEd Schouten }
304ffd1746dSEd Schouten
HandleTagDeclDefinition(TagDecl * D)30559d1ed5bSDimitry Andric void HandleTagDeclDefinition(TagDecl *D) override {
306ffd1746dSEd Schouten PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
307ffd1746dSEd Schouten Context->getSourceManager(),
308ffd1746dSEd Schouten "LLVM IR generation of declaration");
309ffd1746dSEd Schouten Gen->HandleTagDeclDefinition(D);
310ffd1746dSEd Schouten }
311ffd1746dSEd Schouten
HandleTagDeclRequiredDefinition(const TagDecl * D)31259d1ed5bSDimitry Andric void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
313f785676fSDimitry Andric Gen->HandleTagDeclRequiredDefinition(D);
314f785676fSDimitry Andric }
315f785676fSDimitry Andric
CompleteTentativeDefinition(VarDecl * D)31659d1ed5bSDimitry Andric void CompleteTentativeDefinition(VarDecl *D) override {
317ffd1746dSEd Schouten Gen->CompleteTentativeDefinition(D);
318ffd1746dSEd Schouten }
319ffd1746dSEd Schouten
AssignInheritanceModel(CXXRecordDecl * RD)320e7145dcbSDimitry Andric void AssignInheritanceModel(CXXRecordDecl *RD) override {
321e7145dcbSDimitry Andric Gen->AssignInheritanceModel(RD);
322e7145dcbSDimitry Andric }
323e7145dcbSDimitry Andric
HandleVTable(CXXRecordDecl * RD)32433956c43SDimitry Andric void HandleVTable(CXXRecordDecl *RD) override {
32533956c43SDimitry Andric Gen->HandleVTable(RD);
326ffd1746dSEd Schouten }
327ffd1746dSEd Schouten
InlineAsmDiagHandler(const llvm::SMDiagnostic & SM,void * Context,unsigned LocCookie)328ffd1746dSEd Schouten static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,
329ffd1746dSEd Schouten unsigned LocCookie) {
330ffd1746dSEd Schouten SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie);
331ffd1746dSEd Schouten ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc);
332ffd1746dSEd Schouten }
333ffd1746dSEd Schouten
334e7145dcbSDimitry Andric /// Get the best possible source location to represent a diagnostic that
335e7145dcbSDimitry Andric /// may have associated debug info.
336e7145dcbSDimitry Andric const FullSourceLoc
33720e90f04SDimitry Andric getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithLocationBase &D,
338e7145dcbSDimitry Andric bool &BadDebugInfo, StringRef &Filename,
339e7145dcbSDimitry Andric unsigned &Line, unsigned &Column) const;
340e7145dcbSDimitry Andric
341ffd1746dSEd Schouten void InlineAsmDiagHandler2(const llvm::SMDiagnostic &,
342ffd1746dSEd Schouten SourceLocation LocCookie);
34359d1ed5bSDimitry Andric
34459d1ed5bSDimitry Andric void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI);
3454ba319b5SDimitry Andric /// Specialized handler for InlineAsm diagnostic.
34659d1ed5bSDimitry Andric /// \return True if the diagnostic has been successfully reported, false
34759d1ed5bSDimitry Andric /// otherwise.
34859d1ed5bSDimitry Andric bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D);
3494ba319b5SDimitry Andric /// Specialized handler for StackSize diagnostic.
35059d1ed5bSDimitry Andric /// \return True if the diagnostic has been successfully reported, false
35159d1ed5bSDimitry Andric /// otherwise.
35259d1ed5bSDimitry Andric bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D);
3534ba319b5SDimitry Andric /// Specialized handler for unsupported backend feature diagnostic.
354e7145dcbSDimitry Andric void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D);
3554ba319b5SDimitry Andric /// Specialized handlers for optimization remarks.
35659d1ed5bSDimitry Andric /// Note that these handlers only accept remarks and they always handle
35759d1ed5bSDimitry Andric /// them.
35859d1ed5bSDimitry Andric void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D,
35959d1ed5bSDimitry Andric unsigned DiagID);
36020e90f04SDimitry Andric void
36120e90f04SDimitry Andric OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D);
36259d1ed5bSDimitry Andric void OptimizationRemarkHandler(
36344290647SDimitry Andric const llvm::OptimizationRemarkAnalysisFPCommute &D);
36459d1ed5bSDimitry Andric void OptimizationRemarkHandler(
36544290647SDimitry Andric const llvm::OptimizationRemarkAnalysisAliasing &D);
36659d1ed5bSDimitry Andric void OptimizationFailureHandler(
36759d1ed5bSDimitry Andric const llvm::DiagnosticInfoOptimizationFailure &D);
368ffd1746dSEd Schouten };
369dff0c46cSDimitry Andric
anchor()370dff0c46cSDimitry Andric void BackendConsumer::anchor() {}
371ffd1746dSEd Schouten }
372ffd1746dSEd Schouten
handleDiagnostics(const DiagnosticInfo & DI)3739a199699SDimitry Andric bool ClangDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) {
3749a199699SDimitry Andric BackendCon->DiagnosticHandlerImpl(DI);
3759a199699SDimitry Andric return true;
3769a199699SDimitry Andric }
3779a199699SDimitry Andric
378ffd1746dSEd Schouten /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr
379ffd1746dSEd Schouten /// buffer to be a valid FullSourceLoc.
ConvertBackendLocation(const llvm::SMDiagnostic & D,SourceManager & CSM)380ffd1746dSEd Schouten static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D,
381ffd1746dSEd Schouten SourceManager &CSM) {
382ffd1746dSEd Schouten // Get both the clang and llvm source managers. The location is relative to
383ffd1746dSEd Schouten // a memory buffer that the LLVM Source Manager is handling, we need to add
384ffd1746dSEd Schouten // a copy to the Clang source manager.
385ffd1746dSEd Schouten const llvm::SourceMgr &LSM = *D.getSourceMgr();
386ffd1746dSEd Schouten
387ffd1746dSEd Schouten // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr
388ffd1746dSEd Schouten // already owns its one and clang::SourceManager wants to own its one.
389ffd1746dSEd Schouten const MemoryBuffer *LBuf =
390ffd1746dSEd Schouten LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
391ffd1746dSEd Schouten
392ffd1746dSEd Schouten // Create the copy and transfer ownership to clang::SourceManager.
39359d1ed5bSDimitry Andric // TODO: Avoid copying files into memory.
39439d628a0SDimitry Andric std::unique_ptr<llvm::MemoryBuffer> CBuf =
395ffd1746dSEd Schouten llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(),
396ffd1746dSEd Schouten LBuf->getBufferIdentifier());
39759d1ed5bSDimitry Andric // FIXME: Keep a file ID map instead of creating new IDs for each location.
39839d628a0SDimitry Andric FileID FID = CSM.createFileID(std::move(CBuf));
399ffd1746dSEd Schouten
400ffd1746dSEd Schouten // Translate the offset into the file.
401ffd1746dSEd Schouten unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
402ffd1746dSEd Schouten SourceLocation NewLoc =
4036122f3e6SDimitry Andric CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset);
404ffd1746dSEd Schouten return FullSourceLoc(NewLoc, CSM);
405ffd1746dSEd Schouten }
406ffd1746dSEd Schouten
407ffd1746dSEd Schouten
408ffd1746dSEd Schouten /// InlineAsmDiagHandler2 - This function is invoked when the backend hits an
409ffd1746dSEd Schouten /// error parsing inline asm. The SMDiagnostic indicates the error relative to
410ffd1746dSEd Schouten /// the temporary memory buffer that the inline asm parser has set up.
InlineAsmDiagHandler2(const llvm::SMDiagnostic & D,SourceLocation LocCookie)411ffd1746dSEd Schouten void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D,
412ffd1746dSEd Schouten SourceLocation LocCookie) {
413ffd1746dSEd Schouten // There are a couple of different kinds of errors we could get here. First,
414ffd1746dSEd Schouten // we re-format the SMDiagnostic in terms of a clang diagnostic.
415ffd1746dSEd Schouten
416ffd1746dSEd Schouten // Strip "error: " off the start of the message string.
4176122f3e6SDimitry Andric StringRef Message = D.getMessage();
418ffd1746dSEd Schouten if (Message.startswith("error: "))
419ffd1746dSEd Schouten Message = Message.substr(7);
420ffd1746dSEd Schouten
421ffd1746dSEd Schouten // If the SMDiagnostic has an inline asm source location, translate it.
422ffd1746dSEd Schouten FullSourceLoc Loc;
423ffd1746dSEd Schouten if (D.getLoc() != SMLoc())
424ffd1746dSEd Schouten Loc = ConvertBackendLocation(D, Context->getSourceManager());
425ffd1746dSEd Schouten
42659d1ed5bSDimitry Andric unsigned DiagID;
42759d1ed5bSDimitry Andric switch (D.getKind()) {
42859d1ed5bSDimitry Andric case llvm::SourceMgr::DK_Error:
42959d1ed5bSDimitry Andric DiagID = diag::err_fe_inline_asm;
43059d1ed5bSDimitry Andric break;
43159d1ed5bSDimitry Andric case llvm::SourceMgr::DK_Warning:
43259d1ed5bSDimitry Andric DiagID = diag::warn_fe_inline_asm;
43359d1ed5bSDimitry Andric break;
43459d1ed5bSDimitry Andric case llvm::SourceMgr::DK_Note:
43559d1ed5bSDimitry Andric DiagID = diag::note_fe_inline_asm;
43659d1ed5bSDimitry Andric break;
4379a199699SDimitry Andric case llvm::SourceMgr::DK_Remark:
4389a199699SDimitry Andric llvm_unreachable("remarks unexpected");
43959d1ed5bSDimitry Andric }
440ffd1746dSEd Schouten // If this problem has clang-level source location information, report the
44159d1ed5bSDimitry Andric // issue in the source with a note showing the instantiated
442ffd1746dSEd Schouten // code.
443ffd1746dSEd Schouten if (LocCookie.isValid()) {
44459d1ed5bSDimitry Andric Diags.Report(LocCookie, DiagID).AddString(Message);
445ffd1746dSEd Schouten
446dff0c46cSDimitry Andric if (D.getLoc().isValid()) {
447dff0c46cSDimitry Andric DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here);
448dff0c46cSDimitry Andric // Convert the SMDiagnostic ranges into SourceRange and attach them
449dff0c46cSDimitry Andric // to the diagnostic.
4500623d748SDimitry Andric for (const std::pair<unsigned, unsigned> &Range : D.getRanges()) {
451dff0c46cSDimitry Andric unsigned Column = D.getColumnNo();
452dff0c46cSDimitry Andric B << SourceRange(Loc.getLocWithOffset(Range.first - Column),
453dff0c46cSDimitry Andric Loc.getLocWithOffset(Range.second - Column));
454dff0c46cSDimitry Andric }
455dff0c46cSDimitry Andric }
456ffd1746dSEd Schouten return;
457ffd1746dSEd Schouten }
458ffd1746dSEd Schouten
45959d1ed5bSDimitry Andric // Otherwise, report the backend issue as occurring in the generated .s file.
46059d1ed5bSDimitry Andric // If Loc is invalid, we still need to report the issue, it just gets no
461ffd1746dSEd Schouten // location info.
46259d1ed5bSDimitry Andric Diags.Report(Loc, DiagID).AddString(Message);
463ffd1746dSEd Schouten }
464ffd1746dSEd Schouten
46559d1ed5bSDimitry Andric #define ComputeDiagID(Severity, GroupName, DiagID) \
46659d1ed5bSDimitry Andric do { \
46759d1ed5bSDimitry Andric switch (Severity) { \
46859d1ed5bSDimitry Andric case llvm::DS_Error: \
46959d1ed5bSDimitry Andric DiagID = diag::err_fe_##GroupName; \
47059d1ed5bSDimitry Andric break; \
47159d1ed5bSDimitry Andric case llvm::DS_Warning: \
47259d1ed5bSDimitry Andric DiagID = diag::warn_fe_##GroupName; \
47359d1ed5bSDimitry Andric break; \
47459d1ed5bSDimitry Andric case llvm::DS_Remark: \
47559d1ed5bSDimitry Andric llvm_unreachable("'remark' severity not expected"); \
47659d1ed5bSDimitry Andric break; \
47759d1ed5bSDimitry Andric case llvm::DS_Note: \
47859d1ed5bSDimitry Andric DiagID = diag::note_fe_##GroupName; \
47959d1ed5bSDimitry Andric break; \
48059d1ed5bSDimitry Andric } \
48159d1ed5bSDimitry Andric } while (false)
48259d1ed5bSDimitry Andric
48359d1ed5bSDimitry Andric #define ComputeDiagRemarkID(Severity, GroupName, DiagID) \
48459d1ed5bSDimitry Andric do { \
48559d1ed5bSDimitry Andric switch (Severity) { \
48659d1ed5bSDimitry Andric case llvm::DS_Error: \
48759d1ed5bSDimitry Andric DiagID = diag::err_fe_##GroupName; \
48859d1ed5bSDimitry Andric break; \
48959d1ed5bSDimitry Andric case llvm::DS_Warning: \
49059d1ed5bSDimitry Andric DiagID = diag::warn_fe_##GroupName; \
49159d1ed5bSDimitry Andric break; \
49259d1ed5bSDimitry Andric case llvm::DS_Remark: \
49359d1ed5bSDimitry Andric DiagID = diag::remark_fe_##GroupName; \
49459d1ed5bSDimitry Andric break; \
49559d1ed5bSDimitry Andric case llvm::DS_Note: \
49659d1ed5bSDimitry Andric DiagID = diag::note_fe_##GroupName; \
49759d1ed5bSDimitry Andric break; \
49859d1ed5bSDimitry Andric } \
49959d1ed5bSDimitry Andric } while (false)
50059d1ed5bSDimitry Andric
50159d1ed5bSDimitry Andric bool
InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm & D)50259d1ed5bSDimitry Andric BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) {
50359d1ed5bSDimitry Andric unsigned DiagID;
50459d1ed5bSDimitry Andric ComputeDiagID(D.getSeverity(), inline_asm, DiagID);
50559d1ed5bSDimitry Andric std::string Message = D.getMsgStr().str();
50659d1ed5bSDimitry Andric
50759d1ed5bSDimitry Andric // If this problem has clang-level source location information, report the
50859d1ed5bSDimitry Andric // issue as being a problem in the source with a note showing the instantiated
50959d1ed5bSDimitry Andric // code.
51059d1ed5bSDimitry Andric SourceLocation LocCookie =
51159d1ed5bSDimitry Andric SourceLocation::getFromRawEncoding(D.getLocCookie());
51259d1ed5bSDimitry Andric if (LocCookie.isValid())
51359d1ed5bSDimitry Andric Diags.Report(LocCookie, DiagID).AddString(Message);
51459d1ed5bSDimitry Andric else {
51559d1ed5bSDimitry Andric // Otherwise, report the backend diagnostic as occurring in the generated
51659d1ed5bSDimitry Andric // .s file.
51759d1ed5bSDimitry Andric // If Loc is invalid, we still need to report the diagnostic, it just gets
51859d1ed5bSDimitry Andric // no location info.
51959d1ed5bSDimitry Andric FullSourceLoc Loc;
52059d1ed5bSDimitry Andric Diags.Report(Loc, DiagID).AddString(Message);
52159d1ed5bSDimitry Andric }
52259d1ed5bSDimitry Andric // We handled all the possible severities.
52359d1ed5bSDimitry Andric return true;
52459d1ed5bSDimitry Andric }
52559d1ed5bSDimitry Andric
52659d1ed5bSDimitry Andric bool
StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize & D)52759d1ed5bSDimitry Andric BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) {
52859d1ed5bSDimitry Andric if (D.getSeverity() != llvm::DS_Warning)
52959d1ed5bSDimitry Andric // For now, the only support we have for StackSize diagnostic is warning.
53059d1ed5bSDimitry Andric // We do not know how to format other severities.
53159d1ed5bSDimitry Andric return false;
53259d1ed5bSDimitry Andric
53359d1ed5bSDimitry Andric if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) {
534e7145dcbSDimitry Andric // FIXME: Shouldn't need to truncate to uint32_t
53559d1ed5bSDimitry Andric Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()),
53659d1ed5bSDimitry Andric diag::warn_fe_frame_larger_than)
537e7145dcbSDimitry Andric << static_cast<uint32_t>(D.getStackSize()) << Decl::castToDeclContext(ND);
53859d1ed5bSDimitry Andric return true;
53959d1ed5bSDimitry Andric }
54059d1ed5bSDimitry Andric
54159d1ed5bSDimitry Andric return false;
54259d1ed5bSDimitry Andric }
54359d1ed5bSDimitry Andric
getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithLocationBase & D,bool & BadDebugInfo,StringRef & Filename,unsigned & Line,unsigned & Column) const544e7145dcbSDimitry Andric const FullSourceLoc BackendConsumer::getBestLocationFromDebugLoc(
54520e90f04SDimitry Andric const llvm::DiagnosticInfoWithLocationBase &D, bool &BadDebugInfo,
54620e90f04SDimitry Andric StringRef &Filename, unsigned &Line, unsigned &Column) const {
54759d1ed5bSDimitry Andric SourceManager &SourceMgr = Context->getSourceManager();
54859d1ed5bSDimitry Andric FileManager &FileMgr = SourceMgr.getFileManager();
54959d1ed5bSDimitry Andric SourceLocation DILoc;
55033956c43SDimitry Andric
55133956c43SDimitry Andric if (D.isLocationAvailable()) {
552*b5893f02SDimitry Andric D.getLocation(Filename, Line, Column);
553*b5893f02SDimitry Andric if (Line > 0) {
55459d1ed5bSDimitry Andric const FileEntry *FE = FileMgr.getFile(Filename);
555*b5893f02SDimitry Andric if (!FE)
556*b5893f02SDimitry Andric FE = FileMgr.getFile(D.getAbsolutePath());
557*b5893f02SDimitry Andric if (FE) {
55859d1ed5bSDimitry Andric // If -gcolumn-info was not used, Column will be 0. This upsets the
55959d1ed5bSDimitry Andric // source manager, so pass 1 if Column is not set.
56059d1ed5bSDimitry Andric DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1);
56159d1ed5bSDimitry Andric }
562*b5893f02SDimitry Andric }
563e7145dcbSDimitry Andric BadDebugInfo = DILoc.isInvalid();
56433956c43SDimitry Andric }
56559d1ed5bSDimitry Andric
56659d1ed5bSDimitry Andric // If a location isn't available, try to approximate it using the associated
56759d1ed5bSDimitry Andric // function definition. We use the definition's right brace to differentiate
56859d1ed5bSDimitry Andric // from diagnostics that genuinely relate to the function itself.
56959d1ed5bSDimitry Andric FullSourceLoc Loc(DILoc, SourceMgr);
57059d1ed5bSDimitry Andric if (Loc.isInvalid())
57159d1ed5bSDimitry Andric if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName()))
572e7145dcbSDimitry Andric Loc = FD->getASTContext().getFullLoc(FD->getLocation());
57359d1ed5bSDimitry Andric
57433956c43SDimitry Andric if (DILoc.isInvalid() && D.isLocationAvailable())
57559d1ed5bSDimitry Andric // If we were not able to translate the file:line:col information
57659d1ed5bSDimitry Andric // back to a SourceLocation, at least emit a note stating that
57759d1ed5bSDimitry Andric // we could not translate this location. This can happen in the
57859d1ed5bSDimitry Andric // case of #line directives.
579e7145dcbSDimitry Andric Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
580e7145dcbSDimitry Andric << Filename << Line << Column;
581e7145dcbSDimitry Andric
582e7145dcbSDimitry Andric return Loc;
583e7145dcbSDimitry Andric }
584e7145dcbSDimitry Andric
UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported & D)585e7145dcbSDimitry Andric void BackendConsumer::UnsupportedDiagHandler(
586e7145dcbSDimitry Andric const llvm::DiagnosticInfoUnsupported &D) {
587e7145dcbSDimitry Andric // We only support errors.
588e7145dcbSDimitry Andric assert(D.getSeverity() == llvm::DS_Error);
589e7145dcbSDimitry Andric
590e7145dcbSDimitry Andric StringRef Filename;
591e7145dcbSDimitry Andric unsigned Line, Column;
5925517e702SDimitry Andric bool BadDebugInfo = false;
5935517e702SDimitry Andric FullSourceLoc Loc =
5945517e702SDimitry Andric getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
595e7145dcbSDimitry Andric
596e7145dcbSDimitry Andric Diags.Report(Loc, diag::err_fe_backend_unsupported) << D.getMessage().str();
597e7145dcbSDimitry Andric
598e7145dcbSDimitry Andric if (BadDebugInfo)
599e7145dcbSDimitry Andric // If we were not able to translate the file:line:col information
600e7145dcbSDimitry Andric // back to a SourceLocation, at least emit a note stating that
601e7145dcbSDimitry Andric // we could not translate this location. This can happen in the
602e7145dcbSDimitry Andric // case of #line directives.
603e7145dcbSDimitry Andric Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
604e7145dcbSDimitry Andric << Filename << Line << Column;
605e7145dcbSDimitry Andric }
606e7145dcbSDimitry Andric
EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase & D,unsigned DiagID)607e7145dcbSDimitry Andric void BackendConsumer::EmitOptimizationMessage(
608e7145dcbSDimitry Andric const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) {
609e7145dcbSDimitry Andric // We only support warnings and remarks.
610e7145dcbSDimitry Andric assert(D.getSeverity() == llvm::DS_Remark ||
611e7145dcbSDimitry Andric D.getSeverity() == llvm::DS_Warning);
612e7145dcbSDimitry Andric
613e7145dcbSDimitry Andric StringRef Filename;
614e7145dcbSDimitry Andric unsigned Line, Column;
615e7145dcbSDimitry Andric bool BadDebugInfo = false;
6165517e702SDimitry Andric FullSourceLoc Loc =
6175517e702SDimitry Andric getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
618e7145dcbSDimitry Andric
61944290647SDimitry Andric std::string Msg;
62044290647SDimitry Andric raw_string_ostream MsgStream(Msg);
62144290647SDimitry Andric MsgStream << D.getMsg();
62244290647SDimitry Andric
62344290647SDimitry Andric if (D.getHotness())
62444290647SDimitry Andric MsgStream << " (hotness: " << *D.getHotness() << ")";
62544290647SDimitry Andric
626e7145dcbSDimitry Andric Diags.Report(Loc, DiagID)
62744290647SDimitry Andric << AddFlagValue(D.getPassName())
62844290647SDimitry Andric << MsgStream.str();
629e7145dcbSDimitry Andric
630e7145dcbSDimitry Andric if (BadDebugInfo)
631e7145dcbSDimitry Andric // If we were not able to translate the file:line:col information
632e7145dcbSDimitry Andric // back to a SourceLocation, at least emit a note stating that
633e7145dcbSDimitry Andric // we could not translate this location. This can happen in the
634e7145dcbSDimitry Andric // case of #line directives.
635e7145dcbSDimitry Andric Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
63659d1ed5bSDimitry Andric << Filename << Line << Column;
63759d1ed5bSDimitry Andric }
63859d1ed5bSDimitry Andric
OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase & D)63959d1ed5bSDimitry Andric void BackendConsumer::OptimizationRemarkHandler(
64020e90f04SDimitry Andric const llvm::DiagnosticInfoOptimizationBase &D) {
6419a199699SDimitry Andric // Without hotness information, don't show noisy remarks.
6429a199699SDimitry Andric if (D.isVerbose() && !D.getHotness())
6439a199699SDimitry Andric return;
6449a199699SDimitry Andric
64520e90f04SDimitry Andric if (D.isPassed()) {
64659d1ed5bSDimitry Andric // Optimization remarks are active only if the -Rpass flag has a regular
64759d1ed5bSDimitry Andric // expression that matches the name of the pass name in \p D.
64859d1ed5bSDimitry Andric if (CodeGenOpts.OptimizationRemarkPattern &&
64959d1ed5bSDimitry Andric CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName()))
65059d1ed5bSDimitry Andric EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark);
65120e90f04SDimitry Andric } else if (D.isMissed()) {
65259d1ed5bSDimitry Andric // Missed optimization remarks are active only if the -Rpass-missed
65359d1ed5bSDimitry Andric // flag has a regular expression that matches the name of the pass
65459d1ed5bSDimitry Andric // name in \p D.
65559d1ed5bSDimitry Andric if (CodeGenOpts.OptimizationRemarkMissedPattern &&
65659d1ed5bSDimitry Andric CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName()))
65720e90f04SDimitry Andric EmitOptimizationMessage(
65820e90f04SDimitry Andric D, diag::remark_fe_backend_optimization_remark_missed);
65920e90f04SDimitry Andric } else {
66020e90f04SDimitry Andric assert(D.isAnalysis() && "Unknown remark type");
66159d1ed5bSDimitry Andric
66220e90f04SDimitry Andric bool ShouldAlwaysPrint = false;
66320e90f04SDimitry Andric if (auto *ORA = dyn_cast<llvm::OptimizationRemarkAnalysis>(&D))
66420e90f04SDimitry Andric ShouldAlwaysPrint = ORA->shouldAlwaysPrint();
6650623d748SDimitry Andric
66620e90f04SDimitry Andric if (ShouldAlwaysPrint ||
6670623d748SDimitry Andric (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
6680623d748SDimitry Andric CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
66959d1ed5bSDimitry Andric EmitOptimizationMessage(
67059d1ed5bSDimitry Andric D, diag::remark_fe_backend_optimization_remark_analysis);
67159d1ed5bSDimitry Andric }
67220e90f04SDimitry Andric }
67359d1ed5bSDimitry Andric
OptimizationRemarkHandler(const llvm::OptimizationRemarkAnalysisFPCommute & D)6740623d748SDimitry Andric void BackendConsumer::OptimizationRemarkHandler(
67544290647SDimitry Andric const llvm::OptimizationRemarkAnalysisFPCommute &D) {
6760623d748SDimitry Andric // Optimization analysis remarks are active if the pass name is set to
6770623d748SDimitry Andric // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a
6780623d748SDimitry Andric // regular expression that matches the name of the pass name in \p D.
6790623d748SDimitry Andric
680e7145dcbSDimitry Andric if (D.shouldAlwaysPrint() ||
6810623d748SDimitry Andric (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
6820623d748SDimitry Andric CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
6830623d748SDimitry Andric EmitOptimizationMessage(
6840623d748SDimitry Andric D, diag::remark_fe_backend_optimization_remark_analysis_fpcommute);
6850623d748SDimitry Andric }
6860623d748SDimitry Andric
OptimizationRemarkHandler(const llvm::OptimizationRemarkAnalysisAliasing & D)6870623d748SDimitry Andric void BackendConsumer::OptimizationRemarkHandler(
68844290647SDimitry Andric const llvm::OptimizationRemarkAnalysisAliasing &D) {
6890623d748SDimitry Andric // Optimization analysis remarks are active if the pass name is set to
6900623d748SDimitry Andric // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a
6910623d748SDimitry Andric // regular expression that matches the name of the pass name in \p D.
6920623d748SDimitry Andric
693e7145dcbSDimitry Andric if (D.shouldAlwaysPrint() ||
6940623d748SDimitry Andric (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
6950623d748SDimitry Andric CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
6960623d748SDimitry Andric EmitOptimizationMessage(
6970623d748SDimitry Andric D, diag::remark_fe_backend_optimization_remark_analysis_aliasing);
6980623d748SDimitry Andric }
6990623d748SDimitry Andric
OptimizationFailureHandler(const llvm::DiagnosticInfoOptimizationFailure & D)70059d1ed5bSDimitry Andric void BackendConsumer::OptimizationFailureHandler(
70159d1ed5bSDimitry Andric const llvm::DiagnosticInfoOptimizationFailure &D) {
70259d1ed5bSDimitry Andric EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure);
70359d1ed5bSDimitry Andric }
70459d1ed5bSDimitry Andric
7054ba319b5SDimitry Andric /// This function is invoked when the backend needs
70659d1ed5bSDimitry Andric /// to report something to the user.
DiagnosticHandlerImpl(const DiagnosticInfo & DI)70759d1ed5bSDimitry Andric void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
70859d1ed5bSDimitry Andric unsigned DiagID = diag::err_fe_inline_asm;
70959d1ed5bSDimitry Andric llvm::DiagnosticSeverity Severity = DI.getSeverity();
71059d1ed5bSDimitry Andric // Get the diagnostic ID based.
71159d1ed5bSDimitry Andric switch (DI.getKind()) {
71259d1ed5bSDimitry Andric case llvm::DK_InlineAsm:
71359d1ed5bSDimitry Andric if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI)))
71459d1ed5bSDimitry Andric return;
71559d1ed5bSDimitry Andric ComputeDiagID(Severity, inline_asm, DiagID);
71659d1ed5bSDimitry Andric break;
71759d1ed5bSDimitry Andric case llvm::DK_StackSize:
71859d1ed5bSDimitry Andric if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI)))
71959d1ed5bSDimitry Andric return;
72059d1ed5bSDimitry Andric ComputeDiagID(Severity, backend_frame_larger_than, DiagID);
72159d1ed5bSDimitry Andric break;
7220623d748SDimitry Andric case DK_Linker:
7230623d748SDimitry Andric assert(CurLinkModule);
7240623d748SDimitry Andric // FIXME: stop eating the warnings and notes.
7250623d748SDimitry Andric if (Severity != DS_Error)
7260623d748SDimitry Andric return;
7270623d748SDimitry Andric DiagID = diag::err_fe_cannot_link_module;
7280623d748SDimitry Andric break;
72959d1ed5bSDimitry Andric case llvm::DK_OptimizationRemark:
73059d1ed5bSDimitry Andric // Optimization remarks are always handled completely by this
73159d1ed5bSDimitry Andric // handler. There is no generic way of emitting them.
73244290647SDimitry Andric OptimizationRemarkHandler(cast<OptimizationRemark>(DI));
73359d1ed5bSDimitry Andric return;
73459d1ed5bSDimitry Andric case llvm::DK_OptimizationRemarkMissed:
73559d1ed5bSDimitry Andric // Optimization remarks are always handled completely by this
73659d1ed5bSDimitry Andric // handler. There is no generic way of emitting them.
73744290647SDimitry Andric OptimizationRemarkHandler(cast<OptimizationRemarkMissed>(DI));
73859d1ed5bSDimitry Andric return;
73959d1ed5bSDimitry Andric case llvm::DK_OptimizationRemarkAnalysis:
74059d1ed5bSDimitry Andric // Optimization remarks are always handled completely by this
74159d1ed5bSDimitry Andric // handler. There is no generic way of emitting them.
74244290647SDimitry Andric OptimizationRemarkHandler(cast<OptimizationRemarkAnalysis>(DI));
74359d1ed5bSDimitry Andric return;
7440623d748SDimitry Andric case llvm::DK_OptimizationRemarkAnalysisFPCommute:
7450623d748SDimitry Andric // Optimization remarks are always handled completely by this
7460623d748SDimitry Andric // handler. There is no generic way of emitting them.
74744290647SDimitry Andric OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisFPCommute>(DI));
7480623d748SDimitry Andric return;
7490623d748SDimitry Andric case llvm::DK_OptimizationRemarkAnalysisAliasing:
7500623d748SDimitry Andric // Optimization remarks are always handled completely by this
7510623d748SDimitry Andric // handler. There is no generic way of emitting them.
75244290647SDimitry Andric OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisAliasing>(DI));
7530623d748SDimitry Andric return;
75420e90f04SDimitry Andric case llvm::DK_MachineOptimizationRemark:
75520e90f04SDimitry Andric // Optimization remarks are always handled completely by this
75620e90f04SDimitry Andric // handler. There is no generic way of emitting them.
75720e90f04SDimitry Andric OptimizationRemarkHandler(cast<MachineOptimizationRemark>(DI));
75820e90f04SDimitry Andric return;
75920e90f04SDimitry Andric case llvm::DK_MachineOptimizationRemarkMissed:
76020e90f04SDimitry Andric // Optimization remarks are always handled completely by this
76120e90f04SDimitry Andric // handler. There is no generic way of emitting them.
76220e90f04SDimitry Andric OptimizationRemarkHandler(cast<MachineOptimizationRemarkMissed>(DI));
76320e90f04SDimitry Andric return;
76420e90f04SDimitry Andric case llvm::DK_MachineOptimizationRemarkAnalysis:
76520e90f04SDimitry Andric // Optimization remarks are always handled completely by this
76620e90f04SDimitry Andric // handler. There is no generic way of emitting them.
76720e90f04SDimitry Andric OptimizationRemarkHandler(cast<MachineOptimizationRemarkAnalysis>(DI));
76820e90f04SDimitry Andric return;
76959d1ed5bSDimitry Andric case llvm::DK_OptimizationFailure:
77059d1ed5bSDimitry Andric // Optimization failures are always handled completely by this
77159d1ed5bSDimitry Andric // handler.
77259d1ed5bSDimitry Andric OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI));
77359d1ed5bSDimitry Andric return;
774e7145dcbSDimitry Andric case llvm::DK_Unsupported:
775e7145dcbSDimitry Andric UnsupportedDiagHandler(cast<DiagnosticInfoUnsupported>(DI));
776e7145dcbSDimitry Andric return;
77759d1ed5bSDimitry Andric default:
77859d1ed5bSDimitry Andric // Plugin IDs are not bound to any value as they are set dynamically.
77959d1ed5bSDimitry Andric ComputeDiagRemarkID(Severity, backend_plugin, DiagID);
78059d1ed5bSDimitry Andric break;
78159d1ed5bSDimitry Andric }
78259d1ed5bSDimitry Andric std::string MsgStorage;
78359d1ed5bSDimitry Andric {
78459d1ed5bSDimitry Andric raw_string_ostream Stream(MsgStorage);
78559d1ed5bSDimitry Andric DiagnosticPrinterRawOStream DP(Stream);
78659d1ed5bSDimitry Andric DI.print(DP);
78759d1ed5bSDimitry Andric }
78859d1ed5bSDimitry Andric
7890623d748SDimitry Andric if (DiagID == diag::err_fe_cannot_link_module) {
7900623d748SDimitry Andric Diags.Report(diag::err_fe_cannot_link_module)
7910623d748SDimitry Andric << CurLinkModule->getModuleIdentifier() << MsgStorage;
7920623d748SDimitry Andric return;
7930623d748SDimitry Andric }
7940623d748SDimitry Andric
79559d1ed5bSDimitry Andric // Report the backend message using the usual diagnostic mechanism.
79659d1ed5bSDimitry Andric FullSourceLoc Loc;
79759d1ed5bSDimitry Andric Diags.Report(Loc, DiagID).AddString(MsgStorage);
79859d1ed5bSDimitry Andric }
79959d1ed5bSDimitry Andric #undef ComputeDiagID
800ffd1746dSEd Schouten
CodeGenAction(unsigned _Act,LLVMContext * _VMContext)8012754fe60SDimitry Andric CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext)
8020623d748SDimitry Andric : Act(_Act), VMContext(_VMContext ? _VMContext : new LLVMContext),
8032754fe60SDimitry Andric OwnsVMContext(!_VMContext) {}
804ffd1746dSEd Schouten
~CodeGenAction()8052754fe60SDimitry Andric CodeGenAction::~CodeGenAction() {
8062754fe60SDimitry Andric TheModule.reset();
8072754fe60SDimitry Andric if (OwnsVMContext)
8082754fe60SDimitry Andric delete VMContext;
8092754fe60SDimitry Andric }
810ffd1746dSEd Schouten
hasIRSupport() const811ffd1746dSEd Schouten bool CodeGenAction::hasIRSupport() const { return true; }
812ffd1746dSEd Schouten
EndSourceFileAction()813ffd1746dSEd Schouten void CodeGenAction::EndSourceFileAction() {
814ffd1746dSEd Schouten // If the consumer creation failed, do nothing.
815ffd1746dSEd Schouten if (!getCompilerInstance().hasASTConsumer())
816ffd1746dSEd Schouten return;
817ffd1746dSEd Schouten
818ffd1746dSEd Schouten // Steal the module from the consumer.
81939d628a0SDimitry Andric TheModule = BEConsumer->takeModule();
820ffd1746dSEd Schouten }
821ffd1746dSEd Schouten
takeModule()82239d628a0SDimitry Andric std::unique_ptr<llvm::Module> CodeGenAction::takeModule() {
82339d628a0SDimitry Andric return std::move(TheModule);
82439d628a0SDimitry Andric }
825ffd1746dSEd Schouten
takeLLVMContext()8262754fe60SDimitry Andric llvm::LLVMContext *CodeGenAction::takeLLVMContext() {
8272754fe60SDimitry Andric OwnsVMContext = false;
8282754fe60SDimitry Andric return VMContext;
8292754fe60SDimitry Andric }
8302754fe60SDimitry Andric
831e7145dcbSDimitry Andric static std::unique_ptr<raw_pwrite_stream>
GetOutputStream(CompilerInstance & CI,StringRef InFile,BackendAction Action)83233956c43SDimitry Andric GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
833ffd1746dSEd Schouten switch (Action) {
834ffd1746dSEd Schouten case Backend_EmitAssembly:
835ffd1746dSEd Schouten return CI.createDefaultOutputFile(false, InFile, "s");
836ffd1746dSEd Schouten case Backend_EmitLL:
837ffd1746dSEd Schouten return CI.createDefaultOutputFile(false, InFile, "ll");
838ffd1746dSEd Schouten case Backend_EmitBC:
839ffd1746dSEd Schouten return CI.createDefaultOutputFile(true, InFile, "bc");
840ffd1746dSEd Schouten case Backend_EmitNothing:
84159d1ed5bSDimitry Andric return nullptr;
842ffd1746dSEd Schouten case Backend_EmitMCNull:
84359d1ed5bSDimitry Andric return CI.createNullOutputFile();
844ffd1746dSEd Schouten case Backend_EmitObj:
845ffd1746dSEd Schouten return CI.createDefaultOutputFile(true, InFile, "o");
846ffd1746dSEd Schouten }
847ffd1746dSEd Schouten
8486122f3e6SDimitry Andric llvm_unreachable("Invalid action!");
849ffd1746dSEd Schouten }
850ffd1746dSEd Schouten
85139d628a0SDimitry Andric std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)85239d628a0SDimitry Andric CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
853ffd1746dSEd Schouten BackendAction BA = static_cast<BackendAction>(Act);
8544ba319b5SDimitry Andric std::unique_ptr<raw_pwrite_stream> OS = CI.takeOutputStream();
8554ba319b5SDimitry Andric if (!OS)
8564ba319b5SDimitry Andric OS = GetOutputStream(CI, InFile, BA);
8574ba319b5SDimitry Andric
858ffd1746dSEd Schouten if (BA != Backend_EmitNothing && !OS)
85959d1ed5bSDimitry Andric return nullptr;
860ffd1746dSEd Schouten
8610623d748SDimitry Andric // Load bitcode modules to link with, if we need to.
8620623d748SDimitry Andric if (LinkModules.empty())
86320e90f04SDimitry Andric for (const CodeGenOptions::BitcodeFileToLink &F :
86420e90f04SDimitry Andric CI.getCodeGenOpts().LinkBitcodeFiles) {
86520e90f04SDimitry Andric auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename);
866dff0c46cSDimitry Andric if (!BCBuf) {
867dff0c46cSDimitry Andric CI.getDiagnostics().Report(diag::err_cannot_open_file)
86820e90f04SDimitry Andric << F.Filename << BCBuf.getError().message();
8690623d748SDimitry Andric LinkModules.clear();
87059d1ed5bSDimitry Andric return nullptr;
871dff0c46cSDimitry Andric }
872dff0c46cSDimitry Andric
87344290647SDimitry Andric Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
87444290647SDimitry Andric getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext);
87544290647SDimitry Andric if (!ModuleOrErr) {
87644290647SDimitry Andric handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
87744290647SDimitry Andric CI.getDiagnostics().Report(diag::err_cannot_open_file)
87820e90f04SDimitry Andric << F.Filename << EIB.message();
87944290647SDimitry Andric });
8800623d748SDimitry Andric LinkModules.clear();
88159d1ed5bSDimitry Andric return nullptr;
882dff0c46cSDimitry Andric }
88320e90f04SDimitry Andric LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs,
88420e90f04SDimitry Andric F.Internalize, F.LinkFlags});
885dff0c46cSDimitry Andric }
886dff0c46cSDimitry Andric
88739d628a0SDimitry Andric CoverageSourceInfo *CoverageInfo = nullptr;
88839d628a0SDimitry Andric // Add the preprocessor callback only when the coverage mapping is generated.
88939d628a0SDimitry Andric if (CI.getCodeGenOpts().CoverageMapping) {
89039d628a0SDimitry Andric CoverageInfo = new CoverageSourceInfo;
89139d628a0SDimitry Andric CI.getPreprocessor().addPPCallbacks(
89239d628a0SDimitry Andric std::unique_ptr<PPCallbacks>(CoverageInfo));
89339d628a0SDimitry Andric }
8940623d748SDimitry Andric
89539d628a0SDimitry Andric std::unique_ptr<BackendConsumer> Result(new BackendConsumer(
8963dac3a9bSDimitry Andric BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
8973dac3a9bSDimitry Andric CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
89820e90f04SDimitry Andric CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile,
89920e90f04SDimitry Andric std::move(LinkModules), std::move(OS), *VMContext, CoverageInfo));
90039d628a0SDimitry Andric BEConsumer = Result.get();
90120e90f04SDimitry Andric
90220e90f04SDimitry Andric // Enable generating macro debug info only when debug info is not disabled and
90320e90f04SDimitry Andric // also macro debug info is enabled.
90420e90f04SDimitry Andric if (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo &&
90520e90f04SDimitry Andric CI.getCodeGenOpts().MacroDebugInfo) {
90620e90f04SDimitry Andric std::unique_ptr<PPCallbacks> Callbacks =
90720e90f04SDimitry Andric llvm::make_unique<MacroPPCallbacks>(BEConsumer->getCodeGenerator(),
90820e90f04SDimitry Andric CI.getPreprocessor());
90920e90f04SDimitry Andric CI.getPreprocessor().addPPCallbacks(std::move(Callbacks));
91020e90f04SDimitry Andric }
91120e90f04SDimitry Andric
91239d628a0SDimitry Andric return std::move(Result);
913ffd1746dSEd Schouten }
914ffd1746dSEd Schouten
BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic & SM,void * Context,unsigned LocCookie)91533956c43SDimitry Andric static void BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic &SM,
91633956c43SDimitry Andric void *Context,
91733956c43SDimitry Andric unsigned LocCookie) {
91833956c43SDimitry Andric SM.print(nullptr, llvm::errs());
919e7145dcbSDimitry Andric
920e7145dcbSDimitry Andric auto Diags = static_cast<DiagnosticsEngine *>(Context);
921e7145dcbSDimitry Andric unsigned DiagID;
922e7145dcbSDimitry Andric switch (SM.getKind()) {
923e7145dcbSDimitry Andric case llvm::SourceMgr::DK_Error:
924e7145dcbSDimitry Andric DiagID = diag::err_fe_inline_asm;
925e7145dcbSDimitry Andric break;
926e7145dcbSDimitry Andric case llvm::SourceMgr::DK_Warning:
927e7145dcbSDimitry Andric DiagID = diag::warn_fe_inline_asm;
928e7145dcbSDimitry Andric break;
929e7145dcbSDimitry Andric case llvm::SourceMgr::DK_Note:
930e7145dcbSDimitry Andric DiagID = diag::note_fe_inline_asm;
931e7145dcbSDimitry Andric break;
9329a199699SDimitry Andric case llvm::SourceMgr::DK_Remark:
9339a199699SDimitry Andric llvm_unreachable("remarks unexpected");
934e7145dcbSDimitry Andric }
935e7145dcbSDimitry Andric
936e7145dcbSDimitry Andric Diags->Report(DiagID).AddString("cannot compile inline asm");
93733956c43SDimitry Andric }
93833956c43SDimitry Andric
loadModule(MemoryBufferRef MBRef)93920e90f04SDimitry Andric std::unique_ptr<llvm::Module> CodeGenAction::loadModule(MemoryBufferRef MBRef) {
94020e90f04SDimitry Andric CompilerInstance &CI = getCompilerInstance();
94120e90f04SDimitry Andric SourceManager &SM = CI.getSourceManager();
94220e90f04SDimitry Andric
94320e90f04SDimitry Andric // For ThinLTO backend invocations, ensure that the context
94420e90f04SDimitry Andric // merges types based on ODR identifiers. We also need to read
94520e90f04SDimitry Andric // the correct module out of a multi-module bitcode file.
94620e90f04SDimitry Andric if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) {
94720e90f04SDimitry Andric VMContext->enableDebugTypeODRUniquing();
94820e90f04SDimitry Andric
94920e90f04SDimitry Andric auto DiagErrors = [&](Error E) -> std::unique_ptr<llvm::Module> {
95020e90f04SDimitry Andric unsigned DiagID =
95120e90f04SDimitry Andric CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
95220e90f04SDimitry Andric handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
95320e90f04SDimitry Andric CI.getDiagnostics().Report(DiagID) << EIB.message();
95420e90f04SDimitry Andric });
95520e90f04SDimitry Andric return {};
95620e90f04SDimitry Andric };
95720e90f04SDimitry Andric
9584ba319b5SDimitry Andric Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef);
9594ba319b5SDimitry Andric if (!BMsOrErr)
9604ba319b5SDimitry Andric return DiagErrors(BMsOrErr.takeError());
9614ba319b5SDimitry Andric BitcodeModule *Bm = FindThinLTOModule(*BMsOrErr);
9624ba319b5SDimitry Andric // We have nothing to do if the file contains no ThinLTO module. This is
9634ba319b5SDimitry Andric // possible if ThinLTO compilation was not able to split module. Content of
9644ba319b5SDimitry Andric // the file was already processed by indexing and will be passed to the
9654ba319b5SDimitry Andric // linker using merged object file.
9664ba319b5SDimitry Andric if (!Bm) {
9674ba319b5SDimitry Andric auto M = llvm::make_unique<llvm::Module>("empty", *VMContext);
9684ba319b5SDimitry Andric M->setTargetTriple(CI.getTargetOpts().Triple);
9694ba319b5SDimitry Andric return M;
9704ba319b5SDimitry Andric }
97120e90f04SDimitry Andric Expected<std::unique_ptr<llvm::Module>> MOrErr =
9724ba319b5SDimitry Andric Bm->parseModule(*VMContext);
97320e90f04SDimitry Andric if (!MOrErr)
97420e90f04SDimitry Andric return DiagErrors(MOrErr.takeError());
97520e90f04SDimitry Andric return std::move(*MOrErr);
97620e90f04SDimitry Andric }
97720e90f04SDimitry Andric
97820e90f04SDimitry Andric llvm::SMDiagnostic Err;
97920e90f04SDimitry Andric if (std::unique_ptr<llvm::Module> M = parseIR(MBRef, Err, *VMContext))
98020e90f04SDimitry Andric return M;
98120e90f04SDimitry Andric
98220e90f04SDimitry Andric // Translate from the diagnostic info to the SourceManager location if
98320e90f04SDimitry Andric // available.
98420e90f04SDimitry Andric // TODO: Unify this with ConvertBackendLocation()
98520e90f04SDimitry Andric SourceLocation Loc;
98620e90f04SDimitry Andric if (Err.getLineNo() > 0) {
98720e90f04SDimitry Andric assert(Err.getColumnNo() >= 0);
98820e90f04SDimitry Andric Loc = SM.translateFileLineCol(SM.getFileEntryForID(SM.getMainFileID()),
98920e90f04SDimitry Andric Err.getLineNo(), Err.getColumnNo() + 1);
99020e90f04SDimitry Andric }
99120e90f04SDimitry Andric
99220e90f04SDimitry Andric // Strip off a leading diagnostic code if there is one.
99320e90f04SDimitry Andric StringRef Msg = Err.getMessage();
99420e90f04SDimitry Andric if (Msg.startswith("error: "))
99520e90f04SDimitry Andric Msg = Msg.substr(7);
99620e90f04SDimitry Andric
99720e90f04SDimitry Andric unsigned DiagID =
99820e90f04SDimitry Andric CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
99920e90f04SDimitry Andric
100020e90f04SDimitry Andric CI.getDiagnostics().Report(Loc, DiagID) << Msg;
100120e90f04SDimitry Andric return {};
100220e90f04SDimitry Andric }
100320e90f04SDimitry Andric
ExecuteAction()1004ffd1746dSEd Schouten void CodeGenAction::ExecuteAction() {
1005ffd1746dSEd Schouten // If this is an IR file, we have to treat it specially.
1006f37b6182SDimitry Andric if (getCurrentFileKind().getLanguage() == InputKind::LLVM_IR) {
1007ffd1746dSEd Schouten BackendAction BA = static_cast<BackendAction>(Act);
1008ffd1746dSEd Schouten CompilerInstance &CI = getCompilerInstance();
1009e7145dcbSDimitry Andric std::unique_ptr<raw_pwrite_stream> OS =
1010e7145dcbSDimitry Andric GetOutputStream(CI, getCurrentFile(), BA);
1011ffd1746dSEd Schouten if (BA != Backend_EmitNothing && !OS)
1012ffd1746dSEd Schouten return;
1013ffd1746dSEd Schouten
1014ffd1746dSEd Schouten bool Invalid;
1015ffd1746dSEd Schouten SourceManager &SM = CI.getSourceManager();
101659d1ed5bSDimitry Andric FileID FID = SM.getMainFileID();
101759d1ed5bSDimitry Andric llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid);
1018ffd1746dSEd Schouten if (Invalid)
1019ffd1746dSEd Schouten return;
1020ffd1746dSEd Schouten
102120e90f04SDimitry Andric TheModule = loadModule(*MainFile);
102220e90f04SDimitry Andric if (!TheModule)
1023ffd1746dSEd Schouten return;
102420e90f04SDimitry Andric
102559d1ed5bSDimitry Andric const TargetOptions &TargetOpts = CI.getTargetOpts();
102659d1ed5bSDimitry Andric if (TheModule->getTargetTriple() != TargetOpts.Triple) {
102733956c43SDimitry Andric CI.getDiagnostics().Report(SourceLocation(),
102833956c43SDimitry Andric diag::warn_fe_override_module)
102933956c43SDimitry Andric << TargetOpts.Triple;
103059d1ed5bSDimitry Andric TheModule->setTargetTriple(TargetOpts.Triple);
103159d1ed5bSDimitry Andric }
103259d1ed5bSDimitry Andric
1033e7145dcbSDimitry Andric EmbedBitcode(TheModule.get(), CI.getCodeGenOpts(),
1034e7145dcbSDimitry Andric MainFile->getMemBufferRef());
1035e7145dcbSDimitry Andric
103633956c43SDimitry Andric LLVMContext &Ctx = TheModule->getContext();
1037e7145dcbSDimitry Andric Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler,
1038e7145dcbSDimitry Andric &CI.getDiagnostics());
1039e7145dcbSDimitry Andric
104095ec533aSDimitry Andric EmitBackendOutput(CI.getDiagnostics(), CI.getHeaderSearchOpts(),
104195ec533aSDimitry Andric CI.getCodeGenOpts(), TargetOpts, CI.getLangOpts(),
104295ec533aSDimitry Andric CI.getTarget().getDataLayout(), TheModule.get(), BA,
104395ec533aSDimitry Andric std::move(OS));
1044ffd1746dSEd Schouten return;
1045ffd1746dSEd Schouten }
1046ffd1746dSEd Schouten
1047ffd1746dSEd Schouten // Otherwise follow the normal AST path.
1048ffd1746dSEd Schouten this->ASTFrontendAction::ExecuteAction();
1049ffd1746dSEd Schouten }
1050ffd1746dSEd Schouten
1051ffd1746dSEd Schouten //
1052ffd1746dSEd Schouten
anchor()1053dff0c46cSDimitry Andric void EmitAssemblyAction::anchor() { }
EmitAssemblyAction(llvm::LLVMContext * _VMContext)10542754fe60SDimitry Andric EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext)
10552754fe60SDimitry Andric : CodeGenAction(Backend_EmitAssembly, _VMContext) {}
1056ffd1746dSEd Schouten
anchor()1057dff0c46cSDimitry Andric void EmitBCAction::anchor() { }
EmitBCAction(llvm::LLVMContext * _VMContext)10582754fe60SDimitry Andric EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext)
10592754fe60SDimitry Andric : CodeGenAction(Backend_EmitBC, _VMContext) {}
1060ffd1746dSEd Schouten
anchor()1061dff0c46cSDimitry Andric void EmitLLVMAction::anchor() { }
EmitLLVMAction(llvm::LLVMContext * _VMContext)10622754fe60SDimitry Andric EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext)
10632754fe60SDimitry Andric : CodeGenAction(Backend_EmitLL, _VMContext) {}
1064ffd1746dSEd Schouten
anchor()1065dff0c46cSDimitry Andric void EmitLLVMOnlyAction::anchor() { }
EmitLLVMOnlyAction(llvm::LLVMContext * _VMContext)10662754fe60SDimitry Andric EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext)
10672754fe60SDimitry Andric : CodeGenAction(Backend_EmitNothing, _VMContext) {}
1068ffd1746dSEd Schouten
anchor()1069dff0c46cSDimitry Andric void EmitCodeGenOnlyAction::anchor() { }
EmitCodeGenOnlyAction(llvm::LLVMContext * _VMContext)10702754fe60SDimitry Andric EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext)
10712754fe60SDimitry Andric : CodeGenAction(Backend_EmitMCNull, _VMContext) {}
1072ffd1746dSEd Schouten
anchor()1073dff0c46cSDimitry Andric void EmitObjAction::anchor() { }
EmitObjAction(llvm::LLVMContext * _VMContext)10742754fe60SDimitry Andric EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext)
10752754fe60SDimitry Andric : CodeGenAction(Backend_EmitObj, _VMContext) {}
1076