blob: 7f3f358d3d98841e6478173131abe0ff302e0bc4 [file] [log] [blame]
Daniel Dunbarcea0c702010-02-25 04:37:45 +00001//===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===//
Daniel Dunbarc13935e2008-10-21 23:49:24 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Daniel Dunbarc13935e2008-10-21 23:49:24 +00006//
7//===----------------------------------------------------------------------===//
8
Justin Lebarb080b632017-01-25 21:29:48 +00009#include "clang/CodeGen/CodeGenAction.h"
10#include "CodeGenModule.h"
Alex Lorenzee024992014-08-04 18:41:51 +000011#include "CoverageMappingGen.h"
Amjad Aboud546bc112017-02-09 22:07:24 +000012#include "MacroPPCallbacks.h"
Chris Lattner5bbb3c82009-03-29 16:50:03 +000013#include "clang/AST/ASTConsumer.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000014#include "clang/AST/ASTContext.h"
Hans Wennborga926d842014-05-23 20:37:38 +000015#include "clang/AST/DeclCXX.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000016#include "clang/AST/DeclGroup.h"
Petr Hosek7bdad082019-09-11 16:19:50 +000017#include "clang/Basic/DiagnosticFrontend.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000018#include "clang/Basic/FileManager.h"
Rainer Orth09d890d2019-08-05 13:59:26 +000019#include "clang/Basic/LangStandard.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000020#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
Daniel Dunbarc1b17292010-06-15 17:48:49 +000022#include "clang/CodeGen/BackendUtil.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000023#include "clang/CodeGen/ModuleBuilder.h"
Francis Visoiu Mistrihdd422362019-03-12 21:22:27 +000024#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbarcea0c702010-02-25 04:37:45 +000025#include "clang/Frontend/CompilerInstance.h"
Daniel Dunbaracadc552009-12-03 09:12:54 +000026#include "clang/Frontend/FrontendDiagnostic.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000027#include "clang/Lex/Preprocessor.h"
Teresa Johnsonffc4e242016-11-11 05:35:12 +000028#include "llvm/Bitcode/BitcodeReader.h"
Adam Nemet7b796f82017-01-26 04:07:11 +000029#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
Diego Novillo829b1702014-04-16 16:54:24 +000030#include "llvm/IR/DebugInfo.h"
Quentin Colombet728c5542014-02-06 18:30:43 +000031#include "llvm/IR/DiagnosticInfo.h"
32#include "llvm/IR/DiagnosticPrinter.h"
Jonas Devlieghere5eb9c812017-03-13 18:08:11 +000033#include "llvm/IR/GlobalValue.h"
Chandler Carruthffd55512013-01-02 11:45:17 +000034#include "llvm/IR/LLVMContext.h"
35#include "llvm/IR/Module.h"
Francis Visoiu Mistrihb8a847c2019-03-06 15:20:13 +000036#include "llvm/IR/RemarkStreamer.h"
Chandler Carruthb45836a2013-03-26 02:25:54 +000037#include "llvm/IRReader/IRReader.h"
Chandler Carruth00fa3f72014-03-06 03:46:44 +000038#include "llvm/Linker/Linker.h"
Daniel Dunbar3e111522010-06-07 23:21:04 +000039#include "llvm/Pass.h"
Chris Lattner5ec32e72010-04-06 18:38:50 +000040#include "llvm/Support/MemoryBuffer.h"
41#include "llvm/Support/SourceMgr.h"
Anton Afanasyev3f3a2572019-08-19 22:58:26 +000042#include "llvm/Support/TimeProfiler.h"
Chris Lattner263d64c2009-02-18 01:37:30 +000043#include "llvm/Support/Timer.h"
Hal Finkel8f96e822016-10-11 00:26:09 +000044#include "llvm/Support/ToolOutputFile.h"
45#include "llvm/Support/YAMLTraits.h"
Jonas Devlieghere5eb9c812017-03-13 18:08:11 +000046#include "llvm/Transforms/IPO/Internalize.h"
47
Ahmed Charlesdfca6f92014-03-09 11:36:40 +000048#include <memory>
Daniel Dunbarc13935e2008-10-21 23:49:24 +000049using namespace clang;
50using namespace llvm;
51
Nico Weber2992efa2011-01-25 20:34:14 +000052namespace clang {
Vivek Pandya1dee3be2017-09-15 20:09:55 +000053 class BackendConsumer;
54 class ClangDiagnosticHandler final : public DiagnosticHandler {
55 public:
56 ClangDiagnosticHandler(const CodeGenOptions &CGOpts, BackendConsumer *BCon)
57 : CodeGenOpts(CGOpts), BackendCon(BCon) {}
Fangrui Song6907ce22018-07-30 19:24:48 +000058
Vivek Pandya1dee3be2017-09-15 20:09:55 +000059 bool handleDiagnostics(const DiagnosticInfo &DI) override;
Adam Nemet5d2eb162017-09-19 17:59:40 +000060
61 bool isAnalysisRemarkEnabled(StringRef PassName) const override {
Vivek Pandya1dee3be2017-09-15 20:09:55 +000062 return (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
63 CodeGenOpts.OptimizationRemarkAnalysisPattern->match(PassName));
64 }
Adam Nemet5d2eb162017-09-19 17:59:40 +000065 bool isMissedOptRemarkEnabled(StringRef PassName) const override {
Vivek Pandya1dee3be2017-09-15 20:09:55 +000066 return (CodeGenOpts.OptimizationRemarkMissedPattern &&
67 CodeGenOpts.OptimizationRemarkMissedPattern->match(PassName));
68 }
Adam Nemet5d2eb162017-09-19 17:59:40 +000069 bool isPassedOptRemarkEnabled(StringRef PassName) const override {
Vivek Pandya1dee3be2017-09-15 20:09:55 +000070 return (CodeGenOpts.OptimizationRemarkPattern &&
71 CodeGenOpts.OptimizationRemarkPattern->match(PassName));
72 }
Adam Nemet5d2eb162017-09-19 17:59:40 +000073
Adam Nemet3ac802a2017-09-19 23:00:59 +000074 bool isAnyRemarkEnabled() const override {
75 return (CodeGenOpts.OptimizationRemarkAnalysisPattern ||
76 CodeGenOpts.OptimizationRemarkMissedPattern ||
77 CodeGenOpts.OptimizationRemarkPattern);
78 }
79
Vivek Pandya1dee3be2017-09-15 20:09:55 +000080 private:
81 const CodeGenOptions &CodeGenOpts;
82 BackendConsumer *BackendCon;
83 };
84
Zahira Ammarguellata3b25522019-12-05 10:23:47 -050085 static void reportOptRecordError(Error E, DiagnosticsEngine &Diags,
86 const CodeGenOptions CodeGenOpts) {
87 handleAllErrors(
88 std::move(E),
89 [&](const RemarkSetupFileError &E) {
90 Diags.Report(diag::err_cannot_open_file)
91 << CodeGenOpts.OptRecordFile << E.message();
92 },
93 [&](const RemarkSetupPatternError &E) {
94 Diags.Report(diag::err_drv_optimization_remark_pattern)
95 << E.message() << CodeGenOpts.OptRecordPasses;
96 },
97 [&](const RemarkSetupFormatError &E) {
98 Diags.Report(diag::err_drv_optimization_remark_format)
99 << CodeGenOpts.OptRecordFormat;
100 });
101 }
102
Benjamin Kramer16634c22009-11-28 10:07:24 +0000103 class BackendConsumer : public ASTConsumer {
Justin Lebarb080b632017-01-25 21:29:48 +0000104 using LinkModule = CodeGenAction::LinkModule;
105
David Blaikie68e081d2011-12-20 02:48:34 +0000106 virtual void anchor();
David Blaikie9c902b52011-09-25 23:23:43 +0000107 DiagnosticsEngine &Diags;
Daniel Dunbarc13935e2008-10-21 23:49:24 +0000108 BackendAction Action;
Saleem Abdulrasool888e2892017-01-05 16:02:32 +0000109 const HeaderSearchOptions &HeaderSearchOpts;
Daniel Dunbarde182242009-11-30 08:39:32 +0000110 const CodeGenOptions &CodeGenOpts;
Daniel Dunbarde182242009-11-30 08:39:32 +0000111 const TargetOptions &TargetOpts;
Dan Gohmanfec0ff82011-07-05 22:02:36 +0000112 const LangOptions &LangOpts;
Peter Collingbourne03f89072016-07-15 00:55:40 +0000113 std::unique_ptr<raw_pwrite_stream> AsmOutStream;
Chris Lattnereae6cb62009-03-05 08:00:35 +0000114 ASTContext *Context;
Nico Weberade321e2018-04-10 18:53:28 +0000115
116 Timer LLVMIRGeneration;
117 unsigned LLVMIRGenerationRefCount;
Mike Stump11289f42009-09-09 15:08:12 +0000118
Reid Kleckner15241ba2016-11-30 00:25:36 +0000119 /// True if we've finished generating IR. This prevents us from generating
120 /// additional LLVM IR after emitting output in HandleTranslationUnit. This
121 /// can happen when Clang plugins trigger additional AST deserialization.
122 bool IRGenFinished = false;
123
Ahmed Charlesb8984322014-03-07 20:03:18 +0000124 std::unique_ptr<CodeGenerator> Gen;
Mike Stump11289f42009-09-09 15:08:12 +0000125
Justin Lebarb080b632017-01-25 21:29:48 +0000126 SmallVector<LinkModule, 4> LinkModules;
Daniel Dunbarc13935e2008-10-21 23:49:24 +0000127
Rafael Espindola8ce88a52015-12-14 23:17:07 +0000128 // This is here so that the diagnostic printer knows the module a diagnostic
129 // refers to.
130 llvm::Module *CurLinkModule = nullptr;
131
Mike Stump11289f42009-09-09 15:08:12 +0000132 public:
Justin Lebarb080b632017-01-25 21:29:48 +0000133 BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
134 const HeaderSearchOptions &HeaderSearchOpts,
135 const PreprocessorOptions &PPOpts,
136 const CodeGenOptions &CodeGenOpts,
137 const TargetOptions &TargetOpts,
138 const LangOptions &LangOpts, bool TimePasses,
139 const std::string &InFile,
140 SmallVector<LinkModule, 4> LinkModules,
141 std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C,
142 CoverageSourceInfo *CoverageInfo = nullptr)
Saleem Abdulrasool888e2892017-01-05 16:02:32 +0000143 : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
144 CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
Peter Collingbourne03f89072016-07-15 00:55:40 +0000145 AsmOutStream(std::move(OS)), Context(nullptr),
Nico Weberade321e2018-04-10 18:53:28 +0000146 LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
147 LLVMIRGenerationRefCount(0),
Adrian Prantle74f5252015-06-30 02:26:03 +0000148 Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
Justin Lebarb080b632017-01-25 21:29:48 +0000149 CodeGenOpts, C, CoverageInfo)),
150 LinkModules(std::move(LinkModules)) {
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +0000151 FrontendTimesIsEnabled = TimePasses;
Craig Topper2a92a0e2018-08-08 19:14:23 +0000152 llvm::TimePassesIsEnabled = TimePasses;
Chris Lattnerdeffa132009-02-18 01:23:44 +0000153 }
Serge Pavlov41c1f792016-02-18 16:42:09 +0000154 llvm::Module *getModule() const { return Gen->GetModule(); }
155 std::unique_ptr<llvm::Module> takeModule() {
156 return std::unique_ptr<llvm::Module>(Gen->ReleaseModule());
157 }
Daniel Dunbar400a6932010-02-25 04:37:50 +0000158
Amjad Aboud546bc112017-02-09 22:07:24 +0000159 CodeGenerator *getCodeGenerator() { return Gen.get(); }
160
Craig Topper4f12f102014-03-12 06:41:41 +0000161 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
Rafael Espindoladf88f6f2012-03-08 15:51:03 +0000162 Gen->HandleCXXStaticMemberVarInstantiation(VD);
Rafael Espindola189fa742012-03-05 10:54:55 +0000163 }
164
Craig Topper4f12f102014-03-12 06:41:41 +0000165 void Initialize(ASTContext &Ctx) override {
Richard Smith293534b2015-08-18 20:39:29 +0000166 assert(!Context && "initialized multiple times");
Nico Weberade321e2018-04-10 18:53:28 +0000167
Chris Lattner5cf49fe2009-03-28 02:18:25 +0000168 Context = &Ctx;
Nico Weberade321e2018-04-10 18:53:28 +0000169
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +0000170 if (FrontendTimesIsEnabled)
Nico Weberade321e2018-04-10 18:53:28 +0000171 LLVMIRGeneration.startTimer();
172
Chris Lattner5cf49fe2009-03-28 02:18:25 +0000173 Gen->Initialize(Ctx);
Nico Weberade321e2018-04-10 18:53:28 +0000174
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +0000175 if (FrontendTimesIsEnabled)
Nico Weberade321e2018-04-10 18:53:28 +0000176 LLVMIRGeneration.stopTimer();
Daniel Dunbarc13935e2008-10-21 23:49:24 +0000177 }
Mike Stump11289f42009-09-09 15:08:12 +0000178
Craig Topper4f12f102014-03-12 06:41:41 +0000179 bool HandleTopLevelDecl(DeclGroupRef D) override {
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000180 PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
Chris Lattnereae6cb62009-03-05 08:00:35 +0000181 Context->getSourceManager(),
182 "LLVM IR generation of declaration");
Nico Weberade321e2018-04-10 18:53:28 +0000183
184 // Recurse.
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +0000185 if (FrontendTimesIsEnabled) {
Nico Weberade321e2018-04-10 18:53:28 +0000186 LLVMIRGenerationRefCount += 1;
187 if (LLVMIRGenerationRefCount == 1)
188 LLVMIRGeneration.startTimer();
189 }
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000190
Daniel Dunbarc13935e2008-10-21 23:49:24 +0000191 Gen->HandleTopLevelDecl(D);
Nico Weberade321e2018-04-10 18:53:28 +0000192
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +0000193 if (FrontendTimesIsEnabled) {
Nico Weberade321e2018-04-10 18:53:28 +0000194 LLVMIRGenerationRefCount -= 1;
195 if (LLVMIRGenerationRefCount == 0)
196 LLVMIRGeneration.stopTimer();
197 }
198
Argyrios Kyrtzidis841dd882011-11-18 00:26:59 +0000199 return true;
Daniel Dunbarc13935e2008-10-21 23:49:24 +0000200 }
Mike Stump11289f42009-09-09 15:08:12 +0000201
Stephan Bergmann17d7d142016-03-30 06:27:31 +0000202 void HandleInlineFunctionDefinition(FunctionDecl *D) override {
Hans Wennborga926d842014-05-23 20:37:38 +0000203 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
204 Context->getSourceManager(),
Stephan Bergmann17d7d142016-03-30 06:27:31 +0000205 "LLVM IR generation of inline function");
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +0000206 if (FrontendTimesIsEnabled)
Nico Weberade321e2018-04-10 18:53:28 +0000207 LLVMIRGeneration.startTimer();
Hans Wennborga926d842014-05-23 20:37:38 +0000208
Stephan Bergmann17d7d142016-03-30 06:27:31 +0000209 Gen->HandleInlineFunctionDefinition(D);
Nico Weberade321e2018-04-10 18:53:28 +0000210
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +0000211 if (FrontendTimesIsEnabled)
Nico Weberade321e2018-04-10 18:53:28 +0000212 LLVMIRGeneration.stopTimer();
Hans Wennborga926d842014-05-23 20:37:38 +0000213 }
214
Reid Kleckner68c4bb52016-11-30 01:32:53 +0000215 void HandleInterestingDecl(DeclGroupRef D) override {
Reid Kleckner15241ba2016-11-30 00:25:36 +0000216 // Ignore interesting decls from the AST reader after IRGen is finished.
217 if (!IRGenFinished)
218 HandleTopLevelDecl(D);
219 }
220
Justin Lebarb080b632017-01-25 21:29:48 +0000221 // Links each entry in LinkModules into our module. Returns true on error.
222 bool LinkInModules() {
223 for (auto &LM : LinkModules) {
224 if (LM.PropagateAttrs)
225 for (Function &F : *LM.Module)
226 Gen->CGM().AddDefaultFnAttrs(F);
227
228 CurLinkModule = LM.Module.get();
Jonas Devlieghere5eb9c812017-03-13 18:08:11 +0000229
230 bool Err;
231 if (LM.Internalize) {
232 Err = Linker::linkModules(
233 *getModule(), std::move(LM.Module), LM.LinkFlags,
234 [](llvm::Module &M, const llvm::StringSet<> &GVS) {
Reid Kleckner987a2812017-03-13 22:33:07 +0000235 internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) {
Jonas Devlieghere5eb9c812017-03-13 18:08:11 +0000236 return !GV.hasName() || (GVS.count(GV.getName()) == 0);
237 });
238 });
239 } else {
240 Err = Linker::linkModules(*getModule(), std::move(LM.Module),
241 LM.LinkFlags);
242 }
243
244 if (Err)
Justin Lebarb080b632017-01-25 21:29:48 +0000245 return true;
246 }
247 return false; // success
248 }
249
Craig Topper4f12f102014-03-12 06:41:41 +0000250 void HandleTranslationUnit(ASTContext &C) override {
Chris Lattnereae6cb62009-03-05 08:00:35 +0000251 {
Russell Gallopdf494f72019-12-11 11:49:42 +0000252 llvm::TimeTraceScope TimeScope("Frontend");
Chris Lattnere46de752009-03-06 06:46:31 +0000253 PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +0000254 if (FrontendTimesIsEnabled) {
Nico Weberade321e2018-04-10 18:53:28 +0000255 LLVMIRGenerationRefCount += 1;
256 if (LLVMIRGenerationRefCount == 1)
257 LLVMIRGeneration.startTimer();
258 }
Chris Lattner263d64c2009-02-18 01:37:30 +0000259
Chris Lattnercf169832009-03-28 04:11:33 +0000260 Gen->HandleTranslationUnit(C);
Nico Weberade321e2018-04-10 18:53:28 +0000261
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +0000262 if (FrontendTimesIsEnabled) {
Nico Weberade321e2018-04-10 18:53:28 +0000263 LLVMIRGenerationRefCount -= 1;
264 if (LLVMIRGenerationRefCount == 0)
265 LLVMIRGeneration.stopTimer();
266 }
267
Fangrui Song99337e22018-07-20 08:19:20 +0000268 IRGenFinished = true;
Chris Lattnereae6cb62009-03-05 08:00:35 +0000269 }
Chris Lattner263d64c2009-02-18 01:37:30 +0000270
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000271 // Silently ignore if we weren't initialized for some reason.
Serge Pavlov41c1f792016-02-18 16:42:09 +0000272 if (!getModule())
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000273 return;
Mike Stump11289f42009-09-09 15:08:12 +0000274
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000275 // Install an inline asm handler so that diagnostics get printed through
276 // our diagnostics hooks.
Serge Pavlov41c1f792016-02-18 16:42:09 +0000277 LLVMContext &Ctx = getModule()->getContext();
Chris Lattner068f2ab2010-11-17 08:13:04 +0000278 LLVMContext::InlineAsmDiagHandlerTy OldHandler =
279 Ctx.getInlineAsmDiagnosticHandler();
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000280 void *OldContext = Ctx.getInlineAsmDiagnosticContext();
Chris Lattner068f2ab2010-11-17 08:13:04 +0000281 Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this);
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000282
Vivek Pandya1dee3be2017-09-15 20:09:55 +0000283 std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler =
Quentin Colombet728c5542014-02-06 18:30:43 +0000284 Ctx.getDiagnosticHandler();
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +0000285 Ctx.setDiagnosticHandler(std::make_unique<ClangDiagnosticHandler>(
Vivek Pandya1dee3be2017-09-15 20:09:55 +0000286 CodeGenOpts, this));
Quentin Colombet728c5542014-02-06 18:30:43 +0000287
Francis Visoiu Mistrih7a211132019-06-14 16:20:51 +0000288 Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
Zahira Ammarguellata3b25522019-12-05 10:23:47 -0500289 setupOptimizationRemarks(
290 Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
291 CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
292 CodeGenOpts.DiagnosticsHotnessThreshold);
Hal Finkel8f96e822016-10-11 00:26:09 +0000293
Francis Visoiu Mistrih7a211132019-06-14 16:20:51 +0000294 if (Error E = OptRecordFileOrErr.takeError()) {
Zahira Ammarguellata3b25522019-12-05 10:23:47 -0500295 reportOptRecordError(std::move(E), Diags, CodeGenOpts);
Francis Visoiu Mistrih7a211132019-06-14 16:20:51 +0000296 return;
Hal Finkel8f96e822016-10-11 00:26:09 +0000297 }
Zahira Ammarguellata3b25522019-12-05 10:23:47 -0500298
Francis Visoiu Mistrih7a211132019-06-14 16:20:51 +0000299 std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
300 std::move(*OptRecordFileOrErr);
301
302 if (OptRecordFile &&
303 CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone)
304 Ctx.setDiagnosticsHotnessRequested(true);
Hal Finkel8f96e822016-10-11 00:26:09 +0000305
Justin Lebarb080b632017-01-25 21:29:48 +0000306 // Link each LinkModule into our module.
307 if (LinkInModules())
308 return;
Rafael Espindola8ce88a52015-12-14 23:17:07 +0000309
Steven Wu27fb5222016-05-11 16:26:03 +0000310 EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef());
311
Saleem Abdulrasool888e2892017-01-05 16:02:32 +0000312 EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
313 LangOpts, C.getTargetInfo().getDataLayout(),
Peter Collingbourne03f89072016-07-15 00:55:40 +0000314 getModule(), Action, std::move(AsmOutStream));
Rafael Espindola666a2ab2013-12-18 16:38:48 +0000315
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000316 Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
Quentin Colombet728c5542014-02-06 18:30:43 +0000317
Vivek Pandya1dee3be2017-09-15 20:09:55 +0000318 Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
Hal Finkel8f96e822016-10-11 00:26:09 +0000319
320 if (OptRecordFile)
321 OptRecordFile->keep();
Daniel Dunbarc13935e2008-10-21 23:49:24 +0000322 }
Mike Stump11289f42009-09-09 15:08:12 +0000323
Craig Topper4f12f102014-03-12 06:41:41 +0000324 void HandleTagDeclDefinition(TagDecl *D) override {
Chris Lattnereae6cb62009-03-05 08:00:35 +0000325 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
326 Context->getSourceManager(),
327 "LLVM IR generation of declaration");
Daniel Dunbarc13935e2008-10-21 23:49:24 +0000328 Gen->HandleTagDeclDefinition(D);
329 }
Douglas Gregorbeecd582009-04-21 17:11:58 +0000330
Craig Topper4f12f102014-03-12 06:41:41 +0000331 void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
David Blaikie48ad6dc2013-07-13 21:08:14 +0000332 Gen->HandleTagDeclRequiredDefinition(D);
333 }
334
Craig Topper4f12f102014-03-12 06:41:41 +0000335 void CompleteTentativeDefinition(VarDecl *D) override {
Douglas Gregorbeecd582009-04-21 17:11:58 +0000336 Gen->CompleteTentativeDefinition(D);
337 }
Daniel Dunbar50aa0a52010-04-29 16:29:09 +0000338
Yonghong Songd77ae152019-11-22 08:45:37 -0800339 void CompleteExternalDeclaration(VarDecl *D) override {
340 Gen->CompleteExternalDeclaration(D);
341 }
342
David Majnemer929025d2016-01-26 19:30:26 +0000343 void AssignInheritanceModel(CXXRecordDecl *RD) override {
344 Gen->AssignInheritanceModel(RD);
345 }
346
Nico Weberb6a5d052015-01-15 04:07:35 +0000347 void HandleVTable(CXXRecordDecl *RD) override {
348 Gen->HandleVTable(RD);
Douglas Gregor88d292c2010-05-13 16:44:06 +0000349 }
350
Chris Lattner5ec32e72010-04-06 18:38:50 +0000351 static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,
352 unsigned LocCookie) {
353 SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie);
354 ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc);
355 }
Daniel Dunbar50aa0a52010-04-29 16:29:09 +0000356
Oliver Stannard91817852016-02-02 13:52:52 +0000357 /// Get the best possible source location to represent a diagnostic that
358 /// may have associated debug info.
359 const FullSourceLoc
Justin Bognere91e9dd2017-02-17 17:34:49 +0000360 getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithLocationBase &D,
Oliver Stannard91817852016-02-02 13:52:52 +0000361 bool &BadDebugInfo, StringRef &Filename,
362 unsigned &Line, unsigned &Column) const;
363
Chris Lattner5ec32e72010-04-06 18:38:50 +0000364 void InlineAsmDiagHandler2(const llvm::SMDiagnostic &,
365 SourceLocation LocCookie);
Quentin Colombet728c5542014-02-06 18:30:43 +0000366
367 void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000368 /// Specialized handler for InlineAsm diagnostic.
Quentin Colombet728c5542014-02-06 18:30:43 +0000369 /// \return True if the diagnostic has been successfully reported, false
370 /// otherwise.
371 bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000372 /// Specialized handler for StackSize diagnostic.
Quentin Colombet728c5542014-02-06 18:30:43 +0000373 /// \return True if the diagnostic has been successfully reported, false
374 /// otherwise.
375 bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000376 /// Specialized handler for unsupported backend feature diagnostic.
Oliver Stannard91817852016-02-02 13:52:52 +0000377 void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D);
Petr Hosek7bdad082019-09-11 16:19:50 +0000378 /// Specialized handler for misexpect warnings.
379 /// Note that misexpect remarks are emitted through ORE
380 void MisExpectDiagHandler(const llvm::DiagnosticInfoMisExpect &D);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000381 /// Specialized handlers for optimization remarks.
Diego Novillod23ec942014-05-29 19:55:06 +0000382 /// Note that these handlers only accept remarks and they always handle
Diego Novillo829b1702014-04-16 16:54:24 +0000383 /// them.
Tyler Nowickif8a767d2014-07-18 19:40:19 +0000384 void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D,
385 unsigned DiagID);
Adam Nemet7b796f82017-01-26 04:07:11 +0000386 void
387 OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D);
Diego Novillod23ec942014-05-29 19:55:06 +0000388 void OptimizationRemarkHandler(
Adam Nemetb4e64a72016-09-27 22:19:29 +0000389 const llvm::OptimizationRemarkAnalysisFPCommute &D);
Diego Novillod23ec942014-05-29 19:55:06 +0000390 void OptimizationRemarkHandler(
Adam Nemetb4e64a72016-09-27 22:19:29 +0000391 const llvm::OptimizationRemarkAnalysisAliasing &D);
Tyler Nowickif8a767d2014-07-18 19:40:19 +0000392 void OptimizationFailureHandler(
393 const llvm::DiagnosticInfoOptimizationFailure &D);
Mike Stump11289f42009-09-09 15:08:12 +0000394 };
Jonas Devlieghere5eb9c812017-03-13 18:08:11 +0000395
David Blaikie68e081d2011-12-20 02:48:34 +0000396 void BackendConsumer::anchor() {}
Alexander Kornienkoab9db512015-06-22 23:07:51 +0000397}
Daniel Dunbarc13935e2008-10-21 23:49:24 +0000398
Vivek Pandya1dee3be2017-09-15 20:09:55 +0000399bool ClangDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) {
400 BackendCon->DiagnosticHandlerImpl(DI);
401 return true;
402}
403
Chris Lattner79f67a72010-04-08 00:23:06 +0000404/// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr
405/// buffer to be a valid FullSourceLoc.
406static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D,
407 SourceManager &CSM) {
408 // Get both the clang and llvm source managers. The location is relative to
409 // a memory buffer that the LLVM Source Manager is handling, we need to add
Daniel Dunbar50aa0a52010-04-29 16:29:09 +0000410 // a copy to the Clang source manager.
Chris Lattner79f67a72010-04-08 00:23:06 +0000411 const llvm::SourceMgr &LSM = *D.getSourceMgr();
Daniel Dunbar50aa0a52010-04-29 16:29:09 +0000412
Chris Lattner79f67a72010-04-08 00:23:06 +0000413 // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr
414 // already owns its one and clang::SourceManager wants to own its one.
415 const MemoryBuffer *LBuf =
416 LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
Daniel Dunbar50aa0a52010-04-29 16:29:09 +0000417
Chris Lattner79f67a72010-04-08 00:23:06 +0000418 // Create the copy and transfer ownership to clang::SourceManager.
Alp Tokeraa0dd5a2014-06-27 06:02:00 +0000419 // TODO: Avoid copying files into memory.
Rafael Espindolad87f8d72014-08-27 20:03:29 +0000420 std::unique_ptr<llvm::MemoryBuffer> CBuf =
421 llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(),
422 LBuf->getBufferIdentifier());
Alp Tokeraa0dd5a2014-06-27 06:02:00 +0000423 // FIXME: Keep a file ID map instead of creating new IDs for each location.
David Blaikie50a5f972014-08-29 07:59:55 +0000424 FileID FID = CSM.createFileID(std::move(CBuf));
Daniel Dunbar50aa0a52010-04-29 16:29:09 +0000425
Chris Lattner79f67a72010-04-08 00:23:06 +0000426 // Translate the offset into the file.
Alp Tokeraa0dd5a2014-06-27 06:02:00 +0000427 unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
Daniel Dunbar50aa0a52010-04-29 16:29:09 +0000428 SourceLocation NewLoc =
Argyrios Kyrtzidise6e67de2011-09-19 20:40:19 +0000429 CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset);
Chris Lattner79f67a72010-04-08 00:23:06 +0000430 return FullSourceLoc(NewLoc, CSM);
431}
432
Chris Lattner6d672132010-04-06 17:52:14 +0000433
Chris Lattner5ec32e72010-04-06 18:38:50 +0000434/// InlineAsmDiagHandler2 - This function is invoked when the backend hits an
435/// error parsing inline asm. The SMDiagnostic indicates the error relative to
Daniel Dunbar50aa0a52010-04-29 16:29:09 +0000436/// the temporary memory buffer that the inline asm parser has set up.
Chris Lattner5ec32e72010-04-06 18:38:50 +0000437void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D,
438 SourceLocation LocCookie) {
439 // There are a couple of different kinds of errors we could get here. First,
440 // we re-format the SMDiagnostic in terms of a clang diagnostic.
Argyrios Kyrtzidisa11b35a2012-02-01 06:36:49 +0000441
442 // Strip "error: " off the start of the message string.
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000443 StringRef Message = D.getMessage();
Argyrios Kyrtzidisa11b35a2012-02-01 06:36:49 +0000444 if (Message.startswith("error: "))
445 Message = Message.substr(7);
Chris Lattner5ec32e72010-04-06 18:38:50 +0000446
Chris Lattnerc7ed7ea2010-06-15 00:03:12 +0000447 // If the SMDiagnostic has an inline asm source location, translate it.
Chris Lattner5ec32e72010-04-06 18:38:50 +0000448 FullSourceLoc Loc;
Chris Lattner79f67a72010-04-08 00:23:06 +0000449 if (D.getLoc() != SMLoc())
450 Loc = ConvertBackendLocation(D, Context->getSourceManager());
Argyrios Kyrtzidisa11b35a2012-02-01 06:36:49 +0000451
Joey Gouly5798b262014-06-05 21:23:42 +0000452 unsigned DiagID;
453 switch (D.getKind()) {
454 case llvm::SourceMgr::DK_Error:
455 DiagID = diag::err_fe_inline_asm;
456 break;
457 case llvm::SourceMgr::DK_Warning:
458 DiagID = diag::warn_fe_inline_asm;
459 break;
460 case llvm::SourceMgr::DK_Note:
461 DiagID = diag::note_fe_inline_asm;
462 break;
Adam Nemet7b1faaa2017-10-12 23:56:54 +0000463 case llvm::SourceMgr::DK_Remark:
464 llvm_unreachable("remarks unexpected");
Joey Gouly5798b262014-06-05 21:23:42 +0000465 }
Chris Lattnerc7ed7ea2010-06-15 00:03:12 +0000466 // If this problem has clang-level source location information, report the
Joey Gouly5798b262014-06-05 21:23:42 +0000467 // issue in the source with a note showing the instantiated
Chris Lattnerc7ed7ea2010-06-15 00:03:12 +0000468 // code.
469 if (LocCookie.isValid()) {
Joey Gouly5798b262014-06-05 21:23:42 +0000470 Diags.Report(LocCookie, DiagID).AddString(Message);
Jonas Devlieghere5eb9c812017-03-13 18:08:11 +0000471
Benjamin Kramere06b2b72011-10-16 10:48:28 +0000472 if (D.getLoc().isValid()) {
473 DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here);
474 // Convert the SMDiagnostic ranges into SourceRange and attach them
475 // to the diagnostic.
Yaron Kerenede60302015-08-01 19:11:36 +0000476 for (const std::pair<unsigned, unsigned> &Range : D.getRanges()) {
Benjamin Kramere06b2b72011-10-16 10:48:28 +0000477 unsigned Column = D.getColumnNo();
478 B << SourceRange(Loc.getLocWithOffset(Range.first - Column),
479 Loc.getLocWithOffset(Range.second - Column));
480 }
481 }
Chris Lattnerc7ed7ea2010-06-15 00:03:12 +0000482 return;
483 }
Jonas Devlieghere5eb9c812017-03-13 18:08:11 +0000484
Joey Gouly5798b262014-06-05 21:23:42 +0000485 // Otherwise, report the backend issue as occurring in the generated .s file.
486 // If Loc is invalid, we still need to report the issue, it just gets no
Chris Lattnerc7ed7ea2010-06-15 00:03:12 +0000487 // location info.
Joey Gouly5798b262014-06-05 21:23:42 +0000488 Diags.Report(Loc, DiagID).AddString(Message);
Chris Lattner5ec32e72010-04-06 18:38:50 +0000489}
490
Quentin Colombet728c5542014-02-06 18:30:43 +0000491#define ComputeDiagID(Severity, GroupName, DiagID) \
492 do { \
493 switch (Severity) { \
494 case llvm::DS_Error: \
495 DiagID = diag::err_fe_##GroupName; \
496 break; \
497 case llvm::DS_Warning: \
498 DiagID = diag::warn_fe_##GroupName; \
499 break; \
Tobias Grosser74160242014-02-28 09:11:08 +0000500 case llvm::DS_Remark: \
501 llvm_unreachable("'remark' severity not expected"); \
502 break; \
503 case llvm::DS_Note: \
504 DiagID = diag::note_fe_##GroupName; \
505 break; \
506 } \
507 } while (false)
508
509#define ComputeDiagRemarkID(Severity, GroupName, DiagID) \
510 do { \
511 switch (Severity) { \
512 case llvm::DS_Error: \
513 DiagID = diag::err_fe_##GroupName; \
514 break; \
515 case llvm::DS_Warning: \
516 DiagID = diag::warn_fe_##GroupName; \
517 break; \
518 case llvm::DS_Remark: \
519 DiagID = diag::remark_fe_##GroupName; \
520 break; \
Quentin Colombet728c5542014-02-06 18:30:43 +0000521 case llvm::DS_Note: \
522 DiagID = diag::note_fe_##GroupName; \
523 break; \
524 } \
525 } while (false)
526
527bool
528BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) {
529 unsigned DiagID;
530 ComputeDiagID(D.getSeverity(), inline_asm, DiagID);
531 std::string Message = D.getMsgStr().str();
532
533 // If this problem has clang-level source location information, report the
Tobias Grosserbd25beb2014-02-26 10:21:56 +0000534 // issue as being a problem in the source with a note showing the instantiated
Quentin Colombet728c5542014-02-06 18:30:43 +0000535 // code.
536 SourceLocation LocCookie =
537 SourceLocation::getFromRawEncoding(D.getLocCookie());
538 if (LocCookie.isValid())
539 Diags.Report(LocCookie, DiagID).AddString(Message);
540 else {
541 // Otherwise, report the backend diagnostic as occurring in the generated
542 // .s file.
543 // If Loc is invalid, we still need to report the diagnostic, it just gets
544 // no location info.
545 FullSourceLoc Loc;
546 Diags.Report(Loc, DiagID).AddString(Message);
547 }
548 // We handled all the possible severities.
549 return true;
550}
551
552bool
553BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) {
554 if (D.getSeverity() != llvm::DS_Warning)
555 // For now, the only support we have for StackSize diagnostic is warning.
556 // We do not know how to format other severities.
557 return false;
558
Alp Tokerfb8d02b2014-06-05 22:10:59 +0000559 if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) {
Matt Arsenault4deb4ed22016-06-20 18:13:09 +0000560 // FIXME: Shouldn't need to truncate to uint32_t
Alp Tokerfb8d02b2014-06-05 22:10:59 +0000561 Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()),
562 diag::warn_fe_frame_larger_than)
Matt Arsenault4deb4ed22016-06-20 18:13:09 +0000563 << static_cast<uint32_t>(D.getStackSize()) << Decl::castToDeclContext(ND);
Alp Tokerfb8d02b2014-06-05 22:10:59 +0000564 return true;
565 }
566
567 return false;
Quentin Colombet728c5542014-02-06 18:30:43 +0000568}
569
Oliver Stannard91817852016-02-02 13:52:52 +0000570const FullSourceLoc BackendConsumer::getBestLocationFromDebugLoc(
Justin Bognere91e9dd2017-02-17 17:34:49 +0000571 const llvm::DiagnosticInfoWithLocationBase &D, bool &BadDebugInfo,
572 StringRef &Filename, unsigned &Line, unsigned &Column) const {
Diego Novillod23ec942014-05-29 19:55:06 +0000573 SourceManager &SourceMgr = Context->getSourceManager();
574 FileManager &FileMgr = SourceMgr.getFileManager();
Alp Toker27506272014-06-05 22:11:12 +0000575 SourceLocation DILoc;
Diego Novillo86f884e2015-05-08 20:59:56 +0000576
577 if (D.isLocationAvailable()) {
Adrian Prantl212c1042018-12-06 18:44:50 +0000578 D.getLocation(Filename, Line, Column);
579 if (Line > 0) {
Harlan Haskins8d323d12019-08-01 21:31:56 +0000580 auto FE = FileMgr.getFile(Filename);
Adrian Prantl212c1042018-12-06 18:44:50 +0000581 if (!FE)
582 FE = FileMgr.getFile(D.getAbsolutePath());
583 if (FE) {
584 // If -gcolumn-info was not used, Column will be 0. This upsets the
585 // source manager, so pass 1 if Column is not set.
Harlan Haskins8d323d12019-08-01 21:31:56 +0000586 DILoc = SourceMgr.translateFileLineCol(*FE, Line, Column ? Column : 1);
Adrian Prantl212c1042018-12-06 18:44:50 +0000587 }
Diego Novillo86f884e2015-05-08 20:59:56 +0000588 }
Oliver Stannard91817852016-02-02 13:52:52 +0000589 BadDebugInfo = DILoc.isInvalid();
Diego Novillo829b1702014-04-16 16:54:24 +0000590 }
Alp Toker27506272014-06-05 22:11:12 +0000591
592 // If a location isn't available, try to approximate it using the associated
593 // function definition. We use the definition's right brace to differentiate
594 // from diagnostics that genuinely relate to the function itself.
595 FullSourceLoc Loc(DILoc, SourceMgr);
596 if (Loc.isInvalid())
597 if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName()))
Oliver Stannard91817852016-02-02 13:52:52 +0000598 Loc = FD->getASTContext().getFullLoc(FD->getLocation());
Diego Novillod23ec942014-05-29 19:55:06 +0000599
Diego Novillo86f884e2015-05-08 20:59:56 +0000600 if (DILoc.isInvalid() && D.isLocationAvailable())
Diego Novillod23ec942014-05-29 19:55:06 +0000601 // If we were not able to translate the file:line:col information
602 // back to a SourceLocation, at least emit a note stating that
603 // we could not translate this location. This can happen in the
604 // case of #line directives.
Oliver Stannard91817852016-02-02 13:52:52 +0000605 Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
Ben Craig6e4695a2016-05-06 13:29:46 +0000606 << Filename << Line << Column;
Oliver Stannard91817852016-02-02 13:52:52 +0000607
608 return Loc;
609}
610
611void BackendConsumer::UnsupportedDiagHandler(
612 const llvm::DiagnosticInfoUnsupported &D) {
613 // We only support errors.
614 assert(D.getSeverity() == llvm::DS_Error);
615
616 StringRef Filename;
617 unsigned Line, Column;
Reid Klecknerf70ee602017-05-12 00:10:49 +0000618 bool BadDebugInfo = false;
619 FullSourceLoc Loc =
620 getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
Oliver Stannard91817852016-02-02 13:52:52 +0000621
Zachary Turner41a9ee92017-10-11 23:54:34 +0000622 Diags.Report(Loc, diag::err_fe_backend_unsupported) << D.getMessage().str();
Oliver Stannard91817852016-02-02 13:52:52 +0000623
624 if (BadDebugInfo)
625 // If we were not able to translate the file:line:col information
626 // back to a SourceLocation, at least emit a note stating that
627 // we could not translate this location. This can happen in the
628 // case of #line directives.
629 Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
630 << Filename << Line << Column;
631}
632
Petr Hosek7bdad082019-09-11 16:19:50 +0000633void BackendConsumer::MisExpectDiagHandler(
634 const llvm::DiagnosticInfoMisExpect &D) {
635 StringRef Filename;
636 unsigned Line, Column;
637 bool BadDebugInfo = false;
638 FullSourceLoc Loc =
639 getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
640
641 Diags.Report(Loc, diag::warn_profile_data_misexpect) << D.getMsg().str();
642
643 if (BadDebugInfo)
644 // If we were not able to translate the file:line:col information
645 // back to a SourceLocation, at least emit a note stating that
646 // we could not translate this location. This can happen in the
647 // case of #line directives.
648 Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
649 << Filename << Line << Column;
650}
651
Oliver Stannard91817852016-02-02 13:52:52 +0000652void BackendConsumer::EmitOptimizationMessage(
653 const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) {
654 // We only support warnings and remarks.
655 assert(D.getSeverity() == llvm::DS_Remark ||
656 D.getSeverity() == llvm::DS_Warning);
657
658 StringRef Filename;
659 unsigned Line, Column;
660 bool BadDebugInfo = false;
Reid Klecknerf70ee602017-05-12 00:10:49 +0000661 FullSourceLoc Loc =
662 getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
Oliver Stannard91817852016-02-02 13:52:52 +0000663
Adam Nemet1eea3e52016-09-13 04:32:40 +0000664 std::string Msg;
665 raw_string_ostream MsgStream(Msg);
Adam Nemet699fc5b2016-09-27 20:55:12 +0000666 MsgStream << D.getMsg();
Adam Nemet1eea3e52016-09-13 04:32:40 +0000667
668 if (D.getHotness())
669 MsgStream << " (hotness: " << *D.getHotness() << ")";
670
Oliver Stannard91817852016-02-02 13:52:52 +0000671 Diags.Report(Loc, DiagID)
Mehdi Amini117296c2016-10-01 02:56:57 +0000672 << AddFlagValue(D.getPassName())
Adam Nemet1eea3e52016-09-13 04:32:40 +0000673 << MsgStream.str();
Oliver Stannard91817852016-02-02 13:52:52 +0000674
675 if (BadDebugInfo)
676 // If we were not able to translate the file:line:col information
677 // back to a SourceLocation, at least emit a note stating that
678 // we could not translate this location. This can happen in the
679 // case of #line directives.
680 Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
Diego Novillod23ec942014-05-29 19:55:06 +0000681 << Filename << Line << Column;
682}
683
684void BackendConsumer::OptimizationRemarkHandler(
Adam Nemet7b796f82017-01-26 04:07:11 +0000685 const llvm::DiagnosticInfoOptimizationBase &D) {
Adam Nemet28c2c222017-10-04 04:25:31 +0000686 // Without hotness information, don't show noisy remarks.
687 if (D.isVerbose() && !D.getHotness())
688 return;
689
Adam Nemet7b796f82017-01-26 04:07:11 +0000690 if (D.isPassed()) {
691 // Optimization remarks are active only if the -Rpass flag has a regular
692 // expression that matches the name of the pass name in \p D.
693 if (CodeGenOpts.OptimizationRemarkPattern &&
694 CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName()))
695 EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark);
696 } else if (D.isMissed()) {
697 // Missed optimization remarks are active only if the -Rpass-missed
698 // flag has a regular expression that matches the name of the pass
699 // name in \p D.
700 if (CodeGenOpts.OptimizationRemarkMissedPattern &&
701 CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName()))
702 EmitOptimizationMessage(
703 D, diag::remark_fe_backend_optimization_remark_missed);
704 } else {
705 assert(D.isAnalysis() && "Unknown remark type");
Diego Novillod23ec942014-05-29 19:55:06 +0000706
Adam Nemet7b796f82017-01-26 04:07:11 +0000707 bool ShouldAlwaysPrint = false;
708 if (auto *ORA = dyn_cast<llvm::OptimizationRemarkAnalysis>(&D))
709 ShouldAlwaysPrint = ORA->shouldAlwaysPrint();
Diego Novillod23ec942014-05-29 19:55:06 +0000710
Adam Nemet7b796f82017-01-26 04:07:11 +0000711 if (ShouldAlwaysPrint ||
712 (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
713 CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
714 EmitOptimizationMessage(
715 D, diag::remark_fe_backend_optimization_remark_analysis);
716 }
Diego Novillo829b1702014-04-16 16:54:24 +0000717}
718
Tyler Nowicki8a0925c2015-08-10 19:56:40 +0000719void BackendConsumer::OptimizationRemarkHandler(
Adam Nemetb4e64a72016-09-27 22:19:29 +0000720 const llvm::OptimizationRemarkAnalysisFPCommute &D) {
Tyler Nowicki65061a22015-08-11 01:10:08 +0000721 // Optimization analysis remarks are active if the pass name is set to
722 // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a
723 // regular expression that matches the name of the pass name in \p D.
724
Adam Nemetb5beb972016-06-29 04:55:31 +0000725 if (D.shouldAlwaysPrint() ||
Tyler Nowicki65061a22015-08-11 01:10:08 +0000726 (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
727 CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
Tyler Nowicki8a0925c2015-08-10 19:56:40 +0000728 EmitOptimizationMessage(
729 D, diag::remark_fe_backend_optimization_remark_analysis_fpcommute);
730}
731
Tyler Nowicki034baf62015-08-10 23:05:16 +0000732void BackendConsumer::OptimizationRemarkHandler(
Adam Nemetb4e64a72016-09-27 22:19:29 +0000733 const llvm::OptimizationRemarkAnalysisAliasing &D) {
Tyler Nowicki65061a22015-08-11 01:10:08 +0000734 // Optimization analysis remarks are active if the pass name is set to
735 // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a
736 // regular expression that matches the name of the pass name in \p D.
737
Adam Nemetb5beb972016-06-29 04:55:31 +0000738 if (D.shouldAlwaysPrint() ||
Tyler Nowicki65061a22015-08-11 01:10:08 +0000739 (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
740 CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
Tyler Nowicki034baf62015-08-10 23:05:16 +0000741 EmitOptimizationMessage(
742 D, diag::remark_fe_backend_optimization_remark_analysis_aliasing);
743}
744
Tyler Nowickif8a767d2014-07-18 19:40:19 +0000745void BackendConsumer::OptimizationFailureHandler(
746 const llvm::DiagnosticInfoOptimizationFailure &D) {
747 EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure);
748}
749
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000750/// This function is invoked when the backend needs
Quentin Colombet728c5542014-02-06 18:30:43 +0000751/// to report something to the user.
752void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
753 unsigned DiagID = diag::err_fe_inline_asm;
754 llvm::DiagnosticSeverity Severity = DI.getSeverity();
755 // Get the diagnostic ID based.
756 switch (DI.getKind()) {
757 case llvm::DK_InlineAsm:
758 if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI)))
759 return;
760 ComputeDiagID(Severity, inline_asm, DiagID);
761 break;
762 case llvm::DK_StackSize:
763 if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI)))
764 return;
765 ComputeDiagID(Severity, backend_frame_larger_than, DiagID);
766 break;
Rafael Espindola8ce88a52015-12-14 23:17:07 +0000767 case DK_Linker:
768 assert(CurLinkModule);
769 // FIXME: stop eating the warnings and notes.
770 if (Severity != DS_Error)
771 return;
772 DiagID = diag::err_fe_cannot_link_module;
773 break;
Diego Novillo829b1702014-04-16 16:54:24 +0000774 case llvm::DK_OptimizationRemark:
775 // Optimization remarks are always handled completely by this
776 // handler. There is no generic way of emitting them.
Adam Nemetb4e64a72016-09-27 22:19:29 +0000777 OptimizationRemarkHandler(cast<OptimizationRemark>(DI));
Diego Novillo829b1702014-04-16 16:54:24 +0000778 return;
Diego Novillo9c89ff12014-05-29 16:19:27 +0000779 case llvm::DK_OptimizationRemarkMissed:
Diego Novillod23ec942014-05-29 19:55:06 +0000780 // Optimization remarks are always handled completely by this
781 // handler. There is no generic way of emitting them.
Adam Nemetb4e64a72016-09-27 22:19:29 +0000782 OptimizationRemarkHandler(cast<OptimizationRemarkMissed>(DI));
Diego Novillod23ec942014-05-29 19:55:06 +0000783 return;
Diego Novillo9c89ff12014-05-29 16:19:27 +0000784 case llvm::DK_OptimizationRemarkAnalysis:
Diego Novillod23ec942014-05-29 19:55:06 +0000785 // Optimization remarks are always handled completely by this
786 // handler. There is no generic way of emitting them.
Adam Nemetb4e64a72016-09-27 22:19:29 +0000787 OptimizationRemarkHandler(cast<OptimizationRemarkAnalysis>(DI));
Diego Novillo9c89ff12014-05-29 16:19:27 +0000788 return;
Tyler Nowicki8a0925c2015-08-10 19:56:40 +0000789 case llvm::DK_OptimizationRemarkAnalysisFPCommute:
790 // Optimization remarks are always handled completely by this
791 // handler. There is no generic way of emitting them.
Adam Nemetb4e64a72016-09-27 22:19:29 +0000792 OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisFPCommute>(DI));
Tyler Nowicki8a0925c2015-08-10 19:56:40 +0000793 return;
Tyler Nowicki034baf62015-08-10 23:05:16 +0000794 case llvm::DK_OptimizationRemarkAnalysisAliasing:
795 // Optimization remarks are always handled completely by this
796 // handler. There is no generic way of emitting them.
Adam Nemetb4e64a72016-09-27 22:19:29 +0000797 OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisAliasing>(DI));
Tyler Nowicki034baf62015-08-10 23:05:16 +0000798 return;
Adam Nemet7b796f82017-01-26 04:07:11 +0000799 case llvm::DK_MachineOptimizationRemark:
800 // Optimization remarks are always handled completely by this
801 // handler. There is no generic way of emitting them.
802 OptimizationRemarkHandler(cast<MachineOptimizationRemark>(DI));
803 return;
804 case llvm::DK_MachineOptimizationRemarkMissed:
805 // Optimization remarks are always handled completely by this
806 // handler. There is no generic way of emitting them.
807 OptimizationRemarkHandler(cast<MachineOptimizationRemarkMissed>(DI));
808 return;
809 case llvm::DK_MachineOptimizationRemarkAnalysis:
810 // Optimization remarks are always handled completely by this
811 // handler. There is no generic way of emitting them.
812 OptimizationRemarkHandler(cast<MachineOptimizationRemarkAnalysis>(DI));
813 return;
Tyler Nowickif8a767d2014-07-18 19:40:19 +0000814 case llvm::DK_OptimizationFailure:
815 // Optimization failures are always handled completely by this
816 // handler.
817 OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI));
818 return;
Oliver Stannard91817852016-02-02 13:52:52 +0000819 case llvm::DK_Unsupported:
820 UnsupportedDiagHandler(cast<DiagnosticInfoUnsupported>(DI));
821 return;
Petr Hosek7bdad082019-09-11 16:19:50 +0000822 case llvm::DK_MisExpect:
823 MisExpectDiagHandler(cast<DiagnosticInfoMisExpect>(DI));
824 return;
Quentin Colombet728c5542014-02-06 18:30:43 +0000825 default:
826 // Plugin IDs are not bound to any value as they are set dynamically.
Tobias Grosser74160242014-02-28 09:11:08 +0000827 ComputeDiagRemarkID(Severity, backend_plugin, DiagID);
Quentin Colombet728c5542014-02-06 18:30:43 +0000828 break;
829 }
830 std::string MsgStorage;
831 {
832 raw_string_ostream Stream(MsgStorage);
833 DiagnosticPrinterRawOStream DP(Stream);
834 DI.print(DP);
835 }
836
Rafael Espindola8ce88a52015-12-14 23:17:07 +0000837 if (DiagID == diag::err_fe_cannot_link_module) {
838 Diags.Report(diag::err_fe_cannot_link_module)
839 << CurLinkModule->getModuleIdentifier() << MsgStorage;
840 return;
841 }
842
Quentin Colombet728c5542014-02-06 18:30:43 +0000843 // Report the backend message using the usual diagnostic mechanism.
844 FullSourceLoc Loc;
845 Diags.Report(Loc, DiagID).AddString(MsgStorage);
846}
847#undef ComputeDiagID
Daniel Dunbarcea0c702010-02-25 04:37:45 +0000848
Peter Collingbourne8f5cf742011-02-19 23:03:58 +0000849CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext)
Artem Belevich5d40ae32015-10-27 17:56:59 +0000850 : Act(_Act), VMContext(_VMContext ? _VMContext : new LLVMContext),
Eric Christopher02e3dd42016-03-12 01:47:11 +0000851 OwnsVMContext(!_VMContext) {}
Daniel Dunbarcea0c702010-02-25 04:37:45 +0000852
Peter Collingbourne8f5cf742011-02-19 23:03:58 +0000853CodeGenAction::~CodeGenAction() {
854 TheModule.reset();
855 if (OwnsVMContext)
856 delete VMContext;
857}
Daniel Dunbare8ecf9a2010-02-25 20:37:44 +0000858
Daniel Dunbar6f8362c2010-06-07 23:27:59 +0000859bool CodeGenAction::hasIRSupport() const { return true; }
860
Daniel Dunbar400a6932010-02-25 04:37:50 +0000861void CodeGenAction::EndSourceFileAction() {
862 // If the consumer creation failed, do nothing.
863 if (!getCompilerInstance().hasASTConsumer())
864 return;
865
866 // Steal the module from the consumer.
David Blaikie780dd3b2014-08-29 05:08:19 +0000867 TheModule = BEConsumer->takeModule();
Daniel Dunbar400a6932010-02-25 04:37:50 +0000868}
869
Rafael Espindolae8337302014-08-19 14:36:35 +0000870std::unique_ptr<llvm::Module> CodeGenAction::takeModule() {
871 return std::move(TheModule);
872}
873
Peter Collingbourne8f5cf742011-02-19 23:03:58 +0000874llvm::LLVMContext *CodeGenAction::takeLLVMContext() {
875 OwnsVMContext = false;
876 return VMContext;
877}
878
Peter Collingbourne03f89072016-07-15 00:55:40 +0000879static std::unique_ptr<raw_pwrite_stream>
Rafael Espindola2f16bc12015-04-14 15:15:49 +0000880GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
Daniel Dunbar6f8362c2010-06-07 23:27:59 +0000881 switch (Action) {
882 case Backend_EmitAssembly:
883 return CI.createDefaultOutputFile(false, InFile, "s");
884 case Backend_EmitLL:
885 return CI.createDefaultOutputFile(false, InFile, "ll");
886 case Backend_EmitBC:
887 return CI.createDefaultOutputFile(true, InFile, "bc");
888 case Backend_EmitNothing:
Craig Topper8a13c412014-05-21 05:09:00 +0000889 return nullptr;
Daniel Dunbar6f8362c2010-06-07 23:27:59 +0000890 case Backend_EmitMCNull:
Alp Tokerea046722014-06-03 17:23:34 +0000891 return CI.createNullOutputFile();
Daniel Dunbar6f8362c2010-06-07 23:27:59 +0000892 case Backend_EmitObj:
893 return CI.createDefaultOutputFile(true, InFile, "o");
894 }
895
David Blaikie83d382b2011-09-23 05:06:16 +0000896 llvm_unreachable("Invalid action!");
Daniel Dunbar6f8362c2010-06-07 23:27:59 +0000897}
898
David Blaikie6beb6aa2014-08-10 19:56:51 +0000899std::unique_ptr<ASTConsumer>
900CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
Daniel Dunbarcea0c702010-02-25 04:37:45 +0000901 BackendAction BA = static_cast<BackendAction>(Act);
Alexey Sotkinaba98fc2018-03-02 12:11:40 +0000902 std::unique_ptr<raw_pwrite_stream> OS = CI.takeOutputStream();
903 if (!OS)
904 OS = GetOutputStream(CI, InFile, BA);
905
Daniel Dunbarcea0c702010-02-25 04:37:45 +0000906 if (BA != Backend_EmitNothing && !OS)
Craig Topper8a13c412014-05-21 05:09:00 +0000907 return nullptr;
Daniel Dunbarcea0c702010-02-25 04:37:45 +0000908
Artem Belevich5d40ae32015-10-27 17:56:59 +0000909 // Load bitcode modules to link with, if we need to.
910 if (LinkModules.empty())
Justin Lebarb080b632017-01-25 21:29:48 +0000911 for (const CodeGenOptions::BitcodeFileToLink &F :
912 CI.getCodeGenOpts().LinkBitcodeFiles) {
913 auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename);
Artem Belevich5d40ae32015-10-27 17:56:59 +0000914 if (!BCBuf) {
915 CI.getDiagnostics().Report(diag::err_cannot_open_file)
Justin Lebarb080b632017-01-25 21:29:48 +0000916 << F.Filename << BCBuf.getError().message();
Artem Belevich5d40ae32015-10-27 17:56:59 +0000917 LinkModules.clear();
918 return nullptr;
919 }
Peter Collingbournef1d76db2011-10-30 17:30:44 +0000920
Peter Collingbourned9445c42016-11-13 07:00:17 +0000921 Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
Peter Collingbournee2dcf7c2016-11-08 06:03:43 +0000922 getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext);
Peter Collingbourned9445c42016-11-13 07:00:17 +0000923 if (!ModuleOrErr) {
924 handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
925 CI.getDiagnostics().Report(diag::err_cannot_open_file)
Justin Lebarb080b632017-01-25 21:29:48 +0000926 << F.Filename << EIB.message();
Peter Collingbourned9445c42016-11-13 07:00:17 +0000927 });
Artem Belevich5d40ae32015-10-27 17:56:59 +0000928 LinkModules.clear();
929 return nullptr;
930 }
Jonas Devlieghere5eb9c812017-03-13 18:08:11 +0000931 LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs,
932 F.Internalize, F.LinkFlags});
Peter Collingbournef1d76db2011-10-30 17:30:44 +0000933 }
Peter Collingbournef1d76db2011-10-30 17:30:44 +0000934
Alex Lorenzee024992014-08-04 18:41:51 +0000935 CoverageSourceInfo *CoverageInfo = nullptr;
936 // Add the preprocessor callback only when the coverage mapping is generated.
937 if (CI.getCodeGenOpts().CoverageMapping) {
938 CoverageInfo = new CoverageSourceInfo;
Craig Topperb8a70532014-09-10 04:53:53 +0000939 CI.getPreprocessor().addPPCallbacks(
940 std::unique_ptr<PPCallbacks>(CoverageInfo));
Alex Lorenzee024992014-08-04 18:41:51 +0000941 }
Artem Belevich5d40ae32015-10-27 17:56:59 +0000942
David Blaikie037e75b2014-08-10 21:06:17 +0000943 std::unique_ptr<BackendConsumer> Result(new BackendConsumer(
Adrian Prantle74f5252015-06-30 02:26:03 +0000944 BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
945 CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
Justin Lebarb080b632017-01-25 21:29:48 +0000946 CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile,
947 std::move(LinkModules), std::move(OS), *VMContext, CoverageInfo));
David Blaikie6beb6aa2014-08-10 19:56:51 +0000948 BEConsumer = Result.get();
Amjad Aboud546bc112017-02-09 22:07:24 +0000949
950 // Enable generating macro debug info only when debug info is not disabled and
951 // also macro debug info is enabled.
952 if (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo &&
953 CI.getCodeGenOpts().MacroDebugInfo) {
954 std::unique_ptr<PPCallbacks> Callbacks =
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +0000955 std::make_unique<MacroPPCallbacks>(BEConsumer->getCodeGenerator(),
Amjad Aboud546bc112017-02-09 22:07:24 +0000956 CI.getPreprocessor());
957 CI.getPreprocessor().addPPCallbacks(std::move(Callbacks));
958 }
959
David Blaikie6beb6aa2014-08-10 19:56:51 +0000960 return std::move(Result);
Daniel Dunbarc13935e2008-10-21 23:49:24 +0000961}
Daniel Dunbarcea0c702010-02-25 04:37:45 +0000962
Tim Northover1390b442016-04-06 19:58:07 +0000963static void BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic &SM,
964 void *Context,
965 unsigned LocCookie) {
966 SM.print(nullptr, llvm::errs());
967
968 auto Diags = static_cast<DiagnosticsEngine *>(Context);
969 unsigned DiagID;
970 switch (SM.getKind()) {
971 case llvm::SourceMgr::DK_Error:
972 DiagID = diag::err_fe_inline_asm;
973 break;
974 case llvm::SourceMgr::DK_Warning:
975 DiagID = diag::warn_fe_inline_asm;
976 break;
977 case llvm::SourceMgr::DK_Note:
978 DiagID = diag::note_fe_inline_asm;
979 break;
Adam Nemet7b1faaa2017-10-12 23:56:54 +0000980 case llvm::SourceMgr::DK_Remark:
981 llvm_unreachable("remarks unexpected");
Tim Northover1390b442016-04-06 19:58:07 +0000982 }
983
984 Diags->Report(DiagID).AddString("cannot compile inline asm");
985}
986
Nico Weber04347d82019-04-04 21:06:41 +0000987std::unique_ptr<llvm::Module>
988CodeGenAction::loadModule(MemoryBufferRef MBRef) {
Peter Collingbourne65cb42c2017-01-24 19:55:38 +0000989 CompilerInstance &CI = getCompilerInstance();
990 SourceManager &SM = CI.getSourceManager();
991
992 // For ThinLTO backend invocations, ensure that the context
Peter Collingbournef5d17122017-01-26 21:09:48 +0000993 // merges types based on ODR identifiers. We also need to read
994 // the correct module out of a multi-module bitcode file.
995 if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) {
Peter Collingbourne65cb42c2017-01-24 19:55:38 +0000996 VMContext->enableDebugTypeODRUniquing();
997
Peter Collingbournef5d17122017-01-26 21:09:48 +0000998 auto DiagErrors = [&](Error E) -> std::unique_ptr<llvm::Module> {
999 unsigned DiagID =
1000 CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
1001 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1002 CI.getDiagnostics().Report(DiagID) << EIB.message();
1003 });
1004 return {};
1005 };
1006
Vitaly Bukac35ff822018-02-16 23:34:16 +00001007 Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef);
1008 if (!BMsOrErr)
1009 return DiagErrors(BMsOrErr.takeError());
1010 BitcodeModule *Bm = FindThinLTOModule(*BMsOrErr);
1011 // We have nothing to do if the file contains no ThinLTO module. This is
1012 // possible if ThinLTO compilation was not able to split module. Content of
1013 // the file was already processed by indexing and will be passed to the
1014 // linker using merged object file.
1015 if (!Bm) {
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00001016 auto M = std::make_unique<llvm::Module>("empty", *VMContext);
Vitaly Bukac35ff822018-02-16 23:34:16 +00001017 M->setTargetTriple(CI.getTargetOpts().Triple);
1018 return M;
1019 }
Peter Collingbournef5d17122017-01-26 21:09:48 +00001020 Expected<std::unique_ptr<llvm::Module>> MOrErr =
Vitaly Bukac35ff822018-02-16 23:34:16 +00001021 Bm->parseModule(*VMContext);
Peter Collingbournef5d17122017-01-26 21:09:48 +00001022 if (!MOrErr)
1023 return DiagErrors(MOrErr.takeError());
1024 return std::move(*MOrErr);
1025 }
1026
Peter Collingbourne65cb42c2017-01-24 19:55:38 +00001027 llvm::SMDiagnostic Err;
1028 if (std::unique_ptr<llvm::Module> M = parseIR(MBRef, Err, *VMContext))
1029 return M;
1030
1031 // Translate from the diagnostic info to the SourceManager location if
1032 // available.
1033 // TODO: Unify this with ConvertBackendLocation()
1034 SourceLocation Loc;
1035 if (Err.getLineNo() > 0) {
1036 assert(Err.getColumnNo() >= 0);
1037 Loc = SM.translateFileLineCol(SM.getFileEntryForID(SM.getMainFileID()),
1038 Err.getLineNo(), Err.getColumnNo() + 1);
1039 }
1040
1041 // Strip off a leading diagnostic code if there is one.
1042 StringRef Msg = Err.getMessage();
1043 if (Msg.startswith("error: "))
1044 Msg = Msg.substr(7);
1045
1046 unsigned DiagID =
1047 CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
1048
1049 CI.getDiagnostics().Report(Loc, DiagID) << Msg;
1050 return {};
1051}
1052
Daniel Dunbar6f8362c2010-06-07 23:27:59 +00001053void CodeGenAction::ExecuteAction() {
1054 // If this is an IR file, we have to treat it specially.
Rainer Orth09d890d2019-08-05 13:59:26 +00001055 if (getCurrentFileKind().getLanguage() == Language::LLVM_IR) {
Daniel Dunbar6f8362c2010-06-07 23:27:59 +00001056 BackendAction BA = static_cast<BackendAction>(Act);
1057 CompilerInstance &CI = getCompilerInstance();
Zahira Ammarguellata3b25522019-12-05 10:23:47 -05001058 auto &CodeGenOpts = CI.getCodeGenOpts();
1059 auto &Diagnostics = CI.getDiagnostics();
Peter Collingbourne03f89072016-07-15 00:55:40 +00001060 std::unique_ptr<raw_pwrite_stream> OS =
1061 GetOutputStream(CI, getCurrentFile(), BA);
Daniel Dunbar6f8362c2010-06-07 23:27:59 +00001062 if (BA != Backend_EmitNothing && !OS)
1063 return;
1064
1065 bool Invalid;
1066 SourceManager &SM = CI.getSourceManager();
Alp Toker7b463d52014-06-30 01:33:59 +00001067 FileID FID = SM.getMainFileID();
Nico Weber04347d82019-04-04 21:06:41 +00001068 const llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid);
Daniel Dunbar6f8362c2010-06-07 23:27:59 +00001069 if (Invalid)
1070 return;
1071
Peter Collingbourne65cb42c2017-01-24 19:55:38 +00001072 TheModule = loadModule(*MainFile);
1073 if (!TheModule)
Daniel Dunbar6f8362c2010-06-07 23:27:59 +00001074 return;
Peter Collingbourne65cb42c2017-01-24 19:55:38 +00001075
Rafael Espindolad5e81e52013-12-20 22:01:25 +00001076 const TargetOptions &TargetOpts = CI.getTargetOpts();
1077 if (TheModule->getTargetTriple() != TargetOpts.Triple) {
Zahira Ammarguellata3b25522019-12-05 10:23:47 -05001078 Diagnostics.Report(SourceLocation(),
1079 diag::warn_fe_override_module)
Nico Weber6cf2df22015-01-29 06:25:59 +00001080 << TargetOpts.Triple;
Rafael Espindolad5e81e52013-12-20 22:01:25 +00001081 TheModule->setTargetTriple(TargetOpts.Triple);
1082 }
Daniel Dunbar6f8362c2010-06-07 23:27:59 +00001083
Zahira Ammarguellata3b25522019-12-05 10:23:47 -05001084 EmbedBitcode(TheModule.get(), CodeGenOpts,
Steven Wu27fb5222016-05-11 16:26:03 +00001085 MainFile->getMemBufferRef());
1086
Tim Northover1390b442016-04-06 19:58:07 +00001087 LLVMContext &Ctx = TheModule->getContext();
1088 Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler,
Zahira Ammarguellata3b25522019-12-05 10:23:47 -05001089 &Diagnostics);
Steven Wu27fb5222016-05-11 16:26:03 +00001090
Zahira Ammarguellata3b25522019-12-05 10:23:47 -05001091 Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
1092 setupOptimizationRemarks(
1093 Ctx, CodeGenOpts.OptRecordFile,
1094 CodeGenOpts.OptRecordPasses,
1095 CodeGenOpts.OptRecordFormat,
1096 CodeGenOpts.DiagnosticsWithHotness,
1097 CodeGenOpts.DiagnosticsHotnessThreshold);
1098
1099 if (Error E = OptRecordFileOrErr.takeError()) {
1100 reportOptRecordError(std::move(E), Diagnostics, CodeGenOpts);
1101 return;
1102 }
1103 std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
1104 std::move(*OptRecordFileOrErr);
1105
1106 EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(),
1107 CodeGenOpts, TargetOpts, CI.getLangOpts(),
Saleem Abdulrasool888e2892017-01-05 16:02:32 +00001108 CI.getTarget().getDataLayout(), TheModule.get(), BA,
1109 std::move(OS));
Zahira Ammarguellata3b25522019-12-05 10:23:47 -05001110
1111 if (OptRecordFile)
1112 OptRecordFile->keep();
Daniel Dunbar6f8362c2010-06-07 23:27:59 +00001113 return;
1114 }
1115
1116 // Otherwise follow the normal AST path.
1117 this->ASTFrontendAction::ExecuteAction();
1118}
1119
1120//
1121
David Blaikie68e081d2011-12-20 02:48:34 +00001122void EmitAssemblyAction::anchor() { }
Peter Collingbourne8f5cf742011-02-19 23:03:58 +00001123EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext)
1124 : CodeGenAction(Backend_EmitAssembly, _VMContext) {}
Daniel Dunbarcea0c702010-02-25 04:37:45 +00001125
David Blaikie68e081d2011-12-20 02:48:34 +00001126void EmitBCAction::anchor() { }
Peter Collingbourne8f5cf742011-02-19 23:03:58 +00001127EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext)
1128 : CodeGenAction(Backend_EmitBC, _VMContext) {}
Daniel Dunbarcea0c702010-02-25 04:37:45 +00001129
David Blaikie68e081d2011-12-20 02:48:34 +00001130void EmitLLVMAction::anchor() { }
Peter Collingbourne8f5cf742011-02-19 23:03:58 +00001131EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext)
1132 : CodeGenAction(Backend_EmitLL, _VMContext) {}
Daniel Dunbarcea0c702010-02-25 04:37:45 +00001133
David Blaikie68e081d2011-12-20 02:48:34 +00001134void EmitLLVMOnlyAction::anchor() { }
Peter Collingbourne8f5cf742011-02-19 23:03:58 +00001135EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext)
1136 : CodeGenAction(Backend_EmitNothing, _VMContext) {}
Daniel Dunbarcea0c702010-02-25 04:37:45 +00001137
David Blaikie68e081d2011-12-20 02:48:34 +00001138void EmitCodeGenOnlyAction::anchor() { }
Peter Collingbourne8f5cf742011-02-19 23:03:58 +00001139EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext)
1140 : CodeGenAction(Backend_EmitMCNull, _VMContext) {}
Daniel Dunbar4c77a642010-05-25 18:41:01 +00001141
David Blaikie68e081d2011-12-20 02:48:34 +00001142void EmitObjAction::anchor() { }
Peter Collingbourne8f5cf742011-02-19 23:03:58 +00001143EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext)
1144 : CodeGenAction(Backend_EmitObj, _VMContext) {}