Mercurial > hg > CbC > CbC_llvm
comparison clang/lib/Parse/ParseCXXInlineMethods.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | 5f17cb93ff66 |
comparison
equal
deleted
inserted
replaced
173:0572611fdcc8 | 207:2e18cbf3894f |
---|---|
106 | 106 |
107 // In delayed template parsing mode, if we are within a class template | 107 // In delayed template parsing mode, if we are within a class template |
108 // or if we are about to parse function member template then consume | 108 // or if we are about to parse function member template then consume |
109 // the tokens and store them for parsing at the end of the translation unit. | 109 // the tokens and store them for parsing at the end of the translation unit. |
110 if (getLangOpts().DelayedTemplateParsing && | 110 if (getLangOpts().DelayedTemplateParsing && |
111 D.getFunctionDefinitionKind() == FDK_Definition && | 111 D.getFunctionDefinitionKind() == FunctionDefinitionKind::Definition && |
112 !D.getDeclSpec().hasConstexprSpecifier() && | 112 !D.getDeclSpec().hasConstexprSpecifier() && |
113 !(FnD && FnD->getAsFunction() && | 113 !(FnD && FnD->getAsFunction() && |
114 FnD->getAsFunction()->getReturnType()->getContainedAutoType()) && | 114 FnD->getAsFunction()->getReturnType()->getContainedAutoType()) && |
115 ((Actions.CurContext->isDependentContext() || | 115 ((Actions.CurContext->isDependentContext() || |
116 (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && | 116 (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && |
131 | 131 |
132 // Consume the tokens and store them for later parsing. | 132 // Consume the tokens and store them for later parsing. |
133 | 133 |
134 LexedMethod* LM = new LexedMethod(this, FnD); | 134 LexedMethod* LM = new LexedMethod(this, FnD); |
135 getCurrentClass().LateParsedDeclarations.push_back(LM); | 135 getCurrentClass().LateParsedDeclarations.push_back(LM); |
136 LM->TemplateScope = getCurScope()->isTemplateParamScope() || | |
137 (FnD && isa<FunctionTemplateDecl>(FnD) && | |
138 cast<FunctionTemplateDecl>(FnD)->isAbbreviated()); | |
139 CachedTokens &Toks = LM->Toks; | 136 CachedTokens &Toks = LM->Toks; |
140 | 137 |
141 tok::TokenKind kind = Tok.getKind(); | 138 tok::TokenKind kind = Tok.getKind(); |
142 // Consume everything up to (and including) the left brace of the | 139 // Consume everything up to (and including) the left brace of the |
143 // function body. | 140 // function body. |
223 | 220 |
224 Parser::LateParsedDeclaration::~LateParsedDeclaration() {} | 221 Parser::LateParsedDeclaration::~LateParsedDeclaration() {} |
225 void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {} | 222 void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {} |
226 void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {} | 223 void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {} |
227 void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {} | 224 void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {} |
225 void Parser::LateParsedDeclaration::ParseLexedAttributes() {} | |
228 void Parser::LateParsedDeclaration::ParseLexedPragmas() {} | 226 void Parser::LateParsedDeclaration::ParseLexedPragmas() {} |
229 | 227 |
230 Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C) | 228 Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C) |
231 : Self(P), Class(C) {} | 229 : Self(P), Class(C) {} |
232 | 230 |
244 | 242 |
245 void Parser::LateParsedClass::ParseLexedMethodDefs() { | 243 void Parser::LateParsedClass::ParseLexedMethodDefs() { |
246 Self->ParseLexedMethodDefs(*Class); | 244 Self->ParseLexedMethodDefs(*Class); |
247 } | 245 } |
248 | 246 |
247 void Parser::LateParsedClass::ParseLexedAttributes() { | |
248 Self->ParseLexedAttributes(*Class); | |
249 } | |
250 | |
249 void Parser::LateParsedClass::ParseLexedPragmas() { | 251 void Parser::LateParsedClass::ParseLexedPragmas() { |
250 Self->ParseLexedPragmas(*Class); | 252 Self->ParseLexedPragmas(*Class); |
251 } | 253 } |
252 | 254 |
253 void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() { | 255 void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() { |
260 | 262 |
261 void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() { | 263 void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() { |
262 Self->ParseLexedMemberInitializer(*this); | 264 Self->ParseLexedMemberInitializer(*this); |
263 } | 265 } |
264 | 266 |
267 void Parser::LateParsedAttribute::ParseLexedAttributes() { | |
268 Self->ParseLexedAttribute(*this, true, false); | |
269 } | |
270 | |
265 void Parser::LateParsedPragma::ParseLexedPragmas() { | 271 void Parser::LateParsedPragma::ParseLexedPragmas() { |
266 Self->ParseLexedPragma(*this); | 272 Self->ParseLexedPragma(*this); |
267 } | 273 } |
274 | |
275 /// Utility to re-enter a possibly-templated scope while parsing its | |
276 /// late-parsed components. | |
277 struct Parser::ReenterTemplateScopeRAII { | |
278 Parser &P; | |
279 MultiParseScope Scopes; | |
280 TemplateParameterDepthRAII CurTemplateDepthTracker; | |
281 | |
282 ReenterTemplateScopeRAII(Parser &P, Decl *MaybeTemplated, bool Enter = true) | |
283 : P(P), Scopes(P), CurTemplateDepthTracker(P.TemplateParameterDepth) { | |
284 if (Enter) { | |
285 CurTemplateDepthTracker.addDepth( | |
286 P.ReenterTemplateScopes(Scopes, MaybeTemplated)); | |
287 } | |
288 } | |
289 }; | |
290 | |
291 /// Utility to re-enter a class scope while parsing its late-parsed components. | |
292 struct Parser::ReenterClassScopeRAII : ReenterTemplateScopeRAII { | |
293 ParsingClass &Class; | |
294 | |
295 ReenterClassScopeRAII(Parser &P, ParsingClass &Class) | |
296 : ReenterTemplateScopeRAII(P, Class.TagOrTemplate, | |
297 /*Enter=*/!Class.TopLevelClass), | |
298 Class(Class) { | |
299 // If this is the top-level class, we're still within its scope. | |
300 if (Class.TopLevelClass) | |
301 return; | |
302 | |
303 // Re-enter the class scope itself. | |
304 Scopes.Enter(Scope::ClassScope|Scope::DeclScope); | |
305 P.Actions.ActOnStartDelayedMemberDeclarations(P.getCurScope(), | |
306 Class.TagOrTemplate); | |
307 } | |
308 ~ReenterClassScopeRAII() { | |
309 if (Class.TopLevelClass) | |
310 return; | |
311 | |
312 P.Actions.ActOnFinishDelayedMemberDeclarations(P.getCurScope(), | |
313 Class.TagOrTemplate); | |
314 } | |
315 }; | |
268 | 316 |
269 /// ParseLexedMethodDeclarations - We finished parsing the member | 317 /// ParseLexedMethodDeclarations - We finished parsing the member |
270 /// specification of a top (non-nested) C++ class. Now go over the | 318 /// specification of a top (non-nested) C++ class. Now go over the |
271 /// stack of method declarations with some parts for which parsing was | 319 /// stack of method declarations with some parts for which parsing was |
272 /// delayed (such as default arguments) and parse them. | 320 /// delayed (such as default arguments) and parse them. |
273 void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { | 321 void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { |
274 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; | 322 ReenterClassScopeRAII InClassScope(*this, Class); |
275 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, | 323 |
276 HasTemplateScope); | 324 for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations) |
277 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); | 325 LateD->ParseLexedMethodDeclarations(); |
278 if (HasTemplateScope) { | |
279 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); | |
280 ++CurTemplateDepthTracker; | |
281 } | |
282 | |
283 // The current scope is still active if we're the top-level class. | |
284 // Otherwise we'll need to push and enter a new scope. | |
285 bool HasClassScope = !Class.TopLevelClass; | |
286 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, | |
287 HasClassScope); | |
288 if (HasClassScope) | |
289 Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), | |
290 Class.TagOrTemplate); | |
291 | |
292 for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { | |
293 Class.LateParsedDeclarations[i]->ParseLexedMethodDeclarations(); | |
294 } | |
295 | |
296 if (HasClassScope) | |
297 Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), | |
298 Class.TagOrTemplate); | |
299 } | 326 } |
300 | 327 |
301 void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { | 328 void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { |
302 // If this is a member template, introduce the template parameter scope. | 329 // If this is a member template, introduce the template parameter scope. |
303 ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); | 330 ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.Method); |
304 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); | 331 |
305 if (LM.TemplateScope) { | |
306 Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method); | |
307 ++CurTemplateDepthTracker; | |
308 } | |
309 // Start the delayed C++ method declaration | 332 // Start the delayed C++ method declaration |
310 Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method); | 333 Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method); |
311 | 334 |
312 // Introduce the parameters into scope and parse their default | 335 // Introduce the parameters into scope and parse their default |
313 // arguments. | 336 // arguments. |
314 ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope | | 337 InFunctionTemplateScope.Scopes.Enter(Scope::FunctionPrototypeScope | |
315 Scope::FunctionDeclarationScope | Scope::DeclScope); | 338 Scope::FunctionDeclarationScope | |
339 Scope::DeclScope); | |
316 for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) { | 340 for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) { |
317 auto Param = cast<ParmVarDecl>(LM.DefaultArgs[I].Param); | 341 auto Param = cast<ParmVarDecl>(LM.DefaultArgs[I].Param); |
318 // Introduce the parameter into scope. | 342 // Introduce the parameter into scope. |
319 bool HasUnparsed = Param->hasUnparsedDefaultArg(); | 343 bool HasUnparsed = Param->hasUnparsedDefaultArg(); |
320 Actions.ActOnDelayedCXXMethodParameter(getCurScope(), Param); | 344 Actions.ActOnDelayedCXXMethodParameter(getCurScope(), Param); |
379 | 403 |
380 if (Tok.is(tok::eof) && Tok.getEofData() == Param) | 404 if (Tok.is(tok::eof) && Tok.getEofData() == Param) |
381 ConsumeAnyToken(); | 405 ConsumeAnyToken(); |
382 } else if (HasUnparsed) { | 406 } else if (HasUnparsed) { |
383 assert(Param->hasInheritedDefaultArg()); | 407 assert(Param->hasInheritedDefaultArg()); |
384 FunctionDecl *Old = cast<FunctionDecl>(LM.Method)->getPreviousDecl(); | 408 const FunctionDecl *Old; |
385 ParmVarDecl *OldParam = Old->getParamDecl(I); | 409 if (const auto *FunTmpl = dyn_cast<FunctionTemplateDecl>(LM.Method)) |
386 assert (!OldParam->hasUnparsedDefaultArg()); | 410 Old = |
387 if (OldParam->hasUninstantiatedDefaultArg()) | 411 cast<FunctionDecl>(FunTmpl->getTemplatedDecl())->getPreviousDecl(); |
388 Param->setUninstantiatedDefaultArg( | |
389 OldParam->getUninstantiatedDefaultArg()); | |
390 else | 412 else |
391 Param->setDefaultArg(OldParam->getInit()); | 413 Old = cast<FunctionDecl>(LM.Method)->getPreviousDecl(); |
414 if (Old) { | |
415 ParmVarDecl *OldParam = const_cast<ParmVarDecl*>(Old->getParamDecl(I)); | |
416 assert(!OldParam->hasUnparsedDefaultArg()); | |
417 if (OldParam->hasUninstantiatedDefaultArg()) | |
418 Param->setUninstantiatedDefaultArg( | |
419 OldParam->getUninstantiatedDefaultArg()); | |
420 else | |
421 Param->setDefaultArg(OldParam->getInit()); | |
422 } | |
392 } | 423 } |
393 } | 424 } |
394 | 425 |
395 // Parse a delayed exception-specification, if there is one. | 426 // Parse a delayed exception-specification, if there is one. |
396 if (CachedTokens *Toks = LM.ExceptionSpecTokens) { | 427 if (CachedTokens *Toks = LM.ExceptionSpecTokens) { |
464 | 495 |
465 delete Toks; | 496 delete Toks; |
466 LM.ExceptionSpecTokens = nullptr; | 497 LM.ExceptionSpecTokens = nullptr; |
467 } | 498 } |
468 | 499 |
469 PrototypeScope.Exit(); | 500 InFunctionTemplateScope.Scopes.Exit(); |
470 | 501 |
471 // Finish the delayed C++ method declaration. | 502 // Finish the delayed C++ method declaration. |
472 Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method); | 503 Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method); |
473 } | 504 } |
474 | 505 |
475 /// ParseLexedMethodDefs - We finished parsing the member specification of a top | 506 /// ParseLexedMethodDefs - We finished parsing the member specification of a top |
476 /// (non-nested) C++ class. Now go over the stack of lexed methods that were | 507 /// (non-nested) C++ class. Now go over the stack of lexed methods that were |
477 /// collected during its parsing and parse them all. | 508 /// collected during its parsing and parse them all. |
478 void Parser::ParseLexedMethodDefs(ParsingClass &Class) { | 509 void Parser::ParseLexedMethodDefs(ParsingClass &Class) { |
479 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; | 510 ReenterClassScopeRAII InClassScope(*this, Class); |
480 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope); | 511 |
481 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); | 512 for (LateParsedDeclaration *D : Class.LateParsedDeclarations) |
482 if (HasTemplateScope) { | 513 D->ParseLexedMethodDefs(); |
483 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); | |
484 ++CurTemplateDepthTracker; | |
485 } | |
486 bool HasClassScope = !Class.TopLevelClass; | |
487 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, | |
488 HasClassScope); | |
489 | |
490 for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { | |
491 Class.LateParsedDeclarations[i]->ParseLexedMethodDefs(); | |
492 } | |
493 } | 514 } |
494 | 515 |
495 void Parser::ParseLexedMethodDef(LexedMethod &LM) { | 516 void Parser::ParseLexedMethodDef(LexedMethod &LM) { |
496 // If this is a member template, introduce the template parameter scope. | 517 // If this is a member template, introduce the template parameter scope. |
497 ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); | 518 ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.D); |
498 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); | |
499 if (LM.TemplateScope) { | |
500 Actions.ActOnReenterTemplateScope(getCurScope(), LM.D); | |
501 ++CurTemplateDepthTracker; | |
502 } | |
503 | 519 |
504 ParenBraceBracketBalancer BalancerRAIIObj(*this); | 520 ParenBraceBracketBalancer BalancerRAIIObj(*this); |
505 | 521 |
506 assert(!LM.Toks.empty() && "Empty body!"); | 522 assert(!LM.Toks.empty() && "Empty body!"); |
507 Token LastBodyToken = LM.Toks.back(); | 523 Token LastBodyToken = LM.Toks.back(); |
578 | 594 |
579 /// ParseLexedMemberInitializers - We finished parsing the member specification | 595 /// ParseLexedMemberInitializers - We finished parsing the member specification |
580 /// of a top (non-nested) C++ class. Now go over the stack of lexed data member | 596 /// of a top (non-nested) C++ class. Now go over the stack of lexed data member |
581 /// initializers that were collected during its parsing and parse them all. | 597 /// initializers that were collected during its parsing and parse them all. |
582 void Parser::ParseLexedMemberInitializers(ParsingClass &Class) { | 598 void Parser::ParseLexedMemberInitializers(ParsingClass &Class) { |
583 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; | 599 ReenterClassScopeRAII InClassScope(*this, Class); |
584 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, | |
585 HasTemplateScope); | |
586 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); | |
587 if (HasTemplateScope) { | |
588 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); | |
589 ++CurTemplateDepthTracker; | |
590 } | |
591 // Set or update the scope flags. | |
592 bool AlreadyHasClassScope = Class.TopLevelClass; | |
593 unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; | |
594 ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); | |
595 ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); | |
596 | |
597 if (!AlreadyHasClassScope) | |
598 Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), | |
599 Class.TagOrTemplate); | |
600 | 600 |
601 if (!Class.LateParsedDeclarations.empty()) { | 601 if (!Class.LateParsedDeclarations.empty()) { |
602 // C++11 [expr.prim.general]p4: | 602 // C++11 [expr.prim.general]p4: |
603 // Otherwise, if a member-declarator declares a non-static data member | 603 // Otherwise, if a member-declarator declares a non-static data member |
604 // (9.2) of a class X, the expression this is a prvalue of type "pointer | 604 // (9.2) of a class X, the expression this is a prvalue of type "pointer |
605 // to X" within the optional brace-or-equal-initializer. It shall not | 605 // to X" within the optional brace-or-equal-initializer. It shall not |
606 // appear elsewhere in the member-declarator. | 606 // appear elsewhere in the member-declarator. |
607 // FIXME: This should be done in ParseLexedMemberInitializer, not here. | |
607 Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate, | 608 Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate, |
608 Qualifiers()); | 609 Qualifiers()); |
609 | 610 |
610 for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { | 611 for (LateParsedDeclaration *D : Class.LateParsedDeclarations) |
611 Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers(); | 612 D->ParseLexedMemberInitializers(); |
612 } | 613 } |
613 } | |
614 | |
615 if (!AlreadyHasClassScope) | |
616 Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), | |
617 Class.TagOrTemplate); | |
618 | 614 |
619 Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate); | 615 Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate); |
620 } | 616 } |
621 | 617 |
622 void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { | 618 void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { |
660 // Make sure this is *our* artificial EOF token. | 656 // Make sure this is *our* artificial EOF token. |
661 if (Tok.getEofData() == MI.Field) | 657 if (Tok.getEofData() == MI.Field) |
662 ConsumeAnyToken(); | 658 ConsumeAnyToken(); |
663 } | 659 } |
664 | 660 |
661 /// Wrapper class which calls ParseLexedAttribute, after setting up the | |
662 /// scope appropriately. | |
663 void Parser::ParseLexedAttributes(ParsingClass &Class) { | |
664 ReenterClassScopeRAII InClassScope(*this, Class); | |
665 | |
666 for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations) | |
667 LateD->ParseLexedAttributes(); | |
668 } | |
669 | |
670 /// Parse all attributes in LAs, and attach them to Decl D. | |
671 void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, | |
672 bool EnterScope, bool OnDefinition) { | |
673 assert(LAs.parseSoon() && | |
674 "Attribute list should be marked for immediate parsing."); | |
675 for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { | |
676 if (D) | |
677 LAs[i]->addDecl(D); | |
678 ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); | |
679 delete LAs[i]; | |
680 } | |
681 LAs.clear(); | |
682 } | |
683 | |
684 /// Finish parsing an attribute for which parsing was delayed. | |
685 /// This will be called at the end of parsing a class declaration | |
686 /// for each LateParsedAttribute. We consume the saved tokens and | |
687 /// create an attribute with the arguments filled in. We add this | |
688 /// to the Attribute list for the decl. | |
689 void Parser::ParseLexedAttribute(LateParsedAttribute &LA, | |
690 bool EnterScope, bool OnDefinition) { | |
691 // Create a fake EOF so that attribute parsing won't go off the end of the | |
692 // attribute. | |
693 Token AttrEnd; | |
694 AttrEnd.startToken(); | |
695 AttrEnd.setKind(tok::eof); | |
696 AttrEnd.setLocation(Tok.getLocation()); | |
697 AttrEnd.setEofData(LA.Toks.data()); | |
698 LA.Toks.push_back(AttrEnd); | |
699 | |
700 // Append the current token at the end of the new token stream so that it | |
701 // doesn't get lost. | |
702 LA.Toks.push_back(Tok); | |
703 PP.EnterTokenStream(LA.Toks, true, /*IsReinject=*/true); | |
704 // Consume the previously pushed token. | |
705 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); | |
706 | |
707 ParsedAttributes Attrs(AttrFactory); | |
708 SourceLocation endLoc; | |
709 | |
710 if (LA.Decls.size() > 0) { | |
711 Decl *D = LA.Decls[0]; | |
712 NamedDecl *ND = dyn_cast<NamedDecl>(D); | |
713 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); | |
714 | |
715 // Allow 'this' within late-parsed attributes. | |
716 Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(), | |
717 ND && ND->isCXXInstanceMember()); | |
718 | |
719 if (LA.Decls.size() == 1) { | |
720 // If the Decl is templatized, add template parameters to scope. | |
721 ReenterTemplateScopeRAII InDeclScope(*this, D, EnterScope); | |
722 | |
723 // If the Decl is on a function, add function parameters to the scope. | |
724 bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); | |
725 if (HasFunScope) { | |
726 InDeclScope.Scopes.Enter(Scope::FnScope | Scope::DeclScope | | |
727 Scope::CompoundStmtScope); | |
728 Actions.ActOnReenterFunctionContext(Actions.CurScope, D); | |
729 } | |
730 | |
731 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, | |
732 nullptr, SourceLocation(), ParsedAttr::AS_GNU, | |
733 nullptr); | |
734 | |
735 if (HasFunScope) | |
736 Actions.ActOnExitFunctionContext(); | |
737 } else { | |
738 // If there are multiple decls, then the decl cannot be within the | |
739 // function scope. | |
740 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, | |
741 nullptr, SourceLocation(), ParsedAttr::AS_GNU, | |
742 nullptr); | |
743 } | |
744 } else { | |
745 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); | |
746 } | |
747 | |
748 if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() && | |
749 Attrs.begin()->isKnownToGCC()) | |
750 Diag(Tok, diag::warn_attribute_on_function_definition) | |
751 << &LA.AttrName; | |
752 | |
753 for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) | |
754 Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs); | |
755 | |
756 // Due to a parsing error, we either went over the cached tokens or | |
757 // there are still cached tokens left, so we skip the leftover tokens. | |
758 while (Tok.isNot(tok::eof)) | |
759 ConsumeAnyToken(); | |
760 | |
761 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()) | |
762 ConsumeAnyToken(); | |
763 } | |
764 | |
665 void Parser::ParseLexedPragmas(ParsingClass &Class) { | 765 void Parser::ParseLexedPragmas(ParsingClass &Class) { |
666 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; | 766 ReenterClassScopeRAII InClassScope(*this, Class); |
667 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, | 767 |
668 HasTemplateScope); | 768 for (LateParsedDeclaration *D : Class.LateParsedDeclarations) |
669 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); | 769 D->ParseLexedPragmas(); |
670 if (HasTemplateScope) { | |
671 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); | |
672 ++CurTemplateDepthTracker; | |
673 } | |
674 bool HasClassScope = !Class.TopLevelClass; | |
675 ParseScope ClassScope(this, Scope::ClassScope | Scope::DeclScope, | |
676 HasClassScope); | |
677 | |
678 for (LateParsedDeclaration *LPD : Class.LateParsedDeclarations) | |
679 LPD->ParseLexedPragmas(); | |
680 } | 770 } |
681 | 771 |
682 void Parser::ParseLexedPragma(LateParsedPragma &LP) { | 772 void Parser::ParseLexedPragma(LateParsedPragma &LP) { |
683 PP.EnterToken(Tok, /*IsReinject=*/true); | 773 PP.EnterToken(Tok, /*IsReinject=*/true); |
684 PP.EnterTokenStream(LP.toks(), /*DisableMacroExpansion=*/true, | 774 PP.EnterTokenStream(LP.toks(), /*DisableMacroExpansion=*/true, |