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