diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-06 17:59:45 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-06 17:59:45 +0000 |
commit | a8f32e0965ee19ecc53cd796e34268377a20357c (patch) | |
tree | 5fcfab02b127c4a6f93721a0260612245f443f0c /lib/Sema/SemaDecl.cpp | |
parent | b299d3516d4722ef527b1070bb87133427e621a3 (diff) |
Refactor the code that walks a C++ inheritance hierarchy, searching
for bases, members, overridden virtual methods, etc. The operations
isDerivedFrom and lookupInBases are now provided by CXXRecordDecl,
rather than by Sema, so that CodeGen and other clients can use them
directly.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83396 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8e69caae5c..a1fcf89c54 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -12,11 +12,11 @@ //===----------------------------------------------------------------------===// #include "Sema.h" -#include "SemaInherit.h" #include "clang/AST/APValue.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/Analysis/CFG.h" +#include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" @@ -2455,6 +2455,35 @@ static bool isUsingDecl(Decl *D) { return isa<UsingDecl>(D) || isa<UnresolvedUsingDecl>(D); } +/// \brief Data used with FindOverriddenMethod +struct FindOverriddenMethodData { + Sema *S; + CXXMethodDecl *Method; +}; + +/// \brief Member lookup function that determines whether a given C++ +/// method overrides a method in a base class, to be used with +/// CXXRecordDecl::lookupInBases(). +static bool FindOverriddenMethod(CXXBaseSpecifier *Specifier, + CXXBasePath &Path, + void *UserData) { + RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl(); + + FindOverriddenMethodData *Data + = reinterpret_cast<FindOverriddenMethodData*>(UserData); + for (Path.Decls = BaseRecord->lookup(Data->Method->getDeclName()); + Path.Decls.first != Path.Decls.second; + ++Path.Decls.first) { + if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*Path.Decls.first)) { + OverloadedFunctionDecl::function_iterator MatchedDecl; + if (MD->isVirtual() && !Data->S->IsOverload(Data->Method, MD, MatchedDecl)) + return true; + } + } + + return false; +} + NamedDecl* Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, QualType R, DeclaratorInfo *DInfo, @@ -2690,11 +2719,13 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD)) { // Look for virtual methods in base classes that this method might override. - - BasePaths Paths; - if (LookupInBases(cast<CXXRecordDecl>(DC), - MemberLookupCriteria(NewMD), Paths)) { - for (BasePaths::decl_iterator I = Paths.found_decls_begin(), + CXXBasePaths Paths; + FindOverriddenMethodData Data; + Data.Method = NewMD; + Data.S = this; + if (cast<CXXRecordDecl>(DC)->lookupInBases(&FindOverriddenMethod, &Data, + Paths)) { + for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(), E = Paths.found_decls_end(); I != E; ++I) { if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) { if (!CheckOverridingFunctionReturnType(NewMD, OldMD) && |