]> granicus.if.org Git - clang/commitdiff
Support &__uuidof(type) as a non type template argument.
authorFrancois Pichet <pichet2000@gmail.com>
Thu, 28 Apr 2011 04:39:50 +0000 (04:39 +0000)
committerFrancois Pichet <pichet2000@gmail.com>
Thu, 28 Apr 2011 04:39:50 +0000 (04:39 +0000)
This idiom is used everywhere in MFC/COM code and as such this patch removes hundreds of errors when parsing MFC code with clang.

Example:
template <class T, const GUID* g = &__uuidof(T)>
class ComTemplate  { };

typedef ComTemplate<struct_with_uuid, &__uuidof(struct_with_uuid)> COM_TYPE;

Of course this is just parsing support. Trying to use this in CodeGen will generate:
error: cannot yet mangle expression type CXXUuidofExpr

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130381 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
test/Parser/MicrosoftExtensions.cpp

index 3deeedc90da56896fc46159775be1a0d46018193..ae80181d849289d1f77c76cb6666f1dbd5259283 100644 (file)
@@ -3093,6 +3093,15 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
   bool AddressTaken = false;
   SourceLocation AddrOpLoc;
   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
+
+    // Support &__uuidof(class_with_uuid) as a non-type template argument.
+    // Very common in Microsoft COM headers.
+    if (S.getLangOptions().Microsoft && 
+      isa<CXXUuidofExpr>(UnOp->getSubExpr())) {
+      Converted = TemplateArgument(ArgIn);
+      return false;
+    }
+
     if (UnOp->getOpcode() == UO_AddrOf) {
       DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
       AddressTaken = true;
index a5d2d513b12b1bb0c8d695db05723f27ee8d8bcf..decd57510f511fdb32c0956fb1a410f7899ea24b 100644 (file)
@@ -95,6 +95,13 @@ void template_uuid()
 }
 
 
+template <class T, const GUID* g = &__uuidof(T)>
+class COM_CLASS_TEMPLATE  { };
+
+typedef COM_CLASS_TEMPLATE<struct_with_uuid, &__uuidof(struct_with_uuid)> COM_TYPE_1;
+typedef COM_CLASS_TEMPLATE<struct_with_uuid> COM_TYPE_2;
+
+
 
 class CtorCall { 
 public: