summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/ModuleBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/ModuleBuilder.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/ModuleBuilder.cpp130
1 files changed, 100 insertions, 30 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/ModuleBuilder.cpp b/contrib/llvm/tools/clang/lib/CodeGen/ModuleBuilder.cpp
index 0be5c55..952d162 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/ModuleBuilder.cpp
@@ -25,7 +25,9 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include <memory>
+
using namespace clang;
+using namespace CodeGen;
namespace {
class CodeGeneratorImpl : public CodeGenerator {
@@ -36,13 +38,21 @@ namespace {
const CodeGenOptions CodeGenOpts; // Intentionally copied in.
unsigned HandlingTopLevelDecls;
+
+ /// Use this when emitting decls to block re-entrant decl emission. It will
+ /// emit all deferred decls on scope exit. Set EmitDeferred to false if decl
+ /// emission must be deferred longer, like at the end of a tag definition.
struct HandlingTopLevelDeclRAII {
CodeGeneratorImpl &Self;
- HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self) : Self(Self) {
+ bool EmitDeferred;
+ HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
+ bool EmitDeferred = true)
+ : Self(Self), EmitDeferred(EmitDeferred) {
++Self.HandlingTopLevelDecls;
}
~HandlingTopLevelDeclRAII() {
- if (--Self.HandlingTopLevelDecls == 0)
+ unsigned Level = --Self.HandlingTopLevelDecls;
+ if (Level == 0 && EmitDeferred)
Self.EmitDeferredDecls();
}
};
@@ -57,15 +67,16 @@ namespace {
SmallVector<CXXMethodDecl *, 8> DeferredInlineMethodDefinitions;
public:
- CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string &ModuleName,
+ CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
const HeaderSearchOptions &HSO,
const PreprocessorOptions &PPO, const CodeGenOptions &CGO,
llvm::LLVMContext &C,
CoverageSourceInfo *CoverageInfo = nullptr)
: Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO),
PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
- CoverageInfo(CoverageInfo),
- M(new llvm::Module(ModuleName, C)) {}
+ CoverageInfo(CoverageInfo), M(new llvm::Module(ModuleName, C)) {
+ C.setDiscardValueNames(CGO.DiscardValueNames);
+ }
~CodeGeneratorImpl() override {
// There should normally not be any leftover inline method definitions.
@@ -73,11 +84,19 @@ namespace {
Diags.hasErrorOccurred());
}
- llvm::Module* GetModule() override {
+ CodeGenModule &CGM() {
+ return *Builder;
+ }
+
+ llvm::Module *GetModule() {
return M.get();
}
- const Decl *GetDeclForMangledName(StringRef MangledName) override {
+ llvm::Module *ReleaseModule() {
+ return M.release();
+ }
+
+ const Decl *GetDeclForMangledName(StringRef MangledName) {
GlobalDecl Result;
if (!Builder->lookupRepresentativeDecl(MangledName, Result))
return nullptr;
@@ -92,19 +111,23 @@ namespace {
return D;
}
- llvm::Module *ReleaseModule() override { return M.release(); }
+ llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) {
+ return Builder->GetAddrOfGlobal(global, isForDefinition);
+ }
void Initialize(ASTContext &Context) override {
Ctx = &Context;
M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
- M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
+ M->setDataLayout(Ctx->getTargetInfo().getDataLayout());
Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts,
PreprocessorOpts, CodeGenOpts,
*M, Diags, CoverageInfo));
- for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i < e; ++i)
- HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]);
+ for (auto &&Lib : CodeGenOpts.DependentLibraries)
+ Builder->AddDependentLib(Lib);
+ for (auto &&Opt : CodeGenOpts.LinkerOptions)
+ Builder->AppendLinkerOptions(Opt);
}
void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
@@ -140,12 +163,23 @@ namespace {
DeferredInlineMethodDefinitions.clear();
}
- void HandleInlineMethodDefinition(CXXMethodDecl *D) override {
+ void HandleInlineFunctionDefinition(FunctionDecl *D) override {
if (Diags.hasErrorOccurred())
return;
assert(D->doesThisDeclarationHaveABody());
+ // Handle friend functions.
+ if (D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)) {
+ if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()
+ && !D->getLexicalDeclContext()->isDependentContext())
+ Builder->EmitTopLevelDecl(D);
+ return;
+ }
+
+ // Otherwise, must be a method.
+ auto MD = cast<CXXMethodDecl>(D);
+
// We may want to emit this definition. However, that decision might be
// based on computing the linkage, and we have to defer that in case we
// are inside of something that will change the method's final linkage,
@@ -154,13 +188,13 @@ namespace {
// void bar();
// void foo() { bar(); }
// } A;
- DeferredInlineMethodDefinitions.push_back(D);
+ DeferredInlineMethodDefinitions.push_back(MD);
// Provide some coverage mapping even for methods that aren't emitted.
// Don't do this for templated classes though, as they may not be
// instantiable.
- if (!D->getParent()->getDescribedClassTemplate())
- Builder->AddDeferredUnusedCoverageMapping(D);
+ if (!MD->getParent()->getDescribedClassTemplate())
+ Builder->AddDeferredUnusedCoverageMapping(MD);
}
/// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
@@ -171,6 +205,10 @@ namespace {
if (Diags.hasErrorOccurred())
return;
+ // Don't allow re-entrant calls to CodeGen triggered by PCH
+ // deserialization to emit deferred decls.
+ HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
+
Builder->UpdateCompletedType(D);
// For MSVC compatibility, treat declarations of static data members with
@@ -185,27 +223,50 @@ namespace {
}
}
}
+ // For OpenMP emit declare reduction functions, if required.
+ if (Ctx->getLangOpts().OpenMP) {
+ for (Decl *Member : D->decls()) {
+ if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(Member)) {
+ if (Ctx->DeclMustBeEmitted(DRD))
+ Builder->EmitGlobal(DRD);
+ }
+ }
+ }
}
void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
if (Diags.hasErrorOccurred())
return;
+ // Don't allow re-entrant calls to CodeGen triggered by PCH
+ // deserialization to emit deferred decls.
+ HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
+
if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
DI->completeRequiredType(RD);
}
void HandleTranslationUnit(ASTContext &Ctx) override {
+ // Release the Builder when there is no error.
+ if (!Diags.hasErrorOccurred() && Builder)
+ Builder->Release();
+
+ // If there are errors before or when releasing the Builder, reset
+ // the module to stop here before invoking the backend.
if (Diags.hasErrorOccurred()) {
if (Builder)
Builder->clear();
M.reset();
return;
}
+ }
- if (Builder)
- Builder->Release();
+ void AssignInheritanceModel(CXXRecordDecl *RD) override {
+ if (Diags.hasErrorOccurred())
+ return;
+
+ Builder->RefreshTypeCacheForClass(RD);
}
void CompleteTentativeDefinition(VarDecl *D) override {
@@ -221,26 +282,35 @@ namespace {
Builder->EmitVTable(RD);
}
+ };
+}
- void HandleLinkerOptionPragma(llvm::StringRef Opts) override {
- Builder->AppendLinkerOptions(Opts);
- }
+void CodeGenerator::anchor() { }
- void HandleDetectMismatch(llvm::StringRef Name,
- llvm::StringRef Value) override {
- Builder->AddDetectMismatch(Name, Value);
- }
+CodeGenModule &CodeGenerator::CGM() {
+ return static_cast<CodeGeneratorImpl*>(this)->CGM();
+}
- void HandleDependentLibrary(llvm::StringRef Lib) override {
- Builder->AddDependentLib(Lib);
- }
- };
+llvm::Module *CodeGenerator::GetModule() {
+ return static_cast<CodeGeneratorImpl*>(this)->GetModule();
}
-void CodeGenerator::anchor() { }
+llvm::Module *CodeGenerator::ReleaseModule() {
+ return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
+}
+
+const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) {
+ return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name);
+}
+
+llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl global,
+ bool isForDefinition) {
+ return static_cast<CodeGeneratorImpl*>(this)
+ ->GetAddrOfGlobal(global, isForDefinition);
+}
CodeGenerator *clang::CreateLLVMCodeGen(
- DiagnosticsEngine &Diags, const std::string &ModuleName,
+ DiagnosticsEngine &Diags, llvm::StringRef ModuleName,
const HeaderSearchOptions &HeaderSearchOpts,
const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO,
llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo) {
OpenPOWER on IntegriCloud