[cfe-commits] r80783 - in /cfe/trunk: lib/AST/Type.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/typename-specifier-4.cpp
Douglas Gregor
dgregor at apple.com
Wed Sep 2 06:05:45 PDT 2009
Author: dgregor
Date: Wed Sep 2 08:05:45 2009
New Revision: 80783
URL: http://llvm.org/viewvc/llvm-project?rev=80783&view=rev
Log:
When parsing typename specifiers (with either the identifier or
simple-template-id form), check whether the scope specifier is
computable as a declaration context rather than checking whether it is
dependent, so that we properly cope with members of the current
instantiation.
Improve testing for typename specifiers that terminate in a
simpe-template-id.
Added:
cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp (with props)
Modified:
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=80783&r1=80782&r2=80783&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Sep 2 08:05:45 2009
@@ -530,7 +530,7 @@
Type::getAsTemplateSpecializationType() const {
// There is no sugar for class template specialization types, so
// just return the canonical type pointer if it is the right class.
- return dyn_cast<TemplateSpecializationType>(CanonicalType);
+ return this->getAs<TemplateSpecializationType>();
}
bool Type::isIntegerType() const {
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=80783&r1=80782&r2=80783&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Sep 2 08:05:45 2009
@@ -1137,9 +1137,7 @@
NestedNameSpecifier *Qualifier
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
- // FIXME: member of the current instantiation
-
- if (!Qualifier->isDependent()) {
+ if (computeDeclContext(SS, false)) {
// C++0x [temp.names]p5:
// If a name prefixed by the keyword template is not the name of
// a template, the program is ill-formed. [Note: the keyword
@@ -3010,10 +3008,16 @@
= T->getAsTemplateSpecializationType();
assert(TemplateId && "Expected a template specialization type");
- if (NNS->isDependent())
- return Context.getTypenameType(NNS, TemplateId).getAsOpaquePtr();
-
- return Context.getQualifiedNameType(NNS, T).getAsOpaquePtr();
+ if (computeDeclContext(SS, false)) {
+ // If we can compute a declaration context, then the "typename"
+ // keyword was superfluous. Just build a QualifiedNameType to keep
+ // track of the nested-name-specifier.
+
+ // FIXME: Note that the QualifiedNameType had the "typename" keyword!
+ return Context.getQualifiedNameType(NNS, T).getAsOpaquePtr();
+ }
+
+ return Context.getTypenameType(NNS, TemplateId).getAsOpaquePtr();
}
/// \brief Build the type that describes a C++ typename specifier,
Added: cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp?rev=80783&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp (added)
+++ cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp Wed Sep 2 08:05:45 2009
@@ -0,0 +1,56 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+template<typename MetaFun, typename T1, typename T2>
+struct metafun_apply2 {
+ typedef typename MetaFun::template apply<T1, T2> inner;
+ typedef typename inner::type type;
+};
+
+template<typename T, typename U> struct pair;
+
+struct make_pair {
+ template<typename T1, typename T2>
+ struct apply {
+ typedef pair<T1, T2> type;
+ };
+};
+
+int a0[is_same<metafun_apply2<make_pair, int, float>::type,
+ pair<int, float> >::value? 1 : -1];
+int a1[is_same<
+ typename make_pair::template apply<int, float>,
+ make_pair::apply<int, float>
+ >::value? 1 : -1];
+
+template<typename MetaFun>
+struct swap_and_apply2 {
+ template<typename T1, typename T2>
+ struct apply {
+ typedef typename MetaFun::template apply<T2, T1> new_metafun;
+ typedef typename new_metafun::type type;
+ };
+};
+
+int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type,
+ pair<float, int> >::value? 1 : -1];
+
+template<typename T>
+struct X0 {
+ template<typename U, typename V>
+ struct Inner;
+
+ void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}}
+ void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}}
+
+ void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}}
+ void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}}
+};
Propchange: cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list