[cfe-commits] r67627 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp test/SemaCXX/abstract.cpp

Anders Carlsson andersca at mac.com
Tue Mar 24 10:23:43 PDT 2009


Author: andersca
Date: Tue Mar 24 12:23:42 2009
New Revision: 67627

URL: http://llvm.org/viewvc/llvm-project?rev=67627&view=rev
Log:
Fix the bug that Eli noticed where we wouldn't look at function decls outside the class declaration.

Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/abstract.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=67627&r1=67626&r2=67627&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Mar 24 12:23:42 2009
@@ -1647,7 +1647,8 @@
   };
   
   bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID, 
-                              AbstractDiagSelID SelID = AbstractNone);
+                              AbstractDiagSelID SelID = AbstractNone,
+                              const CXXRecordDecl *CurrentRD = 0);
 
   //===--------------------------------------------------------------------===//
   // C++ Overloaded Operators [C++ 13.5]

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=67627&r1=67626&r2=67627&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Mar 24 12:23:42 2009
@@ -785,13 +785,15 @@
 }
 
 bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T, 
-                                  unsigned DiagID, AbstractDiagSelID SelID) {
+                                  unsigned DiagID, AbstractDiagSelID SelID,
+                                  const CXXRecordDecl *CurrentRD) {
   
   if (!getLangOptions().CPlusPlus)
     return false;
   
   if (const ArrayType *AT = Context.getAsArrayType(T))
-    return RequireNonAbstractType(Loc, AT->getElementType(), DiagID, SelID);
+    return RequireNonAbstractType(Loc, AT->getElementType(), DiagID, SelID,
+                                  CurrentRD);
   
   if (const PointerType *PT = T->getAsPointerType()) {
     // Find the innermost pointer type.
@@ -799,7 +801,8 @@
       PT = T;
     
     if (const ArrayType *AT = Context.getAsArrayType(PT->getPointeeType()))
-      return RequireNonAbstractType(Loc, AT->getElementType(), DiagID, SelID);
+      return RequireNonAbstractType(Loc, AT->getElementType(), DiagID, SelID,
+                                    CurrentRD);
   }
   
   const RecordType *RT = T->getAsRecordType();
@@ -810,6 +813,9 @@
   if (!RD)
     return false;
 
+  if (CurrentRD && CurrentRD != RD)
+    return false;
+  
   if (!RD->isAbstract())
     return false;
   
@@ -843,40 +849,58 @@
     Sema &SemaRef;
     CXXRecordDecl *AbstractClass;
   
-  public:
-    AbstractClassUsageDiagnoser(Sema& SemaRef, CXXRecordDecl *ac)
-      : SemaRef(SemaRef), AbstractClass(ac) {}
-      
-    bool VisitCXXRecordDecl(const CXXRecordDecl *RD) {
+    bool VisitDeclContext(const DeclContext *DC) {
       bool Invalid = false;
 
-      for (CXXRecordDecl::decl_iterator I = RD->decls_begin(),
-           E = RD->decls_end(); I != E; ++I)
+      for (CXXRecordDecl::decl_iterator I = DC->decls_begin(),
+           E = DC->decls_end(); I != E; ++I)
         Invalid |= Visit(*I);
-              
+
       return Invalid;
     }
-    
-    bool VisitCXXMethodDecl(const CXXMethodDecl *MD) {
+      
+  public:
+    AbstractClassUsageDiagnoser(Sema& SemaRef, CXXRecordDecl *ac)
+      : SemaRef(SemaRef), AbstractClass(ac) {
+        Visit(SemaRef.Context.getTranslationUnitDecl());
+    }
+
+    bool VisitFunctionDecl(const FunctionDecl *FD) {
+      if (FD->isThisDeclarationADefinition()) {
+        // No need to do the check if we're in a definition, because it requires
+        // that the return/param types are complete.
+        // because that requires 
+        return VisitDeclContext(FD);
+      }
+      
       // Check the return type.
-      QualType RTy = MD->getType()->getAsFunctionType()->getResultType();
+      QualType RTy = FD->getType()->getAsFunctionType()->getResultType();
       bool Invalid = 
-        SemaRef.RequireNonAbstractType(MD->getLocation(), RTy,
+        SemaRef.RequireNonAbstractType(FD->getLocation(), RTy,
                                        diag::err_abstract_type_in_decl,
-                                       Sema::AbstractReturnType);
+                                       Sema::AbstractReturnType,
+                                       AbstractClass);
 
-      for (CXXMethodDecl::param_const_iterator I = MD->param_begin(), 
-           E = MD->param_end(); I != E; ++I) {
+      for (FunctionDecl::param_const_iterator I = FD->param_begin(), 
+           E = FD->param_end(); I != E; ++I) {
         const ParmVarDecl *VD = *I;
         Invalid |= 
           SemaRef.RequireNonAbstractType(VD->getLocation(),
                                          VD->getOriginalType(), 
                                          diag::err_abstract_type_in_decl, 
-                                         Sema::AbstractParamType);
+                                         Sema::AbstractParamType,
+                                         AbstractClass);
       }
 
       return Invalid;
     }
+    
+    bool VisitDecl(const Decl* D) {
+      if (const DeclContext *DC = dyn_cast<DeclContext>(D))
+        return VisitDeclContext(DC);
+      
+      return false;
+    }
   };
 }
 
@@ -898,8 +922,8 @@
       RD->setAbstract(true);
   }
   
-  if (RD->isAbstract())
-    AbstractClassUsageDiagnoser(*this, RD).Visit(RD);
+  if (RD->isAbstract()) 
+    AbstractClassUsageDiagnoser(*this, RD);
     
   if (!Template)
     AddImplicitlyDeclaredMembersToClass(RD);

Modified: cfe/trunk/test/SemaCXX/abstract.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/abstract.cpp?rev=67627&r1=67626&r2=67627&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/abstract.cpp (original)
+++ cfe/trunk/test/SemaCXX/abstract.cpp Tue Mar 24 12:23:42 2009
@@ -66,3 +66,19 @@
     
     virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
 };
+
+class Abstract;
+
+void t7(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+
+void t8() {
+    void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+}
+
+namespace N {
+    void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+}
+
+class Abstract {
+ virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
+};





More information about the cfe-commits mailing list