[PATCH] [-cxx-abi microsoft] Mangle __uuidof correctly into template parameters
David Majnemer
david.majnemer at gmail.com
Sat Aug 10 09:08:04 PDT 2013
Hi rnk, cdavis5x, rsmith,
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.
http://llvm-reviews.chandlerc.com/D1357
Files:
include/clang/AST/ExprCXX.h
lib/AST/ExprCXX.cpp
lib/AST/MicrosoftMangle.cpp
lib/CodeGen/CodeGenModule.cpp
test/CodeGenCXX/mangle-ms-templates.cpp
Index: include/clang/AST/ExprCXX.h
===================================================================
--- include/clang/AST/ExprCXX.h
+++ include/clang/AST/ExprCXX.h
@@ -724,6 +724,8 @@
Operand = E;
}
+ StringRef getUuidAsStringRef(ASTContext &Context) const;
+
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
Index: lib/AST/ExprCXX.cpp
===================================================================
--- lib/AST/ExprCXX.cpp
+++ lib/AST/ExprCXX.cpp
@@ -72,6 +72,21 @@
return 0;
}
+StringRef CXXUuidofExpr::getUuidAsStringRef(ASTContext &Context) const {
+ StringRef Uuid;
+ if (isTypeOperand())
+ Uuid = CXXUuidofExpr::GetUuidAttrOfType(getTypeOperand())->getGuid();
+ else {
+ // Special case: __uuidof(0) means an all-zero GUID.
+ Expr *Op = getExprOperand();
+ if (!Op->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
+ Uuid = CXXUuidofExpr::GetUuidAttrOfType(Op->getType())->getGuid();
+ else
+ Uuid = "00000000-0000-0000-0000-000000000000";
+ }
+ return Uuid;
+}
+
// CXXScalarValueInitExpr
SourceLocation CXXScalarValueInitExpr::getLocStart() const {
return TypeInfo ? TypeInfo->getTypeLoc().getBeginLoc() : RParenLoc;
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -83,6 +83,7 @@
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,25 @@
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) {
+ StringRef Uuid = UE->getUuidAsStringRef(Context.getASTContext());
+ std::string Name = "_GUID_" + Uuid.lower();
+ std::replace(Name.begin(), Name.end(), '-', '_');
+ 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,
@@ -886,9 +906,11 @@
mangleType(T, SourceRange(), QMM_Escape);
break;
}
- case TemplateArgument::Declaration:
- mangle(cast<NamedDecl>(TA.getAsDecl()), "$1?");
+ case TemplateArgument::Declaration: {
+ const NamedDecl *ND = cast<NamedDecl>(TA.getAsDecl());
+ mangle(ND, TA.isDeclForReferenceParam() ? "$E?" : "$1?");
break;
+ }
case TemplateArgument::Integral:
mangleIntegerLiteral(TA.getAsIntegral(),
TA.getIntegralType()->isBooleanType());
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1048,17 +1048,7 @@
const CXXUuidofExpr* E) {
// Sema has verified that IIDSource has a __declspec(uuid()), and that its
// well-formed.
- StringRef Uuid;
- if (E->isTypeOperand())
- Uuid = CXXUuidofExpr::GetUuidAttrOfType(E->getTypeOperand())->getGuid();
- else {
- // Special case: __uuidof(0) means an all-zero GUID.
- Expr *Op = E->getExprOperand();
- if (!Op->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
- Uuid = CXXUuidofExpr::GetUuidAttrOfType(Op->getType())->getGuid();
- else
- Uuid = "00000000-0000-0000-0000-000000000000";
- }
+ StringRef Uuid = E->getUuidAsStringRef(Context);
std::string Name = "_GUID_" + Uuid.lower();
std::replace(Name.begin(), Name.end(), '-', '_');
Index: test/CodeGenCXX/mangle-ms-templates.cpp
===================================================================
--- test/CodeGenCXX/mangle-ms-templates.cpp
+++ test/CodeGenCXX/mangle-ms-templates.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -fms-extensions -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -fms-extensions -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
template<typename T>
class Class {
@@ -190,3 +190,28 @@
template <decltype(nullptr)> struct S1 {};
void f(S1<nullptr>) {}
// CHECK: "\01?f@@YAXU?$S1@$0A@@@@Z"
+
+struct record {
+ int first;
+ int second;
+};
+template <const record &>
+struct type1 {
+};
+extern const record inst;
+void recref(type1<inst>) {}
+// CHECK: "\01?recref@@YAXU?$type1@$E?inst@@3Urecord@@B@@@Z"
+
+struct _GUID {};
+struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid;
+
+template <typename T, const _GUID *G = &__uuidof(T)>
+struct UUIDType1 {};
+
+template <typename T, const _GUID &G = __uuidof(T)>
+struct UUIDType2 {};
+
+void fun(UUIDType1<uuid> a) {}
+// CHECK: "\01?fun@@YAXU?$UUIDType1 at Uuuid@@$1?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@@Z"
+void fun(UUIDType2<uuid> b) {}
+// CHECK: "\01?fun@@YAXU?$UUIDType2 at Uuuid@@$E?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@@Z"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1357.1.patch
Type: text/x-patch
Size: 5709 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130810/cb4e8439/attachment.bin>
More information about the cfe-commits
mailing list