diff options
Diffstat (limited to 'clang/lib/AST/ItaniumMangle.cpp')
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 124 |
1 files changed, 101 insertions, 23 deletions
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index d30f95d0367..68f76f54eda 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -364,6 +364,7 @@ private: StringRef Prefix = ""); void mangleOperatorName(DeclarationName Name, unsigned Arity); void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity); + void mangleVendorQualifier(StringRef qualifier); void mangleQualifiers(Qualifiers Quals); void mangleRefQualifier(RefQualifierKind RefQualifier); @@ -377,7 +378,10 @@ private: void mangleType(const TagType*); void mangleType(TemplateName); - void mangleBareFunctionType(const FunctionType *T, bool MangleReturnType, + static StringRef getCallingConvQualifierName(CallingConv CC); + void mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo info); + void mangleExtFunctionInfo(const FunctionType *T); + void mangleBareFunctionType(const FunctionProtoType *T, bool MangleReturnType, const FunctionDecl *FD = nullptr); void mangleNeonVectorType(const VectorType *T); void mangleAArch64NeonVectorType(const VectorType *T); @@ -523,7 +527,7 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { FD = PrimaryTemplate->getTemplatedDecl(); } - mangleBareFunctionType(FD->getType()->getAs<FunctionType>(), + mangleBareFunctionType(FD->getType()->castAs<FunctionProtoType>(), MangleReturnType, FD); } @@ -1767,14 +1771,9 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) { } void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { - // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const - if (Quals.hasRestrict()) - Out << 'r'; - if (Quals.hasVolatile()) - Out << 'V'; - if (Quals.hasConst()) - Out << 'K'; + // Vendor qualifiers come first. + // Address space qualifiers start with an ordinary letter. if (Quals.hasAddressSpace()) { // Address space extension: // @@ -1802,10 +1801,10 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { case LangAS::cuda_shared: ASString = "CUshared"; break; } } - Out << 'U' << ASString.size() << ASString; + mangleVendorQualifier(ASString); } - - StringRef LifetimeName; + + // The ARC ownership qualifiers start with underscores. switch (Quals.getObjCLifetime()) { // Objective-C ARC Extension: // @@ -1816,15 +1815,15 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { break; case Qualifiers::OCL_Weak: - LifetimeName = "__weak"; + mangleVendorQualifier("__weak"); break; case Qualifiers::OCL_Strong: - LifetimeName = "__strong"; + mangleVendorQualifier("__strong"); break; case Qualifiers::OCL_Autoreleasing: - LifetimeName = "__autoreleasing"; + mangleVendorQualifier("__autoreleasing"); break; case Qualifiers::OCL_ExplicitNone: @@ -1837,8 +1836,18 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { // in any type signatures that need to be mangled. break; } - if (!LifetimeName.empty()) - Out << 'U' << LifetimeName.size() << LifetimeName; + + // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const + if (Quals.hasRestrict()) + Out << 'r'; + if (Quals.hasVolatile()) + Out << 'V'; + if (Quals.hasConst()) + Out << 'K'; +} + +void CXXNameMangler::mangleVendorQualifier(StringRef name) { + Out << 'U' << name.size() << name; } void CXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) { @@ -2137,10 +2146,63 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { } } +StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) { + switch (CC) { + case CC_C: + return ""; + + case CC_X86StdCall: + case CC_X86FastCall: + case CC_X86ThisCall: + case CC_X86VectorCall: + case CC_X86Pascal: + case CC_X86_64Win64: + case CC_X86_64SysV: + case CC_AAPCS: + case CC_AAPCS_VFP: + case CC_IntelOclBicc: + case CC_SpirFunction: + case CC_SpirKernel: + // FIXME: we should be mangling all of the above. + return ""; + } + llvm_unreachable("bad calling convention"); +} + +void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) { + // Fast path. + if (T->getExtInfo() == FunctionType::ExtInfo()) + return; + + // Vendor-specific qualifiers are emitted in reverse alphabetical order. + // This will get more complicated in the future if we mangle other + // things here; but for now, since we mangle ns_returns_retained as + // a qualifier on the result type, we can get away with this: + StringRef CCQualifier = getCallingConvQualifierName(T->getExtInfo().getCC()); + if (!CCQualifier.empty()) + mangleVendorQualifier(CCQualifier); + + // FIXME: regparm + // FIXME: noreturn +} + +void +CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) { + // Vendor-specific qualifiers are emitted in reverse alphabetical order. + + // Note that these are *not* substitution candidates. Demanglers might + // have trouble with this if the parameter type is fully substituted. + + if (PI.isConsumed()) + Out << "U11ns_consumed"; +} + // <type> ::= <function-type> // <function-type> ::= [<CV-qualifiers>] F [Y] // <bare-function-type> [<ref-qualifier>] E void CXXNameMangler::mangleType(const FunctionProtoType *T) { + mangleExtFunctionInfo(T); + // Mangle CV-qualifiers, if present. These are 'this' qualifiers, // e.g. "const" in "int (A::*)() const". mangleQualifiers(Qualifiers::fromCVRMask(T->getTypeQuals())); @@ -2173,12 +2235,9 @@ void CXXNameMangler::mangleType(const FunctionNoProtoType *T) { Out << 'E'; } -void CXXNameMangler::mangleBareFunctionType(const FunctionType *T, +void CXXNameMangler::mangleBareFunctionType(const FunctionProtoType *Proto, bool MangleReturnType, const FunctionDecl *FD) { - // We should never be mangling something without a prototype. - const FunctionProtoType *Proto = cast<FunctionProtoType>(T); - // Record that we're in a function type. See mangleFunctionParam // for details on what we're trying to achieve here. FunctionTypeDepthState saved = FunctionTypeDepth.push(); @@ -2186,7 +2245,20 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T, // <bare-function-type> ::= <signature type>+ if (MangleReturnType) { FunctionTypeDepth.enterResultType(); - mangleType(Proto->getReturnType()); + + // Mangle ns_returns_retained as an order-sensitive qualifier here. + if (Proto->getExtInfo().getProducesResult()) + mangleVendorQualifier("ns_returns_retained"); + + // Mangle the return type without any direct ARC ownership qualifiers. + QualType ReturnTy = Proto->getReturnType(); + if (ReturnTy.getObjCLifetime()) { + auto SplitReturnTy = ReturnTy.split(); + SplitReturnTy.Quals.removeObjCLifetime(); + ReturnTy = getASTContext().getQualifiedType(SplitReturnTy); + } + mangleType(ReturnTy); + FunctionTypeDepth.leaveResultType(); } @@ -2200,7 +2272,13 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T, assert(!FD || FD->getNumParams() == Proto->getNumParams()); for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) { - const auto &ParamTy = Proto->getParamType(I); + // Mangle extended parameter info as order-sensitive qualifiers here. + if (Proto->hasExtParameterInfos()) { + mangleExtParameterInfo(Proto->getExtParameterInfo(I)); + } + + // Mangle the type. + QualType ParamTy = Proto->getParamType(I); mangleType(Context.getASTContext().getSignatureParameterType(ParamTy)); if (FD) { |