summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-27 23:10:48 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-27 23:10:48 +0000
commit333489bba35d91e4ddb101f441087177c492d090 (patch)
tree6b658646aed7c601a730536e09816cecc7ff0c65 /clang/lib/Sema/SemaTemplateInstantiate.cpp
parent669f1d0b0b7ab0fd05f4cf672eab6dbe3f358953 (diff)
downloadbcm5719-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.cpp41
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;
}
OpenPOWER on IntegriCloud