blob: 8836106e3997e8b66898a62ce006ab7801be4ba8 [file] [log] [blame]
Douglas Gregorb3bec712008-12-01 23:54:00 +00001//===--- ParseTemplate.cpp - Template Parsing -----------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements parsing of C++ templates.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Parser.h"
Chris Lattner545f39e2009-01-29 05:15:15 +000015#include "clang/Parse/ParseDiagnostic.h"
Douglas Gregorb3bec712008-12-01 23:54:00 +000016#include "clang/Parse/DeclSpec.h"
17#include "clang/Parse/Scope.h"
18
19using namespace clang;
20
21/// ParseTemplateDeclaration - Parse a template declaration, which includes
22/// the template parameter list and either a function of class declaration.
23///
24/// template-declaration: [C++ temp]
25/// 'export'[opt] 'template' '<' template-parameter-list '>' declaration
26Parser::DeclTy *Parser::ParseTemplateDeclaration(unsigned Context) {
27 assert((Tok.is(tok::kw_export) || Tok.is(tok::kw_template)) &&
28 "Token does not start a template declaration.");
29
Douglas Gregor8e7f9572008-12-02 00:41:28 +000030 // Enter template-parameter scope.
Douglas Gregor95d40792008-12-10 06:34:36 +000031 ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
Douglas Gregor8e7f9572008-12-02 00:41:28 +000032
Douglas Gregor52473432008-12-24 02:52:09 +000033 // Parse multiple levels of template headers within this template
34 // parameter scope, e.g.,
35 //
36 // template<typename T>
37 // template<typename U>
38 // class A<T>::B { ... };
39 //
40 // We parse multiple levels non-recursively so that we can build a
41 // single data structure containing all of the template parameter
Douglas Gregor279272e2009-02-04 19:02:06 +000042 // lists easily differentiate between the case above and:
Douglas Gregor52473432008-12-24 02:52:09 +000043 //
44 // template<typename T>
45 // class A {
46 // template<typename U> class B;
47 // };
48 //
49 // In the first case, the action for declaring A<T>::B receives
50 // both template parameter lists. In the second case, the action for
51 // defining A<T>::B receives just the inner template parameter list
52 // (and retrieves the outer template parameter list from its
53 // context).
54 TemplateParameterLists ParamLists;
55 do {
56 // Consume the 'export', if any.
57 SourceLocation ExportLoc;
58 if (Tok.is(tok::kw_export)) {
59 ExportLoc = ConsumeToken();
60 }
61
62 // Consume the 'template', which should be here.
63 SourceLocation TemplateLoc;
64 if (Tok.is(tok::kw_template)) {
65 TemplateLoc = ConsumeToken();
66 } else {
67 Diag(Tok.getLocation(), diag::err_expected_template);
68 return 0;
69 }
70
71 // Parse the '<' template-parameter-list '>'
72 SourceLocation LAngleLoc, RAngleLoc;
73 TemplateParameterList TemplateParams;
74 ParseTemplateParameters(ParamLists.size(), TemplateParams, LAngleLoc,
75 RAngleLoc);
76
77 ParamLists.push_back(
78 Actions.ActOnTemplateParameterList(ParamLists.size(), ExportLoc,
79 TemplateLoc, LAngleLoc,
80 &TemplateParams[0],
81 TemplateParams.size(), RAngleLoc));
82 } while (Tok.is(tok::kw_export) || Tok.is(tok::kw_template));
83
84 // Parse the actual template declaration.
Douglas Gregor279272e2009-02-04 19:02:06 +000085 return ParseDeclarationOrFunctionDefinition(&ParamLists);
Douglas Gregorb3bec712008-12-01 23:54:00 +000086}
87
88/// ParseTemplateParameters - Parses a template-parameter-list enclosed in
Douglas Gregor279272e2009-02-04 19:02:06 +000089/// angle brackets. Depth is the depth of this template-parameter-list, which
90/// is the number of template headers directly enclosing this template header.
91/// TemplateParams is the current list of template parameters we're building.
92/// The template parameter we parse will be added to this list. LAngleLoc and
93/// RAngleLoc will receive the positions of the '<' and '>', respectively,
94/// that enclose this template parameter list.
Douglas Gregor52473432008-12-24 02:52:09 +000095bool Parser::ParseTemplateParameters(unsigned Depth,
96 TemplateParameterList &TemplateParams,
97 SourceLocation &LAngleLoc,
98 SourceLocation &RAngleLoc) {
Douglas Gregorb3bec712008-12-01 23:54:00 +000099 // Get the template parameter list.
100 if(!Tok.is(tok::less)) {
101 Diag(Tok.getLocation(), diag::err_expected_less_after) << "template";
102 return false;
103 }
Douglas Gregor52473432008-12-24 02:52:09 +0000104 LAngleLoc = ConsumeToken();
Douglas Gregorb3bec712008-12-01 23:54:00 +0000105
106 // Try to parse the template parameter list.
Douglas Gregor52473432008-12-24 02:52:09 +0000107 if (Tok.is(tok::greater))
108 RAngleLoc = ConsumeToken();
109 else if(ParseTemplateParameterList(Depth, TemplateParams)) {
Douglas Gregorb3bec712008-12-01 23:54:00 +0000110 if(!Tok.is(tok::greater)) {
111 Diag(Tok.getLocation(), diag::err_expected_greater);
112 return false;
113 }
Douglas Gregor52473432008-12-24 02:52:09 +0000114 RAngleLoc = ConsumeToken();
Douglas Gregorb3bec712008-12-01 23:54:00 +0000115 }
116 return true;
117}
118
119/// ParseTemplateParameterList - Parse a template parameter list. If
120/// the parsing fails badly (i.e., closing bracket was left out), this
121/// will try to put the token stream in a reasonable position (closing
122/// a statement, etc.) and return false.
123///
124/// template-parameter-list: [C++ temp]
125/// template-parameter
126/// template-parameter-list ',' template-parameter
Douglas Gregor52473432008-12-24 02:52:09 +0000127bool
128Parser::ParseTemplateParameterList(unsigned Depth,
129 TemplateParameterList &TemplateParams) {
Douglas Gregorb3bec712008-12-01 23:54:00 +0000130 while(1) {
Douglas Gregor52473432008-12-24 02:52:09 +0000131 if (DeclTy* TmpParam
132 = ParseTemplateParameter(Depth, TemplateParams.size())) {
133 TemplateParams.push_back(TmpParam);
134 } else {
Douglas Gregorb3bec712008-12-01 23:54:00 +0000135 // If we failed to parse a template parameter, skip until we find
136 // a comma or closing brace.
137 SkipUntil(tok::comma, tok::greater, true, true);
138 }
139
140 // Did we find a comma or the end of the template parmeter list?
141 if(Tok.is(tok::comma)) {
142 ConsumeToken();
143 } else if(Tok.is(tok::greater)) {
144 // Don't consume this... that's done by template parser.
145 break;
146 } else {
147 // Somebody probably forgot to close the template. Skip ahead and
148 // try to get out of the expression. This error is currently
149 // subsumed by whatever goes on in ParseTemplateParameter.
150 // TODO: This could match >>, and it would be nice to avoid those
151 // silly errors with template <vec<T>>.
152 // Diag(Tok.getLocation(), diag::err_expected_comma_greater);
153 SkipUntil(tok::greater, true, true);
154 return false;
155 }
156 }
157 return true;
158}
159
160/// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]).
161///
162/// template-parameter: [C++ temp.param]
163/// type-parameter
164/// parameter-declaration
165///
166/// type-parameter: (see below)
167/// 'class' identifier[opt]
168/// 'class' identifier[opt] '=' type-id
169/// 'typename' identifier[opt]
170/// 'typename' identifier[opt] '=' type-id
171/// 'template' '<' template-parameter-list '>' 'class' identifier[opt]
172/// 'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
Douglas Gregor52473432008-12-24 02:52:09 +0000173Parser::DeclTy *
174Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
Chris Lattner4e7a4202009-01-04 23:51:17 +0000175 if(Tok.is(tok::kw_class) ||
176 (Tok.is(tok::kw_typename) &&
177 // FIXME: Next token has not been annotated!
Chris Lattner5d7eace2009-01-06 05:06:21 +0000178 NextToken().isNot(tok::annot_typename))) {
Douglas Gregor52473432008-12-24 02:52:09 +0000179 return ParseTypeParameter(Depth, Position);
Douglas Gregorb3bec712008-12-01 23:54:00 +0000180 }
Chris Lattner4e7a4202009-01-04 23:51:17 +0000181
182 if(Tok.is(tok::kw_template))
183 return ParseTemplateTemplateParameter(Depth, Position);
184
185 // If it's none of the above, then it must be a parameter declaration.
186 // NOTE: This will pick up errors in the closure of the template parameter
187 // list (e.g., template < ; Check here to implement >> style closures.
188 return ParseNonTypeTemplateParameter(Depth, Position);
Douglas Gregorb3bec712008-12-01 23:54:00 +0000189}
190
191/// ParseTypeParameter - Parse a template type parameter (C++ [temp.param]).
192/// Other kinds of template parameters are parsed in
193/// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter.
194///
195/// type-parameter: [C++ temp.param]
196/// 'class' identifier[opt]
197/// 'class' identifier[opt] '=' type-id
198/// 'typename' identifier[opt]
199/// 'typename' identifier[opt] '=' type-id
Douglas Gregor52473432008-12-24 02:52:09 +0000200Parser::DeclTy *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000201 assert((Tok.is(tok::kw_class) || Tok.is(tok::kw_typename)) &&
202 "A type-parameter starts with 'class' or 'typename'");
203
204 // Consume the 'class' or 'typename' keyword.
205 bool TypenameKeyword = Tok.is(tok::kw_typename);
206 SourceLocation KeyLoc = ConsumeToken();
Douglas Gregorb3bec712008-12-01 23:54:00 +0000207
208 // Grab the template parameter name (if given)
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000209 SourceLocation NameLoc;
210 IdentifierInfo* ParamName = 0;
Douglas Gregorb3bec712008-12-01 23:54:00 +0000211 if(Tok.is(tok::identifier)) {
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000212 ParamName = Tok.getIdentifierInfo();
213 NameLoc = ConsumeToken();
Douglas Gregorb3bec712008-12-01 23:54:00 +0000214 } else if(Tok.is(tok::equal) || Tok.is(tok::comma) ||
215 Tok.is(tok::greater)) {
216 // Unnamed template parameter. Don't have to do anything here, just
217 // don't consume this token.
218 } else {
219 Diag(Tok.getLocation(), diag::err_expected_ident);
220 return 0;
221 }
222
Douglas Gregor279272e2009-02-04 19:02:06 +0000223 DeclTy *TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword,
224 KeyLoc, ParamName, NameLoc,
Douglas Gregor52473432008-12-24 02:52:09 +0000225 Depth, Position);
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000226
Douglas Gregorb3bec712008-12-01 23:54:00 +0000227 // Grab a default type id (if given).
Douglas Gregorb3bec712008-12-01 23:54:00 +0000228 if(Tok.is(tok::equal)) {
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000229 SourceLocation EqualLoc = ConsumeToken();
Douglas Gregor52473432008-12-24 02:52:09 +0000230 if (TypeTy *DefaultType = ParseTypeName())
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000231 Actions.ActOnTypeParameterDefault(TypeParam, DefaultType);
Douglas Gregorb3bec712008-12-01 23:54:00 +0000232 }
233
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000234 return TypeParam;
Douglas Gregorb3bec712008-12-01 23:54:00 +0000235}
236
237/// ParseTemplateTemplateParameter - Handle the parsing of template
238/// template parameters.
239///
240/// type-parameter: [C++ temp.param]
241/// 'template' '<' template-parameter-list '>' 'class' identifier[opt]
242/// 'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
Douglas Gregor52473432008-12-24 02:52:09 +0000243Parser::DeclTy *
244Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
Douglas Gregorb3bec712008-12-01 23:54:00 +0000245 assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
246
247 // Handle the template <...> part.
248 SourceLocation TemplateLoc = ConsumeToken();
Douglas Gregor52473432008-12-24 02:52:09 +0000249 TemplateParameterList TemplateParams;
Douglas Gregord406b032009-02-06 22:42:48 +0000250 SourceLocation LAngleLoc, RAngleLoc;
251 if(!ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc,
252 RAngleLoc)) {
Douglas Gregorb3bec712008-12-01 23:54:00 +0000253 return 0;
254 }
255
256 // Generate a meaningful error if the user forgot to put class before the
257 // identifier, comma, or greater.
258 if(!Tok.is(tok::kw_class)) {
259 Diag(Tok.getLocation(), diag::err_expected_class_before)
260 << PP.getSpelling(Tok);
261 return 0;
262 }
263 SourceLocation ClassLoc = ConsumeToken();
264
265 // Get the identifier, if given.
Douglas Gregor279272e2009-02-04 19:02:06 +0000266 SourceLocation NameLoc;
267 IdentifierInfo* ParamName = 0;
Douglas Gregorb3bec712008-12-01 23:54:00 +0000268 if(Tok.is(tok::identifier)) {
Douglas Gregor279272e2009-02-04 19:02:06 +0000269 ParamName = Tok.getIdentifierInfo();
270 NameLoc = ConsumeToken();
Douglas Gregorb3bec712008-12-01 23:54:00 +0000271 } else if(Tok.is(tok::equal) || Tok.is(tok::comma) || Tok.is(tok::greater)) {
272 // Unnamed template parameter. Don't have to do anything here, just
273 // don't consume this token.
274 } else {
275 Diag(Tok.getLocation(), diag::err_expected_ident);
276 return 0;
277 }
278
279 // Get the a default value, if given.
Douglas Gregor279272e2009-02-04 19:02:06 +0000280 // FIXME: I think that the results of this block need to be passed to the
281 // act-on call, so we can assemble the parameter correctly.
Sebastian Redl62261042008-12-09 20:22:58 +0000282 OwningExprResult DefaultExpr(Actions);
Douglas Gregorb3bec712008-12-01 23:54:00 +0000283 if(Tok.is(tok::equal)) {
284 ConsumeToken();
Sebastian Redlbb4dae72008-12-09 13:15:23 +0000285 DefaultExpr = ParseCXXIdExpression();
286 if(DefaultExpr.isInvalid()) {
Douglas Gregorb3bec712008-12-01 23:54:00 +0000287 return 0;
288 }
289 }
290
Douglas Gregord406b032009-02-06 22:42:48 +0000291 TemplateParamsTy *ParamList =
292 Actions.ActOnTemplateParameterList(Depth, SourceLocation(),
293 TemplateLoc, LAngleLoc,
294 &TemplateParams[0],
295 TemplateParams.size(),
296 RAngleLoc);
297
Douglas Gregor279272e2009-02-04 19:02:06 +0000298 return Actions.ActOnTemplateTemplateParameter(CurScope, TemplateLoc,
Douglas Gregord406b032009-02-06 22:42:48 +0000299 ParamList, ParamName,
Douglas Gregor279272e2009-02-04 19:02:06 +0000300 NameLoc, Depth, Position);
Douglas Gregorb3bec712008-12-01 23:54:00 +0000301}
302
303/// ParseNonTypeTemplateParameter - Handle the parsing of non-type
304/// template parameters (e.g., in "template<int Size> class array;").
Douglas Gregor2fa10442008-12-18 19:37:40 +0000305///
Douglas Gregorb3bec712008-12-01 23:54:00 +0000306/// template-parameter:
307/// ...
308/// parameter-declaration
309///
310/// NOTE: It would be ideal to simply call out to ParseParameterDeclaration(),
311/// but that didn't work out to well. Instead, this tries to recrate the basic
312/// parsing of parameter declarations, but tries to constrain it for template
313/// parameters.
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000314/// FIXME: We need to make a ParseParameterDeclaration that works for
315/// non-type template parameters and normal function parameters.
Douglas Gregor52473432008-12-24 02:52:09 +0000316Parser::DeclTy *
317Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000318 SourceLocation StartLoc = Tok.getLocation();
Douglas Gregorb3bec712008-12-01 23:54:00 +0000319
320 // Parse the declaration-specifiers (i.e., the type).
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000321 // FIXME: The type should probably be restricted in some way... Not all
Douglas Gregorb3bec712008-12-01 23:54:00 +0000322 // declarators (parts of declarators?) are accepted for parameters.
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000323 DeclSpec DS;
324 ParseDeclarationSpecifiers(DS);
Douglas Gregorb3bec712008-12-01 23:54:00 +0000325
326 // Parse this as a typename.
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000327 Declarator ParamDecl(DS, Declarator::TemplateParamContext);
328 ParseDeclarator(ParamDecl);
Chris Lattner8376d2e2009-01-05 01:24:05 +0000329 if (DS.getTypeSpecType() == DeclSpec::TST_unspecified && !DS.getTypeRep()) {
Douglas Gregorb3bec712008-12-01 23:54:00 +0000330 // This probably shouldn't happen - and it's more of a Sema thing, but
331 // basically we didn't parse the type name because we couldn't associate
332 // it with an AST node. we should just skip to the comma or greater.
333 // TODO: This is currently a placeholder for some kind of Sema Error.
334 Diag(Tok.getLocation(), diag::err_parse_error);
335 SkipUntil(tok::comma, tok::greater, true, true);
336 return 0;
337 }
338
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000339 // Create the parameter.
Douglas Gregor52473432008-12-24 02:52:09 +0000340 DeclTy *Param = Actions.ActOnNonTypeTemplateParameter(CurScope, ParamDecl,
341 Depth, Position);
Douglas Gregorb3bec712008-12-01 23:54:00 +0000342
343 // Is there a default value? Parsing this can be fairly annoying because
344 // we have to stop on the first non-nested (paren'd) '>' as the closure
345 // for the template parameter list. Or a ','.
Chris Lattner8376d2e2009-01-05 01:24:05 +0000346 if (Tok.is(tok::equal)) {
Douglas Gregorb3bec712008-12-01 23:54:00 +0000347 // TODO: Implement default non-type values.
348 SkipUntil(tok::comma, tok::greater, true, true);
349 }
350
Douglas Gregor8e7f9572008-12-02 00:41:28 +0000351 return Param;
Douglas Gregorb3bec712008-12-01 23:54:00 +0000352}
Douglas Gregor2fa10442008-12-18 19:37:40 +0000353
354/// AnnotateTemplateIdToken - The current token is an identifier that
355/// refers to the template declaration Template, and is followed by a
356/// '<'. Turn this template-id into a template-id annotation token.
357void Parser::AnnotateTemplateIdToken(DeclTy *Template, const CXXScopeSpec *SS) {
358 assert(getLang().CPlusPlus && "Can only annotate template-ids in C++");
359 assert(Template && Tok.is(tok::identifier) && NextToken().is(tok::less) &&
360 "Parser isn't at the beginning of a template-id");
361
362 // Consume the template-name.
363 SourceLocation TemplateNameLoc = ConsumeToken();
364
365 // Consume the '<'.
366 SourceLocation LAngleLoc = ConsumeToken();
367
368 // Parse the optional template-argument-list.
369 TemplateArgList TemplateArgs;
370 if (Tok.isNot(tok::greater) && ParseTemplateArgumentList(TemplateArgs)) {
371 // Try to find the closing '>'.
372 SkipUntil(tok::greater, true, true);
373
374 // FIXME: What's our recovery strategy for failed template-argument-lists?
375 return;
376 }
377
378 if (Tok.isNot(tok::greater))
379 return;
380
381 // Determine the location of the '>'. We won't actually consume this
382 // token, because we'll be replacing it with the template-id.
383 SourceLocation RAngleLoc = Tok.getLocation();
384
385 Tok.setKind(tok::annot_template_id);
386 Tok.setAnnotationEndLoc(RAngleLoc);
387 Tok.setLocation(TemplateNameLoc);
388 if (SS && SS->isNotEmpty())
389 Tok.setLocation(SS->getBeginLoc());
390
391 TemplateIdAnnotation *TemplateId
392 = (TemplateIdAnnotation *)malloc(sizeof(TemplateIdAnnotation) +
393 sizeof(TemplateArgTy*) * TemplateArgs.size());
394 TemplateId->TemplateNameLoc = TemplateNameLoc;
395 TemplateId->Template = Template;
396 TemplateId->LAngleLoc = LAngleLoc;
397 TemplateId->NumArgs = TemplateArgs.size();
398 TemplateArgTy **Args = (TemplateArgTy**)(TemplateId + 1);
399 for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
400 Args[Arg] = TemplateArgs[Arg];
401 Tok.setAnnotationValue(TemplateId);
402
403 // In case the tokens were cached, have Preprocessor replace them with the
404 // annotation token.
405 PP.AnnotateCachedTokens(Tok);
406}
407
408/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
409///
410/// template-argument: [C++ 14.2]
411/// assignment-expression
412/// type-id
413/// id-expression
414Parser::OwningTemplateArgResult Parser::ParseTemplateArgument() {
415 // FIXME: Implement this!
416 return TemplateArgError();
417}
418
419/// ParseTemplateArgumentList - Parse a C++ template-argument-list
420/// (C++ [temp.names]). Returns true if there was an error.
421///
422/// template-argument-list: [C++ 14.2]
423/// template-argument
424/// template-argument-list ',' template-argument
425bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
426 while (true) {
427 OwningTemplateArgResult Arg = ParseTemplateArgument();
428 if (Arg.isInvalid()) {
429 SkipUntil(tok::comma, tok::greater, true, true);
430 return true;
431 }
432 else
433 TemplateArgs.push_back(Arg.release());
434
435 // If the next token is a comma, consume it and keep reading
436 // arguments.
437 if (Tok.isNot(tok::comma)) break;
438
439 // Consume the comma.
440 ConsumeToken();
441 }
442
443 return Tok.isNot(tok::greater);
444}
445