diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-03-27 23:10:48 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-03-27 23:10:48 +0000 |
| commit | 333489bba35d91e4ddb101f441087177c492d090 (patch) | |
| tree | 6b658646aed7c601a730536e09816cecc7ff0c65 /clang/lib/Sema/SemaTemplateInstantiate.cpp | |
| parent | 669f1d0b0b7ab0fd05f4cf672eab6dbe3f358953 (diff) | |
| download | bcm5719-llvm-333489bba35d91e4ddb101f441087177c492d090.tar.gz bcm5719-llvm-333489bba35d91e4ddb101f441087177c492d090.zip | |
Initial implementation of parsing, semantic analysis, and template
instantiation for C++ typename-specifiers such as
typename T::type
The parsing of typename-specifiers is relatively easy thanks to
annotation tokens. When we see the "typename", we parse the
typename-specifier and produce a typename annotation token. There are
only a few places where we need to handle this. We currently parse the
typename-specifier form that terminates in an identifier, but not the
simple-template-id form, e.g.,
typename T::template apply<U, V>
Parsing of nested-name-specifiers has a similar problem, since at this
point we don't have any representation of a class template
specialization whose template-name is unknown.
Semantic analysis is only partially complete, with some support for
template instantiation that works for simple examples.
llvm-svn: 67875
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 52f87b93f76..b274f870252 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -485,8 +485,23 @@ QualType TemplateTypeInstantiator:: InstantiateQualifiedNameType(const QualifiedNameType *T, unsigned Quals) const { - assert(false && "Cannot have dependent qualified name types (yet)"); - return QualType(); + // When we instantiated a qualified name type, there's no point in + // keeping the qualification around in the instantiated result. So, + // just instantiate the named type. + return (*this)(T->getNamedType()); +} + +QualType +TemplateTypeInstantiator:: +InstantiateTypenameType(const TypenameType *T, unsigned Quals) const { + NestedNameSpecifier *NNS + = SemaRef.InstantiateNestedNameSpecifier(T->getQualifier(), + SourceRange(Loc), + TemplateArgs, NumTemplateArgs); + if (!NNS) + return QualType(); + + return SemaRef.CheckTypenameType(NNS, *T->getName(), SourceRange(Loc)); } QualType @@ -799,21 +814,29 @@ Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS, if (!T->isDependentType()) return NNS; + // FIXME: We won't be able to perform the instantiation here when + // the template-name is dependent, e.g., we have something like + // "T::template apply<U>::type". T = InstantiateType(T, TemplateArgs, NumTemplateArgs, Range.getBegin(), DeclarationName()); if (T.isNull()) return 0; - // Note that T.getTypePtr(), below, strips cv-qualifiers. This is - // perfectly reasonable, since cv-qualified types in - // nested-name-specifiers don't matter. - // FIXME: we need to perform more checking on this type. - return NestedNameSpecifier::Create(Context, Prefix, + if (T->isRecordType() || + (getLangOptions().CPlusPlus0x && T->isEnumeralType())) { + // Note that T.getTypePtr(), below, strips cv-qualifiers. This is + // perfectly reasonable, since cv-qualified types in + // nested-name-specifiers don't matter. + return NestedNameSpecifier::Create(Context, Prefix, NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate, - T.getTypePtr()); + T.getTypePtr()); + } + + Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T; + return 0; } } - // Required to silence GCC warning. + // Required to silence a GCC warning return 0; } |

