2011-03-27 17:00:25 +08:00
|
|
|
//===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- C++ -*-===//
|
2009-10-12 06:13:54 +08:00
|
|
|
//
|
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
|
2009-10-12 06:13:54 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This contains code dealing with C++ code generation of virtual tables.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-08-14 00:25:19 +08:00
|
|
|
#ifndef LLVM_CLANG_LIB_CODEGEN_CGVTABLES_H
|
|
|
|
#define LLVM_CLANG_LIB_CODEGEN_CGVTABLES_H
|
2009-10-12 06:13:54 +08:00
|
|
|
|
2011-09-26 09:56:16 +08:00
|
|
|
#include "clang/AST/BaseSubobject.h"
|
2011-03-24 09:21:01 +08:00
|
|
|
#include "clang/AST/CharUnits.h"
|
2011-06-14 12:02:39 +08:00
|
|
|
#include "clang/AST/GlobalDecl.h"
|
2011-09-26 09:57:12 +08:00
|
|
|
#include "clang/AST/VTableBuilder.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/Basic/ABI.h"
|
|
|
|
#include "llvm/ADT/DenseMap.h"
|
2013-01-02 19:45:17 +08:00
|
|
|
#include "llvm/IR/GlobalVariable.h"
|
2009-10-12 06:13:54 +08:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
class CXXRecordDecl;
|
2009-11-26 21:09:03 +08:00
|
|
|
|
2009-10-12 06:13:54 +08:00
|
|
|
namespace CodeGen {
|
|
|
|
class CodeGenModule;
|
2016-11-29 06:18:33 +08:00
|
|
|
class ConstantArrayBuilder;
|
2016-12-14 04:40:39 +08:00
|
|
|
class ConstantStructBuilder;
|
2009-11-26 10:32:05 +08:00
|
|
|
|
2011-09-26 09:56:30 +08:00
|
|
|
class CodeGenVTables {
|
|
|
|
CodeGenModule &CGM;
|
|
|
|
|
2014-02-06 01:27:08 +08:00
|
|
|
VTableContextBase *VTContext;
|
|
|
|
|
2010-03-26 11:56:54 +08:00
|
|
|
/// VTableAddressPointsMapTy - Address points for a single vtable.
|
2016-12-14 04:40:39 +08:00
|
|
|
typedef VTableLayout::AddressPointsMapTy VTableAddressPointsMapTy;
|
2010-03-26 11:56:54 +08:00
|
|
|
|
2011-09-26 09:56:41 +08:00
|
|
|
typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy;
|
2010-05-03 08:55:11 +08:00
|
|
|
typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2010-03-26 12:23:58 +08:00
|
|
|
/// SubVTTIndicies - Contains indices into the various sub-VTTs.
|
|
|
|
SubVTTIndiciesMapTy SubVTTIndicies;
|
|
|
|
|
2010-05-03 08:55:11 +08:00
|
|
|
typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t>
|
2010-03-26 12:23:58 +08:00
|
|
|
SecondaryVirtualPointerIndicesMapTy;
|
|
|
|
|
|
|
|
/// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer
|
|
|
|
/// indices.
|
|
|
|
SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
|
2010-01-02 09:01:18 +08:00
|
|
|
|
2016-09-08 09:14:39 +08:00
|
|
|
/// Cache for the pure virtual member call function.
|
|
|
|
llvm::Constant *PureVirtualFn = nullptr;
|
|
|
|
|
|
|
|
/// Cache for the deleted virtual member call function.
|
|
|
|
llvm::Constant *DeletedVirtualFn = nullptr;
|
|
|
|
|
[MS] Emit vftable thunks for functions with incomplete prototypes
Summary:
The following class hierarchy requires that we be able to emit a
this-adjusting thunk for B::foo in C's vftable:
struct Incomplete;
struct A {
virtual A* foo(Incomplete p) = 0;
};
struct B : virtual A {
void foo(Incomplete p) override;
};
struct C : B { int c; };
This TU is valid, but lacks a definition of 'Incomplete', which makes it
hard to build a thunk for the final overrider, B::foo.
Before this change, Clang gives up attempting to emit the thunk, because
it assumes that if the parameter types are incomplete, it must be
emitting the thunk for optimization purposes. This is untrue for the MS
ABI, where the implementation of B::foo has no idea what thunks C's
vftable may require. Clang needs to emit the thunk without necessarily
having access to the complete prototype of foo.
This change makes Clang emit a musttail variadic call when it needs such
a thunk. I call these "unprototyped" thunks, because they only prototype
the "this" parameter, which must always come first in the MS C++ ABI.
These thunks work, but they create ugly LLVM IR. If the call to the
thunk is devirtualized, it will be a call to a bitcast of a function
pointer. Today, LLVM cannot inline through such a call, but I want to
address that soon, because we also use this pattern for virtual member
pointer thunks.
This change also implements an old FIXME in the code about reusing the
thunk's computed CGFunctionInfo as much as possible. Now we don't end up
computing the thunk's mangled name and arranging it's prototype up to
around three times.
Fixes PR25641
Reviewers: rjmccall, rsmith, hans
Subscribers: Prazek, cfe-commits
Differential Revision: https://reviews.llvm.org/D45112
llvm-svn: 329009
2018-04-03 04:20:33 +08:00
|
|
|
/// Get the address of a thunk and emit it if necessary.
|
|
|
|
llvm::Constant *maybeEmitThunk(GlobalDecl GD,
|
|
|
|
const ThunkInfo &ThunkAdjustments,
|
|
|
|
bool ForVTable);
|
2011-02-07 02:31:40 +08:00
|
|
|
|
2016-11-29 06:18:33 +08:00
|
|
|
void addVTableComponent(ConstantArrayBuilder &builder,
|
2020-06-12 02:17:08 +08:00
|
|
|
const VTableLayout &layout, unsigned componentIndex,
|
|
|
|
llvm::Constant *rtti, unsigned &nextVTableThunkIndex,
|
|
|
|
unsigned vtableAddressPoint,
|
|
|
|
bool vtableHasLocalLinkage);
|
|
|
|
|
|
|
|
/// Add a 32-bit offset to a component relative to the vtable when using the
|
|
|
|
/// relative vtables ABI. The array builder points to the start of the vtable.
|
|
|
|
void addRelativeComponent(ConstantArrayBuilder &builder,
|
|
|
|
llvm::Constant *component,
|
|
|
|
unsigned vtableAddressPoint,
|
|
|
|
bool vtableHasLocalLinkage,
|
|
|
|
bool isCompleteDtor) const;
|
|
|
|
|
|
|
|
/// Create a dso_local stub that will be used for a relative reference in the
|
|
|
|
/// relative vtable layout. This stub will just be a tail call to the original
|
|
|
|
/// function and propagate any function attributes from the original. If the
|
|
|
|
/// original function is already dso_local, the original is returned instead
|
|
|
|
/// and a stub is not created.
|
|
|
|
llvm::Function *
|
|
|
|
getOrCreateRelativeStub(llvm::Function *func,
|
|
|
|
llvm::GlobalValue::LinkageTypes stubLinkage,
|
|
|
|
bool isCompleteDtor) const;
|
|
|
|
|
|
|
|
bool useRelativeLayout() const;
|
|
|
|
|
|
|
|
llvm::Type *getVTableComponentType() const;
|
2016-09-08 09:14:39 +08:00
|
|
|
|
2013-09-27 22:48:01 +08:00
|
|
|
public:
|
2016-11-29 06:18:33 +08:00
|
|
|
/// Add vtable components for the given vtable layout to the given
|
|
|
|
/// global initializer.
|
2016-12-14 04:40:39 +08:00
|
|
|
void createVTableInitializer(ConstantStructBuilder &builder,
|
2020-06-12 02:17:08 +08:00
|
|
|
const VTableLayout &layout, llvm::Constant *rtti,
|
|
|
|
bool vtableHasLocalLinkage);
|
2010-03-26 11:56:54 +08:00
|
|
|
|
2011-09-26 09:56:30 +08:00
|
|
|
CodeGenVTables(CodeGenModule &CGM);
|
|
|
|
|
2013-12-21 07:58:52 +08:00
|
|
|
ItaniumVTableContext &getItaniumVTableContext() {
|
2014-02-06 01:27:08 +08:00
|
|
|
return *cast<ItaniumVTableContext>(VTContext);
|
2013-12-21 07:58:52 +08:00
|
|
|
}
|
2009-10-12 06:13:54 +08:00
|
|
|
|
2013-11-05 23:54:58 +08:00
|
|
|
MicrosoftVTableContext &getMicrosoftVTableContext() {
|
2014-02-06 01:27:08 +08:00
|
|
|
return *cast<MicrosoftVTableContext>(VTContext);
|
2013-11-05 23:54:58 +08:00
|
|
|
}
|
2013-08-21 14:25:03 +08:00
|
|
|
|
2010-01-02 09:01:18 +08:00
|
|
|
/// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
|
|
|
|
/// given record decl.
|
2010-05-03 07:53:25 +08:00
|
|
|
uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2010-03-26 12:23:58 +08:00
|
|
|
/// getSecondaryVirtualPointerIndex - Return the index in the VTT where the
|
|
|
|
/// virtual pointer for the given subobject is located.
|
|
|
|
uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
|
|
|
|
BaseSubobject Base);
|
|
|
|
|
2018-07-31 03:24:48 +08:00
|
|
|
/// GenerateConstructionVTable - Generate a construction vtable for the given
|
2010-03-25 08:35:49 +08:00
|
|
|
/// base subobject.
|
|
|
|
llvm::GlobalVariable *
|
2018-07-31 03:24:48 +08:00
|
|
|
GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base,
|
|
|
|
bool BaseIsVirtual,
|
2011-03-27 17:00:25 +08:00
|
|
|
llvm::GlobalVariable::LinkageTypes Linkage,
|
2010-03-26 11:56:54 +08:00
|
|
|
VTableAddressPointsMapTy& AddressPoints);
|
2011-01-30 03:16:51 +08:00
|
|
|
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2014-06-03 02:50:54 +08:00
|
|
|
/// GetAddrOfVTT - Get the address of the VTT for the given record decl.
|
2011-01-30 03:16:51 +08:00
|
|
|
llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD);
|
|
|
|
|
|
|
|
/// EmitVTTDefinition - Emit the definition of the given vtable.
|
|
|
|
void EmitVTTDefinition(llvm::GlobalVariable *VTT,
|
|
|
|
llvm::GlobalVariable::LinkageTypes Linkage,
|
|
|
|
const CXXRecordDecl *RD);
|
2010-03-10 10:19:29 +08:00
|
|
|
|
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
|
|
|
/// EmitThunks - Emit the associated thunks for the given global decl.
|
|
|
|
void EmitThunks(GlobalDecl GD);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2013-01-26 06:31:03 +08:00
|
|
|
/// GenerateClassData - Generate all the class data required to be
|
|
|
|
/// generated upon definition of a KeyFunction. This includes the
|
|
|
|
/// vtable, the RTTI data structure (if RTTI is enabled) and the VTT
|
|
|
|
/// (if the class has virtual bases).
|
|
|
|
void GenerateClassData(const CXXRecordDecl *RD);
|
|
|
|
|
|
|
|
bool isVTableExternal(const CXXRecordDecl *RD);
|
2016-12-14 04:40:39 +08:00
|
|
|
|
|
|
|
/// Returns the type of a vtable with the given layout. Normally a struct of
|
|
|
|
/// arrays of pointers, with one struct element for each vtable in the vtable
|
|
|
|
/// group.
|
|
|
|
llvm::Type *getVTableType(const VTableLayout &layout);
|
2020-06-12 02:17:08 +08:00
|
|
|
|
|
|
|
/// Generate a public facing alias for the vtable and make the vtable either
|
|
|
|
/// hidden or private. The alias will have the original linkage and visibility
|
|
|
|
/// of the vtable. This is used for cases under the relative vtables ABI
|
|
|
|
/// when a vtable may not be dso_local.
|
|
|
|
void GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable,
|
|
|
|
llvm::StringRef AliasNameRef);
|
2009-10-12 06:13:54 +08:00
|
|
|
};
|
2009-11-26 21:09:03 +08:00
|
|
|
|
2010-01-14 10:29:07 +08:00
|
|
|
} // end namespace CodeGen
|
|
|
|
} // end namespace clang
|
2009-10-12 06:13:54 +08:00
|
|
|
#endif
|