diff options
Diffstat (limited to 'lib/AST/MicrosoftMangle.cpp')
-rw-r--r-- | lib/AST/MicrosoftMangle.cpp | 502 |
1 files changed, 337 insertions, 165 deletions
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 48a8fa5..136a43b 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -28,6 +28,7 @@ #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/JamCRC.h" using namespace clang; @@ -160,8 +161,6 @@ public: void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl, raw_ostream &Out) override; void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override; - void mangleCXXVTableBitSet(const CXXRecordDecl *RD, - raw_ostream &Out) override; bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) { // Lambda closure types are already numbered. if (isLambda(ND)) @@ -179,7 +178,9 @@ public: // Anonymous tags are already numbered. if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) { - if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl()) + if (!Tag->hasNameForLinkage() && + !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) && + !getASTContext().getTypedefNameForUnnamedTagDecl(Tag)) return false; } @@ -223,6 +224,9 @@ class MicrosoftCXXNameMangler { typedef llvm::DenseMap<void *, unsigned> ArgBackRefMap; ArgBackRefMap TypeBackReferences; + typedef std::set<int> PassObjectSizeArgsSet; + PassObjectSizeArgsSet PassObjectSizeArgs; + ASTContext &getASTContext() const { return Context.getASTContext(); } // FIXME: If we add support for __ptr32/64 qualifiers, then we should push @@ -262,6 +266,9 @@ public: const CXXMethodDecl *MD, const MicrosoftVTableContext::MethodVFTableLocation &ML); void mangleNumber(int64_t Number); + void mangleTagTypeKind(TagTypeKind TK); + void mangleArtificalTagType(TagTypeKind TK, StringRef UnqualifiedName, + ArrayRef<StringRef> NestedNames = None); void mangleType(QualType T, SourceRange Range, QualifierMangleMode QMM = QMM_Mangle); void mangleFunctionType(const FunctionType *T, @@ -289,6 +296,7 @@ private: void mangleObjCMethodName(const ObjCMethodDecl *MD); void mangleArgumentType(QualType T, SourceRange Range); + void manglePassObjectSizeArg(const PassObjectSizeAttr *POSA); // Declare manglers for every type class. #define ABSTRACT_TYPE(CLASS, PARENT) @@ -364,7 +372,8 @@ bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) { DC = getEffectiveParentContext(DC); if (DC->isTranslationUnit() && D->getFormalLinkage() == InternalLinkage && - !isa<VarTemplateSpecializationDecl>(D)) + !isa<VarTemplateSpecializationDecl>(D) && + D->getIdentifier() != nullptr) return false; } @@ -390,14 +399,8 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) { mangleFunctionEncoding(FD, Context.shouldMangleDeclName(FD)); else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) mangleVariableEncoding(VD); - else { - // TODO: Fields? Can MSVC even mangle them? - // Issue a diagnostic for now. - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, "cannot mangle this declaration yet"); - Diags.Report(D->getLocation(), DiagID) << D->getSourceRange(); - } + else + llvm_unreachable("Tried to mangle unexpected NamedDecl!"); } void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD, @@ -420,7 +423,7 @@ void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD, // We would like to mangle all extern "C" functions using this additional // component but this would break compatibility with MSVC's behavior. // Instead, do this when we know that compatibility isn't important (in - // other words, when it is an overloaded extern "C" funciton). + // other words, when it is an overloaded extern "C" function). if (FD->isExternC() && FD->hasAttr<OverloadableAttr>()) Out << "$$J0"; @@ -695,8 +698,7 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // Function templates aren't considered for name back referencing. This // makes sense since function templates aren't likely to occur multiple // times in a symbol. - // FIXME: Test alias template mangling with MSVC 2013. - if (!isa<ClassTemplateDecl>(TD)) { + if (isa<FunctionTemplateDecl>(TD)) { mangleTemplateInstantiationName(TD, *TemplateArgs); Out << '@'; return; @@ -721,7 +723,6 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, llvm::raw_svector_ostream Stream(TemplateMangling); MicrosoftCXXNameMangler Extra(Context, Stream); Extra.mangleTemplateInstantiationName(TD, *TemplateArgs); - Stream.flush(); mangleSourceName(TemplateMangling); return; @@ -787,14 +788,21 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, } llvm::SmallString<64> Name("<unnamed-type-"); - if (TD->hasDeclaratorForAnonDecl()) { - // Anonymous types with no tag or typedef get the name of their + if (DeclaratorDecl *DD = + Context.getASTContext().getDeclaratorForUnnamedTagDecl(TD)) { + // Anonymous types without a name for linkage purposes have their // declarator mangled in if they have one. - Name += TD->getDeclaratorForAnonDecl()->getName(); + Name += DD->getName(); + } else if (TypedefNameDecl *TND = + Context.getASTContext().getTypedefNameForUnnamedTagDecl( + TD)) { + // Anonymous types without a name for linkage purposes have their + // associate typedef mangled in if they have one. + Name += TND->getName(); } else { // Otherwise, number the types using a $S prefix. Name += "$S"; - Name += llvm::utostr(Context.getAnonymousStructId(TD)); + Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1); } Name += ">"; mangleSourceName(Name.str()); @@ -1039,6 +1047,14 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, break; } + case OO_Coawait: { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this operator co_await yet"); + Diags.Report(Loc, DiagID); + break; + } + case OO_None: case NUM_OVERLOADED_OPERATORS: llvm_unreachable("Not an overloaded operator"); @@ -1071,8 +1087,10 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName( // Templates have their own context for back references. ArgBackRefMap OuterArgsContext; BackRefVec OuterTemplateContext; + PassObjectSizeArgsSet OuterPassObjectSizeArgs; NameBackReferences.swap(OuterTemplateContext); TypeBackReferences.swap(OuterArgsContext); + PassObjectSizeArgs.swap(OuterPassObjectSizeArgs); mangleUnscopedTemplateName(TD); mangleTemplateArgs(TD, TemplateArgs); @@ -1080,6 +1098,7 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName( // Restore the previous back reference contexts. NameBackReferences.swap(OuterTemplateContext); TypeBackReferences.swap(OuterArgsContext); + PassObjectSizeArgs.swap(OuterPassObjectSizeArgs); } void @@ -1121,12 +1140,6 @@ void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) { UE = dyn_cast<CXXUuidofExpr>(E); if (UE) { - // This CXXUuidofExpr is mangled as-if it were actually a VarDecl from - // const __s_GUID _GUID_{lower case UUID with underscores} - StringRef Uuid = UE->getUuidAsStringRef(Context.getASTContext()); - std::string Name = "_GUID_" + Uuid.lower(); - std::replace(Name.begin(), Name.end(), '-', '_'); - // If we had to peek through an address-of operator, treat this like we are // dealing with a pointer type. Otherwise, treat it like a const reference. // @@ -1136,7 +1149,22 @@ void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) { Out << "$E?"; else Out << "$1?"; - Out << Name << "@@3U__s_GUID@@B"; + + // This CXXUuidofExpr is mangled as-if it were actually a VarDecl from + // const __s_GUID _GUID_{lower case UUID with underscores} + StringRef Uuid = UE->getUuidAsStringRef(Context.getASTContext()); + std::string Name = "_GUID_" + Uuid.lower(); + std::replace(Name.begin(), Name.end(), '-', '_'); + + mangleSourceName(Name); + // Terminate the whole name with an '@'. + Out << '@'; + // It's a global variable. + Out << '3'; + // It's a struct called __s_GUID. + mangleArtificalTagType(TTK_Struct, "__s_GUID"); + // It's const. + Out << 'B'; return; } @@ -1210,12 +1238,13 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, QualType T = TA.getNullPtrType(); if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) { const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); - if (MPT->isMemberFunctionPointerType() && isa<ClassTemplateDecl>(TD)) { + if (MPT->isMemberFunctionPointerType() && + !isa<FunctionTemplateDecl>(TD)) { mangleMemberFunctionPointer(RD, nullptr); return; } if (MPT->isMemberDataPointer()) { - if (isa<ClassTemplateDecl>(TD)) { + if (!isa<FunctionTemplateDecl>(TD)) { mangleMemberDataPointer(RD, nullptr); return; } @@ -1455,6 +1484,27 @@ void MicrosoftCXXNameMangler::mangleArgumentType(QualType T, } } +void MicrosoftCXXNameMangler::manglePassObjectSizeArg( + const PassObjectSizeAttr *POSA) { + int Type = POSA->getType(); + + auto Iter = PassObjectSizeArgs.insert(Type).first; + void *TypePtr = (void *)&*Iter; + ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr); + + if (Found == TypeBackReferences.end()) { + mangleArtificalTagType(TTK_Enum, "__pass_object_size" + llvm::utostr(Type), + {"__clang"}); + + if (TypeBackReferences.size() < 10) { + size_t Size = TypeBackReferences.size(); + TypeBackReferences[TypePtr] = Size; + } + } else { + Out << Found->second; + } +} + void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range, QualifierMangleMode QMM) { // Don't use the canonical types. MSVC includes things like 'const' on @@ -1546,29 +1596,72 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, // ::= _W # wchar_t // ::= _Z # __float80 (Digital Mars) switch (T->getKind()) { - case BuiltinType::Void: Out << 'X'; break; - case BuiltinType::SChar: Out << 'C'; break; - case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'D'; break; - case BuiltinType::UChar: Out << 'E'; break; - case BuiltinType::Short: Out << 'F'; break; - case BuiltinType::UShort: Out << 'G'; break; - case BuiltinType::Int: Out << 'H'; break; - case BuiltinType::UInt: Out << 'I'; break; - case BuiltinType::Long: Out << 'J'; break; - case BuiltinType::ULong: Out << 'K'; break; - case BuiltinType::Float: Out << 'M'; break; - case BuiltinType::Double: Out << 'N'; break; + case BuiltinType::Void: + Out << 'X'; + break; + case BuiltinType::SChar: + Out << 'C'; + break; + case BuiltinType::Char_U: + case BuiltinType::Char_S: + Out << 'D'; + break; + case BuiltinType::UChar: + Out << 'E'; + break; + case BuiltinType::Short: + Out << 'F'; + break; + case BuiltinType::UShort: + Out << 'G'; + break; + case BuiltinType::Int: + Out << 'H'; + break; + case BuiltinType::UInt: + Out << 'I'; + break; + case BuiltinType::Long: + Out << 'J'; + break; + case BuiltinType::ULong: + Out << 'K'; + break; + case BuiltinType::Float: + Out << 'M'; + break; + case BuiltinType::Double: + Out << 'N'; + break; // TODO: Determine size and mangle accordingly - case BuiltinType::LongDouble: Out << 'O'; break; - case BuiltinType::LongLong: Out << "_J"; break; - case BuiltinType::ULongLong: Out << "_K"; break; - case BuiltinType::Int128: Out << "_L"; break; - case BuiltinType::UInt128: Out << "_M"; break; - case BuiltinType::Bool: Out << "_N"; break; - case BuiltinType::Char16: Out << "_S"; break; - case BuiltinType::Char32: Out << "_U"; break; + case BuiltinType::LongDouble: + Out << 'O'; + break; + case BuiltinType::LongLong: + Out << "_J"; + break; + case BuiltinType::ULongLong: + Out << "_K"; + break; + case BuiltinType::Int128: + Out << "_L"; + break; + case BuiltinType::UInt128: + Out << "_M"; + break; + case BuiltinType::Bool: + Out << "_N"; + break; + case BuiltinType::Char16: + Out << "_S"; + break; + case BuiltinType::Char32: + Out << "_U"; + break; case BuiltinType::WChar_S: - case BuiltinType::WChar_U: Out << "_W"; break; + case BuiltinType::WChar_U: + Out << "_W"; + break; #define BUILTIN_TYPE(Id, SingletonId) #define PLACEHOLDER_TYPE(Id, SingletonId) \ @@ -1577,28 +1670,102 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, case BuiltinType::Dependent: llvm_unreachable("placeholder types shouldn't get to name mangling"); - case BuiltinType::ObjCId: Out << "PAUobjc_object@@"; break; - case BuiltinType::ObjCClass: Out << "PAUobjc_class@@"; break; - case BuiltinType::ObjCSel: Out << "PAUobjc_selector@@"; break; + case BuiltinType::ObjCId: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "objc_object"); + break; + case BuiltinType::ObjCClass: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "objc_class"); + break; + case BuiltinType::ObjCSel: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "objc_selector"); + break; - case BuiltinType::OCLImage1d: Out << "PAUocl_image1d@@"; break; - case BuiltinType::OCLImage1dArray: Out << "PAUocl_image1darray@@"; break; - case BuiltinType::OCLImage1dBuffer: Out << "PAUocl_image1dbuffer@@"; break; - case BuiltinType::OCLImage2d: Out << "PAUocl_image2d@@"; break; - case BuiltinType::OCLImage2dArray: Out << "PAUocl_image2darray@@"; break; - case BuiltinType::OCLImage3d: Out << "PAUocl_image3d@@"; break; - case BuiltinType::OCLSampler: Out << "PAUocl_sampler@@"; break; - case BuiltinType::OCLEvent: Out << "PAUocl_event@@"; break; + case BuiltinType::OCLImage1d: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image1d"); + break; + case BuiltinType::OCLImage1dArray: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image1darray"); + break; + case BuiltinType::OCLImage1dBuffer: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image1dbuffer"); + break; + case BuiltinType::OCLImage2d: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image2d"); + break; + case BuiltinType::OCLImage2dArray: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image2darray"); + break; + case BuiltinType::OCLImage2dDepth: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image2ddepth"); + break; + case BuiltinType::OCLImage2dArrayDepth: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image2darraydepth"); + break; + case BuiltinType::OCLImage2dMSAA: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image2dmsaa"); + break; + case BuiltinType::OCLImage2dArrayMSAA: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image2darraymsaa"); + break; + case BuiltinType::OCLImage2dMSAADepth: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image2dmsaadepth"); + break; + case BuiltinType::OCLImage2dArrayMSAADepth: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image2darraymsaadepth"); + break; + case BuiltinType::OCLImage3d: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_image3d"); + break; + case BuiltinType::OCLSampler: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_sampler"); + break; + case BuiltinType::OCLEvent: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_event"); + break; + case BuiltinType::OCLClkEvent: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_clkevent"); + break; + case BuiltinType::OCLQueue: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_queue"); + break; + case BuiltinType::OCLNDRange: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_ndrange"); + break; + case BuiltinType::OCLReserveID: + Out << "PA"; + mangleArtificalTagType(TTK_Struct, "ocl_reserveid"); + break; - case BuiltinType::NullPtr: Out << "$$T"; break; + case BuiltinType::NullPtr: + Out << "$$T"; + break; case BuiltinType::Half: { DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this built-in %0 type yet"); + unsigned DiagID = Diags.getCustomDiagID( + DiagnosticsEngine::Error, "cannot mangle this built-in %0 type yet"); Diags.Report(Range.getBegin(), DiagID) - << T->getName(Context.getASTContext().getPrintingPolicy()) - << Range; + << T->getName(Context.getASTContext().getPrintingPolicy()) << Range; break; } } @@ -1620,7 +1787,8 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, Qualifiers, } void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T, Qualifiers, SourceRange) { - llvm_unreachable("Can't mangle K&R function prototypes"); + Out << "$$A6"; + mangleFunctionType(T); } void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, @@ -1628,7 +1796,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, bool ForceThisQuals) { // <function-type> ::= <this-cvr-qualifiers> <calling-convention> // <return-type> <argument-list> <throw-spec> - const FunctionProtoType *Proto = cast<FunctionProtoType>(T); + const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T); SourceRange Range; if (D) Range = D->getSourceRange(); @@ -1699,12 +1867,14 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, } Out << '@'; } else { - QualType ResultType = Proto->getReturnType(); + QualType ResultType = T->getReturnType(); if (const auto *AT = dyn_cast_or_null<AutoType>(ResultType->getContainedAutoType())) { Out << '?'; mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false); Out << '?'; + assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType && + "shouldn't need to mangle __auto_type!"); mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>"); Out << '@'; } else { @@ -1717,12 +1887,29 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, // <argument-list> ::= X # void // ::= <type>+ @ // ::= <type>* Z # varargs - if (Proto->getNumParams() == 0 && !Proto->isVariadic()) { + if (!Proto) { + // Function types without prototypes can arise when mangling a function type + // within an overloadable function in C. We mangle these as the absence of + // any parameter types (not even an empty parameter list). + Out << '@'; + } else if (Proto->getNumParams() == 0 && !Proto->isVariadic()) { Out << 'X'; } else { // Happens for function pointer type arguments for example. - for (const QualType &Arg : Proto->param_types()) - mangleArgumentType(Arg, Range); + for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) { + mangleArgumentType(Proto->getParamType(I), Range); + // Mangle each pass_object_size parameter as if it's a paramater of enum + // type passed directly after the parameter with the pass_object_size + // attribute. The aforementioned enum's name is __pass_object_size, and we + // pretend it resides in a top-level namespace called __clang. + // + // FIXME: Is there a defined extension notation for the MS ABI, or is it + // necessary to just cross our fingers and hope this type+namespace + // combination doesn't conflict with anything? + if (D) + if (const auto *P = D->getParamDecl(I)->getAttr<PassObjectSizeAttr>()) + manglePassObjectSizeArg(P); + } // <builtin-type> ::= Z # ellipsis if (Proto->isVariadic()) Out << 'Z'; @@ -1851,16 +2038,8 @@ void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T, // <struct-type> ::= U <name> // <class-type> ::= V <name> // <enum-type> ::= W4 <name> -void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers, - SourceRange) { - mangleType(cast<TagType>(T)->getDecl()); -} -void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers, - SourceRange) { - mangleType(cast<TagType>(T)->getDecl()); -} -void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) { - switch (TD->getTagKind()) { +void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) { + switch (TTK) { case TTK_Union: Out << 'T'; break; @@ -1875,8 +2054,33 @@ void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) { Out << "W4"; break; } +} +void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers, + SourceRange) { + mangleType(cast<TagType>(T)->getDecl()); +} +void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers, + SourceRange) { + mangleType(cast<TagType>(T)->getDecl()); +} +void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) { + mangleTagTypeKind(TD->getTagKind()); mangleName(TD); } +void MicrosoftCXXNameMangler::mangleArtificalTagType( + TagTypeKind TK, StringRef UnqualifiedName, ArrayRef<StringRef> NestedNames) { + // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @ + mangleTagTypeKind(TK); + + // Always start with the unqualified name. + mangleSourceName(UnqualifiedName); + + for (auto I = NestedNames.rbegin(), E = NestedNames.rend(); I != E; ++I) + mangleSourceName(*I); + + // Terminate the whole name with an '@'. + Out << '@'; +} // <type> ::= <array-type> // <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> @@ -2029,11 +2233,16 @@ void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T, void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this complex number type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + QualType ElementType = T->getElementType(); + + llvm::SmallString<64> TemplateMangling; + llvm::raw_svector_ostream Stream(TemplateMangling); + MicrosoftCXXNameMangler Extra(Context, Stream); + Stream << "?$"; + Extra.mangleSourceName("_Complex"); + Extra.mangleType(ElementType, Range, QMM_Escape); + + mangleArtificalTagType(TTK_Struct, TemplateMangling, {"__clang"}); } void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals, @@ -2043,46 +2252,44 @@ void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals, uint64_t Width = getASTContext().getTypeSize(T); // Pattern match exactly the typedefs in our intrinsic headers. Anything that // doesn't match the Intel types uses a custom mangling below. - bool IsBuiltin = true; + size_t OutSizeBefore = Out.tell(); llvm::Triple::ArchType AT = getASTContext().getTargetInfo().getTriple().getArch(); if (AT == llvm::Triple::x86 || AT == llvm::Triple::x86_64) { if (Width == 64 && ET->getKind() == BuiltinType::LongLong) { - Out << "T__m64"; + mangleArtificalTagType(TTK_Union, "__m64"); } else if (Width >= 128) { if (ET->getKind() == BuiltinType::Float) - Out << "T__m" << Width; + mangleArtificalTagType(TTK_Union, "__m" + llvm::utostr(Width)); else if (ET->getKind() == BuiltinType::LongLong) - Out << "T__m" << Width << 'i'; + mangleArtificalTagType(TTK_Union, "__m" + llvm::utostr(Width) + 'i'); else if (ET->getKind() == BuiltinType::Double) - Out << "U__m" << Width << 'd'; - else - IsBuiltin = false; - } else { - IsBuiltin = false; + mangleArtificalTagType(TTK_Struct, "__m" + llvm::utostr(Width) + 'd'); } - } else { - IsBuiltin = false; } + bool IsBuiltin = Out.tell() != OutSizeBefore; if (!IsBuiltin) { // The MS ABI doesn't have a special mangling for vector types, so we define // our own mangling to handle uses of __vector_size__ on user-specified // types, and for extensions like __v4sf. - Out << "T__clang_vec" << T->getNumElements() << '_'; - mangleType(ET, Quals, Range); - } - Out << "@@"; + llvm::SmallString<64> TemplateMangling; + llvm::raw_svector_ostream Stream(TemplateMangling); + MicrosoftCXXNameMangler Extra(Context, Stream); + Stream << "?$"; + Extra.mangleSourceName("__vector"); + Extra.mangleType(QualType(ET, 0), Range, QMM_Escape); + Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()), + /*IsBoolean=*/false); + + mangleArtificalTagType(TTK_Union, TemplateMangling, {"__clang"}); + } } -void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T, Qualifiers, - SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this extended vector type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; +void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T, + Qualifiers Quals, SourceRange Range) { + mangleType(static_cast<const VectorType *>(T), Quals, Range); } void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T, Qualifiers, SourceRange Range) { @@ -2096,7 +2303,7 @@ void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T, void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers, SourceRange) { // ObjC interfaces have structs underlying them. - Out << 'U'; + mangleTagTypeKind(TTK_Struct); mangleName(T->getDecl()); } @@ -2209,11 +2416,16 @@ void MicrosoftCXXNameMangler::mangleType(const AutoType *T, Qualifiers, void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this C11 atomic type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + QualType ValueType = T->getValueType(); + + llvm::SmallString<64> TemplateMangling; + llvm::raw_svector_ostream Stream(TemplateMangling); + MicrosoftCXXNameMangler Extra(Context, Stream); + Stream << "?$"; + Extra.mangleSourceName("_Atomic"); + Extra.mangleType(ValueType, Range, QMM_Escape); + + mangleArtificalTagType(TTK_Struct, TemplateMangling, {"__clang"}); } void MicrosoftMangleContextImpl::mangleCXXName(const NamedDecl *D, @@ -2574,12 +2786,12 @@ void MicrosoftMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D, mangler.mangle(D); } -void MicrosoftMangleContextImpl::mangleReferenceTemporary(const VarDecl *VD, - unsigned, - raw_ostream &) { - unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this reference temporary yet"); - getDiags().Report(VD->getLocation(), DiagID); +void MicrosoftMangleContextImpl::mangleReferenceTemporary( + const VarDecl *VD, unsigned ManglingNumber, raw_ostream &Out) { + MicrosoftCXXNameMangler Mangler(*this, Out); + + Mangler.getStream() << "\01?$RT" << ManglingNumber << '@'; + Mangler.mangle(VD, ""); } void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable( @@ -2688,28 +2900,6 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL, // N.B. The length is in terms of bytes, not characters. Mangler.mangleNumber(SL->getByteLength() + SL->getCharByteWidth()); - // We will use the "Rocksoft^tm Model CRC Algorithm" to describe the - // properties of our CRC: - // Width : 32 - // Poly : 04C11DB7 - // Init : FFFFFFFF - // RefIn : True - // RefOut : True - // XorOut : 00000000 - // Check : 340BC6D9 - uint32_t CRC = 0xFFFFFFFFU; - - auto UpdateCRC = [&CRC](char Byte) { - for (unsigned i = 0; i < 8; ++i) { - bool Bit = CRC & 0x80000000U; - if (Byte & (1U << i)) - Bit = !Bit; - CRC <<= 1; - if (Bit) - CRC ^= 0x04C11DB7U; - } - }; - auto GetLittleEndianByte = [&Mangler, &SL](unsigned Index) { unsigned CharByteWidth = SL->getCharByteWidth(); uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth); @@ -2725,22 +2915,19 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL, }; // CRC all the bytes of the StringLiteral. + llvm::JamCRC JC; for (unsigned I = 0, E = SL->getByteLength(); I != E; ++I) - UpdateCRC(GetLittleEndianByte(I)); + JC.update(GetLittleEndianByte(I)); // The NUL terminator byte(s) were not present earlier, // we need to manually process those bytes into the CRC. for (unsigned NullTerminator = 0; NullTerminator < SL->getCharByteWidth(); ++NullTerminator) - UpdateCRC('\x00'); - - // The literature refers to the process of reversing the bits in the final CRC - // output as "reflection". - CRC = llvm::reverseBits(CRC); + JC.update('\x00'); // <encoded-crc>: The CRC is encoded utilizing the standard number mangling // scheme. - Mangler.mangleNumber(CRC); + Mangler.mangleNumber(JC.getCRC()); // <encoded-string>: The mangled name also contains the first 32 _characters_ // (including null-terminator bytes) of the StringLiteral. @@ -2790,21 +2977,6 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL, Mangler.getStream() << '@'; } -void MicrosoftMangleContextImpl::mangleCXXVTableBitSet(const CXXRecordDecl *RD, - raw_ostream &Out) { - if (!RD->isExternallyVisible()) { - // This part of the identifier needs to be unique across all translation - // units in the linked program. The scheme fails if multiple translation - // units are compiled using the same relative source file path, or if - // multiple translation units are built from the same source file. - SourceManager &SM = getASTContext().getSourceManager(); - Out << "[" << SM.getFileEntryForID(SM.getMainFileID())->getName() << "]"; - } - - MicrosoftCXXNameMangler mangler(*this, Out); - mangler.mangleName(RD); -} - MicrosoftMangleContext * MicrosoftMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) { return new MicrosoftMangleContextImpl(Context, Diags); |