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 TheModule.get(), Action, AsmOutStream); 154 155 Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); 156 } 157 158 virtual void HandleTagDeclDefinition(TagDecl *D) { 159 PrettyStackTraceDecl CrashInfo(D, SourceLocation(), 160 Context->getSourceManager(), 161 "LLVM IR generation of declaration"); 162 Gen->HandleTagDeclDefinition(D); 163 } 164 165 virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) { 166 Gen->HandleTagDeclRequiredDefinition(D); 167 } 168 169 virtual void CompleteTentativeDefinition(VarDecl *D) { 170 Gen->CompleteTentativeDefinition(D); 171 } 172 173 virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) { 174 Gen->HandleVTable(RD, DefinitionRequired); 175 } 176 177 virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) { 178 Gen->HandleLinkerOptionPragma(Opts); 179 } 180 181 virtual void HandleDetectMismatch(llvm::StringRef Name, 182 llvm::StringRef Value) { 183 Gen->HandleDetectMismatch(Name, Value); 184 } 185 186 virtual void HandleDependentLibrary(llvm::StringRef Opts) { 187 Gen->HandleDependentLibrary(Opts); 188 } 189 190 static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context, 191 unsigned LocCookie) { 192 SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie); 193 ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc); 194 } 195 196 void InlineAsmDiagHandler2(const llvm::SMDiagnostic &, 197 SourceLocation LocCookie); 198 }; 199 200 void BackendConsumer::anchor() {} 201 } 202 203 /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr 204 /// buffer to be a valid FullSourceLoc. 205 static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D, 206 SourceManager &CSM) { 207 // Get both the clang and llvm source managers. The location is relative to 208 // a memory buffer that the LLVM Source Manager is handling, we need to add 209 // a copy to the Clang source manager. 210 const llvm::SourceMgr &LSM = *D.getSourceMgr(); 211 212 // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr 213 // already owns its one and clang::SourceManager wants to own its one. 214 const MemoryBuffer *LBuf = 215 LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc())); 216 217 // Create the copy and transfer ownership to clang::SourceManager. 218 llvm::MemoryBuffer *CBuf = 219 llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(), 220 LBuf->getBufferIdentifier()); 221 FileID FID = CSM.createFileIDForMemBuffer(CBuf); 222 223 // Translate the offset into the file. 224 unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); 225 SourceLocation NewLoc = 226 CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset); 227 return FullSourceLoc(NewLoc, CSM); 228 } 229 230 231 /// InlineAsmDiagHandler2 - This function is invoked when the backend hits an 232 /// error parsing inline asm. The SMDiagnostic indicates the error relative to 233 /// the temporary memory buffer that the inline asm parser has set up. 234 void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D, 235 SourceLocation LocCookie) { 236 // There are a couple of different kinds of errors we could get here. First, 237 // we re-format the SMDiagnostic in terms of a clang diagnostic. 238 239 // Strip "error: " off the start of the message string. 240 StringRef Message = D.getMessage(); 241 if (Message.startswith("error: ")) 242 Message = Message.substr(7); 243 244 // If the SMDiagnostic has an inline asm source location, translate it. 245 FullSourceLoc Loc; 246 if (D.getLoc() != SMLoc()) 247 Loc = ConvertBackendLocation(D, Context->getSourceManager()); 248 249 250 // If this problem has clang-level source location information, report the 251 // issue as being an error in the source with a note showing the instantiated 252 // code. 253 if (LocCookie.isValid()) { 254 Diags.Report(LocCookie, diag::err_fe_inline_asm).AddString(Message); 255 256 if (D.getLoc().isValid()) { 257 DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here); 258 // Convert the SMDiagnostic ranges into SourceRange and attach them 259 // to the diagnostic. 260 for (unsigned i = 0, e = D.getRanges().size(); i != e; ++i) { 261 std::pair<unsigned, unsigned> Range = D.getRanges()[i]; 262 unsigned Column = D.getColumnNo(); 263 B << SourceRange(Loc.getLocWithOffset(Range.first - Column), 264 Loc.getLocWithOffset(Range.second - Column)); 265 } 266 } 267 return; 268 } 269 270 // Otherwise, report the backend error as occurring in the generated .s file. 271 // If Loc is invalid, we still need to report the error, it just gets no 272 // location info. 273 Diags.Report(Loc, diag::err_fe_inline_asm).AddString(Message); 274 } 275 276 // 277 278 CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext) 279 : Act(_Act), LinkModule(0), 280 VMContext(_VMContext ? _VMContext : new LLVMContext), 281 OwnsVMContext(!_VMContext) {} 282 283 CodeGenAction::~CodeGenAction() { 284 TheModule.reset(); 285 if (OwnsVMContext) 286 delete VMContext; 287 } 288 289 bool CodeGenAction::hasIRSupport() const { return true; } 290 291 void CodeGenAction::EndSourceFileAction() { 292 // If the consumer creation failed, do nothing. 293 if (!getCompilerInstance().hasASTConsumer()) 294 return; 295 296 // If we were given a link module, release consumer's ownership of it. 297 if (LinkModule) 298 BEConsumer->takeLinkModule(); 299 300 // Steal the module from the consumer. 301 TheModule.reset(BEConsumer->takeModule()); 302 } 303 304 llvm::Module *CodeGenAction::takeModule() { 305 return TheModule.take(); 306 } 307 308 llvm::LLVMContext *CodeGenAction::takeLLVMContext() { 309 OwnsVMContext = false; 310 return VMContext; 311 } 312 313 static raw_ostream *GetOutputStream(CompilerInstance &CI, 314 StringRef InFile, 315 BackendAction Action) { 316 switch (Action) { 317 case Backend_EmitAssembly: 318 return CI.createDefaultOutputFile(false, InFile, "s"); 319 case Backend_EmitLL: 320 return CI.createDefaultOutputFile(false, InFile, "ll"); 321 case Backend_EmitBC: 322 return CI.createDefaultOutputFile(true, InFile, "bc"); 323 case Backend_EmitNothing: 324 return 0; 325 case Backend_EmitMCNull: 326 case Backend_EmitObj: 327 return CI.createDefaultOutputFile(true, InFile, "o"); 328 } 329 330 llvm_unreachable("Invalid action!"); 331 } 332 333 ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, 334 StringRef InFile) { 335 BackendAction BA = static_cast<BackendAction>(Act); 336 OwningPtr<raw_ostream> OS(GetOutputStream(CI, InFile, BA)); 337 if (BA != Backend_EmitNothing && !OS) 338 return 0; 339 340 llvm::Module *LinkModuleToUse = LinkModule; 341 342 // If we were not given a link module, and the user requested that one be 343 // loaded from bitcode, do so now. 344 const std::string &LinkBCFile = CI.getCodeGenOpts().LinkBitcodeFile; 345 if (!LinkModuleToUse && !LinkBCFile.empty()) { 346 std::string ErrorStr; 347 348 llvm::MemoryBuffer *BCBuf = 349 CI.getFileManager().getBufferForFile(LinkBCFile, &ErrorStr); 350 if (!BCBuf) { 351 CI.getDiagnostics().Report(diag::err_cannot_open_file) 352 << LinkBCFile << ErrorStr; 353 return 0; 354 } 355 356 LinkModuleToUse = getLazyBitcodeModule(BCBuf, *VMContext, &ErrorStr); 357 if (!LinkModuleToUse) { 358 CI.getDiagnostics().Report(diag::err_cannot_open_file) 359 << LinkBCFile << ErrorStr; 360 return 0; 361 } 362 } 363 364 BEConsumer = 365 new BackendConsumer(BA, CI.getDiagnostics(), 366 CI.getCodeGenOpts(), CI.getTargetOpts(), 367 CI.getLangOpts(), 368 CI.getFrontendOpts().ShowTimers, InFile, 369 LinkModuleToUse, OS.take(), *VMContext); 370 return BEConsumer; 371 } 372 373 void CodeGenAction::ExecuteAction() { 374 // If this is an IR file, we have to treat it specially. 375 if (getCurrentFileKind() == IK_LLVM_IR) { 376 BackendAction BA = static_cast<BackendAction>(Act); 377 CompilerInstance &CI = getCompilerInstance(); 378 raw_ostream *OS = GetOutputStream(CI, getCurrentFile(), BA); 379 if (BA != Backend_EmitNothing && !OS) 380 return; 381 382 bool Invalid; 383 SourceManager &SM = CI.getSourceManager(); 384 const llvm::MemoryBuffer *MainFile = SM.getBuffer(SM.getMainFileID(), 385 &Invalid); 386 if (Invalid) 387 return; 388 389 // FIXME: This is stupid, IRReader shouldn't take ownership. 390 llvm::MemoryBuffer *MainFileCopy = 391 llvm::MemoryBuffer::getMemBufferCopy(MainFile->getBuffer(), 392 getCurrentFile()); 393 394 llvm::SMDiagnostic Err; 395 TheModule.reset(ParseIR(MainFileCopy, Err, *VMContext)); 396 if (!TheModule) { 397 // Translate from the diagnostic info to the SourceManager location. 398 SourceLocation Loc = SM.translateFileLineCol( 399 SM.getFileEntryForID(SM.getMainFileID()), Err.getLineNo(), 400 Err.getColumnNo() + 1); 401 402 // Get a custom diagnostic for the error. We strip off a leading 403 // diagnostic code if there is one. 404 StringRef Msg = Err.getMessage(); 405 if (Msg.startswith("error: ")) 406 Msg = Msg.substr(7); 407 408 // Escape '%', which is interpreted as a format character. 409 SmallString<128> EscapedMessage; 410 for (unsigned i = 0, e = Msg.size(); i != e; ++i) { 411 if (Msg[i] == '%') 412 EscapedMessage += '%'; 413 EscapedMessage += Msg[i]; 414 } 415 416 unsigned DiagID = CI.getDiagnostics().getCustomDiagID( 417 DiagnosticsEngine::Error, EscapedMessage); 418 419 CI.getDiagnostics().Report(Loc, DiagID); 420 return; 421 } 422 423 EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), 424 CI.getTargetOpts(), CI.getLangOpts(), 425 TheModule.get(), 426 BA, OS); 427 return; 428 } 429 430 // Otherwise follow the normal AST path. 431 this->ASTFrontendAction::ExecuteAction(); 432 } 433 434 // 435 436 void EmitAssemblyAction::anchor() { } 437 EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext) 438 : CodeGenAction(Backend_EmitAssembly, _VMContext) {} 439 440 void EmitBCAction::anchor() { } 441 EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext) 442 : CodeGenAction(Backend_EmitBC, _VMContext) {} 443 444 void EmitLLVMAction::anchor() { } 445 EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext) 446 : CodeGenAction(Backend_EmitLL, _VMContext) {} 447 448 void EmitLLVMOnlyAction::anchor() { } 449 EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext) 450 : CodeGenAction(Backend_EmitNothing, _VMContext) {} 451 452 void EmitCodeGenOnlyAction::anchor() { } 453 EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext) 454 : CodeGenAction(Backend_EmitMCNull, _VMContext) {} 455 456 void EmitObjAction::anchor() { } 457 EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext) 458 : CodeGenAction(Backend_EmitObj, _VMContext) {} 459