File: | tools/clang/lib/CodeGen/CodeGenAction.cpp |
Warning: | line 575, column 5 2nd function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | ||||
10 | #include "clang/CodeGen/CodeGenAction.h" | |||
11 | #include "CodeGenModule.h" | |||
12 | #include "CoverageMappingGen.h" | |||
13 | #include "MacroPPCallbacks.h" | |||
14 | #include "clang/AST/ASTConsumer.h" | |||
15 | #include "clang/AST/ASTContext.h" | |||
16 | #include "clang/AST/DeclCXX.h" | |||
17 | #include "clang/AST/DeclGroup.h" | |||
18 | #include "clang/Basic/FileManager.h" | |||
19 | #include "clang/Basic/SourceManager.h" | |||
20 | #include "clang/Basic/TargetInfo.h" | |||
21 | #include "clang/CodeGen/BackendUtil.h" | |||
22 | #include "clang/CodeGen/ModuleBuilder.h" | |||
23 | #include "clang/Frontend/CompilerInstance.h" | |||
24 | #include "clang/Frontend/FrontendDiagnostic.h" | |||
25 | #include "clang/Lex/Preprocessor.h" | |||
26 | #include "llvm/Bitcode/BitcodeReader.h" | |||
27 | #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" | |||
28 | #include "llvm/IR/DebugInfo.h" | |||
29 | #include "llvm/IR/DiagnosticInfo.h" | |||
30 | #include "llvm/IR/DiagnosticPrinter.h" | |||
31 | #include "llvm/IR/GlobalValue.h" | |||
32 | #include "llvm/IR/LLVMContext.h" | |||
33 | #include "llvm/IR/Module.h" | |||
34 | #include "llvm/IRReader/IRReader.h" | |||
35 | #include "llvm/Linker/Linker.h" | |||
36 | #include "llvm/Pass.h" | |||
37 | #include "llvm/Support/MemoryBuffer.h" | |||
38 | #include "llvm/Support/SourceMgr.h" | |||
39 | #include "llvm/Support/Timer.h" | |||
40 | #include "llvm/Support/ToolOutputFile.h" | |||
41 | #include "llvm/Support/YAMLTraits.h" | |||
42 | #include "llvm/Transforms/IPO/Internalize.h" | |||
43 | ||||
44 | #include <memory> | |||
45 | using namespace clang; | |||
46 | using namespace llvm; | |||
47 | ||||
48 | namespace clang { | |||
49 | class BackendConsumer; | |||
50 | class ClangDiagnosticHandler final : public DiagnosticHandler { | |||
51 | public: | |||
52 | ClangDiagnosticHandler(const CodeGenOptions &CGOpts, BackendConsumer *BCon) | |||
53 | : CodeGenOpts(CGOpts), BackendCon(BCon) {} | |||
54 | ||||
55 | bool handleDiagnostics(const DiagnosticInfo &DI) override; | |||
56 | ||||
57 | bool isAnalysisRemarkEnabled(StringRef PassName) const override { | |||
58 | return (CodeGenOpts.OptimizationRemarkAnalysisPattern && | |||
59 | CodeGenOpts.OptimizationRemarkAnalysisPattern->match(PassName)); | |||
60 | } | |||
61 | bool isMissedOptRemarkEnabled(StringRef PassName) const override { | |||
62 | return (CodeGenOpts.OptimizationRemarkMissedPattern && | |||
63 | CodeGenOpts.OptimizationRemarkMissedPattern->match(PassName)); | |||
64 | } | |||
65 | bool isPassedOptRemarkEnabled(StringRef PassName) const override { | |||
66 | return (CodeGenOpts.OptimizationRemarkPattern && | |||
67 | CodeGenOpts.OptimizationRemarkPattern->match(PassName)); | |||
68 | } | |||
69 | ||||
70 | bool isAnyRemarkEnabled() const override { | |||
71 | return (CodeGenOpts.OptimizationRemarkAnalysisPattern || | |||
72 | CodeGenOpts.OptimizationRemarkMissedPattern || | |||
73 | CodeGenOpts.OptimizationRemarkPattern); | |||
74 | } | |||
75 | ||||
76 | private: | |||
77 | const CodeGenOptions &CodeGenOpts; | |||
78 | BackendConsumer *BackendCon; | |||
79 | }; | |||
80 | ||||
81 | class BackendConsumer : public ASTConsumer { | |||
82 | using LinkModule = CodeGenAction::LinkModule; | |||
83 | ||||
84 | virtual void anchor(); | |||
85 | DiagnosticsEngine &Diags; | |||
86 | BackendAction Action; | |||
87 | const HeaderSearchOptions &HeaderSearchOpts; | |||
88 | const CodeGenOptions &CodeGenOpts; | |||
89 | const TargetOptions &TargetOpts; | |||
90 | const LangOptions &LangOpts; | |||
91 | std::unique_ptr<raw_pwrite_stream> AsmOutStream; | |||
92 | ASTContext *Context; | |||
93 | ||||
94 | Timer LLVMIRGeneration; | |||
95 | unsigned LLVMIRGenerationRefCount; | |||
96 | ||||
97 | /// True if we've finished generating IR. This prevents us from generating | |||
98 | /// additional LLVM IR after emitting output in HandleTranslationUnit. This | |||
99 | /// can happen when Clang plugins trigger additional AST deserialization. | |||
100 | bool IRGenFinished = false; | |||
101 | ||||
102 | std::unique_ptr<CodeGenerator> Gen; | |||
103 | ||||
104 | SmallVector<LinkModule, 4> LinkModules; | |||
105 | ||||
106 | // This is here so that the diagnostic printer knows the module a diagnostic | |||
107 | // refers to. | |||
108 | llvm::Module *CurLinkModule = nullptr; | |||
109 | ||||
110 | public: | |||
111 | BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags, | |||
112 | const HeaderSearchOptions &HeaderSearchOpts, | |||
113 | const PreprocessorOptions &PPOpts, | |||
114 | const CodeGenOptions &CodeGenOpts, | |||
115 | const TargetOptions &TargetOpts, | |||
116 | const LangOptions &LangOpts, bool TimePasses, | |||
117 | const std::string &InFile, | |||
118 | SmallVector<LinkModule, 4> LinkModules, | |||
119 | std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C, | |||
120 | CoverageSourceInfo *CoverageInfo = nullptr) | |||
121 | : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts), | |||
122 | CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts), | |||
123 | AsmOutStream(std::move(OS)), Context(nullptr), | |||
124 | LLVMIRGeneration("irgen", "LLVM IR Generation Time"), | |||
125 | LLVMIRGenerationRefCount(0), | |||
126 | Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts, | |||
127 | CodeGenOpts, C, CoverageInfo)), | |||
128 | LinkModules(std::move(LinkModules)) { | |||
129 | FrontendTimesIsEnabled = TimePasses; | |||
130 | llvm::TimePassesIsEnabled = TimePasses; | |||
131 | } | |||
132 | llvm::Module *getModule() const { return Gen->GetModule(); } | |||
133 | std::unique_ptr<llvm::Module> takeModule() { | |||
134 | return std::unique_ptr<llvm::Module>(Gen->ReleaseModule()); | |||
135 | } | |||
136 | ||||
137 | CodeGenerator *getCodeGenerator() { return Gen.get(); } | |||
138 | ||||
139 | void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { | |||
140 | Gen->HandleCXXStaticMemberVarInstantiation(VD); | |||
141 | } | |||
142 | ||||
143 | void Initialize(ASTContext &Ctx) override { | |||
144 | assert(!Context && "initialized multiple times")((!Context && "initialized multiple times") ? static_cast <void> (0) : __assert_fail ("!Context && \"initialized multiple times\"" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 144, __PRETTY_FUNCTION__)); | |||
145 | ||||
146 | Context = &Ctx; | |||
147 | ||||
148 | if (FrontendTimesIsEnabled) | |||
149 | LLVMIRGeneration.startTimer(); | |||
150 | ||||
151 | Gen->Initialize(Ctx); | |||
152 | ||||
153 | if (FrontendTimesIsEnabled) | |||
154 | LLVMIRGeneration.stopTimer(); | |||
155 | } | |||
156 | ||||
157 | bool HandleTopLevelDecl(DeclGroupRef D) override { | |||
158 | PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(), | |||
159 | Context->getSourceManager(), | |||
160 | "LLVM IR generation of declaration"); | |||
161 | ||||
162 | // Recurse. | |||
163 | if (FrontendTimesIsEnabled) { | |||
164 | LLVMIRGenerationRefCount += 1; | |||
165 | if (LLVMIRGenerationRefCount == 1) | |||
166 | LLVMIRGeneration.startTimer(); | |||
167 | } | |||
168 | ||||
169 | Gen->HandleTopLevelDecl(D); | |||
170 | ||||
171 | if (FrontendTimesIsEnabled) { | |||
172 | LLVMIRGenerationRefCount -= 1; | |||
173 | if (LLVMIRGenerationRefCount == 0) | |||
174 | LLVMIRGeneration.stopTimer(); | |||
175 | } | |||
176 | ||||
177 | return true; | |||
178 | } | |||
179 | ||||
180 | void HandleInlineFunctionDefinition(FunctionDecl *D) override { | |||
181 | PrettyStackTraceDecl CrashInfo(D, SourceLocation(), | |||
182 | Context->getSourceManager(), | |||
183 | "LLVM IR generation of inline function"); | |||
184 | if (FrontendTimesIsEnabled) | |||
185 | LLVMIRGeneration.startTimer(); | |||
186 | ||||
187 | Gen->HandleInlineFunctionDefinition(D); | |||
188 | ||||
189 | if (FrontendTimesIsEnabled) | |||
190 | LLVMIRGeneration.stopTimer(); | |||
191 | } | |||
192 | ||||
193 | void HandleInterestingDecl(DeclGroupRef D) override { | |||
194 | // Ignore interesting decls from the AST reader after IRGen is finished. | |||
195 | if (!IRGenFinished) | |||
196 | HandleTopLevelDecl(D); | |||
197 | } | |||
198 | ||||
199 | // Links each entry in LinkModules into our module. Returns true on error. | |||
200 | bool LinkInModules() { | |||
201 | for (auto &LM : LinkModules) { | |||
202 | if (LM.PropagateAttrs) | |||
203 | for (Function &F : *LM.Module) | |||
204 | Gen->CGM().AddDefaultFnAttrs(F); | |||
205 | ||||
206 | CurLinkModule = LM.Module.get(); | |||
207 | ||||
208 | bool Err; | |||
209 | if (LM.Internalize) { | |||
210 | Err = Linker::linkModules( | |||
211 | *getModule(), std::move(LM.Module), LM.LinkFlags, | |||
212 | [](llvm::Module &M, const llvm::StringSet<> &GVS) { | |||
213 | internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) { | |||
214 | return !GV.hasName() || (GVS.count(GV.getName()) == 0); | |||
215 | }); | |||
216 | }); | |||
217 | } else { | |||
218 | Err = Linker::linkModules(*getModule(), std::move(LM.Module), | |||
219 | LM.LinkFlags); | |||
220 | } | |||
221 | ||||
222 | if (Err) | |||
223 | return true; | |||
224 | } | |||
225 | return false; // success | |||
226 | } | |||
227 | ||||
228 | void HandleTranslationUnit(ASTContext &C) override { | |||
229 | { | |||
230 | PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); | |||
231 | if (FrontendTimesIsEnabled) { | |||
232 | LLVMIRGenerationRefCount += 1; | |||
233 | if (LLVMIRGenerationRefCount == 1) | |||
234 | LLVMIRGeneration.startTimer(); | |||
235 | } | |||
236 | ||||
237 | Gen->HandleTranslationUnit(C); | |||
238 | ||||
239 | if (FrontendTimesIsEnabled) { | |||
240 | LLVMIRGenerationRefCount -= 1; | |||
241 | if (LLVMIRGenerationRefCount == 0) | |||
242 | LLVMIRGeneration.stopTimer(); | |||
243 | } | |||
244 | ||||
245 | IRGenFinished = true; | |||
246 | } | |||
247 | ||||
248 | // Silently ignore if we weren't initialized for some reason. | |||
249 | if (!getModule()) | |||
250 | return; | |||
251 | ||||
252 | // Install an inline asm handler so that diagnostics get printed through | |||
253 | // our diagnostics hooks. | |||
254 | LLVMContext &Ctx = getModule()->getContext(); | |||
255 | LLVMContext::InlineAsmDiagHandlerTy OldHandler = | |||
256 | Ctx.getInlineAsmDiagnosticHandler(); | |||
257 | void *OldContext = Ctx.getInlineAsmDiagnosticContext(); | |||
258 | Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this); | |||
259 | ||||
260 | std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler = | |||
261 | Ctx.getDiagnosticHandler(); | |||
262 | Ctx.setDiagnosticHandler(llvm::make_unique<ClangDiagnosticHandler>( | |||
263 | CodeGenOpts, this)); | |||
264 | Ctx.setDiagnosticsHotnessRequested(CodeGenOpts.DiagnosticsWithHotness); | |||
265 | if (CodeGenOpts.DiagnosticsHotnessThreshold != 0) | |||
266 | Ctx.setDiagnosticsHotnessThreshold( | |||
267 | CodeGenOpts.DiagnosticsHotnessThreshold); | |||
268 | ||||
269 | std::unique_ptr<llvm::ToolOutputFile> OptRecordFile; | |||
270 | if (!CodeGenOpts.OptRecordFile.empty()) { | |||
271 | std::error_code EC; | |||
272 | OptRecordFile = llvm::make_unique<llvm::ToolOutputFile>( | |||
273 | CodeGenOpts.OptRecordFile, EC, sys::fs::F_None); | |||
274 | if (EC) { | |||
275 | Diags.Report(diag::err_cannot_open_file) << | |||
276 | CodeGenOpts.OptRecordFile << EC.message(); | |||
277 | return; | |||
278 | } | |||
279 | ||||
280 | Ctx.setDiagnosticsOutputFile( | |||
281 | llvm::make_unique<yaml::Output>(OptRecordFile->os())); | |||
282 | ||||
283 | if (CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone) | |||
284 | Ctx.setDiagnosticsHotnessRequested(true); | |||
285 | } | |||
286 | ||||
287 | // Link each LinkModule into our module. | |||
288 | if (LinkInModules()) | |||
289 | return; | |||
290 | ||||
291 | EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef()); | |||
292 | ||||
293 | EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, | |||
294 | LangOpts, C.getTargetInfo().getDataLayout(), | |||
295 | getModule(), Action, std::move(AsmOutStream)); | |||
296 | ||||
297 | Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); | |||
298 | ||||
299 | Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler)); | |||
300 | ||||
301 | if (OptRecordFile) | |||
302 | OptRecordFile->keep(); | |||
303 | } | |||
304 | ||||
305 | void HandleTagDeclDefinition(TagDecl *D) override { | |||
306 | PrettyStackTraceDecl CrashInfo(D, SourceLocation(), | |||
307 | Context->getSourceManager(), | |||
308 | "LLVM IR generation of declaration"); | |||
309 | Gen->HandleTagDeclDefinition(D); | |||
310 | } | |||
311 | ||||
312 | void HandleTagDeclRequiredDefinition(const TagDecl *D) override { | |||
313 | Gen->HandleTagDeclRequiredDefinition(D); | |||
314 | } | |||
315 | ||||
316 | void CompleteTentativeDefinition(VarDecl *D) override { | |||
317 | Gen->CompleteTentativeDefinition(D); | |||
318 | } | |||
319 | ||||
320 | void AssignInheritanceModel(CXXRecordDecl *RD) override { | |||
321 | Gen->AssignInheritanceModel(RD); | |||
322 | } | |||
323 | ||||
324 | void HandleVTable(CXXRecordDecl *RD) override { | |||
325 | Gen->HandleVTable(RD); | |||
326 | } | |||
327 | ||||
328 | static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context, | |||
329 | unsigned LocCookie) { | |||
330 | SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie); | |||
331 | ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc); | |||
332 | } | |||
333 | ||||
334 | /// Get the best possible source location to represent a diagnostic that | |||
335 | /// may have associated debug info. | |||
336 | const FullSourceLoc | |||
337 | getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithLocationBase &D, | |||
338 | bool &BadDebugInfo, StringRef &Filename, | |||
339 | unsigned &Line, unsigned &Column) const; | |||
340 | ||||
341 | void InlineAsmDiagHandler2(const llvm::SMDiagnostic &, | |||
342 | SourceLocation LocCookie); | |||
343 | ||||
344 | void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI); | |||
345 | /// Specialized handler for InlineAsm diagnostic. | |||
346 | /// \return True if the diagnostic has been successfully reported, false | |||
347 | /// otherwise. | |||
348 | bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D); | |||
349 | /// Specialized handler for StackSize diagnostic. | |||
350 | /// \return True if the diagnostic has been successfully reported, false | |||
351 | /// otherwise. | |||
352 | bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); | |||
353 | /// Specialized handler for unsupported backend feature diagnostic. | |||
354 | void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D); | |||
355 | /// Specialized handlers for optimization remarks. | |||
356 | /// Note that these handlers only accept remarks and they always handle | |||
357 | /// them. | |||
358 | void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D, | |||
359 | unsigned DiagID); | |||
360 | void | |||
361 | OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D); | |||
362 | void OptimizationRemarkHandler( | |||
363 | const llvm::OptimizationRemarkAnalysisFPCommute &D); | |||
364 | void OptimizationRemarkHandler( | |||
365 | const llvm::OptimizationRemarkAnalysisAliasing &D); | |||
366 | void OptimizationFailureHandler( | |||
367 | const llvm::DiagnosticInfoOptimizationFailure &D); | |||
368 | }; | |||
369 | ||||
370 | void BackendConsumer::anchor() {} | |||
371 | } | |||
372 | ||||
373 | bool ClangDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) { | |||
374 | BackendCon->DiagnosticHandlerImpl(DI); | |||
| ||||
375 | return true; | |||
376 | } | |||
377 | ||||
378 | /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr | |||
379 | /// buffer to be a valid FullSourceLoc. | |||
380 | static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D, | |||
381 | SourceManager &CSM) { | |||
382 | // Get both the clang and llvm source managers. The location is relative to | |||
383 | // a memory buffer that the LLVM Source Manager is handling, we need to add | |||
384 | // a copy to the Clang source manager. | |||
385 | const llvm::SourceMgr &LSM = *D.getSourceMgr(); | |||
386 | ||||
387 | // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr | |||
388 | // already owns its one and clang::SourceManager wants to own its one. | |||
389 | const MemoryBuffer *LBuf = | |||
390 | LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc())); | |||
391 | ||||
392 | // Create the copy and transfer ownership to clang::SourceManager. | |||
393 | // TODO: Avoid copying files into memory. | |||
394 | std::unique_ptr<llvm::MemoryBuffer> CBuf = | |||
395 | llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(), | |||
396 | LBuf->getBufferIdentifier()); | |||
397 | // FIXME: Keep a file ID map instead of creating new IDs for each location. | |||
398 | FileID FID = CSM.createFileID(std::move(CBuf)); | |||
399 | ||||
400 | // Translate the offset into the file. | |||
401 | unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); | |||
402 | SourceLocation NewLoc = | |||
403 | CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset); | |||
404 | return FullSourceLoc(NewLoc, CSM); | |||
405 | } | |||
406 | ||||
407 | ||||
408 | /// InlineAsmDiagHandler2 - This function is invoked when the backend hits an | |||
409 | /// error parsing inline asm. The SMDiagnostic indicates the error relative to | |||
410 | /// the temporary memory buffer that the inline asm parser has set up. | |||
411 | void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D, | |||
412 | SourceLocation LocCookie) { | |||
413 | // There are a couple of different kinds of errors we could get here. First, | |||
414 | // we re-format the SMDiagnostic in terms of a clang diagnostic. | |||
415 | ||||
416 | // Strip "error: " off the start of the message string. | |||
417 | StringRef Message = D.getMessage(); | |||
418 | if (Message.startswith("error: ")) | |||
419 | Message = Message.substr(7); | |||
420 | ||||
421 | // If the SMDiagnostic has an inline asm source location, translate it. | |||
422 | FullSourceLoc Loc; | |||
423 | if (D.getLoc() != SMLoc()) | |||
424 | Loc = ConvertBackendLocation(D, Context->getSourceManager()); | |||
425 | ||||
426 | unsigned DiagID; | |||
427 | switch (D.getKind()) { | |||
428 | case llvm::SourceMgr::DK_Error: | |||
429 | DiagID = diag::err_fe_inline_asm; | |||
430 | break; | |||
431 | case llvm::SourceMgr::DK_Warning: | |||
432 | DiagID = diag::warn_fe_inline_asm; | |||
433 | break; | |||
434 | case llvm::SourceMgr::DK_Note: | |||
435 | DiagID = diag::note_fe_inline_asm; | |||
436 | break; | |||
437 | case llvm::SourceMgr::DK_Remark: | |||
438 | llvm_unreachable("remarks unexpected")::llvm::llvm_unreachable_internal("remarks unexpected", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 438); | |||
439 | } | |||
440 | // If this problem has clang-level source location information, report the | |||
441 | // issue in the source with a note showing the instantiated | |||
442 | // code. | |||
443 | if (LocCookie.isValid()) { | |||
444 | Diags.Report(LocCookie, DiagID).AddString(Message); | |||
445 | ||||
446 | if (D.getLoc().isValid()) { | |||
447 | DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here); | |||
448 | // Convert the SMDiagnostic ranges into SourceRange and attach them | |||
449 | // to the diagnostic. | |||
450 | for (const std::pair<unsigned, unsigned> &Range : D.getRanges()) { | |||
451 | unsigned Column = D.getColumnNo(); | |||
452 | B << SourceRange(Loc.getLocWithOffset(Range.first - Column), | |||
453 | Loc.getLocWithOffset(Range.second - Column)); | |||
454 | } | |||
455 | } | |||
456 | return; | |||
457 | } | |||
458 | ||||
459 | // Otherwise, report the backend issue as occurring in the generated .s file. | |||
460 | // If Loc is invalid, we still need to report the issue, it just gets no | |||
461 | // location info. | |||
462 | Diags.Report(Loc, DiagID).AddString(Message); | |||
463 | } | |||
464 | ||||
465 | #define ComputeDiagID(Severity, GroupName, DiagID) \ | |||
466 | do { \ | |||
467 | switch (Severity) { \ | |||
468 | case llvm::DS_Error: \ | |||
469 | DiagID = diag::err_fe_##GroupName; \ | |||
470 | break; \ | |||
471 | case llvm::DS_Warning: \ | |||
472 | DiagID = diag::warn_fe_##GroupName; \ | |||
473 | break; \ | |||
474 | case llvm::DS_Remark: \ | |||
475 | llvm_unreachable("'remark' severity not expected")::llvm::llvm_unreachable_internal("'remark' severity not expected" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 475); \ | |||
476 | break; \ | |||
477 | case llvm::DS_Note: \ | |||
478 | DiagID = diag::note_fe_##GroupName; \ | |||
479 | break; \ | |||
480 | } \ | |||
481 | } while (false) | |||
482 | ||||
483 | #define ComputeDiagRemarkID(Severity, GroupName, DiagID)do { switch (Severity) { case llvm::DS_Error: DiagID = diag:: err_fe_GroupName; break; case llvm::DS_Warning: DiagID = diag ::warn_fe_GroupName; break; case llvm::DS_Remark: DiagID = diag ::remark_fe_GroupName; break; case llvm::DS_Note: DiagID = diag ::note_fe_GroupName; break; } } while (false) \ | |||
484 | do { \ | |||
485 | switch (Severity) { \ | |||
486 | case llvm::DS_Error: \ | |||
487 | DiagID = diag::err_fe_##GroupName; \ | |||
488 | break; \ | |||
489 | case llvm::DS_Warning: \ | |||
490 | DiagID = diag::warn_fe_##GroupName; \ | |||
491 | break; \ | |||
492 | case llvm::DS_Remark: \ | |||
493 | DiagID = diag::remark_fe_##GroupName; \ | |||
494 | break; \ | |||
495 | case llvm::DS_Note: \ | |||
496 | DiagID = diag::note_fe_##GroupName; \ | |||
497 | break; \ | |||
498 | } \ | |||
499 | } while (false) | |||
500 | ||||
501 | bool | |||
502 | BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) { | |||
503 | unsigned DiagID; | |||
504 | ComputeDiagID(D.getSeverity(), inline_asm, DiagID); | |||
505 | std::string Message = D.getMsgStr().str(); | |||
506 | ||||
507 | // If this problem has clang-level source location information, report the | |||
508 | // issue as being a problem in the source with a note showing the instantiated | |||
509 | // code. | |||
510 | SourceLocation LocCookie = | |||
511 | SourceLocation::getFromRawEncoding(D.getLocCookie()); | |||
512 | if (LocCookie.isValid()) | |||
513 | Diags.Report(LocCookie, DiagID).AddString(Message); | |||
514 | else { | |||
515 | // Otherwise, report the backend diagnostic as occurring in the generated | |||
516 | // .s file. | |||
517 | // If Loc is invalid, we still need to report the diagnostic, it just gets | |||
518 | // no location info. | |||
519 | FullSourceLoc Loc; | |||
520 | Diags.Report(Loc, DiagID).AddString(Message); | |||
521 | } | |||
522 | // We handled all the possible severities. | |||
523 | return true; | |||
524 | } | |||
525 | ||||
526 | bool | |||
527 | BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) { | |||
528 | if (D.getSeverity() != llvm::DS_Warning) | |||
529 | // For now, the only support we have for StackSize diagnostic is warning. | |||
530 | // We do not know how to format other severities. | |||
531 | return false; | |||
532 | ||||
533 | if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) { | |||
534 | // FIXME: Shouldn't need to truncate to uint32_t | |||
535 | Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()), | |||
536 | diag::warn_fe_frame_larger_than) | |||
537 | << static_cast<uint32_t>(D.getStackSize()) << Decl::castToDeclContext(ND); | |||
538 | return true; | |||
539 | } | |||
540 | ||||
541 | return false; | |||
542 | } | |||
543 | ||||
544 | const FullSourceLoc BackendConsumer::getBestLocationFromDebugLoc( | |||
545 | const llvm::DiagnosticInfoWithLocationBase &D, bool &BadDebugInfo, | |||
546 | StringRef &Filename, unsigned &Line, unsigned &Column) const { | |||
547 | SourceManager &SourceMgr = Context->getSourceManager(); | |||
548 | FileManager &FileMgr = SourceMgr.getFileManager(); | |||
549 | SourceLocation DILoc; | |||
550 | ||||
551 | if (D.isLocationAvailable()) { | |||
552 | D.getLocation(&Filename, &Line, &Column); | |||
553 | const FileEntry *FE = FileMgr.getFile(Filename); | |||
554 | if (FE && Line > 0) { | |||
555 | // If -gcolumn-info was not used, Column will be 0. This upsets the | |||
556 | // source manager, so pass 1 if Column is not set. | |||
557 | DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1); | |||
558 | } | |||
559 | BadDebugInfo = DILoc.isInvalid(); | |||
560 | } | |||
561 | ||||
562 | // If a location isn't available, try to approximate it using the associated | |||
563 | // function definition. We use the definition's right brace to differentiate | |||
564 | // from diagnostics that genuinely relate to the function itself. | |||
565 | FullSourceLoc Loc(DILoc, SourceMgr); | |||
566 | if (Loc.isInvalid()) | |||
567 | if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName())) | |||
568 | Loc = FD->getASTContext().getFullLoc(FD->getLocation()); | |||
569 | ||||
570 | if (DILoc.isInvalid() && D.isLocationAvailable()) | |||
571 | // If we were not able to translate the file:line:col information | |||
572 | // back to a SourceLocation, at least emit a note stating that | |||
573 | // we could not translate this location. This can happen in the | |||
574 | // case of #line directives. | |||
575 | Diags.Report(Loc, diag::note_fe_backend_invalid_loc) | |||
| ||||
576 | << Filename << Line << Column; | |||
577 | ||||
578 | return Loc; | |||
579 | } | |||
580 | ||||
581 | void BackendConsumer::UnsupportedDiagHandler( | |||
582 | const llvm::DiagnosticInfoUnsupported &D) { | |||
583 | // We only support errors. | |||
584 | assert(D.getSeverity() == llvm::DS_Error)((D.getSeverity() == llvm::DS_Error) ? static_cast<void> (0) : __assert_fail ("D.getSeverity() == llvm::DS_Error", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 584, __PRETTY_FUNCTION__)); | |||
585 | ||||
586 | StringRef Filename; | |||
587 | unsigned Line, Column; | |||
588 | bool BadDebugInfo = false; | |||
589 | FullSourceLoc Loc = | |||
590 | getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); | |||
591 | ||||
592 | Diags.Report(Loc, diag::err_fe_backend_unsupported) << D.getMessage().str(); | |||
593 | ||||
594 | if (BadDebugInfo) | |||
595 | // If we were not able to translate the file:line:col information | |||
596 | // back to a SourceLocation, at least emit a note stating that | |||
597 | // we could not translate this location. This can happen in the | |||
598 | // case of #line directives. | |||
599 | Diags.Report(Loc, diag::note_fe_backend_invalid_loc) | |||
600 | << Filename << Line << Column; | |||
601 | } | |||
602 | ||||
603 | void BackendConsumer::EmitOptimizationMessage( | |||
604 | const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) { | |||
605 | // We only support warnings and remarks. | |||
606 | assert(D.getSeverity() == llvm::DS_Remark ||((D.getSeverity() == llvm::DS_Remark || D.getSeverity() == llvm ::DS_Warning) ? static_cast<void> (0) : __assert_fail ( "D.getSeverity() == llvm::DS_Remark || D.getSeverity() == llvm::DS_Warning" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 607, __PRETTY_FUNCTION__)) | |||
607 | D.getSeverity() == llvm::DS_Warning)((D.getSeverity() == llvm::DS_Remark || D.getSeverity() == llvm ::DS_Warning) ? static_cast<void> (0) : __assert_fail ( "D.getSeverity() == llvm::DS_Remark || D.getSeverity() == llvm::DS_Warning" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 607, __PRETTY_FUNCTION__)); | |||
608 | ||||
609 | StringRef Filename; | |||
610 | unsigned Line, Column; | |||
611 | bool BadDebugInfo = false; | |||
612 | FullSourceLoc Loc = | |||
613 | getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); | |||
614 | ||||
615 | std::string Msg; | |||
616 | raw_string_ostream MsgStream(Msg); | |||
617 | MsgStream << D.getMsg(); | |||
618 | ||||
619 | if (D.getHotness()) | |||
620 | MsgStream << " (hotness: " << *D.getHotness() << ")"; | |||
621 | ||||
622 | Diags.Report(Loc, DiagID) | |||
623 | << AddFlagValue(D.getPassName()) | |||
624 | << MsgStream.str(); | |||
625 | ||||
626 | if (BadDebugInfo) | |||
627 | // If we were not able to translate the file:line:col information | |||
628 | // back to a SourceLocation, at least emit a note stating that | |||
629 | // we could not translate this location. This can happen in the | |||
630 | // case of #line directives. | |||
631 | Diags.Report(Loc, diag::note_fe_backend_invalid_loc) | |||
632 | << Filename << Line << Column; | |||
633 | } | |||
634 | ||||
635 | void BackendConsumer::OptimizationRemarkHandler( | |||
636 | const llvm::DiagnosticInfoOptimizationBase &D) { | |||
637 | // Without hotness information, don't show noisy remarks. | |||
638 | if (D.isVerbose() && !D.getHotness()) | |||
639 | return; | |||
640 | ||||
641 | if (D.isPassed()) { | |||
642 | // Optimization remarks are active only if the -Rpass flag has a regular | |||
643 | // expression that matches the name of the pass name in \p D. | |||
644 | if (CodeGenOpts.OptimizationRemarkPattern && | |||
645 | CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName())) | |||
646 | EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark); | |||
647 | } else if (D.isMissed()) { | |||
648 | // Missed optimization remarks are active only if the -Rpass-missed | |||
649 | // flag has a regular expression that matches the name of the pass | |||
650 | // name in \p D. | |||
651 | if (CodeGenOpts.OptimizationRemarkMissedPattern && | |||
652 | CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName())) | |||
653 | EmitOptimizationMessage( | |||
654 | D, diag::remark_fe_backend_optimization_remark_missed); | |||
655 | } else { | |||
656 | assert(D.isAnalysis() && "Unknown remark type")((D.isAnalysis() && "Unknown remark type") ? static_cast <void> (0) : __assert_fail ("D.isAnalysis() && \"Unknown remark type\"" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 656, __PRETTY_FUNCTION__)); | |||
657 | ||||
658 | bool ShouldAlwaysPrint = false; | |||
659 | if (auto *ORA = dyn_cast<llvm::OptimizationRemarkAnalysis>(&D)) | |||
660 | ShouldAlwaysPrint = ORA->shouldAlwaysPrint(); | |||
661 | ||||
662 | if (ShouldAlwaysPrint || | |||
663 | (CodeGenOpts.OptimizationRemarkAnalysisPattern && | |||
664 | CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName()))) | |||
665 | EmitOptimizationMessage( | |||
666 | D, diag::remark_fe_backend_optimization_remark_analysis); | |||
667 | } | |||
668 | } | |||
669 | ||||
670 | void BackendConsumer::OptimizationRemarkHandler( | |||
671 | const llvm::OptimizationRemarkAnalysisFPCommute &D) { | |||
672 | // Optimization analysis remarks are active if the pass name is set to | |||
673 | // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a | |||
674 | // regular expression that matches the name of the pass name in \p D. | |||
675 | ||||
676 | if (D.shouldAlwaysPrint() || | |||
677 | (CodeGenOpts.OptimizationRemarkAnalysisPattern && | |||
678 | CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName()))) | |||
679 | EmitOptimizationMessage( | |||
680 | D, diag::remark_fe_backend_optimization_remark_analysis_fpcommute); | |||
681 | } | |||
682 | ||||
683 | void BackendConsumer::OptimizationRemarkHandler( | |||
684 | const llvm::OptimizationRemarkAnalysisAliasing &D) { | |||
685 | // Optimization analysis remarks are active if the pass name is set to | |||
686 | // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a | |||
687 | // regular expression that matches the name of the pass name in \p D. | |||
688 | ||||
689 | if (D.shouldAlwaysPrint() || | |||
690 | (CodeGenOpts.OptimizationRemarkAnalysisPattern && | |||
691 | CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName()))) | |||
692 | EmitOptimizationMessage( | |||
693 | D, diag::remark_fe_backend_optimization_remark_analysis_aliasing); | |||
694 | } | |||
695 | ||||
696 | void BackendConsumer::OptimizationFailureHandler( | |||
697 | const llvm::DiagnosticInfoOptimizationFailure &D) { | |||
698 | EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure); | |||
699 | } | |||
700 | ||||
701 | /// This function is invoked when the backend needs | |||
702 | /// to report something to the user. | |||
703 | void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { | |||
704 | unsigned DiagID = diag::err_fe_inline_asm; | |||
705 | llvm::DiagnosticSeverity Severity = DI.getSeverity(); | |||
706 | // Get the diagnostic ID based. | |||
707 | switch (DI.getKind()) { | |||
708 | case llvm::DK_InlineAsm: | |||
709 | if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI))) | |||
710 | return; | |||
711 | ComputeDiagID(Severity, inline_asm, DiagID); | |||
712 | break; | |||
713 | case llvm::DK_StackSize: | |||
714 | if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI))) | |||
715 | return; | |||
716 | ComputeDiagID(Severity, backend_frame_larger_than, DiagID); | |||
717 | break; | |||
718 | case DK_Linker: | |||
719 | assert(CurLinkModule)((CurLinkModule) ? static_cast<void> (0) : __assert_fail ("CurLinkModule", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 719, __PRETTY_FUNCTION__)); | |||
720 | // FIXME: stop eating the warnings and notes. | |||
721 | if (Severity != DS_Error) | |||
722 | return; | |||
723 | DiagID = diag::err_fe_cannot_link_module; | |||
724 | break; | |||
725 | case llvm::DK_OptimizationRemark: | |||
726 | // Optimization remarks are always handled completely by this | |||
727 | // handler. There is no generic way of emitting them. | |||
728 | OptimizationRemarkHandler(cast<OptimizationRemark>(DI)); | |||
729 | return; | |||
730 | case llvm::DK_OptimizationRemarkMissed: | |||
731 | // Optimization remarks are always handled completely by this | |||
732 | // handler. There is no generic way of emitting them. | |||
733 | OptimizationRemarkHandler(cast<OptimizationRemarkMissed>(DI)); | |||
734 | return; | |||
735 | case llvm::DK_OptimizationRemarkAnalysis: | |||
736 | // Optimization remarks are always handled completely by this | |||
737 | // handler. There is no generic way of emitting them. | |||
738 | OptimizationRemarkHandler(cast<OptimizationRemarkAnalysis>(DI)); | |||
739 | return; | |||
740 | case llvm::DK_OptimizationRemarkAnalysisFPCommute: | |||
741 | // Optimization remarks are always handled completely by this | |||
742 | // handler. There is no generic way of emitting them. | |||
743 | OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisFPCommute>(DI)); | |||
744 | return; | |||
745 | case llvm::DK_OptimizationRemarkAnalysisAliasing: | |||
746 | // Optimization remarks are always handled completely by this | |||
747 | // handler. There is no generic way of emitting them. | |||
748 | OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisAliasing>(DI)); | |||
749 | return; | |||
750 | case llvm::DK_MachineOptimizationRemark: | |||
751 | // Optimization remarks are always handled completely by this | |||
752 | // handler. There is no generic way of emitting them. | |||
753 | OptimizationRemarkHandler(cast<MachineOptimizationRemark>(DI)); | |||
754 | return; | |||
755 | case llvm::DK_MachineOptimizationRemarkMissed: | |||
756 | // Optimization remarks are always handled completely by this | |||
757 | // handler. There is no generic way of emitting them. | |||
758 | OptimizationRemarkHandler(cast<MachineOptimizationRemarkMissed>(DI)); | |||
759 | return; | |||
760 | case llvm::DK_MachineOptimizationRemarkAnalysis: | |||
761 | // Optimization remarks are always handled completely by this | |||
762 | // handler. There is no generic way of emitting them. | |||
763 | OptimizationRemarkHandler(cast<MachineOptimizationRemarkAnalysis>(DI)); | |||
764 | return; | |||
765 | case llvm::DK_OptimizationFailure: | |||
766 | // Optimization failures are always handled completely by this | |||
767 | // handler. | |||
768 | OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI)); | |||
769 | return; | |||
770 | case llvm::DK_Unsupported: | |||
771 | UnsupportedDiagHandler(cast<DiagnosticInfoUnsupported>(DI)); | |||
772 | return; | |||
773 | default: | |||
774 | // Plugin IDs are not bound to any value as they are set dynamically. | |||
775 | ComputeDiagRemarkID(Severity, backend_plugin, DiagID)do { switch (Severity) { case llvm::DS_Error: DiagID = diag:: err_fe_backend_plugin; break; case llvm::DS_Warning: DiagID = diag::warn_fe_backend_plugin; break; case llvm::DS_Remark: DiagID = diag::remark_fe_backend_plugin; break; case llvm::DS_Note: DiagID = diag::note_fe_backend_plugin; break; } } while (false ); | |||
776 | break; | |||
777 | } | |||
778 | std::string MsgStorage; | |||
779 | { | |||
780 | raw_string_ostream Stream(MsgStorage); | |||
781 | DiagnosticPrinterRawOStream DP(Stream); | |||
782 | DI.print(DP); | |||
783 | } | |||
784 | ||||
785 | if (DiagID == diag::err_fe_cannot_link_module) { | |||
786 | Diags.Report(diag::err_fe_cannot_link_module) | |||
787 | << CurLinkModule->getModuleIdentifier() << MsgStorage; | |||
788 | return; | |||
789 | } | |||
790 | ||||
791 | // Report the backend message using the usual diagnostic mechanism. | |||
792 | FullSourceLoc Loc; | |||
793 | Diags.Report(Loc, DiagID).AddString(MsgStorage); | |||
794 | } | |||
795 | #undef ComputeDiagID | |||
796 | ||||
797 | CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext) | |||
798 | : Act(_Act), VMContext(_VMContext ? _VMContext : new LLVMContext), | |||
799 | OwnsVMContext(!_VMContext) {} | |||
800 | ||||
801 | CodeGenAction::~CodeGenAction() { | |||
802 | TheModule.reset(); | |||
803 | if (OwnsVMContext) | |||
804 | delete VMContext; | |||
805 | } | |||
806 | ||||
807 | bool CodeGenAction::hasIRSupport() const { return true; } | |||
808 | ||||
809 | void CodeGenAction::EndSourceFileAction() { | |||
810 | // If the consumer creation failed, do nothing. | |||
811 | if (!getCompilerInstance().hasASTConsumer()) | |||
812 | return; | |||
813 | ||||
814 | // Steal the module from the consumer. | |||
815 | TheModule = BEConsumer->takeModule(); | |||
816 | } | |||
817 | ||||
818 | std::unique_ptr<llvm::Module> CodeGenAction::takeModule() { | |||
819 | return std::move(TheModule); | |||
820 | } | |||
821 | ||||
822 | llvm::LLVMContext *CodeGenAction::takeLLVMContext() { | |||
823 | OwnsVMContext = false; | |||
824 | return VMContext; | |||
825 | } | |||
826 | ||||
827 | static std::unique_ptr<raw_pwrite_stream> | |||
828 | GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) { | |||
829 | switch (Action) { | |||
830 | case Backend_EmitAssembly: | |||
831 | return CI.createDefaultOutputFile(false, InFile, "s"); | |||
832 | case Backend_EmitLL: | |||
833 | return CI.createDefaultOutputFile(false, InFile, "ll"); | |||
834 | case Backend_EmitBC: | |||
835 | return CI.createDefaultOutputFile(true, InFile, "bc"); | |||
836 | case Backend_EmitNothing: | |||
837 | return nullptr; | |||
838 | case Backend_EmitMCNull: | |||
839 | return CI.createNullOutputFile(); | |||
840 | case Backend_EmitObj: | |||
841 | return CI.createDefaultOutputFile(true, InFile, "o"); | |||
842 | } | |||
843 | ||||
844 | llvm_unreachable("Invalid action!")::llvm::llvm_unreachable_internal("Invalid action!", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 844); | |||
845 | } | |||
846 | ||||
847 | std::unique_ptr<ASTConsumer> | |||
848 | CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { | |||
849 | BackendAction BA = static_cast<BackendAction>(Act); | |||
850 | std::unique_ptr<raw_pwrite_stream> OS = CI.takeOutputStream(); | |||
851 | if (!OS) | |||
852 | OS = GetOutputStream(CI, InFile, BA); | |||
853 | ||||
854 | if (BA != Backend_EmitNothing && !OS) | |||
855 | return nullptr; | |||
856 | ||||
857 | // Load bitcode modules to link with, if we need to. | |||
858 | if (LinkModules.empty()) | |||
859 | for (const CodeGenOptions::BitcodeFileToLink &F : | |||
860 | CI.getCodeGenOpts().LinkBitcodeFiles) { | |||
861 | auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename); | |||
862 | if (!BCBuf) { | |||
863 | CI.getDiagnostics().Report(diag::err_cannot_open_file) | |||
864 | << F.Filename << BCBuf.getError().message(); | |||
865 | LinkModules.clear(); | |||
866 | return nullptr; | |||
867 | } | |||
868 | ||||
869 | Expected<std::unique_ptr<llvm::Module>> ModuleOrErr = | |||
870 | getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext); | |||
871 | if (!ModuleOrErr) { | |||
872 | handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) { | |||
873 | CI.getDiagnostics().Report(diag::err_cannot_open_file) | |||
874 | << F.Filename << EIB.message(); | |||
875 | }); | |||
876 | LinkModules.clear(); | |||
877 | return nullptr; | |||
878 | } | |||
879 | LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs, | |||
880 | F.Internalize, F.LinkFlags}); | |||
881 | } | |||
882 | ||||
883 | CoverageSourceInfo *CoverageInfo = nullptr; | |||
884 | // Add the preprocessor callback only when the coverage mapping is generated. | |||
885 | if (CI.getCodeGenOpts().CoverageMapping) { | |||
886 | CoverageInfo = new CoverageSourceInfo; | |||
887 | CI.getPreprocessor().addPPCallbacks( | |||
888 | std::unique_ptr<PPCallbacks>(CoverageInfo)); | |||
889 | } | |||
890 | ||||
891 | std::unique_ptr<BackendConsumer> Result(new BackendConsumer( | |||
892 | BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), | |||
893 | CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(), | |||
894 | CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, | |||
895 | std::move(LinkModules), std::move(OS), *VMContext, CoverageInfo)); | |||
896 | BEConsumer = Result.get(); | |||
897 | ||||
898 | // Enable generating macro debug info only when debug info is not disabled and | |||
899 | // also macro debug info is enabled. | |||
900 | if (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo && | |||
901 | CI.getCodeGenOpts().MacroDebugInfo) { | |||
902 | std::unique_ptr<PPCallbacks> Callbacks = | |||
903 | llvm::make_unique<MacroPPCallbacks>(BEConsumer->getCodeGenerator(), | |||
904 | CI.getPreprocessor()); | |||
905 | CI.getPreprocessor().addPPCallbacks(std::move(Callbacks)); | |||
906 | } | |||
907 | ||||
908 | return std::move(Result); | |||
909 | } | |||
910 | ||||
911 | static void BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic &SM, | |||
912 | void *Context, | |||
913 | unsigned LocCookie) { | |||
914 | SM.print(nullptr, llvm::errs()); | |||
915 | ||||
916 | auto Diags = static_cast<DiagnosticsEngine *>(Context); | |||
917 | unsigned DiagID; | |||
918 | switch (SM.getKind()) { | |||
919 | case llvm::SourceMgr::DK_Error: | |||
920 | DiagID = diag::err_fe_inline_asm; | |||
921 | break; | |||
922 | case llvm::SourceMgr::DK_Warning: | |||
923 | DiagID = diag::warn_fe_inline_asm; | |||
924 | break; | |||
925 | case llvm::SourceMgr::DK_Note: | |||
926 | DiagID = diag::note_fe_inline_asm; | |||
927 | break; | |||
928 | case llvm::SourceMgr::DK_Remark: | |||
929 | llvm_unreachable("remarks unexpected")::llvm::llvm_unreachable_internal("remarks unexpected", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 929); | |||
930 | } | |||
931 | ||||
932 | Diags->Report(DiagID).AddString("cannot compile inline asm"); | |||
933 | } | |||
934 | ||||
935 | std::unique_ptr<llvm::Module> CodeGenAction::loadModule(MemoryBufferRef MBRef) { | |||
936 | CompilerInstance &CI = getCompilerInstance(); | |||
937 | SourceManager &SM = CI.getSourceManager(); | |||
938 | ||||
939 | // For ThinLTO backend invocations, ensure that the context | |||
940 | // merges types based on ODR identifiers. We also need to read | |||
941 | // the correct module out of a multi-module bitcode file. | |||
942 | if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) { | |||
943 | VMContext->enableDebugTypeODRUniquing(); | |||
944 | ||||
945 | auto DiagErrors = [&](Error E) -> std::unique_ptr<llvm::Module> { | |||
946 | unsigned DiagID = | |||
947 | CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); | |||
948 | handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { | |||
949 | CI.getDiagnostics().Report(DiagID) << EIB.message(); | |||
950 | }); | |||
951 | return {}; | |||
952 | }; | |||
953 | ||||
954 | Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef); | |||
955 | if (!BMsOrErr) | |||
956 | return DiagErrors(BMsOrErr.takeError()); | |||
957 | BitcodeModule *Bm = FindThinLTOModule(*BMsOrErr); | |||
958 | // We have nothing to do if the file contains no ThinLTO module. This is | |||
959 | // possible if ThinLTO compilation was not able to split module. Content of | |||
960 | // the file was already processed by indexing and will be passed to the | |||
961 | // linker using merged object file. | |||
962 | if (!Bm) { | |||
963 | auto M = llvm::make_unique<llvm::Module>("empty", *VMContext); | |||
964 | M->setTargetTriple(CI.getTargetOpts().Triple); | |||
965 | return M; | |||
966 | } | |||
967 | Expected<std::unique_ptr<llvm::Module>> MOrErr = | |||
968 | Bm->parseModule(*VMContext); | |||
969 | if (!MOrErr) | |||
970 | return DiagErrors(MOrErr.takeError()); | |||
971 | return std::move(*MOrErr); | |||
972 | } | |||
973 | ||||
974 | llvm::SMDiagnostic Err; | |||
975 | if (std::unique_ptr<llvm::Module> M = parseIR(MBRef, Err, *VMContext)) | |||
976 | return M; | |||
977 | ||||
978 | // Translate from the diagnostic info to the SourceManager location if | |||
979 | // available. | |||
980 | // TODO: Unify this with ConvertBackendLocation() | |||
981 | SourceLocation Loc; | |||
982 | if (Err.getLineNo() > 0) { | |||
983 | assert(Err.getColumnNo() >= 0)((Err.getColumnNo() >= 0) ? static_cast<void> (0) : __assert_fail ("Err.getColumnNo() >= 0", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 983, __PRETTY_FUNCTION__)); | |||
984 | Loc = SM.translateFileLineCol(SM.getFileEntryForID(SM.getMainFileID()), | |||
985 | Err.getLineNo(), Err.getColumnNo() + 1); | |||
986 | } | |||
987 | ||||
988 | // Strip off a leading diagnostic code if there is one. | |||
989 | StringRef Msg = Err.getMessage(); | |||
990 | if (Msg.startswith("error: ")) | |||
991 | Msg = Msg.substr(7); | |||
992 | ||||
993 | unsigned DiagID = | |||
994 | CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); | |||
995 | ||||
996 | CI.getDiagnostics().Report(Loc, DiagID) << Msg; | |||
997 | return {}; | |||
998 | } | |||
999 | ||||
1000 | void CodeGenAction::ExecuteAction() { | |||
1001 | // If this is an IR file, we have to treat it specially. | |||
1002 | if (getCurrentFileKind().getLanguage() == InputKind::LLVM_IR) { | |||
1003 | BackendAction BA = static_cast<BackendAction>(Act); | |||
1004 | CompilerInstance &CI = getCompilerInstance(); | |||
1005 | std::unique_ptr<raw_pwrite_stream> OS = | |||
1006 | GetOutputStream(CI, getCurrentFile(), BA); | |||
1007 | if (BA != Backend_EmitNothing && !OS) | |||
1008 | return; | |||
1009 | ||||
1010 | bool Invalid; | |||
1011 | SourceManager &SM = CI.getSourceManager(); | |||
1012 | FileID FID = SM.getMainFileID(); | |||
1013 | llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid); | |||
1014 | if (Invalid) | |||
1015 | return; | |||
1016 | ||||
1017 | TheModule = loadModule(*MainFile); | |||
1018 | if (!TheModule) | |||
1019 | return; | |||
1020 | ||||
1021 | const TargetOptions &TargetOpts = CI.getTargetOpts(); | |||
1022 | if (TheModule->getTargetTriple() != TargetOpts.Triple) { | |||
1023 | CI.getDiagnostics().Report(SourceLocation(), | |||
1024 | diag::warn_fe_override_module) | |||
1025 | << TargetOpts.Triple; | |||
1026 | TheModule->setTargetTriple(TargetOpts.Triple); | |||
1027 | } | |||
1028 | ||||
1029 | EmbedBitcode(TheModule.get(), CI.getCodeGenOpts(), | |||
1030 | MainFile->getMemBufferRef()); | |||
1031 | ||||
1032 | LLVMContext &Ctx = TheModule->getContext(); | |||
1033 | Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler, | |||
1034 | &CI.getDiagnostics()); | |||
1035 | ||||
1036 | EmitBackendOutput(CI.getDiagnostics(), CI.getHeaderSearchOpts(), | |||
1037 | CI.getCodeGenOpts(), TargetOpts, CI.getLangOpts(), | |||
1038 | CI.getTarget().getDataLayout(), TheModule.get(), BA, | |||
1039 | std::move(OS)); | |||
1040 | return; | |||
1041 | } | |||
1042 | ||||
1043 | // Otherwise follow the normal AST path. | |||
1044 | this->ASTFrontendAction::ExecuteAction(); | |||
1045 | } | |||
1046 | ||||
1047 | // | |||
1048 | ||||
1049 | void EmitAssemblyAction::anchor() { } | |||
1050 | EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext) | |||
1051 | : CodeGenAction(Backend_EmitAssembly, _VMContext) {} | |||
1052 | ||||
1053 | void EmitBCAction::anchor() { } | |||
1054 | EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext) | |||
1055 | : CodeGenAction(Backend_EmitBC, _VMContext) {} | |||
1056 | ||||
1057 | void EmitLLVMAction::anchor() { } | |||
1058 | EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext) | |||
1059 | : CodeGenAction(Backend_EmitLL, _VMContext) {} | |||
1060 | ||||
1061 | void EmitLLVMOnlyAction::anchor() { } | |||
1062 | EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext) | |||
1063 | : CodeGenAction(Backend_EmitNothing, _VMContext) {} | |||
1064 | ||||
1065 | void EmitCodeGenOnlyAction::anchor() { } | |||
1066 | EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext) | |||
1067 | : CodeGenAction(Backend_EmitMCNull, _VMContext) {} | |||
1068 | ||||
1069 | void EmitObjAction::anchor() { } | |||
1070 | EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext) | |||
1071 | : CodeGenAction(Backend_EmitObj, _VMContext) {} |