[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