diff options
author | David Majnemer <david.majnemer@gmail.com> | 2013-08-13 06:32:20 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2013-08-13 06:32:20 +0000 |
commit | 8eaab6ff8e80a95e1da7b49cda81cf0ef5094be8 (patch) | |
tree | 94520101a9519eb34ebdbf4bc53884f6faa4f5cf /clang/lib/AST/MicrosoftMangle.cpp | |
parent | 80d28de87a2d8d1f1bf72418a7523e4debe0e948 (diff) | |
download | bcm5719-llvm-8eaab6ff8e80a95e1da7b49cda81cf0ef5094be8.tar.gz bcm5719-llvm-8eaab6ff8e80a95e1da7b49cda81cf0ef5094be8.zip |
[-cxx-abi microsoft] Mangle __uuidof correctly into template parameters
Summary:
It seems that __uuidof introduces a global extern "C" declaration of
type __s_GUID. However, our implementation of __uuidof does not provide
such a declaration and thus must open-code the mangling for __uuidof in
template parameters.
This allows us to codegen scoped COM pointers and other such things.
This fixes PR16836.
Depends on D1356.
Reviewers: rnk, cdavis5x, rsmith
Reviewed By: rnk
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1357
llvm-svn: 188252
Diffstat (limited to 'clang/lib/AST/MicrosoftMangle.cpp')
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 765b14d49e5..9f4df3a4548 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -83,6 +83,7 @@ public: void mangle(const NamedDecl *D, StringRef Prefix = "\01?"); void mangleName(const NamedDecl *ND); + void mangleDeclaration(const NamedDecl *ND); void mangleFunctionEncoding(const FunctionDecl *FD); void mangleVariableEncoding(const VarDecl *VD); void mangleNumber(int64_t Number); @@ -855,6 +856,33 @@ MicrosoftCXXNameMangler::mangleExpression(const Expr *E) { return; } + const CXXUuidofExpr *UE = 0; + if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { + if (UO->getOpcode() == UO_AddrOf) + UE = dyn_cast<CXXUuidofExpr>(UO->getSubExpr()); + } else + 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 peak through an address-of operator, treat this like we are + // dealing with a pointer type. Otherwise, treat it like a const reference. + // + // N.B. This matches up with the handling of TemplateArgument::Declaration + // in mangleTemplateArg + if (UE == E) + Out << "$E?"; + else + Out << "$1?"; + Out << Name << "@@3U__s_GUID@@B"; + return; + } + // As bad as this diagnostic is, it's better than crashing. DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, |