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()); }
78 return llvm::DenseMapInfo<T>::isEqual(
79 V, llvm::DenseMapInfo<T>::getEmptyKey());
82 return llvm::DenseMapInfo<T>::isEqual(
83 V, llvm::DenseMapInfo<T>::getTombstoneKey());
90 if (LHSEmpty || RHSEmpty)
91 return LHSEmpty && RHSEmpty;
95 if (LHSTombstone || RHSTombstone)
96 return LHSTombstone && RHSTombstone;
102struct DenseMapInfo<DecompositionDeclName> {
103 using ArrayInfo = llvm::DenseMapInfo<ArrayRef<const BindingDecl*>>;
105 return {ArrayInfo::getEmptyKey()};
108 return {ArrayInfo::getTombstoneKey()};
112 return llvm::hash_combine_range(Key);
114 static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS) {
115 if (std::optional<bool> Result =
119 return LHS.Bindings.size() == RHS.Bindings.size() &&
120 std::equal(LHS.begin(), LHS.end(), RHS.begin());
130 ItaniumMangleContext *Mangler;
131 llvm::StringMap<unsigned> LambdaManglingNumbers;
132 unsigned BlockManglingNumber = 0;
133 llvm::DenseMap<const IdentifierInfo *, unsigned> VarManglingNumbers;
134 llvm::DenseMap<const IdentifierInfo *, unsigned> TagManglingNumbers;
135 llvm::DenseMap<DecompositionDeclName, unsigned>
136 DecompsitionDeclManglingNumbers;
139 ItaniumNumberingContext(ItaniumMangleContext *Mangler) : Mangler(Mangler) {}
141 unsigned getManglingNumber(
const CXXMethodDecl *CallOperator)
override {
142 const CXXRecordDecl *Lambda = CallOperator->
getParent();
147 llvm::SmallString<128> LambdaSig;
148 llvm::raw_svector_ostream
Out(LambdaSig);
149 Mangler->mangleLambdaSig(Lambda, Out);
151 return ++LambdaManglingNumbers[LambdaSig];
154 unsigned getManglingNumber(
const BlockDecl *BD)
override {
155 return ++BlockManglingNumber;
158 unsigned getStaticLocalNumber(
const VarDecl *VD)
override {
163 unsigned getManglingNumber(
const VarDecl *VD,
unsigned)
override {
164 if (
auto *DD = dyn_cast<DecompositionDecl>(VD)) {
165 DecompositionDeclName Name{DD->bindings()};
166 return ++DecompsitionDeclManglingNumbers[Name];
173 Identifier = findAnonymousUnionVarDeclName(*VD);
175 return ++VarManglingNumbers[Identifier];
178 unsigned getManglingNumber(
const TagDecl *TD,
unsigned)
override {
187class ItaniumSYCLNumberingContext :
public ItaniumNumberingContext {
188 llvm::DenseMap<const CXXMethodDecl *, unsigned> ManglingNumbers;
189 using ManglingItr =
decltype(ManglingNumbers)::iterator;
192 ItaniumSYCLNumberingContext(ItaniumMangleContext *Mangler)
193 : ItaniumNumberingContext(Mangler) {}
195 unsigned getManglingNumber(
const CXXMethodDecl *CallOperator)
override {
196 unsigned Number = ItaniumNumberingContext::getManglingNumber(CallOperator);
197 std::pair<ManglingItr, bool> emplace_result =
198 ManglingNumbers.try_emplace(CallOperator, Number);
199 (void)emplace_result;
200 assert(emplace_result.second &&
"Lambda number set multiple times?");
204 using ItaniumNumberingContext::getManglingNumber;
206 unsigned getDeviceManglingNumber(
const CXXMethodDecl *CallOperator)
override {
207 ManglingItr Itr = ManglingNumbers.find(CallOperator);
208 assert(Itr != ManglingNumbers.end() &&
"Lambda not yet mangled?");
214class ItaniumCXXABI :
public CXXABI {
216 std::unique_ptr<MangleContext> Mangler;
220 ItaniumCXXABI(ASTContext &Ctx)
221 : Mangler(Ctx.createMangleContext()), Context(Ctx) {}
224 getMemberPointerInfo(
const MemberPointerType *MPT)
const override {
225 const TargetInfo &
Target = Context.getTargetInfo();
226 TargetInfo::IntType PtrDiff =
Target.getPtrDiffType(LangAS::Default);
227 MemberPointerInfo MPI;
228 MPI.Width =
Target.getTypeWidth(PtrDiff);
229 MPI.Align =
Target.getTypeAlign(PtrDiff);
230 MPI.HasPadding =
false;
236 CallingConv getDefaultMethodCallConv(
bool isVariadic)
const override {
237 const llvm::Triple &
T = Context.getTargetInfo().getTriple();
238 if (!isVariadic &&
T.isWindowsGNUEnvironment() &&
239 T.getArch() == llvm::Triple::x86)
241 return Context.getTargetInfo().getDefaultCallingConv();
246 bool isNearlyEmpty(
const CXXRecordDecl *RD)
const override {
252 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
253 CharUnits PointerSize = Context.toCharUnitsFromBits(
254 Context.getTargetInfo().getPointerWidth(LangAS::Default));
258 const CXXConstructorDecl *
259 getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
override {
263 void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
264 CXXConstructorDecl *CD)
override {}
266 void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
267 TypedefNameDecl *DD)
override {}
269 TypedefNameDecl *getTypedefNameForUnnamedTagDecl(
const TagDecl *TD)
override {
273 void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
274 DeclaratorDecl *DD)
override {}
276 DeclaratorDecl *getDeclaratorForUnnamedTagDecl(
const TagDecl *TD)
override {
280 std::unique_ptr<MangleNumberingContext>
281 createMangleNumberingContext()
const override {
282 if (Context.getLangOpts().isSYCL())
283 return std::make_unique<ItaniumSYCLNumberingContext>(
285 return std::make_unique<ItaniumNumberingContext>(
292 return new ItaniumCXXABI(Ctx);
295std::unique_ptr<MangleNumberingContext>
297 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.
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.
const FunctionProtoType * T
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
static bool isDenseMapKeyTombstone(T V)
static bool isDenseMapKeyEmpty(T V)
static std::optional< bool > areDenseMapKeysEqualSpecialValues(T LHS, T RHS)
llvm::DenseMapInfo< ArrayRef< const BindingDecl * > > ArrayInfo
static DecompositionDeclName getTombstoneKey()
static DecompositionDeclName getEmptyKey()
static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS)
static unsigned getHashValue(DecompositionDeclName Key)