28 #include "llvm/ADT/SmallSet.h"
29 #include "llvm/ADT/SmallString.h"
30 #include "llvm/ADT/StringSwitch.h"
32 using namespace clang;
48 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
49 if (DSC == DSC_normal)
50 DSC = DSC_type_specifier;
56 ParseSpecifierQualifierList(DS, AS, DSC);
62 ParseDeclarator(DeclaratorInfo);
75 #define CLANG_ATTR_LATE_PARSED_LIST
76 return llvm::StringSwitch<bool>(II.
getName())
77 #include
"clang/Parse/AttrParserStringSwitches.inc"
79 #undef CLANG_ATTR_LATE_PARSED_LIST
125 LateParsedAttrList *LateAttrs,
127 assert(Tok.
is(tok::kw___attribute) &&
"Not a GNU attribute list!");
129 while (Tok.
is(tok::kw___attribute)) {
131 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
136 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
155 if (Tok.
isNot(tok::l_paren)) {
156 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
163 ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc,
nullptr,
169 LateParsedAttribute *LA =
170 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
171 LateAttrs->push_back(LA);
175 if (!ClassStack.empty() && !LateAttrs->parseSoon())
176 getCurrentClass().LateParsedDeclarations.push_back(LA);
179 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true,
false);
184 LA->Toks.push_back(Eof);
187 if (ExpectAndConsume(tok::r_paren))
190 if (ExpectAndConsume(tok::r_paren))
199 if (Name.size() >= 4 && Name.startswith(
"__") && Name.endswith(
"__"))
200 Name = Name.drop_front(2).drop_back(2);
206 #define CLANG_ATTR_IDENTIFIER_ARG_LIST
208 #include "clang/Parse/AttrParserStringSwitches.inc"
210 #undef CLANG_ATTR_IDENTIFIER_ARG_LIST
215 #define CLANG_ATTR_TYPE_ARG_LIST
217 #include "clang/Parse/AttrParserStringSwitches.inc"
219 #undef CLANG_ATTR_TYPE_ARG_LIST
225 #define CLANG_ATTR_ARG_CONTEXT_LIST
227 #include "clang/Parse/AttrParserStringSwitches.inc"
229 #undef CLANG_ATTR_ARG_CONTEXT_LIST
233 assert(Tok.
is(tok::identifier) &&
"expected an identifier");
249 Parens.consumeOpen();
252 if (Tok.
isNot(tok::r_paren))
255 if (Parens.consumeClose())
263 SourceRange(AttrNameLoc, Parens.getCloseLocation()),
264 ScopeName, ScopeLoc, T.
get(), Syntax);
267 ScopeName, ScopeLoc,
nullptr, 0, Syntax);
270 unsigned Parser::ParseAttributeArgsCommon(
278 if (Tok.
is(tok::identifier)) {
289 IsIdentifierArg = Next.
isOneOf(tok::r_paren, tok::comma);
293 ArgExprs.push_back(ParseIdentifierLoc());
296 if (!ArgExprs.empty() ? Tok.
is(tok::comma) : Tok.
isNot(tok::r_paren)) {
298 if (!ArgExprs.empty())
303 std::unique_ptr<EnterExpressionEvaluationContext> Unevaluated;
310 if (ArgExpr.isInvalid()) {
314 ArgExprs.push_back(ArgExpr.get());
320 if (!ExpectAndConsume(tok::r_paren)) {
323 ArgExprs.data(), ArgExprs.size(), Syntax);
329 return static_cast<unsigned>(ArgExprs.size());
343 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
348 if (AttrKind == AttributeList::AT_Availability) {
349 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
352 }
else if (AttrKind == AttributeList::AT_ObjCBridgeRelated) {
353 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
354 ScopeName, ScopeLoc, Syntax);
356 }
else if (AttrKind == AttributeList::AT_TypeTagForDatatype) {
357 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
358 ScopeName, ScopeLoc, Syntax);
361 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
368 std::unique_ptr<ParseScope> PrototypeScope;
375 for (
unsigned i = 0; i != FTI.
NumParams; ++i) {
381 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
400 if (AttrName->
getName() ==
"property") {
406 T.expectAndConsume(diag::err_expected_lparen_after,
415 bool HasInvalidAccessor =
false;
420 if (!Tok.
is(tok::identifier)) {
422 if (Tok.
is(tok::r_paren) && !HasInvalidAccessor &&
423 AccessorNames[AK_Put] ==
nullptr &&
424 AccessorNames[AK_Get] ==
nullptr) {
425 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
436 if (KindStr ==
"get") {
438 }
else if (KindStr ==
"put") {
442 }
else if (KindStr ==
"set") {
443 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
450 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
452 HasInvalidAccessor =
true;
453 goto next_property_accessor;
457 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
458 HasInvalidAccessor =
true;
477 if (!Tok.
is(tok::identifier)) {
482 if (Kind == AK_Invalid) {
484 }
else if (AccessorNames[Kind] !=
nullptr) {
486 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
492 next_property_accessor:
498 if (Tok.
is(tok::r_paren))
501 Diag(Tok.
getLocation(), diag::err_ms_property_expected_comma_or_rparen);
506 if (!HasInvalidAccessor)
508 AccessorNames[AK_Get], AccessorNames[AK_Put],
511 return !HasInvalidAccessor;
515 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
522 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
536 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
537 assert(Tok.
is(tok::kw___declspec) &&
"Not a declspec!");
539 while (Tok.
is(tok::kw___declspec)) {
542 if (T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
548 while (Tok.
isNot(tok::r_paren)) {
555 bool IsString = Tok.
getKind() == tok::string_literal;
556 if (!IsString && Tok.
getKind() != tok::identifier &&
557 Tok.
getKind() != tok::kw_restrict) {
558 Diag(Tok, diag::err_ms_declspec_type);
568 StringRef Str = PP.
getSpelling(Tok, StrBuffer, &Invalid);
574 AttrNameLoc = ConsumeStringToken();
580 bool AttrHandled =
false;
583 if (Tok.
is(tok::l_paren))
584 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
585 else if (AttrName->
getName() ==
"property")
591 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
596 *End = T.getCloseLocation();
604 case tok::kw___fastcall:
605 case tok::kw___stdcall:
606 case tok::kw___thiscall:
607 case tok::kw___cdecl:
608 case tok::kw___vectorcall:
609 case tok::kw___ptr64:
611 case tok::kw___ptr32:
612 case tok::kw___unaligned:
614 case tok::kw___uptr: {
617 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
627 void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
633 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) << Range;
643 case tok::kw_volatile:
644 case tok::kw___fastcall:
645 case tok::kw___stdcall:
646 case tok::kw___thiscall:
647 case tok::kw___cdecl:
648 case tok::kw___vectorcall:
649 case tok::kw___ptr32:
650 case tok::kw___ptr64:
652 case tok::kw___unaligned:
665 while (Tok.
is(tok::kw___pascal)) {
668 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
675 while (Tok.
is(tok::kw___kernel)) {
678 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
686 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
694 case tok::kw__Nonnull:
695 case tok::kw__Nullable:
696 case tok::kw__Null_unspecified: {
700 Diag(AttrNameLoc, diag::ext_nullability)
702 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
713 return (Separator ==
'.' || Separator ==
'_');
725 if (!Tok.
is(tok::numeric_constant)) {
726 Diag(Tok, diag::err_expected_version);
738 const char *ThisTokBegin = &Buffer[0];
741 bool Invalid =
false;
742 unsigned ActualLength = PP.
getSpelling(Tok, ThisTokBegin, &Invalid);
747 unsigned AfterMajor = 0;
749 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
750 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
754 if (AfterMajor == 0) {
755 Diag(Tok, diag::err_expected_version);
761 if (AfterMajor == ActualLength) {
766 Diag(Tok, diag::err_zero_version);
773 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
775 || (AfterMajor + 1 == ActualLength)) {
776 Diag(Tok, diag::err_expected_version);
783 unsigned AfterMinor = AfterMajor + 1;
785 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
786 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
790 if (AfterMinor == ActualLength) {
794 if (Major == 0 && Minor == 0) {
795 Diag(Tok, diag::err_zero_version);
799 return VersionTuple(Major, Minor, (AfterMajorSeparator ==
'_'));
802 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
805 Diag(Tok, diag::err_expected_version);
812 if (AfterMajorSeparator != AfterMinorSeparator)
813 Diag(Tok, diag::warn_expected_consistent_version_separator);
816 unsigned AfterSubminor = AfterMinor + 1;
817 unsigned Subminor = 0;
818 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
819 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
823 if (AfterSubminor != ActualLength) {
824 Diag(Tok, diag::err_expected_version);
830 return VersionTuple(Major, Minor, Subminor, (AfterMajorSeparator ==
'_'));
852 void Parser::ParseAvailabilityAttribute(
IdentifierInfo &Availability,
859 enum { Introduced, Deprecated, Obsoleted,
Unknown };
865 if (T.consumeOpen()) {
866 Diag(Tok, diag::err_expected) << tok::l_paren;
871 if (Tok.
isNot(tok::identifier)) {
872 Diag(Tok, diag::err_availability_expected_platform);
879 if (ExpectAndConsume(tok::comma)) {
886 if (!Ident_introduced) {
897 if (Tok.
isNot(tok::identifier)) {
898 Diag(Tok, diag::err_availability_expected_change);
905 if (Keyword == Ident_unavailable) {
906 if (UnavailableLoc.
isValid()) {
907 Diag(KeywordLoc, diag::err_availability_redundant)
910 UnavailableLoc = KeywordLoc;
914 if (Tok.
isNot(tok::equal)) {
915 Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
920 if (Keyword == Ident_message) {
921 if (Tok.
isNot(tok::string_literal)) {
922 Diag(Tok, diag::err_expected_string_literal)
927 MessageExpr = ParseStringLiteralExpression();
930 cast_or_null<StringLiteral>(MessageExpr.
get())) {
931 if (MessageStringLiteral->getCharByteWidth() != 1) {
932 Diag(MessageStringLiteral->getSourceRange().getBegin(),
933 diag::err_expected_string_literal)
944 if ((Keyword == Ident_introduced || Keyword == Ident_deprecated) &&
945 Tok.
is(tok::identifier)) {
949 if (Keyword == Ident_introduced)
950 UnavailableLoc = KeywordLoc;
958 if (Version.
empty()) {
964 if (Keyword == Ident_introduced)
966 else if (Keyword == Ident_deprecated)
968 else if (Keyword == Ident_obsoleted)
974 if (!Changes[Index].KeywordLoc.
isInvalid()) {
975 Diag(KeywordLoc, diag::err_availability_redundant)
978 Changes[Index].VersionRange.
getEnd());
982 Changes[Index].
Version = Version;
985 Diag(KeywordLoc, diag::err_availability_unknown_change)
986 << Keyword << VersionRange;
992 if (T.consumeClose())
996 *endLoc = T.getCloseLocation();
1000 if (UnavailableLoc.
isValid()) {
1001 bool Complained =
false;
1002 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1003 if (Changes[Index].KeywordLoc.
isValid()) {
1005 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1007 Changes[Index].VersionRange.
getEnd());
1018 attrs.
addNew(&Availability,
1019 SourceRange(AvailabilityLoc, T.getCloseLocation()),
1020 ScopeName, ScopeLoc,
1022 Changes[Introduced],
1023 Changes[Deprecated],
1025 UnavailableLoc, MessageExpr.
get(),
1040 void Parser::ParseObjCBridgeRelatedAttribute(
IdentifierInfo &ObjCBridgeRelated,
1049 if (T.consumeOpen()) {
1050 Diag(Tok, diag::err_expected) << tok::l_paren;
1055 if (Tok.
isNot(tok::identifier)) {
1056 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1061 if (ExpectAndConsume(tok::comma)) {
1068 if (Tok.
is(tok::identifier)) {
1069 ClassMethod = ParseIdentifierLoc();
1071 Diag(Tok, diag::err_objcbridge_related_selector_name);
1077 if (Tok.
is(tok::colon))
1078 Diag(Tok, diag::err_objcbridge_related_selector_name);
1080 Diag(Tok, diag::err_expected) << tok::comma;
1087 if (Tok.
is(tok::identifier))
1088 InstanceMethod = ParseIdentifierLoc();
1089 else if (Tok.
isNot(tok::r_paren)) {
1090 Diag(Tok, diag::err_expected) << tok::r_paren;
1096 if (T.consumeClose())
1100 *endLoc = T.getCloseLocation();
1103 attrs.
addNew(&ObjCBridgeRelated,
1104 SourceRange(ObjCBridgeRelatedLoc, T.getCloseLocation()),
1105 ScopeName, ScopeLoc,
1115 void Parser::LateParsedDeclaration::ParseLexedAttributes() {}
1117 void Parser::LateParsedClass::ParseLexedAttributes() {
1118 Self->ParseLexedAttributes(*Class);
1121 void Parser::LateParsedAttribute::ParseLexedAttributes() {
1122 Self->ParseLexedAttribute(*
this,
true,
false);
1127 void Parser::ParseLexedAttributes(ParsingClass &Class) {
1130 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
1133 if (HasTemplateScope)
1137 bool AlreadyHasClassScope = Class.TopLevelClass;
1139 ParseScope ClassScope(
this, ScopeFlags, !AlreadyHasClassScope);
1140 ParseScopeFlags ClassScopeFlags(
this, ScopeFlags, AlreadyHasClassScope);
1143 if (!AlreadyHasClassScope)
1145 Class.TagOrTemplate);
1146 if (!Class.LateParsedDeclarations.empty()) {
1147 for (
unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
1148 Class.LateParsedDeclarations[i]->ParseLexedAttributes();
1152 if (!AlreadyHasClassScope)
1154 Class.TagOrTemplate);
1158 void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs,
Decl *D,
1159 bool EnterScope,
bool OnDefinition) {
1160 assert(LAs.parseSoon() &&
1161 "Attribute list should be marked for immediate parsing.");
1162 for (
unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
1165 ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
1176 void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
1177 bool EnterScope,
bool OnDefinition) {
1185 LA.Toks.push_back(AttrEnd);
1189 LA.Toks.push_back(Tok);
1192 ConsumeAnyToken(
true);
1197 if (LA.Decls.size() > 0) {
1198 Decl *D = LA.Decls[0];
1206 if (LA.Decls.size() == 1) {
1210 if (HasTemplateScope)
1219 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
1227 if (HasTemplateScope) {
1233 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
1238 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
1244 Diag(Tok, diag::warn_attribute_on_function_definition)
1247 for (
unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i)
1259 void Parser::ParseTypeTagForDatatypeAttribute(
IdentifierInfo &AttrName,
1266 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1271 if (Tok.
isNot(tok::identifier)) {
1272 Diag(Tok, diag::err_expected) << tok::identifier;
1278 if (ExpectAndConsume(tok::comma)) {
1290 bool LayoutCompatible =
false;
1291 bool MustBeNull =
false;
1293 if (Tok.
isNot(tok::identifier)) {
1294 Diag(Tok, diag::err_expected) << tok::identifier;
1299 if (Flag->
isStr(
"layout_compatible"))
1300 LayoutCompatible =
true;
1301 else if (Flag->
isStr(
"must_be_null"))
1304 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1311 if (!T.consumeClose()) {
1313 ArgumentKind, MatchingCType.
get(),
1314 LayoutCompatible, MustBeNull, Syntax);
1318 *EndLoc = T.getCloseLocation();
1329 bool Parser::DiagnoseProhibitedCXX11Attribute() {
1330 assert(Tok.
is(tok::l_square) &&
NextToken().
is(tok::l_square));
1332 switch (isCXX11AttributeSpecifier(
true)) {
1333 case CAK_NotAttributeSpecifier:
1337 case CAK_InvalidAttributeSpecifier:
1341 case CAK_AttributeSpecifier:
1346 assert(Tok.
is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1348 Diag(BeginLoc, diag::err_attributes_not_allowed)
1352 llvm_unreachable(
"All cases handled above.");
1359 void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
1361 assert((Tok.
is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1362 Tok.
is(tok::kw_alignas));
1366 ParseCXX11Attributes(Attrs);
1369 Diag(Loc, diag::err_attributes_not_allowed)
1374 void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
1375 Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
1379 void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs) {
1383 Diag(AttrList->
getLoc(), diag::err_attribute_not_type_attr)
1387 AttrList = AttrList->
getNext();
1393 void Parser::handleDeclspecAlignBeforeClassKey(ParsedAttributesWithRange &Attrs,
1407 if (AL->
getKind() == AttributeList::AT_Aligned &&
1449 ParsedAttributesWithRange &attrs) {
1455 Decl *SingleDecl =
nullptr;
1456 Decl *OwnedType =
nullptr;
1458 case tok::kw_template:
1459 case tok::kw_export:
1460 ProhibitAttributes(attrs);
1461 SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
1463 case tok::kw_inline:
1466 ProhibitAttributes(attrs);
1468 return ParseNamespace(Context, DeclEnd, InlineLoc);
1470 return ParseSimpleDeclaration(Context, DeclEnd, attrs,
1472 case tok::kw_namespace:
1473 ProhibitAttributes(attrs);
1474 return ParseNamespace(Context, DeclEnd);
1476 SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1477 DeclEnd, attrs, &OwnedType);
1479 case tok::kw_static_assert:
1480 case tok::kw__Static_assert:
1481 ProhibitAttributes(attrs);
1482 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1485 return ParseSimpleDeclaration(Context, DeclEnd, attrs,
true);
1511 Parser::ParseSimpleDeclaration(
unsigned Context,
1513 ParsedAttributesWithRange &Attrs,
1514 bool RequireSemi, ForRangeInit *FRI) {
1518 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1519 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(),
AS_none, DSContext);
1524 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1529 if (Tok.
is(tok::semi)) {
1530 ProhibitAttributes(Attrs);
1535 DS.complete(TheDecl);
1540 return ParseDeclGroup(DS, Context, &DeclEnd, FRI);
1545 bool Parser::MightBeDeclarator(
unsigned Context) {
1547 case tok::annot_cxxscope:
1548 case tok::annot_template_id:
1550 case tok::code_completion:
1551 case tok::coloncolon:
1553 case tok::kw___attribute:
1554 case tok::kw_operator:
1570 case tok::identifier:
1572 case tok::code_completion:
1573 case tok::coloncolon:
1576 case tok::equalequal:
1577 case tok::kw_alignas:
1579 case tok::kw___attribute:
1597 case tok::identifier:
1620 if (Tok.
isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
1644 case tok::kw_inline:
1649 (!ParsingInObjCContainer || CurParsedObjCImpl))
1653 case tok::kw_namespace:
1658 (!ParsingInObjCContainer || CurParsedObjCImpl))
1665 ParsingInObjCContainer)
1677 case tok::annot_module_begin:
1678 case tok::annot_module_end:
1679 case tok::annot_module_include:
1696 ForRangeInit *FRI) {
1702 if (!D.hasName() && !D.mayOmitIdentifier()) {
1710 LateParsedAttrList LateParsedAttrs(
true);
1711 if (D.isFunctionDeclarator()) {
1712 MaybeParseGNUAttributes(D, &LateParsedAttrs);
1717 if (Tok.
is(tok::kw__Noreturn)) {
1719 const char *PrevSpec;
1725 MaybeParseGNUAttributes(D, &LateParsedAttrs);
1726 Fixit &= Tok.
isOneOf(tok::semi, tok::l_brace, tok::kw_try);
1728 Diag(Loc, diag::err_c11_noreturn_misplaced)
1730 << (Fixit ?
FixItHint::CreateInsertion(D.getLocStart(),
"_Noreturn ")
1736 if (D.isFunctionDeclarator() &&
1740 !isDeclarationAfterDeclarator()) {
1746 if (isStartOfFunctionDefinition(D)) {
1748 Diag(Tok, diag::err_function_declared_typedef);
1755 ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
1759 if (isDeclarationSpecifier()) {
1767 Diag(Tok, diag::err_expected_fn_body);
1772 if (Tok.
is(tok::l_brace)) {
1773 Diag(Tok, diag::err_function_definition_not_allowed);
1780 if (ParseAsmAttributesAfterDeclarator(D))
1789 if (FRI && (Tok.
is(tok::colon) || isTokIdentifier_in())) {
1790 bool IsForRangeLoop =
false;
1792 IsForRangeLoop =
true;
1793 if (Tok.
is(tok::l_brace))
1794 FRI->RangeExpr = ParseBraceInitializer();
1803 D.complete(ThisDecl);
1808 Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(
1809 D, ParsedTemplateInfo(), FRI);
1810 if (LateParsedAttrs.size() > 0)
1811 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
1812 D.complete(FirstDecl);
1814 DeclsInGroup.push_back(FirstDecl);
1822 if (Tok.
isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
1826 Diag(CommaLoc, diag::err_expected_semi_declaration)
1834 D.setCommaLoc(CommaLoc);
1843 MaybeParseGNUAttributes(D);
1847 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
1850 if (!D.isInvalidType()) {
1851 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
1852 D.complete(ThisDecl);
1854 DeclsInGroup.push_back(ThisDecl);
1863 ? diag::err_invalid_token_after_toplevel_declarator
1864 : diag::err_expected_semi_declaration)) {
1868 if (!isDeclarationSpecifier()) {
1879 bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
1881 if (Tok.
is(tok::kw_asm)) {
1884 if (AsmLabel.isInvalid()) {
1893 MaybeParseGNUAttributes(D);
1919 Decl *Parser::ParseDeclarationAfterDeclarator(
1920 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
1921 if (ParseAsmAttributesAfterDeclarator(D))
1924 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
1927 Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
1928 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
1930 Decl *ThisDecl =
nullptr;
1931 switch (TemplateInfo.Kind) {
1932 case ParsedTemplateInfo::NonTemplate:
1936 case ParsedTemplateInfo::Template:
1937 case ParsedTemplateInfo::ExplicitSpecialization: {
1939 *TemplateInfo.TemplateParams,
1941 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl))
1944 ThisDecl = VT->getTemplatedDecl();
1947 case ParsedTemplateInfo::ExplicitInstantiation: {
1948 if (Tok.
is(tok::semi)) {
1950 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
1955 ThisDecl = ThisRes.
get();
1963 Diag(Tok, diag::err_template_defn_explicit_instantiation)
1970 diag::err_explicit_instantiation_with_definition)
1992 if (isTokenEqualOrEqualTypo()) {
1995 if (Tok.
is(tok::kw_delete)) {
2001 }
else if (Tok.
is(tok::kw_default)) {
2013 if (Tok.
is(tok::code_completion)) {
2025 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2029 FRI->ColonLoc = EqualLoc;
2031 FRI->RangeExpr = Init;
2039 if (Init.isInvalid()) {
2041 StopTokens.push_back(tok::comma);
2043 StopTokens.push_back(tok::r_paren);
2048 false, TypeContainsAuto);
2050 }
else if (Tok.
is(tok::l_paren)) {
2056 CommaLocsTy CommaLocs;
2063 if (ParseExpressionList(Exprs, CommaLocs, [&] {
2065 cast<VarDecl>(ThisDecl)->getType()->getCanonicalTypeInternal(),
2079 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
2080 "Unexpected number of commas!");
2088 T.getCloseLocation(),
2091 true, TypeContainsAuto);
2093 }
else if (
getLangOpts().CPlusPlus11 && Tok.
is(tok::l_brace) &&
2096 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2110 if (Init.isInvalid()) {
2114 true, TypeContainsAuto);
2132 DeclSpecContext DSC) {
2136 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
2141 Diag(Tok, diag::err_expected_type);
2144 Diag(Tok, diag::err_typename_requires_specqual);
2155 diag::err_typename_invalid_storageclass);
2196 return T.
isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2197 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2211 const ParsedTemplateInfo &TemplateInfo,
2213 ParsedAttributesWithRange &Attrs) {
2214 assert(Tok.
is(tok::identifier) &&
"should have identifier");
2236 if (!isTypeSpecifier(DSC) && !
getLangOpts().CPlusPlus &&
2249 AnnotateScopeToken(*SS,
false);
2259 if (SS ==
nullptr) {
2260 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2266 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2268 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2270 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2272 TagName=
"__interface"; FixitTagName =
"__interface ";
2273 TagKind=tok::kw___interface;
break;
2275 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2283 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2284 << TokenName << TagName <<
getLangOpts().CPlusPlus
2290 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2291 << TokenName << TagName;
2295 if (TagKind == tok::kw_enum)
2296 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
2298 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2299 false, DSC_normal, Attrs);
2306 if (!isTypeSpecifier(DSC) &&
2307 (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
2311 case tok::l_paren: {
2318 TentativeParsingAction PA(*
this);
2320 TPResult TPR = TryParseDeclarator(
false);
2331 if (DSC == DSC_class || (DSC == DSC_top_level && SS)) {
2334 Diag(Loc, diag::err_constructor_bad_name)
2351 AnnotateScopeToken(*SS,
false);
2373 const char *PrevSpec;
2404 Parser::DeclSpecContext
2405 Parser::getDeclSpecContextFromDeclaratorContext(
unsigned Context) {
2409 return DSC_top_level;
2411 return DSC_template_type_arg;
2413 return DSC_trailing;
2416 return DSC_alias_declaration;
2432 if (isTypeIdInParens()) {
2457 assert(Tok.
isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
2458 "Not an alignment-specifier!");
2464 if (T.expectAndConsume())
2468 ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
2476 *EndLoc = T.getCloseLocation();
2479 ArgExprs.push_back(ArgExpr.
get());
2480 Attrs.
addNew(KWName, KWLoc,
nullptr, KWLoc, ArgExprs.data(), 1,
2493 DeclSpecContext DSContext,
2494 LateParsedAttrList *LateAttrs) {
2497 bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
2500 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
2501 tok::annot_template_id) &&
2507 bool HasScope = Tok.
is(tok::annot_cxxscope);
2513 bool MightBeDeclarator =
true;
2514 if (Tok.
isOneOf(tok::kw_typename, tok::annot_typename)) {
2516 MightBeDeclarator =
false;
2517 }
else if (AfterScope.
is(tok::annot_template_id)) {
2523 MightBeDeclarator =
false;
2524 }
else if (AfterScope.
is(tok::identifier)) {
2525 const Token &Next = HasScope ? GetLookAheadToken(2) : NextToken();
2529 if (Next.
isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
2530 tok::annot_cxxscope, tok::coloncolon)) {
2532 MightBeDeclarator =
false;
2533 }
else if (HasScope) {
2544 switch (Classification.
getKind()) {
2551 llvm_unreachable(
"typo correction and nested name specifiers not "
2557 MightBeDeclarator =
false;
2570 if (MightBeDeclarator)
2575 diag::err_expected_after)
2586 ParsedTemplateInfo NotATemplate;
2587 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
2618 void Parser::ParseDeclarationSpecifiers(
DeclSpec &DS,
2619 const ParsedTemplateInfo &TemplateInfo,
2621 DeclSpecContext DSContext,
2622 LateParsedAttrList *LateAttrs) {
2631 bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
2632 bool AttrsLastTime =
false;
2633 ParsedAttributesWithRange attrs(AttrFactory);
2638 bool isStorageClass =
false;
2639 const char *PrevSpec =
nullptr;
2640 unsigned DiagID = 0;
2660 ProhibitAttributes(attrs);
2665 ProhibitCXX11Attributes(attrs);
2672 DS.
Finish(Actions, Policy);
2676 case tok::kw_alignas:
2678 goto DoneWithDeclSpec;
2680 ProhibitAttributes(attrs);
2687 ParseCXX11Attributes(attrs);
2688 AttrsLastTime =
true;
2691 case tok::code_completion: {
2694 bool AllowNonIdentifiers
2700 bool AllowNestedNameSpecifiers
2701 = DSContext == DSC_top_level ||
2705 AllowNonIdentifiers,
2706 AllowNestedNameSpecifiers);
2707 return cutOffParsing();
2712 else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
2715 else if (DSContext == DSC_class)
2717 else if (CurParsedObjCImpl)
2721 return cutOffParsing();
2724 case tok::coloncolon:
2729 goto DoneWithDeclSpec;
2731 if (Tok.
is(tok::coloncolon))
2732 goto DoneWithDeclSpec;
2735 case tok::annot_cxxscope: {
2737 goto DoneWithDeclSpec;
2746 if (Next.
is(tok::annot_template_id) &&
2771 if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
2774 if (isConstructorDeclarator(
false)) {
2779 goto DoneWithDeclSpec;
2787 diag::err_out_of_line_template_id_type_names_constructor)
2788 << TemplateId->
Name << 0 ;
2793 assert(Tok.
is(tok::annot_template_id) &&
2794 "ParseOptionalCXXScopeSpecifier not working");
2795 AnnotateTemplateIdTokenAsType();
2799 if (Next.
is(tok::annot_typename)) {
2806 PrevSpec, DiagID, T, Policy);
2816 if (Next.
isNot(tok::identifier))
2817 goto DoneWithDeclSpec;
2821 if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
2824 if (isConstructorDeclarator(
false))
2825 goto DoneWithDeclSpec;
2834 diag::err_out_of_line_template_id_type_names_constructor)
2851 ParsedAttributesWithRange Attrs(AttrFactory);
2852 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
2853 if (!Attrs.
empty()) {
2854 AttrsLastTime =
true;
2855 attrs.takeAllFrom(Attrs);
2859 goto DoneWithDeclSpec;
2866 DiagID, TypeRep, Policy);
2876 case tok::annot_typename: {
2880 goto DoneWithDeclSpec;
2898 case tok::kw___is_signed:
2909 TryKeywordIdentFallback(
true);
2912 goto DoneWithDeclSpec;
2915 case tok::kw___super:
2916 case tok::kw_decltype:
2917 case tok::identifier: {
2922 goto DoneWithDeclSpec;
2929 goto DoneWithDeclSpec;
2931 if (!Tok.
is(tok::identifier))
2936 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
2942 goto DoneWithDeclSpec;
2944 if (DSContext == DSC_objc_method_result && isObjCInstancetype()) {
2948 DiagID, TypeRep, Policy);
2965 if (!TypeRep && DSContext == DSC_template_type_arg &&
2974 ParsedAttributesWithRange Attrs(AttrFactory);
2975 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
2976 if (!Attrs.
empty()) {
2977 AttrsLastTime =
true;
2978 attrs.takeAllFrom(Attrs);
2982 goto DoneWithDeclSpec;
2989 isConstructorDeclarator(
true))
2990 goto DoneWithDeclSpec;
2993 DiagID, TypeRep, Policy);
3005 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3020 case tok::annot_template_id: {
3025 goto DoneWithDeclSpec;
3033 isConstructorDeclarator(TemplateId->
SS.
isEmpty()))
3034 goto DoneWithDeclSpec;
3038 AnnotateTemplateIdTokenAsType();
3043 case tok::kw___attribute:
3048 case tok::kw___declspec:
3053 case tok::kw___forceinline: {
3062 case tok::kw___sptr:
3063 case tok::kw___uptr:
3064 case tok::kw___ptr64:
3065 case tok::kw___ptr32:
3067 case tok::kw___cdecl:
3068 case tok::kw___stdcall:
3069 case tok::kw___fastcall:
3070 case tok::kw___thiscall:
3071 case tok::kw___vectorcall:
3072 case tok::kw___unaligned:
3077 case tok::kw___pascal:
3082 case tok::kw___kernel:
3087 case tok::kw__Nonnull:
3088 case tok::kw__Nullable:
3089 case tok::kw__Null_unspecified:
3094 case tok::kw___kindof:
3101 case tok::kw_typedef:
3103 PrevSpec, DiagID, Policy);
3104 isStorageClass =
true;
3106 case tok::kw_extern:
3108 Diag(Tok, diag::ext_thread_before) <<
"extern";
3110 PrevSpec, DiagID, Policy);
3111 isStorageClass =
true;
3113 case tok::kw___private_extern__:
3115 Loc, PrevSpec, DiagID, Policy);
3116 isStorageClass =
true;
3118 case tok::kw_static:
3120 Diag(Tok, diag::ext_thread_before) <<
"static";
3122 PrevSpec, DiagID, Policy);
3123 isStorageClass =
true;
3127 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
3129 PrevSpec, DiagID, Policy);
3131 Diag(Tok, diag::ext_auto_storage_class)
3138 PrevSpec, DiagID, Policy);
3139 isStorageClass =
true;
3141 case tok::kw___auto_type:
3142 Diag(Tok, diag::ext_auto_type);
3146 case tok::kw_register:
3148 PrevSpec, DiagID, Policy);
3149 isStorageClass =
true;
3151 case tok::kw_mutable:
3153 PrevSpec, DiagID, Policy);
3154 isStorageClass =
true;
3156 case tok::kw___thread:
3159 isStorageClass =
true;
3161 case tok::kw_thread_local:
3165 case tok::kw__Thread_local:
3167 Loc, PrevSpec, DiagID);
3168 isStorageClass =
true;
3172 case tok::kw_inline:
3175 case tok::kw_virtual:
3178 case tok::kw_explicit:
3181 case tok::kw__Noreturn:
3183 Diag(Loc, diag::ext_c11_noreturn);
3188 case tok::kw__Alignas:
3190 Diag(Tok, diag::ext_c11_alignment) << Tok.
getName();
3195 case tok::kw_friend:
3196 if (DSContext == DSC_class)
3200 DiagID = diag::err_friend_invalid_in_context;
3206 case tok::kw___module_private__:
3211 case tok::kw_constexpr:
3216 case tok::kw_concept:
3233 case tok::kw___int64:
3237 case tok::kw_signed:
3241 case tok::kw_unsigned:
3245 case tok::kw__Complex:
3249 case tok::kw__Imaginary:
3265 case tok::kw___int128:
3277 case tok::kw_double:
3281 case tok::kw_wchar_t:
3285 case tok::kw_char16_t:
3289 case tok::kw_char32_t:
3295 if (Tok.
is(tok::kw_bool) &&
3299 DiagID = diag::err_bool_redeclaration;
3308 case tok::kw__Decimal32:
3312 case tok::kw__Decimal64:
3316 case tok::kw__Decimal128:
3320 case tok::kw___vector:
3323 case tok::kw___pixel:
3326 case tok::kw___bool:
3334 goto DoneWithDeclSpec;
3336 isInvalid = DS.
SetTypePipe(
true, Loc, PrevSpec, DiagID, Policy);
3338 case tok::kw___unknown_anytype:
3340 PrevSpec, DiagID, Policy);
3345 case tok::kw_struct:
3346 case tok::kw___interface:
3347 case tok::kw_union: {
3354 ParsedAttributesWithRange Attributes(AttrFactory);
3355 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
3356 EnteringContext, DSContext, Attributes);
3360 if (!Attributes.empty()) {
3361 AttrsLastTime =
true;
3362 attrs.takeAllFrom(Attributes);
3370 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
3378 case tok::kw_volatile:
3382 case tok::kw_restrict:
3388 case tok::kw_typename:
3391 goto DoneWithDeclSpec;
3393 if (!Tok.
is(tok::kw_typename))
3398 case tok::kw_typeof:
3399 ParseTypeofSpecifier(DS);
3402 case tok::annot_decltype:
3403 ParseDecltypeSpecifier(DS);
3406 case tok::kw___underlying_type:
3407 ParseUnderlyingTypeSpecifier(DS);
3410 case tok::kw__Atomic:
3416 ParseAtomicSpecifier(DS);
3424 case tok::kw___generic:
3428 DiagID = diag::err_opencl_unknown_type_specifier;
3433 case tok::kw___private:
3434 case tok::kw___global:
3435 case tok::kw___local:
3436 case tok::kw___constant:
3437 case tok::kw___read_only:
3438 case tok::kw___write_only:
3439 case tok::kw___read_write:
3448 goto DoneWithDeclSpec;
3455 PrevSpec, DiagID, Type.
get(),
3457 Diag(StartLoc, DiagID) << PrevSpec;
3470 assert(PrevSpec &&
"Method did not return previous specifier!");
3473 if (DiagID == diag::ext_duplicate_declspec)
3476 else if (DiagID == diag::err_opencl_unknown_type_specifier)
3477 Diag(Tok, DiagID) << PrevSpec << isStorageClass;
3479 Diag(Tok, DiagID) << PrevSpec;
3483 if (DiagID != diag::err_bool_redeclaration)
3486 AttrsLastTime =
false;
3507 void Parser::ParseStructDeclaration(
3511 if (Tok.
is(tok::kw___extension__)) {
3515 return ParseStructDeclaration(DS, FieldsCallback);
3519 ParseSpecifierQualifierList(DS);
3523 if (Tok.
is(tok::semi)) {
3531 bool FirstDeclarator =
true;
3535 DeclaratorInfo.D.setCommaLoc(CommaLoc);
3538 if (!FirstDeclarator)
3539 MaybeParseGNUAttributes(DeclaratorInfo.D);
3543 if (Tok.
isNot(tok::colon)) {
3546 ParseDeclarator(DeclaratorInfo.D);
3548 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.
getLocation());
3552 if (Res.isInvalid())
3555 DeclaratorInfo.BitfieldSize = Res.get();
3559 MaybeParseGNUAttributes(DeclaratorInfo.D);
3562 FieldsCallback(DeclaratorInfo);
3569 FirstDeclarator =
false;
3586 "parsing struct/union body");
3590 if (T.consumeOpen())
3599 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
3604 if (Tok.
is(tok::semi)) {
3605 ConsumeExtraSemi(InsideStruct, TagType);
3610 if (Tok.
is(tok::kw__Static_assert)) {
3612 ParseStaticAssertDeclaration(DeclEnd);
3616 if (Tok.
is(tok::annot_pragma_pack)) {
3621 if (Tok.
is(tok::annot_pragma_align)) {
3622 HandlePragmaAlign();
3626 if (Tok.
is(tok::annot_pragma_openmp)) {
3628 auto Res = ParseOpenMPDeclarativeDirective();
3634 if (!Tok.
is(tok::at)) {
3640 FD.D, FD.BitfieldSize);
3641 FieldDecls.push_back(Field);
3647 ParseStructDeclaration(DS, CFieldCallback);
3651 Diag(Tok, diag::err_unexpected_at);
3656 ExpectAndConsume(tok::l_paren);
3657 if (!Tok.
is(tok::identifier)) {
3658 Diag(Tok, diag::err_expected) << tok::identifier;
3665 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
3667 ExpectAndConsume(tok::r_paren);
3673 if (Tok.
is(tok::r_brace)) {
3674 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
3678 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
3689 MaybeParseGNUAttributes(attrs);
3692 RecordLoc, TagDecl, FieldDecls,
3693 T.getOpenLocation(), T.getCloseLocation(),
3697 T.getCloseLocation());
3731 const ParsedTemplateInfo &TemplateInfo,
3734 if (Tok.
is(tok::code_completion)) {
3737 return cutOffParsing();
3741 ParsedAttributesWithRange attrs(AttrFactory);
3742 MaybeParseGNUAttributes(attrs);
3743 MaybeParseCXX11Attributes(attrs);
3744 MaybeParseMicrosoftDeclSpecs(attrs);
3747 bool IsScopedUsingClassTag =
false;
3750 if (Tok.
isOneOf(tok::kw_class, tok::kw_struct)) {
3752 : diag::ext_scoped_enum);
3753 IsScopedUsingClassTag = Tok.
is(tok::kw_class);
3758 ProhibitAttributes(attrs);
3761 MaybeParseGNUAttributes(attrs);
3762 MaybeParseCXX11Attributes(attrs);
3763 MaybeParseMicrosoftDeclSpecs(attrs);
3772 bool shouldDelayDiagsInTag =
3773 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3774 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3778 bool AllowDeclaration = DSC != DSC_trailing;
3780 bool AllowFixedUnderlyingType = AllowDeclaration &&
3791 if (ParseOptionalCXXScopeSpecifier(Spec,
ParsedType(),
3795 if (Spec.
isSet() && Tok.
isNot(tok::identifier)) {
3796 Diag(Tok, diag::err_expected) << tok::identifier;
3797 if (Tok.
isNot(tok::l_brace)) {
3809 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::l_brace) &&
3810 !(AllowFixedUnderlyingType && Tok.
is(tok::colon))) {
3811 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
3821 if (Tok.
is(tok::identifier)) {
3826 if (!Name && ScopedEnumKWLoc.
isValid()) {
3829 Diag(Tok, diag::err_scoped_enum_missing_identifier);
3831 IsScopedUsingClassTag =
false;
3836 if (shouldDelayDiagsInTag)
3837 diagsFromTag.done();
3843 if (AllowFixedUnderlyingType && Tok.
is(tok::colon)) {
3844 bool PossibleBitfield =
false;
3845 if (CanBeBitfield) {
3859 PossibleBitfield =
true;
3865 GetLookAheadToken(2).
getKind() == tok::semi) {
3872 TentativeParsingAction TPA(*
this);
3887 PossibleBitfield =
true;
3899 if (!PossibleBitfield) {
3904 Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
3907 Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type) << Range;
3909 Diag(StartLoc, diag::ext_c_enum_fixed_underlying_type) << Range;
3925 if (!AllowDeclaration) {
3927 }
else if (Tok.
is(tok::l_brace)) {
3937 }
else if (!isTypeSpecifier(DSC) &&
3938 (Tok.
is(tok::semi) ||
3940 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
3942 if (Tok.
isNot(tok::semi)) {
3944 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
3955 diagsFromTag.redelay();
3959 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
3963 Diag(Tok, diag::err_enum_template);
3968 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
3971 Diag(StartLoc, diag::err_explicit_instantiation_enum);
3975 assert(TemplateInfo.TemplateParams &&
"no template parameters");
3977 TemplateInfo.TemplateParams->size());
3981 ProhibitAttributes(attrs);
3984 Diag(Tok, diag::err_enumerator_unnamed_no_def);
3991 handleDeclspecAlignBeforeClassKey(attrs, DS, TUK);
4001 bool IsDependent =
false;
4002 const char *PrevSpec =
nullptr;
4005 StartLoc, SS, Name, NameLoc, attrs.getList(),
4007 Owned, IsDependent, ScopedEnumKWLoc,
4008 IsScopedUsingClassTag, BaseType,
4009 DSC == DSC_type_specifier, &SkipBody);
4019 NameLoc.
isValid() ? NameLoc : StartLoc,
4020 PrevSpec, DiagID, TagDecl, Owned,
4022 Diag(StartLoc, DiagID) << PrevSpec;
4031 Diag(Tok, diag::err_expected_type_name_after_typename);
4043 NameLoc.
isValid() ? NameLoc : StartLoc,
4044 PrevSpec, DiagID, Type.
get(),
4046 Diag(StartLoc, DiagID) << PrevSpec;
4064 ParseEnumBody(StartLoc, TagDecl);
4067 NameLoc.
isValid() ? NameLoc : StartLoc,
4068 PrevSpec, DiagID, TagDecl, Owned,
4070 Diag(StartLoc, DiagID) << PrevSpec;
4093 Diag(Tok, diag::error_empty_enum);
4098 Decl *LastEnumConstDecl =
nullptr;
4101 while (Tok.
isNot(tok::r_brace)) {
4104 if (Tok.
isNot(tok::identifier)) {
4115 ParsedAttributesWithRange attrs(AttrFactory);
4116 MaybeParseGNUAttributes(attrs);
4117 ProhibitAttributes(attrs);
4122 ParseCXX11Attributes(attrs);
4127 EnumAvailabilityDiags.emplace_back(*
this);
4139 attrs.getList(), EqualLoc,
4141 EnumAvailabilityDiags.back().done();
4143 EnumConstantDecls.push_back(EnumConstDecl);
4144 LastEnumConstDecl = EnumConstDecl;
4146 if (Tok.
is(tok::identifier)) {
4149 Diag(Loc, diag::err_enumerator_list_missing_comma)
4172 if (Tok.
is(tok::r_brace) && CommaLoc.
isValid()) {
4175 diag::ext_enumerator_list_comma_cxx :
4176 diag::ext_enumerator_list_comma_c)
4179 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
4190 MaybeParseGNUAttributes(attrs);
4192 Actions.
ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(),
4193 EnumDecl, EnumConstantDecls,
4198 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
4199 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
4201 EnumAvailabilityDiags[i].redelay();
4202 PD.complete(EnumConstantDecls[i]);
4207 T.getCloseLocation());
4212 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
4213 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
4224 bool Parser::isTypeQualifier()
const {
4226 default:
return false;
4229 case tok::kw_volatile:
4230 case tok::kw_restrict:
4231 case tok::kw___private:
4232 case tok::kw___local:
4233 case tok::kw___global:
4234 case tok::kw___constant:
4235 case tok::kw___generic:
4236 case tok::kw___read_only:
4237 case tok::kw___read_write:
4238 case tok::kw___write_only:
4246 bool Parser::isKnownToBeTypeSpecifier(
const Token &Tok)
const {
4248 default:
return false;
4252 case tok::kw___int64:
4253 case tok::kw___int128:
4254 case tok::kw_signed:
4255 case tok::kw_unsigned:
4256 case tok::kw__Complex:
4257 case tok::kw__Imaginary:
4260 case tok::kw_wchar_t:
4261 case tok::kw_char16_t:
4262 case tok::kw_char32_t:
4266 case tok::kw_double:
4269 case tok::kw__Decimal32:
4270 case tok::kw__Decimal64:
4271 case tok::kw__Decimal128:
4272 case tok::kw___vector:
4276 case tok::kw_struct:
4277 case tok::kw___interface:
4283 case tok::annot_typename:
4290 bool Parser::isTypeSpecifierQualifier() {
4292 default:
return false;
4294 case tok::identifier:
4295 if (TryAltiVecVectorToken())
4298 case tok::kw_typename:
4303 if (Tok.
is(tok::identifier))
4305 return isTypeSpecifierQualifier();
4307 case tok::coloncolon:
4314 return isTypeSpecifierQualifier();
4317 case tok::kw___attribute:
4319 case tok::kw_typeof:
4324 case tok::kw___int64:
4325 case tok::kw___int128:
4326 case tok::kw_signed:
4327 case tok::kw_unsigned:
4328 case tok::kw__Complex:
4329 case tok::kw__Imaginary:
4332 case tok::kw_wchar_t:
4333 case tok::kw_char16_t:
4334 case tok::kw_char32_t:
4338 case tok::kw_double:
4341 case tok::kw__Decimal32:
4342 case tok::kw__Decimal64:
4343 case tok::kw__Decimal128:
4344 case tok::kw___vector:
4348 case tok::kw_struct:
4349 case tok::kw___interface:
4356 case tok::kw_volatile:
4357 case tok::kw_restrict:
4360 case tok::kw___unknown_anytype:
4363 case tok::annot_typename:
4370 case tok::kw___cdecl:
4371 case tok::kw___stdcall:
4372 case tok::kw___fastcall:
4373 case tok::kw___thiscall:
4374 case tok::kw___vectorcall:
4376 case tok::kw___ptr64:
4377 case tok::kw___ptr32:
4378 case tok::kw___pascal:
4379 case tok::kw___unaligned:
4381 case tok::kw__Nonnull:
4382 case tok::kw__Nullable:
4383 case tok::kw__Null_unspecified:
4385 case tok::kw___kindof:
4387 case tok::kw___private:
4388 case tok::kw___local:
4389 case tok::kw___global:
4390 case tok::kw___constant:
4391 case tok::kw___generic:
4392 case tok::kw___read_only:
4393 case tok::kw___read_write:
4394 case tok::kw___write_only:
4399 case tok::kw__Atomic:
4409 bool Parser::isDeclarationSpecifier(
bool DisambiguatingWithExpression) {
4411 default:
return false;
4416 case tok::identifier:
4420 if (TryAltiVecVectorToken())
4423 case tok::kw_decltype:
4424 case tok::kw_typename:
4429 if (Tok.
is(tok::identifier))
4437 if (DisambiguatingWithExpression &&
4438 isStartOfObjCClassMessageMissingOpenBracket())
4441 return isDeclarationSpecifier();
4443 case tok::coloncolon:
4452 return isDeclarationSpecifier();
4455 case tok::kw_typedef:
4456 case tok::kw_extern:
4457 case tok::kw___private_extern__:
4458 case tok::kw_static:
4460 case tok::kw___auto_type:
4461 case tok::kw_register:
4462 case tok::kw___thread:
4463 case tok::kw_thread_local:
4464 case tok::kw__Thread_local:
4467 case tok::kw___module_private__:
4470 case tok::kw___unknown_anytype:
4475 case tok::kw___int64:
4476 case tok::kw___int128:
4477 case tok::kw_signed:
4478 case tok::kw_unsigned:
4479 case tok::kw__Complex:
4480 case tok::kw__Imaginary:
4483 case tok::kw_wchar_t:
4484 case tok::kw_char16_t:
4485 case tok::kw_char32_t:
4490 case tok::kw_double:
4493 case tok::kw__Decimal32:
4494 case tok::kw__Decimal64:
4495 case tok::kw__Decimal128:
4496 case tok::kw___vector:
4500 case tok::kw_struct:
4502 case tok::kw___interface:
4508 case tok::kw_volatile:
4509 case tok::kw_restrict:
4512 case tok::kw_inline:
4513 case tok::kw_virtual:
4514 case tok::kw_explicit:
4515 case tok::kw__Noreturn:
4518 case tok::kw__Alignas:
4521 case tok::kw_friend:
4524 case tok::kw__Static_assert:
4527 case tok::kw_typeof:
4530 case tok::kw___attribute:
4533 case tok::annot_decltype:
4534 case tok::kw_constexpr:
4537 case tok::kw_concept:
4540 case tok::kw__Atomic:
4548 case tok::annot_typename:
4549 return !DisambiguatingWithExpression ||
4550 !isStartOfObjCClassMessageMissingOpenBracket();
4552 case tok::kw___declspec:
4553 case tok::kw___cdecl:
4554 case tok::kw___stdcall:
4555 case tok::kw___fastcall:
4556 case tok::kw___thiscall:
4557 case tok::kw___vectorcall:
4559 case tok::kw___sptr:
4560 case tok::kw___uptr:
4561 case tok::kw___ptr64:
4562 case tok::kw___ptr32:
4563 case tok::kw___forceinline:
4564 case tok::kw___pascal:
4565 case tok::kw___unaligned:
4567 case tok::kw__Nonnull:
4568 case tok::kw__Nullable:
4569 case tok::kw__Null_unspecified:
4571 case tok::kw___kindof:
4573 case tok::kw___private:
4574 case tok::kw___local:
4575 case tok::kw___global:
4576 case tok::kw___constant:
4577 case tok::kw___generic:
4578 case tok::kw___read_only:
4579 case tok::kw___read_write:
4580 case tok::kw___write_only:
4586 bool Parser::isConstructorDeclarator(
bool IsUnqualified) {
4587 TentativeParsingAction TPA(*
this);
4591 if (ParseOptionalCXXScopeSpecifier(SS,
ParsedType(),
4598 if (Tok.
isOneOf(tok::identifier, tok::annot_template_id)) {
4608 if (Tok.
isNot(tok::l_paren)) {
4616 if (Tok.
is(tok::r_paren) ||
4625 isCXX11AttributeSpecifier(
false,
4632 DeclaratorScopeObj DeclScopeObj(*
this, SS);
4634 DeclScopeObj.EnterDeclaratorScope();
4638 MaybeParseMicrosoftAttributes(Attrs);
4643 bool IsConstructor =
false;
4644 if (isDeclarationSpecifier())
4645 IsConstructor =
true;
4646 else if (Tok.
is(tok::identifier) ||
4647 (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
4652 if (Tok.
is(tok::annot_cxxscope))
4665 case tok::coloncolon:
4678 IsConstructor =
true;
4693 IsConstructor = IsUnqualified;
4698 IsConstructor =
true;
4704 return IsConstructor;
4719 void Parser::ParseTypeQualifierListOpt(
DeclSpec &DS,
unsigned AttrReqs,
4721 bool IdentifierRequired) {
4723 isCXX11AttributeSpecifier()) {
4724 ParsedAttributesWithRange attrs(AttrFactory);
4725 ParseCXX11Attributes(attrs);
4732 bool isInvalid =
false;
4733 const char *PrevSpec =
nullptr;
4734 unsigned DiagID = 0;
4738 case tok::code_completion:
4740 return cutOffParsing();
4746 case tok::kw_volatile:
4750 case tok::kw_restrict:
4754 case tok::kw__Atomic:
4756 goto DoneWithTypeQuals;
4762 case tok::kw___private:
4763 case tok::kw___global:
4764 case tok::kw___local:
4765 case tok::kw___constant:
4766 case tok::kw___generic:
4767 case tok::kw___read_only:
4768 case tok::kw___write_only:
4769 case tok::kw___read_write:
4773 case tok::kw___uptr:
4776 if ((AttrReqs & AR_DeclspecAttributesParsed) && !
getLangOpts().CPlusPlus &&
4778 if (TryKeywordIdentFallback(
false))
4781 case tok::kw___sptr:
4783 case tok::kw___ptr64:
4784 case tok::kw___ptr32:
4785 case tok::kw___cdecl:
4786 case tok::kw___stdcall:
4787 case tok::kw___fastcall:
4788 case tok::kw___thiscall:
4789 case tok::kw___vectorcall:
4790 case tok::kw___unaligned:
4791 if (AttrReqs & AR_DeclspecAttributesParsed) {
4795 goto DoneWithTypeQuals;
4796 case tok::kw___pascal:
4797 if (AttrReqs & AR_VendorAttributesParsed) {
4801 goto DoneWithTypeQuals;
4804 case tok::kw__Nonnull:
4805 case tok::kw__Nullable:
4806 case tok::kw__Null_unspecified:
4811 case tok::kw___kindof:
4817 case tok::kw___attribute:
4818 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
4820 Diag(Tok, diag::err_attributes_not_allowed);
4824 if (AttrReqs & AR_GNUAttributesParsed ||
4825 AttrReqs & AR_GNUAttributesParsedAndRejected) {
4842 assert(PrevSpec &&
"Method did not return previous specifier!");
4843 Diag(Tok, DiagID) << PrevSpec;
4851 void Parser::ParseDeclarator(
Declarator &D) {
4854 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
4858 unsigned TheContext) {
4859 if (Kind == tok::star || Kind == tok::caret)
4862 if ((Kind == tok::kw_pipe) && Lang.OpenCL && (Lang.OpenCLVersion >= 200))
4865 if (!Lang.CPlusPlus)
4868 if (Kind == tok::amp)
4876 if (Kind == tok::ampamp)
4887 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
4919 void Parser::ParseDeclaratorInternal(
Declarator &D,
4920 DirectDeclParseFunction DirectDeclParser) {
4928 (Tok.
is(tok::coloncolon) ||
4929 (Tok.
is(tok::identifier) &&
4931 Tok.
is(tok::annot_cxxscope))) {
4935 ParseOptionalCXXScopeSpecifier(SS,
ParsedType(), EnteringContext);
4938 if (Tok.
isNot(tok::star)) {
4943 AnnotateScopeToken(SS,
true);
4945 if (DirectDeclParser)
4946 (this->*DirectDeclParser)(D);
4953 ParseTypeQualifierListOpt(DS);
4957 ParseDeclaratorInternal(D, DirectDeclParser);
4981 if (DirectDeclParser)
4982 (this->*DirectDeclParser)(D);
4991 if (Kind == tok::star || Kind == tok::caret) {
4997 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
4999 ? AR_GNUAttributesParsed
5000 : AR_GNUAttributesParsedAndRejected);
5005 ParseDeclaratorInternal(D, DirectDeclParser);
5006 if (Kind == tok::star)
5027 if (Kind == tok::ampamp)
5029 diag::warn_cxx98_compat_rvalue_reference :
5030 diag::ext_rvalue_reference);
5033 ParseTypeQualifierListOpt(DS);
5042 diag::err_invalid_reference_qualifier_application) <<
"const";
5045 diag::err_invalid_reference_qualifier_application) <<
"volatile";
5049 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
5053 ParseDeclaratorInternal(D, DirectDeclParser);
5060 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
5063 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
5134 void Parser::ParseDirectDeclarator(
Declarator &D) {
5159 DeclScopeObj.EnterDeclaratorScope();
5183 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
5193 if (Tok.
isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
5197 bool AllowConstructorName;
5199 AllowConstructorName =
false;
5201 AllowConstructorName =
5212 AllowConstructorName,
5227 DeclScopeObj.EnterDeclaratorScope();
5234 goto PastIdentifier;
5240 diag::err_expected_unqualified_id)
5243 goto PastIdentifier;
5247 "There's a C++-specific check for tok::identifier above");
5252 goto PastIdentifier;
5257 !isCXX11VirtSpecifier(Tok)) {
5262 goto PastIdentifier;
5266 if (Tok.
is(tok::l_paren)) {
5270 ParseParenDeclarator(D);
5283 DeclScopeObj.EnterDeclaratorScope();
5294 diag::ext_abstract_pack_declarator_parens);
5296 if (Tok.
getKind() == tok::annot_pragma_parser_crash)
5298 if (Tok.
is(tok::l_square))
5299 return ParseMisplacedBracketDeclarator(D);
5302 diag::err_expected_member_name_or_semi)
5304 : D.getDeclSpec().getSourceRange());
5306 if (Tok.
isOneOf(tok::period, tok::arrow))
5307 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.
is(tok::arrow);
5315 diag::err_expected_unqualified_id)
5320 diag::err_expected_either)
5321 << tok::identifier << tok::l_paren;
5329 "Haven't past the location of the identifier yet?");
5333 MaybeParseCXX11Attributes(D);
5336 if (Tok.
is(tok::l_paren)) {
5339 ParseScope PrototypeScope(
this,
5347 bool IsAmbiguous =
false;
5351 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
5352 bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous);
5353 TentativelyDeclaredIdentifiers.pop_back();
5354 if (!IsFunctionDecl)
5360 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
5361 PrototypeScope.Exit();
5362 }
else if (Tok.
is(tok::l_square)) {
5363 ParseBracketDeclarator(D);
5383 void Parser::ParseParenDeclarator(
Declarator &D) {
5387 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
5400 bool RequiresArg =
false;
5401 if (Tok.
is(tok::kw___attribute)) {
5402 ParseGNUAttributes(attrs);
5410 ParseMicrosoftTypeAttributes(attrs);
5413 if (Tok.
is(tok::kw___pascal))
5414 ParseBorlandTypeAttributes(attrs);
5426 }
else if (Tok.
is(tok::r_paren) ||
5429 isDeclarationSpecifier() ||
5430 isCXX11AttributeSpecifier()) {
5448 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
5452 T.getCloseLocation()),
5453 attrs, T.getCloseLocation());
5459 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
5472 ParseScope PrototypeScope(
this,
5476 ParseFunctionDeclarator(D, attrs, T,
false, RequiresArg);
5477 PrototypeScope.Exit();
5499 void Parser::ParseFunctionDeclarator(
Declarator &D,
5504 assert(
getCurScope()->isFunctionPrototypeScope() &&
5505 "Should call from a Function scope");
5511 bool HasProto =
false;
5518 bool RefQualifierIsLValueRef =
true;
5538 StartLoc = LParenLoc;
5540 if (isFunctionDeclaratorIdentifierList()) {
5542 Diag(Tok, diag::err_argument_required_after_attribute);
5544 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
5548 LocalEndLoc = RParenLoc;
5551 if (Tok.
isNot(tok::r_paren))
5552 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo,
5554 else if (RequiresArg)
5555 Diag(Tok, diag::err_argument_required_after_attribute);
5557 HasProto = ParamInfo.size() ||
getLangOpts().CPlusPlus;
5562 LocalEndLoc = RParenLoc;
5571 ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed,
5581 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
5582 EndLoc = RefQualifierLoc;
5591 bool IsCXX11MemberFunction =
5605 IsCXX11MemberFunction);
5611 GetLookAheadToken(0).is(tok::kw_noexcept) &&
5612 GetLookAheadToken(1).is(tok::l_paren) &&
5613 GetLookAheadToken(2).is(tok::kw_noexcept) &&
5614 GetLookAheadToken(3).is(tok::l_paren) &&
5615 GetLookAheadToken(4).is(tok::identifier) &&
5616 GetLookAheadToken(4).getIdentifierInfo()->isStr(
"swap")) {
5627 ESpecType = tryParseExceptionSpecification(Delayed,
5630 DynamicExceptionRanges,
5632 ExceptionSpecTokens);
5634 EndLoc = ESpecRange.
getEnd();
5638 MaybeParseCXX11Attributes(FnAttrs);
5641 LocalEndLoc = EndLoc;
5643 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
5648 TrailingReturnType = ParseTrailingReturnType(Range);
5658 ParamInfo.data(), ParamInfo.size(),
5659 EllipsisLoc, RParenLoc,
5661 RefQualifierIsLValueRef,
5662 RefQualifierLoc, ConstQualifierLoc,
5663 VolatileQualifierLoc,
5664 RestrictQualifierLoc,
5666 ESpecType, ESpecRange,
5667 DynamicExceptions.data(),
5668 DynamicExceptionRanges.data(),
5669 DynamicExceptions.size(),
5671 NoexceptExpr.
get() :
nullptr,
5672 ExceptionSpecTokens,
5673 StartLoc, LocalEndLoc, D,
5674 TrailingReturnType),
5680 bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
5682 if (Tok.
isOneOf(tok::amp, tok::ampamp)) {
5684 diag::warn_cxx98_compat_ref_qualifier :
5685 diag::ext_ref_qualifier);
5687 RefQualifierIsLValueRef = Tok.
is(tok::amp);
5699 bool Parser::isFunctionDeclaratorIdentifierList() {
5701 && Tok.
is(tok::identifier)
5702 && !TryAltiVecVectorToken()
5730 void Parser::ParseFunctionDeclaratorIdentifierList(
5738 Diag(Tok, diag::ext_ident_list_in_param);
5741 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
5745 if (Tok.
isNot(tok::identifier)) {
5746 Diag(Tok, diag::err_expected) << tok::identifier;
5757 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
5760 if (!ParamsSoFar.insert(ParmII).second) {
5761 Diag(Tok, diag::err_param_redefinition) << ParmII;
5806 void Parser::ParseParameterDeclarationClause(
5836 ParseDeclarationSpecifiers(DS);
5846 ParseDeclarator(ParmDeclarator);
5849 MaybeParseGNUAttributes(ParmDeclarator);
5860 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
5861 ParmDeclarator.getNumTypeObjects() == 0) {
5863 Diag(DSStart, diag::err_missing_param);
5870 if (Tok.
is(tok::ellipsis) &&
5872 (!ParmDeclarator.getEllipsisLoc().isValid() &&
5875 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
5884 if (Tok.
is(tok::equal)) {
5896 if (!ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument)) {
5898 DefArgToks =
nullptr;
5916 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
5917 DefArgResult = ParseBraceInitializer();
5927 DefArgResult.
get());
5933 ParmDeclarator.getIdentifierLoc(),
5934 Param, DefArgToks));
5941 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
5943 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
5948 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
5949 << ParmEllipsis.
isValid() << ParmEllipsis;
5952 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
5954 Diag(ParmDeclarator.getIdentifierLoc(),
5955 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
5958 << !ParmDeclarator.hasName();
5960 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
5979 void Parser::ParseBracketDeclarator(
Declarator &D) {
5980 if (CheckProhibitedCXX11Attribute())
5988 if (Tok.
getKind() == tok::r_square) {
5991 MaybeParseCXX11Attributes(attrs);
5995 T.getOpenLocation(),
5996 T.getCloseLocation()),
5997 attrs, T.getCloseLocation());
5999 }
else if (Tok.
getKind() == tok::numeric_constant &&
6000 GetLookAheadToken(1).is(tok::r_square)) {
6007 MaybeParseCXX11Attributes(attrs);
6012 T.getOpenLocation(),
6013 T.getCloseLocation()),
6014 attrs, T.getCloseLocation());
6025 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
6033 bool isStar =
false;
6040 if (Tok.
is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
6044 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
6048 }
else if (Tok.
isNot(tok::r_square)) {
6066 Diag(StaticLoc, diag::err_unspecified_size_with_static);
6082 MaybeParseCXX11Attributes(attrs);
6088 T.getOpenLocation(),
6089 T.getCloseLocation()),
6090 attrs, T.getCloseLocation());
6094 void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
6095 assert(Tok.
is(tok::l_square) &&
"Missing opening bracket");
6101 while (Tok.
is(tok::l_square)) {
6102 ParseBracketDeclarator(TempDeclarator);
6108 if (Tok.
is(tok::semi))
6114 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6119 if (TempDeclarator.getNumTypeObjects() == 0)
6123 bool NeedParens =
false;
6149 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
6164 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
6168 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
6176 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
6189 void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
6190 assert(Tok.
is(tok::kw_typeof) &&
"Not a typeof specifier");
6194 const bool hasParens = Tok.
is(tok::l_paren);
6203 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
6219 const char *PrevSpec =
nullptr;
6225 Diag(StartLoc, DiagID) << PrevSpec;
6242 const char *PrevSpec =
nullptr;
6246 DiagID, Operand.
get(),
6248 Diag(StartLoc, DiagID) << PrevSpec;
6254 void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
6255 assert(Tok.
is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
6256 "Not an atomic specifier");
6260 if (T.consumeOpen())
6272 if (T.getCloseLocation().isInvalid())
6278 const char *PrevSpec =
nullptr;
6281 DiagID, Result.
get(),
6283 Diag(StartLoc, DiagID) << PrevSpec;
6288 bool Parser::TryAltiVecVectorTokenOutOfLine() {
6291 default:
return false;
6294 case tok::kw_signed:
6295 case tok::kw_unsigned:
6300 case tok::kw_double:
6302 case tok::kw___bool:
6303 case tok::kw___pixel:
6304 Tok.
setKind(tok::kw___vector);
6306 case tok::identifier:
6308 Tok.
setKind(tok::kw___vector);
6312 Tok.
setKind(tok::kw___vector);
6320 const char *&PrevSpec,
unsigned &DiagID,
6328 case tok::kw_signed:
6329 case tok::kw_unsigned:
6334 case tok::kw_double:
6336 case tok::kw___bool:
6337 case tok::kw___pixel:
6340 case tok::identifier:
void ClearFunctionSpecs()
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
unsigned getFlags() const
getFlags - Return the flags for this scope.
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
SourceLocation getThreadStorageClassSpecLoc() const
SourceLocation getCloseLocation() const
Defines the clang::ASTContext interface.
static bool isAttributeLateParsed(const IdentifierInfo &II)
isAttributeLateParsed - Return true if the attribute has arguments that require late parsing...
SourceLocation getEnd() const
AttributeList * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed)
Add microsoft __delspec(property) attribute.
IdKind getKind() const
Determine what kind of name we have.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
TypeResult ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation TagLoc, SourceLocation NameLoc)
static LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
no exception specification
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
SourceLocation getRestrictSpecLoc() const
This is a scope that corresponds to the parameters within a function prototype.
TemplateParameterList * ActOnTemplateParameterList(unsigned Depth, SourceLocation ExportLoc, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< Decl * > Params, SourceLocation RAngleLoc)
ActOnTemplateParameterList - Builds a TemplateParameterList that contains the template parameters in ...
Represents a version number in the form major[.minor[.subminor[.build]]].
SourceLocation getConstSpecLoc() const
SourceLocation getExplicitSpecLoc() const
TSW getTypeSpecWidth() const
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
static const TSS TSS_unsigned
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
Code completion occurs within a class, struct, or union.
TheContext getContext() const
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc...
IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
const LangOptions & getLangOpts() const
static const TST TST_wchar
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
Decl * getRepAsDecl() const
const LangOptions & getLangOpts() const
SourceLocation TemplateNameLoc
TemplateNameLoc - The location of the template name within the source.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
static const TST TST_typeofExpr
static const TST TST_char16
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, unsigned TheContext)
Decl - This represents one declaration (or definition), e.g.
RAII object used to inform the actions that we're currently parsing a declaration.
bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Is the identifier known as a __declspec-style attribute?
A RAII object used to temporarily suppress access-like checking.
Defines the C++ template declaration subclasses.
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
SCS getStorageClassSpec() const
const char * getName() const
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, unsigned TypeQuals, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation ConstQualifierLoc, SourceLocation VolatileQualifierLoc, SourceLocation RestrictQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult())
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
The base class of the type hierarchy.
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
This indicates that the scope corresponds to a function, which means that labels are set here...
std::unique_ptr< llvm::MemoryBuffer > Buffer
One instance of this struct is used for each type in a declarator that is parsed. ...
Declaration of a variable template.
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location...
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
SourceLocation getInlineSpecLoc() const
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
TemplateNameKind Kind
The kind of template that Template refers to.
void ActOnExitFunctionContext()
Wrapper for void* pointer.
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
SourceLocation getLocEnd() const LLVM_READONLY
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, bool AllowNonIdentifiers, bool AllowNestedNameSpecifiers)
RAII object that enters a new expression evaluation context.
void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record)
void EnterToken(const Token &Tok)
Enters a token in the token stream to be lexed next.
Information about one declarator, including the parsed type information and the identifier.
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void setTypeofParensRange(SourceRange range)
static const TST TST_interface
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
static const TST TST_char
Describes how types, statements, expressions, and declarations should be printed. ...
Code completion occurs within an Objective-C implementation or category implementation.
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing...
Decl * ActOnParamDeclarator(Scope *S, Declarator &D)
ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator() to introduce parameters into fun...
friend class ObjCDeclContextSwitch
ParmVarDecl - Represents a parameter to a function.
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed...
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool isEmpty() const
No scope specifier.
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto)
Information about a template-id annotation token.
Base wrapper for a particular "section" of type source info.
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args)
RecordDecl - Represents a struct/union/class.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
bool TryConsumeToken(tok::TokenKind Expected)
__ptr16, alignas(...), etc.
One of these records is kept for each identifier that is lexed.
void set(AttributeList *newList)
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
static const TST TST_decimal32
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
AttributeList * getList() const
static bool attributeHasIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
bool isTypeSpecPipe() const
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl)
ActOnTagStartDefinition - Invoked when we have entered the scope of a tag's definition (e...
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
static const TST TST_class
bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
AttributeList * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, AttributeList::Syntax syntaxUsed)
Add an attribute with a single type argument.
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
static const TST TST_double
Code completion occurs following one or more template headers within a class.
bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
The iterator over UnresolvedSets.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
ParsedType ActOnObjCInstanceType(SourceLocation Loc)
The parser has parsed the context-sensitive type 'instancetype' in an Objective-C message declaration...
Token - This structure provides full information about a lexed token.
SkipBodyInfo shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, SourceLocation IILoc)
Determine whether the body of an anonymous enumeration should be skipped.
static const TST TST_enum
void setKind(tok::TokenKind K)
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
SourceLocation getTypeSpecTypeLoc() const
Decl * ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, AttributeList *Attrs, SourceLocation EqualLoc, Expr *Val)
void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs)
ActOnFinishDelayedAttribute - Invoked when we have finished parsing an attribute for which parsing is...
void ClearStorageClassSpecs()
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool mayBeFollowedByCXXDirectInit() const
mayBeFollowedByCXXDirectInit - Return true if the declarator can be followed by a C++ direct initiali...
Decl * ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, AccessSpecifier AS, SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, SkipBodyInfo *SkipBody=nullptr)
This is invoked when we see 'struct foo' or 'struct {'.
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
Code completion occurs at top-level or namespace context.
The controlling scope in a if/switch/while/for statement.
const TargetInfo & getTargetInfo() const
void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, IdentifierInfo *ClassName, SmallVectorImpl< Decl * > &Decls)
Called whenever @defs(ClassName) is encountered in the source.
This is a scope that corresponds to a block/closure object.
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
void addAttributes(AttributeList *AL)
Concatenates two attribute lists.
Represents the results of name lookup.
bool hasGroupingParens() const
void setExtension(bool Val=true)
This scope corresponds to an enum.
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=ParsedType(), bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type...
static StringRef normalizeAttrName(StringRef Name)
Normalizes an attribute name by dropping prefixed and suffixed __.
void SetRangeBegin(SourceLocation Loc)
SetRangeBegin - Set the start of the source range to Loc, unless it's invalid.
Code completion occurs following one or more template headers.
void ActOnInitializerError(Decl *Dcl)
ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS)
Determine whether the identifier II is a typo for the name of the class type currently being defined...
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
bool hasAllExtensionsSilenced()
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getEndLoc() const
Represents information about a change in availability for an entity, which is part of the encoding of...
Represents a C++ nested-name-specifier or a global scope specifier.
int hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)
Return the version number associated with the attribute if we recognize and implement the attribute s...
bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
tok::TokenKind getKind() const
Decl * ActOnTemplateDeclarator(Scope *S, MultiTemplateParamsArg TemplateParameterLists, Declarator &D)
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
static bool VersionNumberSeparator(const char Separator)
SourceRange getSourceRange() const LLVM_READONLY
void setInvalid(bool b=true) const
detail::InMemoryDirectory::const_iterator I
VersionTuple Version
The version number at which the change occurred.
void DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, ParsedType &SuggestedType, bool AllowClassTemplates=false)
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
static const TST TST_float
Code completion occurs within a sequence of declaration specifiers within a function, method, or block.
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl)
ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an initializer for the declaratio...
Provides definitions for the various language-specific address spaces.
void * getAnnotationValue() const
DeclSpec & getMutableDeclSpec()
getMutableDeclSpec - Return a non-const version of the DeclSpec.
static const TSW TSW_long
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
TST getTypeSpecType() const
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit, bool TypeMayContainAuto)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
void ClearConstexprSpec()
const void * getEofData() const
SourceLocation getModulePrivateSpecLoc() const
A class for parsing a declarator.
TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S)
isTagName() - This method is called for error recovery purposes only to determine if the specified na...
void SetRangeStart(SourceLocation Loc)
NameClassificationKind getKind() const
SourceLocation getFriendSpecLoc() const
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
TypeResult ParseTypeName(SourceRange *Range=nullptr, Declarator::TheContext Context=Declarator::TypeNameContext, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
bool mayOmitIdentifier() const
mayOmitIdentifier - Return true if the identifier is either optional or not allowed.
void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param)
This is used to implement the constant expression evaluation part of the attribute enable_if extensio...
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
bool containsUnexpandedParameterPacks(Declarator &D)
Determine whether the given declarator contains any unexpanded parameter packs.
StringRef getName() const
Return the actual identifier string.
Represents a character-granular source range.
SourceLocation getAtomicSpecLoc() const
bool isTemplateDecl() const
returns true if this declaration is a template
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
TypeResult ActOnTypeName(Scope *S, Declarator &D)
void setEofData(const void *D)
static bool isPipeDeclerator(const Declarator &D)
void setAsmLabel(Expr *E)
SourceLocation getVolatileSpecLoc() const
DeclContext * getDeclContext()
static const TST TST_decimal64
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the
Decl * ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart, Declarator &D, Expr *BitfieldWidth)
ActOnField - Each field of a C struct/union is passed into this in order to create a FieldDecl object...
void UpdateTypeRep(ParsedType Rep)
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
bool isConstexprSpecified() const
A class for parsing a field declarator.
bool isNot(tok::TokenKind K) const
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
SourceLocation Loc
Loc - The place where this type was defined.
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
void setEllipsisLoc(SourceLocation EL)
bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_half
class LLVM_ALIGNAS(8) TemplateSpecializationType unsigned NumArgs
Represents a type template specialization; the template must be a class template, a type alias templa...
Wraps an identifier and optional source location for the identifier.
void ActOnCXXEnterDeclInitializer(Scope *S, Decl *Dcl)
ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an initializer for the declaration ...
The result type of a method or function.
SourceLocation getStorageClassSpecLoc() const
SourceRange VersionRange
The source range covering the version number.
SourceLocation getAnnotationEndLoc() const
static const TSW TSW_short
bool isVirtualSpecified() const
void CodeCompleteInitializer(Scope *S, Decl *D)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
const clang::PrintingPolicy & getPrintingPolicy() const
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, bool IsAddressOfOperand, std::unique_ptr< CorrectionCandidateCallback > CCC=nullptr)
Perform name lookup on the given name, classifying it based on the results of name lookup and the fol...
This is a scope that corresponds to the parameters within a function prototype for a function declara...
void CodeCompleteTypeQualifiers(DeclSpec &DS)
static const TST TST_char32
A class for parsing a DeclSpec.
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
bool SetConceptSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Stop skipping at semicolon.
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
enum clang::DeclaratorChunk::@183 Kind
Encodes a location in the source.
void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record)
static const TST TST_auto_type
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getPipeLoc() const
TagDecl - Represents the declaration of a struct/union/class/enum.
void ExitScope()
ExitScope - Pop a scope off the scope stack.
This is a scope that corresponds to the Objective-C @catch statement.
ASTContext & getASTContext() const
static const TST TST_union
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error...
Scope * getCurScope() const
void EnterTokenStream(const Token *Toks, unsigned NumToks, bool DisableMacroExpansion, bool OwnsTokens)
Add a "macro" context to the top of the include stack, which will cause the lexer to start returning ...
static const TSS TSS_signed
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void setIdentifierInfo(IdentifierInfo *II)
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them...
void setGroupingParens(bool flag)
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
SourceLocation getConstexprSpecLoc() const
bool isTemplateParamScope() const
isTemplateParamScope - Return true if this scope is a C++ template parameter scope.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
SourceLocation getVirtualSpecLoc() const
static const TST TST_typeofType
SourceLocation getBegin() const
bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D)
Determine if we're in a case where we need to (incorrectly) eagerly parse an exception specification ...
bool hasAttributes() const
bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const LangOptions &Lang)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, ParsedType ObjectType, SourceLocation &TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, AttributeList *AttrList)
ExprResult HandleExprEvaluationContextForTypeof(Expr *E)
bool containsPlaceholderType() const
SourceLocation getOpenLocation() const
The scope of a struct/union/class definition.
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void ActOnReenterFunctionContext(Scope *S, Decl *D)
Push the parameters of D, which must be a function, into scope.
ParserCompletionContext
Describes the context in which code completion occurs.
ParsedType ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II, SourceLocation NameLoc)
For compatibility with MSVC, we delay parsing of some default template type arguments until instantia...
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
TSCS getThreadStorageClassSpec() const
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
static const TST TST_auto
bool isFriendSpecified() const
static const TST TST_void
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero)...
void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, SourceLocation RBraceLoc, Decl *EnumDecl, ArrayRef< Decl * > Elements, Scope *S, AttributeList *Attr)
CXXScopeSpec SS
The nested-name-specifier that precedes the template name.
static const TST TST_int128
void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, SourceLocation RBraceLoc)
ActOnTagFinishDefinition - Invoked once we have finished parsing the definition of a tag (enumeration...
void CodeCompleteTag(Scope *S, unsigned TagSpec)
void ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, Expr *defarg)
ActOnParamDefaultArgument - Check whether the default argument provided for a function parameter is w...
bool hasTagDefinition() const
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
This is a scope that corresponds to the template parameters of a C++ template.
SourceLocation getLocEnd() const LLVM_READONLY
EnumDecl - Represents an enum.
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
The name refers to a template whose specialization produces a type.
static const TST TST_unspecified
bool isFirstDeclarator() const
Syntax
The style used to specify an attribute.
bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)
isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...
ExprResult ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, bool IsType, void *TyOrEx, SourceRange ArgRange)
ActOnUnaryExprOrTypeTraitExpr - Handle sizeof(type) and sizeof expr and the same for alignof and __al...
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
IdentifierInfo * getName() const
static const TST TST_decimal128
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy.
void takeAttributesFrom(ParsedAttributes &attrs)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
static const TSCS TSCS___thread
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure...
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required. ...
bool isKnownToGCC() const
void setNext(AttributeList *N)
unsigned getMaxArgs() const
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_typename
void * getAsOpaquePtr() const
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef< Decl * > Group)
DeclResult ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc, unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, TemplateTy Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, AttributeList *Attr)
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
void ActOnCXXForRangeDecl(Decl *D)
SourceLocation getLoc() const
static bool isInvalid(SourceLocation Loc, bool *Invalid)
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
bool isInlineSpecified() const
A template-id, e.g., f<int>.
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
CXXScopeSpec & getTypeSpecScope()
AttributeList * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
bool isUnexpandedParameterPackPermitted()
Determine whether an unexpanded parameter pack might be permitted in this location.
This is a scope that can contain a declaration.
IdentifierInfo * getIdentifier() const
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static ParsedType getTypeAnnotation(Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
Decl * ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS)
ParsedFreeStandingDeclSpec - This method is invoked when a declspec with no declarator (e...
bool isCXX11Attribute() const
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
void setInvalidType(bool Val=true)
ExprResult ParseConstantExpression(TypeCastState isTypeCast=NotTypeCast)
void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc)
ActOnParamDefaultArgumentError - Parsing or semantic analysis of the default argument for the paramet...
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
Captures information about "declaration specifiers".
bool isExplicitSpecified() const
SourceLocation getIdentifierLoc() const
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
static const TSCS TSCS_thread_local
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc, SourceLocation ArgLoc)
ActOnParamUnparsedDefaultArgument - We've seen a default argument for a function parameter, but we can't parse it yet because we're inside a class definition.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult{return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
bool TryAnnotateTypeOrScopeToken(bool EnteringContext=false, bool NeedType=false)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
static const TST TST_bool
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
void revertTokenIDToIdentifier()
Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 compatibility.
bool diagnoseIdentifier() const
diagnoseIdentifier - Return true if the identifier is prohibited and should be diagnosed (because it ...
bool isTypeSpecOwned() const
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc)
Return a DeclaratorChunk for a pointer.
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Imaginary" (...
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
void ExtendWithDeclSpec(const DeclSpec &DS)
ExtendWithDeclSpec - Extend the declarator source range to include the given declspec, unless its location is invalid.
static const TSW TSW_longlong
static Decl::Kind getKind(const Decl *D)
bool isTypeAltiVecVector() const
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
bool isSet() const
Deprecated.
unsigned getLength() const
static bool attributeIsTypeArgAttr(const IdentifierInfo &II)
Determine whether the given attribute parses a type argument.
static const TST TST_atomic
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7)...
bool isDeclspecAttribute() const
static const TST TST_struct
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed...
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
void setLocation(SourceLocation L)
AttributeList * getNext() const
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
NamedDecl - This represents a decl with a name.
bool isInvalidType() const
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
static const TSCS TSCS__Thread_local
bool isFirstDeclarationOfMember()
Returns true if this declares a real member and not a friend.
SourceLocation getLocEnd() const LLVM_READONLY
void SetRangeEnd(SourceLocation Loc)
ParsedAttributes - A collection of parsed attributes.
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
Attr - This represents one attribute.
ParsedAttributes & getAttributes()
void startToken()
Reset all flags to cleared.
AttributeList * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, AttributeList::Syntax syntax)
Add type_tag_for_datatype attribute.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
Decl * ActOnDeclarator(Scope *S, Declarator &D)
AttributeList - Represents a syntactic attribute.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation Loc)
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Stop skipping at specified token, but don't skip the token itself.
SourceLocation getEllipsisLoc() const
unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template)
IdentifierInfo * getIdentifierInfo() const