diff options
Diffstat (limited to 'lib/AST/ItaniumMangle.cpp')
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 187 |
1 files changed, 134 insertions, 53 deletions
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 977d6fca2c40..156ad646fa6d 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -117,7 +117,7 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext { typedef std::pair<const DeclContext*, IdentifierInfo*> DiscriminatorKeyTy; llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator; llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier; - + public: explicit ItaniumMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags) @@ -150,6 +150,8 @@ public: void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, raw_ostream &) override; + void mangleCXXCtorComdat(const CXXConstructorDecl *D, raw_ostream &) override; + void mangleCXXDtorComdat(const CXXDestructorDecl *D, raw_ostream &) override; void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) override; void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override; void mangleDynamicAtExitDestructor(const VarDecl *D, @@ -373,6 +375,7 @@ private: NamedDecl *firstQualifierLookup, DeclarationName name, unsigned knownArity); + void mangleCastExpression(const Expr *E, StringRef CastEncoding); void mangleExpression(const Expr *E, unsigned Arity = UnknownArity); void mangleCXXCtorType(CXXCtorType T); void mangleCXXDtorType(CXXDtorType T); @@ -634,13 +637,11 @@ void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) { return; // <template-template-param> ::= <template-param> - if (const TemplateTemplateParmDecl *TTP - = dyn_cast<TemplateTemplateParmDecl>(ND)) { + if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) mangleTemplateParameter(TTP->getIndex()); - return; - } + else + mangleUnscopedName(ND->getTemplatedDecl()); - mangleUnscopedName(ND->getTemplatedDecl()); addSubstitution(ND); } @@ -811,6 +812,9 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, // We never want an 'E' here. return; + case NestedNameSpecifier::Super: + llvm_unreachable("Can't mangle __super specifier"); + case NestedNameSpecifier::Namespace: if (qualifier->getPrefix()) mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, @@ -1046,24 +1050,6 @@ void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier, mangleUnqualifiedName(nullptr, name, knownArity); } -static const FieldDecl *FindFirstNamedDataMember(const RecordDecl *RD) { - assert(RD->isAnonymousStructOrUnion() && - "Expected anonymous struct or union!"); - - for (const auto *I : RD->fields()) { - if (I->getIdentifier()) - return I; - - if (const RecordType *RT = I->getType()->getAs<RecordType>()) - if (const FieldDecl *NamedDataMember = - FindFirstNamedDataMember(RT->getDecl())) - return NamedDataMember; - } - - // We didn't find a named data member. - return nullptr; -} - void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, unsigned KnownArity) { @@ -1100,9 +1086,9 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) { // We must have an anonymous union or struct declaration. - const RecordDecl *RD = + const RecordDecl *RD = cast<RecordDecl>(VD->getType()->getAs<RecordType>()->getDecl()); - + // Itanium C++ ABI 5.1.2: // // For the purposes of mangling, the name of an anonymous union is @@ -1112,14 +1098,16 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // the data members in the union are unnamed), then there is no way for // a program to refer to the anonymous union, and there is therefore no // need to mangle its name. - const FieldDecl *FD = FindFirstNamedDataMember(RD); + assert(RD->isAnonymousStructOrUnion() + && "Expected anonymous struct or union!"); + const FieldDecl *FD = RD->findFirstNamedDataMember(); // It's actually possible for various reasons for us to get here // with an empty anonymous struct / union. Fortunately, it // doesn't really matter what name we generate. if (!FD) break; assert(FD->getIdentifier() && "Data member name isn't an identifier!"); - + mangleSourceName(FD->getIdentifier()); break; } @@ -1409,8 +1397,8 @@ void CXXNameMangler::mangleUnqualifiedBlock(const BlockDecl *Block) { if (!Number) Number = Context.getBlockId(Block, false); Out << "Ub"; - if (Number > 1) - Out << Number - 2; + if (Number > 0) + Out << Number - 1; Out << '_'; } @@ -1459,6 +1447,9 @@ void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) { // nothing return; + case NestedNameSpecifier::Super: + llvm_unreachable("Can't mangle __super specifier"); + case NestedNameSpecifier::Namespace: mangleName(qualifier->getAsNamespace()); return; @@ -1554,14 +1545,13 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, return; // <template-template-param> ::= <template-param> - if (const TemplateTemplateParmDecl *TTP - = dyn_cast<TemplateTemplateParmDecl>(ND)) { + if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) { mangleTemplateParameter(TTP->getIndex()); - return; + } else { + manglePrefix(getEffectiveDeclContext(ND), NoFunction); + mangleUnqualifiedName(ND->getTemplatedDecl()); } - manglePrefix(getEffectiveDeclContext(ND), NoFunction); - mangleUnqualifiedName(ND->getTemplatedDecl()); addSubstitution(ND); } @@ -1834,6 +1824,19 @@ void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { Context.mangleObjCMethodName(MD, Out); } +static bool isTypeSubstitutable(Qualifiers Quals, const Type *Ty) { + if (Quals) + return true; + if (Ty->isSpecificBuiltinType(BuiltinType::ObjCSel)) + return true; + if (Ty->isOpenCLSpecificType()) + return true; + if (Ty->isBuiltinType()) + return false; + + return true; +} + void CXXNameMangler::mangleType(QualType T) { // If our type is instantiation-dependent but not dependent, we mangle // it as it was written in the source, removing any top-level sugar. @@ -1875,7 +1878,7 @@ void CXXNameMangler::mangleType(QualType T) { Qualifiers quals = split.Quals; const Type *ty = split.Ty; - bool isSubstitutable = quals || !isa<BuiltinType>(T); + bool isSubstitutable = isTypeSubstitutable(quals, ty); if (isSubstitutable && mangleSubstitution(T)) return; @@ -2301,9 +2304,7 @@ void CXXNameMangler::mangleType(const VectorType *T) { llvm::Triple::ArchType Arch = getASTContext().getTargetInfo().getTriple().getArch(); if ((Arch == llvm::Triple::aarch64 || - Arch == llvm::Triple::aarch64_be || - Arch == llvm::Triple::arm64_be || - Arch == llvm::Triple::arm64) && !Target.isOSDarwin()) + Arch == llvm::Triple::aarch64_be) && !Target.isOSDarwin()) mangleAArch64NeonVectorType(T); else mangleNeonVectorType(T); @@ -2528,6 +2529,18 @@ void CXXNameMangler::mangleMemberExpr(const Expr *base, // <expression> ::= dt <expression> <unresolved-name> // ::= pt <expression> <unresolved-name> if (base) { + + // Ignore member expressions involving anonymous unions. + while (const auto *RT = base->getType()->getAs<RecordType>()) { + if (!RT->getDecl()->isAnonymousStructOrUnion()) + break; + const auto *ME = dyn_cast<MemberExpr>(base); + if (!ME) + break; + base = ME->getBase(); + isArrow = ME->isArrow(); + } + if (base->isImplicitCXXThis()) { // Note: GCC mangles member expressions to the implicit 'this' as // *this., whereas we represent them as this->. The Itanium C++ ABI @@ -2572,12 +2585,23 @@ static bool isParenthesizedADLCallee(const CallExpr *call) { return true; } +void CXXNameMangler::mangleCastExpression(const Expr *E, StringRef CastEncoding) { + const ExplicitCastExpr *ECE = cast<ExplicitCastExpr>(E); + Out << CastEncoding; + mangleType(ECE->getType()); + mangleExpression(ECE->getSubExpr()); +} + void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { // <expression> ::= <unary operator-name> <expression> // ::= <binary operator-name> <expression> <expression> // ::= <trinary operator-name> <expression> <expression> <expression> // ::= cv <type> expression # conversion with one argument // ::= cv <type> _ <expression>* E # conversion with a different number of arguments + // ::= dc <type> <expression> # dynamic_cast<type> (expression) + // ::= sc <type> <expression> # static_cast<type> (expression) + // ::= cc <type> <expression> # const_cast<type> (expression) + // ::= rc <type> <expression> # reinterpret_cast<type> (expression) // ::= st <type> # sizeof (a type) // ::= at <type> # alignof (a type) // ::= <template-param> @@ -2612,6 +2636,7 @@ recurse: case Expr::ParenListExprClass: case Expr::LambdaExprClass: case Expr::MSPropertyRefExprClass: + case Expr::TypoExprClass: // This should no longer exist in the AST by now. llvm_unreachable("unexpected statement kind"); // FIXME: invent manglings for all these. @@ -2643,7 +2668,6 @@ recurse: case Expr::ArrayTypeTraitExprClass: case Expr::ExpressionTraitExprClass: case Expr::VAArgExprClass: - case Expr::CXXUuidofExprClass: case Expr::CUDAKernelCallExprClass: case Expr::AsTypeExprClass: case Expr::PseudoObjectExprClass: @@ -2658,6 +2682,20 @@ recurse: break; } + case Expr::CXXUuidofExprClass: { + const CXXUuidofExpr *UE = cast<CXXUuidofExpr>(E); + if (UE->isTypeOperand()) { + QualType UuidT = UE->getTypeOperand(Context.getASTContext()); + Out << "u8__uuidoft"; + mangleType(UuidT); + } else { + Expr *UuidExp = UE->getExprOperand(); + Out << "u8__uuidofz"; + mangleExpression(UuidExp, Arity); + } + break; + } + // Even gcc-4.5 doesn't mangle this. case Expr::BinaryConditionalOperatorClass: { DiagnosticsEngine &Diags = Context.getDiags(); @@ -2982,17 +3020,22 @@ recurse: // Fall through to mangle the cast itself. case Expr::CStyleCastExprClass: + case Expr::CXXFunctionalCastExprClass: + mangleCastExpression(E, "cv"); + break; + case Expr::CXXStaticCastExprClass: + mangleCastExpression(E, "sc"); + break; case Expr::CXXDynamicCastExprClass: + mangleCastExpression(E, "dc"); + break; case Expr::CXXReinterpretCastExprClass: + mangleCastExpression(E, "rc"); + break; case Expr::CXXConstCastExprClass: - case Expr::CXXFunctionalCastExprClass: { - const ExplicitCastExpr *ECE = cast<ExplicitCastExpr>(E); - Out << "cv"; - mangleType(ECE->getType()); - mangleExpression(ECE->getSubExpr()); + mangleCastExpression(E, "cc"); break; - } case Expr::CXXOperatorCallExprClass: { const CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(E); @@ -3175,12 +3218,33 @@ recurse: mangleFunctionParam(cast<ParmVarDecl>(Pack)); break; } - + case Expr::MaterializeTemporaryExprClass: { mangleExpression(cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr()); break; } - + + case Expr::CXXFoldExprClass: { + auto *FE = cast<CXXFoldExpr>(E); + if (FE->isLeftFold()) + Out << (FE->getInit() ? "fL" : "fl"); + else + Out << (FE->getInit() ? "fR" : "fr"); + + if (FE->getOperator() == BO_PtrMemD) + Out << "ds"; + else + mangleOperatorName( + BinaryOperator::getOverloadedOperator(FE->getOperator()), + /*Arity=*/2); + + if (FE->getLHS()) + mangleExpression(FE->getLHS()); + if (FE->getRHS()) + mangleExpression(FE->getRHS()); + break; + } + case Expr::CXXThisExprClass: Out << "fpT"; break; @@ -3251,8 +3315,8 @@ void CXXNameMangler::mangleFunctionParam(const ParmVarDecl *parm) { void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) { // <ctor-dtor-name> ::= C1 # complete object constructor // ::= C2 # base object constructor - // ::= C3 # complete object allocating constructor // + // In addition, C5 is a comdat name with C1 and C2 in it. switch (T) { case Ctor_Complete: Out << "C1"; @@ -3260,8 +3324,8 @@ void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) { case Ctor_Base: Out << "C2"; break; - case Ctor_CompleteAllocating: - Out << "C3"; + case Ctor_Comdat: + Out << "C5"; break; } } @@ -3271,6 +3335,7 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) { // ::= D1 # complete object destructor // ::= D2 # base object destructor // + // In addition, D5 is a comdat name with D1, D2 and, if virtual, D0 in it. switch (T) { case Dtor_Deleting: Out << "D0"; @@ -3281,6 +3346,9 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) { case Dtor_Base: Out << "D2"; break; + case Dtor_Comdat: + Out << "D5"; + break; } } @@ -3363,7 +3431,7 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) { // and pointer-to-function expressions are represented as a declaration not // an expression. We compensate for it here to produce the correct mangling. ValueDecl *D = A.getAsDecl(); - bool compensateMangling = !A.isDeclForReferenceParam(); + bool compensateMangling = !A.getParamTypeForDecl()->isReferenceType(); if (compensateMangling) { Out << 'X'; mangleOperatorName(OO_Amp, 1); @@ -3674,7 +3742,7 @@ void ItaniumMangleContextImpl::mangleCXXName(const NamedDecl *D, "Mangling declaration"); CXXNameMangler Mangler(*this, Out, D); - return Mangler.mangle(D); + Mangler.mangle(D); } void ItaniumMangleContextImpl::mangleCXXCtor(const CXXConstructorDecl *D, @@ -3691,6 +3759,18 @@ void ItaniumMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D, Mangler.mangle(D); } +void ItaniumMangleContextImpl::mangleCXXCtorComdat(const CXXConstructorDecl *D, + raw_ostream &Out) { + CXXNameMangler Mangler(*this, Out, D, Ctor_Comdat); + Mangler.mangle(D); +} + +void ItaniumMangleContextImpl::mangleCXXDtorComdat(const CXXDestructorDecl *D, + raw_ostream &Out) { + CXXNameMangler Mangler(*this, Out, D, Dtor_Comdat); + Mangler.mangle(D); +} + void ItaniumMangleContextImpl::mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &Out) { @@ -3851,3 +3931,4 @@ ItaniumMangleContext * ItaniumMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) { return new ItaniumMangleContextImpl(Context, Diags); } + |