2007-05-24 14:29:05 +08:00
|
|
|
//===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2007-05-24 14:29:05 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This builds an AST and converts it to LLVM Code.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/CodeGen/ModuleBuilder.h"
|
2013-07-14 05:08:14 +08:00
|
|
|
#include "CGDebugInfo.h"
|
2014-01-07 19:51:46 +08:00
|
|
|
#include "CodeGenModule.h"
|
2008-02-06 10:01:47 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2008-08-11 12:54:23 +08:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
|
|
|
#include "clang/AST/Expr.h"
|
2018-12-11 11:18:39 +08:00
|
|
|
#include "clang/Basic/CodeGenOptions.h"
|
2008-02-06 10:01:47 +08:00
|
|
|
#include "clang/Basic/Diagnostic.h"
|
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2013-05-08 21:44:39 +08:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2013-01-02 19:45:17 +08:00
|
|
|
#include "llvm/IR/DataLayout.h"
|
|
|
|
#include "llvm/IR/LLVMContext.h"
|
|
|
|
#include "llvm/IR/Module.h"
|
2014-03-09 19:36:40 +08:00
|
|
|
#include <memory>
|
2016-05-18 13:21:18 +08:00
|
|
|
|
2009-03-26 13:00:52 +08:00
|
|
|
using namespace clang;
|
2016-05-18 13:21:18 +08:00
|
|
|
using namespace CodeGen;
|
2008-08-06 02:50:11 +08:00
|
|
|
|
2008-02-06 10:01:47 +08:00
|
|
|
namespace {
|
2009-11-29 03:45:26 +08:00
|
|
|
class CodeGeneratorImpl : public CodeGenerator {
|
2011-09-26 07:23:43 +08:00
|
|
|
DiagnosticsEngine &Diags;
|
2008-02-06 10:01:47 +08:00
|
|
|
ASTContext *Ctx;
|
2015-06-30 10:26:03 +08:00
|
|
|
const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info.
|
|
|
|
const PreprocessorOptions &PreprocessorOpts; // Only used for debug info.
|
2009-11-13 01:24:48 +08:00
|
|
|
const CodeGenOptions CodeGenOpts; // Intentionally copied in.
|
2014-08-02 06:42:16 +08:00
|
|
|
|
|
|
|
unsigned HandlingTopLevelDecls;
|
2016-04-23 02:46:33 +08:00
|
|
|
|
|
|
|
/// 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.
|
2014-08-02 06:42:16 +08:00
|
|
|
struct HandlingTopLevelDeclRAII {
|
|
|
|
CodeGeneratorImpl &Self;
|
2016-04-23 02:46:33 +08:00
|
|
|
bool EmitDeferred;
|
|
|
|
HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
|
|
|
|
bool EmitDeferred = true)
|
|
|
|
: Self(Self), EmitDeferred(EmitDeferred) {
|
2014-08-02 06:42:16 +08:00
|
|
|
++Self.HandlingTopLevelDecls;
|
|
|
|
}
|
|
|
|
~HandlingTopLevelDeclRAII() {
|
2016-04-23 02:46:33 +08:00
|
|
|
unsigned Level = --Self.HandlingTopLevelDecls;
|
|
|
|
if (Level == 0 && EmitDeferred)
|
2014-08-02 06:42:16 +08:00
|
|
|
Self.EmitDeferredDecls();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-08-05 02:41:51 +08:00
|
|
|
CoverageSourceInfo *CoverageInfo;
|
|
|
|
|
2008-02-06 10:01:47 +08:00
|
|
|
protected:
|
2014-03-08 04:03:18 +08:00
|
|
|
std::unique_ptr<llvm::Module> M;
|
|
|
|
std::unique_ptr<CodeGen::CodeGenModule> Builder;
|
|
|
|
|
2014-12-19 03:19:00 +08:00
|
|
|
private:
|
2018-09-19 07:16:30 +08:00
|
|
|
SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
|
2014-12-19 03:19:00 +08:00
|
|
|
|
2019-09-30 23:05:35 +08:00
|
|
|
static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
|
|
|
|
const CodeGenOptions &CGO) {
|
|
|
|
if (ModuleName == "-" && !CGO.MainFileName.empty())
|
|
|
|
return CGO.MainFileName;
|
|
|
|
return ModuleName;
|
|
|
|
}
|
|
|
|
|
2008-02-06 10:01:47 +08:00
|
|
|
public:
|
2016-05-18 13:21:18 +08:00
|
|
|
CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
|
2015-06-30 10:26:03 +08:00
|
|
|
const HeaderSearchOptions &HSO,
|
|
|
|
const PreprocessorOptions &PPO, const CodeGenOptions &CGO,
|
|
|
|
llvm::LLVMContext &C,
|
2014-08-05 02:41:51 +08:00
|
|
|
CoverageSourceInfo *CoverageInfo = nullptr)
|
2015-06-30 10:26:03 +08:00
|
|
|
: Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO),
|
|
|
|
PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
|
2019-09-30 23:05:35 +08:00
|
|
|
CoverageInfo(CoverageInfo),
|
|
|
|
M(new llvm::Module(ExpandModuleName(ModuleName, CGO), C)) {
|
2016-03-14 05:05:23 +08:00
|
|
|
C.setDiscardValueNames(CGO.DiscardValueNames);
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2015-04-11 10:00:23 +08:00
|
|
|
~CodeGeneratorImpl() override {
|
2014-12-20 07:35:11 +08:00
|
|
|
// There should normally not be any leftover inline method definitions.
|
2018-09-19 07:16:30 +08:00
|
|
|
assert(DeferredInlineMemberFuncDefs.empty() ||
|
2014-12-20 07:35:11 +08:00
|
|
|
Diags.hasErrorOccurred());
|
2014-12-19 03:19:00 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-05-18 13:21:18 +08:00
|
|
|
CodeGenModule &CGM() {
|
|
|
|
return *Builder;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Module *GetModule() {
|
2008-10-22 03:55:09 +08:00
|
|
|
return M.get();
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2017-02-10 06:07:24 +08:00
|
|
|
CGDebugInfo *getCGDebugInfo() {
|
|
|
|
return Builder->getModuleDebugInfo();
|
|
|
|
}
|
|
|
|
|
2016-05-18 13:21:18 +08:00
|
|
|
llvm::Module *ReleaseModule() {
|
|
|
|
return M.release();
|
|
|
|
}
|
|
|
|
|
|
|
|
const Decl *GetDeclForMangledName(StringRef MangledName) {
|
2014-06-06 06:10:59 +08:00
|
|
|
GlobalDecl Result;
|
|
|
|
if (!Builder->lookupRepresentativeDecl(MangledName, Result))
|
|
|
|
return nullptr;
|
|
|
|
const Decl *D = Result.getCanonicalDecl().getDecl();
|
|
|
|
if (auto FD = dyn_cast<FunctionDecl>(D)) {
|
|
|
|
if (FD->hasBody(FD))
|
|
|
|
return FD;
|
|
|
|
} else if (auto TD = dyn_cast<TagDecl>(D)) {
|
|
|
|
if (auto Def = TD->getDefinition())
|
|
|
|
return Def;
|
|
|
|
}
|
|
|
|
return D;
|
|
|
|
}
|
|
|
|
|
2021-08-31 00:31:54 +08:00
|
|
|
llvm::StringRef GetMangledName(GlobalDecl GD) {
|
|
|
|
return Builder->getMangledName(GD);
|
|
|
|
}
|
|
|
|
|
2016-05-18 13:21:18 +08:00
|
|
|
llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) {
|
2016-12-01 07:25:13 +08:00
|
|
|
return Builder->GetAddrOfGlobal(global, ForDefinition_t(isForDefinition));
|
2016-05-18 13:21:18 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2017-08-27 18:58:03 +08:00
|
|
|
llvm::Module *StartModule(llvm::StringRef ModuleName,
|
|
|
|
llvm::LLVMContext &C) {
|
|
|
|
assert(!M && "Replacing existing Module?");
|
2019-09-30 23:05:35 +08:00
|
|
|
M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C));
|
2017-08-27 18:58:03 +08:00
|
|
|
Initialize(*Ctx);
|
|
|
|
return M.get();
|
|
|
|
}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void Initialize(ASTContext &Context) override {
|
2008-02-06 10:01:47 +08:00
|
|
|
Ctx = &Context;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-09-02 08:18:52 +08:00
|
|
|
M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
|
2021-04-20 01:39:20 +08:00
|
|
|
M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
|
2018-12-18 03:19:15 +08:00
|
|
|
const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion();
|
|
|
|
if (!SDKVersion.empty())
|
|
|
|
M->setSDKVersion(SDKVersion);
|
2022-02-02 16:19:49 +08:00
|
|
|
if (const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())
|
|
|
|
M->setDarwinTargetVariantTriple(TVT->getTriple());
|
|
|
|
if (auto TVSDKVersion =
|
|
|
|
Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())
|
|
|
|
M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
|
2015-07-25 00:04:29 +08:00
|
|
|
Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts,
|
|
|
|
PreprocessorOpts, CodeGenOpts,
|
|
|
|
*M, Diags, CoverageInfo));
|
2013-08-08 08:17:41 +08:00
|
|
|
|
2016-01-16 08:31:22 +08:00
|
|
|
for (auto &&Lib : CodeGenOpts.DependentLibraries)
|
2016-03-03 01:28:48 +08:00
|
|
|
Builder->AddDependentLib(Lib);
|
2016-01-16 08:31:22 +08:00
|
|
|
for (auto &&Opt : CodeGenOpts.LinkerOptions)
|
2016-03-03 01:28:48 +08:00
|
|
|
Builder->AppendLinkerOptions(Opt);
|
2008-02-06 10:01:47 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
|
2013-08-20 05:02:26 +08:00
|
|
|
if (Diags.hasErrorOccurred())
|
|
|
|
return;
|
|
|
|
|
2012-03-08 23:51:03 +08:00
|
|
|
Builder->HandleCXXStaticMemberVarInstantiation(VD);
|
2012-03-05 18:54:55 +08:00
|
|
|
}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
bool HandleTopLevelDecl(DeclGroupRef DG) override {
|
2013-08-20 05:02:26 +08:00
|
|
|
if (Diags.hasErrorOccurred())
|
|
|
|
return true;
|
|
|
|
|
2014-08-02 06:42:16 +08:00
|
|
|
HandlingTopLevelDeclRAII HandlingDecl(*this);
|
|
|
|
|
2009-01-20 09:17:11 +08:00
|
|
|
// Make sure to emit all elements of a Decl.
|
2009-03-30 00:50:03 +08:00
|
|
|
for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
|
|
|
|
Builder->EmitTopLevelDecl(*I);
|
2014-06-07 01:36:17 +08:00
|
|
|
|
2014-08-02 06:42:16 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EmitDeferredDecls() {
|
2018-09-19 07:16:30 +08:00
|
|
|
if (DeferredInlineMemberFuncDefs.empty())
|
2014-08-14 05:15:09 +08:00
|
|
|
return;
|
|
|
|
|
2014-08-02 04:39:36 +08:00
|
|
|
// Emit any deferred inline method definitions. Note that more deferred
|
|
|
|
// methods may be added during this loop, since ASTConsumer callbacks
|
|
|
|
// can be invoked if AST inspection results in declarations being added.
|
2014-08-14 05:15:09 +08:00
|
|
|
HandlingTopLevelDeclRAII HandlingDecl(*this);
|
2018-09-19 07:16:30 +08:00
|
|
|
for (unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
|
|
|
|
Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
|
|
|
|
DeferredInlineMemberFuncDefs.clear();
|
2008-02-06 10:01:47 +08:00
|
|
|
}
|
2008-08-16 07:26:23 +08:00
|
|
|
|
2016-03-30 14:27:31 +08:00
|
|
|
void HandleInlineFunctionDefinition(FunctionDecl *D) override {
|
2014-05-24 04:37:38 +08:00
|
|
|
if (Diags.hasErrorOccurred())
|
|
|
|
return;
|
|
|
|
|
|
|
|
assert(D->doesThisDeclarationHaveABody());
|
|
|
|
|
2014-06-07 01:36:17 +08:00
|
|
|
// 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,
|
|
|
|
// e.g.
|
|
|
|
// typedef struct {
|
|
|
|
// void bar();
|
|
|
|
// void foo() { bar(); }
|
|
|
|
// } A;
|
2018-09-19 07:16:30 +08:00
|
|
|
DeferredInlineMemberFuncDefs.push_back(D);
|
2014-08-05 02:41:51 +08:00
|
|
|
|
2014-11-18 08:34:46 +08:00
|
|
|
// 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.
|
2018-09-19 07:16:30 +08:00
|
|
|
if (!D->getLexicalDeclContext()->isDependentContext())
|
|
|
|
Builder->AddDeferredUnusedCoverageMapping(D);
|
2014-05-24 04:37:38 +08:00
|
|
|
}
|
|
|
|
|
2008-02-06 12:51:19 +08:00
|
|
|
/// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
|
2009-03-30 00:50:03 +08:00
|
|
|
/// to (e.g. struct, union, enum, class) is completed. This allows the
|
|
|
|
/// client hack on the type, which can occur at any point in the file
|
|
|
|
/// (because these can be defined in declspecs).
|
2014-03-12 14:41:41 +08:00
|
|
|
void HandleTagDeclDefinition(TagDecl *D) override {
|
2013-08-20 05:02:26 +08:00
|
|
|
if (Diags.hasErrorOccurred())
|
|
|
|
return;
|
|
|
|
|
2016-04-23 02:46:33 +08:00
|
|
|
// Don't allow re-entrant calls to CodeGen triggered by PCH
|
|
|
|
// deserialization to emit deferred decls.
|
|
|
|
HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
|
|
|
|
|
2008-02-06 13:08:19 +08:00
|
|
|
Builder->UpdateCompletedType(D);
|
2014-07-18 04:25:23 +08:00
|
|
|
|
|
|
|
// For MSVC compatibility, treat declarations of static data members with
|
|
|
|
// inline initializers as definitions.
|
2015-10-08 12:53:31 +08:00
|
|
|
if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
|
2014-07-18 04:25:23 +08:00
|
|
|
for (Decl *Member : D->decls()) {
|
|
|
|
if (VarDecl *VD = dyn_cast<VarDecl>(Member)) {
|
|
|
|
if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
|
|
|
|
Ctx->DeclMustBeEmitted(VD)) {
|
|
|
|
Builder->EmitGlobal(VD);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-04 17:22:22 +08:00
|
|
|
// 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);
|
2019-08-06 02:43:21 +08:00
|
|
|
} else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Member)) {
|
|
|
|
if (Ctx->DeclMustBeEmitted(DMD))
|
|
|
|
Builder->EmitGlobal(DMD);
|
2016-03-04 17:22:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-02-06 12:51:19 +08:00
|
|
|
}
|
2008-08-08 03:47:41 +08:00
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
|
2013-08-20 05:02:26 +08:00
|
|
|
if (Diags.hasErrorOccurred())
|
|
|
|
return;
|
|
|
|
|
2016-04-23 02:46:33 +08:00
|
|
|
// Don't allow re-entrant calls to CodeGen triggered by PCH
|
|
|
|
// deserialization to emit deferred decls.
|
|
|
|
HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
|
|
|
|
|
2013-07-14 05:08:14 +08:00
|
|
|
if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
|
|
|
|
if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
|
2013-08-16 04:49:17 +08:00
|
|
|
DI->completeRequiredType(RD);
|
2013-07-14 05:08:14 +08:00
|
|
|
}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void HandleTranslationUnit(ASTContext &Ctx) override {
|
2016-01-29 07:29:02 +08:00
|
|
|
// 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.
|
2008-08-08 03:47:41 +08:00
|
|
|
if (Diags.hasErrorOccurred()) {
|
2013-12-09 22:59:08 +08:00
|
|
|
if (Builder)
|
|
|
|
Builder->clear();
|
2008-08-08 03:47:41 +08:00
|
|
|
M.reset();
|
|
|
|
return;
|
|
|
|
}
|
2009-12-20 01:50:07 +08:00
|
|
|
}
|
2009-04-22 01:11:58 +08:00
|
|
|
|
2016-01-27 03:30:26 +08:00
|
|
|
void AssignInheritanceModel(CXXRecordDecl *RD) override {
|
|
|
|
if (Diags.hasErrorOccurred())
|
|
|
|
return;
|
|
|
|
|
|
|
|
Builder->RefreshTypeCacheForClass(RD);
|
|
|
|
}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void CompleteTentativeDefinition(VarDecl *D) override {
|
2009-04-22 01:11:58 +08:00
|
|
|
if (Diags.hasErrorOccurred())
|
|
|
|
return;
|
|
|
|
|
|
|
|
Builder->EmitTentativeDefinition(D);
|
|
|
|
}
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
|
2019-11-23 00:45:37 +08:00
|
|
|
void CompleteExternalDeclaration(VarDecl *D) override {
|
|
|
|
Builder->EmitExternalDeclaration(D);
|
|
|
|
}
|
|
|
|
|
2015-01-15 12:07:35 +08:00
|
|
|
void HandleVTable(CXXRecordDecl *RD) override {
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
if (Diags.hasErrorOccurred())
|
|
|
|
return;
|
|
|
|
|
2015-01-15 12:07:35 +08:00
|
|
|
Builder->EmitVTable(RD);
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
}
|
2008-02-06 10:01:47 +08:00
|
|
|
};
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2007-07-13 13:13:43 +08:00
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void CodeGenerator::anchor() { }
|
|
|
|
|
2016-05-18 13:21:18 +08:00
|
|
|
CodeGenModule &CodeGenerator::CGM() {
|
|
|
|
return static_cast<CodeGeneratorImpl*>(this)->CGM();
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Module *CodeGenerator::GetModule() {
|
|
|
|
return static_cast<CodeGeneratorImpl*>(this)->GetModule();
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Module *CodeGenerator::ReleaseModule() {
|
|
|
|
return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
|
|
|
|
}
|
|
|
|
|
2017-02-10 06:07:24 +08:00
|
|
|
CGDebugInfo *CodeGenerator::getCGDebugInfo() {
|
|
|
|
return static_cast<CodeGeneratorImpl*>(this)->getCGDebugInfo();
|
|
|
|
}
|
|
|
|
|
2016-05-18 13:21:18 +08:00
|
|
|
const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) {
|
|
|
|
return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name);
|
|
|
|
}
|
|
|
|
|
2021-08-31 00:31:54 +08:00
|
|
|
llvm::StringRef CodeGenerator::GetMangledName(GlobalDecl GD) {
|
|
|
|
return static_cast<CodeGeneratorImpl *>(this)->GetMangledName(GD);
|
|
|
|
}
|
|
|
|
|
2016-05-18 13:21:18 +08:00
|
|
|
llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl global,
|
|
|
|
bool isForDefinition) {
|
|
|
|
return static_cast<CodeGeneratorImpl*>(this)
|
|
|
|
->GetAddrOfGlobal(global, isForDefinition);
|
|
|
|
}
|
|
|
|
|
2017-08-27 18:58:03 +08:00
|
|
|
llvm::Module *CodeGenerator::StartModule(llvm::StringRef ModuleName,
|
|
|
|
llvm::LLVMContext &C) {
|
|
|
|
return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C);
|
|
|
|
}
|
|
|
|
|
2015-06-30 10:26:03 +08:00
|
|
|
CodeGenerator *clang::CreateLLVMCodeGen(
|
2016-05-18 13:21:18 +08:00
|
|
|
DiagnosticsEngine &Diags, llvm::StringRef ModuleName,
|
2015-06-30 10:26:03 +08:00
|
|
|
const HeaderSearchOptions &HeaderSearchOpts,
|
|
|
|
const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO,
|
|
|
|
llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo) {
|
|
|
|
return new CodeGeneratorImpl(Diags, ModuleName, HeaderSearchOpts,
|
|
|
|
PreprocessorOpts, CGO, C, CoverageInfo);
|
2008-02-05 16:06:13 +08:00
|
|
|
}
|