From 7a3ce0c537023553eb3bf4c8d7bb696e66b8a2ff Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 26 May 2015 01:30:45 +0000 Subject: [PATCH] [MS ABI] Implement restrict qualified references MSVC 2015 supports '__restrict' qualified reference types. llvm-svn: 238166 --- clang/lib/AST/MicrosoftMangle.cpp | 139 +++++++++++---------- .../CodeGenCXX/mangle-ms-return-qualifiers.cpp | 4 + 2 files changed, 78 insertions(+), 65 deletions(-) diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 894db88..77522c1 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -277,7 +277,7 @@ private: void mangleQualifiers(Qualifiers Quals, bool IsMember); void mangleRefQualifier(RefQualifierKind RefQualifier); void manglePointerCVQualifiers(Qualifiers Quals); - void manglePointerExtQualifiers(Qualifiers Quals, const Type *PointeeType); + void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType); void mangleUnscopedTemplateName(const TemplateDecl *ND); void @@ -291,6 +291,7 @@ private: #define ABSTRACT_TYPE(CLASS, PARENT) #define NON_CANONICAL_TYPE(CLASS, PARENT) #define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \ + Qualifiers Quals, \ SourceRange Range); #include "clang/AST/TypeNodes.def" #undef ABSTRACT_TYPE @@ -461,7 +462,7 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) { Ty->isMemberPointerType()) { mangleType(Ty, SR, QMM_Drop); manglePointerExtQualifiers( - Ty.getDesugaredType(getASTContext()).getLocalQualifiers(), nullptr); + Ty.getDesugaredType(getASTContext()).getLocalQualifiers(), QualType()); if (const MemberPointerType *MPT = Ty->getAs()) { mangleQualifiers(MPT->getPointeeType().getQualifiers(), true); // Member pointers are suffixed with a back reference to the member @@ -1351,11 +1352,11 @@ MicrosoftCXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) { } } -void -MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals, - const Type *PointeeType) { +void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals, + QualType PointeeType) { bool HasRestrict = Quals.hasRestrict(); - if (PointersAre64Bit && (!PointeeType || !PointeeType->isFunctionType())) + if (PointersAre64Bit && + (PointeeType.isNull() || !PointeeType->isFunctionType())) Out << 'E'; if (HasRestrict) @@ -1450,7 +1451,7 @@ void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range, } bool IsPointer = T->isAnyPointerType() || T->isMemberPointerType() || - T->isBlockPointerType(); + T->isReferenceType() || T->isBlockPointerType(); switch (QMM) { case QMM_Drop: @@ -1477,11 +1478,6 @@ void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range, break; } - // We have to mangle these now, while we still have enough information. - if (IsPointer) { - manglePointerCVQualifiers(Quals); - manglePointerExtQualifiers(Quals, T->getPointeeType().getTypePtr()); - } const Type *ty = T.getTypePtr(); switch (ty->getTypeClass()) { @@ -1492,7 +1488,7 @@ void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range, return; #define TYPE(CLASS, PARENT) \ case Type::CLASS: \ - mangleType(cast(ty), Range); \ + mangleType(cast(ty), Quals, Range); \ break; #include "clang/AST/TypeNodes.def" #undef ABSTRACT_TYPE @@ -1501,7 +1497,7 @@ void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range, } } -void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, +void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, SourceRange Range) { // ::= // ::= X # void @@ -1587,7 +1583,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, } // ::= -void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, +void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, Qualifiers, SourceRange) { // Structors only appear in decls, so at this point we know it's not a // structor type. @@ -1601,7 +1597,7 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, } } void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T, - SourceRange) { + Qualifiers, SourceRange) { llvm_unreachable("Can't mangle K&R function prototypes"); } @@ -1637,7 +1633,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, // this pointer. if (HasThisQuals) { Qualifiers Quals = Qualifiers::fromCVRMask(Proto->getTypeQuals()); - manglePointerExtQualifiers(Quals, /*PointeeType=*/nullptr); + manglePointerExtQualifiers(Quals, /*PointeeType=*/QualType()); mangleRefQualifier(Proto->getRefQualifier()); mangleQualifiers(Quals, /*IsMember=*/false); } @@ -1818,7 +1814,7 @@ void MicrosoftCXXNameMangler::mangleThrowSpecification( } void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T, - SourceRange Range) { + Qualifiers, SourceRange Range) { // Probably should be mangled as a template instantiation; need to see what // VC does first. DiagnosticsEngine &Diags = Context.getDiags(); @@ -1833,10 +1829,12 @@ void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T, // ::= U // ::= V // ::= W4 -void MicrosoftCXXNameMangler::mangleType(const EnumType *T, SourceRange) { +void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers, + SourceRange) { mangleType(cast(T)->getDecl()); } -void MicrosoftCXXNameMangler::mangleType(const RecordType *T, SourceRange) { +void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers, + SourceRange) { mangleType(cast(T)->getDecl()); } void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) { @@ -1871,20 +1869,20 @@ void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) { manglePointerCVQualifiers(T->getElementType().getQualifiers()); mangleType(T->getElementType(), SourceRange()); } -void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T, +void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T, Qualifiers, SourceRange) { llvm_unreachable("Should have been special cased"); } -void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T, +void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T, Qualifiers, SourceRange) { llvm_unreachable("Should have been special cased"); } void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T, - SourceRange) { + Qualifiers, SourceRange) { llvm_unreachable("Should have been special cased"); } void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T, - SourceRange) { + Qualifiers, SourceRange) { llvm_unreachable("Should have been special cased"); } void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) { @@ -1931,9 +1929,11 @@ void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) { // ::= // ::= // -void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T, +void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T, Qualifiers Quals, SourceRange Range) { QualType PointeeType = T->getPointeeType(); + manglePointerCVQualifiers(Quals); + manglePointerExtQualifiers(Quals, PointeeType); if (const FunctionProtoType *FPT = PointeeType->getAs()) { Out << '8'; mangleName(T->getClass()->castAs()->getDecl()); @@ -1946,7 +1946,7 @@ void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T, } void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T, - SourceRange Range) { + Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "cannot mangle this template type parameter type yet"); @@ -1954,9 +1954,8 @@ void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T, << Range; } -void MicrosoftCXXNameMangler::mangleType( - const SubstTemplateTypeParmPackType *T, - SourceRange Range) { +void MicrosoftCXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T, + Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "cannot mangle this substituted parameter pack yet"); @@ -1967,40 +1966,46 @@ void MicrosoftCXXNameMangler::mangleType( // ::= // ::= E? // # the E is required for 64-bit non-static pointers -void MicrosoftCXXNameMangler::mangleType(const PointerType *T, +void MicrosoftCXXNameMangler::mangleType(const PointerType *T, Qualifiers Quals, SourceRange Range) { - QualType PointeeTy = T->getPointeeType(); - mangleType(PointeeTy, Range); + QualType PointeeType = T->getPointeeType(); + manglePointerCVQualifiers(Quals); + manglePointerExtQualifiers(Quals, PointeeType); + mangleType(PointeeType, Range); } void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T, - SourceRange Range) { + Qualifiers Quals, SourceRange Range) { + QualType PointeeType = T->getPointeeType(); + manglePointerCVQualifiers(Quals); + manglePointerExtQualifiers(Quals, PointeeType); // Object pointers never have qualifiers. Out << 'A'; - manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr()); - mangleType(T->getPointeeType(), Range); + mangleType(PointeeType, Range); } // ::= // ::= A E? // # the E is required for 64-bit non-static lvalue references void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T, - SourceRange Range) { - Out << 'A'; - manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr()); - mangleType(T->getPointeeType(), Range); + Qualifiers Quals, SourceRange Range) { + QualType PointeeType = T->getPointeeType(); + Out << (Quals.hasVolatile() ? 'B' : 'A'); + manglePointerExtQualifiers(Quals, PointeeType); + mangleType(PointeeType, Range); } // ::= // ::= $$Q E? // # the E is required for 64-bit non-static rvalue references void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T, - SourceRange Range) { - Out << "$$Q"; - manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr()); - mangleType(T->getPointeeType(), Range); + Qualifiers Quals, SourceRange Range) { + QualType PointeeType = T->getPointeeType(); + Out << (Quals.hasVolatile() ? "$$R" : "$$Q"); + manglePointerExtQualifiers(Quals, PointeeType); + mangleType(PointeeType, Range); } -void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, +void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, @@ -2009,7 +2014,7 @@ void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, << Range; } -void MicrosoftCXXNameMangler::mangleType(const VectorType *T, +void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals, SourceRange Range) { const BuiltinType *ET = T->getElementType()->getAs(); assert(ET && "vectors with non-builtin elements are unsupported"); @@ -2037,13 +2042,13 @@ void MicrosoftCXXNameMangler::mangleType(const VectorType *T, // 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, Range); + mangleType(ET, Quals, Range); } Out << "@@"; } -void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T, +void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T, Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, @@ -2052,7 +2057,7 @@ void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T, << Range; } void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T, - SourceRange Range) { + Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "cannot mangle this dependent-sized extended vector type yet"); @@ -2060,14 +2065,14 @@ void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T, << Range; } -void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, +void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers, SourceRange) { // ObjC interfaces have structs underlying them. Out << 'U'; mangleName(T->getDecl()); } -void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T, +void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T, Qualifiers, SourceRange Range) { // We don't allow overloading by different protocol qualification, // so mangling them isn't necessary. @@ -2075,20 +2080,23 @@ void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T, } void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T, - SourceRange Range) { + Qualifiers Quals, SourceRange Range) { + QualType PointeeType = T->getPointeeType(); + manglePointerCVQualifiers(Quals); + manglePointerExtQualifiers(Quals, PointeeType); + Out << "_E"; - QualType pointee = T->getPointeeType(); - mangleFunctionType(pointee->castAs()); + mangleFunctionType(PointeeType->castAs()); } void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *, - SourceRange) { + Qualifiers, SourceRange) { llvm_unreachable("Cannot mangle injected class name type."); } void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T, - SourceRange Range) { + Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "cannot mangle this template specialization type yet"); @@ -2096,7 +2104,7 @@ void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T, << Range; } -void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T, +void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T, Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, @@ -2106,8 +2114,8 @@ void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T, } void MicrosoftCXXNameMangler::mangleType( - const DependentTemplateSpecializationType *T, - SourceRange Range) { + const DependentTemplateSpecializationType *T, Qualifiers, + SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "cannot mangle this dependent template specialization type yet"); @@ -2115,7 +2123,7 @@ void MicrosoftCXXNameMangler::mangleType( << Range; } -void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T, +void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T, Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, @@ -2124,7 +2132,7 @@ void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T, << Range; } -void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T, +void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T, Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, @@ -2133,7 +2141,7 @@ void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T, << Range; } -void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T, +void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T, Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, @@ -2142,7 +2150,7 @@ void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T, << Range; } -void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T, +void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T, Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, @@ -2152,7 +2160,7 @@ void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T, } void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T, - SourceRange Range) { + Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "cannot mangle this unary transform type yet"); @@ -2160,7 +2168,8 @@ void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T, << Range; } -void MicrosoftCXXNameMangler::mangleType(const AutoType *T, SourceRange Range) { +void MicrosoftCXXNameMangler::mangleType(const AutoType *T, Qualifiers, + SourceRange Range) { assert(T->getDeducedType().isNull() && "expecting a dependent type!"); DiagnosticsEngine &Diags = Context.getDiags(); @@ -2170,7 +2179,7 @@ void MicrosoftCXXNameMangler::mangleType(const AutoType *T, SourceRange Range) { << Range; } -void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, +void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, diff --git a/clang/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp b/clang/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp index 37bbf09..8b666e4 100644 --- a/clang/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp +++ b/clang/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp @@ -183,3 +183,7 @@ function_pointer* g3() { return 0; } const function_pointer* g4() { return 0; } // CHECK: "\01?g4@@YAPBQ6AHH@ZXZ" + +extern int &z; +int & __restrict h1() { return z; } +// CHECK: "\01?h1@@YAAIAHXZ" -- 2.7.4