Mercurial > hg > CbC > CbC_llvm
comparison clang/lib/Parse/ParseDeclCXX.cpp @ 252:1f2b6ac9f198 llvm-original
LLVM16-1
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 18 Aug 2023 09:04:13 +0900 |
parents | c4bab56944e8 |
children |
comparison
equal
deleted
inserted
replaced
237:c80f45b162ad | 252:1f2b6ac9f198 |
---|---|
17 #include "clang/Basic/Attributes.h" | 17 #include "clang/Basic/Attributes.h" |
18 #include "clang/Basic/CharInfo.h" | 18 #include "clang/Basic/CharInfo.h" |
19 #include "clang/Basic/OperatorKinds.h" | 19 #include "clang/Basic/OperatorKinds.h" |
20 #include "clang/Basic/TargetInfo.h" | 20 #include "clang/Basic/TargetInfo.h" |
21 #include "clang/Basic/TokenKinds.h" | 21 #include "clang/Basic/TokenKinds.h" |
22 #include "clang/Lex/LiteralSupport.h" | |
22 #include "clang/Parse/ParseDiagnostic.h" | 23 #include "clang/Parse/ParseDiagnostic.h" |
23 #include "clang/Parse/Parser.h" | 24 #include "clang/Parse/Parser.h" |
24 #include "clang/Parse/RAIIObjectsForParser.h" | 25 #include "clang/Parse/RAIIObjectsForParser.h" |
25 #include "clang/Sema/DeclSpec.h" | 26 #include "clang/Sema/DeclSpec.h" |
27 #include "clang/Sema/EnterExpressionEvaluationContext.h" | |
26 #include "clang/Sema/ParsedTemplate.h" | 28 #include "clang/Sema/ParsedTemplate.h" |
27 #include "clang/Sema/Scope.h" | 29 #include "clang/Sema/Scope.h" |
28 #include "llvm/ADT/SmallString.h" | 30 #include "llvm/ADT/SmallString.h" |
29 #include "llvm/Support/TimeProfiler.h" | 31 #include "llvm/Support/TimeProfiler.h" |
32 #include <optional> | |
30 | 33 |
31 using namespace clang; | 34 using namespace clang; |
32 | 35 |
33 /// ParseNamespace - We know that the current token is a namespace keyword. This | 36 /// ParseNamespace - We know that the current token is a namespace keyword. This |
34 /// may either be a top level namespace or a block-level namespace alias. If | 37 /// may either be a top level namespace or a block-level namespace alias. If |
225 ParseScope NamespaceScope(this, Scope::DeclScope); | 228 ParseScope NamespaceScope(this, Scope::DeclScope); |
226 | 229 |
227 UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; | 230 UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; |
228 Decl *NamespcDecl = Actions.ActOnStartNamespaceDef( | 231 Decl *NamespcDecl = Actions.ActOnStartNamespaceDef( |
229 getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident, | 232 getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident, |
230 T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl); | 233 T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, false); |
231 | 234 |
232 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl, | 235 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl, |
233 NamespaceLoc, "parsing namespace"); | 236 NamespaceLoc, "parsing namespace"); |
234 | 237 |
235 // Parse the contents of the namespace. This includes parsing recovery on | 238 // Parse the contents of the namespace. This includes parsing recovery on |
252 ParsedAttributes &attrs, | 255 ParsedAttributes &attrs, |
253 BalancedDelimiterTracker &Tracker) { | 256 BalancedDelimiterTracker &Tracker) { |
254 if (index == InnerNSs.size()) { | 257 if (index == InnerNSs.size()) { |
255 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && | 258 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && |
256 Tok.isNot(tok::eof)) { | 259 Tok.isNot(tok::eof)) { |
257 ParsedAttributes Attrs(AttrFactory); | 260 ParsedAttributes DeclAttrs(AttrFactory); |
258 MaybeParseCXX11Attributes(Attrs); | 261 MaybeParseCXX11Attributes(DeclAttrs); |
259 ParseExternalDeclaration(Attrs); | 262 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory); |
263 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs); | |
260 } | 264 } |
261 | 265 |
262 // The caller is what called check -- we are simply calling | 266 // The caller is what called check -- we are simply calling |
263 // the close for it. | 267 // the close for it. |
264 Tracker.consumeClose(); | 268 Tracker.consumeClose(); |
272 ParseScope NamespaceScope(this, Scope::DeclScope); | 276 ParseScope NamespaceScope(this, Scope::DeclScope); |
273 UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; | 277 UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; |
274 Decl *NamespcDecl = Actions.ActOnStartNamespaceDef( | 278 Decl *NamespcDecl = Actions.ActOnStartNamespaceDef( |
275 getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc, | 279 getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc, |
276 InnerNSs[index].IdentLoc, InnerNSs[index].Ident, | 280 InnerNSs[index].IdentLoc, InnerNSs[index].Ident, |
277 Tracker.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl); | 281 Tracker.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, true); |
278 assert(!ImplicitUsingDirectiveDecl && | 282 assert(!ImplicitUsingDirectiveDecl && |
279 "nested namespace definition cannot define anonymous namespace"); | 283 "nested namespace definition cannot define anonymous namespace"); |
280 | 284 |
281 ParseInnerNamespace(InnerNSs, ++index, InlineLoc, attrs, Tracker); | 285 ParseInnerNamespace(InnerNSs, ++index, InlineLoc, attrs, Tracker); |
282 | 286 |
345 /// 'extern' string-literal '{' declaration-seq[opt] '}' | 349 /// 'extern' string-literal '{' declaration-seq[opt] '}' |
346 /// 'extern' string-literal declaration | 350 /// 'extern' string-literal declaration |
347 /// | 351 /// |
348 Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) { | 352 Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) { |
349 assert(isTokenStringLiteral() && "Not a string literal!"); | 353 assert(isTokenStringLiteral() && "Not a string literal!"); |
350 ExprResult Lang = ParseStringLiteralExpression(false); | 354 ExprResult Lang = ParseUnevaluatedStringLiteralExpression(); |
351 | 355 |
352 ParseScope LinkageScope(this, Scope::DeclScope); | 356 ParseScope LinkageScope(this, Scope::DeclScope); |
353 Decl *LinkageSpec = | 357 Decl *LinkageSpec = |
354 Lang.isInvalid() | 358 Lang.isInvalid() |
355 ? nullptr | 359 ? nullptr |
356 : Actions.ActOnStartLinkageSpecification( | 360 : Actions.ActOnStartLinkageSpecification( |
357 getCurScope(), DS.getSourceRange().getBegin(), Lang.get(), | 361 getCurScope(), DS.getSourceRange().getBegin(), Lang.get(), |
358 Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation()); | 362 Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation()); |
359 | 363 |
360 ParsedAttributes DeclAttrs(AttrFactory); | 364 ParsedAttributes DeclAttrs(AttrFactory); |
361 MaybeParseCXX11Attributes(DeclAttrs); | 365 ParsedAttributes DeclSpecAttrs(AttrFactory); |
366 | |
367 while (MaybeParseCXX11Attributes(DeclAttrs) || | |
368 MaybeParseGNUAttributes(DeclSpecAttrs)) | |
369 ; | |
362 | 370 |
363 if (Tok.isNot(tok::l_brace)) { | 371 if (Tok.isNot(tok::l_brace)) { |
364 // Reset the source range in DS, as the leading "extern" | 372 // Reset the source range in DS, as the leading "extern" |
365 // does not really belong to the inner declaration ... | 373 // does not really belong to the inner declaration ... |
366 DS.SetRangeStart(SourceLocation()); | 374 DS.SetRangeStart(SourceLocation()); |
367 DS.SetRangeEnd(SourceLocation()); | 375 DS.SetRangeEnd(SourceLocation()); |
368 // ... but anyway remember that such an "extern" was seen. | 376 // ... but anyway remember that such an "extern" was seen. |
369 DS.setExternInLinkageSpec(true); | 377 DS.setExternInLinkageSpec(true); |
370 ParseExternalDeclaration(DeclAttrs, &DS); | 378 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs, &DS); |
371 return LinkageSpec ? Actions.ActOnFinishLinkageSpecification( | 379 return LinkageSpec ? Actions.ActOnFinishLinkageSpecification( |
372 getCurScope(), LinkageSpec, SourceLocation()) | 380 getCurScope(), LinkageSpec, SourceLocation()) |
373 : nullptr; | 381 : nullptr; |
374 } | 382 } |
375 | 383 |
405 case tok::r_brace: | 413 case tok::r_brace: |
406 if (!NestedModules) | 414 if (!NestedModules) |
407 break; | 415 break; |
408 [[fallthrough]]; | 416 [[fallthrough]]; |
409 default: | 417 default: |
410 ParsedAttributes Attrs(AttrFactory); | 418 ParsedAttributes DeclAttrs(AttrFactory); |
411 MaybeParseCXX11Attributes(Attrs); | 419 MaybeParseCXX11Attributes(DeclAttrs); |
412 ParseExternalDeclaration(Attrs); | 420 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs); |
413 continue; | 421 continue; |
414 } | 422 } |
415 | 423 |
416 break; | 424 break; |
417 } | 425 } |
420 return LinkageSpec ? Actions.ActOnFinishLinkageSpecification( | 428 return LinkageSpec ? Actions.ActOnFinishLinkageSpecification( |
421 getCurScope(), LinkageSpec, T.getCloseLocation()) | 429 getCurScope(), LinkageSpec, T.getCloseLocation()) |
422 : nullptr; | 430 : nullptr; |
423 } | 431 } |
424 | 432 |
425 /// Parse a C++ Modules TS export-declaration. | 433 /// Parse a standard C++ Modules export-declaration. |
426 /// | 434 /// |
427 /// export-declaration: | 435 /// export-declaration: |
428 /// 'export' declaration | 436 /// 'export' declaration |
429 /// 'export' '{' declaration-seq[opt] '}' | 437 /// 'export' '{' declaration-seq[opt] '}' |
430 /// | 438 /// |
437 getCurScope(), ExportLoc, | 445 getCurScope(), ExportLoc, |
438 Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation()); | 446 Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation()); |
439 | 447 |
440 if (Tok.isNot(tok::l_brace)) { | 448 if (Tok.isNot(tok::l_brace)) { |
441 // FIXME: Factor out a ParseExternalDeclarationWithAttrs. | 449 // FIXME: Factor out a ParseExternalDeclarationWithAttrs. |
442 ParsedAttributes Attrs(AttrFactory); | 450 ParsedAttributes DeclAttrs(AttrFactory); |
443 MaybeParseCXX11Attributes(Attrs); | 451 MaybeParseCXX11Attributes(DeclAttrs); |
444 ParseExternalDeclaration(Attrs); | 452 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory); |
453 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs); | |
445 return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl, | 454 return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl, |
446 SourceLocation()); | 455 SourceLocation()); |
447 } | 456 } |
448 | 457 |
449 BalancedDelimiterTracker T(*this, tok::l_brace); | 458 BalancedDelimiterTracker T(*this, tok::l_brace); |
450 T.consumeOpen(); | 459 T.consumeOpen(); |
451 | 460 |
452 // The Modules TS draft says "An export-declaration shall declare at least one | |
453 // entity", but the intent is that it shall contain at least one declaration. | |
454 if (Tok.is(tok::r_brace) && getLangOpts().ModulesTS) { | |
455 Diag(ExportLoc, diag::err_export_empty) | |
456 << SourceRange(ExportLoc, Tok.getLocation()); | |
457 } | |
458 | |
459 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && | 461 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && |
460 Tok.isNot(tok::eof)) { | 462 Tok.isNot(tok::eof)) { |
461 ParsedAttributes Attrs(AttrFactory); | 463 ParsedAttributes DeclAttrs(AttrFactory); |
462 MaybeParseCXX11Attributes(Attrs); | 464 MaybeParseCXX11Attributes(DeclAttrs); |
463 ParseExternalDeclaration(Attrs); | 465 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory); |
466 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs); | |
464 } | 467 } |
465 | 468 |
466 T.consumeClose(); | 469 T.consumeClose(); |
467 return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl, | 470 return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl, |
468 T.getCloseLocation()); | 471 T.getCloseLocation()); |
631 // constructor. | 634 // constructor. |
632 if (getLangOpts().CPlusPlus11 && Context == DeclaratorContext::Member && | 635 if (getLangOpts().CPlusPlus11 && Context == DeclaratorContext::Member && |
633 Tok.is(tok::identifier) && | 636 Tok.is(tok::identifier) && |
634 (NextToken().is(tok::semi) || NextToken().is(tok::comma) || | 637 (NextToken().is(tok::semi) || NextToken().is(tok::comma) || |
635 NextToken().is(tok::ellipsis) || NextToken().is(tok::l_square) || | 638 NextToken().is(tok::ellipsis) || NextToken().is(tok::l_square) || |
639 NextToken().isRegularKeywordAttribute() || | |
636 NextToken().is(tok::kw___attribute)) && | 640 NextToken().is(tok::kw___attribute)) && |
637 D.SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() && | 641 D.SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() && |
638 !D.SS.getScopeRep()->getAsNamespace() && | 642 !D.SS.getScopeRep()->getAsNamespace() && |
639 !D.SS.getScopeRep()->getAsNamespaceAlias()) { | 643 !D.SS.getScopeRep()->getAsNamespaceAlias()) { |
640 SourceLocation IdLoc = ConsumeToken(); | 644 SourceLocation IdLoc = ConsumeToken(); |
763 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs); | 767 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs); |
764 | 768 |
765 // If we had any misplaced attributes from earlier, this is where they | 769 // If we had any misplaced attributes from earlier, this is where they |
766 // should have been written. | 770 // should have been written. |
767 if (MisplacedAttrs.Range.isValid()) { | 771 if (MisplacedAttrs.Range.isValid()) { |
768 Diag(MisplacedAttrs.Range.getBegin(), diag::err_attributes_not_allowed) | 772 auto *FirstAttr = |
773 MisplacedAttrs.empty() ? nullptr : &MisplacedAttrs.front(); | |
774 auto &Range = MisplacedAttrs.Range; | |
775 (FirstAttr && FirstAttr->isRegularKeywordAttribute() | |
776 ? Diag(Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr | |
777 : Diag(Range.getBegin(), diag::err_attributes_not_allowed)) | |
769 << FixItHint::CreateInsertionFromRange( | 778 << FixItHint::CreateInsertionFromRange( |
770 Tok.getLocation(), | 779 Tok.getLocation(), CharSourceRange::getTokenRange(Range)) |
771 CharSourceRange::getTokenRange(MisplacedAttrs.Range)) | 780 << FixItHint::CreateRemoval(Range); |
772 << FixItHint::CreateRemoval(MisplacedAttrs.Range); | |
773 Attrs.takeAllFrom(MisplacedAttrs); | 781 Attrs.takeAllFrom(MisplacedAttrs); |
774 } | 782 } |
775 | 783 |
776 // Maybe this is an alias-declaration. | 784 // Maybe this is an alias-declaration. |
777 if (Tok.is(tok::equal) || InInitStatement) { | 785 if (Tok.is(tok::equal) || InInitStatement) { |
955 /// | 963 /// |
956 Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) { | 964 Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) { |
957 assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) && | 965 assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) && |
958 "Not a static_assert declaration"); | 966 "Not a static_assert declaration"); |
959 | 967 |
960 // Save the token used for static assertion. | 968 // Save the token name used for static assertion. |
961 Token SavedTok = Tok; | 969 const char *TokName = Tok.getName(); |
962 | 970 |
963 if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11) | 971 if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11) |
964 Diag(Tok, diag::ext_c11_feature) << Tok.getName(); | 972 Diag(Tok, diag::ext_c11_feature) << Tok.getName(); |
965 if (Tok.is(tok::kw_static_assert)) { | 973 if (Tok.is(tok::kw_static_assert)) { |
966 if (!getLangOpts().CPlusPlus) { | 974 if (!getLangOpts().CPlusPlus) { |
967 if (!getLangOpts().C2x) | 975 if (getLangOpts().C23) |
976 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName(); | |
977 else | |
968 Diag(Tok, diag::ext_ms_static_assert) << FixItHint::CreateReplacement( | 978 Diag(Tok, diag::ext_ms_static_assert) << FixItHint::CreateReplacement( |
969 Tok.getLocation(), "_Static_assert"); | 979 Tok.getLocation(), "_Static_assert"); |
970 } else | 980 } else |
971 Diag(Tok, diag::warn_cxx98_compat_static_assert); | 981 Diag(Tok, diag::warn_cxx98_compat_static_assert); |
972 } | 982 } |
993 unsigned DiagVal; | 1003 unsigned DiagVal; |
994 if (getLangOpts().CPlusPlus17) | 1004 if (getLangOpts().CPlusPlus17) |
995 DiagVal = diag::warn_cxx14_compat_static_assert_no_message; | 1005 DiagVal = diag::warn_cxx14_compat_static_assert_no_message; |
996 else if (getLangOpts().CPlusPlus) | 1006 else if (getLangOpts().CPlusPlus) |
997 DiagVal = diag::ext_cxx_static_assert_no_message; | 1007 DiagVal = diag::ext_cxx_static_assert_no_message; |
998 else if (getLangOpts().C2x) | 1008 else if (getLangOpts().C23) |
999 DiagVal = diag::warn_c17_compat_static_assert_no_message; | 1009 DiagVal = diag::warn_c17_compat_static_assert_no_message; |
1000 else | 1010 else |
1001 DiagVal = diag::ext_c_static_assert_no_message; | 1011 DiagVal = diag::ext_c_static_assert_no_message; |
1002 Diag(Tok, DiagVal) << getStaticAssertNoMessageFixIt(AssertExpr.get(), | 1012 Diag(Tok, DiagVal) << getStaticAssertNoMessageFixIt(AssertExpr.get(), |
1003 Tok.getLocation()); | 1013 Tok.getLocation()); |
1005 if (ExpectAndConsume(tok::comma)) { | 1015 if (ExpectAndConsume(tok::comma)) { |
1006 SkipUntil(tok::semi); | 1016 SkipUntil(tok::semi); |
1007 return nullptr; | 1017 return nullptr; |
1008 } | 1018 } |
1009 | 1019 |
1010 if (!isTokenStringLiteral()) { | 1020 bool ParseAsExpression = false; |
1021 if (getLangOpts().CPlusPlus26) { | |
1022 for (unsigned I = 0;; ++I) { | |
1023 const Token &T = GetLookAheadToken(I); | |
1024 if (T.is(tok::r_paren)) | |
1025 break; | |
1026 if (!tokenIsLikeStringLiteral(T, getLangOpts())) { | |
1027 ParseAsExpression = true; | |
1028 break; | |
1029 } | |
1030 } | |
1031 } | |
1032 | |
1033 if (ParseAsExpression) | |
1034 AssertMessage = ParseConstantExpressionInExprEvalContext(); | |
1035 else if (tokenIsLikeStringLiteral(Tok, getLangOpts())) | |
1036 AssertMessage = ParseUnevaluatedStringLiteralExpression(); | |
1037 else { | |
1011 Diag(Tok, diag::err_expected_string_literal) | 1038 Diag(Tok, diag::err_expected_string_literal) |
1012 << /*Source='static_assert'*/ 1; | 1039 << /*Source='static_assert'*/ 1; |
1013 SkipMalformedDecl(); | 1040 SkipMalformedDecl(); |
1014 return nullptr; | 1041 return nullptr; |
1015 } | 1042 } |
1016 | 1043 |
1017 AssertMessage = ParseStringLiteralExpression(); | |
1018 if (AssertMessage.isInvalid()) { | 1044 if (AssertMessage.isInvalid()) { |
1019 SkipMalformedDecl(); | 1045 SkipMalformedDecl(); |
1020 return nullptr; | 1046 return nullptr; |
1021 } | 1047 } |
1022 } | 1048 } |
1023 | 1049 |
1024 T.consumeClose(); | 1050 T.consumeClose(); |
1025 | 1051 |
1026 DeclEnd = Tok.getLocation(); | 1052 DeclEnd = Tok.getLocation(); |
1027 // Passing the token used to the error message. | 1053 ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName); |
1028 ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, | |
1029 SavedTok.getName()); | |
1030 | 1054 |
1031 return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, AssertExpr.get(), | 1055 return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, AssertExpr.get(), |
1032 AssertMessage.get(), | 1056 AssertMessage.get(), |
1033 T.getCloseLocation()); | 1057 T.getCloseLocation()); |
1034 } | 1058 } |
1072 } | 1096 } |
1073 | 1097 |
1074 // Check for C++1y 'decltype(auto)'. | 1098 // Check for C++1y 'decltype(auto)'. |
1075 if (Tok.is(tok::kw_auto) && NextToken().is(tok::r_paren)) { | 1099 if (Tok.is(tok::kw_auto) && NextToken().is(tok::r_paren)) { |
1076 // the typename-specifier in a function-style cast expression may | 1100 // the typename-specifier in a function-style cast expression may |
1077 // be 'auto' since C++2b. | 1101 // be 'auto' since C++23. |
1078 Diag(Tok.getLocation(), | 1102 Diag(Tok.getLocation(), |
1079 getLangOpts().CPlusPlus14 | 1103 getLangOpts().CPlusPlus14 |
1080 ? diag::warn_cxx11_compat_decltype_auto_type_specifier | 1104 ? diag::warn_cxx11_compat_decltype_auto_type_specifier |
1081 : diag::ext_decltype_auto_type_specifier); | 1105 : diag::ext_decltype_auto_type_specifier); |
1082 ConsumeToken(); | 1106 ConsumeToken(); |
1367 void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) { | 1391 void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) { |
1368 while (Tok.isOneOf(tok::kw___single_inheritance, | 1392 while (Tok.isOneOf(tok::kw___single_inheritance, |
1369 tok::kw___multiple_inheritance, | 1393 tok::kw___multiple_inheritance, |
1370 tok::kw___virtual_inheritance)) { | 1394 tok::kw___virtual_inheritance)) { |
1371 IdentifierInfo *AttrName = Tok.getIdentifierInfo(); | 1395 IdentifierInfo *AttrName = Tok.getIdentifierInfo(); |
1396 auto Kind = Tok.getKind(); | |
1372 SourceLocation AttrNameLoc = ConsumeToken(); | 1397 SourceLocation AttrNameLoc = ConsumeToken(); |
1373 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, | 1398 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind); |
1374 ParsedAttr::AS_Keyword); | |
1375 } | 1399 } |
1376 } | 1400 } |
1377 | 1401 |
1378 /// Determine whether the following tokens are valid after a type-specifier | 1402 /// Determine whether the following tokens are valid after a type-specifier |
1379 /// which could be a standalone declaration. This will conservatively return | 1403 /// which could be a standalone declaration. This will conservatively return |
1380 /// true if there's any doubt, and is appropriate for insert-';' fixits. | 1404 /// true if there's any doubt, and is appropriate for insert-';' fixits. |
1381 bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) { | 1405 bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) { |
1382 // This switch enumerates the valid "follow" set for type-specifiers. | 1406 // This switch enumerates the valid "follow" set for type-specifiers. |
1383 switch (Tok.getKind()) { | 1407 switch (Tok.getKind()) { |
1384 default: | 1408 default: |
1409 if (Tok.isRegularKeywordAttribute()) | |
1410 return true; | |
1385 break; | 1411 break; |
1386 case tok::semi: // struct foo {...} ; | 1412 case tok::semi: // struct foo {...} ; |
1387 case tok::star: // struct foo {...} * P; | 1413 case tok::star: // struct foo {...} * P; |
1388 case tok::amp: // struct foo {...} & R = ... | 1414 case tok::amp: // struct foo {...} & R = ... |
1389 case tok::ampamp: // struct foo {...} && R = ... | 1415 case tok::ampamp: // struct foo {...} && R = ... |
1619 tok::kw___is_scoped_enum, | 1645 tok::kw___is_scoped_enum, |
1620 tok::kw___is_sealed, | 1646 tok::kw___is_sealed, |
1621 tok::kw___is_signed, | 1647 tok::kw___is_signed, |
1622 tok::kw___is_standard_layout, | 1648 tok::kw___is_standard_layout, |
1623 tok::kw___is_trivial, | 1649 tok::kw___is_trivial, |
1650 tok::kw___is_trivially_equality_comparable, | |
1624 tok::kw___is_trivially_assignable, | 1651 tok::kw___is_trivially_assignable, |
1625 tok::kw___is_trivially_constructible, | 1652 tok::kw___is_trivially_constructible, |
1626 tok::kw___is_trivially_copyable, | 1653 tok::kw___is_trivially_copyable, |
1627 tok::kw___is_unbounded_array, | 1654 tok::kw___is_unbounded_array, |
1628 tok::kw___is_union, | 1655 tok::kw___is_union, |
1671 // "FOO : BAR" is not a potential typo for "FOO::BAR". In this context it | 1698 // "FOO : BAR" is not a potential typo for "FOO::BAR". In this context it |
1672 // is a base-specifier-list. | 1699 // is a base-specifier-list. |
1673 ColonProtectionRAIIObject X(*this); | 1700 ColonProtectionRAIIObject X(*this); |
1674 | 1701 |
1675 CXXScopeSpec Spec; | 1702 CXXScopeSpec Spec; |
1703 if (TemplateInfo.TemplateParams) | |
1704 Spec.setTemplateParamLists(*TemplateInfo.TemplateParams); | |
1705 | |
1676 bool HasValidSpec = true; | 1706 bool HasValidSpec = true; |
1677 if (ParseOptionalCXXScopeSpecifier(Spec, /*ObjectType=*/nullptr, | 1707 if (ParseOptionalCXXScopeSpecifier(Spec, /*ObjectType=*/nullptr, |
1678 /*ObjectHasErrors=*/false, | 1708 /*ObjectHasErrors=*/false, |
1679 EnteringContext)) { | 1709 EnteringContext)) { |
1680 DS.SetTypeSpecError(); | 1710 DS.SetTypeSpecError(); |
1833 TUK = Sema::TUK_Definition; | 1863 TUK = Sema::TUK_Definition; |
1834 } | 1864 } |
1835 } else if (isClassCompatibleKeyword() && | 1865 } else if (isClassCompatibleKeyword() && |
1836 (NextToken().is(tok::l_square) || | 1866 (NextToken().is(tok::l_square) || |
1837 NextToken().is(tok::kw_alignas) || | 1867 NextToken().is(tok::kw_alignas) || |
1868 NextToken().isRegularKeywordAttribute() || | |
1838 isCXX11VirtSpecifier(NextToken()) != VirtSpecifiers::VS_None)) { | 1869 isCXX11VirtSpecifier(NextToken()) != VirtSpecifiers::VS_None)) { |
1839 // We can't tell if this is a definition or reference | 1870 // We can't tell if this is a definition or reference |
1840 // until we skipped the 'final' and C++11 attribute specifiers. | 1871 // until we skipped the 'final' and C++11 attribute specifiers. |
1841 TentativeParsingAction PA(*this); | 1872 TentativeParsingAction PA(*this); |
1842 | 1873 |
1854 } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) { | 1885 } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) { |
1855 ConsumeToken(); | 1886 ConsumeToken(); |
1856 ConsumeParen(); | 1887 ConsumeParen(); |
1857 if (!SkipUntil(tok::r_paren, StopAtSemi)) | 1888 if (!SkipUntil(tok::r_paren, StopAtSemi)) |
1858 break; | 1889 break; |
1890 } else if (Tok.isRegularKeywordAttribute()) { | |
1891 ConsumeToken(); | |
1859 } else { | 1892 } else { |
1860 break; | 1893 break; |
1861 } | 1894 } |
1862 } | 1895 } |
1863 | 1896 |
1890 // is between class-key and class-name. If there are | 1923 // is between class-key and class-name. If there are |
1891 // any attributes after class-name, we try a fixit to move | 1924 // any attributes after class-name, we try a fixit to move |
1892 // them to the right place. | 1925 // them to the right place. |
1893 SourceRange AttrRange = Attributes.Range; | 1926 SourceRange AttrRange = Attributes.Range; |
1894 if (AttrRange.isValid()) { | 1927 if (AttrRange.isValid()) { |
1895 Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed) | 1928 auto *FirstAttr = Attributes.empty() ? nullptr : &Attributes.front(); |
1929 auto Loc = AttrRange.getBegin(); | |
1930 (FirstAttr && FirstAttr->isRegularKeywordAttribute() | |
1931 ? Diag(Loc, diag::err_keyword_not_allowed) << FirstAttr | |
1932 : Diag(Loc, diag::err_attributes_not_allowed)) | |
1896 << AttrRange | 1933 << AttrRange |
1897 << FixItHint::CreateInsertionFromRange( | 1934 << FixItHint::CreateInsertionFromRange( |
1898 AttrFixitLoc, CharSourceRange(AttrRange, true)) | 1935 AttrFixitLoc, CharSourceRange(AttrRange, true)) |
1899 << FixItHint::CreateRemoval(AttrRange); | 1936 << FixItHint::CreateRemoval(AttrRange); |
1900 | 1937 |
1938 // Can't build the declaration. | 1975 // Can't build the declaration. |
1939 } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && | 1976 } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && |
1940 TUK == Sema::TUK_Declaration) { | 1977 TUK == Sema::TUK_Declaration) { |
1941 // This is an explicit instantiation of a class template. | 1978 // This is an explicit instantiation of a class template. |
1942 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, | 1979 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, |
1980 diag::err_keyword_not_allowed, | |
1943 /*DiagnoseEmptyAttrs=*/true); | 1981 /*DiagnoseEmptyAttrs=*/true); |
1944 | 1982 |
1945 TagOrTempResult = Actions.ActOnExplicitInstantiation( | 1983 TagOrTempResult = Actions.ActOnExplicitInstantiation( |
1946 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, | 1984 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, |
1947 TagType, StartLoc, SS, TemplateId->Template, | 1985 TagType, StartLoc, SS, TemplateId->Template, |
1954 // We diagnose this error in ActOnClassTemplateSpecialization. | 1992 // We diagnose this error in ActOnClassTemplateSpecialization. |
1955 } else if (TUK == Sema::TUK_Reference || | 1993 } else if (TUK == Sema::TUK_Reference || |
1956 (TUK == Sema::TUK_Friend && | 1994 (TUK == Sema::TUK_Friend && |
1957 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { | 1995 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { |
1958 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, | 1996 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, |
1997 diag::err_keyword_not_allowed, | |
1959 /*DiagnoseEmptyAttrs=*/true); | 1998 /*DiagnoseEmptyAttrs=*/true); |
1960 TypeResult = Actions.ActOnTagTemplateIdType( | 1999 TypeResult = Actions.ActOnTagTemplateIdType( |
1961 TUK, TagType, StartLoc, SS, TemplateId->TemplateKWLoc, | 2000 TUK, TagType, StartLoc, SS, TemplateId->TemplateKWLoc, |
1962 TemplateId->Template, TemplateId->TemplateNameLoc, | 2001 TemplateId->Template, TemplateId->TemplateNameLoc, |
1963 TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc); | 2002 TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc); |
1993 | 2032 |
1994 // Create a fake template parameter list that contains only | 2033 // Create a fake template parameter list that contains only |
1995 // "template<>", so that we treat this construct as a class | 2034 // "template<>", so that we treat this construct as a class |
1996 // template specialization. | 2035 // template specialization. |
1997 FakedParamLists.push_back(Actions.ActOnTemplateParameterList( | 2036 FakedParamLists.push_back(Actions.ActOnTemplateParameterList( |
1998 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None, | 2037 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, |
1999 LAngleLoc, nullptr)); | 2038 std::nullopt, LAngleLoc, nullptr)); |
2000 TemplateParams = &FakedParamLists; | 2039 TemplateParams = &FakedParamLists; |
2001 } | 2040 } |
2002 } | 2041 } |
2003 | 2042 |
2004 // Build the class template specialization. | 2043 // Build the class template specialization. |
2023 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, | 2062 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, |
2024 TagType, StartLoc, SS, Name, NameLoc, attrs); | 2063 TagType, StartLoc, SS, Name, NameLoc, attrs); |
2025 } else if (TUK == Sema::TUK_Friend && | 2064 } else if (TUK == Sema::TUK_Friend && |
2026 TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) { | 2065 TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) { |
2027 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, | 2066 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, |
2067 diag::err_keyword_not_allowed, | |
2028 /*DiagnoseEmptyAttrs=*/true); | 2068 /*DiagnoseEmptyAttrs=*/true); |
2029 | 2069 |
2030 TagOrTempResult = Actions.ActOnTemplatedFriendTag( | 2070 TagOrTempResult = Actions.ActOnTemplatedFriendTag( |
2031 getCurScope(), DS.getFriendSpecLoc(), TagType, StartLoc, SS, Name, | 2071 getCurScope(), DS.getFriendSpecLoc(), TagType, StartLoc, SS, Name, |
2032 NameLoc, attrs, | 2072 NameLoc, attrs, |
2033 MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr, | 2073 MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr, |
2034 TemplateParams ? TemplateParams->size() : 0)); | 2074 TemplateParams ? TemplateParams->size() : 0)); |
2035 } else { | 2075 } else { |
2036 if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition) | 2076 if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition) |
2037 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, | 2077 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, |
2078 diag::err_keyword_not_allowed, | |
2038 /* DiagnoseEmptyAttrs=*/true); | 2079 /* DiagnoseEmptyAttrs=*/true); |
2039 | 2080 |
2040 if (TUK == Sema::TUK_Definition && | 2081 if (TUK == Sema::TUK_Definition && |
2041 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { | 2082 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { |
2042 // If the declarator-id is not a template-id, issue a diagnostic and | 2083 // If the declarator-id is not a template-id, issue a diagnostic and |
2064 DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent, | 2105 DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent, |
2065 SourceLocation(), false, clang::TypeResult(), | 2106 SourceLocation(), false, clang::TypeResult(), |
2066 DSC == DeclSpecContext::DSC_type_specifier, | 2107 DSC == DeclSpecContext::DSC_type_specifier, |
2067 DSC == DeclSpecContext::DSC_template_param || | 2108 DSC == DeclSpecContext::DSC_template_param || |
2068 DSC == DeclSpecContext::DSC_template_type_arg, | 2109 DSC == DeclSpecContext::DSC_template_type_arg, |
2069 &SkipBody); | 2110 OffsetOfState, &SkipBody); |
2070 | 2111 |
2071 // If ActOnTag said the type was dependent, try again with the | 2112 // If ActOnTag said the type was dependent, try again with the |
2072 // less common call. | 2113 // less common call. |
2073 if (IsDependent) { | 2114 if (IsDependent) { |
2074 assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend); | 2115 assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend); |
2819 ProhibitAttributes(DeclAttrs); | 2860 ProhibitAttributes(DeclAttrs); |
2820 | 2861 |
2821 RecordDecl *AnonRecord = nullptr; | 2862 RecordDecl *AnonRecord = nullptr; |
2822 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec( | 2863 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec( |
2823 getCurScope(), AS, DS, DeclAttrs, TemplateParams, false, AnonRecord); | 2864 getCurScope(), AS, DS, DeclAttrs, TemplateParams, false, AnonRecord); |
2865 Actions.ActOnDefinedDeclarationSpecifier(TheDecl); | |
2824 DS.complete(TheDecl); | 2866 DS.complete(TheDecl); |
2825 if (AnonRecord) { | 2867 if (AnonRecord) { |
2826 Decl *decls[] = {AnonRecord, TheDecl}; | 2868 Decl *decls[] = {AnonRecord, TheDecl}; |
2827 return Actions.BuildDeclaratorGroup(decls); | 2869 return Actions.BuildDeclaratorGroup(decls); |
2828 } | 2870 } |
2829 return Actions.ConvertDeclToDeclGroup(TheDecl); | 2871 return Actions.ConvertDeclToDeclGroup(TheDecl); |
2830 } | 2872 } |
2873 | |
2874 if (DS.hasTagDefinition()) | |
2875 Actions.ActOnDefinedDeclarationSpecifier(DS.getRepAsDecl()); | |
2831 | 2876 |
2832 ParsingDeclarator DeclaratorInfo(*this, DS, DeclAttrs, | 2877 ParsingDeclarator DeclaratorInfo(*this, DS, DeclAttrs, |
2833 DeclaratorContext::Member); | 2878 DeclaratorContext::Member); |
2834 if (TemplateInfo.TemplateParams) | 2879 if (TemplateInfo.TemplateParams) |
2835 DeclaratorInfo.setTemplateParameterLists(TemplateParams); | 2880 DeclaratorInfo.setTemplateParameterLists(TemplateParams); |
3009 // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains | 3054 // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains |
3010 // to a friend declaration, that declaration shall be a definition. | 3055 // to a friend declaration, that declaration shall be a definition. |
3011 // | 3056 // |
3012 // Diagnose attributes that appear in a friend member function declarator: | 3057 // Diagnose attributes that appear in a friend member function declarator: |
3013 // friend int foo [[]] (); | 3058 // friend int foo [[]] (); |
3014 SmallVector<SourceRange, 4> Ranges; | 3059 for (const ParsedAttr &AL : DeclaratorInfo.getAttributes()) |
3015 DeclaratorInfo.getCXX11AttributeRanges(Ranges); | 3060 if (AL.isCXX11Attribute() || AL.isRegularKeywordAttribute()) { |
3016 for (SmallVectorImpl<SourceRange>::iterator I = Ranges.begin(), | 3061 auto Loc = AL.getRange().getBegin(); |
3017 E = Ranges.end(); | 3062 (AL.isRegularKeywordAttribute() |
3018 I != E; ++I) | 3063 ? Diag(Loc, diag::err_keyword_not_allowed) << AL |
3019 Diag((*I).getBegin(), diag::err_attributes_not_allowed) << *I; | 3064 : Diag(Loc, diag::err_attributes_not_allowed)) |
3065 << AL.getRange(); | |
3066 } | |
3020 | 3067 |
3021 ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo, | 3068 ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo, |
3022 TemplateParams); | 3069 TemplateParams); |
3023 } else { | 3070 } else { |
3024 ThisDecl = Actions.ActOnCXXMemberDeclarator( | 3071 ThisDecl = Actions.ActOnCXXMemberDeclarator( |
3182 SourceLocation &EqualLoc) { | 3229 SourceLocation &EqualLoc) { |
3183 assert(Tok.isOneOf(tok::equal, tok::l_brace) && | 3230 assert(Tok.isOneOf(tok::equal, tok::l_brace) && |
3184 "Data member initializer not starting with '=' or '{'"); | 3231 "Data member initializer not starting with '=' or '{'"); |
3185 | 3232 |
3186 EnterExpressionEvaluationContext Context( | 3233 EnterExpressionEvaluationContext Context( |
3187 Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, D); | 3234 Actions, |
3235 isa_and_present<FieldDecl>(D) | |
3236 ? Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed | |
3237 : Sema::ExpressionEvaluationContext::PotentiallyEvaluated, | |
3238 D); | |
3239 Actions.ExprEvalContexts.back().InImmediateEscalatingFunctionContext = true; | |
3188 if (TryConsumeToken(tok::equal, EqualLoc)) { | 3240 if (TryConsumeToken(tok::equal, EqualLoc)) { |
3189 if (Tok.is(tok::kw_delete)) { | 3241 if (Tok.is(tok::kw_delete)) { |
3190 // In principle, an initializer of '= delete p;' is legal, but it will | 3242 // In principle, an initializer of '= delete p;' is legal, but it will |
3191 // never type-check. It's better to diagnose it as an ill-formed | 3243 // never type-check. It's better to diagnose it as an ill-formed |
3192 // expression than as an ill-formed deleted non-function member. An | 3244 // expression than as an ill-formed deleted non-function member. An |
3801 BalancedDelimiterTracker T(*this, tok::l_paren); | 3853 BalancedDelimiterTracker T(*this, tok::l_paren); |
3802 T.consumeOpen(); | 3854 T.consumeOpen(); |
3803 | 3855 |
3804 // Parse the optional expression-list. | 3856 // Parse the optional expression-list. |
3805 ExprVector ArgExprs; | 3857 ExprVector ArgExprs; |
3806 CommaLocsTy CommaLocs; | |
3807 auto RunSignatureHelp = [&] { | 3858 auto RunSignatureHelp = [&] { |
3808 if (TemplateTypeTy.isInvalid()) | 3859 if (TemplateTypeTy.isInvalid()) |
3809 return QualType(); | 3860 return QualType(); |
3810 QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp( | 3861 QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp( |
3811 ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II, | 3862 ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II, |
3812 T.getOpenLocation(), /*Braced=*/false); | 3863 T.getOpenLocation(), /*Braced=*/false); |
3813 CalledSignatureHelp = true; | 3864 CalledSignatureHelp = true; |
3814 return PreferredType; | 3865 return PreferredType; |
3815 }; | 3866 }; |
3816 if (Tok.isNot(tok::r_paren) && | 3867 if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, [&] { |
3817 ParseExpressionList(ArgExprs, CommaLocs, [&] { | |
3818 PreferredType.enterFunctionArgument(Tok.getLocation(), | 3868 PreferredType.enterFunctionArgument(Tok.getLocation(), |
3819 RunSignatureHelp); | 3869 RunSignatureHelp); |
3820 })) { | 3870 })) { |
3821 if (PP.isCodeCompletionReached() && !CalledSignatureHelp) | 3871 if (PP.isCodeCompletionReached() && !CalledSignatureHelp) |
3822 RunSignatureHelp(); | 3872 RunSignatureHelp(); |
4060 Scope::FunctionDeclarationScope | | 4110 Scope::FunctionDeclarationScope | |
4061 Scope::FunctionPrototypeScope); | 4111 Scope::FunctionPrototypeScope); |
4062 | 4112 |
4063 Actions.ActOnStartTrailingRequiresClause(getCurScope(), D); | 4113 Actions.ActOnStartTrailingRequiresClause(getCurScope(), D); |
4064 | 4114 |
4065 llvm::Optional<Sema::CXXThisScopeRAII> ThisScope; | 4115 std::optional<Sema::CXXThisScopeRAII> ThisScope; |
4066 InitCXXThisScopeForDeclaratorIfRelevant(D, D.getDeclSpec(), ThisScope); | 4116 InitCXXThisScopeForDeclaratorIfRelevant(D, D.getDeclSpec(), ThisScope); |
4067 | 4117 |
4068 TrailingRequiresClause = | 4118 TrailingRequiresClause = |
4069 ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true); | 4119 ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true); |
4070 | 4120 |
4189 return nullptr; | 4239 return nullptr; |
4190 | 4240 |
4191 case tok::code_completion: | 4241 case tok::code_completion: |
4192 cutOffParsing(); | 4242 cutOffParsing(); |
4193 Actions.CodeCompleteAttribute(getLangOpts().CPlusPlus ? ParsedAttr::AS_CXX11 | 4243 Actions.CodeCompleteAttribute(getLangOpts().CPlusPlus ? ParsedAttr::AS_CXX11 |
4194 : ParsedAttr::AS_C2x, | 4244 : ParsedAttr::AS_C23, |
4195 Completion, Scope); | 4245 Completion, Scope); |
4196 return nullptr; | 4246 return nullptr; |
4197 | 4247 |
4198 case tok::numeric_constant: { | 4248 case tok::numeric_constant: { |
4199 // If we got a numeric constant, check to see if it comes from a macro that | 4249 // If we got a numeric constant, check to see if it comes from a macro that |
4346 ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName, | 4396 ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName, |
4347 SourceLocation ScopeLoc, CachedTokens &OpenMPTokens) { | 4397 SourceLocation ScopeLoc, CachedTokens &OpenMPTokens) { |
4348 assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list"); | 4398 assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list"); |
4349 SourceLocation LParenLoc = Tok.getLocation(); | 4399 SourceLocation LParenLoc = Tok.getLocation(); |
4350 const LangOptions &LO = getLangOpts(); | 4400 const LangOptions &LO = getLangOpts(); |
4351 ParsedAttr::Syntax Syntax = | 4401 ParsedAttr::Form Form = |
4352 LO.CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x; | 4402 LO.CPlusPlus ? ParsedAttr::Form::CXX11() : ParsedAttr::Form::C23(); |
4353 | 4403 |
4354 // Try parsing microsoft attributes | 4404 // Try parsing microsoft attributes |
4355 if (getLangOpts().MicrosoftExt || getLangOpts().HLSL) { | 4405 if (getLangOpts().MicrosoftExt || getLangOpts().HLSL) { |
4356 if (hasAttribute(AttributeCommonInfo::Syntax::AS_Microsoft, ScopeName, | 4406 if (hasAttribute(AttributeCommonInfo::Syntax::AS_Microsoft, ScopeName, |
4357 AttrName, getTargetInfo(), getLangOpts())) | 4407 AttrName, getTargetInfo(), getLangOpts())) |
4358 Syntax = ParsedAttr::AS_Microsoft; | 4408 Form = ParsedAttr::Form::Microsoft(); |
4359 } | 4409 } |
4360 | 4410 |
4361 // If the attribute isn't known, we will not attempt to parse any | 4411 // If the attribute isn't known, we will not attempt to parse any |
4362 // arguments. | 4412 // arguments. |
4363 if (Syntax != ParsedAttr::AS_Microsoft && | 4413 if (Form.getSyntax() != ParsedAttr::AS_Microsoft && |
4364 !hasAttribute(LO.CPlusPlus ? AttributeCommonInfo::Syntax::AS_CXX11 | 4414 !hasAttribute(LO.CPlusPlus ? AttributeCommonInfo::Syntax::AS_CXX11 |
4365 : AttributeCommonInfo::Syntax::AS_C2x, | 4415 : AttributeCommonInfo::Syntax::AS_C23, |
4366 ScopeName, AttrName, getTargetInfo(), getLangOpts())) { | 4416 ScopeName, AttrName, getTargetInfo(), getLangOpts())) { |
4367 if (getLangOpts().MicrosoftExt || getLangOpts().HLSL) { | 4417 if (getLangOpts().MicrosoftExt || getLangOpts().HLSL) { |
4368 } | 4418 } |
4369 // Eat the left paren, then skip to the ending right paren. | 4419 // Eat the left paren, then skip to the ending right paren. |
4370 ConsumeParen(); | 4420 ConsumeParen(); |
4374 | 4424 |
4375 if (ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"))) { | 4425 if (ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"))) { |
4376 // GNU-scoped attributes have some special cases to handle GNU-specific | 4426 // GNU-scoped attributes have some special cases to handle GNU-specific |
4377 // behaviors. | 4427 // behaviors. |
4378 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, | 4428 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, |
4379 ScopeLoc, Syntax, nullptr); | 4429 ScopeLoc, Form, nullptr); |
4380 return true; | 4430 return true; |
4381 } | 4431 } |
4382 | 4432 |
4383 if (ScopeName && ScopeName->isStr("omp")) { | 4433 if (ScopeName && ScopeName->isStr("omp")) { |
4384 Diag(AttrNameLoc, getLangOpts().OpenMP >= 51 | 4434 Diag(AttrNameLoc, getLangOpts().OpenMP >= 51 |
4394 | 4444 |
4395 unsigned NumArgs; | 4445 unsigned NumArgs; |
4396 // Some Clang-scoped attributes have some special parsing behavior. | 4446 // Some Clang-scoped attributes have some special parsing behavior. |
4397 if (ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang"))) | 4447 if (ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang"))) |
4398 NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, | 4448 NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, |
4399 ScopeName, ScopeLoc, Syntax); | 4449 ScopeName, ScopeLoc, Form); |
4400 else | 4450 else |
4401 NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, | 4451 NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, |
4402 ScopeName, ScopeLoc, Syntax); | 4452 ScopeName, ScopeLoc, Form); |
4403 | 4453 |
4404 if (!Attrs.empty() && | 4454 if (!Attrs.empty() && |
4405 IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) { | 4455 IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) { |
4406 ParsedAttr &Attr = Attrs.back(); | 4456 ParsedAttr &Attr = Attrs.back(); |
4407 // If the attribute is a standard or built-in attribute and we are | 4457 // If the attribute is a standard or built-in attribute and we are |
4424 } | 4474 } |
4425 } | 4475 } |
4426 return true; | 4476 return true; |
4427 } | 4477 } |
4428 | 4478 |
4429 /// Parse a C++11 or C2x attribute-specifier. | 4479 /// Parse a C++11 or C23 attribute-specifier. |
4430 /// | 4480 /// |
4431 /// [C++11] attribute-specifier: | 4481 /// [C++11] attribute-specifier: |
4432 /// '[' '[' attribute-list ']' ']' | 4482 /// '[' '[' attribute-list ']' ']' |
4433 /// alignment-specifier | 4483 /// alignment-specifier |
4434 /// | 4484 /// |
4452 /// identifier | 4502 /// identifier |
4453 void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, | 4503 void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, |
4454 CachedTokens &OpenMPTokens, | 4504 CachedTokens &OpenMPTokens, |
4455 SourceLocation *EndLoc) { | 4505 SourceLocation *EndLoc) { |
4456 if (Tok.is(tok::kw_alignas)) { | 4506 if (Tok.is(tok::kw_alignas)) { |
4457 Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas); | 4507 if (getLangOpts().C23) |
4508 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName(); | |
4509 else | |
4510 Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas); | |
4458 ParseAlignmentSpecifier(Attrs, EndLoc); | 4511 ParseAlignmentSpecifier(Attrs, EndLoc); |
4459 return; | 4512 return; |
4460 } | 4513 } |
4461 | 4514 |
4515 if (Tok.isRegularKeywordAttribute()) { | |
4516 SourceLocation Loc = Tok.getLocation(); | |
4517 IdentifierInfo *AttrName = Tok.getIdentifierInfo(); | |
4518 Attrs.addNew(AttrName, Loc, nullptr, Loc, nullptr, 0, Tok.getKind()); | |
4519 ConsumeToken(); | |
4520 return; | |
4521 } | |
4522 | |
4462 assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) && | 4523 assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) && |
4463 "Not a double square bracket attribute list"); | 4524 "Not a double square bracket attribute list"); |
4464 | 4525 |
4465 SourceLocation OpenLoc = Tok.getLocation(); | 4526 SourceLocation OpenLoc = Tok.getLocation(); |
4466 Diag(OpenLoc, diag::warn_cxx98_compat_attribute); | 4527 if (getLangOpts().CPlusPlus) { |
4528 Diag(OpenLoc, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_attribute | |
4529 : diag::warn_ext_cxx11_attributes); | |
4530 } else { | |
4531 Diag(OpenLoc, getLangOpts().C23 ? diag::warn_pre_c23_compat_attributes | |
4532 : diag::warn_ext_c23_attributes); | |
4533 } | |
4467 | 4534 |
4468 ConsumeBracket(); | 4535 ConsumeBracket(); |
4469 checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin); | 4536 checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin); |
4470 ConsumeBracket(); | 4537 ConsumeBracket(); |
4471 | 4538 |
4484 SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); | 4551 SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); |
4485 } | 4552 } |
4486 if (!TryConsumeToken(tok::colon) && CommonScopeName) | 4553 if (!TryConsumeToken(tok::colon) && CommonScopeName) |
4487 Diag(Tok.getLocation(), diag::err_expected) << tok::colon; | 4554 Diag(Tok.getLocation(), diag::err_expected) << tok::colon; |
4488 } | 4555 } |
4489 | |
4490 llvm::SmallDenseMap<IdentifierInfo *, SourceLocation, 4> SeenAttrs; | |
4491 | 4556 |
4492 bool AttrParsed = false; | 4557 bool AttrParsed = false; |
4493 while (!Tok.isOneOf(tok::r_square, tok::semi, tok::eof)) { | 4558 while (!Tok.isOneOf(tok::r_square, tok::semi, tok::eof)) { |
4494 if (AttrParsed) { | 4559 if (AttrParsed) { |
4495 // If we parsed an attribute, a comma is required before parsing any | 4560 // If we parsed an attribute, a comma is required before parsing any |
4546 if (!AttrParsed) { | 4611 if (!AttrParsed) { |
4547 Attrs.addNew( | 4612 Attrs.addNew( |
4548 AttrName, | 4613 AttrName, |
4549 SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc), | 4614 SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc), |
4550 ScopeName, ScopeLoc, nullptr, 0, | 4615 ScopeName, ScopeLoc, nullptr, 0, |
4551 getLangOpts().CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x); | 4616 getLangOpts().CPlusPlus ? ParsedAttr::Form::CXX11() |
4617 : ParsedAttr::Form::C23()); | |
4552 AttrParsed = true; | 4618 AttrParsed = true; |
4553 } | 4619 } |
4554 | 4620 |
4555 if (TryConsumeToken(tok::ellipsis)) | 4621 if (TryConsumeToken(tok::ellipsis)) |
4556 Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) << AttrName; | 4622 Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) << AttrName; |
4572 *EndLoc = Tok.getLocation(); | 4638 *EndLoc = Tok.getLocation(); |
4573 if (ExpectAndConsume(tok::r_square)) | 4639 if (ExpectAndConsume(tok::r_square)) |
4574 SkipUntil(tok::r_square); | 4640 SkipUntil(tok::r_square); |
4575 } | 4641 } |
4576 | 4642 |
4577 /// ParseCXX11Attributes - Parse a C++11 or C2x attribute-specifier-seq. | 4643 /// ParseCXX11Attributes - Parse a C++11 or C23 attribute-specifier-seq. |
4578 /// | 4644 /// |
4579 /// attribute-specifier-seq: | 4645 /// attribute-specifier-seq: |
4580 /// attribute-specifier-seq[opt] attribute-specifier | 4646 /// attribute-specifier-seq[opt] attribute-specifier |
4581 void Parser::ParseCXX11Attributes(ParsedAttributes &Attrs) { | 4647 void Parser::ParseCXX11Attributes(ParsedAttributes &Attrs) { |
4582 assert(standardAttributesAllowed()); | |
4583 | |
4584 SourceLocation StartLoc = Tok.getLocation(); | 4648 SourceLocation StartLoc = Tok.getLocation(); |
4585 SourceLocation EndLoc = StartLoc; | 4649 SourceLocation EndLoc = StartLoc; |
4586 | 4650 |
4587 do { | 4651 do { |
4588 ParseCXX11AttributeSpecifier(Attrs, &EndLoc); | 4652 ParseCXX11AttributeSpecifier(Attrs, &EndLoc); |
4589 } while (isCXX11AttributeSpecifier()); | 4653 } while (isAllowedCXX11AttributeSpecifier()); |
4590 | 4654 |
4591 Attrs.Range = SourceRange(StartLoc, EndLoc); | 4655 Attrs.Range = SourceRange(StartLoc, EndLoc); |
4592 } | 4656 } |
4593 | 4657 |
4594 void Parser::DiagnoseAndSkipCXX11Attributes() { | 4658 void Parser::DiagnoseAndSkipCXX11Attributes() { |
4659 auto Keyword = | |
4660 Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() : nullptr; | |
4595 // Start and end location of an attribute or an attribute list. | 4661 // Start and end location of an attribute or an attribute list. |
4596 SourceLocation StartLoc = Tok.getLocation(); | 4662 SourceLocation StartLoc = Tok.getLocation(); |
4597 SourceLocation EndLoc = SkipCXX11Attributes(); | 4663 SourceLocation EndLoc = SkipCXX11Attributes(); |
4598 | 4664 |
4599 if (EndLoc.isValid()) { | 4665 if (EndLoc.isValid()) { |
4600 SourceRange Range(StartLoc, EndLoc); | 4666 SourceRange Range(StartLoc, EndLoc); |
4601 Diag(StartLoc, diag::err_attributes_not_allowed) << Range; | 4667 (Keyword ? Diag(StartLoc, diag::err_keyword_not_allowed) << Keyword |
4668 : Diag(StartLoc, diag::err_attributes_not_allowed)) | |
4669 << Range; | |
4602 } | 4670 } |
4603 } | 4671 } |
4604 | 4672 |
4605 SourceLocation Parser::SkipCXX11Attributes() { | 4673 SourceLocation Parser::SkipCXX11Attributes() { |
4606 SourceLocation EndLoc; | 4674 SourceLocation EndLoc; |
4612 if (Tok.is(tok::l_square)) { | 4680 if (Tok.is(tok::l_square)) { |
4613 BalancedDelimiterTracker T(*this, tok::l_square); | 4681 BalancedDelimiterTracker T(*this, tok::l_square); |
4614 T.consumeOpen(); | 4682 T.consumeOpen(); |
4615 T.skipToEnd(); | 4683 T.skipToEnd(); |
4616 EndLoc = T.getCloseLocation(); | 4684 EndLoc = T.getCloseLocation(); |
4685 } else if (Tok.isRegularKeywordAttribute()) { | |
4686 EndLoc = Tok.getLocation(); | |
4687 ConsumeToken(); | |
4617 } else { | 4688 } else { |
4618 assert(Tok.is(tok::kw_alignas) && "not an attribute specifier"); | 4689 assert(Tok.is(tok::kw_alignas) && "not an attribute specifier"); |
4619 ConsumeToken(); | 4690 ConsumeToken(); |
4620 BalancedDelimiterTracker T(*this, tok::l_paren); | 4691 BalancedDelimiterTracker T(*this, tok::l_paren); |
4621 if (!T.consumeOpen()) | 4692 if (!T.consumeOpen()) |
4706 } | 4777 } |
4707 | 4778 |
4708 if (!T.consumeClose()) { | 4779 if (!T.consumeClose()) { |
4709 Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr, | 4780 Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr, |
4710 SourceLocation(), ArgExprs.data(), ArgExprs.size(), | 4781 SourceLocation(), ArgExprs.data(), ArgExprs.size(), |
4711 ParsedAttr::AS_Microsoft); | 4782 ParsedAttr::Form::Microsoft()); |
4712 } | 4783 } |
4713 } | 4784 } |
4714 | 4785 |
4715 /// ParseMicrosoftAttributes - Parse Microsoft attributes [Attr] | 4786 /// ParseMicrosoftAttributes - Parse Microsoft attributes [Attr] |
4716 /// | 4787 /// |
4762 SourceLocation(), OpenMPTokens); | 4833 SourceLocation(), OpenMPTokens); |
4763 ReplayOpenMPAttributeTokens(OpenMPTokens); | 4834 ReplayOpenMPAttributeTokens(OpenMPTokens); |
4764 } | 4835 } |
4765 if (!AttrParsed) { | 4836 if (!AttrParsed) { |
4766 Attrs.addNew(II, NameLoc, nullptr, SourceLocation(), nullptr, 0, | 4837 Attrs.addNew(II, NameLoc, nullptr, SourceLocation(), nullptr, 0, |
4767 ParsedAttr::AS_Microsoft); | 4838 ParsedAttr::Form::Microsoft()); |
4768 } | 4839 } |
4769 } | 4840 } |
4770 } | 4841 } |
4771 } | 4842 } |
4772 | 4843 |