diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-01-19 06:46:48 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-01-19 06:46:48 +0000 |
commit | a3b624aa557cbb153dc8fc3443ffdd7f540a0505 (patch) | |
tree | 87f9011240c44502400236496f090a677281b095 /clang/lib/Sema | |
parent | 3024e9813ecb7a0816ca0f5c0d27cdac84fea4fb (diff) | |
download | bcm5719-llvm-a3b624aa557cbb153dc8fc3443ffdd7f540a0505.tar.gz bcm5719-llvm-a3b624aa557cbb153dc8fc3443ffdd7f540a0505.zip |
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
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index a81a04e45e1..669629468de 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -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); + } } } |