aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-26 00:10:35 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-26 00:10:35 +0000
commitbefc20e1dc869edb0e7b560e69f32d5c71f867ab (patch)
treecc632d95aec3f7ff8a85e7f01fe420acab35ce6b /lib/Sema/SemaTemplate.cpp
parent1329c274628cc8c4e8ad472b41d1a78c8123f611 (diff)
The injected-class-name of class templates and class template
specializations can be treated as a template. Finally, we can parse and process the first implementation of Fibonacci I wrote! Note that this code does not handle all of the cases where injected-class-names can be treated as templates. In particular, there's an ambiguity case that we should be able to handle (but can't), e.g., template <class T> struct Base { }; template <class T> struct Derived : Base<int>, Base<char> { typename Derived::Base b; // error: ambiguous typename Derived::Base<double> d; // OK }; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67720 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 24b35ee5f5..c0476a8d3f 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -42,6 +42,28 @@ TemplateNameKind Sema::isTemplateName(IdentifierInfo &II, Scope *S,
return TNK_Template_template_parm;
else
assert(false && "Unknown TemplateDecl");
+ } else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(IIDecl)) {
+ // C++ [temp.local]p1:
+ // Like normal (non-template) classes, class templates have an
+ // injected-class-name (Clause 9). The injected-class-name
+ // can be used with or without a template-argument-list. When
+ // it is used without a template-argument-list, it is
+ // equivalent to the injected-class-name followed by the
+ // template-parameters of the class template enclosed in
+ // <>. When it is used with a template-argument-list, it
+ // refers to the specified class template specialization,
+ // which could be the current specialization or another
+ // specialization.
+ if (Record->isInjectedClassName()) {
+ Record = cast<CXXRecordDecl>(Context.getCanonicalDecl(Record));
+ if ((Template = Record->getDescribedClassTemplate()))
+ return TNK_Class_template;
+ else if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
+ Template = Spec->getSpecializedTemplate();
+ return TNK_Class_template;
+ }
+ }
}
// FIXME: What follows is a gross hack.
@@ -469,7 +491,7 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
// If we had a scope specifier, we better have a previous template
// declaration!
- TagDecl *NewClass =
+ CXXRecordDecl *NewClass =
CXXRecordDecl::Create(Context, Kind, SemanticContext, NameLoc, Name,
PrevClassTemplate?
PrevClassTemplate->getTemplatedDecl() : 0);
@@ -478,7 +500,8 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
= ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
DeclarationName(Name), TemplateParams,
NewClass, PrevClassTemplate);
-
+ NewClass->setDescribedClassTemplate(NewTemplate);
+
// Set the lexical context of these templates
NewClass->setLexicalDeclContext(CurContext);
NewTemplate->setLexicalDeclContext(CurContext);