diff options
Diffstat (limited to 'lib/AST/MicrosoftMangle.cpp')
-rw-r--r-- | lib/AST/MicrosoftMangle.cpp | 822 |
1 files changed, 664 insertions, 158 deletions
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index ba9856a..e2cee7f 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -21,6 +21,8 @@ #include "clang/AST/ExprCXX.h" #include "clang/Basic/ABI.h" +#include <map> + using namespace clang; namespace { @@ -31,36 +33,59 @@ class MicrosoftCXXNameMangler { MangleContext &Context; raw_ostream &Out; + // FIXME: audit the performance of BackRefMap as it might do way too many + // copying of strings. + typedef std::map<std::string, unsigned> BackRefMap; + BackRefMap NameBackReferences; + bool UseNameBackReferences; + + typedef llvm::DenseMap<void*, unsigned> ArgBackRefMap; + ArgBackRefMap TypeBackReferences; + ASTContext &getASTContext() const { return Context.getASTContext(); } public: MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_) - : Context(C), Out(Out_) { } + : Context(C), Out(Out_), UseNameBackReferences(true) { } + + raw_ostream &getStream() const { return Out; } - void mangle(const NamedDecl *D, StringRef Prefix = "?"); + void mangle(const NamedDecl *D, StringRef Prefix = "\01?"); void mangleName(const NamedDecl *ND); void mangleFunctionEncoding(const FunctionDecl *FD); void mangleVariableEncoding(const VarDecl *VD); void mangleNumber(int64_t Number); - void mangleType(QualType T); + void mangleNumber(const llvm::APSInt &Value); + void mangleType(QualType T, SourceRange Range); private: + void disableBackReferences() { UseNameBackReferences = false; } void mangleUnqualifiedName(const NamedDecl *ND) { mangleUnqualifiedName(ND, ND->getDeclName()); } void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name); void mangleSourceName(const IdentifierInfo *II); void manglePostfix(const DeclContext *DC, bool NoFunction=false); - void mangleOperatorName(OverloadedOperatorKind OO); + void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc); void mangleQualifiers(Qualifiers Quals, bool IsMember); + void mangleUnscopedTemplateName(const TemplateDecl *ND); + void mangleTemplateInstantiationName(const TemplateDecl *TD, + const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs); void mangleObjCMethodName(const ObjCMethodDecl *MD); + void mangleLocalName(const FunctionDecl *FD); + + void mangleTypeRepeated(QualType T, SourceRange Range); // Declare manglers for every type class. #define ABSTRACT_TYPE(CLASS, PARENT) #define NON_CANONICAL_TYPE(CLASS, PARENT) -#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T); +#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \ + SourceRange Range); #include "clang/AST/TypeNodes.def" +#undef ABSTRACT_TYPE +#undef NON_CANONICAL_TYPE +#undef TYPE void mangleType(const TagType*); void mangleType(const FunctionType *T, const FunctionDecl *D, @@ -69,8 +94,12 @@ private: void mangleExtraDimensions(QualType T); void mangleFunctionClass(const FunctionDecl *FD); void mangleCallingConvention(const FunctionType *T, bool IsInstMethod = false); + void mangleIntegerLiteral(QualType T, const llvm::APSInt &Number); void mangleThrowSpecification(const FunctionProtoType *T); + void mangleTemplateArgs( + const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs); + }; /// MicrosoftMangleContext - Overrides the default MangleContext for the @@ -157,15 +186,15 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) { // MSVC doesn't mangle C++ names the same way it mangles extern "C" names. // Therefore it's really important that we don't decorate the - // name with leading underscores or leading/trailing at signs. So, emit a - // asm marker at the start so we get the name right. - Out << '\01'; // LLVM IR Marker for __asm("foo") + // name with leading underscores or leading/trailing at signs. So, by + // default, we emit an asm marker at the start so we get the name right. + // Callers can override this with a custom prefix. // Any decl can be declared with __asm("foo") on it, and this takes precedence // over all other naming in the .o file. if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) { // If we have an asm name, then we use it as the mangling. - Out << ALA->getLabel(); + Out << '\01' << ALA->getLabel(); return; } @@ -176,7 +205,15 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, mangleFunctionEncoding(FD); else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) mangleVariableEncoding(VD); - // TODO: Fields? Can MSVC even mangle them? + 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(); + } } void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { @@ -188,7 +225,7 @@ void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { // We should never ever see a FunctionNoProtoType at this point. // We don't even know how to mangle their types anyway :). - const FunctionProtoType *FT = cast<FunctionProtoType>(FD->getType()); + const FunctionProtoType *FT = FD->getType()->castAs<FunctionProtoType>(); bool InStructor = false, InInstMethod = false; const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD); @@ -232,16 +269,17 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) { // ::= <type> A # pointers, references, arrays // Pointers and references are odd. The type of 'int * const foo;' gets // mangled as 'QAHA' instead of 'PAHB', for example. - QualType Ty = VD->getType(); + TypeLoc TL = VD->getTypeSourceInfo()->getTypeLoc(); + QualType Ty = TL.getType(); if (Ty->isPointerType() || Ty->isReferenceType()) { - mangleType(Ty); + mangleType(Ty, TL.getSourceRange()); Out << 'A'; - } else if (Ty->isArrayType()) { + } else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) { // Global arrays are funny, too. - mangleType(cast<ArrayType>(Ty.getTypePtr()), true); + mangleType(AT, true); Out << 'A'; } else { - mangleType(Ty.getLocalUnqualifiedType()); + mangleType(Ty.getLocalUnqualifiedType(), TL.getSourceRange()); mangleQualifiers(Ty.getLocalQualifiers(), false); } } @@ -266,35 +304,156 @@ void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) { } void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) { - // <number> ::= [?] <decimal digit> # <= 9 - // ::= [?] <hex digit>+ @ # > 9; A = 0, B = 1, etc... + // <number> ::= [?] <decimal digit> # 1 <= Number <= 10 + // ::= [?] <hex digit>+ @ # 0 or > 9; A = 0, B = 1, etc... + // ::= [?] @ # 0 (alternate mangling, not emitted by VC) if (Number < 0) { Out << '?'; Number = -Number; } - if (Number >= 1 && Number <= 10) { + // There's a special shorter mangling for 0, but Microsoft + // chose not to use it. Instead, 0 gets mangled as "A@". Oh well... + if (Number >= 1 && Number <= 10) Out << Number-1; - } else { + else { // We have to build up the encoding in reverse order, so it will come // out right when we write it out. char Encoding[16]; char *EndPtr = Encoding+sizeof(Encoding); char *CurPtr = EndPtr; - while (Number) { + do { *--CurPtr = 'A' + (Number % 16); Number /= 16; + } while (Number); + Out.write(CurPtr, EndPtr-CurPtr); + Out << '@'; + } +} + +void MicrosoftCXXNameMangler::mangleNumber(const llvm::APSInt &Value) { + if (Value.isSigned() && Value.isNegative()) { + Out << '?'; + mangleNumber(llvm::APSInt(Value.abs())); + return; + } + llvm::APSInt Temp(Value); + if (Value.uge(1) && Value.ule(10)) { + --Temp; + Temp.print(Out, false); + } else { + // We have to build up the encoding in reverse order, so it will come + // out right when we write it out. + char Encoding[64]; + char *EndPtr = Encoding+sizeof(Encoding); + char *CurPtr = EndPtr; + llvm::APSInt NibbleMask(Value.getBitWidth(), Value.isUnsigned()); + NibbleMask = 0xf; + for (int i = 0, e = Value.getActiveBits() / 4; i != e; ++i) { + *--CurPtr = 'A' + Temp.And(NibbleMask).getLimitedValue(0xf); + Temp = Temp.lshr(4); } Out.write(CurPtr, EndPtr-CurPtr); Out << '@'; } } +static const TemplateDecl * +isTemplate(const NamedDecl *ND, + SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) { + // Check if we have a function template. + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){ + if (const TemplateDecl *TD = FD->getPrimaryTemplate()) { + if (FD->getTemplateSpecializationArgsAsWritten()) { + const ASTTemplateArgumentListInfo *ArgList = + FD->getTemplateSpecializationArgsAsWritten(); + TemplateArgs.append(ArgList->getTemplateArgs(), + ArgList->getTemplateArgs() + + ArgList->NumTemplateArgs); + } else { + const TemplateArgumentList *ArgList = + FD->getTemplateSpecializationArgs(); + TemplateArgumentListInfo LI; + for (unsigned i = 0, e = ArgList->size(); i != e; ++i) + TemplateArgs.push_back(TemplateArgumentLoc(ArgList->get(i), + FD->getTypeSourceInfo())); + } + return TD; + } + } + + // Check if we have a class template. + if (const ClassTemplateSpecializationDecl *Spec = + dyn_cast<ClassTemplateSpecializationDecl>(ND)) { + TypeSourceInfo *TSI = Spec->getTypeAsWritten(); + if (TSI) { + TemplateSpecializationTypeLoc &TSTL = + cast<TemplateSpecializationTypeLoc>(TSI->getTypeLoc()); + TemplateArgumentListInfo LI(TSTL.getLAngleLoc(), TSTL.getRAngleLoc()); + for (unsigned i = 0, e = TSTL.getNumArgs(); i != e; ++i) + TemplateArgs.push_back(TSTL.getArgLoc(i)); + } else { + TemplateArgumentListInfo LI; + const TemplateArgumentList &ArgList = + Spec->getTemplateArgs(); + for (unsigned i = 0, e = ArgList.size(); i != e; ++i) + TemplateArgs.push_back(TemplateArgumentLoc(ArgList[i], + TemplateArgumentLocInfo())); + } + return Spec->getSpecializedTemplate(); + } + + return 0; +} + void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name) { // <unqualified-name> ::= <operator-name> // ::= <ctor-dtor-name> // ::= <source-name> + // ::= <template-name> + SmallVector<TemplateArgumentLoc, 2> TemplateArgs; + // Check if we have a template. + if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + // We have a template. + // Here comes the tricky thing: if we need to mangle something like + // void foo(A::X<Y>, B::X<Y>), + // the X<Y> part is aliased. However, if you need to mangle + // void foo(A::X<A::Y>, A::X<B::Y>), + // the A::X<> part is not aliased. + // That said, from the mangler's perspective we have a structure like this: + // namespace[s] -> type[ -> template-parameters] + // but from the Clang perspective we have + // type [ -> template-parameters] + // \-> namespace[s] + // What we do is we create a new mangler, mangle the same type (without + // a namespace suffix) using the extra mangler with back references + // disabled (to avoid infinite recursion) and then use the mangled type + // name as a key to check the mangling of different types for aliasing. + + std::string BackReferenceKey; + BackRefMap::iterator Found; + if (UseNameBackReferences) { + llvm::raw_string_ostream Stream(BackReferenceKey); + MicrosoftCXXNameMangler Extra(Context, Stream); + Extra.disableBackReferences(); + Extra.mangleUnqualifiedName(ND, Name); + Stream.flush(); + + Found = NameBackReferences.find(BackReferenceKey); + } + if (!UseNameBackReferences || Found == NameBackReferences.end()) { + mangleTemplateInstantiationName(TD, TemplateArgs); + if (UseNameBackReferences && NameBackReferences.size() < 10) { + size_t Size = NameBackReferences.size(); + NameBackReferences[BackReferenceKey] = Size; + } + } else { + Out << Found->second; + } + return; + } + switch (Name.getNameKind()) { case DeclarationName::Identifier: { if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) { @@ -349,12 +508,17 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, break; case DeclarationName::CXXOperatorName: - mangleOperatorName(Name.getCXXOverloadedOperator()); + mangleOperatorName(Name.getCXXOverloadedOperator(), ND->getLocation()); break; - case DeclarationName::CXXLiteralOperatorName: + case DeclarationName::CXXLiteralOperatorName: { // FIXME: Was this added in VS2010? Does MS even know how to mangle this? - llvm_unreachable("Don't know how to mangle literal operators yet!"); + DiagnosticsEngine Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this literal operator yet"); + Diags.Report(ND->getLocation(), DiagID); + break; + } case DeclarationName::CXXUsingDirective: llvm_unreachable("Can't mangle a using directive name!"); @@ -364,8 +528,6 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC, bool NoFunction) { // <postfix> ::= <unqualified-name> [<postfix>] - // ::= <template-postfix> <template-args> [<postfix>] - // ::= <template-param> // ::= <substitution> [<postfix>] if (!DC) return; @@ -386,13 +548,16 @@ void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC, return; else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) mangleObjCMethodName(Method); + else if (const FunctionDecl *Func = dyn_cast<FunctionDecl>(DC)) + mangleLocalName(Func); else { mangleUnqualifiedName(cast<NamedDecl>(DC)); manglePostfix(DC->getParent(), NoFunction); } } -void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO) { +void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, + SourceLocation Loc) { switch (OO) { // ?0 # constructor // ?1 # destructor @@ -509,8 +674,13 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO) { // <operator-name> ::= ?_V # delete[] case OO_Array_Delete: Out << "?_V"; break; - case OO_Conditional: - llvm_unreachable("Don't know how to mangle ?:"); + case OO_Conditional: { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this conditional operator yet"); + Diags.Report(Loc, DiagID); + break; + } case OO_None: case NUM_OVERLOADED_OPERATORS: @@ -520,13 +690,141 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO) { void MicrosoftCXXNameMangler::mangleSourceName(const IdentifierInfo *II) { // <source name> ::= <identifier> @ - Out << II->getName() << '@'; + std::string key = II->getNameStart(); + BackRefMap::iterator Found; + if (UseNameBackReferences) + Found = NameBackReferences.find(key); + if (!UseNameBackReferences || Found == NameBackReferences.end()) { + Out << II->getName() << '@'; + if (UseNameBackReferences && NameBackReferences.size() < 10) { + size_t Size = NameBackReferences.size(); + NameBackReferences[key] = Size; + } + } else { + Out << Found->second; + } } void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { Context.mangleObjCMethodName(MD, Out); } +// Find out how many function decls live above this one and return an integer +// suitable for use as the number in a numbered anonymous scope. +// TODO: Memoize. +static unsigned getLocalNestingLevel(const FunctionDecl *FD) { + const DeclContext *DC = FD->getParent(); + int level = 1; + + while (DC && !DC->isTranslationUnit()) { + if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) level++; + DC = DC->getParent(); + } + + return 2*level; +} + +void MicrosoftCXXNameMangler::mangleLocalName(const FunctionDecl *FD) { + // <nested-name> ::= <numbered-anonymous-scope> ? <mangled-name> + // <numbered-anonymous-scope> ::= ? <number> + // Even though the name is rendered in reverse order (e.g. + // A::B::C is rendered as C@B@A), VC numbers the scopes from outermost to + // innermost. So a method bar in class C local to function foo gets mangled + // as something like: + // ?bar@C@?1??foo@@YAXXZ@QAEXXZ + // This is more apparent when you have a type nested inside a method of a + // type nested inside a function. A method baz in class D local to method + // bar of class C local to function foo gets mangled as: + // ?baz@D@?3??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ + // This scheme is general enough to support GCC-style nested + // functions. You could have a method baz of class C inside a function bar + // inside a function foo, like so: + // ?baz@C@?3??bar@?1??foo@@YAXXZ@YAXXZ@QAEXXZ + int NestLevel = getLocalNestingLevel(FD); + Out << '?'; + mangleNumber(NestLevel); + Out << '?'; + mangle(FD, "?"); +} + +void MicrosoftCXXNameMangler::mangleTemplateInstantiationName( + const TemplateDecl *TD, + const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) { + // <template-name> ::= <unscoped-template-name> <template-args> + // ::= <substitution> + // Always start with the unqualified name. + + // Templates have their own context for back references. + BackRefMap TemplateContext; + NameBackReferences.swap(TemplateContext); + + mangleUnscopedTemplateName(TD); + mangleTemplateArgs(TemplateArgs); + + NameBackReferences.swap(TemplateContext); +} + +void +MicrosoftCXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *TD) { + // <unscoped-template-name> ::= ?$ <unqualified-name> + Out << "?$"; + mangleUnqualifiedName(TD); +} + +void +MicrosoftCXXNameMangler::mangleIntegerLiteral(QualType T, + const llvm::APSInt &Value) { + // <integer-literal> ::= $0 <number> + Out << "$0"; + // Make sure booleans are encoded as 0/1. + if (T->isBooleanType()) + Out << (Value.getBoolValue() ? "0" : "A@"); + else + mangleNumber(Value); +} + +void +MicrosoftCXXNameMangler::mangleTemplateArgs( + const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) { + // <template-args> ::= {<type> | <integer-literal>}+ @ + unsigned NumTemplateArgs = TemplateArgs.size(); + for (unsigned i = 0; i < NumTemplateArgs; ++i) { + const TemplateArgumentLoc &TAL = TemplateArgs[i]; + const TemplateArgument &TA = TAL.getArgument(); + switch (TA.getKind()) { + case TemplateArgument::Null: + llvm_unreachable("Can't mangle null template arguments!"); + case TemplateArgument::Type: + mangleType(TA.getAsType(), TAL.getSourceRange()); + break; + case TemplateArgument::Integral: + mangleIntegerLiteral(TA.getIntegralType(), TA.getAsIntegral()); + break; + case TemplateArgument::Expression: { + // See if this is a constant expression. + Expr *TAE = TA.getAsExpr(); + llvm::APSInt Value; + if (TAE->isIntegerConstantExpr(Value, Context.getASTContext())) { + mangleIntegerLiteral(TAE->getType(), Value); + break; + } + /* fallthrough */ + } default: { + // Issue a diagnostic. + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this %select{ERROR|ERROR|pointer/reference|ERROR|" + "template|template pack expansion|expression|parameter pack}0 " + "template argument yet"); + Diags.Report(TAL.getLocation(), DiagID) + << TA.getKind() + << TAL.getSourceRange(); + } + } + } + Out << '@'; +} + void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals, bool IsMember) { // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers> @@ -610,7 +908,29 @@ void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals, // FIXME: For now, just drop all extension qualifiers on the floor. } -void MicrosoftCXXNameMangler::mangleType(QualType T) { +void MicrosoftCXXNameMangler::mangleTypeRepeated(QualType T, SourceRange Range) { + void *TypePtr = getASTContext().getCanonicalType(T).getAsOpaquePtr(); + ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr); + + if (Found == TypeBackReferences.end()) { + size_t OutSizeBefore = Out.GetNumBytesInBuffer(); + + mangleType(T,Range); + + // See if it's worth creating a back reference. + // Only types longer than 1 character are considered + // and only 10 back references slots are available: + bool LongerThanOneChar = (Out.GetNumBytesInBuffer() - OutSizeBefore > 1); + if (LongerThanOneChar && TypeBackReferences.size() < 10) { + size_t Size = TypeBackReferences.size(); + TypeBackReferences[TypePtr] = Size; + } + } else { + Out << Found->second; + } +} + +void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range) { // Only operate on the canonical type! T = getASTContext().getCanonicalType(T); @@ -644,18 +964,22 @@ void MicrosoftCXXNameMangler::mangleType(QualType T) { switch (T->getTypeClass()) { #define ABSTRACT_TYPE(CLASS, PARENT) #define NON_CANONICAL_TYPE(CLASS, PARENT) \ -case Type::CLASS: \ -llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \ -return; + case Type::CLASS: \ + llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \ + return; #define TYPE(CLASS, PARENT) \ -case Type::CLASS: \ -mangleType(static_cast<const CLASS##Type*>(T.getTypePtr())); \ -break; + case Type::CLASS: \ + mangleType(static_cast<const CLASS##Type*>(T.getTypePtr()), Range); \ + break; #include "clang/AST/TypeNodes.def" +#undef ABSTRACT_TYPE +#undef NON_CANONICAL_TYPE +#undef TYPE } } -void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T) { +void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, + SourceRange Range) { // <type> ::= <builtin-type> // <builtin-type> ::= X # void // ::= C # signed char @@ -713,24 +1037,32 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T) { case BuiltinType::ObjCId: Out << "PAUobjc_object@@"; break; case BuiltinType::ObjCClass: Out << "PAUobjc_class@@"; break; case BuiltinType::ObjCSel: Out << "PAUobjc_selector@@"; break; + + case BuiltinType::NullPtr: Out << "$$T"; break; case BuiltinType::Char16: case BuiltinType::Char32: - case BuiltinType::Half: - case BuiltinType::NullPtr: - assert(0 && "Don't know how to mangle this type yet"); + case BuiltinType::Half: { + DiagnosticsEngine &Diags = Context.getDiags(); + 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; + break; + } } } // <type> ::= <function-type> -void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T) { +void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, + SourceRange) { // Structors only appear in decls, so at this point we know it's not a // structor type. - // I'll probably have mangleType(MemberPointerType) call the mangleType() - // method directly. mangleType(T, NULL, false, false); } -void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T) { +void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T, + SourceRange) { llvm_unreachable("Can't mangle K&R function prototypes"); } @@ -753,8 +1085,23 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionType *T, // ::= @ # structors (they have no declared return type) if (IsStructor) Out << '@'; - else - mangleType(Proto->getResultType()); + else { + QualType Result = Proto->getResultType(); + const Type* RT = Result.getTypePtr(); + if (!RT->isAnyPointerType() && !RT->isReferenceType()) { + if (Result.hasQualifiers() || !RT->isBuiltinType()) + Out << '?'; + if (!RT->isBuiltinType() && !Result.hasQualifiers()) { + // Lack of qualifiers for user types is mangled as 'A'. + Out << 'A'; + } + } + + // FIXME: Get the source range for the result type. Or, better yet, + // implement the unimplemented stuff so we don't need accurate source + // location info anymore :). + mangleType(Result, SourceRange()); + } // <argument-list> ::= X # void // ::= <type>+ @ @@ -763,17 +1110,21 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionType *T, Out << 'X'; } else { if (D) { - // If we got a decl, use the "types-as-written" to make sure arrays - // get mangled right. + // If we got a decl, use the type-as-written to make sure arrays + // get mangled right. Note that we can't rely on the TSI + // existing if (for example) the parameter was synthesized. for (FunctionDecl::param_const_iterator Parm = D->param_begin(), - ParmEnd = D->param_end(); - Parm != ParmEnd; ++Parm) - mangleType((*Parm)->getTypeSourceInfo()->getType()); + ParmEnd = D->param_end(); Parm != ParmEnd; ++Parm) { + TypeSourceInfo *TSI = (*Parm)->getTypeSourceInfo(); + QualType Type = TSI ? TSI->getType() : (*Parm)->getType(); + mangleTypeRepeated(Type, (*Parm)->getSourceRange()); + } } else { + // Happens for function pointer type arguments for example. for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(), ArgEnd = Proto->arg_type_end(); Arg != ArgEnd; ++Arg) - mangleType(*Arg); + mangleTypeRepeated(*Arg, SourceRange()); } // <builtin-type> ::= Z # ellipsis if (Proto->isVariadic()) @@ -860,8 +1211,16 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T, // that they could be in a DLL and somebody from another module could call // them.) CallingConv CC = T->getCallConv(); - if (CC == CC_Default) - CC = IsInstMethod ? getASTContext().getDefaultMethodCallConv() : CC_C; + if (CC == CC_Default) { + if (IsInstMethod) { + const FunctionProtoType *FPT = + T->getCanonicalTypeUnqualified().getAs<FunctionProtoType>(); + bool isVariadic = FPT->isVariadic(); + CC = getASTContext().getDefaultCXXMethodCallConv(isVariadic); + } else { + CC = CC_C; + } + } switch (CC) { default: llvm_unreachable("Unsupported CC for mangling"); @@ -884,8 +1243,15 @@ void MicrosoftCXXNameMangler::mangleThrowSpecification( Out << 'Z'; } -void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T) { - llvm_unreachable("Don't know how to mangle UnresolvedUsingTypes yet!"); +void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T, + SourceRange Range) { + // Probably should be mangled as a template instantiation; need to see what + // VC does first. + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this unresolved dependent type yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; } // <type> ::= <union-type> | <struct-type> | <class-type> | <enum-type> @@ -893,10 +1259,10 @@ void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T) { // <struct-type> ::= U <name> // <class-type> ::= V <name> // <enum-type> ::= W <size> <name> -void MicrosoftCXXNameMangler::mangleType(const EnumType *T) { +void MicrosoftCXXNameMangler::mangleType(const EnumType *T, SourceRange) { mangleType(static_cast<const TagType*>(T)); } -void MicrosoftCXXNameMangler::mangleType(const RecordType *T) { +void MicrosoftCXXNameMangler::mangleType(const RecordType *T, SourceRange) { mangleType(static_cast<const TagType*>(T)); } void MicrosoftCXXNameMangler::mangleType(const TagType *T) { @@ -936,31 +1302,48 @@ void MicrosoftCXXNameMangler::mangleType(const ArrayType *T, bool IsGlobal) { Out << 'Q'; mangleExtraDimensions(T->getElementType()); } -void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T) { +void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T, + SourceRange) { mangleType(static_cast<const ArrayType *>(T), false); } -void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T) { +void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T, + SourceRange) { mangleType(static_cast<const ArrayType *>(T), false); } -void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T) { +void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T, + SourceRange) { mangleType(static_cast<const ArrayType *>(T), false); } -void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T) { +void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T, + SourceRange) { mangleType(static_cast<const ArrayType *>(T), false); } void MicrosoftCXXNameMangler::mangleExtraDimensions(QualType ElementTy) { SmallVector<llvm::APInt, 3> Dimensions; for (;;) { - if (ElementTy->isConstantArrayType()) { - const ConstantArrayType *CAT = - static_cast<const ConstantArrayType *>(ElementTy.getTypePtr()); + if (const ConstantArrayType *CAT = + getASTContext().getAsConstantArrayType(ElementTy)) { Dimensions.push_back(CAT->getSize()); ElementTy = CAT->getElementType(); } else if (ElementTy->isVariableArrayType()) { - llvm_unreachable("Don't know how to mangle VLAs!"); + const VariableArrayType *VAT = + getASTContext().getAsVariableArrayType(ElementTy); + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this variable-length array yet"); + Diags.Report(VAT->getSizeExpr()->getExprLoc(), DiagID) + << VAT->getBracketsRange(); + return; } else if (ElementTy->isDependentSizedArrayType()) { // The dependent expression has to be folded into a constant (TODO). - llvm_unreachable("Don't know how to mangle dependent-sized arrays!"); + const DependentSizedArrayType *DSAT = + getASTContext().getAsDependentSizedArrayType(ElementTy); + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this dependent-length array yet"); + Diags.Report(DSAT->getSizeExpr()->getExprLoc(), DiagID) + << DSAT->getBracketsRange(); + return; } else if (ElementTy->isIncompleteArrayType()) continue; else break; } @@ -974,151 +1357,246 @@ void MicrosoftCXXNameMangler::mangleExtraDimensions(QualType ElementTy) { mangleNumber(Dimensions[Dim].getLimitedValue()); } } - mangleType(ElementTy.getLocalUnqualifiedType()); + mangleType(ElementTy.getLocalUnqualifiedType(), SourceRange()); } // <type> ::= <pointer-to-member-type> // <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> // <class name> <type> -void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T) { +void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T, + SourceRange Range) { QualType PointeeType = T->getPointeeType(); - if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) { + if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) { Out << '8'; - mangleName(cast<RecordType>(T->getClass())->getDecl()); + mangleName(T->getClass()->castAs<RecordType>()->getDecl()); mangleType(FPT, NULL, false, true); } else { mangleQualifiers(PointeeType.getQualifiers(), true); - mangleName(cast<RecordType>(T->getClass())->getDecl()); - mangleType(PointeeType.getLocalUnqualifiedType()); + mangleName(T->getClass()->castAs<RecordType>()->getDecl()); + mangleType(PointeeType.getLocalUnqualifiedType(), Range); } } -void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T) { - llvm_unreachable("Don't know how to mangle TemplateTypeParmTypes yet!"); +void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this template type parameter type yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; } void MicrosoftCXXNameMangler::mangleType( - const SubstTemplateTypeParmPackType *T) { - llvm_unreachable( - "Don't know how to mangle SubstTemplateTypeParmPackTypes yet!"); + const SubstTemplateTypeParmPackType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this substituted parameter pack yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; } // <type> ::= <pointer-type> // <pointer-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> <type> -void MicrosoftCXXNameMangler::mangleType(const PointerType *T) { +void MicrosoftCXXNameMangler::mangleType(const PointerType *T, + SourceRange Range) { QualType PointeeTy = T->getPointeeType(); if (PointeeTy->isArrayType()) { // Pointers to arrays are mangled like arrays. - mangleExtraDimensions(T->getPointeeType()); - } else if (PointeeTy->isFunctionType()) { + mangleExtraDimensions(PointeeTy); + } else if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) { // Function pointers are special. Out << '6'; - mangleType(static_cast<const FunctionType *>(PointeeTy.getTypePtr()), - NULL, false, false); + mangleType(FT, NULL, false, false); } else { if (!PointeeTy.hasQualifiers()) // Lack of qualifiers is mangled as 'A'. Out << 'A'; - mangleType(PointeeTy); + mangleType(PointeeTy, Range); } } -void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T) { +void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T, + SourceRange Range) { // Object pointers never have qualifiers. Out << 'A'; - mangleType(T->getPointeeType()); + mangleType(T->getPointeeType(), Range); } // <type> ::= <reference-type> // <reference-type> ::= A <cvr-qualifiers> <type> -void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T) { +void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T, + SourceRange Range) { Out << 'A'; QualType PointeeTy = T->getPointeeType(); if (!PointeeTy.hasQualifiers()) // Lack of qualifiers is mangled as 'A'. Out << 'A'; - mangleType(PointeeTy); -} - -void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T) { - llvm_unreachable("Don't know how to mangle RValueReferenceTypes yet!"); -} - -void MicrosoftCXXNameMangler::mangleType(const ComplexType *T) { - llvm_unreachable("Don't know how to mangle ComplexTypes yet!"); + mangleType(PointeeTy, Range); } -void MicrosoftCXXNameMangler::mangleType(const VectorType *T) { - llvm_unreachable("Don't know how to mangle VectorTypes yet!"); -} -void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T) { - llvm_unreachable("Don't know how to mangle ExtVectorTypes yet!"); -} -void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T) { - llvm_unreachable( - "Don't know how to mangle DependentSizedExtVectorTypes yet!"); -} - -void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T) { +// <type> ::= <r-value-reference-type> +// <r-value-reference-type> ::= $$Q <cvr-qualifiers> <type> +void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T, + SourceRange Range) { + Out << "$$Q"; + QualType PointeeTy = T->getPointeeType(); + if (!PointeeTy.hasQualifiers()) + // Lack of qualifiers is mangled as 'A'. + Out << 'A'; + mangleType(PointeeTy, Range); +} + +void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, + 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; +} + +void MicrosoftCXXNameMangler::mangleType(const VectorType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this vector type yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; +} +void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T, + 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 DependentSizedExtVectorType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this dependent-sized extended vector type yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; +} + +void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, + SourceRange) { // ObjC interfaces have structs underlying them. Out << 'U'; mangleName(T->getDecl()); } -void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T) { +void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T, + SourceRange Range) { // We don't allow overloading by different protocol qualification, // so mangling them isn't necessary. - mangleType(T->getBaseType()); + mangleType(T->getBaseType(), Range); } -void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T) { +void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T, + SourceRange Range) { Out << "_E"; - mangleType(T->getPointeeType()); + mangleType(T->getPointeeType(), Range); } -void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *T) { - llvm_unreachable("Don't know how to mangle InjectedClassNameTypes yet!"); +void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this injected class name type yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; } -void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T) { - llvm_unreachable("Don't know how to mangle TemplateSpecializationTypes yet!"); +void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this template specialization type yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; } -void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T) { - llvm_unreachable("Don't know how to mangle DependentNameTypes yet!"); +void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this dependent name type yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; } void MicrosoftCXXNameMangler::mangleType( - const DependentTemplateSpecializationType *T) { - llvm_unreachable( - "Don't know how to mangle DependentTemplateSpecializationTypes yet!"); -} - -void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T) { - llvm_unreachable("Don't know how to mangle PackExpansionTypes yet!"); -} - -void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T) { - llvm_unreachable("Don't know how to mangle TypeOfTypes yet!"); -} - -void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T) { - llvm_unreachable("Don't know how to mangle TypeOfExprTypes yet!"); -} - -void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T) { - llvm_unreachable("Don't know how to mangle DecltypeTypes yet!"); -} - -void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T) { - llvm_unreachable("Don't know how to mangle UnaryTransformationTypes yet!"); -} - -void MicrosoftCXXNameMangler::mangleType(const AutoType *T) { - llvm_unreachable("Don't know how to mangle AutoTypes yet!"); -} - -void MicrosoftCXXNameMangler::mangleType(const AtomicType *T) { - llvm_unreachable("Don't know how to mangle AtomicTypes yet!"); + const DependentTemplateSpecializationType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this dependent template specialization type yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; +} + +void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this pack expansion yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; +} + +void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this typeof(type) yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; +} + +void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this typeof(expression) yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; +} + +void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this decltype() yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; +} + +void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T, + SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this unary transform type yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; +} + +void MicrosoftCXXNameMangler::mangleType(const AutoType *T, SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this 'auto' type yet"); + Diags.Report(Range.getBegin(), DiagID) + << Range; +} + +void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, + 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; } void MicrosoftMangleContext::mangleName(const NamedDecl *D, @@ -1138,17 +1616,35 @@ void MicrosoftMangleContext::mangleName(const NamedDecl *D, void MicrosoftMangleContext::mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) { - llvm_unreachable("Can't yet mangle thunks!"); + unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle thunk for this method yet"); + getDiags().Report(MD->getLocation(), DiagID); } void MicrosoftMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThisAdjustment &, raw_ostream &) { - llvm_unreachable("Can't yet mangle destructor thunks!"); + unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle thunk for this destructor yet"); + getDiags().Report(DD->getLocation(), DiagID); } void MicrosoftMangleContext::mangleCXXVTable(const CXXRecordDecl *RD, - raw_ostream &) { - llvm_unreachable("Can't yet mangle virtual tables!"); + raw_ostream &Out) { + // <mangled-name> ::= ? <operator-name> <class-name> <storage-class> + // <cvr-qualifiers> [<name>] @ + // <operator-name> ::= _7 # vftable + // ::= _8 # vbtable + // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class> + // is always '6' for vftables and '7' for vbtables. (The difference is + // beyond me.) + // TODO: vbtables. + MicrosoftCXXNameMangler Mangler(*this, Out); + Mangler.getStream() << "\01??_7"; + Mangler.mangleName(RD); + Mangler.getStream() << "6B"; + // TODO: If the class has more than one vtable, mangle in the class it came + // from. + Mangler.getStream() << '@'; } void MicrosoftMangleContext::mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) { @@ -1162,11 +1658,19 @@ void MicrosoftMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD, } void MicrosoftMangleContext::mangleCXXRTTI(QualType T, raw_ostream &) { - llvm_unreachable("Can't yet mangle RTTI!"); + // FIXME: Give a location... + unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle RTTI descriptors for type %0 yet"); + getDiags().Report(DiagID) + << T.getBaseTypeIdentifier(); } void MicrosoftMangleContext::mangleCXXRTTIName(QualType T, raw_ostream &) { - llvm_unreachable("Can't yet mangle RTTI names!"); + // FIXME: Give a location... + unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle the name of type %0 into RTTI descriptors yet"); + getDiags().Report(DiagID) + << T.getBaseTypeIdentifier(); } void MicrosoftMangleContext::mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, @@ -1180,9 +1684,11 @@ void MicrosoftMangleContext::mangleCXXDtor(const CXXDestructorDecl *D, MicrosoftCXXNameMangler mangler(*this, Out); mangler.mangle(D); } -void MicrosoftMangleContext::mangleReferenceTemporary(const clang::VarDecl *, +void MicrosoftMangleContext::mangleReferenceTemporary(const clang::VarDecl *VD, raw_ostream &) { - llvm_unreachable("Can't yet mangle reference temporaries!"); + unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle this reference temporary yet"); + getDiags().Report(VD->getLocation(), DiagID); } MangleContext *clang::createMicrosoftMangleContext(ASTContext &Context, |