diff options
author | dim <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
commit | 50b73317314e889cf39c7b1d6cbf419fa7502f22 (patch) | |
tree | be1815eb79b42ff482a8562b13c2dcbf0c5dcbee /lib/CodeGen/CodeGenAction.cpp | |
parent | dc04cb328508e61aad809d9b53b12f9799a00e7d (diff) | |
download | FreeBSD-src-50b73317314e889cf39c7b1d6cbf419fa7502f22.zip FreeBSD-src-50b73317314e889cf39c7b1d6cbf419fa7502f22.tar.gz |
Vendor import of clang trunk r154661:
http://llvm.org/svn/llvm-project/cfe/trunk@r154661
Diffstat (limited to 'lib/CodeGen/CodeGenAction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenAction.cpp | 107 |
1 files changed, 94 insertions, 13 deletions
diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp index 68dd5c9..dd32167 100644 --- a/lib/CodeGen/CodeGenAction.cpp +++ b/lib/CodeGen/CodeGenAction.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "clang/CodeGen/CodeGenAction.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/AST/ASTConsumer.h" @@ -18,9 +19,12 @@ #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/LLVMContext.h" +#include "llvm/Linker.h" #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Support/IRReader.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" @@ -30,6 +34,7 @@ using namespace llvm; namespace clang { class BackendConsumer : public ASTConsumer { + virtual void anchor(); DiagnosticsEngine &Diags; BackendAction Action; const CodeGenOptions &CodeGenOpts; @@ -40,9 +45,9 @@ namespace clang { Timer LLVMIRGeneration; - llvm::OwningPtr<CodeGenerator> Gen; + OwningPtr<CodeGenerator> Gen; - llvm::OwningPtr<llvm::Module> TheModule; + OwningPtr<llvm::Module> TheModule, LinkModule; public: BackendConsumer(BackendAction action, DiagnosticsEngine &_Diags, @@ -50,7 +55,9 @@ namespace clang { const TargetOptions &targetopts, const LangOptions &langopts, bool TimePasses, - const std::string &infile, raw_ostream *OS, + const std::string &infile, + llvm::Module *LinkModule, + raw_ostream *OS, LLVMContext &C) : Diags(_Diags), Action(action), @@ -59,11 +66,17 @@ namespace clang { LangOpts(langopts), AsmOutStream(OS), LLVMIRGeneration("LLVM IR Generation Time"), - Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)) { + Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)), + LinkModule(LinkModule) { llvm::TimePassesIsEnabled = TimePasses; } llvm::Module *takeModule() { return TheModule.take(); } + llvm::Module *takeLinkModule() { return LinkModule.take(); } + + virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { + Gen->HandleCXXStaticMemberVarInstantiation(VD); + } virtual void Initialize(ASTContext &Ctx) { Context = &Ctx; @@ -79,7 +92,7 @@ namespace clang { LLVMIRGeneration.stopTimer(); } - virtual void HandleTopLevelDecl(DeclGroupRef D) { + virtual bool HandleTopLevelDecl(DeclGroupRef D) { PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(), Context->getSourceManager(), "LLVM IR generation of declaration"); @@ -91,6 +104,8 @@ namespace clang { if (llvm::TimePassesIsEnabled) LLVMIRGeneration.stopTimer(); + + return true; } virtual void HandleTranslationUnit(ASTContext &C) { @@ -111,7 +126,7 @@ namespace clang { // Make sure IR generation is happy with the module. This is released by // the module provider. - Module *M = Gen->ReleaseModule(); + llvm::Module *M = Gen->ReleaseModule(); if (!M) { // The module has been released by IR gen on failures, do not double // free. @@ -122,6 +137,17 @@ namespace clang { assert(TheModule.get() == M && "Unexpected module change during IR generation"); + // Link LinkModule into this module if present, preserving its validity. + if (LinkModule) { + std::string ErrorMsg; + if (Linker::LinkModules(M, LinkModule.get(), Linker::PreserveSource, + &ErrorMsg)) { + Diags.Report(diag::err_fe_cannot_link_module) + << LinkModule->getModuleIdentifier() << ErrorMsg; + return; + } + } + // Install an inline asm handler so that diagnostics get printed through // our diagnostics hooks. LLVMContext &Ctx = TheModule->getContext(); @@ -160,6 +186,8 @@ namespace clang { void InlineAsmDiagHandler2(const llvm::SMDiagnostic &, SourceLocation LocCookie); }; + + void BackendConsumer::anchor() {} } /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr @@ -215,8 +243,17 @@ void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D, if (LocCookie.isValid()) { Diags.Report(LocCookie, diag::err_fe_inline_asm).AddString(Message); - if (D.getLoc().isValid()) - Diags.Report(Loc, diag::note_fe_inline_asm_here); + if (D.getLoc().isValid()) { + DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here); + // Convert the SMDiagnostic ranges into SourceRange and attach them + // to the diagnostic. + for (unsigned i = 0, e = D.getRanges().size(); i != e; ++i) { + std::pair<unsigned, unsigned> Range = D.getRanges()[i]; + unsigned Column = D.getColumnNo(); + B << SourceRange(Loc.getLocWithOffset(Range.first - Column), + Loc.getLocWithOffset(Range.second - Column)); + } + } return; } @@ -229,7 +266,8 @@ void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D, // CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext) - : Act(_Act), VMContext(_VMContext ? _VMContext : new LLVMContext), + : Act(_Act), LinkModule(0), + VMContext(_VMContext ? _VMContext : new LLVMContext), OwnsVMContext(!_VMContext) {} CodeGenAction::~CodeGenAction() { @@ -245,6 +283,10 @@ void CodeGenAction::EndSourceFileAction() { if (!getCompilerInstance().hasASTConsumer()) return; + // If we were given a link module, release consumer's ownership of it. + if (LinkModule) + BEConsumer->takeLinkModule(); + // Steal the module from the consumer. TheModule.reset(BEConsumer->takeModule()); } @@ -281,16 +323,40 @@ static raw_ostream *GetOutputStream(CompilerInstance &CI, ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { BackendAction BA = static_cast<BackendAction>(Act); - llvm::OwningPtr<raw_ostream> OS(GetOutputStream(CI, InFile, BA)); + OwningPtr<raw_ostream> OS(GetOutputStream(CI, InFile, BA)); if (BA != Backend_EmitNothing && !OS) return 0; + llvm::Module *LinkModuleToUse = LinkModule; + + // If we were not given a link module, and the user requested that one be + // loaded from bitcode, do so now. + const std::string &LinkBCFile = CI.getCodeGenOpts().LinkBitcodeFile; + if (!LinkModuleToUse && !LinkBCFile.empty()) { + std::string ErrorStr; + + llvm::MemoryBuffer *BCBuf = + CI.getFileManager().getBufferForFile(LinkBCFile, &ErrorStr); + if (!BCBuf) { + CI.getDiagnostics().Report(diag::err_cannot_open_file) + << LinkBCFile << ErrorStr; + return 0; + } + + LinkModuleToUse = getLazyBitcodeModule(BCBuf, *VMContext, &ErrorStr); + if (!LinkModuleToUse) { + CI.getDiagnostics().Report(diag::err_cannot_open_file) + << LinkBCFile << ErrorStr; + return 0; + } + } + BEConsumer = new BackendConsumer(BA, CI.getDiagnostics(), CI.getCodeGenOpts(), CI.getTargetOpts(), CI.getLangOpts(), - CI.getFrontendOpts().ShowTimers, InFile, OS.take(), - *VMContext); + CI.getFrontendOpts().ShowTimers, InFile, + LinkModuleToUse, OS.take(), *VMContext); return BEConsumer; } @@ -328,8 +394,17 @@ void CodeGenAction::ExecuteAction() { StringRef Msg = Err.getMessage(); if (Msg.startswith("error: ")) Msg = Msg.substr(7); + + // Escape '%', which is interpreted as a format character. + llvm::SmallString<128> EscapedMessage; + for (unsigned i = 0, e = Msg.size(); i != e; ++i) { + if (Msg[i] == '%') + EscapedMessage += '%'; + EscapedMessage += Msg[i]; + } + unsigned DiagID = CI.getDiagnostics().getCustomDiagID( - DiagnosticsEngine::Error, Msg); + DiagnosticsEngine::Error, EscapedMessage); CI.getDiagnostics().Report(Loc, DiagID); return; @@ -348,20 +423,26 @@ void CodeGenAction::ExecuteAction() { // +void EmitAssemblyAction::anchor() { } EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext) : CodeGenAction(Backend_EmitAssembly, _VMContext) {} +void EmitBCAction::anchor() { } EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext) : CodeGenAction(Backend_EmitBC, _VMContext) {} +void EmitLLVMAction::anchor() { } EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext) : CodeGenAction(Backend_EmitLL, _VMContext) {} +void EmitLLVMOnlyAction::anchor() { } EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext) : CodeGenAction(Backend_EmitNothing, _VMContext) {} +void EmitCodeGenOnlyAction::anchor() { } EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext) : CodeGenAction(Backend_EmitMCNull, _VMContext) {} +void EmitObjAction::anchor() { } EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext) : CodeGenAction(Backend_EmitObj, _VMContext) {} |