]> granicus.if.org Git - clang/commitdiff
More support for pseudo dtors.
authorAnders Carlsson <andersca@mac.com>
Wed, 26 Aug 2009 19:22:42 +0000 (19:22 +0000)
committerAnders Carlsson <andersca@mac.com>
Wed, 26 Aug 2009 19:22:42 +0000 (19:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80129 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExprCXX.cpp
test/SemaCXX/pseudo-destructors.cpp [new file with mode: 0644]

index 1230f5b9d43c6dfca9c1424343de92214e5bdb78..670a0d048a6c4fb84f1724c8c5d49ef025a12806 100644 (file)
@@ -1554,6 +1554,11 @@ def err_throw_incomplete_ptr : Error<
 def err_return_in_constructor_handler : Error<
   "return in the catch of a function try block of a constructor is illegal">;
 
+def err_ident_in_pseudo_dtor_not_a_type : Error<
+  "identifier %0 in pseudo-destructor expression does not name a type">;
+def err_type_in_pseudo_dtor_not_a_class_type : Error<
+  "type %0 in pseudo-destructor expression is not a class type">;
+
 def err_invalid_use_of_function_type : Error<
   "a function type is not allowed here">;
 def err_invalid_use_of_array_type : Error<"an array type is not allowed here">;
index cf52bae86ca5db332f35c8440923a7cc686d9b68..2b0749aec029bea411e66cfe6ebc11ef4c2993c1 100644 (file)
@@ -1694,18 +1694,35 @@ Sema::ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
                                    const CXXScopeSpec *SS) {
   if (SS && SS->isInvalid())
     return ExprError();
+
+  Expr *BaseExpr = (Expr *)Base.get();
   
-  // Since this might be a postfix expression, get rid of ParenListExprs.
-  Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
-  
-  Expr *BaseExpr = Base.takeAs<Expr>();
-  assert(BaseExpr && "no record expression");
+  if (BaseExpr->isTypeDependent() || 
+      (SS && isDependentScopeSpecifier(*SS))) {
+    // FIXME: Return an unresolved ref expr.
+    return ExprError();
+  }
+
+  TypeTy *BaseTy = getTypeName(*ClassName, ClassNameLoc, S, SS);
+  if (!BaseTy) {
+    Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type) 
+      << ClassName;
+    return ExprError();
+  }
   
-  // Perform default conversions.
-  DefaultFunctionArrayConversion(BaseExpr);
+  QualType BaseType = GetTypeFromParser(BaseTy);
+  if (!BaseType->isRecordType()) {
+    Diag(ClassNameLoc, diag::err_type_in_pseudo_dtor_not_a_class_type)
+      << BaseType;
+    return ExprError();
+  }
   
-  QualType BaseType = BaseExpr->getType();
-  return ExprError();
+  CanQualType CanBaseType = Context.getCanonicalType(BaseType);
+  DeclarationName DtorName = 
+    Context.DeclarationNames.getCXXDestructorName(CanBaseType);
+
+  return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, ClassNameLoc,
+                                  DtorName, DeclPtrTy(), SS);
 }
 
 Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp
new file mode 100644 (file)
index 0000000..8c41f22
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+struct A {};
+
+enum Foo { F };
+typedef Foo Bar;
+
+void f(A* a) {
+  a->~A();
+  a->A::~A();
+  
+  a->~foo(); // expected-error{{identifier 'foo' in pseudo-destructor expression does not name a type}}
+  a->~Bar(); // expected-error{{type 'Bar' (aka 'enum Foo') in pseudo-destructor expression is not a class type}}
+}