ParseTemplate.cpp revision aaba5e346dffdbad5d1c42765a89e4a7afb0da67
1//===--- 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"
15#include "clang/Parse/ParseDiagnostic.h"
16#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
30  // Enter template-parameter scope.
31  ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
32
33  // 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
42  // lists easily differentiate between the case above and:
43  //
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.
85  return ParseDeclarationOrFunctionDefinition(&ParamLists);
86}
87
88/// ParseTemplateParameters - Parses a template-parameter-list enclosed in
89/// 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.
95bool Parser::ParseTemplateParameters(unsigned Depth,
96                                     TemplateParameterList &TemplateParams,
97                                     SourceLocation &LAngleLoc,
98                                     SourceLocation &RAngleLoc) {
99  // 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  }
104  LAngleLoc = ConsumeToken();
105
106  // Try to parse the template parameter list.
107  if (Tok.is(tok::greater))
108    RAngleLoc = ConsumeToken();
109  else if(ParseTemplateParameterList(Depth, TemplateParams)) {
110    if(!Tok.is(tok::greater)) {
111      Diag(Tok.getLocation(), diag::err_expected_greater);
112      return false;
113    }
114    RAngleLoc = ConsumeToken();
115  }
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
127bool
128Parser::ParseTemplateParameterList(unsigned Depth,
129                                   TemplateParameterList &TemplateParams) {
130  while(1) {
131    if (DeclTy* TmpParam
132          = ParseTemplateParameter(Depth, TemplateParams.size())) {
133      TemplateParams.push_back(TmpParam);
134    } else {
135      // 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
173Parser::DeclTy *
174Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
175  if(Tok.is(tok::kw_class) ||
176     (Tok.is(tok::kw_typename) &&
177         // FIXME: Next token has not been annotated!
178	 NextToken().isNot(tok::annot_typename))) {
179    return ParseTypeParameter(Depth, Position);
180  }
181
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);
189}
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
200Parser::DeclTy *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
201  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();
207
208  // Grab the template parameter name (if given)
209  SourceLocation NameLoc;
210  IdentifierInfo* ParamName = 0;
211  if(Tok.is(tok::identifier)) {
212    ParamName = Tok.getIdentifierInfo();
213    NameLoc = ConsumeToken();
214  } 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
223  DeclTy *TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword,
224                                                 KeyLoc, ParamName, NameLoc,
225                                                 Depth, Position);
226
227  // Grab a default type id (if given).
228  if(Tok.is(tok::equal)) {
229    SourceLocation EqualLoc = ConsumeToken();
230    if (TypeTy *DefaultType = ParseTypeName())
231      Actions.ActOnTypeParameterDefault(TypeParam, DefaultType);
232  }
233
234  return TypeParam;
235}
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
243Parser::DeclTy *
244Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
245  assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
246
247  // Handle the template <...> part.
248  SourceLocation TemplateLoc = ConsumeToken();
249  TemplateParameterList TemplateParams;
250  SourceLocation LParenLoc, RParenLoc;
251  if(!ParseTemplateParameters(Depth + 1, TemplateParams, LParenLoc,
252                              RParenLoc)) {
253    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.
266  SourceLocation NameLoc;
267  IdentifierInfo* ParamName = 0;
268  if(Tok.is(tok::identifier)) {
269    ParamName = Tok.getIdentifierInfo();
270    NameLoc = ConsumeToken();
271  } 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.
280  // 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.
282  OwningExprResult DefaultExpr(Actions);
283  if(Tok.is(tok::equal)) {
284    ConsumeToken();
285    DefaultExpr = ParseCXXIdExpression();
286    if(DefaultExpr.isInvalid()) {
287      return 0;
288    }
289  }
290
291  return Actions.ActOnTemplateTemplateParameter(CurScope, TemplateLoc,
292                                                &TemplateParams, ParamName,
293                                                NameLoc, Depth, Position);
294}
295
296/// ParseNonTypeTemplateParameter - Handle the parsing of non-type
297/// template parameters (e.g., in "template<int Size> class array;").
298///
299///       template-parameter:
300///         ...
301///         parameter-declaration
302///
303/// NOTE: It would be ideal to simply call out to ParseParameterDeclaration(),
304/// but that didn't work out to well. Instead, this tries to recrate the basic
305/// parsing of parameter declarations, but tries to constrain it for template
306/// parameters.
307/// FIXME: We need to make a ParseParameterDeclaration that works for
308/// non-type template parameters and normal function parameters.
309Parser::DeclTy *
310Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
311  SourceLocation StartLoc = Tok.getLocation();
312
313  // Parse the declaration-specifiers (i.e., the type).
314  // FIXME: The type should probably be restricted in some way... Not all
315  // declarators (parts of declarators?) are accepted for parameters.
316  DeclSpec DS;
317  ParseDeclarationSpecifiers(DS);
318
319  // Parse this as a typename.
320  Declarator ParamDecl(DS, Declarator::TemplateParamContext);
321  ParseDeclarator(ParamDecl);
322  if (DS.getTypeSpecType() == DeclSpec::TST_unspecified && !DS.getTypeRep()) {
323    // This probably shouldn't happen - and it's more of a Sema thing, but
324    // basically we didn't parse the type name because we couldn't associate
325    // it with an AST node. we should just skip to the comma or greater.
326    // TODO: This is currently a placeholder for some kind of Sema Error.
327    Diag(Tok.getLocation(), diag::err_parse_error);
328    SkipUntil(tok::comma, tok::greater, true, true);
329    return 0;
330  }
331
332  // Create the parameter.
333  DeclTy *Param = Actions.ActOnNonTypeTemplateParameter(CurScope, ParamDecl,
334                                                        Depth, Position);
335
336  // Is there a default value? Parsing this can be fairly annoying because
337  // we have to stop on the first non-nested (paren'd) '>' as the closure
338  // for the template parameter list. Or a ','.
339  if (Tok.is(tok::equal)) {
340    // TODO: Implement default non-type values.
341    SkipUntil(tok::comma, tok::greater, true, true);
342  }
343
344  return Param;
345}
346
347/// AnnotateTemplateIdToken - The current token is an identifier that
348/// refers to the template declaration Template, and is followed by a
349/// '<'. Turn this template-id into a template-id annotation token.
350void Parser::AnnotateTemplateIdToken(DeclTy *Template, const CXXScopeSpec *SS) {
351  assert(getLang().CPlusPlus && "Can only annotate template-ids in C++");
352  assert(Template && Tok.is(tok::identifier) && NextToken().is(tok::less) &&
353         "Parser isn't at the beginning of a template-id");
354
355  // Consume the template-name.
356  SourceLocation TemplateNameLoc = ConsumeToken();
357
358  // Consume the '<'.
359  SourceLocation LAngleLoc = ConsumeToken();
360
361  // Parse the optional template-argument-list.
362  TemplateArgList TemplateArgs;
363  if (Tok.isNot(tok::greater) && ParseTemplateArgumentList(TemplateArgs)) {
364    // Try to find the closing '>'.
365    SkipUntil(tok::greater, true, true);
366
367    // FIXME: What's our recovery strategy for failed template-argument-lists?
368    return;
369  }
370
371  if (Tok.isNot(tok::greater))
372    return;
373
374  // Determine the location of the '>'. We won't actually consume this
375  // token, because we'll be replacing it with the template-id.
376  SourceLocation RAngleLoc = Tok.getLocation();
377
378  Tok.setKind(tok::annot_template_id);
379  Tok.setAnnotationEndLoc(RAngleLoc);
380  Tok.setLocation(TemplateNameLoc);
381  if (SS && SS->isNotEmpty())
382    Tok.setLocation(SS->getBeginLoc());
383
384  TemplateIdAnnotation *TemplateId
385    = (TemplateIdAnnotation *)malloc(sizeof(TemplateIdAnnotation) +
386                                  sizeof(TemplateArgTy*) * TemplateArgs.size());
387  TemplateId->TemplateNameLoc = TemplateNameLoc;
388  TemplateId->Template = Template;
389  TemplateId->LAngleLoc = LAngleLoc;
390  TemplateId->NumArgs = TemplateArgs.size();
391  TemplateArgTy **Args = (TemplateArgTy**)(TemplateId + 1);
392  for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
393    Args[Arg] = TemplateArgs[Arg];
394  Tok.setAnnotationValue(TemplateId);
395
396  // In case the tokens were cached, have Preprocessor replace them with the
397  // annotation token.
398  PP.AnnotateCachedTokens(Tok);
399}
400
401/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
402///
403///       template-argument: [C++ 14.2]
404///         assignment-expression
405///         type-id
406///         id-expression
407Parser::OwningTemplateArgResult Parser::ParseTemplateArgument() {
408  // FIXME: Implement this!
409  return TemplateArgError();
410}
411
412/// ParseTemplateArgumentList - Parse a C++ template-argument-list
413/// (C++ [temp.names]). Returns true if there was an error.
414///
415///       template-argument-list: [C++ 14.2]
416///         template-argument
417///         template-argument-list ',' template-argument
418bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
419  while (true) {
420    OwningTemplateArgResult Arg = ParseTemplateArgument();
421    if (Arg.isInvalid()) {
422      SkipUntil(tok::comma, tok::greater, true, true);
423      return true;
424    }
425    else
426      TemplateArgs.push_back(Arg.release());
427
428    // If the next token is a comma, consume it and keep reading
429    // arguments.
430    if (Tok.isNot(tok::comma)) break;
431
432    // Consume the comma.
433    ConsumeToken();
434  }
435
436  return Tok.isNot(tok::greater);
437}
438
439