diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp | 163 |
1 files changed, 131 insertions, 32 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp index 694fde3..ab3e49d 100644 --- a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp @@ -405,12 +405,14 @@ public: CXXNameMangler(CXXNameMangler &Outer, raw_ostream &Out_) : Context(Outer.Context), Out(Out_), NullOut(false), Structor(Outer.Structor), StructorType(Outer.StructorType), - SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {} + SeqID(Outer.SeqID), FunctionTypeDepth(Outer.FunctionTypeDepth), + AbiTagsRoot(AbiTags), Substitutions(Outer.Substitutions) {} CXXNameMangler(CXXNameMangler &Outer, llvm::raw_null_ostream &Out_) : Context(Outer.Context), Out(Out_), NullOut(true), Structor(Outer.Structor), StructorType(Outer.StructorType), - SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {} + SeqID(Outer.SeqID), FunctionTypeDepth(Outer.FunctionTypeDepth), + AbiTagsRoot(AbiTags), Substitutions(Outer.Substitutions) {} #if MANGLE_CHECKER ~CXXNameMangler() { @@ -458,11 +460,15 @@ private: void addSubstitution(QualType T); void addSubstitution(TemplateName Template); void addSubstitution(uintptr_t Ptr); + // Destructive copy substitutions from other mangler. + void extendSubstitutions(CXXNameMangler* Other); void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, bool recursive = false); void mangleUnresolvedName(NestedNameSpecifier *qualifier, DeclarationName name, + const TemplateArgumentLoc *TemplateArgs, + unsigned NumTemplateArgs, unsigned KnownArity = UnknownArity); void mangleFunctionEncodingBareType(const FunctionDecl *FD); @@ -487,6 +493,7 @@ private: void mangleUnscopedTemplateName(TemplateName, const AbiTagList *AdditionalAbiTags); void mangleSourceName(const IdentifierInfo *II); + void mangleRegCallName(const IdentifierInfo *II); void mangleSourceNameWithAbiTags( const NamedDecl *ND, const AbiTagList *AdditionalAbiTags = nullptr); void mangleLocalName(const Decl *D, @@ -537,6 +544,8 @@ private: NestedNameSpecifier *qualifier, NamedDecl *firstQualifierLookup, DeclarationName name, + const TemplateArgumentLoc *TemplateArgs, + unsigned NumTemplateArgs, unsigned knownArity); void mangleCastExpression(const Expr *E, StringRef CastEncoding); void mangleInitListElements(const InitListExpr *InitList); @@ -593,7 +602,7 @@ bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) { return false; const VarDecl *VD = dyn_cast<VarDecl>(D); - if (VD) { + if (VD && !isa<DecompositionDecl>(D)) { // C variables are not mangled. if (VD->isExternC()) return false; @@ -685,6 +694,10 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { // Output name with implicit tags and function encoding from temporary buffer. mangleNameWithAbiTags(FD, &AdditionalAbiTags); Out << FunctionEncodingStream.str().substr(EncodingPositionStart); + + // Function encoding could create new substitutions so we have to add + // temp mangled substitutions to main mangler. + extendSubstitutions(&FunctionEncodingMangler); } void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) { @@ -1151,9 +1164,10 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, /// Mangle an unresolved-name, which is generally used for names which /// weren't resolved to specific entities. -void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier, - DeclarationName name, - unsigned knownArity) { +void CXXNameMangler::mangleUnresolvedName( + NestedNameSpecifier *qualifier, DeclarationName name, + const TemplateArgumentLoc *TemplateArgs, unsigned NumTemplateArgs, + unsigned knownArity) { if (qualifier) mangleUnresolvedPrefix(qualifier); switch (name.getNameKind()) { // <base-unresolved-name> ::= <simple-id> @@ -1181,6 +1195,11 @@ void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier, case DeclarationName::ObjCZeroArgSelector: llvm_unreachable("Can't mangle Objective-C selector names here!"); } + + // The <simple-id> and on <operator-name> productions end in an optional + // <template-args>. + if (TemplateArgs) + mangleTemplateArgs(TemplateArgs, NumTemplateArgs); } void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, @@ -1193,7 +1212,26 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // ::= <source-name> switch (Name.getNameKind()) { case DeclarationName::Identifier: { - if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) { + const IdentifierInfo *II = Name.getAsIdentifierInfo(); + + // We mangle decomposition declarations as the names of their bindings. + if (auto *DD = dyn_cast<DecompositionDecl>(ND)) { + // FIXME: Non-standard mangling for decomposition declarations: + // + // <unqualified-name> ::= DC <source-name>* E + // + // These can never be referenced across translation units, so we do + // not need a cross-vendor mangling for anything other than demanglers. + // Proposed on cxx-abi-dev on 2016-08-12 + Out << "DC"; + for (auto *BD : DD->bindings()) + mangleSourceName(BD->getDeclName().getAsIdentifierInfo()); + Out << 'E'; + writeAbiTags(ND, AdditionalAbiTags); + break; + } + + if (II) { // We must avoid conflicts between internally- and externally- // linked variable and function declaration names in the same TU: // void test() { extern void foo(); } @@ -1204,7 +1242,15 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, getEffectiveDeclContext(ND)->isFileContext()) Out << 'L'; - mangleSourceName(II); + auto *FD = dyn_cast<FunctionDecl>(ND); + bool IsRegCall = FD && + FD->getType()->castAs<FunctionType>()->getCallConv() == + clang::CC_X86RegCall; + if (IsRegCall) + mangleRegCallName(II); + else + mangleSourceName(II); + writeAbiTags(ND, AdditionalAbiTags); break; } @@ -1378,6 +1424,14 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, } } +void CXXNameMangler::mangleRegCallName(const IdentifierInfo *II) { + // <source-name> ::= <positive length number> __regcall3__ <identifier> + // <number> ::= [n] <non-negative decimal integer> + // <identifier> ::= <unqualified source code identifier> + Out << II->getLength() + sizeof("__regcall3__") - 1 << "__regcall3__" + << II->getName(); +} + void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) { // <source-name> ::= <positive length number> <identifier> // <number> ::= [n] <non-negative decimal integer> @@ -1471,7 +1525,7 @@ void CXXNameMangler::mangleLocalName(const Decl *D, // numbering will be local to the particular argument in which it appears // -- other default arguments do not affect its encoding. const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD); - if (CXXRD->isLambda()) { + if (CXXRD && CXXRD->isLambda()) { if (const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(CXXRD->getLambdaContextDecl())) { if (const FunctionDecl *Func @@ -1820,6 +1874,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, case Type::ObjCObject: case Type::ObjCInterface: case Type::ObjCObjectPointer: + case Type::ObjCTypeParam: case Type::Atomic: case Type::Pipe: llvm_unreachable("type is illegal as a nested name specifier"); @@ -2207,6 +2262,22 @@ void CXXNameMangler::mangleType(QualType T) { // they aren't written. // - Conversions on non-type template arguments need to be expressed, since // they can affect the mangling of sizeof/alignof. + // + // FIXME: This is wrong when mapping to the canonical type for a dependent + // type discards instantiation-dependent portions of the type, such as for: + // + // template<typename T, int N> void f(T (&)[sizeof(N)]); + // template<typename T> void f(T() throw(typename T::type)); (pre-C++17) + // + // It's also wrong in the opposite direction when instantiation-dependent, + // canonically-equivalent types differ in some irrelevant portion of inner + // type sugar. In such cases, we fail to form correct substitutions, eg: + // + // template<int N> void f(A<sizeof(N)> *, A<sizeof(N)> (*)); + // + // We should instead canonicalize the non-instantiation-dependent parts, + // regardless of whether the type as a whole is dependent or instantiation + // dependent. if (!T->isInstantiationDependentType() || T->isDependentType()) T = T.getCanonicalType(); else { @@ -2443,6 +2514,7 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) { case CC_X86Pascal: case CC_X86_64Win64: case CC_X86_64SysV: + case CC_X86RegCall: case CC_AAPCS: case CC_AAPCS_VFP: case CC_IntelOclBicc: @@ -2509,6 +2581,24 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) { // e.g. "const" in "int (A::*)() const". mangleQualifiers(Qualifiers::fromCVRMask(T->getTypeQuals())); + // Mangle instantiation-dependent exception-specification, if present, + // per cxx-abi-dev proposal on 2016-10-11. + if (T->hasInstantiationDependentExceptionSpec()) { + if (T->getExceptionSpecType() == EST_ComputedNoexcept) { + Out << "DO"; + mangleExpression(T->getNoexceptExpr()); + Out << "E"; + } else { + assert(T->getExceptionSpecType() == EST_Dynamic); + Out << "Dw"; + for (auto ExceptTy : T->exceptions()) + mangleType(ExceptTy); + Out << "E"; + } + } else if (T->isNothrow(getASTContext())) { + Out << "Do"; + } + Out << 'F'; // FIXME: We don't have enough information in the AST to produce the 'Y' @@ -3115,12 +3205,14 @@ void CXXNameMangler::mangleMemberExpr(const Expr *base, NestedNameSpecifier *qualifier, NamedDecl *firstQualifierLookup, DeclarationName member, + const TemplateArgumentLoc *TemplateArgs, + unsigned NumTemplateArgs, unsigned arity) { // <expression> ::= dt <expression> <unresolved-name> // ::= pt <expression> <unresolved-name> if (base) mangleMemberExprBase(base, isArrow); - mangleUnresolvedName(qualifier, member, arity); + mangleUnresolvedName(qualifier, member, TemplateArgs, NumTemplateArgs, arity); } /// Look at the callee of the given call expression and determine if @@ -3209,6 +3301,8 @@ recurse: case Expr::AddrLabelExprClass: case Expr::DesignatedInitUpdateExprClass: case Expr::ImplicitValueInitExprClass: + case Expr::ArrayInitLoopExprClass: + case Expr::ArrayInitIndexExprClass: case Expr::NoInitExprClass: case Expr::ParenListExprClass: case Expr::LambdaExprClass: @@ -3418,7 +3512,9 @@ recurse: const MemberExpr *ME = cast<MemberExpr>(E); mangleMemberExpr(ME->getBase(), ME->isArrow(), ME->getQualifier(), nullptr, - ME->getMemberDecl()->getDeclName(), Arity); + ME->getMemberDecl()->getDeclName(), + ME->getTemplateArgs(), ME->getNumTemplateArgs(), + Arity); break; } @@ -3426,9 +3522,9 @@ recurse: const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E); mangleMemberExpr(ME->isImplicitAccess() ? nullptr : ME->getBase(), ME->isArrow(), ME->getQualifier(), nullptr, - ME->getMemberName(), Arity); - if (ME->hasExplicitTemplateArgs()) - mangleTemplateArgs(ME->getTemplateArgs(), ME->getNumTemplateArgs()); + ME->getMemberName(), + ME->getTemplateArgs(), ME->getNumTemplateArgs(), + Arity); break; } @@ -3438,21 +3534,17 @@ recurse: mangleMemberExpr(ME->isImplicitAccess() ? nullptr : ME->getBase(), ME->isArrow(), ME->getQualifier(), ME->getFirstQualifierFoundInScope(), - ME->getMember(), Arity); - if (ME->hasExplicitTemplateArgs()) - mangleTemplateArgs(ME->getTemplateArgs(), ME->getNumTemplateArgs()); + ME->getMember(), + ME->getTemplateArgs(), ME->getNumTemplateArgs(), + Arity); break; } case Expr::UnresolvedLookupExprClass: { const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E); - mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), Arity); - - // All the <unresolved-name> productions end in a - // base-unresolved-name, where <template-args> are just tacked - // onto the end. - if (ULE->hasExplicitTemplateArgs()) - mangleTemplateArgs(ULE->getTemplateArgs(), ULE->getNumTemplateArgs()); + mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), + ULE->getTemplateArgs(), ULE->getNumTemplateArgs(), + Arity); break; } @@ -3707,7 +3799,10 @@ recurse: case Expr::CXXOperatorCallExprClass: { const CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(E); unsigned NumArgs = CE->getNumArgs(); - mangleOperatorName(CE->getOperator(), /*Arity=*/NumArgs); + // A CXXOperatorCallExpr for OO_Arrow models only semantics, not syntax + // (the enclosing MemberExpr covers the syntactic portion). + if (CE->getOperator() != OO_Arrow) + mangleOperatorName(CE->getOperator(), /*Arity=*/NumArgs); // Mangle the arguments. for (unsigned i = 0; i != NumArgs; ++i) mangleExpression(CE->getArg(i)); @@ -3768,13 +3863,9 @@ recurse: case Expr::DependentScopeDeclRefExprClass: { const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E); - mangleUnresolvedName(DRE->getQualifier(), DRE->getDeclName(), Arity); - - // All the <unresolved-name> productions end in a - // base-unresolved-name, where <template-args> are just tacked - // onto the end. - if (DRE->hasExplicitTemplateArgs()) - mangleTemplateArgs(DRE->getTemplateArgs(), DRE->getNumTemplateArgs()); + mangleUnresolvedName(DRE->getQualifier(), DRE->getDeclName(), + DRE->getTemplateArgs(), DRE->getNumTemplateArgs(), + Arity); break; } @@ -4406,6 +4497,14 @@ void CXXNameMangler::addSubstitution(uintptr_t Ptr) { Substitutions[Ptr] = SeqID++; } +void CXXNameMangler::extendSubstitutions(CXXNameMangler* Other) { + assert(Other->SeqID >= SeqID && "Must be superset of substitutions!"); + if (Other->SeqID > SeqID) { + Substitutions.swap(Other->Substitutions); + SeqID = Other->SeqID; + } +} + CXXNameMangler::AbiTagList CXXNameMangler::makeFunctionReturnTypeTags(const FunctionDecl *FD) { // When derived abi tags are disabled there is no need to make any list. |