clang API Documentation
00001 //===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "CoverageMappingGen.h" 00011 #include "clang/CodeGen/CodeGenAction.h" 00012 #include "clang/AST/ASTConsumer.h" 00013 #include "clang/AST/ASTContext.h" 00014 #include "clang/AST/DeclGroup.h" 00015 #include "clang/AST/DeclCXX.h" 00016 #include "clang/Basic/FileManager.h" 00017 #include "clang/Basic/SourceManager.h" 00018 #include "clang/Basic/TargetInfo.h" 00019 #include "clang/Lex/Preprocessor.h" 00020 #include "clang/CodeGen/BackendUtil.h" 00021 #include "clang/CodeGen/ModuleBuilder.h" 00022 #include "clang/Frontend/CompilerInstance.h" 00023 #include "clang/Frontend/FrontendDiagnostic.h" 00024 #include "llvm/ADT/SmallString.h" 00025 #include "llvm/Bitcode/ReaderWriter.h" 00026 #include "llvm/IR/DebugInfo.h" 00027 #include "llvm/IR/DiagnosticInfo.h" 00028 #include "llvm/IR/DiagnosticPrinter.h" 00029 #include "llvm/IR/LLVMContext.h" 00030 #include "llvm/IR/Module.h" 00031 #include "llvm/IRReader/IRReader.h" 00032 #include "llvm/Linker/Linker.h" 00033 #include "llvm/Pass.h" 00034 #include "llvm/Support/MemoryBuffer.h" 00035 #include "llvm/Support/SourceMgr.h" 00036 #include "llvm/Support/Timer.h" 00037 #include <memory> 00038 using namespace clang; 00039 using namespace llvm; 00040 00041 namespace clang { 00042 class BackendConsumer : public ASTConsumer { 00043 virtual void anchor(); 00044 DiagnosticsEngine &Diags; 00045 BackendAction Action; 00046 const CodeGenOptions &CodeGenOpts; 00047 const TargetOptions &TargetOpts; 00048 const LangOptions &LangOpts; 00049 raw_ostream *AsmOutStream; 00050 ASTContext *Context; 00051 00052 Timer LLVMIRGeneration; 00053 00054 std::unique_ptr<CodeGenerator> Gen; 00055 00056 std::unique_ptr<llvm::Module> TheModule, LinkModule; 00057 00058 public: 00059 BackendConsumer(BackendAction action, DiagnosticsEngine &_Diags, 00060 const CodeGenOptions &compopts, 00061 const TargetOptions &targetopts, 00062 const LangOptions &langopts, bool TimePasses, 00063 const std::string &infile, llvm::Module *LinkModule, 00064 raw_ostream *OS, LLVMContext &C, 00065 CoverageSourceInfo *CoverageInfo = nullptr) 00066 : Diags(_Diags), Action(action), CodeGenOpts(compopts), 00067 TargetOpts(targetopts), LangOpts(langopts), AsmOutStream(OS), 00068 Context(), LLVMIRGeneration("LLVM IR Generation Time"), 00069 Gen(CreateLLVMCodeGen(Diags, infile, compopts, 00070 targetopts, C, CoverageInfo)), 00071 LinkModule(LinkModule) { 00072 llvm::TimePassesIsEnabled = TimePasses; 00073 } 00074 00075 std::unique_ptr<llvm::Module> takeModule() { return std::move(TheModule); } 00076 llvm::Module *takeLinkModule() { return LinkModule.release(); } 00077 00078 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { 00079 Gen->HandleCXXStaticMemberVarInstantiation(VD); 00080 } 00081 00082 void Initialize(ASTContext &Ctx) override { 00083 Context = &Ctx; 00084 00085 if (llvm::TimePassesIsEnabled) 00086 LLVMIRGeneration.startTimer(); 00087 00088 Gen->Initialize(Ctx); 00089 00090 TheModule.reset(Gen->GetModule()); 00091 00092 if (llvm::TimePassesIsEnabled) 00093 LLVMIRGeneration.stopTimer(); 00094 } 00095 00096 bool HandleTopLevelDecl(DeclGroupRef D) override { 00097 PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(), 00098 Context->getSourceManager(), 00099 "LLVM IR generation of declaration"); 00100 00101 if (llvm::TimePassesIsEnabled) 00102 LLVMIRGeneration.startTimer(); 00103 00104 Gen->HandleTopLevelDecl(D); 00105 00106 if (llvm::TimePassesIsEnabled) 00107 LLVMIRGeneration.stopTimer(); 00108 00109 return true; 00110 } 00111 00112 void HandleInlineMethodDefinition(CXXMethodDecl *D) override { 00113 PrettyStackTraceDecl CrashInfo(D, SourceLocation(), 00114 Context->getSourceManager(), 00115 "LLVM IR generation of inline method"); 00116 if (llvm::TimePassesIsEnabled) 00117 LLVMIRGeneration.startTimer(); 00118 00119 Gen->HandleInlineMethodDefinition(D); 00120 00121 if (llvm::TimePassesIsEnabled) 00122 LLVMIRGeneration.stopTimer(); 00123 } 00124 00125 void HandleTranslationUnit(ASTContext &C) override { 00126 { 00127 PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); 00128 if (llvm::TimePassesIsEnabled) 00129 LLVMIRGeneration.startTimer(); 00130 00131 Gen->HandleTranslationUnit(C); 00132 00133 if (llvm::TimePassesIsEnabled) 00134 LLVMIRGeneration.stopTimer(); 00135 } 00136 00137 // Silently ignore if we weren't initialized for some reason. 00138 if (!TheModule) 00139 return; 00140 00141 // Make sure IR generation is happy with the module. This is released by 00142 // the module provider. 00143 llvm::Module *M = Gen->ReleaseModule(); 00144 if (!M) { 00145 // The module has been released by IR gen on failures, do not double 00146 // free. 00147 TheModule.release(); 00148 return; 00149 } 00150 00151 assert(TheModule.get() == M && 00152 "Unexpected module change during IR generation"); 00153 00154 // Link LinkModule into this module if present, preserving its validity. 00155 if (LinkModule) { 00156 if (Linker::LinkModules( 00157 M, LinkModule.get(), 00158 [=](const DiagnosticInfo &DI) { linkerDiagnosticHandler(DI); })) 00159 return; 00160 } 00161 00162 // Install an inline asm handler so that diagnostics get printed through 00163 // our diagnostics hooks. 00164 LLVMContext &Ctx = TheModule->getContext(); 00165 LLVMContext::InlineAsmDiagHandlerTy OldHandler = 00166 Ctx.getInlineAsmDiagnosticHandler(); 00167 void *OldContext = Ctx.getInlineAsmDiagnosticContext(); 00168 Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this); 00169 00170 LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 00171 Ctx.getDiagnosticHandler(); 00172 void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 00173 Ctx.setDiagnosticHandler(DiagnosticHandler, this); 00174 00175 EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, 00176 C.getTargetInfo().getTargetDescription(), 00177 TheModule.get(), Action, AsmOutStream); 00178 00179 Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); 00180 00181 Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext); 00182 } 00183 00184 void HandleTagDeclDefinition(TagDecl *D) override { 00185 PrettyStackTraceDecl CrashInfo(D, SourceLocation(), 00186 Context->getSourceManager(), 00187 "LLVM IR generation of declaration"); 00188 Gen->HandleTagDeclDefinition(D); 00189 } 00190 00191 void HandleTagDeclRequiredDefinition(const TagDecl *D) override { 00192 Gen->HandleTagDeclRequiredDefinition(D); 00193 } 00194 00195 void CompleteTentativeDefinition(VarDecl *D) override { 00196 Gen->CompleteTentativeDefinition(D); 00197 } 00198 00199 void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override { 00200 Gen->HandleVTable(RD, DefinitionRequired); 00201 } 00202 00203 void HandleLinkerOptionPragma(llvm::StringRef Opts) override { 00204 Gen->HandleLinkerOptionPragma(Opts); 00205 } 00206 00207 void HandleDetectMismatch(llvm::StringRef Name, 00208 llvm::StringRef Value) override { 00209 Gen->HandleDetectMismatch(Name, Value); 00210 } 00211 00212 void HandleDependentLibrary(llvm::StringRef Opts) override { 00213 Gen->HandleDependentLibrary(Opts); 00214 } 00215 00216 static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context, 00217 unsigned LocCookie) { 00218 SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie); 00219 ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc); 00220 } 00221 00222 void linkerDiagnosticHandler(const llvm::DiagnosticInfo &DI); 00223 00224 static void DiagnosticHandler(const llvm::DiagnosticInfo &DI, 00225 void *Context) { 00226 ((BackendConsumer *)Context)->DiagnosticHandlerImpl(DI); 00227 } 00228 00229 void InlineAsmDiagHandler2(const llvm::SMDiagnostic &, 00230 SourceLocation LocCookie); 00231 00232 void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI); 00233 /// \brief Specialized handler for InlineAsm diagnostic. 00234 /// \return True if the diagnostic has been successfully reported, false 00235 /// otherwise. 00236 bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D); 00237 /// \brief Specialized handler for StackSize diagnostic. 00238 /// \return True if the diagnostic has been successfully reported, false 00239 /// otherwise. 00240 bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); 00241 /// \brief Specialized handlers for optimization remarks. 00242 /// Note that these handlers only accept remarks and they always handle 00243 /// them. 00244 void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D, 00245 unsigned DiagID); 00246 void 00247 OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D); 00248 void OptimizationRemarkHandler( 00249 const llvm::DiagnosticInfoOptimizationRemarkMissed &D); 00250 void OptimizationRemarkHandler( 00251 const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D); 00252 void OptimizationFailureHandler( 00253 const llvm::DiagnosticInfoOptimizationFailure &D); 00254 }; 00255 00256 void BackendConsumer::anchor() {} 00257 } 00258 00259 /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr 00260 /// buffer to be a valid FullSourceLoc. 00261 static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D, 00262 SourceManager &CSM) { 00263 // Get both the clang and llvm source managers. The location is relative to 00264 // a memory buffer that the LLVM Source Manager is handling, we need to add 00265 // a copy to the Clang source manager. 00266 const llvm::SourceMgr &LSM = *D.getSourceMgr(); 00267 00268 // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr 00269 // already owns its one and clang::SourceManager wants to own its one. 00270 const MemoryBuffer *LBuf = 00271 LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc())); 00272 00273 // Create the copy and transfer ownership to clang::SourceManager. 00274 // TODO: Avoid copying files into memory. 00275 std::unique_ptr<llvm::MemoryBuffer> CBuf = 00276 llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(), 00277 LBuf->getBufferIdentifier()); 00278 // FIXME: Keep a file ID map instead of creating new IDs for each location. 00279 FileID FID = CSM.createFileID(std::move(CBuf)); 00280 00281 // Translate the offset into the file. 00282 unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); 00283 SourceLocation NewLoc = 00284 CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset); 00285 return FullSourceLoc(NewLoc, CSM); 00286 } 00287 00288 00289 /// InlineAsmDiagHandler2 - This function is invoked when the backend hits an 00290 /// error parsing inline asm. The SMDiagnostic indicates the error relative to 00291 /// the temporary memory buffer that the inline asm parser has set up. 00292 void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D, 00293 SourceLocation LocCookie) { 00294 // There are a couple of different kinds of errors we could get here. First, 00295 // we re-format the SMDiagnostic in terms of a clang diagnostic. 00296 00297 // Strip "error: " off the start of the message string. 00298 StringRef Message = D.getMessage(); 00299 if (Message.startswith("error: ")) 00300 Message = Message.substr(7); 00301 00302 // If the SMDiagnostic has an inline asm source location, translate it. 00303 FullSourceLoc Loc; 00304 if (D.getLoc() != SMLoc()) 00305 Loc = ConvertBackendLocation(D, Context->getSourceManager()); 00306 00307 unsigned DiagID; 00308 switch (D.getKind()) { 00309 case llvm::SourceMgr::DK_Error: 00310 DiagID = diag::err_fe_inline_asm; 00311 break; 00312 case llvm::SourceMgr::DK_Warning: 00313 DiagID = diag::warn_fe_inline_asm; 00314 break; 00315 case llvm::SourceMgr::DK_Note: 00316 DiagID = diag::note_fe_inline_asm; 00317 break; 00318 } 00319 // If this problem has clang-level source location information, report the 00320 // issue in the source with a note showing the instantiated 00321 // code. 00322 if (LocCookie.isValid()) { 00323 Diags.Report(LocCookie, DiagID).AddString(Message); 00324 00325 if (D.getLoc().isValid()) { 00326 DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here); 00327 // Convert the SMDiagnostic ranges into SourceRange and attach them 00328 // to the diagnostic. 00329 for (unsigned i = 0, e = D.getRanges().size(); i != e; ++i) { 00330 std::pair<unsigned, unsigned> Range = D.getRanges()[i]; 00331 unsigned Column = D.getColumnNo(); 00332 B << SourceRange(Loc.getLocWithOffset(Range.first - Column), 00333 Loc.getLocWithOffset(Range.second - Column)); 00334 } 00335 } 00336 return; 00337 } 00338 00339 // Otherwise, report the backend issue as occurring in the generated .s file. 00340 // If Loc is invalid, we still need to report the issue, it just gets no 00341 // location info. 00342 Diags.Report(Loc, DiagID).AddString(Message); 00343 } 00344 00345 #define ComputeDiagID(Severity, GroupName, DiagID) \ 00346 do { \ 00347 switch (Severity) { \ 00348 case llvm::DS_Error: \ 00349 DiagID = diag::err_fe_##GroupName; \ 00350 break; \ 00351 case llvm::DS_Warning: \ 00352 DiagID = diag::warn_fe_##GroupName; \ 00353 break; \ 00354 case llvm::DS_Remark: \ 00355 llvm_unreachable("'remark' severity not expected"); \ 00356 break; \ 00357 case llvm::DS_Note: \ 00358 DiagID = diag::note_fe_##GroupName; \ 00359 break; \ 00360 } \ 00361 } while (false) 00362 00363 #define ComputeDiagRemarkID(Severity, GroupName, DiagID) \ 00364 do { \ 00365 switch (Severity) { \ 00366 case llvm::DS_Error: \ 00367 DiagID = diag::err_fe_##GroupName; \ 00368 break; \ 00369 case llvm::DS_Warning: \ 00370 DiagID = diag::warn_fe_##GroupName; \ 00371 break; \ 00372 case llvm::DS_Remark: \ 00373 DiagID = diag::remark_fe_##GroupName; \ 00374 break; \ 00375 case llvm::DS_Note: \ 00376 DiagID = diag::note_fe_##GroupName; \ 00377 break; \ 00378 } \ 00379 } while (false) 00380 00381 bool 00382 BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) { 00383 unsigned DiagID; 00384 ComputeDiagID(D.getSeverity(), inline_asm, DiagID); 00385 std::string Message = D.getMsgStr().str(); 00386 00387 // If this problem has clang-level source location information, report the 00388 // issue as being a problem in the source with a note showing the instantiated 00389 // code. 00390 SourceLocation LocCookie = 00391 SourceLocation::getFromRawEncoding(D.getLocCookie()); 00392 if (LocCookie.isValid()) 00393 Diags.Report(LocCookie, DiagID).AddString(Message); 00394 else { 00395 // Otherwise, report the backend diagnostic as occurring in the generated 00396 // .s file. 00397 // If Loc is invalid, we still need to report the diagnostic, it just gets 00398 // no location info. 00399 FullSourceLoc Loc; 00400 Diags.Report(Loc, DiagID).AddString(Message); 00401 } 00402 // We handled all the possible severities. 00403 return true; 00404 } 00405 00406 bool 00407 BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) { 00408 if (D.getSeverity() != llvm::DS_Warning) 00409 // For now, the only support we have for StackSize diagnostic is warning. 00410 // We do not know how to format other severities. 00411 return false; 00412 00413 if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) { 00414 Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()), 00415 diag::warn_fe_frame_larger_than) 00416 << D.getStackSize() << Decl::castToDeclContext(ND); 00417 return true; 00418 } 00419 00420 return false; 00421 } 00422 00423 void BackendConsumer::EmitOptimizationMessage( 00424 const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) { 00425 // We only support warnings and remarks. 00426 assert(D.getSeverity() == llvm::DS_Remark || 00427 D.getSeverity() == llvm::DS_Warning); 00428 00429 SourceManager &SourceMgr = Context->getSourceManager(); 00430 FileManager &FileMgr = SourceMgr.getFileManager(); 00431 StringRef Filename; 00432 unsigned Line, Column; 00433 D.getLocation(&Filename, &Line, &Column); 00434 SourceLocation DILoc; 00435 const FileEntry *FE = FileMgr.getFile(Filename); 00436 if (FE && Line > 0) { 00437 // If -gcolumn-info was not used, Column will be 0. This upsets the 00438 // source manager, so pass 1 if Column is not set. 00439 DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1); 00440 } 00441 00442 // If a location isn't available, try to approximate it using the associated 00443 // function definition. We use the definition's right brace to differentiate 00444 // from diagnostics that genuinely relate to the function itself. 00445 FullSourceLoc Loc(DILoc, SourceMgr); 00446 if (Loc.isInvalid()) 00447 if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName())) 00448 Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace()); 00449 00450 Diags.Report(Loc, DiagID) 00451 << AddFlagValue(D.getPassName() ? D.getPassName() : "") 00452 << D.getMsg().str(); 00453 00454 if (DILoc.isInvalid()) 00455 // If we were not able to translate the file:line:col information 00456 // back to a SourceLocation, at least emit a note stating that 00457 // we could not translate this location. This can happen in the 00458 // case of #line directives. 00459 Diags.Report(Loc, diag::note_fe_backend_optimization_remark_invalid_loc) 00460 << Filename << Line << Column; 00461 } 00462 00463 void BackendConsumer::OptimizationRemarkHandler( 00464 const llvm::DiagnosticInfoOptimizationRemark &D) { 00465 // Optimization remarks are active only if the -Rpass flag has a regular 00466 // expression that matches the name of the pass name in \p D. 00467 if (CodeGenOpts.OptimizationRemarkPattern && 00468 CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName())) 00469 EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark); 00470 } 00471 00472 void BackendConsumer::OptimizationRemarkHandler( 00473 const llvm::DiagnosticInfoOptimizationRemarkMissed &D) { 00474 // Missed optimization remarks are active only if the -Rpass-missed 00475 // flag has a regular expression that matches the name of the pass 00476 // name in \p D. 00477 if (CodeGenOpts.OptimizationRemarkMissedPattern && 00478 CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName())) 00479 EmitOptimizationMessage(D, 00480 diag::remark_fe_backend_optimization_remark_missed); 00481 } 00482 00483 void BackendConsumer::OptimizationRemarkHandler( 00484 const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D) { 00485 // Optimization analysis remarks are active only if the -Rpass-analysis 00486 // flag has a regular expression that matches the name of the pass 00487 // name in \p D. 00488 if (CodeGenOpts.OptimizationRemarkAnalysisPattern && 00489 CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())) 00490 EmitOptimizationMessage( 00491 D, diag::remark_fe_backend_optimization_remark_analysis); 00492 } 00493 00494 void BackendConsumer::OptimizationFailureHandler( 00495 const llvm::DiagnosticInfoOptimizationFailure &D) { 00496 EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure); 00497 } 00498 00499 void BackendConsumer::linkerDiagnosticHandler(const DiagnosticInfo &DI) { 00500 if (DI.getSeverity() != DS_Error) 00501 return; 00502 00503 std::string MsgStorage; 00504 { 00505 raw_string_ostream Stream(MsgStorage); 00506 DiagnosticPrinterRawOStream DP(Stream); 00507 DI.print(DP); 00508 } 00509 00510 Diags.Report(diag::err_fe_cannot_link_module) 00511 << LinkModule->getModuleIdentifier() << MsgStorage; 00512 } 00513 00514 /// \brief This function is invoked when the backend needs 00515 /// to report something to the user. 00516 void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { 00517 unsigned DiagID = diag::err_fe_inline_asm; 00518 llvm::DiagnosticSeverity Severity = DI.getSeverity(); 00519 // Get the diagnostic ID based. 00520 switch (DI.getKind()) { 00521 case llvm::DK_InlineAsm: 00522 if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI))) 00523 return; 00524 ComputeDiagID(Severity, inline_asm, DiagID); 00525 break; 00526 case llvm::DK_StackSize: 00527 if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI))) 00528 return; 00529 ComputeDiagID(Severity, backend_frame_larger_than, DiagID); 00530 break; 00531 case llvm::DK_OptimizationRemark: 00532 // Optimization remarks are always handled completely by this 00533 // handler. There is no generic way of emitting them. 00534 OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemark>(DI)); 00535 return; 00536 case llvm::DK_OptimizationRemarkMissed: 00537 // Optimization remarks are always handled completely by this 00538 // handler. There is no generic way of emitting them. 00539 OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemarkMissed>(DI)); 00540 return; 00541 case llvm::DK_OptimizationRemarkAnalysis: 00542 // Optimization remarks are always handled completely by this 00543 // handler. There is no generic way of emitting them. 00544 OptimizationRemarkHandler( 00545 cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI)); 00546 return; 00547 case llvm::DK_OptimizationFailure: 00548 // Optimization failures are always handled completely by this 00549 // handler. 00550 OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI)); 00551 return; 00552 default: 00553 // Plugin IDs are not bound to any value as they are set dynamically. 00554 ComputeDiagRemarkID(Severity, backend_plugin, DiagID); 00555 break; 00556 } 00557 std::string MsgStorage; 00558 { 00559 raw_string_ostream Stream(MsgStorage); 00560 DiagnosticPrinterRawOStream DP(Stream); 00561 DI.print(DP); 00562 } 00563 00564 // Report the backend message using the usual diagnostic mechanism. 00565 FullSourceLoc Loc; 00566 Diags.Report(Loc, DiagID).AddString(MsgStorage); 00567 } 00568 #undef ComputeDiagID 00569 00570 CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext) 00571 : Act(_Act), LinkModule(nullptr), 00572 VMContext(_VMContext ? _VMContext : new LLVMContext), 00573 OwnsVMContext(!_VMContext) {} 00574 00575 CodeGenAction::~CodeGenAction() { 00576 TheModule.reset(); 00577 if (OwnsVMContext) 00578 delete VMContext; 00579 } 00580 00581 bool CodeGenAction::hasIRSupport() const { return true; } 00582 00583 void CodeGenAction::EndSourceFileAction() { 00584 // If the consumer creation failed, do nothing. 00585 if (!getCompilerInstance().hasASTConsumer()) 00586 return; 00587 00588 // If we were given a link module, release consumer's ownership of it. 00589 if (LinkModule) 00590 BEConsumer->takeLinkModule(); 00591 00592 // Steal the module from the consumer. 00593 TheModule = BEConsumer->takeModule(); 00594 } 00595 00596 std::unique_ptr<llvm::Module> CodeGenAction::takeModule() { 00597 return std::move(TheModule); 00598 } 00599 00600 llvm::LLVMContext *CodeGenAction::takeLLVMContext() { 00601 OwnsVMContext = false; 00602 return VMContext; 00603 } 00604 00605 static raw_ostream *GetOutputStream(CompilerInstance &CI, 00606 StringRef InFile, 00607 BackendAction Action) { 00608 switch (Action) { 00609 case Backend_EmitAssembly: 00610 return CI.createDefaultOutputFile(false, InFile, "s"); 00611 case Backend_EmitLL: 00612 return CI.createDefaultOutputFile(false, InFile, "ll"); 00613 case Backend_EmitBC: 00614 return CI.createDefaultOutputFile(true, InFile, "bc"); 00615 case Backend_EmitNothing: 00616 return nullptr; 00617 case Backend_EmitMCNull: 00618 return CI.createNullOutputFile(); 00619 case Backend_EmitObj: 00620 return CI.createDefaultOutputFile(true, InFile, "o"); 00621 } 00622 00623 llvm_unreachable("Invalid action!"); 00624 } 00625 00626 std::unique_ptr<ASTConsumer> 00627 CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 00628 BackendAction BA = static_cast<BackendAction>(Act); 00629 std::unique_ptr<raw_ostream> OS(GetOutputStream(CI, InFile, BA)); 00630 if (BA != Backend_EmitNothing && !OS) 00631 return nullptr; 00632 00633 llvm::Module *LinkModuleToUse = LinkModule; 00634 00635 // If we were not given a link module, and the user requested that one be 00636 // loaded from bitcode, do so now. 00637 const std::string &LinkBCFile = CI.getCodeGenOpts().LinkBitcodeFile; 00638 if (!LinkModuleToUse && !LinkBCFile.empty()) { 00639 auto BCBuf = CI.getFileManager().getBufferForFile(LinkBCFile); 00640 if (!BCBuf) { 00641 CI.getDiagnostics().Report(diag::err_cannot_open_file) 00642 << LinkBCFile << BCBuf.getError().message(); 00643 return nullptr; 00644 } 00645 00646 ErrorOr<llvm::Module *> ModuleOrErr = 00647 getLazyBitcodeModule(std::move(*BCBuf), *VMContext); 00648 if (std::error_code EC = ModuleOrErr.getError()) { 00649 CI.getDiagnostics().Report(diag::err_cannot_open_file) 00650 << LinkBCFile << EC.message(); 00651 return nullptr; 00652 } 00653 LinkModuleToUse = ModuleOrErr.get(); 00654 } 00655 00656 CoverageSourceInfo *CoverageInfo = nullptr; 00657 // Add the preprocessor callback only when the coverage mapping is generated. 00658 if (CI.getCodeGenOpts().CoverageMapping) { 00659 CoverageInfo = new CoverageSourceInfo; 00660 CI.getPreprocessor().addPPCallbacks( 00661 std::unique_ptr<PPCallbacks>(CoverageInfo)); 00662 } 00663 std::unique_ptr<BackendConsumer> Result(new BackendConsumer( 00664 BA, CI.getDiagnostics(), CI.getCodeGenOpts(), CI.getTargetOpts(), 00665 CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, 00666 LinkModuleToUse, OS.release(), *VMContext, CoverageInfo)); 00667 BEConsumer = Result.get(); 00668 return std::move(Result); 00669 } 00670 00671 void CodeGenAction::ExecuteAction() { 00672 // If this is an IR file, we have to treat it specially. 00673 if (getCurrentFileKind() == IK_LLVM_IR) { 00674 BackendAction BA = static_cast<BackendAction>(Act); 00675 CompilerInstance &CI = getCompilerInstance(); 00676 raw_ostream *OS = GetOutputStream(CI, getCurrentFile(), BA); 00677 if (BA != Backend_EmitNothing && !OS) 00678 return; 00679 00680 bool Invalid; 00681 SourceManager &SM = CI.getSourceManager(); 00682 FileID FID = SM.getMainFileID(); 00683 llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid); 00684 if (Invalid) 00685 return; 00686 00687 llvm::SMDiagnostic Err; 00688 TheModule = parseIR(MainFile->getMemBufferRef(), Err, *VMContext); 00689 if (!TheModule) { 00690 // Translate from the diagnostic info to the SourceManager location if 00691 // available. 00692 // TODO: Unify this with ConvertBackendLocation() 00693 SourceLocation Loc; 00694 if (Err.getLineNo() > 0) { 00695 assert(Err.getColumnNo() >= 0); 00696 Loc = SM.translateFileLineCol(SM.getFileEntryForID(FID), 00697 Err.getLineNo(), Err.getColumnNo() + 1); 00698 } 00699 00700 // Strip off a leading diagnostic code if there is one. 00701 StringRef Msg = Err.getMessage(); 00702 if (Msg.startswith("error: ")) 00703 Msg = Msg.substr(7); 00704 00705 unsigned DiagID = 00706 CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); 00707 00708 CI.getDiagnostics().Report(Loc, DiagID) << Msg; 00709 return; 00710 } 00711 const TargetOptions &TargetOpts = CI.getTargetOpts(); 00712 if (TheModule->getTargetTriple() != TargetOpts.Triple) { 00713 unsigned DiagID = CI.getDiagnostics().getCustomDiagID( 00714 DiagnosticsEngine::Warning, 00715 "overriding the module target triple with %0"); 00716 00717 CI.getDiagnostics().Report(SourceLocation(), DiagID) << TargetOpts.Triple; 00718 TheModule->setTargetTriple(TargetOpts.Triple); 00719 } 00720 00721 EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts, 00722 CI.getLangOpts(), CI.getTarget().getTargetDescription(), 00723 TheModule.get(), BA, OS); 00724 return; 00725 } 00726 00727 // Otherwise follow the normal AST path. 00728 this->ASTFrontendAction::ExecuteAction(); 00729 } 00730 00731 // 00732 00733 void EmitAssemblyAction::anchor() { } 00734 EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext) 00735 : CodeGenAction(Backend_EmitAssembly, _VMContext) {} 00736 00737 void EmitBCAction::anchor() { } 00738 EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext) 00739 : CodeGenAction(Backend_EmitBC, _VMContext) {} 00740 00741 void EmitLLVMAction::anchor() { } 00742 EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext) 00743 : CodeGenAction(Backend_EmitLL, _VMContext) {} 00744 00745 void EmitLLVMOnlyAction::anchor() { } 00746 EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext) 00747 : CodeGenAction(Backend_EmitNothing, _VMContext) {} 00748 00749 void EmitCodeGenOnlyAction::anchor() { } 00750 EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext) 00751 : CodeGenAction(Backend_EmitMCNull, _VMContext) {} 00752 00753 void EmitObjAction::anchor() { } 00754 EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext) 00755 : CodeGenAction(Backend_EmitObj, _VMContext) {}