When building a type for a typename specifier, check specifically for
authorDouglas Gregor <dgregor@apple.com>
Tue, 1 Mar 2011 16:44:30 +0000 (16:44 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 1 Mar 2011 16:44:30 +0000 (16:44 +0000)
a dependent template name rather than (indirectly and incorrectly)
trying to determine whether we can compute a context for the
nested-name-specifier. Fixes a GCC testsuite regression,
<rdar://problem/9068589>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126749 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
test/SemaTemplate/typename-specifier-4.cpp

index fbb7246533509cadb2a756e7778da52359e13e20..a710f94436bea8608a92258d5e99d46a29f91bef 100644 (file)
@@ -5950,62 +5950,56 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
   translateTemplateArguments(TemplateArgsIn, TemplateArgs);
   
   TemplateName Template = TemplateIn.get();
-  
-  if (computeDeclContext(SS, false)) {
-    // If we can compute a declaration context, then the "typename"
-    // keyword was superfluous. Just build an ElaboratedType to keep
-    // track of the nested-name-specifier.
-    
-    QualType T = CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
-    if (T.isNull())
-      return true;
+  if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
+    // Construct a dependent template specialization type.
+    assert(DTN && "dependent template has non-dependent name?");
+    assert(DTN->getQualifier()
+           == static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
+    QualType T = Context.getDependentTemplateSpecializationType(ETK_Typename,
+                                                          DTN->getQualifier(),
+                                                          DTN->getIdentifier(),
+                                                                TemplateArgs);
     
-    // Provide source-location information for the template specialization 
-    // type.
+    // Create source-location information for this type.
     TypeLocBuilder Builder;
-    TemplateSpecializationTypeLoc SpecTL 
-      = Builder.push<TemplateSpecializationTypeLoc>(T);
-    
-    // FIXME: No place to set the location of the 'template' keyword!
+    DependentTemplateSpecializationTypeLoc SpecTL 
+    = Builder.push<DependentTemplateSpecializationTypeLoc>(T);
     SpecTL.setLAngleLoc(LAngleLoc);
     SpecTL.setRAngleLoc(RAngleLoc);
-    SpecTL.setTemplateNameLoc(TemplateNameLoc);
+    SpecTL.setKeywordLoc(TypenameLoc);
+    SpecTL.setNameLoc(TemplateNameLoc);
     for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
     
-    T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T);
-    ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
-    TL.setKeywordLoc(TypenameLoc);
-    TL.setQualifierLoc(SS.getWithLocInContext(Context));
-    
-    TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
-    return CreateParsedType(T, TSI);
+    // FIXME: Nested-name-specifier source locations.
+    SpecTL.setQualifierRange(SS.getRange());
+    return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
   }
   
-  // Construct a dependent template specialization type.
-  DependentTemplateName *DTN = Template.getAsDependentTemplateName();
-  assert(DTN && "dependent template has non-dependent name?");
-  assert(DTN->getQualifier()
-         == static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
-  QualType T = Context.getDependentTemplateSpecializationType(ETK_Typename,
-                                                          DTN->getQualifier(),
-                                                          DTN->getIdentifier(),
-                                                              TemplateArgs);
+  QualType T = CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
+  if (T.isNull())
+    return true;
   
-  // Create source-location information for this type.
+  // Provide source-location information for the template specialization 
+  // type.
   TypeLocBuilder Builder;
-  DependentTemplateSpecializationTypeLoc SpecTL 
-  = Builder.push<DependentTemplateSpecializationTypeLoc>(T);
+  TemplateSpecializationTypeLoc SpecTL 
+    = Builder.push<TemplateSpecializationTypeLoc>(T);
+  
+  // FIXME: No place to set the location of the 'template' keyword!
   SpecTL.setLAngleLoc(LAngleLoc);
   SpecTL.setRAngleLoc(RAngleLoc);
-  SpecTL.setKeywordLoc(TypenameLoc);
-  SpecTL.setNameLoc(TemplateNameLoc);
+  SpecTL.setTemplateNameLoc(TemplateNameLoc);
   for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
     SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
   
-  // FIXME: Nested-name-specifier source locations.
-  SpecTL.setQualifierRange(SS.getRange());
-  return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+  T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T);
+  ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
+  TL.setKeywordLoc(TypenameLoc);
+  TL.setQualifierLoc(SS.getWithLocInContext(Context));
+  
+  TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
+  return CreateParsedType(T, TSI);
 }
 
 
index 38045e0a31bf30ef0ccd981faebe96762bba6e6b..44cf966e33b593e0e2b5a3a82c459db64f9815f0 100644 (file)
@@ -154,3 +154,11 @@ namespace rdar8740998 {
     xi.f();
   }
 }
+
+namespace rdar9068589 {
+  // From GCC PR c++/13950
+  template <class T> struct Base {};
+  template <class T> struct Derived: public Base<T> {
+    typename Derived::template Base<double>* p1;
+  };
+}