diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-02-09 18:46:07 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-02-09 18:46:07 +0000 |
commit | 55f6b14230c94272efbbcdd89a92224c8db9f225 (patch) | |
tree | 988ae940f14f93aac610fbc36d89766e539eab6c /lib/Parse/ParseDecl.cpp | |
parent | 00e68e2cc5ce37cb95beb801cae73c0d1e9dda37 (diff) |
Start processing template-ids as types when the template-name refers
to a class template. For example, the template-id 'vector<int>' now
has a nice, sugary type in the type system. What we can do now:
- Parse template-ids like 'vector<int>' (where 'vector' names a
class template) and form proper types for them in the type system.
- Parse icky template-ids like 'A<5>' and 'A<(5 > 0)>' properly,
using (sadly) a bool in the parser to tell it whether '>' should
be treated as an operator or not.
This is a baby-step, with major problems and limitations:
- There are currently two ways that we handle template arguments
(whether they are types or expressions). These will be merged, and,
most likely, TemplateArg will disappear.
- We don't have any notion of the declaration of class template
specializations or of template instantiations, so all template-ids
are fancy names for 'int' :)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64153 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 73a09ee39c..5d601bc4f1 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -499,6 +499,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, Token Next = NextToken(); TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), Next.getLocation(), CurScope, &SS); + if (TypeRep == 0) goto DoneWithDeclSpec; @@ -553,9 +554,23 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // It has to be available as a typedef too! TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(), CurScope); + + if (TypeRep == 0 && getLang().CPlusPlus && NextToken().is(tok::less)) { + // If we have a template name, annotate the token and try again. + DeclTy *Template = 0; + if (TemplateNameKind TNK = + Actions.isTemplateName(*Tok.getIdentifierInfo(), CurScope, + Template)) { + AnnotateTemplateIdToken(Template, TNK, 0); + continue; + } + } + if (TypeRep == 0) goto DoneWithDeclSpec; + + // C++: If the identifier is actually the name of the class type // being defined and the next token is a '(', then this is a // constructor declaration. We're done with the decl-specifiers @@ -1752,11 +1767,12 @@ void Parser::ParseDirectDeclarator(Declarator &D) { // If this identifier is followed by a '<', we may have a template-id. DeclTy *Template; + Action::TemplateNameKind TNK; if (getLang().CPlusPlus && NextToken().is(tok::less) && - (Template = Actions.isTemplateName(*Tok.getIdentifierInfo(), - CurScope))) { + (TNK = Actions.isTemplateName(*Tok.getIdentifierInfo(), + CurScope, Template))) { IdentifierInfo *II = Tok.getIdentifierInfo(); - AnnotateTemplateIdToken(Template, 0); + AnnotateTemplateIdToken(Template, TNK, 0); // FIXME: Set the declarator to a template-id. How? I don't // know... for now, just use the identifier. D.SetIdentifier(II, Tok.getLocation()); |