diff options
Diffstat (limited to 'clang/lib/AST/DeclCXX.cpp')
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 58 | 
1 files changed, 58 insertions, 0 deletions
| diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 036292b6a56..6e879ee9ee4 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -14,6 +14,7 @@  #include "clang/AST/DeclCXX.h"  #include "clang/AST/DeclTemplate.h"  #include "clang/AST/ASTContext.h" +#include "clang/AST/CXXInheritance.h"  #include "clang/AST/Expr.h"  #include "clang/AST/TypeLoc.h"  #include "clang/Basic/IdentifierTable.h" @@ -794,6 +795,63 @@ CXXDestructorDecl *CXXRecordDecl::getDestructor() const {    return Dtor;  } +void CXXRecordDecl::completeDefinition() { +  completeDefinition(0); +} + +void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) { +  RecordDecl::completeDefinition(); +   +  // If the class may be abstract (but hasn't been marked as such), check for +  // any pure final overriders. +  if (mayBeAbstract()) { +    CXXFinalOverriderMap MyFinalOverriders; +    if (!FinalOverriders) { +      getFinalOverriders(MyFinalOverriders); +      FinalOverriders = &MyFinalOverriders; +    } +     +    bool Done = false; +    for (CXXFinalOverriderMap::iterator M = FinalOverriders->begin(),  +                                     MEnd = FinalOverriders->end(); +         M != MEnd && !Done; ++M) { +      for (OverridingMethods::iterator SO = M->second.begin(),  +                                    SOEnd = M->second.end(); +           SO != SOEnd && !Done; ++SO) { +        assert(SO->second.size() > 0 &&  +               "All virtual functions have overridding virtual functions"); +         +        // C++ [class.abstract]p4: +        //   A class is abstract if it contains or inherits at least one +        //   pure virtual function for which the final overrider is pure +        //   virtual. +        if (SO->second.front().Method->isPure()) { +          data().Abstract = true; +          Done = true; +          break; +        } +      } +    } +  } +} + +bool CXXRecordDecl::mayBeAbstract() const { +  if (data().Abstract || isInvalidDecl() || !data().Polymorphic || +      isDependentContext()) +    return false; +   +  for (CXXRecordDecl::base_class_const_iterator B = bases_begin(), +                                             BEnd = bases_end(); +       B != BEnd; ++B) { +    CXXRecordDecl *BaseDecl  +      = cast<CXXRecordDecl>(B->getType()->getAs<RecordType>()->getDecl()); +    if (BaseDecl->isAbstract()) +      return true; +  } +   +  return false; +} +  CXXMethodDecl *  CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,                        const DeclarationNameInfo &NameInfo, | 

