diff options
author | Anders Carlsson <andersca@mac.com> | 2009-03-22 20:18:17 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-03-22 20:18:17 +0000 |
commit | 4681ebd429846ed98e7beaf49934fa347ff22152 (patch) | |
tree | b6cc31b6b66002b1e0fb9bca6c9ab6a495cd176d /lib/Sema/SemaDeclCXX.cpp | |
parent | ff75e1db95a53c7606e0bb114cf9adc59ab3d7f6 (diff) |
Disallow abstract types where appropriate.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67476 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index b18b6c8f84..60d1692156 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -731,7 +731,10 @@ namespace { } } - bool empty() const { return Methods.empty(); } + bool empty() const { return Methods.empty(); } + + MethodList::const_iterator methods_begin() { return Methods.begin(); } + MethodList::const_iterator methods_end() { return Methods.end(); } }; void PureVirtualMethodCollector::Collect(const CXXRecordDecl* RD, @@ -777,6 +780,47 @@ namespace { } } +bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T, + unsigned SelID) { + + if (!getLangOptions().CPlusPlus) + return false; + + const RecordType *RT = T->getAsRecordType(); + if (!RT) + return false; + + const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); + if (!RD) + return false; + + if (!RD->isAbstract()) + return false; + + Diag(Loc, diag::err_abstract_type_in_decl) << SelID << RD->getDeclName(); + + // Check if we've already emitted the list of pure virtual functions for this + // class. + if (PureVirtualClassDiagSet && PureVirtualClassDiagSet->count(RD)) + return true; + + PureVirtualMethodCollector Collector(Context, RD); + + for (PureVirtualMethodCollector::MethodList::const_iterator I = + Collector.methods_begin(), E = Collector.methods_end(); I != E; ++I) { + const CXXMethodDecl *MD = *I; + + Diag(MD->getLocation(), diag::note_pure_virtual_function) << + MD->getDeclName(); + } + + if (!PureVirtualClassDiagSet) + PureVirtualClassDiagSet.reset(new RecordDeclSetTy); + PureVirtualClassDiagSet->insert(RD); + + return true; +} + void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, DeclTy *TagDecl, SourceLocation LBrac, |