]> granicus.if.org Git - clang/commitdiff
Fix for PR5693: shift some code into SetClassDeclAttributesFromBase so that
authorEli Friedman <eli.friedman@gmail.com>
Sat, 5 Dec 2009 23:03:49 +0000 (23:03 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sat, 5 Dec 2009 23:03:49 +0000 (23:03 +0000)
it gets called during template instantiation.

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

lib/Sema/SemaDeclCXX.cpp
test/SemaTemplate/template-class-traits.cpp [new file with mode: 0644]

index 992bb80189a0e39b619a901566631554f84ab907..652b92db5ed6c7cbe50f7e573a9aab1746902244 100644 (file)
@@ -484,10 +484,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
   assert(BaseDecl && "Base type is not incomplete, but has no definition");
   CXXRecordDecl * CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl);
   assert(CXXBaseDecl && "Base type is not a C++ type");
-  if (!CXXBaseDecl->isEmpty())
-    Class->setEmpty(false);
-  if (CXXBaseDecl->isPolymorphic())
-    Class->setPolymorphic(true);
+
   // C++0x CWG Issue #817 indicates that [[final]] classes shouldn't be bases.
   if (CXXBaseDecl->hasAttr<FinalAttr>()) {
     Diag(BaseLoc, diag::err_final_base) << BaseType.getAsString();
@@ -496,7 +493,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
     return 0;
   }
 
-  SetClassDeclAttributesFromBase(Class, cast<CXXRecordDecl>(BaseDecl), Virtual);
+  SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual);
   
   // Create the base specifier.
   // FIXME: Allocate via ASTContext?
@@ -508,10 +505,23 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
                                           const CXXRecordDecl *BaseClass,
                                           bool BaseIsVirtual) {
+  // A class with a non-empty base class is not empty.
+  // FIXME: Standard ref?
+  if (!BaseClass->isEmpty())
+    Class->setEmpty(false);
+
+  // C++ [class.virtual]p1:
+  //   A class that [...] inherits a virtual function is called a polymorphic
+  //   class.
+  if (BaseClass->isPolymorphic())
+    Class->setPolymorphic(true);
 
   // C++ [dcl.init.aggr]p1:
   //   An aggregate is [...] a class with [...] no base classes [...].
   Class->setAggregate(false);
+
+  // C++ [class]p4:
+  //   A POD-struct is an aggregate class...
   Class->setPOD(false);
 
   if (BaseIsVirtual) {
diff --git a/test/SemaTemplate/template-class-traits.cpp b/test/SemaTemplate/template-class-traits.cpp
new file mode 100644 (file)
index 0000000..7cf2004
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: clang-cc -fsyntax-only -verify %s 
+#define T(b) (b) ? 1 : -1
+#define F(b) (b) ? -1 : 1
+
+struct HasVirt { virtual void a(); };
+template<class T> struct InheritPolymorph : HasVirt {};
+int t01[T(__is_polymorphic(InheritPolymorph<int>))];
+