diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-11-18 21:51:29 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-11-18 21:51:29 +0000 |
commit | d5b2453722a8e49b98ec6b15676379d514418c3c (patch) | |
tree | 55addbdc31dbfd7118695768205e59eea9888786 /clang/lib | |
parent | 7147de2c4ec3c68eb5c70b4fdd5393a07cd75469 (diff) | |
download | bcm5719-llvm-d5b2453722a8e49b98ec6b15676379d514418c3c.tar.gz bcm5719-llvm-d5b2453722a8e49b98ec6b15676379d514418c3c.zip |
Track overriding methods when instantiating a template class. Fixes PR5550.
llvm-svn: 89248
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Sema.h | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 40 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 |
3 files changed, 25 insertions, 18 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index a13ffc54da3..6a2b6d971bc 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -567,6 +567,7 @@ public: MultiTemplateParamsArg TemplateParamLists, bool IsFunctionDefinition, bool &Redeclaration); + void AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); void CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl, bool IsExplicitSpecialization, bool &Redeclaration, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 57c101bd32c..c2c048b3cf8 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2486,6 +2486,26 @@ static bool FindOverriddenMethod(const CXXBaseSpecifier *Specifier, return false; } +/// AddOverriddenMethods - See if a method overrides any in the base classes, +/// and if so, check that it's a valid override and remember it. +void Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) { + // Look for virtual methods in base classes that this method might override. + CXXBasePaths Paths; + FindOverriddenMethodData Data; + Data.Method = MD; + Data.S = this; + if (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(MD, OldMD) && + !CheckOverridingFunctionExceptionSpec(MD, OldMD)) + MD->addOverriddenMethod(OldMD); + } + } + } +} + NamedDecl* Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, QualType R, DeclaratorInfo *DInfo, @@ -2746,24 +2766,8 @@ 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. - 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) && - !CheckOverridingFunctionExceptionSpec(NewMD, OldMD)) - NewMD->addOverriddenMethod(OldMD); - } - } - } - } + if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD)) + AddOverriddenMethods(cast<CXXRecordDecl>(DC), NewMD); if (SC == FunctionDecl::Static && isa<CXXMethodDecl>(NewFD) && !CurContext->isRecord()) { diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 7e618cd4fae..deb7ff0ccc6 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -869,6 +869,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, !Method->getFriendObjectKind()) Owner->addDecl(Method); + SemaRef.AddOverriddenMethods(Record, Method); + return Method; } |