diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-20 05:58:46 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-20 05:58:46 +0000 |
commit | 6cd219879ffce00920189ec1dcea927a42602961 (patch) | |
tree | cbaf0d413a75df7af09ee3f907fb3bbc020b0d07 /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | 8f99993856b4647a094bf1c2b703c4acc003f577 (diff) |
Handle substitutions into the "first qualifier in scope" of a
qualified member access expression (e.g., t->U::member) when that
first qualifier refers to a template parameters.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84612 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 7f8960a2bf..75719b0de9 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -400,6 +400,10 @@ namespace { /// instantiating it. Decl *TransformDefinition(Decl *D); + /// \bried Transform the first qualifier within a scope by instantiating the + /// declaration. + NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc); + /// \brief Rebuild the exception declaration and register the declaration /// as an instantiated local. VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T, @@ -457,6 +461,31 @@ Decl *TemplateInstantiator::TransformDefinition(Decl *D) { return Inst; } +NamedDecl * +TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D, + SourceLocation Loc) { + // If the first part of the nested-name-specifier was a template type + // parameter, instantiate that type parameter down to a tag type. + if (TemplateTypeParmDecl *TTPD = dyn_cast_or_null<TemplateTypeParmDecl>(D)) { + const TemplateTypeParmType *TTP + = cast<TemplateTypeParmType>(getSema().Context.getTypeDeclType(TTPD)); + if (TTP->getDepth() < TemplateArgs.getNumLevels()) { + QualType T = TemplateArgs(TTP->getDepth(), TTP->getIndex()).getAsType(); + if (T.isNull()) + return cast_or_null<NamedDecl>(TransformDecl(D)); + + if (const TagType *Tag = T->getAs<TagType>()) + return Tag->getDecl(); + + // The resulting type is not a tag; complain. + getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T; + return 0; + } + } + + return cast_or_null<NamedDecl>(TransformDecl(D)); +} + VarDecl * TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T, |