File: | tools/clang/lib/CodeGen/CodeGenAction.cpp |
Location: | line 477, column 5 |
Description: | Function call argument is an uninitialized value |
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 "CoverageMappingGen.h" | |||
11 | #include "clang/AST/ASTConsumer.h" | |||
12 | #include "clang/AST/ASTContext.h" | |||
13 | #include "clang/AST/DeclCXX.h" | |||
14 | #include "clang/AST/DeclGroup.h" | |||
15 | #include "clang/Basic/FileManager.h" | |||
16 | #include "clang/Basic/SourceManager.h" | |||
17 | #include "clang/Basic/TargetInfo.h" | |||
18 | #include "clang/CodeGen/BackendUtil.h" | |||
19 | #include "clang/CodeGen/CodeGenAction.h" | |||
20 | #include "clang/CodeGen/ModuleBuilder.h" | |||
21 | #include "clang/Frontend/CompilerInstance.h" | |||
22 | #include "clang/Frontend/FrontendDiagnostic.h" | |||
23 | #include "clang/Lex/Preprocessor.h" | |||
24 | #include "llvm/ADT/SmallString.h" | |||
25 | #include "llvm/Bitcode/ReaderWriter.h" | |||
26 | #include "llvm/IR/DebugInfo.h" | |||
27 | #include "llvm/IR/DiagnosticInfo.h" | |||
28 | #include "llvm/IR/DiagnosticPrinter.h" | |||
29 | #include "llvm/IR/LLVMContext.h" | |||
30 | #include "llvm/IR/Module.h" | |||
31 | #include "llvm/IRReader/IRReader.h" | |||
32 | #include "llvm/Linker/Linker.h" | |||
33 | #include "llvm/Pass.h" | |||
34 | #include "llvm/Support/MemoryBuffer.h" | |||
35 | #include "llvm/Support/SourceMgr.h" | |||
36 | #include "llvm/Support/Timer.h" | |||
37 | #include <memory> | |||
38 | using namespace clang; | |||
39 | using namespace llvm; | |||
40 | ||||
41 | namespace clang { | |||
42 | class BackendConsumer : public ASTConsumer { | |||
43 | virtual void anchor(); | |||
44 | DiagnosticsEngine &Diags; | |||
45 | BackendAction Action; | |||
46 | const CodeGenOptions &CodeGenOpts; | |||
47 | const TargetOptions &TargetOpts; | |||
48 | const LangOptions &LangOpts; | |||
49 | raw_pwrite_stream *AsmOutStream; | |||
50 | ASTContext *Context; | |||
51 | ||||
52 | Timer LLVMIRGeneration; | |||
53 | ||||
54 | std::unique_ptr<CodeGenerator> Gen; | |||
55 | ||||
56 | std::unique_ptr<llvm::Module> TheModule; | |||
57 | SmallVector<std::pair<unsigned, std::unique_ptr<llvm::Module>>, 4> | |||
58 | LinkModules; | |||
59 | ||||
60 | // This is here so that the diagnostic printer knows the module a diagnostic | |||
61 | // refers to. | |||
62 | llvm::Module *CurLinkModule = nullptr; | |||
63 | ||||
64 | public: | |||
65 | BackendConsumer( | |||
66 | BackendAction Action, DiagnosticsEngine &Diags, | |||
67 | const HeaderSearchOptions &HeaderSearchOpts, | |||
68 | const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, | |||
69 | const TargetOptions &TargetOpts, const LangOptions &LangOpts, | |||
70 | bool TimePasses, const std::string &InFile, | |||
71 | const SmallVectorImpl<std::pair<unsigned, llvm::Module *>> &LinkModules, | |||
72 | raw_pwrite_stream *OS, LLVMContext &C, | |||
73 | CoverageSourceInfo *CoverageInfo = nullptr) | |||
74 | : Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts), | |||
75 | TargetOpts(TargetOpts), LangOpts(LangOpts), AsmOutStream(OS), | |||
76 | Context(nullptr), LLVMIRGeneration("LLVM IR Generation Time"), | |||
77 | Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts, | |||
78 | CodeGenOpts, C, CoverageInfo)) { | |||
79 | llvm::TimePassesIsEnabled = TimePasses; | |||
80 | for (auto &I : LinkModules) | |||
81 | this->LinkModules.push_back( | |||
82 | std::make_pair(I.first, std::unique_ptr<llvm::Module>(I.second))); | |||
83 | } | |||
84 | std::unique_ptr<llvm::Module> takeModule() { return std::move(TheModule); } | |||
85 | void releaseLinkModules() { | |||
86 | for (auto &I : LinkModules) | |||
87 | I.second.release(); | |||
88 | } | |||
89 | ||||
90 | void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { | |||
91 | Gen->HandleCXXStaticMemberVarInstantiation(VD); | |||
92 | } | |||
93 | ||||
94 | void Initialize(ASTContext &Ctx) override { | |||
95 | assert(!Context && "initialized multiple times")((!Context && "initialized multiple times") ? static_cast <void> (0) : __assert_fail ("!Context && \"initialized multiple times\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 95, __PRETTY_FUNCTION__)); | |||
96 | ||||
97 | Context = &Ctx; | |||
98 | ||||
99 | if (llvm::TimePassesIsEnabled) | |||
100 | LLVMIRGeneration.startTimer(); | |||
101 | ||||
102 | Gen->Initialize(Ctx); | |||
103 | ||||
104 | TheModule.reset(Gen->GetModule()); | |||
105 | ||||
106 | if (llvm::TimePassesIsEnabled) | |||
107 | LLVMIRGeneration.stopTimer(); | |||
108 | } | |||
109 | ||||
110 | bool HandleTopLevelDecl(DeclGroupRef D) override { | |||
111 | PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(), | |||
112 | Context->getSourceManager(), | |||
113 | "LLVM IR generation of declaration"); | |||
114 | ||||
115 | if (llvm::TimePassesIsEnabled) | |||
116 | LLVMIRGeneration.startTimer(); | |||
117 | ||||
118 | Gen->HandleTopLevelDecl(D); | |||
119 | ||||
120 | if (llvm::TimePassesIsEnabled) | |||
121 | LLVMIRGeneration.stopTimer(); | |||
122 | ||||
123 | return true; | |||
124 | } | |||
125 | ||||
126 | void HandleInlineMethodDefinition(CXXMethodDecl *D) override { | |||
127 | PrettyStackTraceDecl CrashInfo(D, SourceLocation(), | |||
128 | Context->getSourceManager(), | |||
129 | "LLVM IR generation of inline method"); | |||
130 | if (llvm::TimePassesIsEnabled) | |||
131 | LLVMIRGeneration.startTimer(); | |||
132 | ||||
133 | Gen->HandleInlineMethodDefinition(D); | |||
134 | ||||
135 | if (llvm::TimePassesIsEnabled) | |||
136 | LLVMIRGeneration.stopTimer(); | |||
137 | } | |||
138 | ||||
139 | void HandleTranslationUnit(ASTContext &C) override { | |||
140 | { | |||
141 | PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); | |||
142 | if (llvm::TimePassesIsEnabled) | |||
143 | LLVMIRGeneration.startTimer(); | |||
144 | ||||
145 | Gen->HandleTranslationUnit(C); | |||
146 | ||||
147 | if (llvm::TimePassesIsEnabled) | |||
148 | LLVMIRGeneration.stopTimer(); | |||
149 | } | |||
150 | ||||
151 | // Silently ignore if we weren't initialized for some reason. | |||
152 | if (!TheModule) | |||
153 | return; | |||
154 | ||||
155 | // Make sure IR generation is happy with the module. This is released by | |||
156 | // the module provider. | |||
157 | llvm::Module *M = Gen->ReleaseModule(); | |||
158 | if (!M) { | |||
159 | // The module has been released by IR gen on failures, do not double | |||
160 | // free. | |||
161 | TheModule.release(); | |||
162 | return; | |||
163 | } | |||
164 | ||||
165 | assert(TheModule.get() == M &&((TheModule.get() == M && "Unexpected module change during IR generation" ) ? static_cast<void> (0) : __assert_fail ("TheModule.get() == M && \"Unexpected module change during IR generation\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 166, __PRETTY_FUNCTION__)) | |||
166 | "Unexpected module change during IR generation")((TheModule.get() == M && "Unexpected module change during IR generation" ) ? static_cast<void> (0) : __assert_fail ("TheModule.get() == M && \"Unexpected module change during IR generation\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 166, __PRETTY_FUNCTION__)); | |||
167 | ||||
168 | // Install an inline asm handler so that diagnostics get printed through | |||
169 | // our diagnostics hooks. | |||
170 | LLVMContext &Ctx = TheModule->getContext(); | |||
171 | LLVMContext::InlineAsmDiagHandlerTy OldHandler = | |||
172 | Ctx.getInlineAsmDiagnosticHandler(); | |||
173 | void *OldContext = Ctx.getInlineAsmDiagnosticContext(); | |||
174 | Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this); | |||
175 | ||||
176 | LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = | |||
177 | Ctx.getDiagnosticHandler(); | |||
178 | void *OldDiagnosticContext = Ctx.getDiagnosticContext(); | |||
179 | Ctx.setDiagnosticHandler(DiagnosticHandler, this); | |||
180 | ||||
181 | // Link LinkModule into this module if present, preserving its validity. | |||
182 | for (auto &I : LinkModules) { | |||
183 | unsigned LinkFlags = I.first; | |||
184 | CurLinkModule = I.second.get(); | |||
185 | if (Linker::linkModules(*M, std::move(I.second), LinkFlags)) | |||
186 | return; | |||
187 | } | |||
188 | ||||
189 | EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, | |||
190 | C.getTargetInfo().getDataLayoutString(), | |||
191 | TheModule.get(), Action, AsmOutStream); | |||
192 | ||||
193 | Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); | |||
194 | ||||
195 | Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext); | |||
196 | } | |||
197 | ||||
198 | void HandleTagDeclDefinition(TagDecl *D) override { | |||
199 | PrettyStackTraceDecl CrashInfo(D, SourceLocation(), | |||
200 | Context->getSourceManager(), | |||
201 | "LLVM IR generation of declaration"); | |||
202 | Gen->HandleTagDeclDefinition(D); | |||
203 | } | |||
204 | ||||
205 | void HandleTagDeclRequiredDefinition(const TagDecl *D) override { | |||
206 | Gen->HandleTagDeclRequiredDefinition(D); | |||
207 | } | |||
208 | ||||
209 | void CompleteTentativeDefinition(VarDecl *D) override { | |||
210 | Gen->CompleteTentativeDefinition(D); | |||
211 | } | |||
212 | ||||
213 | void HandleVTable(CXXRecordDecl *RD) override { | |||
214 | Gen->HandleVTable(RD); | |||
215 | } | |||
216 | ||||
217 | void HandleLinkerOptionPragma(llvm::StringRef Opts) override { | |||
218 | Gen->HandleLinkerOptionPragma(Opts); | |||
219 | } | |||
220 | ||||
221 | void HandleDetectMismatch(llvm::StringRef Name, | |||
222 | llvm::StringRef Value) override { | |||
223 | Gen->HandleDetectMismatch(Name, Value); | |||
224 | } | |||
225 | ||||
226 | void HandleDependentLibrary(llvm::StringRef Opts) override { | |||
227 | Gen->HandleDependentLibrary(Opts); | |||
228 | } | |||
229 | ||||
230 | static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context, | |||
231 | unsigned LocCookie) { | |||
232 | SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie); | |||
233 | ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc); | |||
234 | } | |||
235 | ||||
236 | static void DiagnosticHandler(const llvm::DiagnosticInfo &DI, | |||
237 | void *Context) { | |||
238 | ((BackendConsumer *)Context)->DiagnosticHandlerImpl(DI); | |||
239 | } | |||
240 | ||||
241 | void InlineAsmDiagHandler2(const llvm::SMDiagnostic &, | |||
242 | SourceLocation LocCookie); | |||
243 | ||||
244 | void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI); | |||
245 | /// \brief Specialized handler for InlineAsm diagnostic. | |||
246 | /// \return True if the diagnostic has been successfully reported, false | |||
247 | /// otherwise. | |||
248 | bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D); | |||
249 | /// \brief Specialized handler for StackSize diagnostic. | |||
250 | /// \return True if the diagnostic has been successfully reported, false | |||
251 | /// otherwise. | |||
252 | bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); | |||
253 | /// \brief Specialized handlers for optimization remarks. | |||
254 | /// Note that these handlers only accept remarks and they always handle | |||
255 | /// them. | |||
256 | void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D, | |||
257 | unsigned DiagID); | |||
258 | void | |||
259 | OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D); | |||
260 | void OptimizationRemarkHandler( | |||
261 | const llvm::DiagnosticInfoOptimizationRemarkMissed &D); | |||
262 | void OptimizationRemarkHandler( | |||
263 | const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D); | |||
264 | void OptimizationRemarkHandler( | |||
265 | const llvm::DiagnosticInfoOptimizationRemarkAnalysisFPCommute &D); | |||
266 | void OptimizationRemarkHandler( | |||
267 | const llvm::DiagnosticInfoOptimizationRemarkAnalysisAliasing &D); | |||
268 | void OptimizationFailureHandler( | |||
269 | const llvm::DiagnosticInfoOptimizationFailure &D); | |||
270 | }; | |||
271 | ||||
272 | void BackendConsumer::anchor() {} | |||
273 | } | |||
274 | ||||
275 | /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr | |||
276 | /// buffer to be a valid FullSourceLoc. | |||
277 | static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D, | |||
278 | SourceManager &CSM) { | |||
279 | // Get both the clang and llvm source managers. The location is relative to | |||
280 | // a memory buffer that the LLVM Source Manager is handling, we need to add | |||
281 | // a copy to the Clang source manager. | |||
282 | const llvm::SourceMgr &LSM = *D.getSourceMgr(); | |||
283 | ||||
284 | // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr | |||
285 | // already owns its one and clang::SourceManager wants to own its one. | |||
286 | const MemoryBuffer *LBuf = | |||
287 | LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc())); | |||
288 | ||||
289 | // Create the copy and transfer ownership to clang::SourceManager. | |||
290 | // TODO: Avoid copying files into memory. | |||
291 | std::unique_ptr<llvm::MemoryBuffer> CBuf = | |||
292 | llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(), | |||
293 | LBuf->getBufferIdentifier()); | |||
294 | // FIXME: Keep a file ID map instead of creating new IDs for each location. | |||
295 | FileID FID = CSM.createFileID(std::move(CBuf)); | |||
296 | ||||
297 | // Translate the offset into the file. | |||
298 | unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); | |||
299 | SourceLocation NewLoc = | |||
300 | CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset); | |||
301 | return FullSourceLoc(NewLoc, CSM); | |||
302 | } | |||
303 | ||||
304 | ||||
305 | /// InlineAsmDiagHandler2 - This function is invoked when the backend hits an | |||
306 | /// error parsing inline asm. The SMDiagnostic indicates the error relative to | |||
307 | /// the temporary memory buffer that the inline asm parser has set up. | |||
308 | void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D, | |||
309 | SourceLocation LocCookie) { | |||
310 | // There are a couple of different kinds of errors we could get here. First, | |||
311 | // we re-format the SMDiagnostic in terms of a clang diagnostic. | |||
312 | ||||
313 | // Strip "error: " off the start of the message string. | |||
314 | StringRef Message = D.getMessage(); | |||
315 | if (Message.startswith("error: ")) | |||
316 | Message = Message.substr(7); | |||
317 | ||||
318 | // If the SMDiagnostic has an inline asm source location, translate it. | |||
319 | FullSourceLoc Loc; | |||
320 | if (D.getLoc() != SMLoc()) | |||
321 | Loc = ConvertBackendLocation(D, Context->getSourceManager()); | |||
322 | ||||
323 | unsigned DiagID; | |||
324 | switch (D.getKind()) { | |||
325 | case llvm::SourceMgr::DK_Error: | |||
326 | DiagID = diag::err_fe_inline_asm; | |||
327 | break; | |||
328 | case llvm::SourceMgr::DK_Warning: | |||
329 | DiagID = diag::warn_fe_inline_asm; | |||
330 | break; | |||
331 | case llvm::SourceMgr::DK_Note: | |||
332 | DiagID = diag::note_fe_inline_asm; | |||
333 | break; | |||
334 | } | |||
335 | // If this problem has clang-level source location information, report the | |||
336 | // issue in the source with a note showing the instantiated | |||
337 | // code. | |||
338 | if (LocCookie.isValid()) { | |||
339 | Diags.Report(LocCookie, DiagID).AddString(Message); | |||
340 | ||||
341 | if (D.getLoc().isValid()) { | |||
342 | DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here); | |||
343 | // Convert the SMDiagnostic ranges into SourceRange and attach them | |||
344 | // to the diagnostic. | |||
345 | for (const std::pair<unsigned, unsigned> &Range : D.getRanges()) { | |||
346 | unsigned Column = D.getColumnNo(); | |||
347 | B << SourceRange(Loc.getLocWithOffset(Range.first - Column), | |||
348 | Loc.getLocWithOffset(Range.second - Column)); | |||
349 | } | |||
350 | } | |||
351 | return; | |||
352 | } | |||
353 | ||||
354 | // Otherwise, report the backend issue as occurring in the generated .s file. | |||
355 | // If Loc is invalid, we still need to report the issue, it just gets no | |||
356 | // location info. | |||
357 | Diags.Report(Loc, DiagID).AddString(Message); | |||
358 | } | |||
359 | ||||
360 | #define ComputeDiagID(Severity, GroupName, DiagID) \ | |||
361 | do { \ | |||
362 | switch (Severity) { \ | |||
363 | case llvm::DS_Error: \ | |||
364 | DiagID = diag::err_fe_##GroupName; \ | |||
365 | break; \ | |||
366 | case llvm::DS_Warning: \ | |||
367 | DiagID = diag::warn_fe_##GroupName; \ | |||
368 | break; \ | |||
369 | case llvm::DS_Remark: \ | |||
370 | llvm_unreachable("'remark' severity not expected")::llvm::llvm_unreachable_internal("'remark' severity not expected" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 370); \ | |||
371 | break; \ | |||
372 | case llvm::DS_Note: \ | |||
373 | DiagID = diag::note_fe_##GroupName; \ | |||
374 | break; \ | |||
375 | } \ | |||
376 | } while (false) | |||
377 | ||||
378 | #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) \ | |||
379 | do { \ | |||
380 | switch (Severity) { \ | |||
381 | case llvm::DS_Error: \ | |||
382 | DiagID = diag::err_fe_##GroupName; \ | |||
383 | break; \ | |||
384 | case llvm::DS_Warning: \ | |||
385 | DiagID = diag::warn_fe_##GroupName; \ | |||
386 | break; \ | |||
387 | case llvm::DS_Remark: \ | |||
388 | DiagID = diag::remark_fe_##GroupName; \ | |||
389 | break; \ | |||
390 | case llvm::DS_Note: \ | |||
391 | DiagID = diag::note_fe_##GroupName; \ | |||
392 | break; \ | |||
393 | } \ | |||
394 | } while (false) | |||
395 | ||||
396 | bool | |||
397 | BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) { | |||
398 | unsigned DiagID; | |||
399 | ComputeDiagID(D.getSeverity(), inline_asm, DiagID); | |||
400 | std::string Message = D.getMsgStr().str(); | |||
401 | ||||
402 | // If this problem has clang-level source location information, report the | |||
403 | // issue as being a problem in the source with a note showing the instantiated | |||
404 | // code. | |||
405 | SourceLocation LocCookie = | |||
406 | SourceLocation::getFromRawEncoding(D.getLocCookie()); | |||
407 | if (LocCookie.isValid()) | |||
408 | Diags.Report(LocCookie, DiagID).AddString(Message); | |||
409 | else { | |||
410 | // Otherwise, report the backend diagnostic as occurring in the generated | |||
411 | // .s file. | |||
412 | // If Loc is invalid, we still need to report the diagnostic, it just gets | |||
413 | // no location info. | |||
414 | FullSourceLoc Loc; | |||
415 | Diags.Report(Loc, DiagID).AddString(Message); | |||
416 | } | |||
417 | // We handled all the possible severities. | |||
418 | return true; | |||
419 | } | |||
420 | ||||
421 | bool | |||
422 | BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) { | |||
423 | if (D.getSeverity() != llvm::DS_Warning) | |||
424 | // For now, the only support we have for StackSize diagnostic is warning. | |||
425 | // We do not know how to format other severities. | |||
426 | return false; | |||
427 | ||||
428 | if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) { | |||
429 | Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()), | |||
430 | diag::warn_fe_frame_larger_than) | |||
431 | << D.getStackSize() << Decl::castToDeclContext(ND); | |||
432 | return true; | |||
433 | } | |||
434 | ||||
435 | return false; | |||
436 | } | |||
437 | ||||
438 | void BackendConsumer::EmitOptimizationMessage( | |||
439 | const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) { | |||
440 | // We only support warnings and remarks. | |||
441 | 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" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 442, __PRETTY_FUNCTION__)) | |||
442 | 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" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 442, __PRETTY_FUNCTION__)); | |||
443 | ||||
444 | SourceManager &SourceMgr = Context->getSourceManager(); | |||
445 | FileManager &FileMgr = SourceMgr.getFileManager(); | |||
446 | StringRef Filename; | |||
447 | unsigned Line, Column; | |||
448 | SourceLocation DILoc; | |||
449 | ||||
450 | if (D.isLocationAvailable()) { | |||
451 | D.getLocation(&Filename, &Line, &Column); | |||
452 | const FileEntry *FE = FileMgr.getFile(Filename); | |||
453 | if (FE && Line > 0) { | |||
454 | // If -gcolumn-info was not used, Column will be 0. This upsets the | |||
455 | // source manager, so pass 1 if Column is not set. | |||
456 | DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1); | |||
457 | } | |||
458 | } | |||
459 | ||||
460 | // If a location isn't available, try to approximate it using the associated | |||
461 | // function definition. We use the definition's right brace to differentiate | |||
462 | // from diagnostics that genuinely relate to the function itself. | |||
463 | FullSourceLoc Loc(DILoc, SourceMgr); | |||
464 | if (Loc.isInvalid()) | |||
465 | if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName())) | |||
466 | Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace()); | |||
467 | ||||
468 | Diags.Report(Loc, DiagID) | |||
469 | << AddFlagValue(D.getPassName() ? D.getPassName() : "") | |||
470 | << D.getMsg().str(); | |||
471 | ||||
472 | if (DILoc.isInvalid() && D.isLocationAvailable()) | |||
473 | // If we were not able to translate the file:line:col information | |||
474 | // back to a SourceLocation, at least emit a note stating that | |||
475 | // we could not translate this location. This can happen in the | |||
476 | // case of #line directives. | |||
477 | Diags.Report(Loc, diag::note_fe_backend_optimization_remark_invalid_loc) | |||
| ||||
478 | << Filename << Line << Column; | |||
479 | } | |||
480 | ||||
481 | void BackendConsumer::OptimizationRemarkHandler( | |||
482 | const llvm::DiagnosticInfoOptimizationRemark &D) { | |||
483 | // Optimization remarks are active only if the -Rpass flag has a regular | |||
484 | // expression that matches the name of the pass name in \p D. | |||
485 | if (CodeGenOpts.OptimizationRemarkPattern && | |||
486 | CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName())) | |||
487 | EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark); | |||
488 | } | |||
489 | ||||
490 | void BackendConsumer::OptimizationRemarkHandler( | |||
491 | const llvm::DiagnosticInfoOptimizationRemarkMissed &D) { | |||
492 | // Missed optimization remarks are active only if the -Rpass-missed | |||
493 | // flag has a regular expression that matches the name of the pass | |||
494 | // name in \p D. | |||
495 | if (CodeGenOpts.OptimizationRemarkMissedPattern && | |||
496 | CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName())) | |||
497 | EmitOptimizationMessage(D, | |||
498 | diag::remark_fe_backend_optimization_remark_missed); | |||
499 | } | |||
500 | ||||
501 | void BackendConsumer::OptimizationRemarkHandler( | |||
502 | const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D) { | |||
503 | // Optimization analysis remarks are active if the pass name is set to | |||
504 | // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a | |||
505 | // regular expression that matches the name of the pass name in \p D. | |||
506 | ||||
507 | if (D.getPassName() == llvm::DiagnosticInfo::AlwaysPrint || | |||
508 | (CodeGenOpts.OptimizationRemarkAnalysisPattern && | |||
509 | CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName()))) | |||
510 | EmitOptimizationMessage( | |||
511 | D, diag::remark_fe_backend_optimization_remark_analysis); | |||
512 | } | |||
513 | ||||
514 | void BackendConsumer::OptimizationRemarkHandler( | |||
515 | const llvm::DiagnosticInfoOptimizationRemarkAnalysisFPCommute &D) { | |||
516 | // Optimization analysis remarks are active if the pass name is set to | |||
517 | // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a | |||
518 | // regular expression that matches the name of the pass name in \p D. | |||
519 | ||||
520 | if (D.getPassName() == llvm::DiagnosticInfo::AlwaysPrint || | |||
521 | (CodeGenOpts.OptimizationRemarkAnalysisPattern && | |||
522 | CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName()))) | |||
523 | EmitOptimizationMessage( | |||
524 | D, diag::remark_fe_backend_optimization_remark_analysis_fpcommute); | |||
525 | } | |||
526 | ||||
527 | void BackendConsumer::OptimizationRemarkHandler( | |||
528 | const llvm::DiagnosticInfoOptimizationRemarkAnalysisAliasing &D) { | |||
529 | // Optimization analysis remarks are active if the pass name is set to | |||
530 | // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a | |||
531 | // regular expression that matches the name of the pass name in \p D. | |||
532 | ||||
533 | if (D.getPassName() == llvm::DiagnosticInfo::AlwaysPrint || | |||
534 | (CodeGenOpts.OptimizationRemarkAnalysisPattern && | |||
535 | CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName()))) | |||
536 | EmitOptimizationMessage( | |||
537 | D, diag::remark_fe_backend_optimization_remark_analysis_aliasing); | |||
538 | } | |||
539 | ||||
540 | void BackendConsumer::OptimizationFailureHandler( | |||
541 | const llvm::DiagnosticInfoOptimizationFailure &D) { | |||
542 | EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure); | |||
| ||||
543 | } | |||
544 | ||||
545 | /// \brief This function is invoked when the backend needs | |||
546 | /// to report something to the user. | |||
547 | void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { | |||
548 | unsigned DiagID = diag::err_fe_inline_asm; | |||
549 | llvm::DiagnosticSeverity Severity = DI.getSeverity(); | |||
550 | // Get the diagnostic ID based. | |||
551 | switch (DI.getKind()) { | |||
552 | case llvm::DK_InlineAsm: | |||
553 | if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI))) | |||
554 | return; | |||
555 | ComputeDiagID(Severity, inline_asm, DiagID); | |||
556 | break; | |||
557 | case llvm::DK_StackSize: | |||
558 | if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI))) | |||
559 | return; | |||
560 | ComputeDiagID(Severity, backend_frame_larger_than, DiagID); | |||
561 | break; | |||
562 | case DK_Linker: | |||
563 | assert(CurLinkModule)((CurLinkModule) ? static_cast<void> (0) : __assert_fail ("CurLinkModule", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 563, __PRETTY_FUNCTION__)); | |||
564 | // FIXME: stop eating the warnings and notes. | |||
565 | if (Severity != DS_Error) | |||
566 | return; | |||
567 | DiagID = diag::err_fe_cannot_link_module; | |||
568 | break; | |||
569 | case llvm::DK_OptimizationRemark: | |||
570 | // Optimization remarks are always handled completely by this | |||
571 | // handler. There is no generic way of emitting them. | |||
572 | OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemark>(DI)); | |||
573 | return; | |||
574 | case llvm::DK_OptimizationRemarkMissed: | |||
575 | // Optimization remarks are always handled completely by this | |||
576 | // handler. There is no generic way of emitting them. | |||
577 | OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemarkMissed>(DI)); | |||
578 | return; | |||
579 | case llvm::DK_OptimizationRemarkAnalysis: | |||
580 | // Optimization remarks are always handled completely by this | |||
581 | // handler. There is no generic way of emitting them. | |||
582 | OptimizationRemarkHandler( | |||
583 | cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI)); | |||
584 | return; | |||
585 | case llvm::DK_OptimizationRemarkAnalysisFPCommute: | |||
586 | // Optimization remarks are always handled completely by this | |||
587 | // handler. There is no generic way of emitting them. | |||
588 | OptimizationRemarkHandler( | |||
589 | cast<DiagnosticInfoOptimizationRemarkAnalysisFPCommute>(DI)); | |||
590 | return; | |||
591 | case llvm::DK_OptimizationRemarkAnalysisAliasing: | |||
592 | // Optimization remarks are always handled completely by this | |||
593 | // handler. There is no generic way of emitting them. | |||
594 | OptimizationRemarkHandler( | |||
595 | cast<DiagnosticInfoOptimizationRemarkAnalysisAliasing>(DI)); | |||
596 | return; | |||
597 | case llvm::DK_OptimizationFailure: | |||
598 | // Optimization failures are always handled completely by this | |||
599 | // handler. | |||
600 | OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI)); | |||
601 | return; | |||
602 | default: | |||
603 | // Plugin IDs are not bound to any value as they are set dynamically. | |||
604 | 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 ); | |||
605 | break; | |||
606 | } | |||
607 | std::string MsgStorage; | |||
608 | { | |||
609 | raw_string_ostream Stream(MsgStorage); | |||
610 | DiagnosticPrinterRawOStream DP(Stream); | |||
611 | DI.print(DP); | |||
612 | } | |||
613 | ||||
614 | if (DiagID == diag::err_fe_cannot_link_module) { | |||
615 | Diags.Report(diag::err_fe_cannot_link_module) | |||
616 | << CurLinkModule->getModuleIdentifier() << MsgStorage; | |||
617 | return; | |||
618 | } | |||
619 | ||||
620 | // Report the backend message using the usual diagnostic mechanism. | |||
621 | FullSourceLoc Loc; | |||
622 | Diags.Report(Loc, DiagID).AddString(MsgStorage); | |||
623 | } | |||
624 | #undef ComputeDiagID | |||
625 | ||||
626 | CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext) | |||
627 | : Act(_Act), VMContext(_VMContext ? _VMContext : new LLVMContext), | |||
628 | OwnsVMContext(!_VMContext) {} | |||
629 | ||||
630 | CodeGenAction::~CodeGenAction() { | |||
631 | TheModule.reset(); | |||
632 | if (OwnsVMContext) | |||
633 | delete VMContext; | |||
634 | } | |||
635 | ||||
636 | bool CodeGenAction::hasIRSupport() const { return true; } | |||
637 | ||||
638 | void CodeGenAction::EndSourceFileAction() { | |||
639 | // If the consumer creation failed, do nothing. | |||
640 | if (!getCompilerInstance().hasASTConsumer()) | |||
641 | return; | |||
642 | ||||
643 | // Take back ownership of link modules we passed to consumer. | |||
644 | if (!LinkModules.empty()) | |||
645 | BEConsumer->releaseLinkModules(); | |||
646 | ||||
647 | // Steal the module from the consumer. | |||
648 | TheModule = BEConsumer->takeModule(); | |||
649 | } | |||
650 | ||||
651 | std::unique_ptr<llvm::Module> CodeGenAction::takeModule() { | |||
652 | return std::move(TheModule); | |||
653 | } | |||
654 | ||||
655 | llvm::LLVMContext *CodeGenAction::takeLLVMContext() { | |||
656 | OwnsVMContext = false; | |||
657 | return VMContext; | |||
658 | } | |||
659 | ||||
660 | static raw_pwrite_stream * | |||
661 | GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) { | |||
662 | switch (Action) { | |||
663 | case Backend_EmitAssembly: | |||
664 | return CI.createDefaultOutputFile(false, InFile, "s"); | |||
665 | case Backend_EmitLL: | |||
666 | return CI.createDefaultOutputFile(false, InFile, "ll"); | |||
667 | case Backend_EmitBC: | |||
668 | return CI.createDefaultOutputFile(true, InFile, "bc"); | |||
669 | case Backend_EmitNothing: | |||
670 | return nullptr; | |||
671 | case Backend_EmitMCNull: | |||
672 | return CI.createNullOutputFile(); | |||
673 | case Backend_EmitObj: | |||
674 | return CI.createDefaultOutputFile(true, InFile, "o"); | |||
675 | } | |||
676 | ||||
677 | llvm_unreachable("Invalid action!")::llvm::llvm_unreachable_internal("Invalid action!", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 677); | |||
678 | } | |||
679 | ||||
680 | std::unique_ptr<ASTConsumer> | |||
681 | CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { | |||
682 | BackendAction BA = static_cast<BackendAction>(Act); | |||
683 | raw_pwrite_stream *OS = GetOutputStream(CI, InFile, BA); | |||
684 | if (BA != Backend_EmitNothing && !OS) | |||
685 | return nullptr; | |||
686 | ||||
687 | // Load bitcode modules to link with, if we need to. | |||
688 | if (LinkModules.empty()) | |||
689 | for (auto &I : CI.getCodeGenOpts().LinkBitcodeFiles) { | |||
690 | const std::string &LinkBCFile = I.second; | |||
691 | ||||
692 | auto BCBuf = CI.getFileManager().getBufferForFile(LinkBCFile); | |||
693 | if (!BCBuf) { | |||
694 | CI.getDiagnostics().Report(diag::err_cannot_open_file) | |||
695 | << LinkBCFile << BCBuf.getError().message(); | |||
696 | LinkModules.clear(); | |||
697 | return nullptr; | |||
698 | } | |||
699 | ||||
700 | ErrorOr<std::unique_ptr<llvm::Module>> ModuleOrErr = | |||
701 | getLazyBitcodeModule(std::move(*BCBuf), *VMContext); | |||
702 | if (std::error_code EC = ModuleOrErr.getError()) { | |||
703 | CI.getDiagnostics().Report(diag::err_cannot_open_file) << LinkBCFile | |||
704 | << EC.message(); | |||
705 | LinkModules.clear(); | |||
706 | return nullptr; | |||
707 | } | |||
708 | addLinkModule(ModuleOrErr.get().release(), I.first); | |||
709 | } | |||
710 | ||||
711 | CoverageSourceInfo *CoverageInfo = nullptr; | |||
712 | // Add the preprocessor callback only when the coverage mapping is generated. | |||
713 | if (CI.getCodeGenOpts().CoverageMapping) { | |||
714 | CoverageInfo = new CoverageSourceInfo; | |||
715 | CI.getPreprocessor().addPPCallbacks( | |||
716 | std::unique_ptr<PPCallbacks>(CoverageInfo)); | |||
717 | } | |||
718 | ||||
719 | std::unique_ptr<BackendConsumer> Result(new BackendConsumer( | |||
720 | BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), | |||
721 | CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(), | |||
722 | CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, LinkModules, | |||
723 | OS, *VMContext, CoverageInfo)); | |||
724 | BEConsumer = Result.get(); | |||
725 | return std::move(Result); | |||
726 | } | |||
727 | ||||
728 | static void BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic &SM, | |||
729 | void *Context, | |||
730 | unsigned LocCookie) { | |||
731 | SM.print(nullptr, llvm::errs()); | |||
732 | } | |||
733 | ||||
734 | void CodeGenAction::ExecuteAction() { | |||
735 | // If this is an IR file, we have to treat it specially. | |||
736 | if (getCurrentFileKind() == IK_LLVM_IR) { | |||
737 | BackendAction BA = static_cast<BackendAction>(Act); | |||
738 | CompilerInstance &CI = getCompilerInstance(); | |||
739 | raw_pwrite_stream *OS = GetOutputStream(CI, getCurrentFile(), BA); | |||
740 | if (BA != Backend_EmitNothing && !OS) | |||
741 | return; | |||
742 | ||||
743 | bool Invalid; | |||
744 | SourceManager &SM = CI.getSourceManager(); | |||
745 | FileID FID = SM.getMainFileID(); | |||
746 | llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid); | |||
747 | if (Invalid) | |||
748 | return; | |||
749 | ||||
750 | llvm::SMDiagnostic Err; | |||
751 | TheModule = parseIR(MainFile->getMemBufferRef(), Err, *VMContext); | |||
752 | if (!TheModule) { | |||
753 | // Translate from the diagnostic info to the SourceManager location if | |||
754 | // available. | |||
755 | // TODO: Unify this with ConvertBackendLocation() | |||
756 | SourceLocation Loc; | |||
757 | if (Err.getLineNo() > 0) { | |||
758 | assert(Err.getColumnNo() >= 0)((Err.getColumnNo() >= 0) ? static_cast<void> (0) : __assert_fail ("Err.getColumnNo() >= 0", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/tools/clang/lib/CodeGen/CodeGenAction.cpp" , 758, __PRETTY_FUNCTION__)); | |||
759 | Loc = SM.translateFileLineCol(SM.getFileEntryForID(FID), | |||
760 | Err.getLineNo(), Err.getColumnNo() + 1); | |||
761 | } | |||
762 | ||||
763 | // Strip off a leading diagnostic code if there is one. | |||
764 | StringRef Msg = Err.getMessage(); | |||
765 | if (Msg.startswith("error: ")) | |||
766 | Msg = Msg.substr(7); | |||
767 | ||||
768 | unsigned DiagID = | |||
769 | CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); | |||
770 | ||||
771 | CI.getDiagnostics().Report(Loc, DiagID) << Msg; | |||
772 | return; | |||
773 | } | |||
774 | const TargetOptions &TargetOpts = CI.getTargetOpts(); | |||
775 | if (TheModule->getTargetTriple() != TargetOpts.Triple) { | |||
776 | CI.getDiagnostics().Report(SourceLocation(), | |||
777 | diag::warn_fe_override_module) | |||
778 | << TargetOpts.Triple; | |||
779 | TheModule->setTargetTriple(TargetOpts.Triple); | |||
780 | } | |||
781 | ||||
782 | LLVMContext &Ctx = TheModule->getContext(); | |||
783 | Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler); | |||
784 | EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts, | |||
785 | CI.getLangOpts(), CI.getTarget().getDataLayoutString(), | |||
786 | TheModule.get(), BA, OS); | |||
787 | return; | |||
788 | } | |||
789 | ||||
790 | // Otherwise follow the normal AST path. | |||
791 | this->ASTFrontendAction::ExecuteAction(); | |||
792 | } | |||
793 | ||||
794 | // | |||
795 | ||||
796 | void EmitAssemblyAction::anchor() { } | |||
797 | EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext) | |||
798 | : CodeGenAction(Backend_EmitAssembly, _VMContext) {} | |||
799 | ||||
800 | void EmitBCAction::anchor() { } | |||
801 | EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext) | |||
802 | : CodeGenAction(Backend_EmitBC, _VMContext) {} | |||
803 | ||||
804 | void EmitLLVMAction::anchor() { } | |||
805 | EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext) | |||
806 | : CodeGenAction(Backend_EmitLL, _VMContext) {} | |||
807 | ||||
808 | void EmitLLVMOnlyAction::anchor() { } | |||
809 | EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext) | |||
810 | : CodeGenAction(Backend_EmitNothing, _VMContext) {} | |||
811 | ||||
812 | void EmitCodeGenOnlyAction::anchor() { } | |||
813 | EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext) | |||
814 | : CodeGenAction(Backend_EmitMCNull, _VMContext) {} | |||
815 | ||||
816 | void EmitObjAction::anchor() { } | |||
817 | EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext) | |||
818 | : CodeGenAction(Backend_EmitObj, _VMContext) {} |