In a mem-initializer, a nested-name-specifier followed by an

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.

llvm-svn: 93871
This commit is contained in:
Douglas Gregor 2010-01-19 06:46:48 +00:00
parent 3024e9813e
commit a3b624aa55
2 changed files with 43 additions and 8 deletions

View 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);
}
}
}

View 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) { }
};
}