27#include "llvm/ADT/iterator.h"
46 assert(RD->isUnion() &&
"RecordType is expected to be a union.");
47 if (
const FieldDecl *FD = RD->findFirstNamedDataMember()) {
48 return FD->getIdentifier();
55struct DecompositionDeclName {
56 using BindingArray = ArrayRef<const BindingDecl*>;
59 BindingArray Bindings;
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) {}
68 return (*this->I)->getIdentifier();
71 Iterator begin()
const {
return Iterator(Bindings.begin()); }
72 Iterator end()
const {
return Iterator(Bindings.end()); }
78struct DenseMapInfo<DecompositionDeclName> {
79 using ArrayInfo = llvm::DenseMapInfo<ArrayRef<const BindingDecl*>>;
81 return llvm::hash_combine_range(Key);
83 static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS) {
84 return LHS.Bindings.size() == RHS.Bindings.size() &&
85 std::equal(LHS.begin(), LHS.end(), RHS.begin());
95 ItaniumMangleContext *Mangler;
96 llvm::StringMap<unsigned> LambdaManglingNumbers;
97 unsigned BlockManglingNumber = 0;
98 llvm::DenseMap<const IdentifierInfo *, unsigned> VarManglingNumbers;
99 llvm::DenseMap<const IdentifierInfo *, unsigned> TagManglingNumbers;
100 llvm::DenseMap<DecompositionDeclName, unsigned>
101 DecompsitionDeclManglingNumbers;
104 ItaniumNumberingContext(ItaniumMangleContext *Mangler) : Mangler(Mangler) {}
106 unsigned getManglingNumber(
const CXXMethodDecl *CallOperator)
override {
107 const CXXRecordDecl *Lambda = CallOperator->
getParent();
112 llvm::SmallString<128> LambdaSig;
113 llvm::raw_svector_ostream
Out(LambdaSig);
114 Mangler->mangleLambdaSig(Lambda, Out);
116 return ++LambdaManglingNumbers[LambdaSig];
119 unsigned getManglingNumber(
const BlockDecl *BD)
override {
120 return ++BlockManglingNumber;
123 unsigned getStaticLocalNumber(
const VarDecl *VD)
override {
128 unsigned getManglingNumber(
const VarDecl *VD,
unsigned)
override {
129 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
130 DecompositionDeclName Name{DD->bindings()};
131 return ++DecompsitionDeclManglingNumbers[Name];
138 Identifier = findAnonymousUnionVarDeclName(*VD);
140 return ++VarManglingNumbers[Identifier];
143 unsigned getManglingNumber(
const TagDecl *TD,
unsigned)
override {
152class ItaniumSYCLNumberingContext :
public ItaniumNumberingContext {
153 llvm::DenseMap<const CXXMethodDecl *, unsigned> ManglingNumbers;
154 using ManglingItr =
decltype(ManglingNumbers)::iterator;
157 ItaniumSYCLNumberingContext(ItaniumMangleContext *Mangler)
158 : ItaniumNumberingContext(Mangler) {}
160 unsigned getManglingNumber(
const CXXMethodDecl *CallOperator)
override {
161 unsigned Number = ItaniumNumberingContext::getManglingNumber(CallOperator);
162 std::pair<ManglingItr, bool> emplace_result =
163 ManglingNumbers.try_emplace(CallOperator, Number);
164 (void)emplace_result;
165 assert(emplace_result.second &&
"Lambda number set multiple times?");
169 using ItaniumNumberingContext::getManglingNumber;
171 unsigned getDeviceManglingNumber(
const CXXMethodDecl *CallOperator)
override {
172 ManglingItr Itr = ManglingNumbers.find(CallOperator);
173 assert(Itr != ManglingNumbers.end() &&
"Lambda not yet mangled?");
179class ItaniumCXXABI :
public CXXABI {
181 std::unique_ptr<MangleContext> Mangler;
185 ItaniumCXXABI(ASTContext &Ctx)
186 : Mangler(Ctx.createMangleContext()), Context(Ctx) {}
189 getMemberPointerInfo(
const MemberPointerType *MPT)
const override {
190 const TargetInfo &
Target = Context.getTargetInfo();
191 TargetInfo::IntType PtrDiff =
Target.getPtrDiffType(LangAS::Default);
192 MemberPointerInfo MPI;
193 MPI.Width =
Target.getTypeWidth(PtrDiff);
194 MPI.Align =
Target.getTypeAlign(PtrDiff);
195 MPI.HasPadding =
false;
201 CallingConv getDefaultMethodCallConv(
bool isVariadic)
const override {
202 const llvm::Triple &T = Context.getTargetInfo().getTriple();
203 if (!isVariadic && T.isWindowsGNUEnvironment() &&
204 T.getArch() == llvm::Triple::x86)
206 return Context.getTargetInfo().getDefaultCallingConv();
211 bool isNearlyEmpty(
const CXXRecordDecl *RD)
const override {
217 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
218 CharUnits PointerSize = Context.toCharUnitsFromBits(
219 Context.getTargetInfo().getPointerWidth(LangAS::Default));
223 const CXXConstructorDecl *
224 getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
override {
228 void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
229 CXXConstructorDecl *CD)
override {}
231 void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
232 TypedefNameDecl *DD)
override {}
234 TypedefNameDecl *getTypedefNameForUnnamedTagDecl(
const TagDecl *TD)
override {
238 void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
239 DeclaratorDecl *DD)
override {}
241 DeclaratorDecl *getDeclaratorForUnnamedTagDecl(
const TagDecl *TD)
override {
245 std::unique_ptr<MangleNumberingContext>
246 createMangleNumberingContext()
const override {
247 if (Context.getLangOpts().isSYCL())
248 return std::make_unique<ItaniumSYCLNumberingContext>(
250 return std::make_unique<ItaniumNumberingContext>(
257 return new ItaniumCXXABI(Ctx);
260std::unique_ptr<MangleNumberingContext>
262 return std::make_unique<ItaniumNumberingContext>(
Defines the clang::ASTContext interface.
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
#define CXXABI(Name, Str)
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
Implements C++ ABI-specific semantic analysis functions.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isLambda() const
Determine whether this class describes a lambda function object.
bool isDynamicClass() const
Represents a member of a struct/union/class.
One of these records is kept for each identifier that is lexed.
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
Keeps track of the mangled names of lambda expressions and block literals within a particular context...
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
RecordDecl * castAsRecordDecl() const
Represents a variable declaration or definition.
Defines the clang::TargetInfo interface.
@ Number
Just a number, nothing else.
The JSON file list parser is used to communicate input to InstallAPI.
std::unique_ptr< MangleNumberingContext > createItaniumNumberingContext(MangleContext *)
CXXABI * CreateItaniumCXXABI(ASTContext &Ctx)
Creates an instance of a C++ ABI class.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
llvm::DenseMapInfo< ArrayRef< const BindingDecl * > > ArrayInfo
static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS)
static unsigned getHashValue(DecompositionDeclName Key)