/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- ParseCXXInlineMethods.cpp - C++ class inline methods 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 for C++ class inline methods. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "clang/Parse/Parser.h" |
15 | | #include "clang/AST/DeclTemplate.h" |
16 | | #include "clang/Parse/ParseDiagnostic.h" |
17 | | #include "clang/Parse/RAIIObjectsForParser.h" |
18 | | #include "clang/Sema/DeclSpec.h" |
19 | | #include "clang/Sema/Scope.h" |
20 | | using namespace clang; |
21 | | |
22 | | /// ParseCXXInlineMethodDef - We parsed and verified that the specified |
23 | | /// Declarator is a well formed C++ inline method definition. Now lex its body |
24 | | /// and store its tokens for parsing after the C++ class is complete. |
25 | | NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, |
26 | | AttributeList *AccessAttrs, |
27 | | ParsingDeclarator &D, |
28 | | const ParsedTemplateInfo &TemplateInfo, |
29 | | const VirtSpecifiers& VS, |
30 | 269k | SourceLocation PureSpecLoc) { |
31 | 269k | assert(D.isFunctionDeclarator() && "This isn't a function declarator!"); |
32 | 269k | assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try, tok::equal) && |
33 | 269k | "Current token not a '{', ':', '=', or 'try'!"); |
34 | 269k | |
35 | 269k | MultiTemplateParamsArg TemplateParams( |
36 | 5.13k | TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() |
37 | 264k | : nullptr, |
38 | 269k | TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size()5.13k : 0264k ); |
39 | 269k | |
40 | 269k | NamedDecl *FnD; |
41 | 269k | if (D.getDeclSpec().isFriendSpecified()) |
42 | 433 | FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D, |
43 | 433 | TemplateParams); |
44 | 269k | else { |
45 | 269k | FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D, |
46 | 269k | TemplateParams, nullptr, |
47 | 269k | VS, ICIS_NoInit); |
48 | 269k | if (FnD269k ) { |
49 | 269k | Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs); |
50 | 269k | if (PureSpecLoc.isValid()) |
51 | 2 | Actions.ActOnPureSpecifier(FnD, PureSpecLoc); |
52 | 269k | } |
53 | 269k | } |
54 | 269k | |
55 | 269k | if (FnD) |
56 | 269k | HandleMemberFunctionDeclDelays(D, FnD); |
57 | 269k | |
58 | 269k | D.complete(FnD); |
59 | 269k | |
60 | 269k | if (TryConsumeToken(tok::equal)269k ) { |
61 | 4.02k | if (!FnD4.02k ) { |
62 | 1 | SkipUntil(tok::semi); |
63 | 1 | return nullptr; |
64 | 1 | } |
65 | 4.02k | |
66 | 4.02k | bool Delete = false; |
67 | 4.02k | SourceLocation KWLoc; |
68 | 4.02k | SourceLocation KWEndLoc = Tok.getEndLoc().getLocWithOffset(-1); |
69 | 4.02k | if (TryConsumeToken(tok::kw_delete, KWLoc)4.02k ) { |
70 | 2.66k | Diag(KWLoc, getLangOpts().CPlusPlus11 |
71 | 2.63k | ? diag::warn_cxx98_compat_defaulted_deleted_function |
72 | 38 | : diag::ext_defaulted_deleted_function) |
73 | 2.66k | << 1 /* deleted */; |
74 | 2.66k | Actions.SetDeclDeleted(FnD, KWLoc); |
75 | 2.66k | Delete = true; |
76 | 2.66k | if (auto *DeclAsFunction2.66k = dyn_cast<FunctionDecl>(FnD)) { |
77 | 2.63k | DeclAsFunction->setRangeEnd(KWEndLoc); |
78 | 2.63k | } |
79 | 4.02k | } else if (1.35k TryConsumeToken(tok::kw_default, KWLoc)1.35k ) { |
80 | 1.35k | Diag(KWLoc, getLangOpts().CPlusPlus11 |
81 | 1.32k | ? diag::warn_cxx98_compat_defaulted_deleted_function |
82 | 29 | : diag::ext_defaulted_deleted_function) |
83 | 1.35k | << 0 /* defaulted */; |
84 | 1.35k | Actions.SetDeclDefaulted(FnD, KWLoc); |
85 | 1.35k | if (auto *DeclAsFunction1.35k = dyn_cast<FunctionDecl>(FnD)) { |
86 | 1.35k | DeclAsFunction->setRangeEnd(KWEndLoc); |
87 | 1.35k | } |
88 | 0 | } else { |
89 | 0 | llvm_unreachable("function definition after = not 'delete' or 'default'"); |
90 | 1.35k | } |
91 | 4.02k | |
92 | 4.02k | if (4.02k Tok.is(tok::comma)4.02k ) { |
93 | 0 | Diag(KWLoc, diag::err_default_delete_in_multiple_declaration) |
94 | 0 | << Delete; |
95 | 0 | SkipUntil(tok::semi); |
96 | 4.02k | } else if (4.02k ExpectAndConsume(tok::semi, diag::err_expected_after, |
97 | 4.02k | Delete ? "delete"2.66k : "default"1.35k )) { |
98 | 1 | SkipUntil(tok::semi); |
99 | 1 | } |
100 | 4.02k | |
101 | 4.02k | return FnD; |
102 | 4.02k | } |
103 | 265k | |
104 | 265k | if (265k SkipFunctionBodies && 265k (!FnD || 213 Actions.canSkipFunctionBody(FnD)213 ) && |
105 | 265k | trySkippingFunctionBody()209 ) { |
106 | 184 | Actions.ActOnSkippedFunctionBody(FnD); |
107 | 184 | return FnD; |
108 | 184 | } |
109 | 265k | |
110 | 265k | // In delayed template parsing mode, if we are within a class template |
111 | 265k | // or if we are about to parse function member template then consume |
112 | 265k | // the tokens and store them for parsing at the end of the translation unit. |
113 | 265k | if (265k getLangOpts().DelayedTemplateParsing && |
114 | 285 | D.getFunctionDefinitionKind() == FDK_Definition && |
115 | 285 | !D.getDeclSpec().isConstexprSpecified() && |
116 | 273 | !(FnD && 273 FnD->getAsFunction()273 && |
117 | 273 | FnD->getAsFunction()->getReturnType()->getContainedAutoType()) && |
118 | 230 | ((Actions.CurContext->isDependentContext() || |
119 | 125 | (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && |
120 | 125 | TemplateInfo.Kind != ParsedTemplateInfo::ExplicitSpecialization)) && |
121 | 265k | !Actions.IsInsideALocalClassWithinATemplateFunction()128 )) { |
122 | 112 | |
123 | 112 | CachedTokens Toks; |
124 | 112 | LexTemplateFunctionForLateParsing(Toks); |
125 | 112 | |
126 | 112 | if (FnD112 ) { |
127 | 112 | FunctionDecl *FD = FnD->getAsFunction(); |
128 | 112 | Actions.CheckForFunctionRedefinition(FD); |
129 | 112 | Actions.MarkAsLateParsedTemplate(FD, FnD, Toks); |
130 | 112 | } |
131 | 112 | |
132 | 112 | return FnD; |
133 | 112 | } |
134 | 265k | |
135 | 265k | // Consume the tokens and store them for later parsing. |
136 | 265k | |
137 | 265k | LexedMethod* LM = new LexedMethod(this, FnD); |
138 | 265k | getCurrentClass().LateParsedDeclarations.push_back(LM); |
139 | 265k | LM->TemplateScope = getCurScope()->isTemplateParamScope(); |
140 | 265k | CachedTokens &Toks = LM->Toks; |
141 | 265k | |
142 | 265k | tok::TokenKind kind = Tok.getKind(); |
143 | 265k | // Consume everything up to (and including) the left brace of the |
144 | 265k | // function body. |
145 | 265k | if (ConsumeAndStoreFunctionPrologue(Toks)265k ) { |
146 | 16 | // We didn't find the left-brace we expected after the |
147 | 16 | // constructor initializer; we already printed an error, and it's likely |
148 | 16 | // impossible to recover, so don't try to parse this method later. |
149 | 16 | // Skip over the rest of the decl and back to somewhere that looks |
150 | 16 | // reasonable. |
151 | 16 | SkipMalformedDecl(); |
152 | 16 | delete getCurrentClass().LateParsedDeclarations.back(); |
153 | 16 | getCurrentClass().LateParsedDeclarations.pop_back(); |
154 | 16 | return FnD; |
155 | 0 | } else { |
156 | 265k | // Consume everything up to (and including) the matching right brace. |
157 | 265k | ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); |
158 | 265k | } |
159 | 265k | |
160 | 265k | // If we're in a function-try-block, we need to store all the catch blocks. |
161 | 265k | if (265k kind == tok::kw_try265k ) { |
162 | 60 | while (Tok.is(tok::kw_catch)60 ) { |
163 | 30 | ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false); |
164 | 30 | ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); |
165 | 30 | } |
166 | 30 | } |
167 | 265k | |
168 | 265k | if (FnD265k ) { |
169 | 265k | FunctionDecl *FD = FnD->getAsFunction(); |
170 | 265k | // Track that this function will eventually have a body; Sema needs |
171 | 265k | // to know this. |
172 | 265k | Actions.CheckForFunctionRedefinition(FD); |
173 | 265k | FD->setWillHaveBody(true); |
174 | 265k | } else { |
175 | 21 | // If semantic analysis could not build a function declaration, |
176 | 21 | // just throw away the late-parsed declaration. |
177 | 21 | delete getCurrentClass().LateParsedDeclarations.back(); |
178 | 21 | getCurrentClass().LateParsedDeclarations.pop_back(); |
179 | 21 | } |
180 | 265k | |
181 | 265k | return FnD; |
182 | 269k | } |
183 | | |
184 | | /// ParseCXXNonStaticMemberInitializer - We parsed and verified that the |
185 | | /// specified Declarator is a well formed C++ non-static data member |
186 | | /// declaration. Now lex its initializer and store its tokens for parsing |
187 | | /// after the class is complete. |
188 | 937 | void Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) { |
189 | 937 | assert(Tok.isOneOf(tok::l_brace, tok::equal) && |
190 | 937 | "Current token not a '{' or '='!"); |
191 | 937 | |
192 | 937 | LateParsedMemberInitializer *MI = |
193 | 937 | new LateParsedMemberInitializer(this, VarD); |
194 | 937 | getCurrentClass().LateParsedDeclarations.push_back(MI); |
195 | 937 | CachedTokens &Toks = MI->Toks; |
196 | 937 | |
197 | 937 | tok::TokenKind kind = Tok.getKind(); |
198 | 937 | if (kind == tok::equal937 ) { |
199 | 902 | Toks.push_back(Tok); |
200 | 902 | ConsumeToken(); |
201 | 902 | } |
202 | 937 | |
203 | 937 | if (kind == tok::l_brace937 ) { |
204 | 35 | // Begin by storing the '{' token. |
205 | 35 | Toks.push_back(Tok); |
206 | 35 | ConsumeBrace(); |
207 | 35 | |
208 | 35 | // Consume everything up to (and including) the matching right brace. |
209 | 35 | ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/true); |
210 | 937 | } else { |
211 | 902 | // Consume everything up to (but excluding) the comma or semicolon. |
212 | 902 | ConsumeAndStoreInitializer(Toks, CIK_DefaultInitializer); |
213 | 902 | } |
214 | 937 | |
215 | 937 | // Store an artificial EOF token to ensure that we don't run off the end of |
216 | 937 | // the initializer when we come to parse it. |
217 | 937 | Token Eof; |
218 | 937 | Eof.startToken(); |
219 | 937 | Eof.setKind(tok::eof); |
220 | 937 | Eof.setLocation(Tok.getLocation()); |
221 | 937 | Eof.setEofData(VarD); |
222 | 937 | Toks.push_back(Eof); |
223 | 937 | } |
224 | | |
225 | 287k | Parser::LateParsedDeclaration::~LateParsedDeclaration() {} |
226 | 267k | void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {} |
227 | 275k | void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {} |
228 | 11.6k | void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {} |
229 | | |
230 | | Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C) |
231 | 3.52k | : Self(P), Class(C) {} |
232 | | |
233 | 3.52k | Parser::LateParsedClass::~LateParsedClass() { |
234 | 3.52k | Self->DeallocateParsedClasses(Class); |
235 | 3.52k | } |
236 | | |
237 | 3.52k | void Parser::LateParsedClass::ParseLexedMethodDeclarations() { |
238 | 3.52k | Self->ParseLexedMethodDeclarations(*Class); |
239 | 3.52k | } |
240 | | |
241 | 3.52k | void Parser::LateParsedClass::ParseLexedMemberInitializers() { |
242 | 3.52k | Self->ParseLexedMemberInitializers(*Class); |
243 | 3.52k | } |
244 | | |
245 | 3.52k | void Parser::LateParsedClass::ParseLexedMethodDefs() { |
246 | 3.52k | Self->ParseLexedMethodDefs(*Class); |
247 | 3.52k | } |
248 | | |
249 | 9.69k | void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() { |
250 | 9.69k | Self->ParseLexedMethodDeclaration(*this); |
251 | 9.69k | } |
252 | | |
253 | 265k | void Parser::LexedMethod::ParseLexedMethodDefs() { |
254 | 265k | Self->ParseLexedMethodDef(*this); |
255 | 265k | } |
256 | | |
257 | 937 | void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() { |
258 | 937 | Self->ParseLexedMemberInitializer(*this); |
259 | 937 | } |
260 | | |
261 | | /// ParseLexedMethodDeclarations - We finished parsing the member |
262 | | /// specification of a top (non-nested) C++ class. Now go over the |
263 | | /// stack of method declarations with some parts for which parsing was |
264 | | /// delayed (such as default arguments) and parse them. |
265 | 213k | void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { |
266 | 3.52k | bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; |
267 | 213k | ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, |
268 | 213k | HasTemplateScope); |
269 | 213k | TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); |
270 | 213k | if (HasTemplateScope213k ) { |
271 | 979 | Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); |
272 | 979 | ++CurTemplateDepthTracker; |
273 | 979 | } |
274 | 213k | |
275 | 213k | // The current scope is still active if we're the top-level class. |
276 | 213k | // Otherwise we'll need to push and enter a new scope. |
277 | 213k | bool HasClassScope = !Class.TopLevelClass; |
278 | 213k | ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, |
279 | 213k | HasClassScope); |
280 | 213k | if (HasClassScope) |
281 | 3.52k | Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), |
282 | 3.52k | Class.TagOrTemplate); |
283 | 213k | |
284 | 494k | for (size_t i = 0; i < Class.LateParsedDeclarations.size()494k ; ++i280k ) { |
285 | 280k | Class.LateParsedDeclarations[i]->ParseLexedMethodDeclarations(); |
286 | 280k | } |
287 | 213k | |
288 | 213k | if (HasClassScope) |
289 | 3.52k | Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), |
290 | 3.52k | Class.TagOrTemplate); |
291 | 213k | } |
292 | | |
293 | 9.69k | void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { |
294 | 9.69k | // If this is a member template, introduce the template parameter scope. |
295 | 9.69k | ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); |
296 | 9.69k | TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); |
297 | 9.69k | if (LM.TemplateScope9.69k ) { |
298 | 101 | Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method); |
299 | 101 | ++CurTemplateDepthTracker; |
300 | 101 | } |
301 | 9.69k | // Start the delayed C++ method declaration |
302 | 9.69k | Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method); |
303 | 9.69k | |
304 | 9.69k | // Introduce the parameters into scope and parse their default |
305 | 9.69k | // arguments. |
306 | 9.69k | ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope | |
307 | 9.69k | Scope::FunctionDeclarationScope | Scope::DeclScope); |
308 | 34.5k | for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N34.5k ; ++I24.8k ) { |
309 | 24.8k | auto Param = cast<ParmVarDecl>(LM.DefaultArgs[I].Param); |
310 | 24.8k | // Introduce the parameter into scope. |
311 | 24.8k | bool HasUnparsed = Param->hasUnparsedDefaultArg(); |
312 | 24.8k | Actions.ActOnDelayedCXXMethodParameter(getCurScope(), Param); |
313 | 24.8k | std::unique_ptr<CachedTokens> Toks = std::move(LM.DefaultArgs[I].Toks); |
314 | 24.8k | if (Toks24.8k ) { |
315 | 11.8k | // Mark the end of the default argument so that we know when to stop when |
316 | 11.8k | // we parse it later on. |
317 | 11.8k | Token LastDefaultArgToken = Toks->back(); |
318 | 11.8k | Token DefArgEnd; |
319 | 11.8k | DefArgEnd.startToken(); |
320 | 11.8k | DefArgEnd.setKind(tok::eof); |
321 | 11.8k | DefArgEnd.setLocation(LastDefaultArgToken.getEndLoc()); |
322 | 11.8k | DefArgEnd.setEofData(Param); |
323 | 11.8k | Toks->push_back(DefArgEnd); |
324 | 11.8k | |
325 | 11.8k | // Parse the default argument from its saved token stream. |
326 | 11.8k | Toks->push_back(Tok); // So that the current token doesn't get lost |
327 | 11.8k | PP.EnterTokenStream(*Toks, true); |
328 | 11.8k | |
329 | 11.8k | // Consume the previously-pushed token. |
330 | 11.8k | ConsumeAnyToken(); |
331 | 11.8k | |
332 | 11.8k | // Consume the '='. |
333 | 11.8k | assert(Tok.is(tok::equal) && "Default argument not starting with '='"); |
334 | 11.8k | SourceLocation EqualLoc = ConsumeToken(); |
335 | 11.8k | |
336 | 11.8k | // The argument isn't actually potentially evaluated unless it is |
337 | 11.8k | // used. |
338 | 11.8k | EnterExpressionEvaluationContext Eval( |
339 | 11.8k | Actions, |
340 | 11.8k | Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, Param); |
341 | 11.8k | |
342 | 11.8k | ExprResult DefArgResult; |
343 | 11.8k | if (getLangOpts().CPlusPlus11 && 11.8k Tok.is(tok::l_brace)2.07k ) { |
344 | 5 | Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); |
345 | 5 | DefArgResult = ParseBraceInitializer(); |
346 | 5 | } else |
347 | 11.8k | DefArgResult = ParseAssignmentExpression(); |
348 | 11.8k | DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult); |
349 | 11.8k | if (DefArgResult.isInvalid()11.8k ) { |
350 | 96 | Actions.ActOnParamDefaultArgumentError(Param, EqualLoc); |
351 | 11.8k | } else { |
352 | 11.7k | if (Tok.isNot(tok::eof) || 11.7k Tok.getEofData() != Param11.7k ) { |
353 | 2 | // The last two tokens are the terminator and the saved value of |
354 | 2 | // Tok; the last token in the default argument is the one before |
355 | 2 | // those. |
356 | 2 | assert(Toks->size() >= 3 && "expected a token in default arg"); |
357 | 2 | Diag(Tok.getLocation(), diag::err_default_arg_unparsed) |
358 | 2 | << SourceRange(Tok.getLocation(), |
359 | 2 | (*Toks)[Toks->size() - 3].getLocation()); |
360 | 2 | } |
361 | 11.7k | Actions.ActOnParamDefaultArgument(Param, EqualLoc, |
362 | 11.7k | DefArgResult.get()); |
363 | 11.7k | } |
364 | 11.8k | |
365 | 11.8k | // There could be leftover tokens (e.g. because of an error). |
366 | 11.8k | // Skip through until we reach the 'end of default argument' token. |
367 | 11.8k | while (Tok.isNot(tok::eof)) |
368 | 11 | ConsumeAnyToken(); |
369 | 11.8k | |
370 | 11.8k | if (Tok.is(tok::eof) && 11.8k Tok.getEofData() == Param11.8k ) |
371 | 11.8k | ConsumeAnyToken(); |
372 | 24.8k | } else if (13.0k HasUnparsed13.0k ) { |
373 | 3 | assert(Param->hasInheritedDefaultArg()); |
374 | 3 | FunctionDecl *Old = cast<FunctionDecl>(LM.Method)->getPreviousDecl(); |
375 | 3 | ParmVarDecl *OldParam = Old->getParamDecl(I); |
376 | 3 | assert (!OldParam->hasUnparsedDefaultArg()); |
377 | 3 | if (OldParam->hasUninstantiatedDefaultArg()) |
378 | 2 | Param->setUninstantiatedDefaultArg( |
379 | 2 | OldParam->getUninstantiatedDefaultArg()); |
380 | 3 | else |
381 | 1 | Param->setDefaultArg(OldParam->getInit()); |
382 | 13.0k | } |
383 | 24.8k | } |
384 | 9.69k | |
385 | 9.69k | // Parse a delayed exception-specification, if there is one. |
386 | 9.69k | if (CachedTokens *Toks9.69k = LM.ExceptionSpecTokens) { |
387 | 801 | // Add the 'stop' token. |
388 | 801 | Token LastExceptionSpecToken = Toks->back(); |
389 | 801 | Token ExceptionSpecEnd; |
390 | 801 | ExceptionSpecEnd.startToken(); |
391 | 801 | ExceptionSpecEnd.setKind(tok::eof); |
392 | 801 | ExceptionSpecEnd.setLocation(LastExceptionSpecToken.getEndLoc()); |
393 | 801 | ExceptionSpecEnd.setEofData(LM.Method); |
394 | 801 | Toks->push_back(ExceptionSpecEnd); |
395 | 801 | |
396 | 801 | // Parse the default argument from its saved token stream. |
397 | 801 | Toks->push_back(Tok); // So that the current token doesn't get lost |
398 | 801 | PP.EnterTokenStream(*Toks, true); |
399 | 801 | |
400 | 801 | // Consume the previously-pushed token. |
401 | 801 | ConsumeAnyToken(); |
402 | 801 | |
403 | 801 | // C++11 [expr.prim.general]p3: |
404 | 801 | // If a declaration declares a member function or member function |
405 | 801 | // template of a class X, the expression this is a prvalue of type |
406 | 801 | // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq |
407 | 801 | // and the end of the function-definition, member-declarator, or |
408 | 801 | // declarator. |
409 | 801 | CXXMethodDecl *Method; |
410 | 801 | if (FunctionTemplateDecl *FunTmpl |
411 | 801 | = dyn_cast<FunctionTemplateDecl>(LM.Method)) |
412 | 10 | Method = cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); |
413 | 801 | else |
414 | 791 | Method = cast<CXXMethodDecl>(LM.Method); |
415 | 801 | |
416 | 801 | Sema::CXXThisScopeRAII ThisScope(Actions, Method->getParent(), |
417 | 801 | Method->getTypeQualifiers(), |
418 | 801 | getLangOpts().CPlusPlus11); |
419 | 801 | |
420 | 801 | // Parse the exception-specification. |
421 | 801 | SourceRange SpecificationRange; |
422 | 801 | SmallVector<ParsedType, 4> DynamicExceptions; |
423 | 801 | SmallVector<SourceRange, 4> DynamicExceptionRanges; |
424 | 801 | ExprResult NoexceptExpr; |
425 | 801 | CachedTokens *ExceptionSpecTokens; |
426 | 801 | |
427 | 801 | ExceptionSpecificationType EST |
428 | 801 | = tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange, |
429 | 801 | DynamicExceptions, |
430 | 801 | DynamicExceptionRanges, NoexceptExpr, |
431 | 801 | ExceptionSpecTokens); |
432 | 801 | |
433 | 801 | if (Tok.isNot(tok::eof) || 801 Tok.getEofData() != LM.Method801 ) |
434 | 0 | Diag(Tok.getLocation(), diag::err_except_spec_unparsed); |
435 | 801 | |
436 | 801 | // Attach the exception-specification to the method. |
437 | 801 | Actions.actOnDelayedExceptionSpecification(LM.Method, EST, |
438 | 801 | SpecificationRange, |
439 | 801 | DynamicExceptions, |
440 | 801 | DynamicExceptionRanges, |
441 | 801 | NoexceptExpr.isUsable()? |
442 | 801 | NoexceptExpr.get()176 : nullptr625 ); |
443 | 801 | |
444 | 801 | // There could be leftover tokens (e.g. because of an error). |
445 | 801 | // Skip through until we reach the original token position. |
446 | 801 | while (Tok.isNot(tok::eof)) |
447 | 0 | ConsumeAnyToken(); |
448 | 801 | |
449 | 801 | // Clean up the remaining EOF token. |
450 | 801 | if (Tok.is(tok::eof) && 801 Tok.getEofData() == LM.Method801 ) |
451 | 801 | ConsumeAnyToken(); |
452 | 801 | |
453 | 801 | delete Toks; |
454 | 801 | LM.ExceptionSpecTokens = nullptr; |
455 | 801 | } |
456 | 9.69k | |
457 | 9.69k | PrototypeScope.Exit(); |
458 | 9.69k | |
459 | 9.69k | // Finish the delayed C++ method declaration. |
460 | 9.69k | Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method); |
461 | 9.69k | } |
462 | | |
463 | | /// ParseLexedMethodDefs - We finished parsing the member specification of a top |
464 | | /// (non-nested) C++ class. Now go over the stack of lexed methods that were |
465 | | /// collected during its parsing and parse them all. |
466 | 213k | void Parser::ParseLexedMethodDefs(ParsingClass &Class) { |
467 | 3.52k | bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; |
468 | 213k | ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope); |
469 | 213k | TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); |
470 | 213k | if (HasTemplateScope213k ) { |
471 | 979 | Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); |
472 | 979 | ++CurTemplateDepthTracker; |
473 | 979 | } |
474 | 213k | bool HasClassScope = !Class.TopLevelClass; |
475 | 213k | ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, |
476 | 213k | HasClassScope); |
477 | 213k | |
478 | 494k | for (size_t i = 0; i < Class.LateParsedDeclarations.size()494k ; ++i280k ) { |
479 | 280k | Class.LateParsedDeclarations[i]->ParseLexedMethodDefs(); |
480 | 280k | } |
481 | 213k | } |
482 | | |
483 | 265k | void Parser::ParseLexedMethodDef(LexedMethod &LM) { |
484 | 265k | // If this is a member template, introduce the template parameter scope. |
485 | 265k | ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); |
486 | 265k | TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); |
487 | 265k | if (LM.TemplateScope265k ) { |
488 | 4.97k | Actions.ActOnReenterTemplateScope(getCurScope(), LM.D); |
489 | 4.97k | ++CurTemplateDepthTracker; |
490 | 4.97k | } |
491 | 265k | |
492 | 265k | assert(!LM.Toks.empty() && "Empty body!"); |
493 | 265k | Token LastBodyToken = LM.Toks.back(); |
494 | 265k | Token BodyEnd; |
495 | 265k | BodyEnd.startToken(); |
496 | 265k | BodyEnd.setKind(tok::eof); |
497 | 265k | BodyEnd.setLocation(LastBodyToken.getEndLoc()); |
498 | 265k | BodyEnd.setEofData(LM.D); |
499 | 265k | LM.Toks.push_back(BodyEnd); |
500 | 265k | // Append the current token at the end of the new token stream so that it |
501 | 265k | // doesn't get lost. |
502 | 265k | LM.Toks.push_back(Tok); |
503 | 265k | PP.EnterTokenStream(LM.Toks, true); |
504 | 265k | |
505 | 265k | // Consume the previously pushed token. |
506 | 265k | ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); |
507 | 265k | assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) |
508 | 265k | && "Inline method not starting with '{', ':' or 'try'"); |
509 | 265k | |
510 | 265k | // Parse the method body. Function body parsing code is similar enough |
511 | 265k | // to be re-used for method bodies as well. |
512 | 265k | ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope | |
513 | 265k | Scope::CompoundStmtScope); |
514 | 265k | Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D); |
515 | 265k | |
516 | 265k | if (Tok.is(tok::kw_try)265k ) { |
517 | 30 | ParseFunctionTryBlock(LM.D, FnScope); |
518 | 30 | |
519 | 30 | while (Tok.isNot(tok::eof)) |
520 | 0 | ConsumeAnyToken(); |
521 | 30 | |
522 | 30 | if (Tok.is(tok::eof) && 30 Tok.getEofData() == LM.D30 ) |
523 | 30 | ConsumeAnyToken(); |
524 | 30 | return; |
525 | 30 | } |
526 | 265k | if (265k Tok.is(tok::colon)265k ) { |
527 | 27.7k | ParseConstructorInitializer(LM.D); |
528 | 27.7k | |
529 | 27.7k | // Error recovery. |
530 | 27.7k | if (!Tok.is(tok::l_brace)27.7k ) { |
531 | 14 | FnScope.Exit(); |
532 | 14 | Actions.ActOnFinishFunctionBody(LM.D, nullptr); |
533 | 14 | |
534 | 14 | while (Tok.isNot(tok::eof)) |
535 | 0 | ConsumeAnyToken(); |
536 | 14 | |
537 | 14 | if (Tok.is(tok::eof) && 14 Tok.getEofData() == LM.D14 ) |
538 | 2 | ConsumeAnyToken(); |
539 | 14 | return; |
540 | 14 | } |
541 | 265k | } else |
542 | 237k | Actions.ActOnDefaultCtorInitializers(LM.D); |
543 | 265k | |
544 | 265k | assert((Actions.getDiagnostics().hasErrorOccurred() || |
545 | 265k | !isa<FunctionTemplateDecl>(LM.D) || |
546 | 265k | cast<FunctionTemplateDecl>(LM.D)->getTemplateParameters()->getDepth() |
547 | 265k | < TemplateParameterDepth) && |
548 | 265k | "TemplateParameterDepth should be greater than the depth of " |
549 | 265k | "current template being instantiated!"); |
550 | 265k | |
551 | 265k | ParseFunctionStatementBody(LM.D, FnScope); |
552 | 265k | |
553 | 265k | while (Tok.isNot(tok::eof)) |
554 | 0 | ConsumeAnyToken(); |
555 | 265k | |
556 | 265k | if (Tok.is(tok::eof) && 265k Tok.getEofData() == LM.D265k ) |
557 | 265k | ConsumeAnyToken(); |
558 | 265k | |
559 | 265k | if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D)) |
560 | 260k | if (260k isa<CXXMethodDecl>(FD) || |
561 | 411 | FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)) |
562 | 260k | Actions.ActOnFinishInlineFunctionDef(FD); |
563 | 265k | } |
564 | | |
565 | | /// ParseLexedMemberInitializers - We finished parsing the member specification |
566 | | /// of a top (non-nested) C++ class. Now go over the stack of lexed data member |
567 | | /// initializers that were collected during its parsing and parse them all. |
568 | 213k | void Parser::ParseLexedMemberInitializers(ParsingClass &Class) { |
569 | 3.52k | bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; |
570 | 213k | ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, |
571 | 213k | HasTemplateScope); |
572 | 213k | TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); |
573 | 213k | if (HasTemplateScope213k ) { |
574 | 979 | Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); |
575 | 979 | ++CurTemplateDepthTracker; |
576 | 979 | } |
577 | 213k | // Set or update the scope flags. |
578 | 213k | bool AlreadyHasClassScope = Class.TopLevelClass; |
579 | 213k | unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; |
580 | 213k | ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); |
581 | 213k | ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); |
582 | 213k | |
583 | 213k | if (!AlreadyHasClassScope) |
584 | 3.52k | Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), |
585 | 3.52k | Class.TagOrTemplate); |
586 | 213k | |
587 | 213k | if (!Class.LateParsedDeclarations.empty()213k ) { |
588 | 56.2k | // C++11 [expr.prim.general]p4: |
589 | 56.2k | // Otherwise, if a member-declarator declares a non-static data member |
590 | 56.2k | // (9.2) of a class X, the expression this is a prvalue of type "pointer |
591 | 56.2k | // to X" within the optional brace-or-equal-initializer. It shall not |
592 | 56.2k | // appear elsewhere in the member-declarator. |
593 | 56.2k | Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate, |
594 | 56.2k | /*TypeQuals=*/(unsigned)0); |
595 | 56.2k | |
596 | 336k | for (size_t i = 0; i < Class.LateParsedDeclarations.size()336k ; ++i280k ) { |
597 | 280k | Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers(); |
598 | 280k | } |
599 | 56.2k | } |
600 | 213k | |
601 | 213k | if (!AlreadyHasClassScope) |
602 | 3.52k | Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), |
603 | 3.52k | Class.TagOrTemplate); |
604 | 213k | |
605 | 213k | Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate); |
606 | 213k | } |
607 | | |
608 | 937 | void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { |
609 | 937 | if (!MI.Field || 937 MI.Field->isInvalidDecl()927 ) |
610 | 18 | return; |
611 | 919 | |
612 | 919 | // Append the current token at the end of the new token stream so that it |
613 | 919 | // doesn't get lost. |
614 | 919 | MI.Toks.push_back(Tok); |
615 | 919 | PP.EnterTokenStream(MI.Toks, true); |
616 | 919 | |
617 | 919 | // Consume the previously pushed token. |
618 | 919 | ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); |
619 | 919 | |
620 | 919 | SourceLocation EqualLoc; |
621 | 919 | |
622 | 919 | Actions.ActOnStartCXXInClassMemberInitializer(); |
623 | 919 | |
624 | 919 | ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false, |
625 | 919 | EqualLoc); |
626 | 919 | |
627 | 919 | Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc, |
628 | 919 | Init.get()); |
629 | 919 | |
630 | 919 | // The next token should be our artificial terminating EOF token. |
631 | 919 | if (Tok.isNot(tok::eof)919 ) { |
632 | 19 | if (!Init.isInvalid()19 ) { |
633 | 8 | SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation); |
634 | 8 | if (!EndLoc.isValid()) |
635 | 0 | EndLoc = Tok.getLocation(); |
636 | 8 | // No fixit; we can't recover as if there were a semicolon here. |
637 | 8 | Diag(EndLoc, diag::err_expected_semi_decl_list); |
638 | 8 | } |
639 | 19 | |
640 | 19 | // Consume tokens until we hit the artificial EOF. |
641 | 47 | while (Tok.isNot(tok::eof)) |
642 | 28 | ConsumeAnyToken(); |
643 | 19 | } |
644 | 919 | // Make sure this is *our* artificial EOF token. |
645 | 919 | if (Tok.getEofData() == MI.Field) |
646 | 918 | ConsumeAnyToken(); |
647 | 937 | } |
648 | | |
649 | | /// ConsumeAndStoreUntil - Consume and store the token at the passed token |
650 | | /// container until the token 'T' is reached (which gets |
651 | | /// consumed/stored too, if ConsumeFinalToken). |
652 | | /// If StopAtSemi is true, then we will stop early at a ';' character. |
653 | | /// Returns true if token 'T1' or 'T2' was found. |
654 | | /// NOTE: This is a specialized version of Parser::SkipUntil. |
655 | | bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, |
656 | | CachedTokens &Toks, |
657 | 1.76M | bool StopAtSemi, bool ConsumeFinalToken) { |
658 | 1.76M | // We always want this function to consume at least one token if the first |
659 | 1.76M | // token isn't T and if not at EOF. |
660 | 1.76M | bool isFirstTokenConsumed = true; |
661 | 8.88M | while (18.88M ) { |
662 | 8.88M | // If we found one of the tokens, stop and return true. |
663 | 8.88M | if (Tok.is(T1) || 8.88M Tok.is(T2)7.12M ) { |
664 | 1.76M | if (ConsumeFinalToken1.76M ) { |
665 | 1.52M | Toks.push_back(Tok); |
666 | 1.52M | ConsumeAnyToken(); |
667 | 1.52M | } |
668 | 1.76M | return true; |
669 | 1.76M | } |
670 | 7.12M | |
671 | 7.12M | switch (Tok.getKind()) { |
672 | 154 | case tok::eof: |
673 | 154 | case tok::annot_module_begin: |
674 | 154 | case tok::annot_module_end: |
675 | 154 | case tok::annot_module_include: |
676 | 154 | // Ran out of tokens. |
677 | 154 | return false; |
678 | 154 | |
679 | 919k | case tok::l_paren: |
680 | 919k | // Recursively consume properly-nested parens. |
681 | 919k | Toks.push_back(Tok); |
682 | 919k | ConsumeParen(); |
683 | 919k | ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false); |
684 | 919k | break; |
685 | 192k | case tok::l_square: |
686 | 192k | // Recursively consume properly-nested square brackets. |
687 | 192k | Toks.push_back(Tok); |
688 | 192k | ConsumeBracket(); |
689 | 192k | ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false); |
690 | 192k | break; |
691 | 79.5k | case tok::l_brace: |
692 | 79.5k | // Recursively consume properly-nested braces. |
693 | 79.5k | Toks.push_back(Tok); |
694 | 79.5k | ConsumeBrace(); |
695 | 79.5k | ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); |
696 | 79.5k | break; |
697 | 154 | |
698 | 154 | // Okay, we found a ']' or '}' or ')', which we think should be balanced. |
699 | 154 | // Since the user wasn't looking for this token (if they were, it would |
700 | 154 | // already be handled), this isn't balanced. If there is a LHS token at a |
701 | 154 | // higher level, we will assume that this matches the unbalanced token |
702 | 154 | // and return it. Otherwise, this is a spurious RHS token, which we skip. |
703 | 3 | case tok::r_paren: |
704 | 3 | if (ParenCount && 3 !isFirstTokenConsumed3 ) |
705 | 2 | return false; // Matches something. |
706 | 1 | Toks.push_back(Tok); |
707 | 1 | ConsumeParen(); |
708 | 1 | break; |
709 | 33 | case tok::r_square: |
710 | 33 | if (BracketCount && 33 !isFirstTokenConsumed0 ) |
711 | 0 | return false; // Matches something. |
712 | 33 | Toks.push_back(Tok); |
713 | 33 | ConsumeBracket(); |
714 | 33 | break; |
715 | 23 | case tok::r_brace: |
716 | 23 | if (BraceCount && 23 !isFirstTokenConsumed23 ) |
717 | 23 | return false; // Matches something. |
718 | 0 | Toks.push_back(Tok); |
719 | 0 | ConsumeBrace(); |
720 | 0 | break; |
721 | 0 |
|
722 | 702k | case tok::semi: |
723 | 702k | if (StopAtSemi) |
724 | 9 | return false; |
725 | 702k | // FALL THROUGH. |
726 | 6.63M | default: |
727 | 6.63M | // consume this token. |
728 | 6.63M | Toks.push_back(Tok); |
729 | 6.63M | ConsumeAnyToken(/*ConsumeCodeCompletionTok*/true); |
730 | 6.63M | break; |
731 | 7.12M | } |
732 | 7.12M | isFirstTokenConsumed = false; |
733 | 7.12M | } |
734 | 1.76M | } |
735 | | |
736 | | /// \brief Consume tokens and store them in the passed token container until |
737 | | /// we've passed the try keyword and constructor initializers and have consumed |
738 | | /// the opening brace of the function body. The opening brace will be consumed |
739 | | /// if and only if there was no error. |
740 | | /// |
741 | | /// \return True on error. |
742 | 267k | bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) { |
743 | 267k | if (Tok.is(tok::kw_try)267k ) { |
744 | 44 | Toks.push_back(Tok); |
745 | 44 | ConsumeToken(); |
746 | 44 | } |
747 | 267k | |
748 | 267k | if (Tok.isNot(tok::colon)267k ) { |
749 | 239k | // Easy case, just a function body. |
750 | 239k | |
751 | 239k | // Grab any remaining garbage to be diagnosed later. We stop when we reach a |
752 | 239k | // brace: an opening one is the function body, while a closing one probably |
753 | 239k | // means we've reached the end of the class. |
754 | 239k | ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks, |
755 | 239k | /*StopAtSemi=*/true, |
756 | 239k | /*ConsumeFinalToken=*/false); |
757 | 239k | if (Tok.isNot(tok::l_brace)) |
758 | 1 | return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace; |
759 | 239k | |
760 | 239k | Toks.push_back(Tok); |
761 | 239k | ConsumeBrace(); |
762 | 239k | return false; |
763 | 239k | } |
764 | 27.9k | |
765 | 27.9k | Toks.push_back(Tok); |
766 | 27.9k | ConsumeToken(); |
767 | 27.9k | |
768 | 27.9k | // We can't reliably skip over a mem-initializer-id, because it could be |
769 | 27.9k | // a template-id involving not-yet-declared names. Given: |
770 | 27.9k | // |
771 | 27.9k | // S ( ) : a < b < c > ( e ) |
772 | 27.9k | // |
773 | 27.9k | // 'e' might be an initializer or part of a template argument, depending |
774 | 27.9k | // on whether 'b' is a template. |
775 | 27.9k | |
776 | 27.9k | // Track whether we might be inside a template argument. We can give |
777 | 27.9k | // significantly better diagnostics if we know that we're not. |
778 | 27.9k | bool MightBeTemplateArgument = false; |
779 | 27.9k | |
780 | 54.2k | while (true54.2k ) { |
781 | 54.2k | // Skip over the mem-initializer-id, if possible. |
782 | 54.2k | if (Tok.is(tok::kw_decltype)54.2k ) { |
783 | 8 | Toks.push_back(Tok); |
784 | 8 | SourceLocation OpenLoc = ConsumeToken(); |
785 | 8 | if (Tok.isNot(tok::l_paren)) |
786 | 1 | return Diag(Tok.getLocation(), diag::err_expected_lparen_after) |
787 | 1 | << "decltype"; |
788 | 7 | Toks.push_back(Tok); |
789 | 7 | ConsumeParen(); |
790 | 7 | if (!ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/true)7 ) { |
791 | 1 | Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren; |
792 | 1 | Diag(OpenLoc, diag::note_matching) << tok::l_paren; |
793 | 1 | return true; |
794 | 1 | } |
795 | 54.2k | } |
796 | 54.2k | do 54.2k { |
797 | 54.3k | // Walk over a component of a nested-name-specifier. |
798 | 54.3k | if (Tok.is(tok::coloncolon)54.3k ) { |
799 | 83 | Toks.push_back(Tok); |
800 | 83 | ConsumeToken(); |
801 | 83 | |
802 | 83 | if (Tok.is(tok::kw_template)83 ) { |
803 | 2 | Toks.push_back(Tok); |
804 | 2 | ConsumeToken(); |
805 | 2 | } |
806 | 83 | } |
807 | 54.3k | |
808 | 54.3k | if (Tok.is(tok::identifier)54.3k ) { |
809 | 54.2k | Toks.push_back(Tok); |
810 | 54.2k | ConsumeToken(); |
811 | 54.3k | } else { |
812 | 117 | break; |
813 | 117 | } |
814 | 54.2k | } while (Tok.is(tok::coloncolon)); |
815 | 54.2k | |
816 | 54.2k | if (Tok.is(tok::code_completion)54.2k ) { |
817 | 33 | Toks.push_back(Tok); |
818 | 33 | ConsumeCodeCompletionToken(); |
819 | 33 | if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype)33 ) { |
820 | 11 | // Could be the start of another member initializer (the ',' has not |
821 | 11 | // been written yet) |
822 | 11 | continue; |
823 | 11 | } |
824 | 54.1k | } |
825 | 54.1k | |
826 | 54.1k | if (54.1k Tok.is(tok::comma)54.1k ) { |
827 | 7 | // The initialization is missing, we'll diagnose it later. |
828 | 7 | Toks.push_back(Tok); |
829 | 7 | ConsumeToken(); |
830 | 7 | continue; |
831 | 7 | } |
832 | 54.1k | if (54.1k Tok.is(tok::less)54.1k ) |
833 | 959 | MightBeTemplateArgument = true; |
834 | 54.1k | |
835 | 54.1k | if (MightBeTemplateArgument54.1k ) { |
836 | 1.64k | // We may be inside a template argument list. Grab up to the start of the |
837 | 1.64k | // next parenthesized initializer or braced-init-list. This *might* be the |
838 | 1.64k | // initializer, or it might be a subexpression in the template argument |
839 | 1.64k | // list. |
840 | 1.64k | // FIXME: Count angle brackets, and clear MightBeTemplateArgument |
841 | 1.64k | // if all angles are closed. |
842 | 1.64k | if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks, |
843 | 1.64k | /*StopAtSemi=*/true, |
844 | 1.64k | /*ConsumeFinalToken=*/false)) { |
845 | 0 | // We're not just missing the initializer, we're also missing the |
846 | 0 | // function body! |
847 | 0 | return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace; |
848 | 0 | } |
849 | 52.5k | } else if (52.5k Tok.isNot(tok::l_paren) && 52.5k Tok.isNot(tok::l_brace)694 ) { |
850 | 1 | // We found something weird in a mem-initializer-id. |
851 | 1 | if (getLangOpts().CPlusPlus11) |
852 | 1 | return Diag(Tok.getLocation(), diag::err_expected_either) |
853 | 1 | << tok::l_paren << tok::l_brace; |
854 | 1 | else |
855 | 0 | return Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren; |
856 | 54.1k | } |
857 | 54.1k | |
858 | 54.1k | tok::TokenKind kind = Tok.getKind(); |
859 | 54.1k | Toks.push_back(Tok); |
860 | 54.1k | bool IsLParen = (kind == tok::l_paren); |
861 | 54.1k | SourceLocation OpenLoc = Tok.getLocation(); |
862 | 54.1k | |
863 | 54.1k | if (IsLParen54.1k ) { |
864 | 53.5k | ConsumeParen(); |
865 | 54.1k | } else { |
866 | 645 | assert(kind == tok::l_brace && "Must be left paren or brace here."); |
867 | 645 | ConsumeBrace(); |
868 | 645 | // In C++03, this has to be the start of the function body, which |
869 | 645 | // means the initializer is malformed; we'll diagnose it later. |
870 | 645 | if (!getLangOpts().CPlusPlus11) |
871 | 54 | return false; |
872 | 591 | |
873 | 591 | const Token &PreviousToken = Toks[Toks.size() - 2]; |
874 | 591 | if (!MightBeTemplateArgument && |
875 | 639 | !PreviousToken.isOneOf(tok::identifier, tok::greater, |
876 | 591 | tok::greatergreater)) { |
877 | 28 | // If the opening brace is not preceded by one of these tokens, we are |
878 | 28 | // missing the mem-initializer-id. In order to recover better, we need |
879 | 28 | // to use heuristics to determine if this '{' is most likely the |
880 | 28 | // beginning of a brace-init-list or the function body. |
881 | 28 | // Check the token after the corresponding '}'. |
882 | 28 | TentativeParsingAction PA(*this); |
883 | 28 | if (SkipUntil(tok::r_brace) && |
884 | 28 | !Tok.isOneOf(tok::comma, tok::ellipsis, tok::l_brace)28 ) { |
885 | 28 | // Consider there was a malformed initializer and this is the start |
886 | 28 | // of the function body. We'll diagnose it later. |
887 | 28 | PA.Revert(); |
888 | 28 | return false; |
889 | 28 | } |
890 | 0 | PA.Revert(); |
891 | 0 | } |
892 | 645 | } |
893 | 54.1k | |
894 | 54.1k | // Grab the initializer (or the subexpression of the template argument). |
895 | 54.1k | // FIXME: If we support lambdas here, we'll need to set StopAtSemi to false |
896 | 54.1k | // if we might be inside the braces of a lambda-expression. |
897 | 54.1k | tok::TokenKind CloseKind = IsLParen ? 54.1k tok::r_paren53.5k : tok::r_brace563 ; |
898 | 54.1k | if (!ConsumeAndStoreUntil(CloseKind, Toks, /*StopAtSemi=*/true)54.1k ) { |
899 | 5 | Diag(Tok, diag::err_expected) << CloseKind; |
900 | 5 | Diag(OpenLoc, diag::note_matching) << kind; |
901 | 5 | return true; |
902 | 5 | } |
903 | 54.0k | |
904 | 54.0k | // Grab pack ellipsis, if present. |
905 | 54.0k | if (54.0k Tok.is(tok::ellipsis)54.0k ) { |
906 | 13 | Toks.push_back(Tok); |
907 | 13 | ConsumeToken(); |
908 | 13 | } |
909 | 54.0k | |
910 | 54.0k | // If we know we just consumed a mem-initializer, we must have ',' or '{' |
911 | 54.0k | // next. |
912 | 54.0k | if (Tok.is(tok::comma)54.0k ) { |
913 | 26.3k | Toks.push_back(Tok); |
914 | 26.3k | ConsumeToken(); |
915 | 54.0k | } else if (27.7k Tok.is(tok::l_brace)27.7k ) { |
916 | 27.8k | // This is the function body if the ')' or '}' is immediately followed by |
917 | 27.8k | // a '{'. That cannot happen within a template argument, apart from the |
918 | 27.8k | // case where a template argument contains a compound literal: |
919 | 27.8k | // |
920 | 27.8k | // S ( ) : a < b < c > ( d ) { } |
921 | 27.8k | // // End of declaration, or still inside the template argument? |
922 | 27.8k | // |
923 | 27.8k | // ... and the case where the template argument contains a lambda: |
924 | 27.8k | // |
925 | 27.8k | // S ( ) : a < 0 && b < c > ( d ) + [ ] ( ) { return 0; } |
926 | 27.8k | // ( ) > ( ) { } |
927 | 27.8k | // |
928 | 27.8k | // FIXME: Disambiguate these cases. Note that the latter case is probably |
929 | 27.8k | // going to be made ill-formed by core issue 1607. |
930 | 27.8k | Toks.push_back(Tok); |
931 | 27.8k | ConsumeBrace(); |
932 | 27.8k | return false; |
933 | 18.4E | } else if (18.4E !MightBeTemplateArgument18.4E ) { |
934 | 8 | return Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace |
935 | 8 | << tok::comma; |
936 | 8 | } |
937 | 54.2k | } |
938 | 267k | } |
939 | | |
940 | | /// \brief Consume and store tokens from the '?' to the ':' in a conditional |
941 | | /// expression. |
942 | 4 | bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) { |
943 | 4 | // Consume '?'. |
944 | 4 | assert(Tok.is(tok::question)); |
945 | 4 | Toks.push_back(Tok); |
946 | 4 | ConsumeToken(); |
947 | 4 | |
948 | 8 | while (Tok.isNot(tok::colon)8 ) { |
949 | 4 | if (!ConsumeAndStoreUntil(tok::question, tok::colon, Toks, |
950 | 4 | /*StopAtSemi=*/true, |
951 | 4 | /*ConsumeFinalToken=*/false)) |
952 | 0 | return false; |
953 | 4 | |
954 | 4 | // If we found a nested conditional, consume it. |
955 | 4 | if (4 Tok.is(tok::question) && 4 !ConsumeAndStoreConditional(Toks)0 ) |
956 | 0 | return false; |
957 | 4 | } |
958 | 4 | |
959 | 4 | // Consume ':'. |
960 | 4 | Toks.push_back(Tok); |
961 | 4 | ConsumeToken(); |
962 | 4 | return true; |
963 | 4 | } |
964 | | |
965 | | /// \brief A tentative parsing action that can also revert token annotations. |
966 | | class Parser::UnannotatedTentativeParsingAction : public TentativeParsingAction { |
967 | | public: |
968 | | explicit UnannotatedTentativeParsingAction(Parser &Self, |
969 | | tok::TokenKind EndKind) |
970 | 83 | : TentativeParsingAction(Self), Self(Self), EndKind(EndKind) { |
971 | 83 | // Stash away the old token stream, so we can restore it once the |
972 | 83 | // tentative parse is complete. |
973 | 83 | TentativeParsingAction Inner(Self); |
974 | 83 | Self.ConsumeAndStoreUntil(EndKind, Toks, true, /*ConsumeFinalToken*/false); |
975 | 83 | Inner.Revert(); |
976 | 83 | } |
977 | | |
978 | 57 | void RevertAnnotations() { |
979 | 57 | Revert(); |
980 | 57 | |
981 | 57 | // Put back the original tokens. |
982 | 57 | Self.SkipUntil(EndKind, StopAtSemi | StopBeforeMatch); |
983 | 57 | if (Toks.size()57 ) { |
984 | 57 | auto Buffer = llvm::make_unique<Token[]>(Toks.size()); |
985 | 57 | std::copy(Toks.begin() + 1, Toks.end(), Buffer.get()); |
986 | 57 | Buffer[Toks.size() - 1] = Self.Tok; |
987 | 57 | Self.PP.EnterTokenStream(std::move(Buffer), Toks.size(), true); |
988 | 57 | |
989 | 57 | Self.Tok = Toks.front(); |
990 | 57 | } |
991 | 57 | } |
992 | | |
993 | | private: |
994 | | Parser &Self; |
995 | | CachedTokens Toks; |
996 | | tok::TokenKind EndKind; |
997 | | }; |
998 | | |
999 | | /// ConsumeAndStoreInitializer - Consume and store the token at the passed token |
1000 | | /// container until the end of the current initializer expression (either a |
1001 | | /// default argument or an in-class initializer for a non-static data member). |
1002 | | /// |
1003 | | /// Returns \c true if we reached the end of something initializer-shaped, |
1004 | | /// \c false if we bailed out. |
1005 | | bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks, |
1006 | 12.7k | CachedInitKind CIK) { |
1007 | 12.7k | // We always want this function to consume at least one token if not at EOF. |
1008 | 12.7k | bool IsFirstToken = true; |
1009 | 12.7k | |
1010 | 12.7k | // Number of possible unclosed <s we've seen so far. These might be templates, |
1011 | 12.7k | // and might not, but if there were none of them (or we know for sure that |
1012 | 12.7k | // we're within a template), we can avoid a tentative parse. |
1013 | 12.7k | unsigned AngleCount = 0; |
1014 | 12.7k | unsigned KnownTemplateCount = 0; |
1015 | 12.7k | |
1016 | 41.1k | while (141.1k ) { |
1017 | 41.1k | switch (Tok.getKind()) { |
1018 | 3.09k | case tok::comma: |
1019 | 3.09k | // If we might be in a template, perform a tentative parse to check. |
1020 | 3.09k | if (!AngleCount) |
1021 | 3.09k | // Not a template argument: this is the end of the initializer. |
1022 | 2.99k | return true; |
1023 | 96 | if (96 KnownTemplateCount96 ) |
1024 | 13 | goto consume_token; |
1025 | 83 | |
1026 | 83 | // We hit a comma inside angle brackets. This is the hard case. The |
1027 | 83 | // rule we follow is: |
1028 | 83 | // * For a default argument, if the tokens after the comma form a |
1029 | 83 | // syntactically-valid parameter-declaration-clause, in which each |
1030 | 83 | // parameter has an initializer, then this comma ends the default |
1031 | 83 | // argument. |
1032 | 83 | // * For a default initializer, if the tokens after the comma form a |
1033 | 83 | // syntactically-valid init-declarator-list, then this comma ends |
1034 | 83 | // the default initializer. |
1035 | 83 | { |
1036 | 83 | UnannotatedTentativeParsingAction PA(*this, |
1037 | 83 | CIK == CIK_DefaultInitializer |
1038 | 83 | ? tok::semi36 : tok::r_paren47 ); |
1039 | 83 | Sema::TentativeAnalysisScope Scope(Actions); |
1040 | 83 | |
1041 | 83 | TPResult Result = TPResult::Error; |
1042 | 83 | ConsumeToken(); |
1043 | 83 | switch (CIK) { |
1044 | 36 | case CIK_DefaultInitializer: |
1045 | 36 | Result = TryParseInitDeclaratorList(); |
1046 | 36 | // If we parsed a complete, ambiguous init-declarator-list, this |
1047 | 36 | // is only syntactically-valid if it's followed by a semicolon. |
1048 | 36 | if (Result == TPResult::Ambiguous && 36 Tok.isNot(tok::semi)22 ) |
1049 | 14 | Result = TPResult::False; |
1050 | 36 | break; |
1051 | 83 | |
1052 | 47 | case CIK_DefaultArgument: |
1053 | 47 | bool InvalidAsDeclaration = false; |
1054 | 47 | Result = TryParseParameterDeclarationClause( |
1055 | 47 | &InvalidAsDeclaration, /*VersusTemplateArgument=*/true); |
1056 | 47 | // If this is an expression or a declaration with a missing |
1057 | 47 | // 'typename', assume it's not a declaration. |
1058 | 47 | if (Result == TPResult::Ambiguous && 47 InvalidAsDeclaration0 ) |
1059 | 0 | Result = TPResult::False; |
1060 | 47 | break; |
1061 | 83 | } |
1062 | 83 | |
1063 | 83 | // If what follows could be a declaration, it is a declaration. |
1064 | 83 | if (83 Result != TPResult::False && 83 Result != TPResult::Error32 ) { |
1065 | 26 | PA.Revert(); |
1066 | 26 | return true; |
1067 | 26 | } |
1068 | 57 | |
1069 | 57 | // In the uncommon case that we decide the following tokens are part |
1070 | 57 | // of a template argument, revert any annotations we've performed in |
1071 | 57 | // those tokens. We're not going to look them up until we've parsed |
1072 | 57 | // the rest of the class, and that might add more declarations. |
1073 | 57 | PA.RevertAnnotations(); |
1074 | 57 | } |
1075 | 57 | |
1076 | 57 | // Keep going. We know we're inside a template argument list now. |
1077 | 57 | ++KnownTemplateCount; |
1078 | 57 | goto consume_token; |
1079 | 57 | |
1080 | 1 | case tok::eof: |
1081 | 1 | case tok::annot_module_begin: |
1082 | 1 | case tok::annot_module_end: |
1083 | 1 | case tok::annot_module_include: |
1084 | 1 | // Ran out of tokens. |
1085 | 1 | return false; |
1086 | 1 | |
1087 | 202 | case tok::less: |
1088 | 202 | // FIXME: A '<' can only start a template-id if it's preceded by an |
1089 | 202 | // identifier, an operator-function-id, or a literal-operator-id. |
1090 | 202 | ++AngleCount; |
1091 | 202 | goto consume_token; |
1092 | 1 | |
1093 | 4 | case tok::question: |
1094 | 4 | // In 'a ? b : c', 'b' can contain an unparenthesized comma. If it does, |
1095 | 4 | // that is *never* the end of the initializer. Skip to the ':'. |
1096 | 4 | if (!ConsumeAndStoreConditional(Toks)) |
1097 | 0 | return false; |
1098 | 4 | break; |
1099 | 4 | |
1100 | 0 | case tok::greatergreatergreater: |
1101 | 0 | if (!getLangOpts().CPlusPlus11) |
1102 | 0 | goto consume_token; |
1103 | 0 | if (0 AngleCount0 ) --AngleCount0 ; |
1104 | 0 | if (KnownTemplateCount0 ) --KnownTemplateCount0 ; |
1105 | 0 | // Fall through. |
1106 | 7 | case tok::greatergreater: |
1107 | 7 | if (!getLangOpts().CPlusPlus11) |
1108 | 0 | goto consume_token; |
1109 | 7 | if (7 AngleCount7 ) --AngleCount6 ; |
1110 | 7 | if (KnownTemplateCount7 ) --KnownTemplateCount6 ; |
1111 | 7 | // Fall through. |
1112 | 176 | case tok::greater: |
1113 | 176 | if (AngleCount176 ) --AngleCount166 ; |
1114 | 176 | if (KnownTemplateCount176 ) --KnownTemplateCount55 ; |
1115 | 176 | goto consume_token; |
1116 | 7 | |
1117 | 4 | case tok::kw_template: |
1118 | 4 | // 'template' identifier '<' is known to start a template argument list, |
1119 | 4 | // and can be used to disambiguate the parse. |
1120 | 4 | // FIXME: Support all forms of 'template' unqualified-id '<'. |
1121 | 4 | Toks.push_back(Tok); |
1122 | 4 | ConsumeToken(); |
1123 | 4 | if (Tok.is(tok::identifier)4 ) { |
1124 | 4 | Toks.push_back(Tok); |
1125 | 4 | ConsumeToken(); |
1126 | 4 | if (Tok.is(tok::less)4 ) { |
1127 | 4 | ++AngleCount; |
1128 | 4 | ++KnownTemplateCount; |
1129 | 4 | Toks.push_back(Tok); |
1130 | 4 | ConsumeToken(); |
1131 | 4 | } |
1132 | 4 | } |
1133 | 4 | break; |
1134 | 7 | |
1135 | 20 | case tok::kw_operator: |
1136 | 20 | // If 'operator' precedes other punctuation, that punctuation loses |
1137 | 20 | // its special behavior. |
1138 | 20 | Toks.push_back(Tok); |
1139 | 20 | ConsumeToken(); |
1140 | 20 | switch (Tok.getKind()) { |
1141 | 19 | case tok::comma: |
1142 | 19 | case tok::greatergreatergreater: |
1143 | 19 | case tok::greatergreater: |
1144 | 19 | case tok::greater: |
1145 | 19 | case tok::less: |
1146 | 19 | Toks.push_back(Tok); |
1147 | 19 | ConsumeToken(); |
1148 | 19 | break; |
1149 | 1 | default: |
1150 | 1 | break; |
1151 | 20 | } |
1152 | 20 | break; |
1153 | 20 | |
1154 | 2.21k | case tok::l_paren: |
1155 | 2.21k | // Recursively consume properly-nested parens. |
1156 | 2.21k | Toks.push_back(Tok); |
1157 | 2.21k | ConsumeParen(); |
1158 | 2.21k | ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false); |
1159 | 2.21k | break; |
1160 | 122 | case tok::l_square: |
1161 | 122 | // Recursively consume properly-nested square brackets. |
1162 | 122 | Toks.push_back(Tok); |
1163 | 122 | ConsumeBracket(); |
1164 | 122 | ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false); |
1165 | 122 | break; |
1166 | 226 | case tok::l_brace: |
1167 | 226 | // Recursively consume properly-nested braces. |
1168 | 226 | Toks.push_back(Tok); |
1169 | 226 | ConsumeBrace(); |
1170 | 226 | ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); |
1171 | 226 | break; |
1172 | 20 | |
1173 | 20 | // Okay, we found a ']' or '}' or ')', which we think should be balanced. |
1174 | 20 | // Since the user wasn't looking for this token (if they were, it would |
1175 | 20 | // already be handled), this isn't balanced. If there is a LHS token at a |
1176 | 20 | // higher level, we will assume that this matches the unbalanced token |
1177 | 20 | // and return it. Otherwise, this is a spurious RHS token, which we |
1178 | 20 | // consume and pass on to downstream code to diagnose. |
1179 | 8.88k | case tok::r_paren: |
1180 | 8.88k | if (CIK == CIK_DefaultArgument) |
1181 | 8.88k | return true; // End of the default argument. |
1182 | 6 | if (6 ParenCount && 6 !IsFirstToken0 ) |
1183 | 0 | return false; |
1184 | 6 | Toks.push_back(Tok); |
1185 | 6 | ConsumeParen(); |
1186 | 6 | continue; |
1187 | 6 | case tok::r_square: |
1188 | 6 | if (BracketCount && 6 !IsFirstToken0 ) |
1189 | 0 | return false; |
1190 | 6 | Toks.push_back(Tok); |
1191 | 6 | ConsumeBracket(); |
1192 | 6 | continue; |
1193 | 6 | case tok::r_brace: |
1194 | 6 | if (BraceCount && 6 !IsFirstToken6 ) |
1195 | 3 | return false; |
1196 | 3 | Toks.push_back(Tok); |
1197 | 3 | ConsumeBrace(); |
1198 | 3 | continue; |
1199 | 3 | |
1200 | 0 | case tok::code_completion: |
1201 | 0 | Toks.push_back(Tok); |
1202 | 0 | ConsumeCodeCompletionToken(); |
1203 | 0 | break; |
1204 | 3 | |
1205 | 31 | case tok::string_literal: |
1206 | 31 | case tok::wide_string_literal: |
1207 | 31 | case tok::utf8_string_literal: |
1208 | 31 | case tok::utf16_string_literal: |
1209 | 31 | case tok::utf32_string_literal: |
1210 | 31 | Toks.push_back(Tok); |
1211 | 31 | ConsumeStringToken(); |
1212 | 31 | break; |
1213 | 855 | case tok::semi: |
1214 | 855 | if (CIK == CIK_DefaultInitializer) |
1215 | 855 | return true; // End of the default initializer. |
1216 | 0 | // FALL THROUGH. |
1217 | 25.3k | default: |
1218 | 25.7k | consume_token: |
1219 | 25.7k | Toks.push_back(Tok); |
1220 | 25.7k | ConsumeToken(); |
1221 | 25.7k | break; |
1222 | 28.3k | } |
1223 | 28.3k | IsFirstToken = false; |
1224 | 28.3k | } |
1225 | 12.7k | } |