clang 8.0.0

ItaniumCXXABI.cpp
Go to the documentation of this file.
1 //===------- ItaniumCXXABI.cpp - AST support for the Itanium C++ ABI ------===//
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 // This provides C++ AST support targeting the Itanium C++ ABI, which is
11 // documented at:
12 // http://www.codesourcery.com/public/cxx-abi/abi.html
13 // http://www.codesourcery.com/public/cxx-abi/abi-eh.html
14 //
15 // It also supports the closely-related ARM C++ ABI, documented at:
16 // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
17 //
18 //===----------------------------------------------------------------------===//
19
20 #include "CXXABI.h"
21 #include "clang/AST/ASTContext.h"
22 #include "clang/AST/DeclCXX.h"
23 #include "clang/AST/MangleNumberingContext.h"
24 #include "clang/AST/RecordLayout.h"
25 #include "clang/AST/Type.h"
26 #include "clang/Basic/TargetInfo.h"
27 #include "llvm/ADT/iterator.h"
28
29 using namespace clang;
30
31 namespace {
32
33 /// According to Itanium C++ ABI 5.1.2:
34 /// the name of an anonymous union is considered to be
35 /// the name of the first named data member found by a pre-order,
36 /// depth-first, declaration-order walk of the data members of
37 /// the anonymous union.
38 /// If there is no such data member (i.e., if all of the data members
39 /// in the union are unnamed), then there is no way for a program to
40 /// refer to the anonymous union, and there is therefore no need to mangle its name.
41 ///
42 /// Returns the name of anonymous union VarDecl or nullptr if it is not found.
43 static const IdentifierInfo *findAnonymousUnionVarDeclName(const VarDecl& VD) {
44 const RecordType *RT = VD.getType()->getAs<RecordType>();
45 assert(RT && "type of VarDecl is expected to be RecordType.");
46 assert(RT->getDecl()->isUnion() && "RecordType is expected to be a union.");
47 if (const FieldDecl *FD = RT->getDecl()->findFirstNamedDataMember()) {
48 return FD->getIdentifier();
49 }
50
51 return nullptr;
52 }
53
54 /// The name of a decomposition declaration.
55 struct DecompositionDeclName {
56 using BindingArray = ArrayRef<const BindingDecl*>;
57
58 /// Representative example of a set of bindings with these names.
59 BindingArray Bindings;
60
61 /// Iterators over the sequence of identifiers in the name.
62 struct Iterator
63 : llvm::iterator_adaptor_base<Iterator, BindingArray::const_iterator,
64 std::random_access_iterator_tag,
65 const IdentifierInfo *> {
66 Iterator(BindingArray::const_iterator It) : iterator_adaptor_base(It) {}
67 const IdentifierInfo *operator*() const {
68 return (*this->I)->getIdentifier();
69 }
70 };
71 Iterator begin() const { return Iterator(Bindings.begin()); }
72 Iterator end() const { return Iterator(Bindings.end()); }
73 };
74 }
75
76 namespace llvm {
77 template<>
78 struct DenseMapInfo<DecompositionDeclName> {
79 using ArrayInfo = llvm::DenseMapInfo<ArrayRef<const BindingDecl*>>;
80 using IdentInfo = llvm::DenseMapInfo<const IdentifierInfo*>;
81 static DecompositionDeclName getEmptyKey() {
82 return {ArrayInfo::getEmptyKey()};
83 }
84 static DecompositionDeclName getTombstoneKey() {
85 return {ArrayInfo::getTombstoneKey()};
86 }
87 static unsigned getHashValue(DecompositionDeclName Key) {
88 assert(!isEqual(Key, getEmptyKey()) && !isEqual(Key, getTombstoneKey()));
89 return llvm::hash_combine_range(Key.begin(), Key.end());
90 }
91 static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS) {
92 if (ArrayInfo::isEqual(LHS.Bindings, ArrayInfo::getEmptyKey()))
93 return ArrayInfo::isEqual(RHS.Bindings, ArrayInfo::getEmptyKey());
94 if (ArrayInfo::isEqual(LHS.Bindings, ArrayInfo::getTombstoneKey()))
95 return ArrayInfo::isEqual(RHS.Bindings, ArrayInfo::getTombstoneKey());
96 return LHS.Bindings.size() == RHS.Bindings.size() &&
97 std::equal(LHS.begin(), LHS.end(), RHS.begin());
98 }
99 };
100 }
101
102 namespace {
103
104 /// Keeps track of the mangled names of lambda expressions and block
105 /// literals within a particular context.
106 class ItaniumNumberingContext : public MangleNumberingContext {
107 llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
108 llvm::DenseMap<const IdentifierInfo *, unsigned> VarManglingNumbers;
109 llvm::DenseMap<const IdentifierInfo *, unsigned> TagManglingNumbers;
110 llvm::DenseMap<DecompositionDeclName, unsigned>
111 DecompsitionDeclManglingNumbers;
112
113 public:
114 unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
115 const FunctionProtoType *Proto =
116 CallOperator->getType()->getAs<FunctionProtoType>();
117 ASTContext &Context = CallOperator->getASTContext();
118
119 FunctionProtoType::ExtProtoInfo EPI;
120 EPI.Variadic = Proto->isVariadic();
121 QualType Key =
122 Context.getFunctionType(Context.VoidTy, Proto->getParamTypes(), EPI);
123 Key = Context.getCanonicalType(Key);
124 return ++ManglingNumbers[Key->castAs<FunctionProtoType>()];
125 }
126
127 unsigned getManglingNumber(const BlockDecl *BD) override {
128 const Type *Ty = nullptr;
129 return ++ManglingNumbers[Ty];
130 }
131
132 unsigned getStaticLocalNumber(const VarDecl *VD) override {
133 return 0;
134 }
135
136 /// Variable decls are numbered by identifier.
137 unsigned getManglingNumber(const VarDecl *VD, unsigned) override {
138 if (auto *DD = dyn_cast<DecompositionDecl>(VD)) {
139 DecompositionDeclName Name{DD->bindings()};
140 return ++DecompsitionDeclManglingNumbers[Name];
141 }
142
143 const IdentifierInfo *Identifier = VD->getIdentifier();
144 if (!Identifier) {
145 // VarDecl without an identifier represents an anonymous union
146 // declaration.
147 Identifier = findAnonymousUnionVarDeclName(*VD);
148 }
149 return ++VarManglingNumbers[Identifier];
150 }
151
152 unsigned getManglingNumber(const TagDecl *TD, unsigned) override {
153 return ++TagManglingNumbers[TD->getIdentifier()];
154 }
155 };
156
157 class ItaniumCXXABI : public CXXABI {
158 protected:
159 ASTContext &Context;
160 public:
161 ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { }
162
163 MemberPointerInfo
164 getMemberPointerInfo(const MemberPointerType *MPT) const override {
165 const TargetInfo &Target = Context.getTargetInfo();
166 TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0);
167 MemberPointerInfo MPI;
168 MPI.Width = Target.getTypeWidth(PtrDiff);
169 MPI.Align = Target.getTypeAlign(PtrDiff);
170 MPI.HasPadding = false;
171 if (MPT->isMemberFunctionPointer())
172 MPI.Width *= 2;
173 return MPI;
174 }
175
176 CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
177 const llvm::Triple &T = Context.getTargetInfo().getTriple();
178 if (!isVariadic && T.isWindowsGNUEnvironment() &&
179 T.getArch() == llvm::Triple::x86)
180 return CC_X86ThisCall;
181 return CC_C;
182 }
183
184 // We cheat and just check that the class has a vtable pointer, and that it's
185 // only big enough to have a vtable pointer and nothing more (or less).
186 bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
187
188 // Check that the class has a vtable pointer.
189 if (!RD->isDynamicClass())
190 return false;
191
192 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
193 CharUnits PointerSize =
194 Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
195 return Layout.getNonVirtualSize() == PointerSize;
196 }
197
198 const CXXConstructorDecl *
199 getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
200 return nullptr;
201 }
202
203 void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
204 CXXConstructorDecl *CD) override {}
205
206 void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
207 TypedefNameDecl *DD) override {}
208
209 TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
210 return nullptr;
211 }
212
213 void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
214 DeclaratorDecl *DD) override {}
215
216 DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
217 return nullptr;
218 }
219
220 std::unique_ptr<MangleNumberingContext>
221 createMangleNumberingContext() const override {
222 return llvm::make_unique<ItaniumNumberingContext>();
223 }
224 };
225 }
226
227 CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) {
228 return new ItaniumCXXABI(Ctx);
229 }
ASTContext.h
Defines the clang::ASTContext interface.
clang::TargetInfo::getTypeWidth
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
Definition: TargetInfo.cpp:214
Identifier
StringRef Identifier
Definition: Format.cpp:1636
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:638
llvm
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:30
clang::ASTContext::getASTRecordLayout
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
Definition: RecordLayoutBuilder.cpp:2966
clang::TargetInfo::getTriple
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:953
Type.h
C Language Family Type Representation.
clang::FunctionProtoType::isVariadic
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:4002
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1407
clang::ASTContext::getTargetInfo
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:690
llvm::DenseMapInfo
Definition: TypeOrdering.h:38
clang::CXXConstructorDecl
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2484
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:813
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6748
clang::FunctionProtoType::ExtProtoInfo
Extra information about a function prototype.
Definition: Type.h:3767
clang::MultiVersionKind::Target
clang::NamedDecl::getIdentifier
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
clang::TargetInfo::getPointerWidth
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
Definition: TargetInfo.h:349
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:58
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:155
clang::FunctionProtoType::getParamTypes
ArrayRef< QualType > getParamTypes() const
Definition: Type.h:3895
clang::FieldDecl
Represents a member of a struct/union/class.
Definition: Decl.h:2579
llvm::DenseMapInfo< DecompositionDeclName >::getTombstoneKey
static DecompositionDeclName getTombstoneKey()
Definition: ItaniumCXXABI.cpp:84
operator*
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
Definition: CharUnits.h:208
llvm::DenseMapInfo< DecompositionDeclName >::isEqual
static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS)
Definition: ItaniumCXXABI.cpp:91
clang::CharUnits
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
clang::MangleNumberingContext
Keeps track of the mangled names of lambda expressions and block literals within a particular context...
Definition: MangleNumberingContext.h:32
clang::CreateItaniumCXXABI
CXXABI * CreateItaniumCXXABI(ASTContext &Ctx)
Creates an instance of a C++ ABI class.
Definition: ItaniumCXXABI.cpp:227
llvm::ArrayRef
Definition: LLVM.h:32
llvm::DenseMapInfo< DecompositionDeclName >::getHashValue
static unsigned getHashValue(DecompositionDeclName Key)
Definition: ItaniumCXXABI.cpp:87
clang::FunctionProtoType
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3687
clang::CXXRecordDecl::isDynamicClass
bool isDynamicClass() const
Definition: DeclCXX.h:789
clang::DeclaratorDecl
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:689
clang::CC_X86ThisCall
Definition: Specifiers.h:240
clang::ASTRecordLayout
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:39
clang::TargetInfo
Exposes information about the current target.
Definition: TargetInfo.h:54
clang::BlockDecl
Pepresents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:3858
clang::RecordDecl::findFirstNamedDataMember
const FieldDecl * findFirstNamedDataMember() const
Finds the first data member which has a name.
Definition: Decl.cpp:4237
clang::Type::castAs
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:6811
llvm::DenseMapInfo< DecompositionDeclName >::getEmptyKey
static DecompositionDeclName getEmptyKey()
Definition: ItaniumCXXABI.cpp:81
clang::CXXABI
Implements C++ ABI-specific semantic analysis functions.
Definition: CXXABI.h:30
clang::CallingConv
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:236
clang::TargetInfo::getTypeAlign
unsigned getTypeAlign(IntType T) const
Return the alignment (in bits) of the specified integer type enum.
Definition: TargetInfo.cpp:285
clang::RecordType::getDecl
RecordDecl * getDecl() const
Definition: Type.h:4380
clang::TargetInfo::getPtrDiffType
IntType getPtrDiffType(unsigned AddrSpace) const
Definition: TargetInfo.h:278
clang::QualType::getCanonicalType
QualType getCanonicalType() const
Definition: Type.h:6111
clang::TagDecl
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3064
clang::Decl::getASTContext
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:376
clang::CXXMethodDecl
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2041
clang::TypedefNameDecl
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:2916
clang::TargetInfo::IntType
IntType
===-— Target Data Type Query Methods ----------------------------—===//
Definition: TargetInfo.h:158
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:22
clang::CC_C
Definition: Specifiers.h:237
clang::MemberPointerType
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:2756
clang::RecordType
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4370
clang::ASTContext::toCharUnitsFromBits
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Definition: ASTContext.cpp:2156
DeclCXX.h
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:300
clang::MemberPointerType::isMemberFunctionPointer
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
Definition: Type.h:2780
RecordLayout.h
clang::ASTRecordLayout::getNonVirtualSize
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
Definition: RecordLayout.h:203
TargetInfo.h
Defines the clang::TargetInfo interface.
clang::TagDecl::isUnion
bool isUnion() const
Definition: Decl.h:3252
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:648
clang::FunctionProtoType::ExtProtoInfo::Variadic
bool Variadic
Definition: Type.h:3769
MangleNumberingContext.h
CXXABI.h