Index: clang/include/clang/AST/GlobalDecl.h =================================================================== --- clang/include/clang/AST/GlobalDecl.h +++ clang/include/clang/AST/GlobalDecl.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_GLOBALDECL_H #define LLVM_CLANG_AST_GLOBALDECL_H +#include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclOpenMP.h" @@ -33,6 +34,11 @@ AtExit, }; +enum class HIPKernelKind : unsigned { + Kernel = 0, + Stub = 1, +}; + /// GlobalDecl - represents a global declaration. This can either be a /// CXXConstructorDecl and the constructor type (Base, Complete). /// a CXXDestructorDecl and the destructor type (Base, Complete) or @@ -42,8 +48,8 @@ unsigned MultiVersionIndex = 0; void Init(const Decl *D) { - assert(!isa(D) && "Use other ctor with ctor decls!"); - assert(!isa(D) && "Use other ctor with dtor decls!"); + assert((!D || !isa(D)) && "Use other ctor with ctor decls!"); + assert((!D || !isa(D)) && "Use other ctor with dtor decls!"); Value.setPointer(D); } @@ -55,6 +61,7 @@ : MultiVersionIndex(MVIndex) { Init(D); } + GlobalDecl(const NamedDecl *D) { Init(D); } GlobalDecl(const BlockDecl *D) { Init(D); } GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); } @@ -64,6 +71,10 @@ GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {} GlobalDecl(const VarDecl *D, DynamicInitKind StubKind) : Value(D, unsigned(StubKind)) {} + GlobalDecl(const FunctionDecl *D, HIPKernelKind Kind) + : Value(D, unsigned(Kind)) { + assert(D->hasAttr() && "Decl is not a HIP kernel!"); + } GlobalDecl getCanonicalDecl() const { GlobalDecl CanonGD; @@ -94,13 +105,22 @@ } unsigned getMultiVersionIndex() const { - assert(isa(getDecl()) && + assert(isa( + getDecl()) && + !cast(getDecl())->hasAttr() && !isa(getDecl()) && !isa(getDecl()) && "Decl is not a plain FunctionDecl!"); return MultiVersionIndex; } + HIPKernelKind getHIPKernelKind() const { + assert(isa(getDecl()) && + cast(getDecl())->hasAttr() && + "Decl is not a HIP kernel!"); + return static_cast(Value.getInt()); + } + friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) { return LHS.Value == RHS.Value && LHS.MultiVersionIndex == RHS.MultiVersionIndex; @@ -108,6 +128,8 @@ void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } + operator bool() const { return getAsOpaquePtr(); } + static GlobalDecl getFromOpaquePtr(void *P) { GlobalDecl GD; GD.Value.setFromOpaqueValue(P); @@ -135,7 +157,9 @@ } GlobalDecl getWithMultiVersionIndex(unsigned Index) { - assert(isa(getDecl()) && + assert(isa( + getDecl()) && + !cast(getDecl())->hasAttr() && !isa(getDecl()) && !isa(getDecl()) && "Decl is not a plain FunctionDecl!"); @@ -143,6 +167,15 @@ Result.MultiVersionIndex = Index; return Result; } + + GlobalDecl getWithHIPKernelKind(HIPKernelKind Kind) { + assert(isa(getDecl()) && + cast(getDecl())->hasAttr() && + "Decl is not a HIP kernel!"); + GlobalDecl Result(*this); + Result.Value.setInt(unsigned(Kind)); + return Result; + } }; } // namespace clang Index: clang/include/clang/AST/Mangle.h =================================================================== --- clang/include/clang/AST/Mangle.h +++ clang/include/clang/AST/Mangle.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_AST_MANGLE_H #include "clang/AST/Decl.h" +#include "clang/AST/GlobalDecl.h" #include "clang/AST/Type.h" #include "clang/Basic/ABI.h" #include "llvm/ADT/DenseMap.h" @@ -96,8 +97,8 @@ virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0; // FIXME: consider replacing raw_ostream & with something like SmallString &. - void mangleName(const NamedDecl *D, raw_ostream &); - virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0; + void mangleName(GlobalDecl GD, raw_ostream &); + virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0; virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) = 0; Index: clang/lib/AST/ItaniumMangle.cpp =================================================================== --- clang/lib/AST/ItaniumMangle.cpp +++ clang/lib/AST/ItaniumMangle.cpp @@ -135,7 +135,7 @@ bool shouldMangleStringLiteral(const StringLiteral *) override { return false; } - void mangleCXXName(const NamedDecl *D, raw_ostream &) override; + void mangleCXXName(GlobalDecl GD, raw_ostream &) override; void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) override; void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, @@ -417,14 +417,14 @@ void disableDerivedAbiTags() { DisableDerivedAbiTags = true; } static bool shouldHaveAbiTags(ItaniumMangleContextImpl &C, const VarDecl *VD); - void mangle(const NamedDecl *D); + void mangle(GlobalDecl GD); void mangleCallOffset(int64_t NonVirtual, int64_t Virtual); void mangleNumber(const llvm::APSInt &I); void mangleNumber(int64_t Number); void mangleFloat(const llvm::APFloat &F); - void mangleFunctionEncoding(const FunctionDecl *FD); + void mangleFunctionEncoding(GlobalDecl GD); void mangleSeqID(unsigned SeqID); - void mangleName(const NamedDecl *ND); + void mangleName(GlobalDecl GD); void mangleType(QualType T); void mangleNameOrStandardSubstitution(const NamedDecl *ND); void mangleLambdaSig(const CXXRecordDecl *Lambda); @@ -461,38 +461,39 @@ void mangleFunctionEncodingBareType(const FunctionDecl *FD); - void mangleNameWithAbiTags(const NamedDecl *ND, + void mangleNameWithAbiTags(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); void mangleModuleName(const Module *M); void mangleModuleNamePrefix(StringRef Name); void mangleTemplateName(const TemplateDecl *TD, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs); - void mangleUnqualifiedName(const NamedDecl *ND, + void mangleUnqualifiedName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { - mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity, + mangleUnqualifiedName(GD, cast(GD.getDecl())->getDeclName(), UnknownArity, AdditionalAbiTags); } - void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, + void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name, unsigned KnownArity, const AbiTagList *AdditionalAbiTags); - void mangleUnscopedName(const NamedDecl *ND, + void mangleUnscopedName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); - void mangleUnscopedTemplateName(const TemplateDecl *ND, + void mangleUnscopedTemplateName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); void mangleUnscopedTemplateName(TemplateName, const AbiTagList *AdditionalAbiTags); void mangleSourceName(const IdentifierInfo *II); void mangleRegCallName(const IdentifierInfo *II); + void mangleDeviceStubName(const IdentifierInfo *II); void mangleSourceNameWithAbiTags( const NamedDecl *ND, const AbiTagList *AdditionalAbiTags = nullptr); - void mangleLocalName(const Decl *D, + void mangleLocalName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); void mangleBlockForPrefix(const BlockDecl *Block); void mangleUnqualifiedBlock(const BlockDecl *Block); void mangleTemplateParamDecl(const NamedDecl *Decl); void mangleLambda(const CXXRecordDecl *Lambda); - void mangleNestedName(const NamedDecl *ND, const DeclContext *DC, + void mangleNestedName(GlobalDecl GD, const DeclContext *DC, const AbiTagList *AdditionalAbiTags, bool NoFunction=false); void mangleNestedName(const TemplateDecl *TD, @@ -501,7 +502,7 @@ void manglePrefix(NestedNameSpecifier *qualifier); void manglePrefix(const DeclContext *DC, bool NoFunction=false); void manglePrefix(QualType type); - void mangleTemplatePrefix(const TemplateDecl *ND, bool NoFunction=false); + void mangleTemplatePrefix(GlobalDecl GD, bool NoFunction=false); void mangleTemplatePrefix(TemplateName Template); bool mangleUnresolvedTypeOrSimpleId(QualType DestroyedType, StringRef Prefix = ""); @@ -640,13 +641,14 @@ writeAbiTags(ND, AdditionalAbiTags); } -void CXXNameMangler::mangle(const NamedDecl *D) { +void CXXNameMangler::mangle(GlobalDecl GD) { + const NamedDecl *D = dyn_cast(GD.getDecl()); // ::= _Z // ::= // ::= Out << "_Z"; if (const FunctionDecl *FD = dyn_cast(D)) - mangleFunctionEncoding(FD); + mangleFunctionEncoding(GD); else if (const VarDecl *VD = dyn_cast(D)) mangleName(VD); else if (const IndirectFieldDecl *IFD = dyn_cast(D)) @@ -655,19 +657,20 @@ mangleName(cast(D)); } -void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { +void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) { + const FunctionDecl *FD = cast(GD.getDecl()); // ::= // Don't mangle in the type if this isn't a decl we should typically mangle. if (!Context.shouldMangleDeclName(FD)) { - mangleName(FD); + mangleName(GD); return; } AbiTagList ReturnTypeAbiTags = makeFunctionReturnTypeTags(FD); if (ReturnTypeAbiTags.empty()) { // There are no tags for return type, the simplest case. - mangleName(FD); + mangleName(GD); mangleFunctionEncodingBareType(FD); return; } @@ -787,13 +790,14 @@ return isStd(cast(DC)); } -static const TemplateDecl * -isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) { +static const GlobalDecl +isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs) { + const NamedDecl *ND = cast(GD.getDecl()); // Check if we have a function template. if (const FunctionDecl *FD = dyn_cast(ND)) { if (const TemplateDecl *TD = FD->getPrimaryTemplate()) { TemplateArgs = FD->getTemplateSpecializationArgs(); - return TD; + return GD.getWithDecl(TD); } } @@ -801,20 +805,21 @@ if (const ClassTemplateSpecializationDecl *Spec = dyn_cast(ND)) { TemplateArgs = &Spec->getTemplateArgs(); - return Spec->getSpecializedTemplate(); + return GD.getWithDecl(Spec->getSpecializedTemplate()); } // Check if we have a variable template. if (const VarTemplateSpecializationDecl *Spec = dyn_cast(ND)) { TemplateArgs = &Spec->getTemplateArgs(); - return Spec->getSpecializedTemplate(); + return GD.getWithDecl(Spec->getSpecializedTemplate()); } - return nullptr; + return GlobalDecl::getFromOpaquePtr(nullptr); } -void CXXNameMangler::mangleName(const NamedDecl *ND) { +void CXXNameMangler::mangleName(GlobalDecl GD) { + const NamedDecl *ND = cast(GD.getDecl()); if (const VarDecl *VD = dyn_cast(ND)) { // Variables should have implicit tags from its type. AbiTagList VariableTypeAbiTags = makeVariableTypeTags(VD); @@ -843,12 +848,13 @@ // Output name with implicit tags. mangleNameWithAbiTags(VD, &AdditionalAbiTags); } else { - mangleNameWithAbiTags(ND, nullptr); + mangleNameWithAbiTags(GD, nullptr); } } -void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND, +void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const NamedDecl *ND = cast(GD.getDecl()); // ::= [] // ::= [] // ::= [] @@ -864,14 +870,14 @@ while (!DC->isNamespace() && !DC->isTranslationUnit()) DC = getEffectiveParentContext(DC); else if (GetLocalClassDecl(ND)) { - mangleLocalName(ND, AdditionalAbiTags); + mangleLocalName(GD, AdditionalAbiTags); return; } DC = IgnoreLinkageSpecDecls(DC); if (isLocalContainerContext(DC)) { - mangleLocalName(ND, AdditionalAbiTags); + mangleLocalName(GD, AdditionalAbiTags); return; } @@ -886,17 +892,17 @@ if (DC->isTranslationUnit() || isStdNamespace(DC)) { // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) { mangleUnscopedTemplateName(TD, AdditionalAbiTags); mangleTemplateArgs(*TemplateArgs); return; } - mangleUnscopedName(ND, AdditionalAbiTags); + mangleUnscopedName(GD, AdditionalAbiTags); return; } - mangleNestedName(ND, DC, AdditionalAbiTags); + mangleNestedName(GD, DC, AdditionalAbiTags); } void CXXNameMangler::mangleModuleName(const Module *M) { @@ -947,19 +953,21 @@ } } -void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND, +void CXXNameMangler::mangleUnscopedName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const NamedDecl *ND = cast(GD.getDecl()); // ::= // ::= St # ::std:: if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND)))) Out << "St"; - mangleUnqualifiedName(ND, AdditionalAbiTags); + mangleUnqualifiedName(GD, AdditionalAbiTags); } void CXXNameMangler::mangleUnscopedTemplateName( - const TemplateDecl *ND, const AbiTagList *AdditionalAbiTags) { + GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const TemplateDecl *ND = cast(GD.getDecl()); // ::= // ::= if (mangleSubstitution(ND)) @@ -971,9 +979,9 @@ "template template param cannot have abi tags"); mangleTemplateParameter(TTP->getDepth(), TTP->getIndex()); } else if (isa(ND) || isa(ND)) { - mangleUnscopedName(ND, AdditionalAbiTags); + mangleUnscopedName(GD, AdditionalAbiTags); } else { - mangleUnscopedName(ND->getTemplatedDecl(), AdditionalAbiTags); + mangleUnscopedName(GD.getWithDecl(ND->getTemplatedDecl()), AdditionalAbiTags); } addSubstitution(ND); @@ -1250,10 +1258,11 @@ mangleTemplateArgs(TemplateArgs, NumTemplateArgs); } -void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, +void CXXNameMangler::mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name, unsigned KnownArity, const AbiTagList *AdditionalAbiTags) { + const NamedDecl *ND = cast_or_null(GD.getDecl()); unsigned Arity = KnownArity; // ::= // ::= @@ -1303,7 +1312,12 @@ bool IsRegCall = FD && FD->getType()->castAs()->getCallConv() == clang::CC_X86RegCall; - if (IsRegCall) + bool IsDeviceStub = + FD && FD->hasAttr() && + GD.getHIPKernelKind() == HIPKernelKind::Stub; + if (IsDeviceStub) + mangleDeviceStubName(II); + else if (IsRegCall) mangleRegCallName(II); else mangleSourceName(II); @@ -1492,6 +1506,14 @@ << II->getName(); } +void CXXNameMangler::mangleDeviceStubName(const IdentifierInfo *II) { + // ::= __device_stub__ + // ::= [n] + // ::= + Out << II->getLength() + sizeof("__device_stub__") - 1 << "__device_stub__" + << II->getName(); +} + void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) { // ::= // ::= [n] @@ -1499,10 +1521,11 @@ Out << II->getLength() << II->getName(); } -void CXXNameMangler::mangleNestedName(const NamedDecl *ND, +void CXXNameMangler::mangleNestedName(GlobalDecl GD, const DeclContext *DC, const AbiTagList *AdditionalAbiTags, bool NoFunction) { + const NamedDecl *ND = cast(GD.getDecl()); // // ::= N [] [] E // ::= N [] [] @@ -1520,13 +1543,13 @@ // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) { mangleTemplatePrefix(TD, NoFunction); mangleTemplateArgs(*TemplateArgs); } else { manglePrefix(DC, NoFunction); - mangleUnqualifiedName(ND, AdditionalAbiTags); + mangleUnqualifiedName(GD, AdditionalAbiTags); } Out << 'E'; @@ -1544,8 +1567,9 @@ Out << 'E'; } -void CXXNameMangler::mangleLocalName(const Decl *D, +void CXXNameMangler::mangleLocalName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const Decl *D = GD.getDecl(); // := Z E [] // := Z E s [] // := Z E d [ ] @@ -1564,8 +1588,17 @@ mangleObjCMethodName(MD); else if (const BlockDecl *BD = dyn_cast(DC)) mangleBlockForPrefix(BD); - else - mangleFunctionEncoding(cast(DC)); + else { + GlobalDecl DCGD; + // The ctor and dtor type is not available in the declare context. + if (auto *CD = dyn_cast(DC)) + DCGD = GlobalDecl(CD, Ctor_Complete); + else if (auto *DD = dyn_cast(DC)) + DCGD = GlobalDecl(DD, Dtor_Complete); + else + DCGD = GlobalDecl(dyn_cast(DC)); + mangleFunctionEncoding(DCGD); + } // Implicit ABI tags (from namespace) are not available in the following // entity; reset to actually emitted tags, which are available. @@ -1608,7 +1641,7 @@ mangleUnqualifiedBlock(BD); } else { const NamedDecl *ND = cast(D); - mangleNestedName(ND, getEffectiveDeclContext(ND), AdditionalAbiTags, + mangleNestedName(GD, getEffectiveDeclContext(ND), AdditionalAbiTags, true /*NoFunction*/); } } else if (const BlockDecl *BD = dyn_cast(D)) { @@ -1629,7 +1662,7 @@ assert(!AdditionalAbiTags && "Block cannot have additional abi tags"); mangleUnqualifiedBlock(BD); } else { - mangleUnqualifiedName(cast(D), AdditionalAbiTags); + mangleUnqualifiedName(GD, AdditionalAbiTags); } if (const NamedDecl *ND = dyn_cast(RD ? RD : D)) { @@ -1840,7 +1873,7 @@ // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + if (GlobalDecl TD = isTemplate(ND, TemplateArgs)) { mangleTemplatePrefix(TD); mangleTemplateArgs(*TemplateArgs); } else { @@ -1863,7 +1896,7 @@ if (OverloadedTemplateStorage *Overloaded = Template.getAsOverloadedTemplate()) { - mangleUnqualifiedName(nullptr, (*Overloaded->begin())->getDeclName(), + mangleUnqualifiedName(static_cast(nullptr), (*Overloaded->begin())->getDeclName(), UnknownArity, nullptr); return; } @@ -1875,8 +1908,9 @@ mangleUnscopedTemplateName(Template, /* AdditionalAbiTags */ nullptr); } -void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, +void CXXNameMangler::mangleTemplatePrefix(GlobalDecl GD, bool NoFunction) { + const TemplateDecl *ND = cast(GD.getDecl()); // ::=