From 5149f37cfc736d03233bf92b5ba7c6e866c6647b Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 25 Feb 2011 15:54:31 +0000 Subject: [PATCH] Maintain nested-name-specifier source-location information through instantiation of using declarations (all three forms). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126485 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiateDecl.cpp | 40 +++++++++----------- test/SemaCXX/nested-name-spec-locations.cpp | 42 +++++++++++++++++++++ 2 files changed, 59 insertions(+), 23 deletions(-) create mode 100644 test/SemaCXX/nested-name-spec-locations.cpp diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index f437cd3092..c96430a5d5 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1661,11 +1661,10 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { // template struct t; // Here, in using s1::f1, s1 refers to t::s1; // we need to substitute for t::s1. - NestedNameSpecifier *NNS - = SemaRef.SubstNestedNameSpecifier(D->getQualifier(), - D->getQualifierRange(), - TemplateArgs); - if (!NNS) + NestedNameSpecifierLoc QualifierLoc + = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), + TemplateArgs); + if (!QualifierLoc) return 0; // The name info is non-dependent, so no transformation @@ -1680,18 +1679,14 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName, Sema::ForRedeclaration); - CXXScopeSpec SS; - if (NNS == D->getQualifier()) - SS.Adopt(D->getQualifierLoc()); - else - SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange()); - UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner, D->getUsingLocation(), - SS.getWithLocInContext(SemaRef.Context), + QualifierLoc, NameInfo, D->isTypeName()); + CXXScopeSpec SS; + SS.Adopt(QualifierLoc); if (CheckRedeclaration) { Prev.setHideTags(false); SemaRef.LookupQualifiedName(Prev, Owner); @@ -1750,14 +1745,14 @@ Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) { Decl * TemplateDeclInstantiator ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { - NestedNameSpecifier *NNS = - SemaRef.SubstNestedNameSpecifier(D->getQualifier(), D->getQualifierRange(), - TemplateArgs); - if (!NNS) + NestedNameSpecifierLoc QualifierLoc + = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), + TemplateArgs); + if (!QualifierLoc) return 0; CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange()); + SS.Adopt(QualifierLoc); // Since NameInfo refers to a typename, it cannot be a C++ special name. // Hence, no tranformation is required for it. @@ -1775,14 +1770,13 @@ Decl * TemplateDeclInstantiator Decl * TemplateDeclInstantiator ::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { - NestedNameSpecifier *NNS = - SemaRef.SubstNestedNameSpecifier(D->getQualifier(), D->getQualifierRange(), - TemplateArgs); - if (!NNS) + NestedNameSpecifierLoc QualifierLoc + = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs); + if (!QualifierLoc) return 0; - + CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange()); + SS.Adopt(QualifierLoc); DeclarationNameInfo NameInfo = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs); diff --git a/test/SemaCXX/nested-name-spec-locations.cpp b/test/SemaCXX/nested-name-spec-locations.cpp new file mode 100644 index 0000000000..f0f42f754c --- /dev/null +++ b/test/SemaCXX/nested-name-spec-locations.cpp @@ -0,0 +1,42 @@ +// RUN: %clang-cc1 -fsyntax-only -verify %s + +// Note: the formatting in this test case is intentionally funny, with +// nested-name-specifiers stretched out vertically so that we can +// match up diagnostics per-line and still verify that we're getting +// good source-location information. + +namespace outer { + namespace inner { + template + struct X0 { + }; + } +} + +template +struct add_reference { + typedef T& type; +}; + +namespace outer_alias = outer; + +template +struct UnresolvedUsingValueDeclTester { + using outer::inner::X0< + typename add_reference::type + * // expected-error{{declared as a pointer to a reference of type}} + >::value; +}; + +UnresolvedUsingValueDeclTester UnresolvedUsingValueDeclCheck; // expected-note{{in instantiation of template class}} + +template +struct UnresolvedUsingTypenameDeclTester { + using outer::inner::X0< + typename add_reference::type + * // expected-error{{declared as a pointer to a reference of type}} + >::value; +}; + +UnresolvedUsingTypenameDeclTester UnresolvedUsingTypenameDeclCheck; // expected-note{{in instantiation of template class}} + -- 2.40.0