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 "clang/AST/ASTConsumer.h" 12 #include "clang/AST/ASTContext.h" 13 #include "clang/AST/DeclGroup.h" 14 #include "clang/Basic/FileManager.h" 15 #include "clang/Basic/SourceManager.h" 16 #include "clang/Basic/TargetInfo.h" 17 #include "clang/CodeGen/BackendUtil.h" 18 #include "clang/CodeGen/ModuleBuilder.h" 19 #include "clang/Frontend/CompilerInstance.h" 20 #include "clang/Frontend/FrontendDiagnostic.h" 21 #include "llvm/ADT/OwningPtr.h" 22 #include "llvm/ADT/SmallString.h" 23 #include "llvm/Bitcode/ReaderWriter.h" 24 #include "llvm/IR/LLVMContext.h" 25 #include "llvm/IR/Module.h" 26 #include "llvm/IRReader/IRReader.h" 27 #include "llvm/Linker.h" 28 #include "llvm/Pass.h" 29 #include "llvm/Support/MemoryBuffer.h" 30 #include "llvm/Support/SourceMgr.h" 31 #include "llvm/Support/Timer.h" 32 using namespace clang; 33 using namespace llvm; 34 35 namespace clang { 36 class BackendConsumer : public ASTConsumer { 37 virtual void anchor(); 38 DiagnosticsEngine &Diags; 39 BackendAction Action; 40 const CodeGenOptions &CodeGenOpts; 41 const TargetOptions &TargetOpts; 42 const LangOptions &LangOpts; 43 raw_ostream *AsmOutStream; 44 ASTContext *Context; 45 46 Timer LLVMIRGeneration; 47 48 OwningPtr<CodeGenerator> Gen; 49 50 OwningPtr<llvm::Module> TheModule, LinkModule; 51 52 public: 53 BackendConsumer(BackendAction action, DiagnosticsEngine &_Diags, 54 const CodeGenOptions &compopts, 55 const TargetOptions &targetopts, 56 const LangOptions &langopts, bool TimePasses, 57 const std::string &infile, llvm::Module *LinkModule, 58 raw_ostream *OS, LLVMContext &C) 59 : Diags(_Diags), Action(action), CodeGenOpts(compopts), 60 TargetOpts(targetopts), LangOpts(langopts), AsmOutStream(OS), 61 Context(), LLVMIRGeneration("LLVM IR Generation Time"), 62 Gen(CreateLLVMCodeGen(Diags, infile, compopts, targetopts, C)), 63 LinkModule(LinkModule) { 64 llvm::TimePassesIsEnabled = TimePasses; 65 } 66 67 llvm::Module *takeModule() { return TheModule.take(); } 68 llvm::Module *takeLinkModule() { return LinkModule.take(); } 69 70 virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { 71 Gen->HandleCXXStaticMemberVarInstantiation(VD); 72 } 73 74 virtual void Initialize(ASTContext &Ctx) { 75 Context = &Ctx; 76 77 if (llvm::TimePassesIsEnabled) 78 LLVMIRGeneration.startTimer(); 79 80 Gen->Initialize(Ctx); 81 82 TheModule.reset(Gen->GetModule()); 83 84 if (llvm::TimePassesIsEnabled) 85 LLVMIRGeneration.stopTimer(); 86 } 87 88 virtual bool HandleTopLevelDecl(DeclGroupRef D) { 89 PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(), 90 Context->getSourceManager(), 91 "LLVM IR generation of declaration"); 92 93 if (llvm::TimePassesIsEnabled) 94 LLVMIRGeneration.startTimer(); 95 96 Gen->HandleTopLevelDecl(D); 97 98 if (llvm::TimePassesIsEnabled) 99 LLVMIRGeneration.stopTimer(); 100 101 return true; 102 } 103 104 virtual void HandleTranslationUnit(ASTContext &C) { 105 { 106 PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); 107 if (llvm::TimePassesIsEnabled) 108 LLVMIRGeneration.startTimer(); 109 110 Gen->HandleTranslationUnit(C); 111 112 if (llvm::TimePassesIsEnabled) 113 LLVMIRGeneration.stopTimer(); 114 } 115 116 // Silently ignore if we weren't initialized for some reason. 117 if (!TheModule) 118 return; 119 120 // Make sure IR generation is happy with the module. This is released by 121 // the module provider. 122 llvm::Module *M = Gen->ReleaseModule(); 123 if (!M) { 124 // The module has been released by IR gen on failures, do not double 125 // free. 126 TheModule.take(); 127 return; 128 } 129 130 assert(TheModule.get() == M && 131 "Unexpected module change during IR generation"); 132 133 // Link LinkModule into this module if present, preserving its validity. 134 if (LinkModule) { 135 std::string ErrorMsg; 136 if (Linker::LinkModules(M, LinkModule.get(), Linker::PreserveSource, 137 &ErrorMsg)) { 138 Diags.Report(diag::err_fe_cannot_link_module) 139 << LinkModule->getModuleIdentifier() << ErrorMsg; 140 return; 141 } 142 } 143 144 // Install an inline asm handler so that diagnostics get printed through 145 // our diagnostics hooks. 146 LLVMContext &Ctx = TheModule->getContext(); 147 LLVMContext::InlineAsmDiagHandlerTy OldHandler = 148 Ctx.getInlineAsmDiagnosticHandler(); 149 void *OldContext = Ctx.getInlineAsmDiagnosticContext(); 150 Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this); 151 152 EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, 153 C.getTargetInfo().getTargetDescription(), 154 TheModule.get(), Action, AsmOutStream); 155 156 Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); 157 } 158 159 virtual void HandleTagDeclDefinition(TagDecl *D) { 160 PrettyStackTraceDecl CrashInfo(D, SourceLocation(), 161 Context->getSourceManager(), 162 "LLVM IR generation of declaration"); 163 Gen->HandleTagDeclDefinition(D); 164 } 165 166 virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) { 167 Gen->HandleTagDeclRequiredDefinition(D); 168 } 169 170 virtual void CompleteTentativeDefinition(VarDecl *D) { 171 Gen->CompleteTentativeDefinition(D); 172 } 173 174 virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) { 175 Gen->HandleVTable(RD, DefinitionRequired); 176 } 177 178 virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) { 179 Gen->HandleLinkerOptionPragma(Opts); 180 } 181 182 virtual void HandleDetectMismatch(llvm::StringRef Name, 183 llvm::StringRef Value) { 184 Gen->HandleDetectMismatch(Name, Value); 185 } 186 187 virtual void HandleDependentLibrary(llvm::StringRef Opts) { 188 Gen->HandleDependentLibrary(Opts); 189 } 190 191 static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context, 192 unsigned LocCookie) { 193 SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie); 194 ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc); 195 } 196 197 void InlineAsmDiagHandler2(const llvm::SMDiagnostic &, 198 SourceLocation LocCookie); 199 }; 200 201 void BackendConsumer::anchor() {} 202 } 203 204 /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr 205 /// buffer to be a valid FullSourceLoc. 206 static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D, 207 SourceManager &CSM) { 208 // Get both the clang and llvm source managers. The location is relative to 209 // a memory buffer that the LLVM Source Manager is handling, we need to add 210 // a copy to the Clang source manager. 211 const llvm::SourceMgr &LSM = *D.getSourceMgr(); 212 213 // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr 214 // already owns its one and clang::SourceManager wants to own its one. 215 const MemoryBuffer *LBuf = 216 LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc())); 217 218 // Create the copy and transfer ownership to clang::SourceManager. 219 llvm::MemoryBuffer *CBuf = 220 llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(), 221 LBuf->getBufferIdentifier()); 222 FileID FID = CSM.createFileIDForMemBuffer(CBuf); 223 224 // Translate the offset into the file. 225 unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); 226 SourceLocation NewLoc = 227 CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset); 228 return FullSourceLoc(NewLoc, CSM); 229 } 230 231 232 /// InlineAsmDiagHandler2 - This function is invoked when the backend hits an 233 /// error parsing inline asm. The SMDiagnostic indicates the error relative to 234 /// the temporary memory buffer that the inline asm parser has set up. 235 void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D, 236 SourceLocation LocCookie) { 237 // There are a couple of different kinds of errors we could get here. First, 238 // we re-format the SMDiagnostic in terms of a clang diagnostic. 239 240 // Strip "error: " off the start of the message string. 241 StringRef Message = D.getMessage(); 242 if (Message.startswith("error: ")) 243 Message = Message.substr(7); 244 245 // If the SMDiagnostic has an inline asm source location, translate it. 246 FullSourceLoc Loc; 247 if (D.getLoc() != SMLoc()) 248 Loc = ConvertBackendLocation(D, Context->getSourceManager()); 249 250 251 // If this problem has clang-level source location information, report the 252 // issue as being an error in the source with a note showing the instantiated 253 // code. 254 if (LocCookie.isValid()) { 255 Diags.Report(LocCookie, diag::err_fe_inline_asm).AddString(Message); 256 257 if (D.getLoc().isValid()) { 258 DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here); 259 // Convert the SMDiagnostic ranges into SourceRange and attach them 260 // to the diagnostic. 261 for (unsigned i = 0, e = D.getRanges().size(); i != e; ++i) { 262 std::pair<unsigned, unsigned> Range = D.getRanges()[i]; 263 unsigned Column = D.getColumnNo(); 264 B << SourceRange(Loc.getLocWithOffset(Range.first - Column), 265 Loc.getLocWithOffset(Range.second - Column)); 266 } 267 } 268 return; 269 } 270 271 // Otherwise, report the backend error as occurring in the generated .s file. 272 // If Loc is invalid, we still need to report the error, it just gets no 273 // location info. 274 Diags.Report(Loc, diag::err_fe_inline_asm).AddString(Message); 275 } 276 277 // 278 279 CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext) 280 : Act(_Act), LinkModule(0), 281 VMContext(_VMContext ? _VMContext : new LLVMContext), 282 OwnsVMContext(!_VMContext) {} 283 284 CodeGenAction::~CodeGenAction() { 285 TheModule.reset(); 286 if (OwnsVMContext) 287 delete VMContext; 288 } 289 290 bool CodeGenAction::hasIRSupport() const { return true; } 291 292 void CodeGenAction::EndSourceFileAction() { 293 // If the consumer creation failed, do nothing. 294 if (!getCompilerInstance().hasASTConsumer()) 295 return; 296 297 // If we were given a link module, release consumer's ownership of it. 298 if (LinkModule) 299 BEConsumer->takeLinkModule(); 300 301 // Steal the module from the consumer. 302 TheModule.reset(BEConsumer->takeModule()); 303 } 304 305 llvm::Module *CodeGenAction::takeModule() { 306 return TheModule.take(); 307 } 308 309 llvm::LLVMContext *CodeGenAction::takeLLVMContext() { 310 OwnsVMContext = false; 311 return VMContext; 312 } 313 314 static raw_ostream *GetOutputStream(CompilerInstance &CI, 315 StringRef InFile, 316 BackendAction Action) { 317 switch (Action) { 318 case Backend_EmitAssembly: 319 return CI.createDefaultOutputFile(false, InFile, "s"); 320 case Backend_EmitLL: 321 return CI.createDefaultOutputFile(false, InFile, "ll"); 322 case Backend_EmitBC: 323 return CI.createDefaultOutputFile(true, InFile, "bc"); 324 case Backend_EmitNothing: 325 return 0; 326 case Backend_EmitMCNull: 327 case Backend_EmitObj: 328 return CI.createDefaultOutputFile(true, InFile, "o"); 329 } 330 331 llvm_unreachable("Invalid action!"); 332 } 333 334 ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, 335 StringRef InFile) { 336 BackendAction BA = static_cast<BackendAction>(Act); 337 OwningPtr<raw_ostream> OS(GetOutputStream(CI, InFile, BA)); 338 if (BA != Backend_EmitNothing && !OS) 339 return 0; 340 341 llvm::Module *LinkModuleToUse = LinkModule; 342 343 // If we were not given a link module, and the user requested that one be 344 // loaded from bitcode, do so now. 345 const std::string &LinkBCFile = CI.getCodeGenOpts().LinkBitcodeFile; 346 if (!LinkModuleToUse && !LinkBCFile.empty()) { 347 std::string ErrorStr; 348 349 llvm::MemoryBuffer *BCBuf = 350 CI.getFileManager().getBufferForFile(LinkBCFile, &ErrorStr); 351 if (!BCBuf) { 352 CI.getDiagnostics().Report(diag::err_cannot_open_file) 353 << LinkBCFile << ErrorStr; 354 return 0; 355 } 356 357 ErrorOr<llvm::Module *> ModuleOrErr = 358 getLazyBitcodeModule(BCBuf, *VMContext); 359 if (error_code EC = ModuleOrErr.getError()) { 360 CI.getDiagnostics().Report(diag::err_cannot_open_file) 361 << LinkBCFile << EC.message(); 362 return 0; 363 } 364 LinkModuleToUse = ModuleOrErr.get(); 365 } 366 367 BEConsumer = 368 new BackendConsumer(BA, CI.getDiagnostics(), 369 CI.getCodeGenOpts(), CI.getTargetOpts(), 370 CI.getLangOpts(), 371 CI.getFrontendOpts().ShowTimers, InFile, 372 LinkModuleToUse, OS.take(), *VMContext); 373 return BEConsumer; 374 } 375 376 void CodeGenAction::ExecuteAction() { 377 // If this is an IR file, we have to treat it specially. 378 if (getCurrentFileKind() == IK_LLVM_IR) { 379 BackendAction BA = static_cast<BackendAction>(Act); 380 CompilerInstance &CI = getCompilerInstance(); 381 raw_ostream *OS = GetOutputStream(CI, getCurrentFile(), BA); 382 if (BA != Backend_EmitNothing && !OS) 383 return; 384 385 bool Invalid; 386 SourceManager &SM = CI.getSourceManager(); 387 const llvm::MemoryBuffer *MainFile = SM.getBuffer(SM.getMainFileID(), 388 &Invalid); 389 if (Invalid) 390 return; 391 392 // FIXME: This is stupid, IRReader shouldn't take ownership. 393 llvm::MemoryBuffer *MainFileCopy = 394 llvm::MemoryBuffer::getMemBufferCopy(MainFile->getBuffer(), 395 getCurrentFile()); 396 397 llvm::SMDiagnostic Err; 398 TheModule.reset(ParseIR(MainFileCopy, Err, *VMContext)); 399 if (!TheModule) { 400 // Translate from the diagnostic info to the SourceManager location. 401 SourceLocation Loc = SM.translateFileLineCol( 402 SM.getFileEntryForID(SM.getMainFileID()), Err.getLineNo(), 403 Err.getColumnNo() + 1); 404 405 // Strip off a leading diagnostic code if there is one. 406 StringRef Msg = Err.getMessage(); 407 if (Msg.startswith("error: ")) 408 Msg = Msg.substr(7); 409 410 unsigned DiagID = 411 CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); 412 413 CI.getDiagnostics().Report(Loc, DiagID) << Msg; 414 return; 415 } 416 const TargetOptions &TargetOpts = CI.getTargetOpts(); 417 if (TheModule->getTargetTriple() != TargetOpts.Triple) { 418 unsigned DiagID = CI.getDiagnostics().getCustomDiagID( 419 DiagnosticsEngine::Warning, 420 "overriding the module target triple with %0"); 421 422 CI.getDiagnostics().Report(SourceLocation(), DiagID) << TargetOpts.Triple; 423 TheModule->setTargetTriple(TargetOpts.Triple); 424 } 425 426 EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts, 427 CI.getLangOpts(), CI.getTarget().getTargetDescription(), 428 TheModule.get(), BA, OS); 429 return; 430 } 431 432 // Otherwise follow the normal AST path. 433 this->ASTFrontendAction::ExecuteAction(); 434 } 435 436 // 437 438 void EmitAssemblyAction::anchor() { } 439 EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext) 440 : CodeGenAction(Backend_EmitAssembly, _VMContext) {} 441 442 void EmitBCAction::anchor() { } 443 EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext) 444 : CodeGenAction(Backend_EmitBC, _VMContext) {} 445 446 void EmitLLVMAction::anchor() { } 447 EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext) 448 : CodeGenAction(Backend_EmitLL, _VMContext) {} 449 450 void EmitLLVMOnlyAction::anchor() { } 451 EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext) 452 : CodeGenAction(Backend_EmitNothing, _VMContext) {} 453 454 void EmitCodeGenOnlyAction::anchor() { } 455 EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext) 456 : CodeGenAction(Backend_EmitMCNull, _VMContext) {} 457 458 void EmitObjAction::anchor() { } 459 EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext) 460 : CodeGenAction(Backend_EmitObj, _VMContext) {} 461