[cfe-commits] [Request for approval] Redundant NNS and missing template keyword

Douglas Gregor dgregor at apple.com
Fri Aug 6 04:04:57 PDT 2010


On Jul 27, 2010, at 12:01 PM, Abramo Bagnara wrote:

> Please find attached a couple of patches that are meant to fix the
> problems shown by the following examples.
> 
> ==============
> $ cat bug1.cc
> template <typename T>
> struct Outer {
>  template <typename U>
>  struct Inner {
>    Inner& foo();
>  };
> };
> 
> 
> template <typename T>
> template <typename U>
> typename Outer<T> ::template Inner<U>&
> Outer<T>::Inner<U>::foo() {}
> ==============
> 
> If this is pretty printed using clang, we obtain the following:
> 
> ==============
> $ llvm/Debug+Asserts/bin/clang -cc1 -ast-print bug1.cc
> struct __va_list_tag {
>    unsigned int gp_offset;
>    unsigned int fp_offset;
>    void *overflow_arg_area;
>    void *reg_save_area;
> };
> typedef struct __va_list_tag __va_list_tag;
> template <typename T> struct Outer {
>    template <typename U> struct Inner {
>        Inner<U> &foo();
>    };
> };
> typename Outer<T>::Outer<T>::Inner<U> &foo() {
> }
> ==============
> 
> The printed return type in the out-of-line definition of method foo has
> two problems: the name qualification Outer<T>:: is repeated and the name
> qualification Inner<U> is missing the "template" keyword.
> 
> The first problem is due to the fact that the NNS is encoded *both* in
> the ElaboratedType and in the underlying (dependent)
> TemplateSpecializationType: this should be corrected in redundant-nns.patch

In this patch, we have:

Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp	(revision 109367)
+++ lib/Sema/SemaTemplate.cpp	(working copy)
@@ -5258,8 +5260,6 @@
   
   TypeSourceInfo *InnerTSI = 0;
   QualType T = GetTypeFromParser(Ty, &InnerTSI);
-  NestedNameSpecifier *NNS
-    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
 
   assert(isa<TemplateSpecializationType>(T) && 
          "Expected a template specialization type");
@@ -5276,7 +5276,7 @@
     else
       Builder.push<TemplateSpecializationTypeLoc>(T).initialize(TemplateLoc);
 
-    T = Context.getElaboratedType(ETK_Typename, NNS, T);
+    T = Context.getElaboratedType(ETK_Typename, /*NNS=*/0, T);
     ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
     TL.setKeywordLoc(TypenameLoc);
     TL.setQualifierRange(SS.getRange());

I think we only want to drop NNS when T is a TemplateSpecializationTypeLoc. Otherwise, we'll end up eliminating some syntactic sugar in the non-template-specialization case.

> The second problem is caused by method Sema::isTemplateName(), which
> sometimes builds a QualifiedTemplateName disregarding whether or not the
> "template" keyword was specified: this should be corrected in
> template-keyword.patch

This patch looks good, thanks!

	- Doug



More information about the cfe-commits mailing list