diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-09-29 00:15:42 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-09-29 00:15:42 +0000 |
| commit | 8fb9512966b724000ec5384d97137ed6854a40f3 (patch) | |
| tree | e53632ca0af6b717833fe7b3ab34a16f76112ff7 /clang/lib/Sema/SemaDecl.cpp | |
| parent | 58c6273b84f6537f4368ac6b134101ebb130ceaa (diff) | |
| download | bcm5719-llvm-8fb9512966b724000ec5384d97137ed6854a40f3.tar.gz bcm5719-llvm-8fb9512966b724000ec5384d97137ed6854a40f3.zip | |
Move the maintenance of CXXRecordDecl::DefinitionData's Abstract bit
completely into CXXRecordDecl, by adding a new completeDefinition()
function. This required a little reshuffling of the final-overrider
checking code, since the "abstract" calculation in the presence of
abstract base classes needs to occur in
CXXRecordDecl::completeDefinition() but we don't want to compute final
overriders more than one in the common case.
llvm-svn: 115007
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 871cb9fd785..7902ce84b5f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6692,7 +6692,64 @@ void Sema::ActOnFields(Scope* S, // Okay, we successfully defined 'Record'. if (Record) { - Record->completeDefinition(); + bool Completed = false; + if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record)) { + if (!CXXRecord->isInvalidDecl()) { + // Set access bits correctly on the directly-declared conversions. + UnresolvedSetImpl *Convs = CXXRecord->getConversionFunctions(); + for (UnresolvedSetIterator I = Convs->begin(), E = Convs->end(); + I != E; ++I) + Convs->setAccess(I, (*I)->getAccess()); + + if (!CXXRecord->isDependentType()) { + // Add any implicitly-declared members to this class. + AddImplicitlyDeclaredMembersToClass(CXXRecord); + + // If we have virtual base classes, we may end up finding multiple + // final overriders for a given virtual function. Check for this + // problem now. + if (CXXRecord->getNumVBases()) { + CXXFinalOverriderMap FinalOverriders; + CXXRecord->getFinalOverriders(FinalOverriders); + + for (CXXFinalOverriderMap::iterator M = FinalOverriders.begin(), + MEnd = FinalOverriders.end(); + M != MEnd; ++M) { + for (OverridingMethods::iterator SO = M->second.begin(), + SOEnd = M->second.end(); + SO != SOEnd; ++SO) { + assert(SO->second.size() > 0 && + "Virtual function without overridding functions?"); + if (SO->second.size() == 1) + continue; + + // C++ [class.virtual]p2: + // In a derived class, if a virtual member function of a base + // class subobject has more than one final overrider the + // program is ill-formed. + Diag(Record->getLocation(), diag::err_multiple_final_overriders) + << (NamedDecl *)M->first << Record; + Diag(M->first->getLocation(), + diag::note_overridden_virtual_function); + for (OverridingMethods::overriding_iterator + OM = SO->second.begin(), + OMEnd = SO->second.end(); + OM != OMEnd; ++OM) + Diag(OM->Method->getLocation(), diag::note_final_overrider) + << (NamedDecl *)M->first << OM->Method->getParent(); + + Record->setInvalidDecl(); + } + } + CXXRecord->completeDefinition(&FinalOverriders); + Completed = true; + } + } + } + } + + if (!Completed) + Record->completeDefinition(); } else { ObjCIvarDecl **ClsFields = reinterpret_cast<ObjCIvarDecl**>(RecFields.data()); |

