]> granicus.if.org Git - clang/commitdiff
Implement __has_virtual_destructor. Patch by Steven Watanabe.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Thu, 2 Sep 2010 23:19:42 +0000 (23:19 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Thu, 2 Sep 2010 23:19:42 +0000 (23:19 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112905 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/DeclCXX.cpp
lib/AST/ExprCXX.cpp
lib/Parse/ParseExpr.cpp
test/SemaCXX/type-traits.cpp

index f4041553507e96b521325e96ae44d0ed29b975dc..f2f0694826c6ab82c564e9474b2f661f5c1c34f7 100644 (file)
@@ -609,7 +609,8 @@ CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
 
   DeclContext::lookup_const_iterator I, E;
   llvm::tie(I, E) = lookup(Name);
-  assert(I != E && "Did not find a destructor!");
+  if (I == E)
+    return 0;
 
   CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I);
   assert(++I == E && "Found more than one destructor!");
index ae57f4cd673b5300aed95e1e5a95c5b46db02ff5..0a101300d8fa1ac11a8fdb112da6854f71851e36 100644 (file)
@@ -488,6 +488,16 @@ bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
       }
     }
     return false;
+  case UTT_HasVirtualDestructor:
+    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
+    //   If type is a class type with a virtual destructor ([class.dtor])
+    //   then the trait is true, else it is false.
+    if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
+      CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
+      if (CXXDestructorDecl *Destructor = RD->getDestructor())
+        return Destructor->isVirtual();
+    }
+    return false;
   }
 }
 
index f1abd59421e4931cccd8fb873561e69f3dd30cb7..c4beab191d37c26c22438effa1974cb8a68d7276 100644 (file)
@@ -533,7 +533,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
 ///                   '__has_trivial_copy'                    [TODO]
 ///                   '__has_trivial_constructor'
 ///                   '__has_trivial_destructor'
-///                   '__has_virtual_destructor'              [TODO]
+///                   '__has_virtual_destructor'
 ///                   '__is_abstract'                         [TODO]
 ///                   '__is_class'
 ///                   '__is_empty'                            [TODO]
@@ -903,6 +903,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
   case tok::kw___has_nothrow_assign:
   case tok::kw___has_nothrow_copy:
   case tok::kw___has_nothrow_constructor:
+  case tok::kw___has_virtual_destructor:
     return ParseUnaryTypeTrait();
 
   case tok::at: {
index b561206143e001aca810a6cb518e995ad96c7a76..b05dd07ec2ec4431d8c549096c556b17460d9612 100644 (file)
@@ -61,6 +61,10 @@ struct HasMultipleNoThrowCopy {
   HasMultipleNoThrowCopy(volatile HasMultipleNoThrowCopy&) throw();
 };
 
+struct HasVirtDest { virtual ~HasVirtDest(); };
+struct DerivedVirtDest : HasVirtDest {};
+typedef HasVirtDest VirtDestAr[1];
+
 void is_pod()
 {
   int t01[T(__is_pod(int))];
@@ -359,3 +363,28 @@ void has_nothrow_constructor() {
   int t19[T(__has_nothrow_constructor(HasNoThrowConstructor))];
   int t20[F(__has_nothrow_constructor(HasNoThrowConstructorWithArgs))];
 }
+
+void has_virtual_destructor() {
+  int t01[F(__has_virtual_destructor(Int))];
+  int t02[F(__has_virtual_destructor(IntAr))];
+  int t03[F(__has_virtual_destructor(Union))];
+  int t04[F(__has_virtual_destructor(UnionAr))];
+  int t05[F(__has_virtual_destructor(POD))];
+  int t06[F(__has_virtual_destructor(Derives))];
+  int t07[F(__has_virtual_destructor(ConstIntAr))];
+  int t08[F(__has_virtual_destructor(ConstIntArAr))];
+  int t09[F(__has_virtual_destructor(HasDest))];
+  int t10[F(__has_virtual_destructor(HasPriv))];
+  int t11[F(__has_virtual_destructor(HasCons))];
+  int t12[F(__has_virtual_destructor(HasRef))];
+  int t13[F(__has_virtual_destructor(HasCopy))];
+  int t14[F(__has_virtual_destructor(IntRef))];
+  int t15[F(__has_virtual_destructor(HasCopyAssign))];
+  int t16[F(__has_virtual_destructor(const Int))];
+  int t17[F(__has_virtual_destructor(NonPODAr))];
+  int t18[F(__has_virtual_destructor(VirtAr))];
+
+  int t19[T(__has_virtual_destructor(HasVirtDest))];
+  int t20[T(__has_virtual_destructor(DerivedVirtDest))];
+  int t21[F(__has_virtual_destructor(VirtDestAr))];
+}