Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/lib/Parse/ParseTemplate.cpp
Warning:line 1722, column 51
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ParseTemplate.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm -resource-dir /usr/lib/llvm-15/lib/clang/15.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/lib/Parse -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/lib/Parse -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-15/lib/clang/15.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm=build-llvm -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm=build-llvm -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm=build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-04-20-140412-16051-1 -x c++ /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/lib/Parse/ParseTemplate.cpp
1//===--- ParseTemplate.cpp - Template Parsing -----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements parsing of C++ templates.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/ASTContext.h"
14#include "clang/AST/DeclTemplate.h"
15#include "clang/AST/ExprCXX.h"
16#include "clang/Parse/ParseDiagnostic.h"
17#include "clang/Parse/Parser.h"
18#include "clang/Parse/RAIIObjectsForParser.h"
19#include "clang/Sema/DeclSpec.h"
20#include "clang/Sema/ParsedTemplate.h"
21#include "clang/Sema/Scope.h"
22#include "clang/Sema/SemaDiagnostic.h"
23#include "llvm/Support/TimeProfiler.h"
24using namespace clang;
25
26/// Re-enter a possible template scope, creating as many template parameter
27/// scopes as necessary.
28/// \return The number of template parameter scopes entered.
29unsigned Parser::ReenterTemplateScopes(MultiParseScope &S, Decl *D) {
30 return Actions.ActOnReenterTemplateScope(D, [&] {
31 S.Enter(Scope::TemplateParamScope);
32 return Actions.getCurScope();
33 });
34}
35
36/// Parse a template declaration, explicit instantiation, or
37/// explicit specialization.
38Decl *Parser::ParseDeclarationStartingWithTemplate(
39 DeclaratorContext Context, SourceLocation &DeclEnd,
40 ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
41 ObjCDeclContextSwitch ObjCDC(*this);
42
43 if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) {
44 return ParseExplicitInstantiation(Context, SourceLocation(), ConsumeToken(),
45 DeclEnd, AccessAttrs, AS);
46 }
47 return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,
48 AS);
49}
50
51/// Parse a template declaration or an explicit specialization.
52///
53/// Template declarations include one or more template parameter lists
54/// and either the function or class template declaration. Explicit
55/// specializations contain one or more 'template < >' prefixes
56/// followed by a (possibly templated) declaration. Since the
57/// syntactic form of both features is nearly identical, we parse all
58/// of the template headers together and let semantic analysis sort
59/// the declarations from the explicit specializations.
60///
61/// template-declaration: [C++ temp]
62/// 'export'[opt] 'template' '<' template-parameter-list '>' declaration
63///
64/// template-declaration: [C++2a]
65/// template-head declaration
66/// template-head concept-definition
67///
68/// TODO: requires-clause
69/// template-head: [C++2a]
70/// 'template' '<' template-parameter-list '>'
71/// requires-clause[opt]
72///
73/// explicit-specialization: [ C++ temp.expl.spec]
74/// 'template' '<' '>' declaration
75Decl *Parser::ParseTemplateDeclarationOrSpecialization(
76 DeclaratorContext Context, SourceLocation &DeclEnd,
77 ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
78 assert(Tok.isOneOf(tok::kw_export, tok::kw_template) &&(static_cast <bool> (Tok.isOneOf(tok::kw_export, tok::kw_template
) && "Token does not start a template declaration.") ?
void (0) : __assert_fail ("Tok.isOneOf(tok::kw_export, tok::kw_template) && \"Token does not start a template declaration.\""
, "clang/lib/Parse/ParseTemplate.cpp", 79, __extension__ __PRETTY_FUNCTION__
))
79 "Token does not start a template declaration.")(static_cast <bool> (Tok.isOneOf(tok::kw_export, tok::kw_template
) && "Token does not start a template declaration.") ?
void (0) : __assert_fail ("Tok.isOneOf(tok::kw_export, tok::kw_template) && \"Token does not start a template declaration.\""
, "clang/lib/Parse/ParseTemplate.cpp", 79, __extension__ __PRETTY_FUNCTION__
))
;
80
81 MultiParseScope TemplateParamScopes(*this);
82
83 // Tell the action that names should be checked in the context of
84 // the declaration to come.
85 ParsingDeclRAIIObject
86 ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent);
87
88 // Parse multiple levels of template headers within this template
89 // parameter scope, e.g.,
90 //
91 // template<typename T>
92 // template<typename U>
93 // class A<T>::B { ... };
94 //
95 // We parse multiple levels non-recursively so that we can build a
96 // single data structure containing all of the template parameter
97 // lists to easily differentiate between the case above and:
98 //
99 // template<typename T>
100 // class A {
101 // template<typename U> class B;
102 // };
103 //
104 // In the first case, the action for declaring A<T>::B receives
105 // both template parameter lists. In the second case, the action for
106 // defining A<T>::B receives just the inner template parameter list
107 // (and retrieves the outer template parameter list from its
108 // context).
109 bool isSpecialization = true;
110 bool LastParamListWasEmpty = false;
111 TemplateParameterLists ParamLists;
112 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
113
114 do {
115 // Consume the 'export', if any.
116 SourceLocation ExportLoc;
117 TryConsumeToken(tok::kw_export, ExportLoc);
118
119 // Consume the 'template', which should be here.
120 SourceLocation TemplateLoc;
121 if (!TryConsumeToken(tok::kw_template, TemplateLoc)) {
122 Diag(Tok.getLocation(), diag::err_expected_template);
123 return nullptr;
124 }
125
126 // Parse the '<' template-parameter-list '>'
127 SourceLocation LAngleLoc, RAngleLoc;
128 SmallVector<NamedDecl*, 4> TemplateParams;
129 if (ParseTemplateParameters(TemplateParamScopes,
130 CurTemplateDepthTracker.getDepth(),
131 TemplateParams, LAngleLoc, RAngleLoc)) {
132 // Skip until the semi-colon or a '}'.
133 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
134 TryConsumeToken(tok::semi);
135 return nullptr;
136 }
137
138 ExprResult OptionalRequiresClauseConstraintER;
139 if (!TemplateParams.empty()) {
140 isSpecialization = false;
141 ++CurTemplateDepthTracker;
142
143 if (TryConsumeToken(tok::kw_requires)) {
144 OptionalRequiresClauseConstraintER =
145 Actions.ActOnRequiresClause(ParseConstraintLogicalOrExpression(
146 /*IsTrailingRequiresClause=*/false));
147 if (!OptionalRequiresClauseConstraintER.isUsable()) {
148 // Skip until the semi-colon or a '}'.
149 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
150 TryConsumeToken(tok::semi);
151 return nullptr;
152 }
153 }
154 } else {
155 LastParamListWasEmpty = true;
156 }
157
158 ParamLists.push_back(Actions.ActOnTemplateParameterList(
159 CurTemplateDepthTracker.getDepth(), ExportLoc, TemplateLoc, LAngleLoc,
160 TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.get()));
161 } while (Tok.isOneOf(tok::kw_export, tok::kw_template));
162
163 // Parse the actual template declaration.
164 if (Tok.is(tok::kw_concept))
165 return ParseConceptDefinition(
166 ParsedTemplateInfo(&ParamLists, isSpecialization,
167 LastParamListWasEmpty),
168 DeclEnd);
169
170 return ParseSingleDeclarationAfterTemplate(
171 Context,
172 ParsedTemplateInfo(&ParamLists, isSpecialization, LastParamListWasEmpty),
173 ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
174}
175
176/// Parse a single declaration that declares a template,
177/// template specialization, or explicit instantiation of a template.
178///
179/// \param DeclEnd will receive the source location of the last token
180/// within this declaration.
181///
182/// \param AS the access specifier associated with this
183/// declaration. Will be AS_none for namespace-scope declarations.
184///
185/// \returns the new declaration.
186Decl *Parser::ParseSingleDeclarationAfterTemplate(
187 DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
188 ParsingDeclRAIIObject &DiagsFromTParams, SourceLocation &DeclEnd,
189 ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
190 assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&(static_cast <bool> (TemplateInfo.Kind != ParsedTemplateInfo
::NonTemplate && "Template information required") ? void
(0) : __assert_fail ("TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && \"Template information required\""
, "clang/lib/Parse/ParseTemplate.cpp", 191, __extension__ __PRETTY_FUNCTION__
))
191 "Template information required")(static_cast <bool> (TemplateInfo.Kind != ParsedTemplateInfo
::NonTemplate && "Template information required") ? void
(0) : __assert_fail ("TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && \"Template information required\""
, "clang/lib/Parse/ParseTemplate.cpp", 191, __extension__ __PRETTY_FUNCTION__
))
;
192
193 if (Tok.is(tok::kw_static_assert)) {
194 // A static_assert declaration may not be templated.
195 Diag(Tok.getLocation(), diag::err_templated_invalid_declaration)
196 << TemplateInfo.getSourceRange();
197 // Parse the static_assert declaration to improve error recovery.
198 return ParseStaticAssertDeclaration(DeclEnd);
199 }
200
201 if (Context == DeclaratorContext::Member) {
202 // We are parsing a member template.
203 ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
204 &DiagsFromTParams);
205 return nullptr;
206 }
207
208 ParsedAttributes prefixAttrs(AttrFactory);
209 MaybeParseCXX11Attributes(prefixAttrs);
210
211 if (Tok.is(tok::kw_using)) {
212 auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
213 prefixAttrs);
214 if (!usingDeclPtr || !usingDeclPtr.get().isSingleDecl())
215 return nullptr;
216 return usingDeclPtr.get().getSingleDecl();
217 }
218
219 // Parse the declaration specifiers, stealing any diagnostics from
220 // the template parameters.
221 ParsingDeclSpec DS(*this, &DiagsFromTParams);
222
223 ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
224 getDeclSpecContextFromDeclaratorContext(Context));
225
226 if (Tok.is(tok::semi)) {
227 ProhibitAttributes(prefixAttrs);
228 DeclEnd = ConsumeToken();
229 RecordDecl *AnonRecord = nullptr;
230 Decl *Decl = Actions.ParsedFreeStandingDeclSpec(
231 getCurScope(), AS, DS,
232 TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams
233 : MultiTemplateParamsArg(),
234 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation,
235 AnonRecord);
236 assert(!AnonRecord &&(static_cast <bool> (!AnonRecord && "Anonymous unions/structs should not be valid with template"
) ? void (0) : __assert_fail ("!AnonRecord && \"Anonymous unions/structs should not be valid with template\""
, "clang/lib/Parse/ParseTemplate.cpp", 237, __extension__ __PRETTY_FUNCTION__
))
237 "Anonymous unions/structs should not be valid with template")(static_cast <bool> (!AnonRecord && "Anonymous unions/structs should not be valid with template"
) ? void (0) : __assert_fail ("!AnonRecord && \"Anonymous unions/structs should not be valid with template\""
, "clang/lib/Parse/ParseTemplate.cpp", 237, __extension__ __PRETTY_FUNCTION__
))
;
238 DS.complete(Decl);
239 return Decl;
240 }
241
242 // Move the attributes from the prefix into the DS.
243 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
244 ProhibitAttributes(prefixAttrs);
245 else
246 DS.takeAttributesFrom(prefixAttrs);
247
248 // Parse the declarator.
249 ParsingDeclarator DeclaratorInfo(*this, DS, (DeclaratorContext)Context);
250 if (TemplateInfo.TemplateParams)
251 DeclaratorInfo.setTemplateParameterLists(*TemplateInfo.TemplateParams);
252
253 // Turn off usual access checking for template specializations and
254 // instantiations.
255 // C++20 [temp.spec] 13.9/6.
256 // This disables the access checking rules for function template explicit
257 // instantiation and explicit specialization:
258 // - parameter-list;
259 // - template-argument-list;
260 // - noexcept-specifier;
261 // - dynamic-exception-specifications (deprecated in C++11, removed since
262 // C++17).
263 bool IsTemplateSpecOrInst =
264 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
265 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
266 SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);
267
268 ParseDeclarator(DeclaratorInfo);
269
270 if (IsTemplateSpecOrInst)
271 SAC.done();
272
273 // Error parsing the declarator?
274 if (!DeclaratorInfo.hasName()) {
275 // If so, skip until the semi-colon or a }.
276 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
277 if (Tok.is(tok::semi))
278 ConsumeToken();
279 return nullptr;
280 }
281
282 llvm::TimeTraceScope TimeScope("ParseTemplate", [&]() {
283 return std::string(DeclaratorInfo.getIdentifier() != nullptr
284 ? DeclaratorInfo.getIdentifier()->getName()
285 : "<unknown>");
286 });
287
288 LateParsedAttrList LateParsedAttrs(true);
289 if (DeclaratorInfo.isFunctionDeclarator()) {
290 if (Tok.is(tok::kw_requires))
291 ParseTrailingRequiresClause(DeclaratorInfo);
292
293 MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
294 }
295
296 if (DeclaratorInfo.isFunctionDeclarator() &&
297 isStartOfFunctionDefinition(DeclaratorInfo)) {
298
299 // Function definitions are only allowed at file scope and in C++ classes.
300 // The C++ inline method definition case is handled elsewhere, so we only
301 // need to handle the file scope definition case.
302 if (Context != DeclaratorContext::File) {
303 Diag(Tok, diag::err_function_definition_not_allowed);
304 SkipMalformedDecl();
305 return nullptr;
306 }
307
308 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
309 // Recover by ignoring the 'typedef'. This was probably supposed to be
310 // the 'typename' keyword, which we should have already suggested adding
311 // if it's appropriate.
312 Diag(DS.getStorageClassSpecLoc(), diag::err_function_declared_typedef)
313 << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
314 DS.ClearStorageClassSpecs();
315 }
316
317 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
318 if (DeclaratorInfo.getName().getKind() !=
319 UnqualifiedIdKind::IK_TemplateId) {
320 // If the declarator-id is not a template-id, issue a diagnostic and
321 // recover by ignoring the 'template' keyword.
322 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
323 return ParseFunctionDefinition(DeclaratorInfo, ParsedTemplateInfo(),
324 &LateParsedAttrs);
325 } else {
326 SourceLocation LAngleLoc
327 = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
328 Diag(DeclaratorInfo.getIdentifierLoc(),
329 diag::err_explicit_instantiation_with_definition)
330 << SourceRange(TemplateInfo.TemplateLoc)
331 << FixItHint::CreateInsertion(LAngleLoc, "<>");
332
333 // Recover as if it were an explicit specialization.
334 TemplateParameterLists FakedParamLists;
335 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
336 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None,
337 LAngleLoc, nullptr));
338
339 return ParseFunctionDefinition(
340 DeclaratorInfo, ParsedTemplateInfo(&FakedParamLists,
341 /*isSpecialization=*/true,
342 /*lastParameterListWasEmpty=*/true),
343 &LateParsedAttrs);
344 }
345 }
346 return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo,
347 &LateParsedAttrs);
348 }
349
350 // Parse this declaration.
351 Decl *ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo,
352 TemplateInfo);
353
354 if (Tok.is(tok::comma)) {
355 Diag(Tok, diag::err_multiple_template_declarators)
356 << (int)TemplateInfo.Kind;
357 SkipUntil(tok::semi);
358 return ThisDecl;
359 }
360
361 // Eat the semi colon after the declaration.
362 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
363 if (LateParsedAttrs.size() > 0)
364 ParseLexedAttributeList(LateParsedAttrs, ThisDecl, true, false);
365 DeclaratorInfo.complete(ThisDecl);
366 return ThisDecl;
367}
368
369/// \brief Parse a single declaration that declares a concept.
370///
371/// \param DeclEnd will receive the source location of the last token
372/// within this declaration.
373///
374/// \returns the new declaration.
375Decl *
376Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
377 SourceLocation &DeclEnd) {
378 assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&(static_cast <bool> (TemplateInfo.Kind != ParsedTemplateInfo
::NonTemplate && "Template information required") ? void
(0) : __assert_fail ("TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && \"Template information required\""
, "clang/lib/Parse/ParseTemplate.cpp", 379, __extension__ __PRETTY_FUNCTION__
))
379 "Template information required")(static_cast <bool> (TemplateInfo.Kind != ParsedTemplateInfo
::NonTemplate && "Template information required") ? void
(0) : __assert_fail ("TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && \"Template information required\""
, "clang/lib/Parse/ParseTemplate.cpp", 379, __extension__ __PRETTY_FUNCTION__
))
;
380 assert(Tok.is(tok::kw_concept) &&(static_cast <bool> (Tok.is(tok::kw_concept) &&
"ParseConceptDefinition must be called when at a 'concept' keyword"
) ? void (0) : __assert_fail ("Tok.is(tok::kw_concept) && \"ParseConceptDefinition must be called when at a 'concept' keyword\""
, "clang/lib/Parse/ParseTemplate.cpp", 381, __extension__ __PRETTY_FUNCTION__
))
381 "ParseConceptDefinition must be called when at a 'concept' keyword")(static_cast <bool> (Tok.is(tok::kw_concept) &&
"ParseConceptDefinition must be called when at a 'concept' keyword"
) ? void (0) : __assert_fail ("Tok.is(tok::kw_concept) && \"ParseConceptDefinition must be called when at a 'concept' keyword\""
, "clang/lib/Parse/ParseTemplate.cpp", 381, __extension__ __PRETTY_FUNCTION__
))
;
382
383 ConsumeToken(); // Consume 'concept'
384
385 SourceLocation BoolKWLoc;
386 if (TryConsumeToken(tok::kw_bool, BoolKWLoc))
387 Diag(Tok.getLocation(), diag::ext_concept_legacy_bool_keyword) <<
388 FixItHint::CreateRemoval(SourceLocation(BoolKWLoc));
389
390 DiagnoseAndSkipCXX11Attributes();
391
392 CXXScopeSpec SS;
393 if (ParseOptionalCXXScopeSpecifier(
394 SS, /*ObjectType=*/nullptr,
395 /*ObjectHasErrors=*/false, /*EnteringContext=*/false,
396 /*MayBePseudoDestructor=*/nullptr,
397 /*IsTypename=*/false, /*LastII=*/nullptr, /*OnlyNamespace=*/true) ||
398 SS.isInvalid()) {
399 SkipUntil(tok::semi);
400 return nullptr;
401 }
402
403 if (SS.isNotEmpty())
404 Diag(SS.getBeginLoc(),
405 diag::err_concept_definition_not_identifier);
406
407 UnqualifiedId Result;
408 if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
409 /*ObjectHadErrors=*/false, /*EnteringContext=*/false,
410 /*AllowDestructorName=*/false,
411 /*AllowConstructorName=*/false,
412 /*AllowDeductionGuide=*/false,
413 /*TemplateKWLoc=*/nullptr, Result)) {
414 SkipUntil(tok::semi);
415 return nullptr;
416 }
417
418 if (Result.getKind() != UnqualifiedIdKind::IK_Identifier) {
419 Diag(Result.getBeginLoc(), diag::err_concept_definition_not_identifier);
420 SkipUntil(tok::semi);
421 return nullptr;
422 }
423
424 IdentifierInfo *Id = Result.Identifier;
425 SourceLocation IdLoc = Result.getBeginLoc();
426
427 DiagnoseAndSkipCXX11Attributes();
428
429 if (!TryConsumeToken(tok::equal)) {
430 Diag(Tok.getLocation(), diag::err_expected) << tok::equal;
431 SkipUntil(tok::semi);
432 return nullptr;
433 }
434
435 ExprResult ConstraintExprResult =
436 Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression());
437 if (ConstraintExprResult.isInvalid()) {
438 SkipUntil(tok::semi);
439 return nullptr;
440 }
441
442 DeclEnd = Tok.getLocation();
443 ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
444 Expr *ConstraintExpr = ConstraintExprResult.get();
445 return Actions.ActOnConceptDefinition(getCurScope(),
446 *TemplateInfo.TemplateParams,
447 Id, IdLoc, ConstraintExpr);
448}
449
450/// ParseTemplateParameters - Parses a template-parameter-list enclosed in
451/// angle brackets. Depth is the depth of this template-parameter-list, which
452/// is the number of template headers directly enclosing this template header.
453/// TemplateParams is the current list of template parameters we're building.
454/// The template parameter we parse will be added to this list. LAngleLoc and
455/// RAngleLoc will receive the positions of the '<' and '>', respectively,
456/// that enclose this template parameter list.
457///
458/// \returns true if an error occurred, false otherwise.
459bool Parser::ParseTemplateParameters(
460 MultiParseScope &TemplateScopes, unsigned Depth,
461 SmallVectorImpl<NamedDecl *> &TemplateParams, SourceLocation &LAngleLoc,
462 SourceLocation &RAngleLoc) {
463 // Get the template parameter list.
464 if (!TryConsumeToken(tok::less, LAngleLoc)) {
465 Diag(Tok.getLocation(), diag::err_expected_less_after) << "template";
466 return true;
467 }
468
469 // Try to parse the template parameter list.
470 bool Failed = false;
471 // FIXME: Missing greatergreatergreater support.
472 if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater)) {
473 TemplateScopes.Enter(Scope::TemplateParamScope);
474 Failed = ParseTemplateParameterList(Depth, TemplateParams);
475 }
476
477 if (Tok.is(tok::greatergreater)) {
478 // No diagnostic required here: a template-parameter-list can only be
479 // followed by a declaration or, for a template template parameter, the
480 // 'class' keyword. Therefore, the second '>' will be diagnosed later.
481 // This matters for elegant diagnosis of:
482 // template<template<typename>> struct S;
483 Tok.setKind(tok::greater);
484 RAngleLoc = Tok.getLocation();
485 Tok.setLocation(Tok.getLocation().getLocWithOffset(1));
486 } else if (!TryConsumeToken(tok::greater, RAngleLoc) && Failed) {
487 Diag(Tok.getLocation(), diag::err_expected) << tok::greater;
488 return true;
489 }
490 return false;
491}
492
493/// ParseTemplateParameterList - Parse a template parameter list. If
494/// the parsing fails badly (i.e., closing bracket was left out), this
495/// will try to put the token stream in a reasonable position (closing
496/// a statement, etc.) and return false.
497///
498/// template-parameter-list: [C++ temp]
499/// template-parameter
500/// template-parameter-list ',' template-parameter
501bool
502Parser::ParseTemplateParameterList(const unsigned Depth,
503 SmallVectorImpl<NamedDecl*> &TemplateParams) {
504 while (true) {
505
506 if (NamedDecl *TmpParam
507 = ParseTemplateParameter(Depth, TemplateParams.size())) {
508 TemplateParams.push_back(TmpParam);
509 } else {
510 // If we failed to parse a template parameter, skip until we find
511 // a comma or closing brace.
512 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
513 StopAtSemi | StopBeforeMatch);
514 }
515
516 // Did we find a comma or the end of the template parameter list?
517 if (Tok.is(tok::comma)) {
518 ConsumeToken();
519 } else if (Tok.isOneOf(tok::greater, tok::greatergreater)) {
520 // Don't consume this... that's done by template parser.
521 break;
522 } else {
523 // Somebody probably forgot to close the template. Skip ahead and
524 // try to get out of the expression. This error is currently
525 // subsumed by whatever goes on in ParseTemplateParameter.
526 Diag(Tok.getLocation(), diag::err_expected_comma_greater);
527 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
528 StopAtSemi | StopBeforeMatch);
529 return false;
530 }
531 }
532 return true;
533}
534
535/// Determine whether the parser is at the start of a template
536/// type parameter.
537Parser::TPResult Parser::isStartOfTemplateTypeParameter() {
538 if (Tok.is(tok::kw_class)) {
539 // "class" may be the start of an elaborated-type-specifier or a
540 // type-parameter. Per C++ [temp.param]p3, we prefer the type-parameter.
541 switch (NextToken().getKind()) {
542 case tok::equal:
543 case tok::comma:
544 case tok::greater:
545 case tok::greatergreater:
546 case tok::ellipsis:
547 return TPResult::True;
548
549 case tok::identifier:
550 // This may be either a type-parameter or an elaborated-type-specifier.
551 // We have to look further.
552 break;
553
554 default:
555 return TPResult::False;
556 }
557
558 switch (GetLookAheadToken(2).getKind()) {
559 case tok::equal:
560 case tok::comma:
561 case tok::greater:
562 case tok::greatergreater:
563 return TPResult::True;
564
565 default:
566 return TPResult::False;
567 }
568 }
569
570 if (TryAnnotateTypeConstraint())
571 return TPResult::Error;
572
573 if (isTypeConstraintAnnotation() &&
574 // Next token might be 'auto' or 'decltype', indicating that this
575 // type-constraint is in fact part of a placeholder-type-specifier of a
576 // non-type template parameter.
577 !GetLookAheadToken(Tok.is(tok::annot_cxxscope) ? 2 : 1)
578 .isOneOf(tok::kw_auto, tok::kw_decltype))
579 return TPResult::True;
580
581 // 'typedef' is a reasonably-common typo/thinko for 'typename', and is
582 // ill-formed otherwise.
583 if (Tok.isNot(tok::kw_typename) && Tok.isNot(tok::kw_typedef))
584 return TPResult::False;
585
586 // C++ [temp.param]p2:
587 // There is no semantic difference between class and typename in a
588 // template-parameter. typename followed by an unqualified-id
589 // names a template type parameter. typename followed by a
590 // qualified-id denotes the type in a non-type
591 // parameter-declaration.
592 Token Next = NextToken();
593
594 // If we have an identifier, skip over it.
595 if (Next.getKind() == tok::identifier)
596 Next = GetLookAheadToken(2);
597
598 switch (Next.getKind()) {
599 case tok::equal:
600 case tok::comma:
601 case tok::greater:
602 case tok::greatergreater:
603 case tok::ellipsis:
604 return TPResult::True;
605
606 case tok::kw_typename:
607 case tok::kw_typedef:
608 case tok::kw_class:
609 // These indicate that a comma was missed after a type parameter, not that
610 // we have found a non-type parameter.
611 return TPResult::True;
612
613 default:
614 return TPResult::False;
615 }
616}
617
618/// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]).
619///
620/// template-parameter: [C++ temp.param]
621/// type-parameter
622/// parameter-declaration
623///
624/// type-parameter: (See below)
625/// type-parameter-key ...[opt] identifier[opt]
626/// type-parameter-key identifier[opt] = type-id
627/// (C++2a) type-constraint ...[opt] identifier[opt]
628/// (C++2a) type-constraint identifier[opt] = type-id
629/// 'template' '<' template-parameter-list '>' type-parameter-key
630/// ...[opt] identifier[opt]
631/// 'template' '<' template-parameter-list '>' type-parameter-key
632/// identifier[opt] '=' id-expression
633///
634/// type-parameter-key:
635/// class
636/// typename
637///
638NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
639
640 switch (isStartOfTemplateTypeParameter()) {
641 case TPResult::True:
642 // Is there just a typo in the input code? ('typedef' instead of
643 // 'typename')
644 if (Tok.is(tok::kw_typedef)) {
645 Diag(Tok.getLocation(), diag::err_expected_template_parameter);
646
647 Diag(Tok.getLocation(), diag::note_meant_to_use_typename)
648 << FixItHint::CreateReplacement(CharSourceRange::getCharRange(
649 Tok.getLocation(),
650 Tok.getEndLoc()),
651 "typename");
652
653 Tok.setKind(tok::kw_typename);
654 }
655
656 return ParseTypeParameter(Depth, Position);
657 case TPResult::False:
658 break;
659
660 case TPResult::Error: {
661 // We return an invalid parameter as opposed to null to avoid having bogus
662 // diagnostics about an empty template parameter list.
663 // FIXME: Fix ParseTemplateParameterList to better handle nullptr results
664 // from here.
665 // Return a NTTP as if there was an error in a scope specifier, the user
666 // probably meant to write the type of a NTTP.
667 DeclSpec DS(getAttrFactory());
668 DS.SetTypeSpecError();
669 Declarator D(DS, DeclaratorContext::TemplateParam);
670 D.SetIdentifier(nullptr, Tok.getLocation());
671 D.setInvalidType(true);
672 NamedDecl *ErrorParam = Actions.ActOnNonTypeTemplateParameter(
673 getCurScope(), D, Depth, Position, /*EqualLoc=*/SourceLocation(),
674 /*DefaultArg=*/nullptr);
675 ErrorParam->setInvalidDecl(true);
676 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
677 StopAtSemi | StopBeforeMatch);
678 return ErrorParam;
679 }
680
681 case TPResult::Ambiguous:
682 llvm_unreachable("template param classification can't be ambiguous")::llvm::llvm_unreachable_internal("template param classification can't be ambiguous"
, "clang/lib/Parse/ParseTemplate.cpp", 682)
;
683 }
684
685 if (Tok.is(tok::kw_template))
686 return ParseTemplateTemplateParameter(Depth, Position);
687
688 // If it's none of the above, then it must be a parameter declaration.
689 // NOTE: This will pick up errors in the closure of the template parameter
690 // list (e.g., template < ; Check here to implement >> style closures.
691 return ParseNonTypeTemplateParameter(Depth, Position);
692}
693
694/// Check whether the current token is a template-id annotation denoting a
695/// type-constraint.
696bool Parser::isTypeConstraintAnnotation() {
697 const Token &T = Tok.is(tok::annot_cxxscope) ? NextToken() : Tok;
698 if (T.isNot(tok::annot_template_id))
699 return false;
700 const auto *ExistingAnnot =
701 static_cast<TemplateIdAnnotation *>(T.getAnnotationValue());
702 return ExistingAnnot->Kind == TNK_Concept_template;
703}
704
705/// Try parsing a type-constraint at the current location.
706///
707/// type-constraint:
708/// nested-name-specifier[opt] concept-name
709/// nested-name-specifier[opt] concept-name
710/// '<' template-argument-list[opt] '>'[opt]
711///
712/// \returns true if an error occurred, and false otherwise.
713bool Parser::TryAnnotateTypeConstraint() {
714 if (!getLangOpts().CPlusPlus20)
715 return false;
716 CXXScopeSpec SS;
717 bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
718 if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
719 /*ObjectHasErrors=*/false,
720 /*EnteringContext=*/false,
721 /*MayBePseudoDestructor=*/nullptr,
722 // If this is not a type-constraint, then
723 // this scope-spec is part of the typename
724 // of a non-type template parameter
725 /*IsTypename=*/true, /*LastII=*/nullptr,
726 // We won't find concepts in
727 // non-namespaces anyway, so might as well
728 // parse this correctly for possible type
729 // names.
730 /*OnlyNamespace=*/false))
731 return true;
732
733 if (Tok.is(tok::identifier)) {
734 UnqualifiedId PossibleConceptName;
735 PossibleConceptName.setIdentifier(Tok.getIdentifierInfo(),
736 Tok.getLocation());
737
738 TemplateTy PossibleConcept;
739 bool MemberOfUnknownSpecialization = false;
740 auto TNK = Actions.isTemplateName(getCurScope(), SS,
741 /*hasTemplateKeyword=*/false,
742 PossibleConceptName,
743 /*ObjectType=*/ParsedType(),
744 /*EnteringContext=*/false,
745 PossibleConcept,
746 MemberOfUnknownSpecialization,
747 /*Disambiguation=*/true);
748 if (MemberOfUnknownSpecialization || !PossibleConcept ||
749 TNK != TNK_Concept_template) {
750 if (SS.isNotEmpty())
751 AnnotateScopeToken(SS, !WasScopeAnnotation);
752 return false;
753 }
754
755 // At this point we're sure we're dealing with a constrained parameter. It
756 // may or may not have a template parameter list following the concept
757 // name.
758 if (AnnotateTemplateIdToken(PossibleConcept, TNK, SS,
759 /*TemplateKWLoc=*/SourceLocation(),
760 PossibleConceptName,
761 /*AllowTypeAnnotation=*/false,
762 /*TypeConstraint=*/true))
763 return true;
764 }
765
766 if (SS.isNotEmpty())
767 AnnotateScopeToken(SS, !WasScopeAnnotation);
768 return false;
769}
770
771/// ParseTypeParameter - Parse a template type parameter (C++ [temp.param]).
772/// Other kinds of template parameters are parsed in
773/// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter.
774///
775/// type-parameter: [C++ temp.param]
776/// 'class' ...[opt][C++0x] identifier[opt]
777/// 'class' identifier[opt] '=' type-id
778/// 'typename' ...[opt][C++0x] identifier[opt]
779/// 'typename' identifier[opt] '=' type-id
780NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
781 assert((Tok.isOneOf(tok::kw_class, tok::kw_typename) ||(static_cast <bool> ((Tok.isOneOf(tok::kw_class, tok::kw_typename
) || isTypeConstraintAnnotation()) && "A type-parameter starts with 'class', 'typename' or a "
"type-constraint") ? void (0) : __assert_fail ("(Tok.isOneOf(tok::kw_class, tok::kw_typename) || isTypeConstraintAnnotation()) && \"A type-parameter starts with 'class', 'typename' or a \" \"type-constraint\""
, "clang/lib/Parse/ParseTemplate.cpp", 784, __extension__ __PRETTY_FUNCTION__
))
782 isTypeConstraintAnnotation()) &&(static_cast <bool> ((Tok.isOneOf(tok::kw_class, tok::kw_typename
) || isTypeConstraintAnnotation()) && "A type-parameter starts with 'class', 'typename' or a "
"type-constraint") ? void (0) : __assert_fail ("(Tok.isOneOf(tok::kw_class, tok::kw_typename) || isTypeConstraintAnnotation()) && \"A type-parameter starts with 'class', 'typename' or a \" \"type-constraint\""
, "clang/lib/Parse/ParseTemplate.cpp", 784, __extension__ __PRETTY_FUNCTION__
))
783 "A type-parameter starts with 'class', 'typename' or a "(static_cast <bool> ((Tok.isOneOf(tok::kw_class, tok::kw_typename
) || isTypeConstraintAnnotation()) && "A type-parameter starts with 'class', 'typename' or a "
"type-constraint") ? void (0) : __assert_fail ("(Tok.isOneOf(tok::kw_class, tok::kw_typename) || isTypeConstraintAnnotation()) && \"A type-parameter starts with 'class', 'typename' or a \" \"type-constraint\""
, "clang/lib/Parse/ParseTemplate.cpp", 784, __extension__ __PRETTY_FUNCTION__
))
784 "type-constraint")(static_cast <bool> ((Tok.isOneOf(tok::kw_class, tok::kw_typename
) || isTypeConstraintAnnotation()) && "A type-parameter starts with 'class', 'typename' or a "
"type-constraint") ? void (0) : __assert_fail ("(Tok.isOneOf(tok::kw_class, tok::kw_typename) || isTypeConstraintAnnotation()) && \"A type-parameter starts with 'class', 'typename' or a \" \"type-constraint\""
, "clang/lib/Parse/ParseTemplate.cpp", 784, __extension__ __PRETTY_FUNCTION__
))
;
785
786 CXXScopeSpec TypeConstraintSS;
787 TemplateIdAnnotation *TypeConstraint = nullptr;
788 bool TypenameKeyword = false;
789 SourceLocation KeyLoc;
790 ParseOptionalCXXScopeSpecifier(TypeConstraintSS, /*ObjectType=*/nullptr,
791 /*ObjectHasErrors=*/false,
792 /*EnteringContext*/ false);
793 if (Tok.is(tok::annot_template_id)) {
794 // Consume the 'type-constraint'.
795 TypeConstraint =
796 static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
797 assert(TypeConstraint->Kind == TNK_Concept_template &&(static_cast <bool> (TypeConstraint->Kind == TNK_Concept_template
&& "stray non-concept template-id annotation") ? void
(0) : __assert_fail ("TypeConstraint->Kind == TNK_Concept_template && \"stray non-concept template-id annotation\""
, "clang/lib/Parse/ParseTemplate.cpp", 798, __extension__ __PRETTY_FUNCTION__
))
798 "stray non-concept template-id annotation")(static_cast <bool> (TypeConstraint->Kind == TNK_Concept_template
&& "stray non-concept template-id annotation") ? void
(0) : __assert_fail ("TypeConstraint->Kind == TNK_Concept_template && \"stray non-concept template-id annotation\""
, "clang/lib/Parse/ParseTemplate.cpp", 798, __extension__ __PRETTY_FUNCTION__
))
;
799 KeyLoc = ConsumeAnnotationToken();
800 } else {
801 assert(TypeConstraintSS.isEmpty() &&(static_cast <bool> (TypeConstraintSS.isEmpty() &&
"expected type constraint after scope specifier") ? void (0)
: __assert_fail ("TypeConstraintSS.isEmpty() && \"expected type constraint after scope specifier\""
, "clang/lib/Parse/ParseTemplate.cpp", 802, __extension__ __PRETTY_FUNCTION__
))
802 "expected type constraint after scope specifier")(static_cast <bool> (TypeConstraintSS.isEmpty() &&
"expected type constraint after scope specifier") ? void (0)
: __assert_fail ("TypeConstraintSS.isEmpty() && \"expected type constraint after scope specifier\""
, "clang/lib/Parse/ParseTemplate.cpp", 802, __extension__ __PRETTY_FUNCTION__
))
;
803
804 // Consume the 'class' or 'typename' keyword.
805 TypenameKeyword = Tok.is(tok::kw_typename);
806 KeyLoc = ConsumeToken();
807 }
808
809 // Grab the ellipsis (if given).
810 SourceLocation EllipsisLoc;
811 if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) {
812 Diag(EllipsisLoc,
813 getLangOpts().CPlusPlus11
814 ? diag::warn_cxx98_compat_variadic_templates
815 : diag::ext_variadic_templates);
816 }
817
818 // Grab the template parameter name (if given)
819 SourceLocation NameLoc = Tok.getLocation();
820 IdentifierInfo *ParamName = nullptr;
821 if (Tok.is(tok::identifier)) {
822 ParamName = Tok.getIdentifierInfo();
823 ConsumeToken();
824 } else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
825 tok::greatergreater)) {
826 // Unnamed template parameter. Don't have to do anything here, just
827 // don't consume this token.
828 } else {
829 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
830 return nullptr;
831 }
832
833 // Recover from misplaced ellipsis.
834 bool AlreadyHasEllipsis = EllipsisLoc.isValid();
835 if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
836 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);
837
838 // Grab a default argument (if available).
839 // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
840 // we introduce the type parameter into the local scope.
841 SourceLocation EqualLoc;
842 ParsedType DefaultArg;
843 if (TryConsumeToken(tok::equal, EqualLoc))
844 DefaultArg =
845 ParseTypeName(/*Range=*/nullptr, DeclaratorContext::TemplateTypeArg)
846 .get();
847
848 NamedDecl *NewDecl = Actions.ActOnTypeParameter(getCurScope(),
849 TypenameKeyword, EllipsisLoc,
850 KeyLoc, ParamName, NameLoc,
851 Depth, Position, EqualLoc,
852 DefaultArg,
853 TypeConstraint != nullptr);
854
855 if (TypeConstraint) {
856 Actions.ActOnTypeConstraint(TypeConstraintSS, TypeConstraint,
857 cast<TemplateTypeParmDecl>(NewDecl),
858 EllipsisLoc);
859 }
860
861 return NewDecl;
862}
863
864/// ParseTemplateTemplateParameter - Handle the parsing of template
865/// template parameters.
866///
867/// type-parameter: [C++ temp.param]
868/// 'template' '<' template-parameter-list '>' type-parameter-key
869/// ...[opt] identifier[opt]
870/// 'template' '<' template-parameter-list '>' type-parameter-key
871/// identifier[opt] = id-expression
872/// type-parameter-key:
873/// 'class'
874/// 'typename' [C++1z]
875NamedDecl *
876Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
877 assert(Tok.is(tok::kw_template) && "Expected 'template' keyword")(static_cast <bool> (Tok.is(tok::kw_template) &&
"Expected 'template' keyword") ? void (0) : __assert_fail ("Tok.is(tok::kw_template) && \"Expected 'template' keyword\""
, "clang/lib/Parse/ParseTemplate.cpp", 877, __extension__ __PRETTY_FUNCTION__
))
;
878
879 // Handle the template <...> part.
880 SourceLocation TemplateLoc = ConsumeToken();
881 SmallVector<NamedDecl*,8> TemplateParams;
882 SourceLocation LAngleLoc, RAngleLoc;
883 {
884 MultiParseScope TemplateParmScope(*this);
885 if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams,
886 LAngleLoc, RAngleLoc)) {
887 return nullptr;
888 }
889 }
890
891 // Provide an ExtWarn if the C++1z feature of using 'typename' here is used.
892 // Generate a meaningful error if the user forgot to put class before the
893 // identifier, comma, or greater. Provide a fixit if the identifier, comma,
894 // or greater appear immediately or after 'struct'. In the latter case,
895 // replace the keyword with 'class'.
896 if (!TryConsumeToken(tok::kw_class)) {
897 bool Replace = Tok.isOneOf(tok::kw_typename, tok::kw_struct);
898 const Token &Next = Tok.is(tok::kw_struct) ? NextToken() : Tok;
899 if (Tok.is(tok::kw_typename)) {
900 Diag(Tok.getLocation(),
901 getLangOpts().CPlusPlus17
902 ? diag::warn_cxx14_compat_template_template_param_typename
903 : diag::ext_template_template_param_typename)
904 << (!getLangOpts().CPlusPlus17
905 ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
906 : FixItHint());
907 } else if (Next.isOneOf(tok::identifier, tok::comma, tok::greater,
908 tok::greatergreater, tok::ellipsis)) {
909 Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
910 << getLangOpts().CPlusPlus17
911 << (Replace
912 ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
913 : FixItHint::CreateInsertion(Tok.getLocation(), "class "));
914 } else
915 Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
916 << getLangOpts().CPlusPlus17;
917
918 if (Replace)
919 ConsumeToken();
920 }
921
922 // Parse the ellipsis, if given.
923 SourceLocation EllipsisLoc;
924 if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
925 Diag(EllipsisLoc,
926 getLangOpts().CPlusPlus11
927 ? diag::warn_cxx98_compat_variadic_templates
928 : diag::ext_variadic_templates);
929
930 // Get the identifier, if given.
931 SourceLocation NameLoc = Tok.getLocation();
932 IdentifierInfo *ParamName = nullptr;
933 if (Tok.is(tok::identifier)) {
934 ParamName = Tok.getIdentifierInfo();
935 ConsumeToken();
936 } else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
937 tok::greatergreater)) {
938 // Unnamed template parameter. Don't have to do anything here, just
939 // don't consume this token.
940 } else {
941 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
942 return nullptr;
943 }
944
945 // Recover from misplaced ellipsis.
946 bool AlreadyHasEllipsis = EllipsisLoc.isValid();
947 if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
948 DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);
949
950 TemplateParameterList *ParamList =
951 Actions.ActOnTemplateParameterList(Depth, SourceLocation(),
952 TemplateLoc, LAngleLoc,
953 TemplateParams,
954 RAngleLoc, nullptr);
955
956 // Grab a default argument (if available).
957 // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
958 // we introduce the template parameter into the local scope.
959 SourceLocation EqualLoc;
960 ParsedTemplateArgument DefaultArg;
961 if (TryConsumeToken(tok::equal, EqualLoc)) {
962 DefaultArg = ParseTemplateTemplateArgument();
963 if (DefaultArg.isInvalid()) {
964 Diag(Tok.getLocation(),
965 diag::err_default_template_template_parameter_not_template);
966 SkipUntil(tok::comma, tok::greater, tok::greatergreater,
967 StopAtSemi | StopBeforeMatch);
968 }
969 }
970
971 return Actions.ActOnTemplateTemplateParameter(getCurScope(), TemplateLoc,
972 ParamList, EllipsisLoc,
973 ParamName, NameLoc, Depth,
974 Position, EqualLoc, DefaultArg);
975}
976
977/// ParseNonTypeTemplateParameter - Handle the parsing of non-type
978/// template parameters (e.g., in "template<int Size> class array;").
979///
980/// template-parameter:
981/// ...
982/// parameter-declaration
983NamedDecl *
984Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
985 // Parse the declaration-specifiers (i.e., the type).
986 // FIXME: The type should probably be restricted in some way... Not all
987 // declarators (parts of declarators?) are accepted for parameters.
988 DeclSpec DS(AttrFactory);
989 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
990 DeclSpecContext::DSC_template_param);
991
992 // Parse this as a typename.
993 Declarator ParamDecl(DS, DeclaratorContext::TemplateParam);
994 ParseDeclarator(ParamDecl);
995 if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
996 Diag(Tok.getLocation(), diag::err_expected_template_parameter);
997 return nullptr;
998 }
999
1000 // Recover from misplaced ellipsis.
1001 SourceLocation EllipsisLoc;
1002 if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
1003 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
1004
1005 // If there is a default value, parse it.
1006 // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
1007 // we introduce the template parameter into the local scope.
1008 SourceLocation EqualLoc;
1009 ExprResult DefaultArg;
1010 if (TryConsumeToken(tok::equal, EqualLoc)) {
1011 if (Tok.is(tok::l_paren) && NextToken().is(tok::l_brace)) {
1012 Diag(Tok.getLocation(), diag::err_stmt_expr_in_default_arg) << 1;
1013 SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);
1014 } else {
1015 // C++ [temp.param]p15:
1016 // When parsing a default template-argument for a non-type
1017 // template-parameter, the first non-nested > is taken as the
1018 // end of the template-parameter-list rather than a greater-than
1019 // operator.
1020 GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
1021 EnterExpressionEvaluationContext ConstantEvaluated(
1022 Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
1023 DefaultArg =
1024 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
1025 if (DefaultArg.isInvalid())
1026 SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);
1027 }
1028 }
1029
1030 // Create the parameter.
1031 return Actions.ActOnNonTypeTemplateParameter(getCurScope(), ParamDecl,
1032 Depth, Position, EqualLoc,
1033 DefaultArg.get());
1034}
1035
1036void Parser::DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
1037 SourceLocation CorrectLoc,
1038 bool AlreadyHasEllipsis,
1039 bool IdentifierHasName) {
1040 FixItHint Insertion;
1041 if (!AlreadyHasEllipsis)
1042 Insertion = FixItHint::CreateInsertion(CorrectLoc, "...");
1043 Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
1044 << FixItHint::CreateRemoval(EllipsisLoc) << Insertion
1045 << !IdentifierHasName;
1046}
1047
1048void Parser::DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
1049 Declarator &D) {
1050 assert(EllipsisLoc.isValid())(static_cast <bool> (EllipsisLoc.isValid()) ? void (0) :
__assert_fail ("EllipsisLoc.isValid()", "clang/lib/Parse/ParseTemplate.cpp"
, 1050, __extension__ __PRETTY_FUNCTION__))
;
1051 bool AlreadyHasEllipsis = D.getEllipsisLoc().isValid();
1052 if (!AlreadyHasEllipsis)
1053 D.setEllipsisLoc(EllipsisLoc);
1054 DiagnoseMisplacedEllipsis(EllipsisLoc, D.getIdentifierLoc(),
1055 AlreadyHasEllipsis, D.hasName());
1056}
1057
1058/// Parses a '>' at the end of a template list.
1059///
1060/// If this function encounters '>>', '>>>', '>=', or '>>=', it tries
1061/// to determine if these tokens were supposed to be a '>' followed by
1062/// '>', '>>', '>=', or '>='. It emits an appropriate diagnostic if necessary.
1063///
1064/// \param RAngleLoc the location of the consumed '>'.
1065///
1066/// \param ConsumeLastToken if true, the '>' is consumed.
1067///
1068/// \param ObjCGenericList if true, this is the '>' closing an Objective-C
1069/// type parameter or type argument list, rather than a C++ template parameter
1070/// or argument list.
1071///
1072/// \returns true, if current token does not start with '>', false otherwise.
1073bool Parser::ParseGreaterThanInTemplateList(SourceLocation LAngleLoc,
1074 SourceLocation &RAngleLoc,
1075 bool ConsumeLastToken,
1076 bool ObjCGenericList) {
1077 // What will be left once we've consumed the '>'.
1078 tok::TokenKind RemainingToken;
1079 const char *ReplacementStr = "> >";
1080 bool MergeWithNextToken = false;
1081
1082 switch (Tok.getKind()) {
1083 default:
1084 Diag(getEndOfPreviousToken(), diag::err_expected) << tok::greater;
1085 Diag(LAngleLoc, diag::note_matching) << tok::less;
1086 return true;
1087
1088 case tok::greater:
1089 // Determine the location of the '>' token. Only consume this token
1090 // if the caller asked us to.
1091 RAngleLoc = Tok.getLocation();
1092 if (ConsumeLastToken)
1093 ConsumeToken();
1094 return false;
1095
1096 case tok::greatergreater:
1097 RemainingToken = tok::greater;
1098 break;
1099
1100 case tok::greatergreatergreater:
1101 RemainingToken = tok::greatergreater;
1102 break;
1103
1104 case tok::greaterequal:
1105 RemainingToken = tok::equal;
1106 ReplacementStr = "> =";
1107
1108 // Join two adjacent '=' tokens into one, for cases like:
1109 // void (*p)() = f<int>;
1110 // return f<int>==p;
1111 if (NextToken().is(tok::equal) &&
1112 areTokensAdjacent(Tok, NextToken())) {
1113 RemainingToken = tok::equalequal;
1114 MergeWithNextToken = true;
1115 }
1116 break;
1117
1118 case tok::greatergreaterequal:
1119 RemainingToken = tok::greaterequal;
1120 break;
1121 }
1122
1123 // This template-id is terminated by a token that starts with a '>'.
1124 // Outside C++11 and Objective-C, this is now error recovery.
1125 //
1126 // C++11 allows this when the token is '>>', and in CUDA + C++11 mode, we
1127 // extend that treatment to also apply to the '>>>' token.
1128 //
1129 // Objective-C allows this in its type parameter / argument lists.
1130
1131 SourceLocation TokBeforeGreaterLoc = PrevTokLocation;
1132 SourceLocation TokLoc = Tok.getLocation();
1133 Token Next = NextToken();
1134
1135 // Whether splitting the current token after the '>' would undesirably result
1136 // in the remaining token pasting with the token after it. This excludes the
1137 // MergeWithNextToken cases, which we've already handled.
1138 bool PreventMergeWithNextToken =
1139 (RemainingToken == tok::greater ||
1140 RemainingToken == tok::greatergreater) &&
1141 (Next.isOneOf(tok::greater, tok::greatergreater,
1142 tok::greatergreatergreater, tok::equal, tok::greaterequal,
1143 tok::greatergreaterequal, tok::equalequal)) &&
1144 areTokensAdjacent(Tok, Next);
1145
1146 // Diagnose this situation as appropriate.
1147 if (!ObjCGenericList) {
1148 // The source range of the replaced token(s).
1149 CharSourceRange ReplacementRange = CharSourceRange::getCharRange(
1150 TokLoc, Lexer::AdvanceToTokenCharacter(TokLoc, 2, PP.getSourceManager(),
1151 getLangOpts()));
1152
1153 // A hint to put a space between the '>>'s. In order to make the hint as
1154 // clear as possible, we include the characters either side of the space in
1155 // the replacement, rather than just inserting a space at SecondCharLoc.
1156 FixItHint Hint1 = FixItHint::CreateReplacement(ReplacementRange,
1157 ReplacementStr);
1158
1159 // A hint to put another space after the token, if it would otherwise be
1160 // lexed differently.
1161 FixItHint Hint2;
1162 if (PreventMergeWithNextToken)
1163 Hint2 = FixItHint::CreateInsertion(Next.getLocation(), " ");
1164
1165 unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
1166 if (getLangOpts().CPlusPlus11 &&
1167 (Tok.is(tok::greatergreater) || Tok.is(tok::greatergreatergreater)))
1168 DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
1169 else if (Tok.is(tok::greaterequal))
1170 DiagId = diag::err_right_angle_bracket_equal_needs_space;
1171 Diag(TokLoc, DiagId) << Hint1 << Hint2;
1172 }
1173
1174 // Find the "length" of the resulting '>' token. This is not always 1, as it
1175 // can contain escaped newlines.
1176 unsigned GreaterLength = Lexer::getTokenPrefixLength(
1177 TokLoc, 1, PP.getSourceManager(), getLangOpts());
1178
1179 // Annotate the source buffer to indicate that we split the token after the
1180 // '>'. This allows us to properly find the end of, and extract the spelling
1181 // of, the '>' token later.
1182 RAngleLoc = PP.SplitToken(TokLoc, GreaterLength);
1183
1184 // Strip the initial '>' from the token.
1185 bool CachingTokens = PP.IsPreviousCachedToken(Tok);
1186
1187 Token Greater = Tok;
1188 Greater.setLocation(RAngleLoc);
1189 Greater.setKind(tok::greater);
1190 Greater.setLength(GreaterLength);
1191
1192 unsigned OldLength = Tok.getLength();
1193 if (MergeWithNextToken) {
1194 ConsumeToken();
1195 OldLength += Tok.getLength();
1196 }
1197
1198 Tok.setKind(RemainingToken);
1199 Tok.setLength(OldLength - GreaterLength);
1200
1201 // Split the second token if lexing it normally would lex a different token
1202 // (eg, the fifth token in 'A<B>>>' should re-lex as '>', not '>>').
1203 SourceLocation AfterGreaterLoc = TokLoc.getLocWithOffset(GreaterLength);
1204 if (PreventMergeWithNextToken)
1205 AfterGreaterLoc = PP.SplitToken(AfterGreaterLoc, Tok.getLength());
1206 Tok.setLocation(AfterGreaterLoc);
1207
1208 // Update the token cache to match what we just did if necessary.
1209 if (CachingTokens) {
1210 // If the previous cached token is being merged, delete it.
1211 if (MergeWithNextToken)
1212 PP.ReplacePreviousCachedToken({});
1213
1214 if (ConsumeLastToken)
1215 PP.ReplacePreviousCachedToken({Greater, Tok});
1216 else
1217 PP.ReplacePreviousCachedToken({Greater});
1218 }
1219
1220 if (ConsumeLastToken) {
1221 PrevTokLocation = RAngleLoc;
1222 } else {
1223 PrevTokLocation = TokBeforeGreaterLoc;
1224 PP.EnterToken(Tok, /*IsReinject=*/true);
1225 Tok = Greater;
1226 }
1227
1228 return false;
1229}
1230
1231/// Parses a template-id that after the template name has
1232/// already been parsed.
1233///
1234/// This routine takes care of parsing the enclosed template argument
1235/// list ('<' template-parameter-list [opt] '>') and placing the
1236/// results into a form that can be transferred to semantic analysis.
1237///
1238/// \param ConsumeLastToken if true, then we will consume the last
1239/// token that forms the template-id. Otherwise, we will leave the
1240/// last token in the stream (e.g., so that it can be replaced with an
1241/// annotation token).
1242bool Parser::ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
1243 SourceLocation &LAngleLoc,
1244 TemplateArgList &TemplateArgs,
1245 SourceLocation &RAngleLoc,
1246 TemplateTy Template) {
1247 assert(Tok.is(tok::less) && "Must have already parsed the template-name")(static_cast <bool> (Tok.is(tok::less) && "Must have already parsed the template-name"
) ? void (0) : __assert_fail ("Tok.is(tok::less) && \"Must have already parsed the template-name\""
, "clang/lib/Parse/ParseTemplate.cpp", 1247, __extension__ __PRETTY_FUNCTION__
))
;
1248
1249 // Consume the '<'.
1250 LAngleLoc = ConsumeToken();
1251
1252 // Parse the optional template-argument-list.
1253 bool Invalid = false;
1254 {
1255 GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
1256 if (!Tok.isOneOf(tok::greater, tok::greatergreater,
1257 tok::greatergreatergreater, tok::greaterequal,
1258 tok::greatergreaterequal))
1259 Invalid = ParseTemplateArgumentList(TemplateArgs, Template, LAngleLoc);
1260
1261 if (Invalid) {
1262 // Try to find the closing '>'.
1263 if (getLangOpts().CPlusPlus11)
1264 SkipUntil(tok::greater, tok::greatergreater,
1265 tok::greatergreatergreater, StopAtSemi | StopBeforeMatch);
1266 else
1267 SkipUntil(tok::greater, StopAtSemi | StopBeforeMatch);
1268 }
1269 }
1270
1271 return ParseGreaterThanInTemplateList(LAngleLoc, RAngleLoc, ConsumeLastToken,
1272 /*ObjCGenericList=*/false) ||
1273 Invalid;
1274}
1275
1276/// Replace the tokens that form a simple-template-id with an
1277/// annotation token containing the complete template-id.
1278///
1279/// The first token in the stream must be the name of a template that
1280/// is followed by a '<'. This routine will parse the complete
1281/// simple-template-id and replace the tokens with a single annotation
1282/// token with one of two different kinds: if the template-id names a
1283/// type (and \p AllowTypeAnnotation is true), the annotation token is
1284/// a type annotation that includes the optional nested-name-specifier
1285/// (\p SS). Otherwise, the annotation token is a template-id
1286/// annotation that does not include the optional
1287/// nested-name-specifier.
1288///
1289/// \param Template the declaration of the template named by the first
1290/// token (an identifier), as returned from \c Action::isTemplateName().
1291///
1292/// \param TNK the kind of template that \p Template
1293/// refers to, as returned from \c Action::isTemplateName().
1294///
1295/// \param SS if non-NULL, the nested-name-specifier that precedes
1296/// this template name.
1297///
1298/// \param TemplateKWLoc if valid, specifies that this template-id
1299/// annotation was preceded by the 'template' keyword and gives the
1300/// location of that keyword. If invalid (the default), then this
1301/// template-id was not preceded by a 'template' keyword.
1302///
1303/// \param AllowTypeAnnotation if true (the default), then a
1304/// simple-template-id that refers to a class template, template
1305/// template parameter, or other template that produces a type will be
1306/// replaced with a type annotation token. Otherwise, the
1307/// simple-template-id is always replaced with a template-id
1308/// annotation token.
1309///
1310/// \param TypeConstraint if true, then this is actually a type-constraint,
1311/// meaning that the template argument list can be omitted (and the template in
1312/// question must be a concept).
1313///
1314/// If an unrecoverable parse error occurs and no annotation token can be
1315/// formed, this function returns true.
1316///
1317bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
1318 CXXScopeSpec &SS,
1319 SourceLocation TemplateKWLoc,
1320 UnqualifiedId &TemplateName,
1321 bool AllowTypeAnnotation,
1322 bool TypeConstraint) {
1323 assert(getLangOpts().CPlusPlus && "Can only annotate template-ids in C++")(static_cast <bool> (getLangOpts().CPlusPlus &&
"Can only annotate template-ids in C++") ? void (0) : __assert_fail
("getLangOpts().CPlusPlus && \"Can only annotate template-ids in C++\""
, "clang/lib/Parse/ParseTemplate.cpp", 1323, __extension__ __PRETTY_FUNCTION__
))
;
1324 assert((Tok.is(tok::less) || TypeConstraint) &&(static_cast <bool> ((Tok.is(tok::less) || TypeConstraint
) && "Parser isn't at the beginning of a template-id"
) ? void (0) : __assert_fail ("(Tok.is(tok::less) || TypeConstraint) && \"Parser isn't at the beginning of a template-id\""
, "clang/lib/Parse/ParseTemplate.cpp", 1325, __extension__ __PRETTY_FUNCTION__
))
1325 "Parser isn't at the beginning of a template-id")(static_cast <bool> ((Tok.is(tok::less) || TypeConstraint
) && "Parser isn't at the beginning of a template-id"
) ? void (0) : __assert_fail ("(Tok.is(tok::less) || TypeConstraint) && \"Parser isn't at the beginning of a template-id\""
, "clang/lib/Parse/ParseTemplate.cpp", 1325, __extension__ __PRETTY_FUNCTION__
))
;
1326 assert(!(TypeConstraint && AllowTypeAnnotation) && "type-constraint can't be "(static_cast <bool> (!(TypeConstraint && AllowTypeAnnotation
) && "type-constraint can't be " "a type annotation")
? void (0) : __assert_fail ("!(TypeConstraint && AllowTypeAnnotation) && \"type-constraint can't be \" \"a type annotation\""
, "clang/lib/Parse/ParseTemplate.cpp", 1327, __extension__ __PRETTY_FUNCTION__
))
1327 "a type annotation")(static_cast <bool> (!(TypeConstraint && AllowTypeAnnotation
) && "type-constraint can't be " "a type annotation")
? void (0) : __assert_fail ("!(TypeConstraint && AllowTypeAnnotation) && \"type-constraint can't be \" \"a type annotation\""
, "clang/lib/Parse/ParseTemplate.cpp", 1327, __extension__ __PRETTY_FUNCTION__
))
;
1328 assert((!TypeConstraint || TNK == TNK_Concept_template) && "type-constraint "(static_cast <bool> ((!TypeConstraint || TNK == TNK_Concept_template
) && "type-constraint " "must accompany a concept name"
) ? void (0) : __assert_fail ("(!TypeConstraint || TNK == TNK_Concept_template) && \"type-constraint \" \"must accompany a concept name\""
, "clang/lib/Parse/ParseTemplate.cpp", 1329, __extension__ __PRETTY_FUNCTION__
))
1329 "must accompany a concept name")(static_cast <bool> ((!TypeConstraint || TNK == TNK_Concept_template
) && "type-constraint " "must accompany a concept name"
) ? void (0) : __assert_fail ("(!TypeConstraint || TNK == TNK_Concept_template) && \"type-constraint \" \"must accompany a concept name\""
, "clang/lib/Parse/ParseTemplate.cpp", 1329, __extension__ __PRETTY_FUNCTION__
))
;
1330 assert((Template || TNK == TNK_Non_template) && "missing template name")(static_cast <bool> ((Template || TNK == TNK_Non_template
) && "missing template name") ? void (0) : __assert_fail
("(Template || TNK == TNK_Non_template) && \"missing template name\""
, "clang/lib/Parse/ParseTemplate.cpp", 1330, __extension__ __PRETTY_FUNCTION__
))
;
1331
1332 // Consume the template-name.
1333 SourceLocation TemplateNameLoc = TemplateName.getSourceRange().getBegin();
1334
1335 // Parse the enclosed template argument list.
1336 SourceLocation LAngleLoc, RAngleLoc;
1337 TemplateArgList TemplateArgs;
1338 bool ArgsInvalid = false;
1339 if (!TypeConstraint || Tok.is(tok::less)) {
1340 ArgsInvalid = ParseTemplateIdAfterTemplateName(
1341 false, LAngleLoc, TemplateArgs, RAngleLoc, Template);
1342 // If we couldn't recover from invalid arguments, don't form an annotation
1343 // token -- we don't know how much to annotate.
1344 // FIXME: This can lead to duplicate diagnostics if we retry parsing this
1345 // template-id in another context. Try to annotate anyway?
1346 if (RAngleLoc.isInvalid())
1347 return true;
1348 }
1349
1350 ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs);
1351
1352 // Build the annotation token.
1353 if (TNK == TNK_Type_template && AllowTypeAnnotation) {
1354 TypeResult Type = ArgsInvalid
1355 ? TypeError()
1356 : Actions.ActOnTemplateIdType(
1357 getCurScope(), SS, TemplateKWLoc, Template,
1358 TemplateName.Identifier, TemplateNameLoc,
1359 LAngleLoc, TemplateArgsPtr, RAngleLoc);
1360
1361 Tok.setKind(tok::annot_typename);
1362 setTypeAnnotation(Tok, Type);
1363 if (SS.isNotEmpty())
1364 Tok.setLocation(SS.getBeginLoc());
1365 else if (TemplateKWLoc.isValid())
1366 Tok.setLocation(TemplateKWLoc);
1367 else
1368 Tok.setLocation(TemplateNameLoc);
1369 } else {
1370 // Build a template-id annotation token that can be processed
1371 // later.
1372 Tok.setKind(tok::annot_template_id);
1373
1374 IdentifierInfo *TemplateII =
1375 TemplateName.getKind() == UnqualifiedIdKind::IK_Identifier
1376 ? TemplateName.Identifier
1377 : nullptr;
1378
1379 OverloadedOperatorKind OpKind =
1380 TemplateName.getKind() == UnqualifiedIdKind::IK_Identifier
1381 ? OO_None
1382 : TemplateName.OperatorFunctionId.Operator;
1383
1384 TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
1385 TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
1386 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid, TemplateIds);
1387
1388 Tok.setAnnotationValue(TemplateId);
1389 if (TemplateKWLoc.isValid())
1390 Tok.setLocation(TemplateKWLoc);
1391 else
1392 Tok.setLocation(TemplateNameLoc);
1393 }
1394
1395 // Common fields for the annotation token
1396 Tok.setAnnotationEndLoc(RAngleLoc);
1397
1398 // In case the tokens were cached, have Preprocessor replace them with the
1399 // annotation token.
1400 PP.AnnotateCachedTokens(Tok);
1401 return false;
1402}
1403
1404/// Replaces a template-id annotation token with a type
1405/// annotation token.
1406///
1407/// If there was a failure when forming the type from the template-id,
1408/// a type annotation token will still be created, but will have a
1409/// NULL type pointer to signify an error.
1410///
1411/// \param SS The scope specifier appearing before the template-id, if any.
1412///
1413/// \param IsClassName Is this template-id appearing in a context where we
1414/// know it names a class, such as in an elaborated-type-specifier or
1415/// base-specifier? ('typename' and 'template' are unneeded and disallowed
1416/// in those contexts.)
1417void Parser::AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS,
1418 bool IsClassName) {
1419 assert(Tok.is(tok::annot_template_id) && "Requires template-id tokens")(static_cast <bool> (Tok.is(tok::annot_template_id) &&
"Requires template-id tokens") ? void (0) : __assert_fail ("Tok.is(tok::annot_template_id) && \"Requires template-id tokens\""
, "clang/lib/Parse/ParseTemplate.cpp", 1419, __extension__ __PRETTY_FUNCTION__
))
;
1420
1421 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1422 assert(TemplateId->mightBeType() &&(static_cast <bool> (TemplateId->mightBeType() &&
"Only works for type and dependent templates") ? void (0) : __assert_fail
("TemplateId->mightBeType() && \"Only works for type and dependent templates\""
, "clang/lib/Parse/ParseTemplate.cpp", 1423, __extension__ __PRETTY_FUNCTION__
))
1423 "Only works for type and dependent templates")(static_cast <bool> (TemplateId->mightBeType() &&
"Only works for type and dependent templates") ? void (0) : __assert_fail
("TemplateId->mightBeType() && \"Only works for type and dependent templates\""
, "clang/lib/Parse/ParseTemplate.cpp", 1423, __extension__ __PRETTY_FUNCTION__
))
;
1424
1425 ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
1426 TemplateId->NumArgs);
1427
1428 TypeResult Type =
1429 TemplateId->isInvalid()
1430 ? TypeError()
1431 : Actions.ActOnTemplateIdType(
1432 getCurScope(), SS, TemplateId->TemplateKWLoc,
1433 TemplateId->Template, TemplateId->Name,
1434 TemplateId->TemplateNameLoc, TemplateId->LAngleLoc,
1435 TemplateArgsPtr, TemplateId->RAngleLoc,
1436 /*IsCtorOrDtorName*/ false, IsClassName);
1437 // Create the new "type" annotation token.
1438 Tok.setKind(tok::annot_typename);
1439 setTypeAnnotation(Tok, Type);
1440 if (SS.isNotEmpty()) // it was a C++ qualified type name.
1441 Tok.setLocation(SS.getBeginLoc());
1442 // End location stays the same
1443
1444 // Replace the template-id annotation token, and possible the scope-specifier
1445 // that precedes it, with the typename annotation token.
1446 PP.AnnotateCachedTokens(Tok);
1447}
1448
1449/// Determine whether the given token can end a template argument.
1450static bool isEndOfTemplateArgument(Token Tok) {
1451 // FIXME: Handle '>>>'.
1452 return Tok.isOneOf(tok::comma, tok::greater, tok::greatergreater,
1453 tok::greatergreatergreater);
1454}
1455
1456/// Parse a C++ template template argument.
1457ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
1458 if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&
1459 !Tok.is(tok::annot_cxxscope))
1460 return ParsedTemplateArgument();
1461
1462 // C++0x [temp.arg.template]p1:
1463 // A template-argument for a template template-parameter shall be the name
1464 // of a class template or an alias template, expressed as id-expression.
1465 //
1466 // We parse an id-expression that refers to a class template or alias
1467 // template. The grammar we parse is:
1468 //
1469 // nested-name-specifier[opt] template[opt] identifier ...[opt]
1470 //
1471 // followed by a token that terminates a template argument, such as ',',
1472 // '>', or (in some cases) '>>'.
1473 CXXScopeSpec SS; // nested-name-specifier, if present
1474 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1475 /*ObjectHasErrors=*/false,
1476 /*EnteringContext=*/false);
1477
1478 ParsedTemplateArgument Result;
1479 SourceLocation EllipsisLoc;
1480 if (SS.isSet() && Tok.is(tok::kw_template)) {
1481 // Parse the optional 'template' keyword following the
1482 // nested-name-specifier.
1483 SourceLocation TemplateKWLoc = ConsumeToken();
1484
1485 if (Tok.is(tok::identifier)) {
1486 // We appear to have a dependent template name.
1487 UnqualifiedId Name;
1488 Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1489 ConsumeToken(); // the identifier
1490
1491 TryConsumeToken(tok::ellipsis, EllipsisLoc);
1492
1493 // If the next token signals the end of a template argument, then we have
1494 // a (possibly-dependent) template name that could be a template template
1495 // argument.
1496 TemplateTy Template;
1497 if (isEndOfTemplateArgument(Tok) &&
1498 Actions.ActOnTemplateName(getCurScope(), SS, TemplateKWLoc, Name,
1499 /*ObjectType=*/nullptr,
1500 /*EnteringContext=*/false, Template))
1501 Result = ParsedTemplateArgument(SS, Template, Name.StartLocation);
1502 }
1503 } else if (Tok.is(tok::identifier)) {
1504 // We may have a (non-dependent) template name.
1505 TemplateTy Template;
1506 UnqualifiedId Name;
1507 Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1508 ConsumeToken(); // the identifier
1509
1510 TryConsumeToken(tok::ellipsis, EllipsisLoc);
1511
1512 if (isEndOfTemplateArgument(Tok)) {
1513 bool MemberOfUnknownSpecialization;
1514 TemplateNameKind TNK = Actions.isTemplateName(
1515 getCurScope(), SS,
1516 /*hasTemplateKeyword=*/false, Name,
1517 /*ObjectType=*/nullptr,
1518 /*EnteringContext=*/false, Template, MemberOfUnknownSpecialization);
1519 if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) {
1520 // We have an id-expression that refers to a class template or
1521 // (C++0x) alias template.
1522 Result = ParsedTemplateArgument(SS, Template, Name.StartLocation);
1523 }
1524 }
1525 }
1526
1527 // If this is a pack expansion, build it as such.
1528 if (EllipsisLoc.isValid() && !Result.isInvalid())
1529 Result = Actions.ActOnPackExpansion(Result, EllipsisLoc);
1530
1531 return Result;
1532}
1533
1534/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
1535///
1536/// template-argument: [C++ 14.2]
1537/// constant-expression
1538/// type-id
1539/// id-expression
1540ParsedTemplateArgument Parser::ParseTemplateArgument() {
1541 // C++ [temp.arg]p2:
1542 // In a template-argument, an ambiguity between a type-id and an
1543 // expression is resolved to a type-id, regardless of the form of
1544 // the corresponding template-parameter.
1545 //
1546 // Therefore, we initially try to parse a type-id - and isCXXTypeId might look
1547 // up and annotate an identifier as an id-expression during disambiguation,
1548 // so enter the appropriate context for a constant expression template
1549 // argument before trying to disambiguate.
1550
1551 EnterExpressionEvaluationContext EnterConstantEvaluated(
1552 Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated,
1553 /*LambdaContextDecl=*/nullptr,
1554 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
1555 if (isCXXTypeId(TypeIdAsTemplateArgument)) {
1556 TypeResult TypeArg = ParseTypeName(
1557 /*Range=*/nullptr, DeclaratorContext::TemplateArg);
1558 return Actions.ActOnTemplateTypeArgument(TypeArg);
1559 }
1560
1561 // Try to parse a template template argument.
1562 {
1563 TentativeParsingAction TPA(*this);
1564
1565 ParsedTemplateArgument TemplateTemplateArgument
1566 = ParseTemplateTemplateArgument();
1567 if (!TemplateTemplateArgument.isInvalid()) {
1568 TPA.Commit();
1569 return TemplateTemplateArgument;
1570 }
1571
1572 // Revert this tentative parse to parse a non-type template argument.
1573 TPA.Revert();
1574 }
1575
1576 // Parse a non-type template argument.
1577 SourceLocation Loc = Tok.getLocation();
1578 ExprResult ExprArg = ParseConstantExpressionInExprEvalContext(MaybeTypeCast);
1579 if (ExprArg.isInvalid() || !ExprArg.get()) {
1580 return ParsedTemplateArgument();
1581 }
1582
1583 return ParsedTemplateArgument(ParsedTemplateArgument::NonType,
1584 ExprArg.get(), Loc);
1585}
1586
1587/// ParseTemplateArgumentList - Parse a C++ template-argument-list
1588/// (C++ [temp.names]). Returns true if there was an error.
1589///
1590/// template-argument-list: [C++ 14.2]
1591/// template-argument
1592/// template-argument-list ',' template-argument
1593///
1594/// \param Template is only used for code completion, and may be null.
1595bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
1596 TemplateTy Template,
1597 SourceLocation OpenLoc) {
1598
1599 ColonProtectionRAIIObject ColonProtection(*this, false);
1600
1601 auto RunSignatureHelp = [&] {
1602 if (!Template)
1603 return QualType();
1604 CalledSignatureHelp = true;
1605 return Actions.ProduceTemplateArgumentSignatureHelp(Template, TemplateArgs,
1606 OpenLoc);
1607 };
1608
1609 do {
1610 PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);
1611 ParsedTemplateArgument Arg = ParseTemplateArgument();
1612 SourceLocation EllipsisLoc;
1613 if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
1614 Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc);
1615
1616 if (Arg.isInvalid()) {
1617 if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
1618 RunSignatureHelp();
1619 return true;
1620 }
1621
1622 // Save this template argument.
1623 TemplateArgs.push_back(Arg);
1624
1625 // If the next token is a comma, consume it and keep reading
1626 // arguments.
1627 } while (TryConsumeToken(tok::comma));
1628
1629 return false;
1630}
1631
1632/// Parse a C++ explicit template instantiation
1633/// (C++ [temp.explicit]).
1634///
1635/// explicit-instantiation:
1636/// 'extern' [opt] 'template' declaration
1637///
1638/// Note that the 'extern' is a GNU extension and C++11 feature.
1639Decl *Parser::ParseExplicitInstantiation(DeclaratorContext Context,
1640 SourceLocation ExternLoc,
1641 SourceLocation TemplateLoc,
1642 SourceLocation &DeclEnd,
1643 ParsedAttributes &AccessAttrs,
1644 AccessSpecifier AS) {
1645 // This isn't really required here.
1646 ParsingDeclRAIIObject
1647 ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent);
1648
1649 return ParseSingleDeclarationAfterTemplate(
1650 Context, ParsedTemplateInfo(ExternLoc, TemplateLoc),
1651 ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
1652}
1653
1654SourceRange Parser::ParsedTemplateInfo::getSourceRange() const {
1655 if (TemplateParams)
1656 return getTemplateParamsRange(TemplateParams->data(),
1657 TemplateParams->size());
1658
1659 SourceRange R(TemplateLoc);
1660 if (ExternLoc.isValid())
1661 R.setBegin(ExternLoc);
1662 return R;
1663}
1664
1665void Parser::LateTemplateParserCallback(void *P, LateParsedTemplate &LPT) {
1666 ((Parser *)P)->ParseLateTemplatedFuncDef(LPT);
1
Calling 'Parser::ParseLateTemplatedFuncDef'
1667}
1668
1669/// Late parse a C++ function template in Microsoft mode.
1670void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
1671 if (!LPT.D)
2
Assuming field 'D' is non-null
3
Taking false branch
1672 return;
1673
1674 // Destroy TemplateIdAnnotations when we're done, if possible.
1675 DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
1676
1677 // Get the FunctionDecl.
1678 FunctionDecl *FunD = LPT.D->getAsFunction();
4
'FunD' initialized here
1679 // Track template parameter depth.
1680 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1681
1682 // To restore the context after late parsing.
1683 Sema::ContextRAII GlobalSavedContext(
1684 Actions, Actions.Context.getTranslationUnitDecl());
1685
1686 MultiParseScope Scopes(*this);
1687
1688 // Get the list of DeclContexts to reenter.
1689 SmallVector<DeclContext*, 4> DeclContextsToReenter;
1690 for (DeclContext *DC = FunD; DC && !DC->isTranslationUnit();
5
Assuming 'DC' is null
6
Assuming pointer value is null
1691 DC = DC->getLexicalParent())
1692 DeclContextsToReenter.push_back(DC);
1693
1694 // Reenter scopes from outermost to innermost.
1695 for (DeclContext *DC : reverse(DeclContextsToReenter)) {
1696 CurTemplateDepthTracker.addDepth(
1697 ReenterTemplateScopes(Scopes, cast<Decl>(DC)));
1698 Scopes.Enter(Scope::DeclScope);
1699 // We'll reenter the function context itself below.
1700 if (DC != FunD)
1701 Actions.PushDeclContext(Actions.getCurScope(), DC);
1702 }
1703
1704 assert(!LPT.Toks.empty() && "Empty body!")(static_cast <bool> (!LPT.Toks.empty() && "Empty body!"
) ? void (0) : __assert_fail ("!LPT.Toks.empty() && \"Empty body!\""
, "clang/lib/Parse/ParseTemplate.cpp", 1704, __extension__ __PRETTY_FUNCTION__
))
;
7
'?' condition is true
1705
1706 // Append the current token at the end of the new token stream so that it
1707 // doesn't get lost.
1708 LPT.Toks.push_back(Tok);
1709 PP.EnterTokenStream(LPT.Toks, true, /*IsReinject*/true);
1710
1711 // Consume the previously pushed token.
1712 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1713 assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&(static_cast <bool> (Tok.isOneOf(tok::l_brace, tok::colon
, tok::kw_try) && "Inline method not starting with '{', ':' or 'try'"
) ? void (0) : __assert_fail ("Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) && \"Inline method not starting with '{', ':' or 'try'\""
, "clang/lib/Parse/ParseTemplate.cpp", 1714, __extension__ __PRETTY_FUNCTION__
))
8
'?' condition is true
1714 "Inline method not starting with '{', ':' or 'try'")(static_cast <bool> (Tok.isOneOf(tok::l_brace, tok::colon
, tok::kw_try) && "Inline method not starting with '{', ':' or 'try'"
) ? void (0) : __assert_fail ("Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) && \"Inline method not starting with '{', ':' or 'try'\""
, "clang/lib/Parse/ParseTemplate.cpp", 1714, __extension__ __PRETTY_FUNCTION__
))
;
1715
1716 // Parse the method body. Function body parsing code is similar enough
1717 // to be re-used for method bodies as well.
1718 ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope |
1719 Scope::CompoundStmtScope);
1720
1721 // Recreate the containing function DeclContext.
1722 Sema::ContextRAII FunctionSavedContext(Actions, FunD->getLexicalParent());
9
Called C++ object pointer is null
1723
1724 Actions.ActOnStartOfFunctionDef(getCurScope(), FunD);
1725
1726 if (Tok.is(tok::kw_try)) {
1727 ParseFunctionTryBlock(LPT.D, FnScope);
1728 } else {
1729 if (Tok.is(tok::colon))
1730 ParseConstructorInitializer(LPT.D);
1731 else
1732 Actions.ActOnDefaultCtorInitializers(LPT.D);
1733
1734 if (Tok.is(tok::l_brace)) {
1735 assert((!isa<FunctionTemplateDecl>(LPT.D) ||(static_cast <bool> ((!isa<FunctionTemplateDecl>(
LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters
() ->getDepth() == TemplateParameterDepth - 1) && "TemplateParameterDepth should be greater than the depth of "
"current template being instantiated!") ? void (0) : __assert_fail
("(!isa<FunctionTemplateDecl>(LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters() ->getDepth() == TemplateParameterDepth - 1) && \"TemplateParameterDepth should be greater than the depth of \" \"current template being instantiated!\""
, "clang/lib/Parse/ParseTemplate.cpp", 1740, __extension__ __PRETTY_FUNCTION__
))
1736 cast<FunctionTemplateDecl>(LPT.D)(static_cast <bool> ((!isa<FunctionTemplateDecl>(
LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters
() ->getDepth() == TemplateParameterDepth - 1) && "TemplateParameterDepth should be greater than the depth of "
"current template being instantiated!") ? void (0) : __assert_fail
("(!isa<FunctionTemplateDecl>(LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters() ->getDepth() == TemplateParameterDepth - 1) && \"TemplateParameterDepth should be greater than the depth of \" \"current template being instantiated!\""
, "clang/lib/Parse/ParseTemplate.cpp", 1740, __extension__ __PRETTY_FUNCTION__
))
1737 ->getTemplateParameters()(static_cast <bool> ((!isa<FunctionTemplateDecl>(
LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters
() ->getDepth() == TemplateParameterDepth - 1) && "TemplateParameterDepth should be greater than the depth of "
"current template being instantiated!") ? void (0) : __assert_fail
("(!isa<FunctionTemplateDecl>(LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters() ->getDepth() == TemplateParameterDepth - 1) && \"TemplateParameterDepth should be greater than the depth of \" \"current template being instantiated!\""
, "clang/lib/Parse/ParseTemplate.cpp", 1740, __extension__ __PRETTY_FUNCTION__
))
1738 ->getDepth() == TemplateParameterDepth - 1) &&(static_cast <bool> ((!isa<FunctionTemplateDecl>(
LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters
() ->getDepth() == TemplateParameterDepth - 1) && "TemplateParameterDepth should be greater than the depth of "
"current template being instantiated!") ? void (0) : __assert_fail
("(!isa<FunctionTemplateDecl>(LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters() ->getDepth() == TemplateParameterDepth - 1) && \"TemplateParameterDepth should be greater than the depth of \" \"current template being instantiated!\""
, "clang/lib/Parse/ParseTemplate.cpp", 1740, __extension__ __PRETTY_FUNCTION__
))
1739 "TemplateParameterDepth should be greater than the depth of "(static_cast <bool> ((!isa<FunctionTemplateDecl>(
LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters
() ->getDepth() == TemplateParameterDepth - 1) && "TemplateParameterDepth should be greater than the depth of "
"current template being instantiated!") ? void (0) : __assert_fail
("(!isa<FunctionTemplateDecl>(LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters() ->getDepth() == TemplateParameterDepth - 1) && \"TemplateParameterDepth should be greater than the depth of \" \"current template being instantiated!\""
, "clang/lib/Parse/ParseTemplate.cpp", 1740, __extension__ __PRETTY_FUNCTION__
))
1740 "current template being instantiated!")(static_cast <bool> ((!isa<FunctionTemplateDecl>(
LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters
() ->getDepth() == TemplateParameterDepth - 1) && "TemplateParameterDepth should be greater than the depth of "
"current template being instantiated!") ? void (0) : __assert_fail
("(!isa<FunctionTemplateDecl>(LPT.D) || cast<FunctionTemplateDecl>(LPT.D) ->getTemplateParameters() ->getDepth() == TemplateParameterDepth - 1) && \"TemplateParameterDepth should be greater than the depth of \" \"current template being instantiated!\""
, "clang/lib/Parse/ParseTemplate.cpp", 1740, __extension__ __PRETTY_FUNCTION__
))
;
1741 ParseFunctionStatementBody(LPT.D, FnScope);
1742 Actions.UnmarkAsLateParsedTemplate(FunD);
1743 } else
1744 Actions.ActOnFinishFunctionBody(LPT.D, nullptr);
1745 }
1746}
1747
1748/// Lex a delayed template function for late parsing.
1749void Parser::LexTemplateFunctionForLateParsing(CachedTokens &Toks) {
1750 tok::TokenKind kind = Tok.getKind();
1751 if (!ConsumeAndStoreFunctionPrologue(Toks)) {
1752 // Consume everything up to (and including) the matching right brace.
1753 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
1754 }
1755
1756 // If we're in a function-try-block, we need to store all the catch blocks.
1757 if (kind == tok::kw_try) {
1758 while (Tok.is(tok::kw_catch)) {
1759 ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);
1760 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
1761 }
1762 }
1763}
1764
1765/// We've parsed something that could plausibly be intended to be a template
1766/// name (\p LHS) followed by a '<' token, and the following code can't possibly
1767/// be an expression. Determine if this is likely to be a template-id and if so,
1768/// diagnose it.
1769bool Parser::diagnoseUnknownTemplateId(ExprResult LHS, SourceLocation Less) {
1770 TentativeParsingAction TPA(*this);
1771 // FIXME: We could look at the token sequence in a lot more detail here.
1772 if (SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
1773 StopAtSemi | StopBeforeMatch)) {
1774 TPA.Commit();
1775
1776 SourceLocation Greater;
1777 ParseGreaterThanInTemplateList(Less, Greater, true, false);
1778 Actions.diagnoseExprIntendedAsTemplateName(getCurScope(), LHS,
1779 Less, Greater);
1780 return true;
1781 }
1782
1783 // There's no matching '>' token, this probably isn't supposed to be
1784 // interpreted as a template-id. Parse it as an (ill-formed) comparison.
1785 TPA.Revert();
1786 return false;
1787}
1788
1789void Parser::checkPotentialAngleBracket(ExprResult &PotentialTemplateName) {
1790 assert(Tok.is(tok::less) && "not at a potential angle bracket")(static_cast <bool> (Tok.is(tok::less) && "not at a potential angle bracket"
) ? void (0) : __assert_fail ("Tok.is(tok::less) && \"not at a potential angle bracket\""
, "clang/lib/Parse/ParseTemplate.cpp", 1790, __extension__ __PRETTY_FUNCTION__
))
;
1791
1792 bool DependentTemplateName = false;
1793 if (!Actions.mightBeIntendedToBeTemplateName(PotentialTemplateName,
1794 DependentTemplateName))
1795 return;
1796
1797 // OK, this might be a name that the user intended to be parsed as a
1798 // template-name, followed by a '<' token. Check for some easy cases.
1799
1800 // If we have potential_template<>, then it's supposed to be a template-name.
1801 if (NextToken().is(tok::greater) ||
1802 (getLangOpts().CPlusPlus11 &&
1803 NextToken().isOneOf(tok::greatergreater, tok::greatergreatergreater))) {
1804 SourceLocation Less = ConsumeToken();
1805 SourceLocation Greater;
1806 ParseGreaterThanInTemplateList(Less, Greater, true, false);
1807 Actions.diagnoseExprIntendedAsTemplateName(
1808 getCurScope(), PotentialTemplateName, Less, Greater);
1809 // FIXME: Perform error recovery.
1810 PotentialTemplateName = ExprError();
1811 return;
1812 }
1813
1814 // If we have 'potential_template<type-id', assume it's supposed to be a
1815 // template-name if there's a matching '>' later on.
1816 {
1817 // FIXME: Avoid the tentative parse when NextToken() can't begin a type.
1818 TentativeParsingAction TPA(*this);
1819 SourceLocation Less = ConsumeToken();
1820 if (isTypeIdUnambiguously() &&
1821 diagnoseUnknownTemplateId(PotentialTemplateName, Less)) {
1822 TPA.Commit();
1823 // FIXME: Perform error recovery.
1824 PotentialTemplateName = ExprError();
1825 return;
1826 }
1827 TPA.Revert();
1828 }
1829
1830 // Otherwise, remember that we saw this in case we see a potentially-matching
1831 // '>' token later on.
1832 AngleBracketTracker::Priority Priority =
1833 (DependentTemplateName ? AngleBracketTracker::DependentName
1834 : AngleBracketTracker::PotentialTypo) |
1835 (Tok.hasLeadingSpace() ? AngleBracketTracker::SpaceBeforeLess
1836 : AngleBracketTracker::NoSpaceBeforeLess);
1837 AngleBrackets.add(*this, PotentialTemplateName.get(), Tok.getLocation(),
1838 Priority);
1839}
1840
1841bool Parser::checkPotentialAngleBracketDelimiter(
1842 const AngleBracketTracker::Loc &LAngle, const Token &OpToken) {
1843 // If a comma in an expression context is followed by a type that can be a
1844 // template argument and cannot be an expression, then this is ill-formed,
1845 // but might be intended to be part of a template-id.
1846 if (OpToken.is(tok::comma) && isTypeIdUnambiguously() &&
1847 diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
1848 AngleBrackets.clear(*this);
1849 return true;
1850 }
1851
1852 // If a context that looks like a template-id is followed by '()', then
1853 // this is ill-formed, but might be intended to be a template-id
1854 // followed by '()'.
1855 if (OpToken.is(tok::greater) && Tok.is(tok::l_paren) &&
1856 NextToken().is(tok::r_paren)) {
1857 Actions.diagnoseExprIntendedAsTemplateName(
1858 getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1859 OpToken.getLocation());
1860 AngleBrackets.clear(*this);
1861 return true;
1862 }
1863
1864 // After a '>' (etc), we're no longer potentially in a construct that's
1865 // intended to be treated as a template-id.
1866 if (OpToken.is(tok::greater) ||
1867 (getLangOpts().CPlusPlus11 &&
1868 OpToken.isOneOf(tok::greatergreater, tok::greatergreatergreater)))
1869 AngleBrackets.clear(*this);
1870 return false;
1871}