Mercurial > hg > CbC > CbC_llvm
comparison tools/clang/lib/Parse/ParseTemplate.cpp @ 0:95c75e76d11b LLVM3.4
LLVM 3.4
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 12 Dec 2013 13:56:28 +0900 |
parents | |
children | e4204d083e25 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:95c75e76d11b |
---|---|
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 "RAIIObjectsForParser.h" | |
16 #include "clang/AST/ASTConsumer.h" | |
17 #include "clang/AST/DeclTemplate.h" | |
18 #include "clang/Parse/ParseDiagnostic.h" | |
19 #include "clang/Sema/DeclSpec.h" | |
20 #include "clang/Sema/ParsedTemplate.h" | |
21 #include "clang/Sema/Scope.h" | |
22 using namespace clang; | |
23 | |
24 /// \brief Parse a template declaration, explicit instantiation, or | |
25 /// explicit specialization. | |
26 Decl * | |
27 Parser::ParseDeclarationStartingWithTemplate(unsigned Context, | |
28 SourceLocation &DeclEnd, | |
29 AccessSpecifier AS, | |
30 AttributeList *AccessAttrs) { | |
31 ObjCDeclContextSwitch ObjCDC(*this); | |
32 | |
33 if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) { | |
34 return ParseExplicitInstantiation(Context, | |
35 SourceLocation(), ConsumeToken(), | |
36 DeclEnd, AS); | |
37 } | |
38 return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS, | |
39 AccessAttrs); | |
40 } | |
41 | |
42 | |
43 | |
44 /// \brief Parse a template declaration or an explicit specialization. | |
45 /// | |
46 /// Template declarations include one or more template parameter lists | |
47 /// and either the function or class template declaration. Explicit | |
48 /// specializations contain one or more 'template < >' prefixes | |
49 /// followed by a (possibly templated) declaration. Since the | |
50 /// syntactic form of both features is nearly identical, we parse all | |
51 /// of the template headers together and let semantic analysis sort | |
52 /// the declarations from the explicit specializations. | |
53 /// | |
54 /// template-declaration: [C++ temp] | |
55 /// 'export'[opt] 'template' '<' template-parameter-list '>' declaration | |
56 /// | |
57 /// explicit-specialization: [ C++ temp.expl.spec] | |
58 /// 'template' '<' '>' declaration | |
59 Decl * | |
60 Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, | |
61 SourceLocation &DeclEnd, | |
62 AccessSpecifier AS, | |
63 AttributeList *AccessAttrs) { | |
64 assert((Tok.is(tok::kw_export) || Tok.is(tok::kw_template)) && | |
65 "Token does not start a template declaration."); | |
66 | |
67 // Enter template-parameter scope. | |
68 ParseScope TemplateParmScope(this, Scope::TemplateParamScope); | |
69 | |
70 // Tell the action that names should be checked in the context of | |
71 // the declaration to come. | |
72 ParsingDeclRAIIObject | |
73 ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent); | |
74 | |
75 // Parse multiple levels of template headers within this template | |
76 // parameter scope, e.g., | |
77 // | |
78 // template<typename T> | |
79 // template<typename U> | |
80 // class A<T>::B { ... }; | |
81 // | |
82 // We parse multiple levels non-recursively so that we can build a | |
83 // single data structure containing all of the template parameter | |
84 // lists to easily differentiate between the case above and: | |
85 // | |
86 // template<typename T> | |
87 // class A { | |
88 // template<typename U> class B; | |
89 // }; | |
90 // | |
91 // In the first case, the action for declaring A<T>::B receives | |
92 // both template parameter lists. In the second case, the action for | |
93 // defining A<T>::B receives just the inner template parameter list | |
94 // (and retrieves the outer template parameter list from its | |
95 // context). | |
96 bool isSpecialization = true; | |
97 bool LastParamListWasEmpty = false; | |
98 TemplateParameterLists ParamLists; | |
99 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); | |
100 | |
101 do { | |
102 // Consume the 'export', if any. | |
103 SourceLocation ExportLoc; | |
104 if (Tok.is(tok::kw_export)) { | |
105 ExportLoc = ConsumeToken(); | |
106 } | |
107 | |
108 // Consume the 'template', which should be here. | |
109 SourceLocation TemplateLoc; | |
110 if (Tok.is(tok::kw_template)) { | |
111 TemplateLoc = ConsumeToken(); | |
112 } else { | |
113 Diag(Tok.getLocation(), diag::err_expected_template); | |
114 return 0; | |
115 } | |
116 | |
117 // Parse the '<' template-parameter-list '>' | |
118 SourceLocation LAngleLoc, RAngleLoc; | |
119 SmallVector<Decl*, 4> TemplateParams; | |
120 if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(), | |
121 TemplateParams, LAngleLoc, RAngleLoc)) { | |
122 // Skip until the semi-colon or a }. | |
123 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); | |
124 if (Tok.is(tok::semi)) | |
125 ConsumeToken(); | |
126 return 0; | |
127 } | |
128 | |
129 ParamLists.push_back( | |
130 Actions.ActOnTemplateParameterList(CurTemplateDepthTracker.getDepth(), | |
131 ExportLoc, | |
132 TemplateLoc, LAngleLoc, | |
133 TemplateParams.data(), | |
134 TemplateParams.size(), RAngleLoc)); | |
135 | |
136 if (!TemplateParams.empty()) { | |
137 isSpecialization = false; | |
138 ++CurTemplateDepthTracker; | |
139 } else { | |
140 LastParamListWasEmpty = true; | |
141 } | |
142 } while (Tok.is(tok::kw_export) || Tok.is(tok::kw_template)); | |
143 | |
144 // Parse the actual template declaration. | |
145 return ParseSingleDeclarationAfterTemplate(Context, | |
146 ParsedTemplateInfo(&ParamLists, | |
147 isSpecialization, | |
148 LastParamListWasEmpty), | |
149 ParsingTemplateParams, | |
150 DeclEnd, AS, AccessAttrs); | |
151 } | |
152 | |
153 /// \brief Parse a single declaration that declares a template, | |
154 /// template specialization, or explicit instantiation of a template. | |
155 /// | |
156 /// \param DeclEnd will receive the source location of the last token | |
157 /// within this declaration. | |
158 /// | |
159 /// \param AS the access specifier associated with this | |
160 /// declaration. Will be AS_none for namespace-scope declarations. | |
161 /// | |
162 /// \returns the new declaration. | |
163 Decl * | |
164 Parser::ParseSingleDeclarationAfterTemplate( | |
165 unsigned Context, | |
166 const ParsedTemplateInfo &TemplateInfo, | |
167 ParsingDeclRAIIObject &DiagsFromTParams, | |
168 SourceLocation &DeclEnd, | |
169 AccessSpecifier AS, | |
170 AttributeList *AccessAttrs) { | |
171 assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && | |
172 "Template information required"); | |
173 | |
174 if (Context == Declarator::MemberContext) { | |
175 // We are parsing a member template. | |
176 ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo, | |
177 &DiagsFromTParams); | |
178 return 0; | |
179 } | |
180 | |
181 ParsedAttributesWithRange prefixAttrs(AttrFactory); | |
182 MaybeParseCXX11Attributes(prefixAttrs); | |
183 | |
184 if (Tok.is(tok::kw_using)) | |
185 return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd, | |
186 prefixAttrs); | |
187 | |
188 // Parse the declaration specifiers, stealing any diagnostics from | |
189 // the template parameters. | |
190 ParsingDeclSpec DS(*this, &DiagsFromTParams); | |
191 | |
192 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, | |
193 getDeclSpecContextFromDeclaratorContext(Context)); | |
194 | |
195 if (Tok.is(tok::semi)) { | |
196 ProhibitAttributes(prefixAttrs); | |
197 DeclEnd = ConsumeToken(); | |
198 Decl *Decl = Actions.ParsedFreeStandingDeclSpec( | |
199 getCurScope(), AS, DS, | |
200 TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams | |
201 : MultiTemplateParamsArg(), | |
202 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation); | |
203 DS.complete(Decl); | |
204 return Decl; | |
205 } | |
206 | |
207 // Move the attributes from the prefix into the DS. | |
208 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) | |
209 ProhibitAttributes(prefixAttrs); | |
210 else | |
211 DS.takeAttributesFrom(prefixAttrs); | |
212 | |
213 // Parse the declarator. | |
214 ParsingDeclarator DeclaratorInfo(*this, DS, (Declarator::TheContext)Context); | |
215 ParseDeclarator(DeclaratorInfo); | |
216 // Error parsing the declarator? | |
217 if (!DeclaratorInfo.hasName()) { | |
218 // If so, skip until the semi-colon or a }. | |
219 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); | |
220 if (Tok.is(tok::semi)) | |
221 ConsumeToken(); | |
222 return 0; | |
223 } | |
224 | |
225 LateParsedAttrList LateParsedAttrs(true); | |
226 if (DeclaratorInfo.isFunctionDeclarator()) | |
227 MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); | |
228 | |
229 if (DeclaratorInfo.isFunctionDeclarator() && | |
230 isStartOfFunctionDefinition(DeclaratorInfo)) { | |
231 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { | |
232 // Recover by ignoring the 'typedef'. This was probably supposed to be | |
233 // the 'typename' keyword, which we should have already suggested adding | |
234 // if it's appropriate. | |
235 Diag(DS.getStorageClassSpecLoc(), diag::err_function_declared_typedef) | |
236 << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); | |
237 DS.ClearStorageClassSpecs(); | |
238 } | |
239 | |
240 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { | |
241 if (DeclaratorInfo.getName().getKind() != UnqualifiedId::IK_TemplateId) { | |
242 // If the declarator-id is not a template-id, issue a diagnostic and | |
243 // recover by ignoring the 'template' keyword. | |
244 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0; | |
245 return ParseFunctionDefinition(DeclaratorInfo, ParsedTemplateInfo(), | |
246 &LateParsedAttrs); | |
247 } else { | |
248 SourceLocation LAngleLoc | |
249 = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); | |
250 Diag(DeclaratorInfo.getIdentifierLoc(), | |
251 diag::err_explicit_instantiation_with_definition) | |
252 << SourceRange(TemplateInfo.TemplateLoc) | |
253 << FixItHint::CreateInsertion(LAngleLoc, "<>"); | |
254 | |
255 // Recover as if it were an explicit specialization. | |
256 TemplateParameterLists FakedParamLists; | |
257 FakedParamLists.push_back(Actions.ActOnTemplateParameterList( | |
258 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, 0, 0, | |
259 LAngleLoc)); | |
260 | |
261 return ParseFunctionDefinition( | |
262 DeclaratorInfo, ParsedTemplateInfo(&FakedParamLists, | |
263 /*isSpecialization=*/true, | |
264 /*LastParamListWasEmpty=*/true), | |
265 &LateParsedAttrs); | |
266 } | |
267 } | |
268 return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo, | |
269 &LateParsedAttrs); | |
270 } | |
271 | |
272 // Parse this declaration. | |
273 Decl *ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo, | |
274 TemplateInfo); | |
275 | |
276 if (Tok.is(tok::comma)) { | |
277 Diag(Tok, diag::err_multiple_template_declarators) | |
278 << (int)TemplateInfo.Kind; | |
279 SkipUntil(tok::semi); | |
280 return ThisDecl; | |
281 } | |
282 | |
283 // Eat the semi colon after the declaration. | |
284 ExpectAndConsumeSemi(diag::err_expected_semi_declaration); | |
285 if (LateParsedAttrs.size() > 0) | |
286 ParseLexedAttributeList(LateParsedAttrs, ThisDecl, true, false); | |
287 DeclaratorInfo.complete(ThisDecl); | |
288 return ThisDecl; | |
289 } | |
290 | |
291 /// ParseTemplateParameters - Parses a template-parameter-list enclosed in | |
292 /// angle brackets. Depth is the depth of this template-parameter-list, which | |
293 /// is the number of template headers directly enclosing this template header. | |
294 /// TemplateParams is the current list of template parameters we're building. | |
295 /// The template parameter we parse will be added to this list. LAngleLoc and | |
296 /// RAngleLoc will receive the positions of the '<' and '>', respectively, | |
297 /// that enclose this template parameter list. | |
298 /// | |
299 /// \returns true if an error occurred, false otherwise. | |
300 bool Parser::ParseTemplateParameters(unsigned Depth, | |
301 SmallVectorImpl<Decl*> &TemplateParams, | |
302 SourceLocation &LAngleLoc, | |
303 SourceLocation &RAngleLoc) { | |
304 // Get the template parameter list. | |
305 if (!Tok.is(tok::less)) { | |
306 Diag(Tok.getLocation(), diag::err_expected_less_after) << "template"; | |
307 return true; | |
308 } | |
309 LAngleLoc = ConsumeToken(); | |
310 | |
311 // Try to parse the template parameter list. | |
312 bool Failed = false; | |
313 if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater)) | |
314 Failed = ParseTemplateParameterList(Depth, TemplateParams); | |
315 | |
316 if (Tok.is(tok::greatergreater)) { | |
317 // No diagnostic required here: a template-parameter-list can only be | |
318 // followed by a declaration or, for a template template parameter, the | |
319 // 'class' keyword. Therefore, the second '>' will be diagnosed later. | |
320 // This matters for elegant diagnosis of: | |
321 // template<template<typename>> struct S; | |
322 Tok.setKind(tok::greater); | |
323 RAngleLoc = Tok.getLocation(); | |
324 Tok.setLocation(Tok.getLocation().getLocWithOffset(1)); | |
325 } else if (Tok.is(tok::greater)) | |
326 RAngleLoc = ConsumeToken(); | |
327 else if (Failed) { | |
328 Diag(Tok.getLocation(), diag::err_expected_greater); | |
329 return true; | |
330 } | |
331 return false; | |
332 } | |
333 | |
334 /// ParseTemplateParameterList - Parse a template parameter list. If | |
335 /// the parsing fails badly (i.e., closing bracket was left out), this | |
336 /// will try to put the token stream in a reasonable position (closing | |
337 /// a statement, etc.) and return false. | |
338 /// | |
339 /// template-parameter-list: [C++ temp] | |
340 /// template-parameter | |
341 /// template-parameter-list ',' template-parameter | |
342 bool | |
343 Parser::ParseTemplateParameterList(unsigned Depth, | |
344 SmallVectorImpl<Decl*> &TemplateParams) { | |
345 while (1) { | |
346 if (Decl *TmpParam | |
347 = ParseTemplateParameter(Depth, TemplateParams.size())) { | |
348 TemplateParams.push_back(TmpParam); | |
349 } else { | |
350 // If we failed to parse a template parameter, skip until we find | |
351 // a comma or closing brace. | |
352 SkipUntil(tok::comma, tok::greater, tok::greatergreater, | |
353 StopAtSemi | StopBeforeMatch); | |
354 } | |
355 | |
356 // Did we find a comma or the end of the template parameter list? | |
357 if (Tok.is(tok::comma)) { | |
358 ConsumeToken(); | |
359 } else if (Tok.is(tok::greater) || Tok.is(tok::greatergreater)) { | |
360 // Don't consume this... that's done by template parser. | |
361 break; | |
362 } else { | |
363 // Somebody probably forgot to close the template. Skip ahead and | |
364 // try to get out of the expression. This error is currently | |
365 // subsumed by whatever goes on in ParseTemplateParameter. | |
366 Diag(Tok.getLocation(), diag::err_expected_comma_greater); | |
367 SkipUntil(tok::comma, tok::greater, tok::greatergreater, | |
368 StopAtSemi | StopBeforeMatch); | |
369 return false; | |
370 } | |
371 } | |
372 return true; | |
373 } | |
374 | |
375 /// \brief Determine whether the parser is at the start of a template | |
376 /// type parameter. | |
377 bool Parser::isStartOfTemplateTypeParameter() { | |
378 if (Tok.is(tok::kw_class)) { | |
379 // "class" may be the start of an elaborated-type-specifier or a | |
380 // type-parameter. Per C++ [temp.param]p3, we prefer the type-parameter. | |
381 switch (NextToken().getKind()) { | |
382 case tok::equal: | |
383 case tok::comma: | |
384 case tok::greater: | |
385 case tok::greatergreater: | |
386 case tok::ellipsis: | |
387 return true; | |
388 | |
389 case tok::identifier: | |
390 // This may be either a type-parameter or an elaborated-type-specifier. | |
391 // We have to look further. | |
392 break; | |
393 | |
394 default: | |
395 return false; | |
396 } | |
397 | |
398 switch (GetLookAheadToken(2).getKind()) { | |
399 case tok::equal: | |
400 case tok::comma: | |
401 case tok::greater: | |
402 case tok::greatergreater: | |
403 return true; | |
404 | |
405 default: | |
406 return false; | |
407 } | |
408 } | |
409 | |
410 if (Tok.isNot(tok::kw_typename)) | |
411 return false; | |
412 | |
413 // C++ [temp.param]p2: | |
414 // There is no semantic difference between class and typename in a | |
415 // template-parameter. typename followed by an unqualified-id | |
416 // names a template type parameter. typename followed by a | |
417 // qualified-id denotes the type in a non-type | |
418 // parameter-declaration. | |
419 Token Next = NextToken(); | |
420 | |
421 // If we have an identifier, skip over it. | |
422 if (Next.getKind() == tok::identifier) | |
423 Next = GetLookAheadToken(2); | |
424 | |
425 switch (Next.getKind()) { | |
426 case tok::equal: | |
427 case tok::comma: | |
428 case tok::greater: | |
429 case tok::greatergreater: | |
430 case tok::ellipsis: | |
431 return true; | |
432 | |
433 default: | |
434 return false; | |
435 } | |
436 } | |
437 | |
438 /// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]). | |
439 /// | |
440 /// template-parameter: [C++ temp.param] | |
441 /// type-parameter | |
442 /// parameter-declaration | |
443 /// | |
444 /// type-parameter: (see below) | |
445 /// 'class' ...[opt] identifier[opt] | |
446 /// 'class' identifier[opt] '=' type-id | |
447 /// 'typename' ...[opt] identifier[opt] | |
448 /// 'typename' identifier[opt] '=' type-id | |
449 /// 'template' '<' template-parameter-list '>' | |
450 /// 'class' ...[opt] identifier[opt] | |
451 /// 'template' '<' template-parameter-list '>' 'class' identifier[opt] | |
452 /// = id-expression | |
453 Decl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { | |
454 if (isStartOfTemplateTypeParameter()) | |
455 return ParseTypeParameter(Depth, Position); | |
456 | |
457 if (Tok.is(tok::kw_template)) | |
458 return ParseTemplateTemplateParameter(Depth, Position); | |
459 | |
460 // If it's none of the above, then it must be a parameter declaration. | |
461 // NOTE: This will pick up errors in the closure of the template parameter | |
462 // list (e.g., template < ; Check here to implement >> style closures. | |
463 return ParseNonTypeTemplateParameter(Depth, Position); | |
464 } | |
465 | |
466 /// ParseTypeParameter - Parse a template type parameter (C++ [temp.param]). | |
467 /// Other kinds of template parameters are parsed in | |
468 /// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter. | |
469 /// | |
470 /// type-parameter: [C++ temp.param] | |
471 /// 'class' ...[opt][C++0x] identifier[opt] | |
472 /// 'class' identifier[opt] '=' type-id | |
473 /// 'typename' ...[opt][C++0x] identifier[opt] | |
474 /// 'typename' identifier[opt] '=' type-id | |
475 Decl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) { | |
476 assert((Tok.is(tok::kw_class) || Tok.is(tok::kw_typename)) && | |
477 "A type-parameter starts with 'class' or 'typename'"); | |
478 | |
479 // Consume the 'class' or 'typename' keyword. | |
480 bool TypenameKeyword = Tok.is(tok::kw_typename); | |
481 SourceLocation KeyLoc = ConsumeToken(); | |
482 | |
483 // Grab the ellipsis (if given). | |
484 bool Ellipsis = false; | |
485 SourceLocation EllipsisLoc; | |
486 if (Tok.is(tok::ellipsis)) { | |
487 Ellipsis = true; | |
488 EllipsisLoc = ConsumeToken(); | |
489 | |
490 Diag(EllipsisLoc, | |
491 getLangOpts().CPlusPlus11 | |
492 ? diag::warn_cxx98_compat_variadic_templates | |
493 : diag::ext_variadic_templates); | |
494 } | |
495 | |
496 // Grab the template parameter name (if given) | |
497 SourceLocation NameLoc; | |
498 IdentifierInfo* ParamName = 0; | |
499 if (Tok.is(tok::identifier)) { | |
500 ParamName = Tok.getIdentifierInfo(); | |
501 NameLoc = ConsumeToken(); | |
502 } else if (Tok.is(tok::equal) || Tok.is(tok::comma) || | |
503 Tok.is(tok::greater) || Tok.is(tok::greatergreater)) { | |
504 // Unnamed template parameter. Don't have to do anything here, just | |
505 // don't consume this token. | |
506 } else { | |
507 Diag(Tok.getLocation(), diag::err_expected_ident); | |
508 return 0; | |
509 } | |
510 | |
511 // Grab a default argument (if available). | |
512 // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before | |
513 // we introduce the type parameter into the local scope. | |
514 SourceLocation EqualLoc; | |
515 ParsedType DefaultArg; | |
516 if (Tok.is(tok::equal)) { | |
517 EqualLoc = ConsumeToken(); | |
518 DefaultArg = ParseTypeName(/*Range=*/0, | |
519 Declarator::TemplateTypeArgContext).get(); | |
520 } | |
521 | |
522 return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, Ellipsis, | |
523 EllipsisLoc, KeyLoc, ParamName, NameLoc, | |
524 Depth, Position, EqualLoc, DefaultArg); | |
525 } | |
526 | |
527 /// ParseTemplateTemplateParameter - Handle the parsing of template | |
528 /// template parameters. | |
529 /// | |
530 /// type-parameter: [C++ temp.param] | |
531 /// 'template' '<' template-parameter-list '>' 'class' | |
532 /// ...[opt] identifier[opt] | |
533 /// 'template' '<' template-parameter-list '>' 'class' identifier[opt] | |
534 /// = id-expression | |
535 Decl * | |
536 Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { | |
537 assert(Tok.is(tok::kw_template) && "Expected 'template' keyword"); | |
538 | |
539 // Handle the template <...> part. | |
540 SourceLocation TemplateLoc = ConsumeToken(); | |
541 SmallVector<Decl*,8> TemplateParams; | |
542 SourceLocation LAngleLoc, RAngleLoc; | |
543 { | |
544 ParseScope TemplateParmScope(this, Scope::TemplateParamScope); | |
545 if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc, | |
546 RAngleLoc)) { | |
547 return 0; | |
548 } | |
549 } | |
550 | |
551 // Generate a meaningful error if the user forgot to put class before the | |
552 // identifier, comma, or greater. Provide a fixit if the identifier, comma, | |
553 // or greater appear immediately or after 'typename' or 'struct'. In the | |
554 // latter case, replace the keyword with 'class'. | |
555 if (!Tok.is(tok::kw_class)) { | |
556 bool Replace = Tok.is(tok::kw_typename) || Tok.is(tok::kw_struct); | |
557 const Token& Next = Replace ? NextToken() : Tok; | |
558 if (Next.is(tok::identifier) || Next.is(tok::comma) || | |
559 Next.is(tok::greater) || Next.is(tok::greatergreater) || | |
560 Next.is(tok::ellipsis)) | |
561 Diag(Tok.getLocation(), diag::err_class_on_template_template_param) | |
562 << (Replace ? FixItHint::CreateReplacement(Tok.getLocation(), "class") | |
563 : FixItHint::CreateInsertion(Tok.getLocation(), "class ")); | |
564 else | |
565 Diag(Tok.getLocation(), diag::err_class_on_template_template_param); | |
566 | |
567 if (Replace) | |
568 ConsumeToken(); | |
569 } else | |
570 ConsumeToken(); | |
571 | |
572 // Parse the ellipsis, if given. | |
573 SourceLocation EllipsisLoc; | |
574 if (Tok.is(tok::ellipsis)) { | |
575 EllipsisLoc = ConsumeToken(); | |
576 | |
577 Diag(EllipsisLoc, | |
578 getLangOpts().CPlusPlus11 | |
579 ? diag::warn_cxx98_compat_variadic_templates | |
580 : diag::ext_variadic_templates); | |
581 } | |
582 | |
583 // Get the identifier, if given. | |
584 SourceLocation NameLoc; | |
585 IdentifierInfo* ParamName = 0; | |
586 if (Tok.is(tok::identifier)) { | |
587 ParamName = Tok.getIdentifierInfo(); | |
588 NameLoc = ConsumeToken(); | |
589 } else if (Tok.is(tok::equal) || Tok.is(tok::comma) || | |
590 Tok.is(tok::greater) || Tok.is(tok::greatergreater)) { | |
591 // Unnamed template parameter. Don't have to do anything here, just | |
592 // don't consume this token. | |
593 } else { | |
594 Diag(Tok.getLocation(), diag::err_expected_ident); | |
595 return 0; | |
596 } | |
597 | |
598 TemplateParameterList *ParamList = | |
599 Actions.ActOnTemplateParameterList(Depth, SourceLocation(), | |
600 TemplateLoc, LAngleLoc, | |
601 TemplateParams.data(), | |
602 TemplateParams.size(), | |
603 RAngleLoc); | |
604 | |
605 // Grab a default argument (if available). | |
606 // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before | |
607 // we introduce the template parameter into the local scope. | |
608 SourceLocation EqualLoc; | |
609 ParsedTemplateArgument DefaultArg; | |
610 if (Tok.is(tok::equal)) { | |
611 EqualLoc = ConsumeToken(); | |
612 DefaultArg = ParseTemplateTemplateArgument(); | |
613 if (DefaultArg.isInvalid()) { | |
614 Diag(Tok.getLocation(), | |
615 diag::err_default_template_template_parameter_not_template); | |
616 SkipUntil(tok::comma, tok::greater, tok::greatergreater, | |
617 StopAtSemi | StopBeforeMatch); | |
618 } | |
619 } | |
620 | |
621 return Actions.ActOnTemplateTemplateParameter(getCurScope(), TemplateLoc, | |
622 ParamList, EllipsisLoc, | |
623 ParamName, NameLoc, Depth, | |
624 Position, EqualLoc, DefaultArg); | |
625 } | |
626 | |
627 /// ParseNonTypeTemplateParameter - Handle the parsing of non-type | |
628 /// template parameters (e.g., in "template<int Size> class array;"). | |
629 /// | |
630 /// template-parameter: | |
631 /// ... | |
632 /// parameter-declaration | |
633 Decl * | |
634 Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { | |
635 // Parse the declaration-specifiers (i.e., the type). | |
636 // FIXME: The type should probably be restricted in some way... Not all | |
637 // declarators (parts of declarators?) are accepted for parameters. | |
638 DeclSpec DS(AttrFactory); | |
639 ParseDeclarationSpecifiers(DS); | |
640 | |
641 // Parse this as a typename. | |
642 Declarator ParamDecl(DS, Declarator::TemplateParamContext); | |
643 ParseDeclarator(ParamDecl); | |
644 if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) { | |
645 Diag(Tok.getLocation(), diag::err_expected_template_parameter); | |
646 return 0; | |
647 } | |
648 | |
649 // If there is a default value, parse it. | |
650 // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before | |
651 // we introduce the template parameter into the local scope. | |
652 SourceLocation EqualLoc; | |
653 ExprResult DefaultArg; | |
654 if (Tok.is(tok::equal)) { | |
655 EqualLoc = ConsumeToken(); | |
656 | |
657 // C++ [temp.param]p15: | |
658 // When parsing a default template-argument for a non-type | |
659 // template-parameter, the first non-nested > is taken as the | |
660 // end of the template-parameter-list rather than a greater-than | |
661 // operator. | |
662 GreaterThanIsOperatorScope G(GreaterThanIsOperator, false); | |
663 EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); | |
664 | |
665 DefaultArg = ParseAssignmentExpression(); | |
666 if (DefaultArg.isInvalid()) | |
667 SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch); | |
668 } | |
669 | |
670 // Create the parameter. | |
671 return Actions.ActOnNonTypeTemplateParameter(getCurScope(), ParamDecl, | |
672 Depth, Position, EqualLoc, | |
673 DefaultArg.take()); | |
674 } | |
675 | |
676 /// \brief Parses a '>' at the end of a template list. | |
677 /// | |
678 /// If this function encounters '>>', '>>>', '>=', or '>>=', it tries | |
679 /// to determine if these tokens were supposed to be a '>' followed by | |
680 /// '>', '>>', '>=', or '>='. It emits an appropriate diagnostic if necessary. | |
681 /// | |
682 /// \param RAngleLoc the location of the consumed '>'. | |
683 /// | |
684 /// \param ConsumeLastToken if true, the '>' is not consumed. | |
685 /// | |
686 /// \returns true, if current token does not start with '>', false otherwise. | |
687 bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc, | |
688 bool ConsumeLastToken) { | |
689 // What will be left once we've consumed the '>'. | |
690 tok::TokenKind RemainingToken; | |
691 const char *ReplacementStr = "> >"; | |
692 | |
693 switch (Tok.getKind()) { | |
694 default: | |
695 Diag(Tok.getLocation(), diag::err_expected_greater); | |
696 return true; | |
697 | |
698 case tok::greater: | |
699 // Determine the location of the '>' token. Only consume this token | |
700 // if the caller asked us to. | |
701 RAngleLoc = Tok.getLocation(); | |
702 if (ConsumeLastToken) | |
703 ConsumeToken(); | |
704 return false; | |
705 | |
706 case tok::greatergreater: | |
707 RemainingToken = tok::greater; | |
708 break; | |
709 | |
710 case tok::greatergreatergreater: | |
711 RemainingToken = tok::greatergreater; | |
712 break; | |
713 | |
714 case tok::greaterequal: | |
715 RemainingToken = tok::equal; | |
716 ReplacementStr = "> ="; | |
717 break; | |
718 | |
719 case tok::greatergreaterequal: | |
720 RemainingToken = tok::greaterequal; | |
721 break; | |
722 } | |
723 | |
724 // This template-id is terminated by a token which starts with a '>'. Outside | |
725 // C++11, this is now error recovery, and in C++11, this is error recovery if | |
726 // the token isn't '>>'. | |
727 | |
728 RAngleLoc = Tok.getLocation(); | |
729 | |
730 // The source range of the '>>' or '>=' at the start of the token. | |
731 CharSourceRange ReplacementRange = | |
732 CharSourceRange::getCharRange(RAngleLoc, | |
733 Lexer::AdvanceToTokenCharacter(RAngleLoc, 2, PP.getSourceManager(), | |
734 getLangOpts())); | |
735 | |
736 // A hint to put a space between the '>>'s. In order to make the hint as | |
737 // clear as possible, we include the characters either side of the space in | |
738 // the replacement, rather than just inserting a space at SecondCharLoc. | |
739 FixItHint Hint1 = FixItHint::CreateReplacement(ReplacementRange, | |
740 ReplacementStr); | |
741 | |
742 // A hint to put another space after the token, if it would otherwise be | |
743 // lexed differently. | |
744 FixItHint Hint2; | |
745 Token Next = NextToken(); | |
746 if ((RemainingToken == tok::greater || | |
747 RemainingToken == tok::greatergreater) && | |
748 (Next.is(tok::greater) || Next.is(tok::greatergreater) || | |
749 Next.is(tok::greatergreatergreater) || Next.is(tok::equal) || | |
750 Next.is(tok::greaterequal) || Next.is(tok::greatergreaterequal) || | |
751 Next.is(tok::equalequal)) && | |
752 areTokensAdjacent(Tok, Next)) | |
753 Hint2 = FixItHint::CreateInsertion(Next.getLocation(), " "); | |
754 | |
755 unsigned DiagId = diag::err_two_right_angle_brackets_need_space; | |
756 if (getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater)) | |
757 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets; | |
758 else if (Tok.is(tok::greaterequal)) | |
759 DiagId = diag::err_right_angle_bracket_equal_needs_space; | |
760 Diag(Tok.getLocation(), DiagId) << Hint1 << Hint2; | |
761 | |
762 // Strip the initial '>' from the token. | |
763 if (RemainingToken == tok::equal && Next.is(tok::equal) && | |
764 areTokensAdjacent(Tok, Next)) { | |
765 // Join two adjacent '=' tokens into one, for cases like: | |
766 // void (*p)() = f<int>; | |
767 // return f<int>==p; | |
768 ConsumeToken(); | |
769 Tok.setKind(tok::equalequal); | |
770 Tok.setLength(Tok.getLength() + 1); | |
771 } else { | |
772 Tok.setKind(RemainingToken); | |
773 Tok.setLength(Tok.getLength() - 1); | |
774 } | |
775 Tok.setLocation(Lexer::AdvanceToTokenCharacter(RAngleLoc, 1, | |
776 PP.getSourceManager(), | |
777 getLangOpts())); | |
778 | |
779 if (!ConsumeLastToken) { | |
780 // Since we're not supposed to consume the '>' token, we need to push | |
781 // this token and revert the current token back to the '>'. | |
782 PP.EnterToken(Tok); | |
783 Tok.setKind(tok::greater); | |
784 Tok.setLength(1); | |
785 Tok.setLocation(RAngleLoc); | |
786 } | |
787 return false; | |
788 } | |
789 | |
790 | |
791 /// \brief Parses a template-id that after the template name has | |
792 /// already been parsed. | |
793 /// | |
794 /// This routine takes care of parsing the enclosed template argument | |
795 /// list ('<' template-parameter-list [opt] '>') and placing the | |
796 /// results into a form that can be transferred to semantic analysis. | |
797 /// | |
798 /// \param Template the template declaration produced by isTemplateName | |
799 /// | |
800 /// \param TemplateNameLoc the source location of the template name | |
801 /// | |
802 /// \param SS if non-NULL, the nested-name-specifier preceding the | |
803 /// template name. | |
804 /// | |
805 /// \param ConsumeLastToken if true, then we will consume the last | |
806 /// token that forms the template-id. Otherwise, we will leave the | |
807 /// last token in the stream (e.g., so that it can be replaced with an | |
808 /// annotation token). | |
809 bool | |
810 Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template, | |
811 SourceLocation TemplateNameLoc, | |
812 const CXXScopeSpec &SS, | |
813 bool ConsumeLastToken, | |
814 SourceLocation &LAngleLoc, | |
815 TemplateArgList &TemplateArgs, | |
816 SourceLocation &RAngleLoc) { | |
817 assert(Tok.is(tok::less) && "Must have already parsed the template-name"); | |
818 | |
819 // Consume the '<'. | |
820 LAngleLoc = ConsumeToken(); | |
821 | |
822 // Parse the optional template-argument-list. | |
823 bool Invalid = false; | |
824 { | |
825 GreaterThanIsOperatorScope G(GreaterThanIsOperator, false); | |
826 if (Tok.isNot(tok::greater) && Tok.isNot(tok::greatergreater)) | |
827 Invalid = ParseTemplateArgumentList(TemplateArgs); | |
828 | |
829 if (Invalid) { | |
830 // Try to find the closing '>'. | |
831 if (ConsumeLastToken) | |
832 SkipUntil(tok::greater, StopAtSemi); | |
833 else | |
834 SkipUntil(tok::greater, StopAtSemi | StopBeforeMatch); | |
835 return true; | |
836 } | |
837 } | |
838 | |
839 return ParseGreaterThanInTemplateList(RAngleLoc, ConsumeLastToken); | |
840 } | |
841 | |
842 /// \brief Replace the tokens that form a simple-template-id with an | |
843 /// annotation token containing the complete template-id. | |
844 /// | |
845 /// The first token in the stream must be the name of a template that | |
846 /// is followed by a '<'. This routine will parse the complete | |
847 /// simple-template-id and replace the tokens with a single annotation | |
848 /// token with one of two different kinds: if the template-id names a | |
849 /// type (and \p AllowTypeAnnotation is true), the annotation token is | |
850 /// a type annotation that includes the optional nested-name-specifier | |
851 /// (\p SS). Otherwise, the annotation token is a template-id | |
852 /// annotation that does not include the optional | |
853 /// nested-name-specifier. | |
854 /// | |
855 /// \param Template the declaration of the template named by the first | |
856 /// token (an identifier), as returned from \c Action::isTemplateName(). | |
857 /// | |
858 /// \param TNK the kind of template that \p Template | |
859 /// refers to, as returned from \c Action::isTemplateName(). | |
860 /// | |
861 /// \param SS if non-NULL, the nested-name-specifier that precedes | |
862 /// this template name. | |
863 /// | |
864 /// \param TemplateKWLoc if valid, specifies that this template-id | |
865 /// annotation was preceded by the 'template' keyword and gives the | |
866 /// location of that keyword. If invalid (the default), then this | |
867 /// template-id was not preceded by a 'template' keyword. | |
868 /// | |
869 /// \param AllowTypeAnnotation if true (the default), then a | |
870 /// simple-template-id that refers to a class template, template | |
871 /// template parameter, or other template that produces a type will be | |
872 /// replaced with a type annotation token. Otherwise, the | |
873 /// simple-template-id is always replaced with a template-id | |
874 /// annotation token. | |
875 /// | |
876 /// If an unrecoverable parse error occurs and no annotation token can be | |
877 /// formed, this function returns true. | |
878 /// | |
879 bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, | |
880 CXXScopeSpec &SS, | |
881 SourceLocation TemplateKWLoc, | |
882 UnqualifiedId &TemplateName, | |
883 bool AllowTypeAnnotation) { | |
884 assert(getLangOpts().CPlusPlus && "Can only annotate template-ids in C++"); | |
885 assert(Template && Tok.is(tok::less) && | |
886 "Parser isn't at the beginning of a template-id"); | |
887 | |
888 // Consume the template-name. | |
889 SourceLocation TemplateNameLoc = TemplateName.getSourceRange().getBegin(); | |
890 | |
891 // Parse the enclosed template argument list. | |
892 SourceLocation LAngleLoc, RAngleLoc; | |
893 TemplateArgList TemplateArgs; | |
894 bool Invalid = ParseTemplateIdAfterTemplateName(Template, | |
895 TemplateNameLoc, | |
896 SS, false, LAngleLoc, | |
897 TemplateArgs, | |
898 RAngleLoc); | |
899 | |
900 if (Invalid) { | |
901 // If we failed to parse the template ID but skipped ahead to a >, we're not | |
902 // going to be able to form a token annotation. Eat the '>' if present. | |
903 if (Tok.is(tok::greater)) | |
904 ConsumeToken(); | |
905 return true; | |
906 } | |
907 | |
908 ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs); | |
909 | |
910 // Build the annotation token. | |
911 if (TNK == TNK_Type_template && AllowTypeAnnotation) { | |
912 TypeResult Type | |
913 = Actions.ActOnTemplateIdType(SS, TemplateKWLoc, | |
914 Template, TemplateNameLoc, | |
915 LAngleLoc, TemplateArgsPtr, RAngleLoc); | |
916 if (Type.isInvalid()) { | |
917 // If we failed to parse the template ID but skipped ahead to a >, we're not | |
918 // going to be able to form a token annotation. Eat the '>' if present. | |
919 if (Tok.is(tok::greater)) | |
920 ConsumeToken(); | |
921 return true; | |
922 } | |
923 | |
924 Tok.setKind(tok::annot_typename); | |
925 setTypeAnnotation(Tok, Type.get()); | |
926 if (SS.isNotEmpty()) | |
927 Tok.setLocation(SS.getBeginLoc()); | |
928 else if (TemplateKWLoc.isValid()) | |
929 Tok.setLocation(TemplateKWLoc); | |
930 else | |
931 Tok.setLocation(TemplateNameLoc); | |
932 } else { | |
933 // Build a template-id annotation token that can be processed | |
934 // later. | |
935 Tok.setKind(tok::annot_template_id); | |
936 TemplateIdAnnotation *TemplateId | |
937 = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds); | |
938 TemplateId->TemplateNameLoc = TemplateNameLoc; | |
939 if (TemplateName.getKind() == UnqualifiedId::IK_Identifier) { | |
940 TemplateId->Name = TemplateName.Identifier; | |
941 TemplateId->Operator = OO_None; | |
942 } else { | |
943 TemplateId->Name = 0; | |
944 TemplateId->Operator = TemplateName.OperatorFunctionId.Operator; | |
945 } | |
946 TemplateId->SS = SS; | |
947 TemplateId->TemplateKWLoc = TemplateKWLoc; | |
948 TemplateId->Template = Template; | |
949 TemplateId->Kind = TNK; | |
950 TemplateId->LAngleLoc = LAngleLoc; | |
951 TemplateId->RAngleLoc = RAngleLoc; | |
952 ParsedTemplateArgument *Args = TemplateId->getTemplateArgs(); | |
953 for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg) | |
954 Args[Arg] = ParsedTemplateArgument(TemplateArgs[Arg]); | |
955 Tok.setAnnotationValue(TemplateId); | |
956 if (TemplateKWLoc.isValid()) | |
957 Tok.setLocation(TemplateKWLoc); | |
958 else | |
959 Tok.setLocation(TemplateNameLoc); | |
960 } | |
961 | |
962 // Common fields for the annotation token | |
963 Tok.setAnnotationEndLoc(RAngleLoc); | |
964 | |
965 // In case the tokens were cached, have Preprocessor replace them with the | |
966 // annotation token. | |
967 PP.AnnotateCachedTokens(Tok); | |
968 return false; | |
969 } | |
970 | |
971 /// \brief Replaces a template-id annotation token with a type | |
972 /// annotation token. | |
973 /// | |
974 /// If there was a failure when forming the type from the template-id, | |
975 /// a type annotation token will still be created, but will have a | |
976 /// NULL type pointer to signify an error. | |
977 void Parser::AnnotateTemplateIdTokenAsType() { | |
978 assert(Tok.is(tok::annot_template_id) && "Requires template-id tokens"); | |
979 | |
980 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); | |
981 assert((TemplateId->Kind == TNK_Type_template || | |
982 TemplateId->Kind == TNK_Dependent_template_name) && | |
983 "Only works for type and dependent templates"); | |
984 | |
985 ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), | |
986 TemplateId->NumArgs); | |
987 | |
988 TypeResult Type | |
989 = Actions.ActOnTemplateIdType(TemplateId->SS, | |
990 TemplateId->TemplateKWLoc, | |
991 TemplateId->Template, | |
992 TemplateId->TemplateNameLoc, | |
993 TemplateId->LAngleLoc, | |
994 TemplateArgsPtr, | |
995 TemplateId->RAngleLoc); | |
996 // Create the new "type" annotation token. | |
997 Tok.setKind(tok::annot_typename); | |
998 setTypeAnnotation(Tok, Type.isInvalid() ? ParsedType() : Type.get()); | |
999 if (TemplateId->SS.isNotEmpty()) // it was a C++ qualified type name. | |
1000 Tok.setLocation(TemplateId->SS.getBeginLoc()); | |
1001 // End location stays the same | |
1002 | |
1003 // Replace the template-id annotation token, and possible the scope-specifier | |
1004 // that precedes it, with the typename annotation token. | |
1005 PP.AnnotateCachedTokens(Tok); | |
1006 } | |
1007 | |
1008 /// \brief Determine whether the given token can end a template argument. | |
1009 static bool isEndOfTemplateArgument(Token Tok) { | |
1010 return Tok.is(tok::comma) || Tok.is(tok::greater) || | |
1011 Tok.is(tok::greatergreater); | |
1012 } | |
1013 | |
1014 /// \brief Parse a C++ template template argument. | |
1015 ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { | |
1016 if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) && | |
1017 !Tok.is(tok::annot_cxxscope)) | |
1018 return ParsedTemplateArgument(); | |
1019 | |
1020 // C++0x [temp.arg.template]p1: | |
1021 // A template-argument for a template template-parameter shall be the name | |
1022 // of a class template or an alias template, expressed as id-expression. | |
1023 // | |
1024 // We parse an id-expression that refers to a class template or alias | |
1025 // template. The grammar we parse is: | |
1026 // | |
1027 // nested-name-specifier[opt] template[opt] identifier ...[opt] | |
1028 // | |
1029 // followed by a token that terminates a template argument, such as ',', | |
1030 // '>', or (in some cases) '>>'. | |
1031 CXXScopeSpec SS; // nested-name-specifier, if present | |
1032 ParseOptionalCXXScopeSpecifier(SS, ParsedType(), | |
1033 /*EnteringContext=*/false); | |
1034 | |
1035 ParsedTemplateArgument Result; | |
1036 SourceLocation EllipsisLoc; | |
1037 if (SS.isSet() && Tok.is(tok::kw_template)) { | |
1038 // Parse the optional 'template' keyword following the | |
1039 // nested-name-specifier. | |
1040 SourceLocation TemplateKWLoc = ConsumeToken(); | |
1041 | |
1042 if (Tok.is(tok::identifier)) { | |
1043 // We appear to have a dependent template name. | |
1044 UnqualifiedId Name; | |
1045 Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); | |
1046 ConsumeToken(); // the identifier | |
1047 | |
1048 // Parse the ellipsis. | |
1049 if (Tok.is(tok::ellipsis)) | |
1050 EllipsisLoc = ConsumeToken(); | |
1051 | |
1052 // If the next token signals the end of a template argument, | |
1053 // then we have a dependent template name that could be a template | |
1054 // template argument. | |
1055 TemplateTy Template; | |
1056 if (isEndOfTemplateArgument(Tok) && | |
1057 Actions.ActOnDependentTemplateName(getCurScope(), | |
1058 SS, TemplateKWLoc, Name, | |
1059 /*ObjectType=*/ ParsedType(), | |
1060 /*EnteringContext=*/false, | |
1061 Template)) | |
1062 Result = ParsedTemplateArgument(SS, Template, Name.StartLocation); | |
1063 } | |
1064 } else if (Tok.is(tok::identifier)) { | |
1065 // We may have a (non-dependent) template name. | |
1066 TemplateTy Template; | |
1067 UnqualifiedId Name; | |
1068 Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); | |
1069 ConsumeToken(); // the identifier | |
1070 | |
1071 // Parse the ellipsis. | |
1072 if (Tok.is(tok::ellipsis)) | |
1073 EllipsisLoc = ConsumeToken(); | |
1074 | |
1075 if (isEndOfTemplateArgument(Tok)) { | |
1076 bool MemberOfUnknownSpecialization; | |
1077 TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, | |
1078 /*hasTemplateKeyword=*/false, | |
1079 Name, | |
1080 /*ObjectType=*/ ParsedType(), | |
1081 /*EnteringContext=*/false, | |
1082 Template, | |
1083 MemberOfUnknownSpecialization); | |
1084 if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) { | |
1085 // We have an id-expression that refers to a class template or | |
1086 // (C++0x) alias template. | |
1087 Result = ParsedTemplateArgument(SS, Template, Name.StartLocation); | |
1088 } | |
1089 } | |
1090 } | |
1091 | |
1092 // If this is a pack expansion, build it as such. | |
1093 if (EllipsisLoc.isValid() && !Result.isInvalid()) | |
1094 Result = Actions.ActOnPackExpansion(Result, EllipsisLoc); | |
1095 | |
1096 return Result; | |
1097 } | |
1098 | |
1099 /// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]). | |
1100 /// | |
1101 /// template-argument: [C++ 14.2] | |
1102 /// constant-expression | |
1103 /// type-id | |
1104 /// id-expression | |
1105 ParsedTemplateArgument Parser::ParseTemplateArgument() { | |
1106 // C++ [temp.arg]p2: | |
1107 // In a template-argument, an ambiguity between a type-id and an | |
1108 // expression is resolved to a type-id, regardless of the form of | |
1109 // the corresponding template-parameter. | |
1110 // | |
1111 // Therefore, we initially try to parse a type-id. | |
1112 if (isCXXTypeId(TypeIdAsTemplateArgument)) { | |
1113 SourceLocation Loc = Tok.getLocation(); | |
1114 TypeResult TypeArg = ParseTypeName(/*Range=*/0, | |
1115 Declarator::TemplateTypeArgContext); | |
1116 if (TypeArg.isInvalid()) | |
1117 return ParsedTemplateArgument(); | |
1118 | |
1119 return ParsedTemplateArgument(ParsedTemplateArgument::Type, | |
1120 TypeArg.get().getAsOpaquePtr(), | |
1121 Loc); | |
1122 } | |
1123 | |
1124 // Try to parse a template template argument. | |
1125 { | |
1126 TentativeParsingAction TPA(*this); | |
1127 | |
1128 ParsedTemplateArgument TemplateTemplateArgument | |
1129 = ParseTemplateTemplateArgument(); | |
1130 if (!TemplateTemplateArgument.isInvalid()) { | |
1131 TPA.Commit(); | |
1132 return TemplateTemplateArgument; | |
1133 } | |
1134 | |
1135 // Revert this tentative parse to parse a non-type template argument. | |
1136 TPA.Revert(); | |
1137 } | |
1138 | |
1139 // Parse a non-type template argument. | |
1140 SourceLocation Loc = Tok.getLocation(); | |
1141 ExprResult ExprArg = ParseConstantExpression(MaybeTypeCast); | |
1142 if (ExprArg.isInvalid() || !ExprArg.get()) | |
1143 return ParsedTemplateArgument(); | |
1144 | |
1145 return ParsedTemplateArgument(ParsedTemplateArgument::NonType, | |
1146 ExprArg.release(), Loc); | |
1147 } | |
1148 | |
1149 /// \brief Determine whether the current tokens can only be parsed as a | |
1150 /// template argument list (starting with the '<') and never as a '<' | |
1151 /// expression. | |
1152 bool Parser::IsTemplateArgumentList(unsigned Skip) { | |
1153 struct AlwaysRevertAction : TentativeParsingAction { | |
1154 AlwaysRevertAction(Parser &P) : TentativeParsingAction(P) { } | |
1155 ~AlwaysRevertAction() { Revert(); } | |
1156 } Tentative(*this); | |
1157 | |
1158 while (Skip) { | |
1159 ConsumeToken(); | |
1160 --Skip; | |
1161 } | |
1162 | |
1163 // '<' | |
1164 if (!Tok.is(tok::less)) | |
1165 return false; | |
1166 ConsumeToken(); | |
1167 | |
1168 // An empty template argument list. | |
1169 if (Tok.is(tok::greater)) | |
1170 return true; | |
1171 | |
1172 // See whether we have declaration specifiers, which indicate a type. | |
1173 while (isCXXDeclarationSpecifier() == TPResult::True()) | |
1174 ConsumeToken(); | |
1175 | |
1176 // If we have a '>' or a ',' then this is a template argument list. | |
1177 return Tok.is(tok::greater) || Tok.is(tok::comma); | |
1178 } | |
1179 | |
1180 /// ParseTemplateArgumentList - Parse a C++ template-argument-list | |
1181 /// (C++ [temp.names]). Returns true if there was an error. | |
1182 /// | |
1183 /// template-argument-list: [C++ 14.2] | |
1184 /// template-argument | |
1185 /// template-argument-list ',' template-argument | |
1186 bool | |
1187 Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) { | |
1188 // Template argument lists are constant-evaluation contexts. | |
1189 EnterExpressionEvaluationContext EvalContext(Actions,Sema::ConstantEvaluated); | |
1190 | |
1191 while (true) { | |
1192 ParsedTemplateArgument Arg = ParseTemplateArgument(); | |
1193 if (Tok.is(tok::ellipsis)) { | |
1194 SourceLocation EllipsisLoc = ConsumeToken(); | |
1195 Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc); | |
1196 } | |
1197 | |
1198 if (Arg.isInvalid()) { | |
1199 SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch); | |
1200 return true; | |
1201 } | |
1202 | |
1203 // Save this template argument. | |
1204 TemplateArgs.push_back(Arg); | |
1205 | |
1206 // If the next token is a comma, consume it and keep reading | |
1207 // arguments. | |
1208 if (Tok.isNot(tok::comma)) break; | |
1209 | |
1210 // Consume the comma. | |
1211 ConsumeToken(); | |
1212 } | |
1213 | |
1214 return false; | |
1215 } | |
1216 | |
1217 /// \brief Parse a C++ explicit template instantiation | |
1218 /// (C++ [temp.explicit]). | |
1219 /// | |
1220 /// explicit-instantiation: | |
1221 /// 'extern' [opt] 'template' declaration | |
1222 /// | |
1223 /// Note that the 'extern' is a GNU extension and C++11 feature. | |
1224 Decl *Parser::ParseExplicitInstantiation(unsigned Context, | |
1225 SourceLocation ExternLoc, | |
1226 SourceLocation TemplateLoc, | |
1227 SourceLocation &DeclEnd, | |
1228 AccessSpecifier AS) { | |
1229 // This isn't really required here. | |
1230 ParsingDeclRAIIObject | |
1231 ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent); | |
1232 | |
1233 return ParseSingleDeclarationAfterTemplate(Context, | |
1234 ParsedTemplateInfo(ExternLoc, | |
1235 TemplateLoc), | |
1236 ParsingTemplateParams, | |
1237 DeclEnd, AS); | |
1238 } | |
1239 | |
1240 SourceRange Parser::ParsedTemplateInfo::getSourceRange() const { | |
1241 if (TemplateParams) | |
1242 return getTemplateParamsRange(TemplateParams->data(), | |
1243 TemplateParams->size()); | |
1244 | |
1245 SourceRange R(TemplateLoc); | |
1246 if (ExternLoc.isValid()) | |
1247 R.setBegin(ExternLoc); | |
1248 return R; | |
1249 } | |
1250 | |
1251 void Parser::LateTemplateParserCallback(void *P, LateParsedTemplate &LPT) { | |
1252 ((Parser *)P)->ParseLateTemplatedFuncDef(LPT); | |
1253 } | |
1254 | |
1255 /// \brief Late parse a C++ function template in Microsoft mode. | |
1256 void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { | |
1257 if (!LPT.D) | |
1258 return; | |
1259 | |
1260 // Get the FunctionDecl. | |
1261 FunctionTemplateDecl *FunTmplD = dyn_cast<FunctionTemplateDecl>(LPT.D); | |
1262 FunctionDecl *FunD = | |
1263 FunTmplD ? FunTmplD->getTemplatedDecl() : cast<FunctionDecl>(LPT.D); | |
1264 // Track template parameter depth. | |
1265 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); | |
1266 | |
1267 // To restore the context after late parsing. | |
1268 Sema::ContextRAII GlobalSavedContext(Actions, Actions.CurContext); | |
1269 | |
1270 SmallVector<ParseScope*, 4> TemplateParamScopeStack; | |
1271 | |
1272 // Get the list of DeclContexts to reenter. | |
1273 SmallVector<DeclContext*, 4> DeclContextsToReenter; | |
1274 DeclContext *DD = FunD->getLexicalParent(); | |
1275 while (DD && !DD->isTranslationUnit()) { | |
1276 DeclContextsToReenter.push_back(DD); | |
1277 DD = DD->getLexicalParent(); | |
1278 } | |
1279 | |
1280 // Reenter template scopes from outermost to innermost. | |
1281 SmallVectorImpl<DeclContext *>::reverse_iterator II = | |
1282 DeclContextsToReenter.rbegin(); | |
1283 for (; II != DeclContextsToReenter.rend(); ++II) { | |
1284 if (ClassTemplatePartialSpecializationDecl *MD = | |
1285 dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(*II)) { | |
1286 TemplateParamScopeStack.push_back( | |
1287 new ParseScope(this, Scope::TemplateParamScope)); | |
1288 Actions.ActOnReenterTemplateScope(getCurScope(), MD); | |
1289 ++CurTemplateDepthTracker; | |
1290 } else if (CXXRecordDecl *MD = dyn_cast_or_null<CXXRecordDecl>(*II)) { | |
1291 bool IsClassTemplate = MD->getDescribedClassTemplate() != 0; | |
1292 TemplateParamScopeStack.push_back( | |
1293 new ParseScope(this, Scope::TemplateParamScope, | |
1294 /*ManageScope*/IsClassTemplate)); | |
1295 Actions.ActOnReenterTemplateScope(getCurScope(), | |
1296 MD->getDescribedClassTemplate()); | |
1297 if (IsClassTemplate) | |
1298 ++CurTemplateDepthTracker; | |
1299 } | |
1300 TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope)); | |
1301 Actions.PushDeclContext(Actions.getCurScope(), *II); | |
1302 } | |
1303 TemplateParamScopeStack.push_back( | |
1304 new ParseScope(this, Scope::TemplateParamScope)); | |
1305 | |
1306 DeclaratorDecl *Declarator = dyn_cast<DeclaratorDecl>(FunD); | |
1307 if (Declarator && Declarator->getNumTemplateParameterLists() != 0) { | |
1308 Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator); | |
1309 ++CurTemplateDepthTracker; | |
1310 } | |
1311 Actions.ActOnReenterTemplateScope(getCurScope(), LPT.D); | |
1312 ++CurTemplateDepthTracker; | |
1313 | |
1314 assert(!LPT.Toks.empty() && "Empty body!"); | |
1315 | |
1316 // Append the current token at the end of the new token stream so that it | |
1317 // doesn't get lost. | |
1318 LPT.Toks.push_back(Tok); | |
1319 PP.EnterTokenStream(LPT.Toks.data(), LPT.Toks.size(), true, false); | |
1320 | |
1321 // Consume the previously pushed token. | |
1322 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); | |
1323 assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) | |
1324 && "Inline method not starting with '{', ':' or 'try'"); | |
1325 | |
1326 // Parse the method body. Function body parsing code is similar enough | |
1327 // to be re-used for method bodies as well. | |
1328 ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope); | |
1329 | |
1330 // Recreate the containing function DeclContext. | |
1331 Sema::ContextRAII FunctionSavedContext(Actions, Actions.getContainingDC(FunD)); | |
1332 | |
1333 Actions.ActOnStartOfFunctionDef(getCurScope(), FunD); | |
1334 | |
1335 if (Tok.is(tok::kw_try)) { | |
1336 ParseFunctionTryBlock(LPT.D, FnScope); | |
1337 } else { | |
1338 if (Tok.is(tok::colon)) | |
1339 ParseConstructorInitializer(LPT.D); | |
1340 else | |
1341 Actions.ActOnDefaultCtorInitializers(LPT.D); | |
1342 | |
1343 if (Tok.is(tok::l_brace)) { | |
1344 assert((!FunTmplD || FunTmplD->getTemplateParameters()->getDepth() < | |
1345 TemplateParameterDepth) && | |
1346 "TemplateParameterDepth should be greater than the depth of " | |
1347 "current template being instantiated!"); | |
1348 ParseFunctionStatementBody(LPT.D, FnScope); | |
1349 Actions.UnmarkAsLateParsedTemplate(FunD); | |
1350 } else | |
1351 Actions.ActOnFinishFunctionBody(LPT.D, 0); | |
1352 } | |
1353 | |
1354 // Exit scopes. | |
1355 FnScope.Exit(); | |
1356 SmallVectorImpl<ParseScope *>::reverse_iterator I = | |
1357 TemplateParamScopeStack.rbegin(); | |
1358 for (; I != TemplateParamScopeStack.rend(); ++I) | |
1359 delete *I; | |
1360 } | |
1361 | |
1362 /// \brief Lex a delayed template function for late parsing. | |
1363 void Parser::LexTemplateFunctionForLateParsing(CachedTokens &Toks) { | |
1364 tok::TokenKind kind = Tok.getKind(); | |
1365 if (!ConsumeAndStoreFunctionPrologue(Toks)) { | |
1366 // Consume everything up to (and including) the matching right brace. | |
1367 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); | |
1368 } | |
1369 | |
1370 // If we're in a function-try-block, we need to store all the catch blocks. | |
1371 if (kind == tok::kw_try) { | |
1372 while (Tok.is(tok::kw_catch)) { | |
1373 ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false); | |
1374 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); | |
1375 } | |
1376 } | |
1377 } |