]> granicus.if.org Git - clang/commitdiff
In a mem-initializer, a nested-name-specifier followed by an
authorDouglas Gregor <dgregor@apple.com>
Tue, 19 Jan 2010 06:46:48 +0000 (06:46 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 19 Jan 2010 06:46:48 +0000 (06:46 +0000)
identifier always names a type. In the case of a dependent
nested-name-specifier, build a TypenameType to describe the dependent
base type. I'd like to move more of this behavior up into the parser,
but this fixes PR6062.

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

lib/Sema/SemaDeclCXX.cpp
test/SemaTemplate/dependent-base-member-init.cpp

index a81a04e45e1830f42abce50087a21c72ed5da196..669629468de8f00c133e54be11782dec2c7179df 100644 (file)
@@ -1062,8 +1062,23 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
     if (!TyD) {
       if (R.isAmbiguous()) return true;
 
+      if (SS.isSet() && isDependentScopeSpecifier(SS)) {
+        bool NotUnknownSpecialization = false;
+        DeclContext *DC = computeDeclContext(SS, false);
+        if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(DC)) 
+          NotUnknownSpecialization = !Record->hasAnyDependentBases();
+
+        if (!NotUnknownSpecialization) {
+          // When the scope specifier can refer to a member of an unknown
+          // specialization, we take it as a type name.
+          BaseType = CheckTypenameType((NestedNameSpecifier *)SS.getScopeRep(),
+                                       *MemberOrBase, SS.getRange());
+          R.clear();
+        }
+      }
+
       // If no results were found, try to correct typos.
-      if (R.empty() && 
+      if (R.empty() && BaseType.isNull() &&
           CorrectTypo(R, S, &SS, ClassDecl) && R.isSingleResult()) {
         if (FieldDecl *Member = R.getAsSingle<FieldDecl>()) {
           if (Member->getDeclContext()->getLookupContext()->Equals(ClassDecl)) {
@@ -1106,20 +1121,22 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
         }
       }
 
-      if (!TyD) {
+      if (!TyD && BaseType.isNull()) {
         Diag(IdLoc, diag::err_mem_init_not_member_or_class)
           << MemberOrBase << SourceRange(IdLoc, RParenLoc);
         return true;
       }
     }
 
-    BaseType = Context.getTypeDeclType(TyD);
-    if (SS.isSet()) {
-      NestedNameSpecifier *Qualifier =
-        static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+    if (BaseType.isNull()) {
+      BaseType = Context.getTypeDeclType(TyD);
+      if (SS.isSet()) {
+        NestedNameSpecifier *Qualifier =
+          static_cast<NestedNameSpecifier*>(SS.getScopeRep());
 
-      // FIXME: preserve source range information
-      BaseType = Context.getQualifiedNameType(Qualifier, BaseType);
+        // FIXME: preserve source range information
+        BaseType = Context.getQualifiedNameType(Qualifier, BaseType);
+      }
     }
   }
 
index c9823d227d4cddd46daeb4b01e6eea2c07621784..3109375806422152f6e5dc15a40192706c51e4da 100644 (file)
@@ -34,3 +34,21 @@ template<typename T> struct s1 : s0<typename s0_traits<T>::t0> {
   s1() {}
 };
 
+// PR6062
+namespace PR6062 {
+  template <typename T>
+  class A : public T::type
+  {
+    A() : T::type()
+    {  
+    }
+    
+    template <typename U>
+    A(U const& init)
+      : T::type(init)
+    { }
+
+    template<typename U>
+    A(U& init) : U::other_type(init) { }
+  };
+}