26 #include "llvm/ADT/Optional.h" 27 #include "llvm/ADT/SmallSet.h" 28 #include "llvm/ADT/SmallString.h" 29 #include "llvm/ADT/StringSwitch.h" 31 using namespace clang;
47 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
48 if (DSC == DeclSpecContext::DSC_normal)
49 DSC = DeclSpecContext::DSC_type_specifier;
55 ParseSpecifierQualifierList(DS, AS, DSC);
61 ParseDeclarator(DeclaratorInfo);
73 if (Name.size() >= 4 && Name.startswith(
"__") && Name.endswith(
"__"))
74 return Name.drop_front(2).drop_back(2);
81 #define CLANG_ATTR_LATE_PARSED_LIST 83 #include "clang/Parse/AttrParserStringSwitches.inc" 85 #undef CLANG_ATTR_LATE_PARSED_LIST 98 bool AttrStartIsInMacro =
100 bool AttrEndIsInMacro =
102 return AttrStartIsInMacro && AttrEndIsInMacro;
148 LateParsedAttrList *LateAttrs,
150 assert(Tok.
is(tok::kw___attribute) &&
"Not a GNU attribute list!");
152 while (Tok.
is(tok::kw___attribute)) {
154 unsigned OldNumAttrs = attrs.
size();
155 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
157 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
162 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
181 if (Tok.
isNot(tok::l_paren)) {
182 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
189 ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc,
nullptr,
195 LateParsedAttribute *LA =
196 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
197 LateAttrs->push_back(LA);
201 if (!ClassStack.empty() && !LateAttrs->parseSoon())
202 getCurrentClass().LateParsedDeclarations.push_back(LA);
206 LA->Toks.push_back(Tok);
209 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true);
214 LA->Toks.push_back(Eof);
215 }
while (Tok.
is(tok::comma));
217 if (ExpectAndConsume(tok::r_paren))
220 if (ExpectAndConsume(tok::r_paren))
231 StringRef FoundName =
235 for (
unsigned i = OldNumAttrs;
i < attrs.
size(); ++
i)
236 attrs[
i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
239 for (
unsigned i = OldNumLateAttrs;
i < LateAttrs->size(); ++
i)
240 (*LateAttrs)[
i]->MacroII = MacroII;
248 #define CLANG_ATTR_IDENTIFIER_ARG_LIST 250 #include "clang/Parse/AttrParserStringSwitches.inc" 252 #undef CLANG_ATTR_IDENTIFIER_ARG_LIST 257 #define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST 259 #include "clang/Parse/AttrParserStringSwitches.inc" 261 #undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST 266 #define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST 268 #include "clang/Parse/AttrParserStringSwitches.inc" 270 #undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST 275 #define CLANG_ATTR_TYPE_ARG_LIST 277 #include "clang/Parse/AttrParserStringSwitches.inc" 279 #undef CLANG_ATTR_TYPE_ARG_LIST 285 #define CLANG_ATTR_ARG_CONTEXT_LIST 287 #include "clang/Parse/AttrParserStringSwitches.inc" 289 #undef CLANG_ATTR_ARG_CONTEXT_LIST 293 assert(Tok.
is(tok::identifier) &&
"expected an identifier");
312 if (Tok.
isNot(tok::r_paren))
324 ScopeName, ScopeLoc, T.
get(), Syntax);
327 ScopeName, ScopeLoc,
nullptr, 0, Syntax);
330 unsigned Parser::ParseAttributeArgsCommon(
340 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
344 if (Tok.
is(tok::identifier)) {
356 IsIdentifierArg = Next.
isOneOf(tok::r_paren, tok::comma);
360 ArgExprs.push_back(ParseIdentifierLoc());
363 if (!ArgExprs.empty() ? Tok.
is(tok::comma) : Tok.
isNot(tok::r_paren)) {
365 if (!ArgExprs.empty())
371 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
375 if (Tok.
is(tok::identifier) &&
377 ArgExprs.push_back(ParseIdentifierLoc());
391 ArgExprs.push_back(ArgExpr.
get());
398 if (!ExpectAndConsume(tok::r_paren)) {
401 ArgExprs.data(), ArgExprs.size(), Syntax);
407 return static_cast<unsigned>(ArgExprs.size());
421 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
426 if (AttrKind == ParsedAttr::AT_Availability) {
427 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
430 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
431 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
432 ScopeName, ScopeLoc, Syntax);
434 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
435 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
436 ScopeName, ScopeLoc, Syntax);
438 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
439 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
440 ScopeName, ScopeLoc, Syntax);
443 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
463 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
467 unsigned Parser::ParseClangAttributeArgs(
471 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
478 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
479 ScopeName, ScopeLoc, Syntax);
480 case ParsedAttr::AT_ExternalSourceSymbol:
481 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
482 ScopeName, ScopeLoc, Syntax);
484 case ParsedAttr::AT_Availability:
485 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
488 case ParsedAttr::AT_ObjCBridgeRelated:
489 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
490 ScopeName, ScopeLoc, Syntax);
492 case ParsedAttr::AT_TypeTagForDatatype:
493 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
494 ScopeName, ScopeLoc, Syntax);
497 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
515 if (AttrName->
getName() ==
"property") {
530 bool HasInvalidAccessor =
false;
535 if (!Tok.
is(tok::identifier)) {
537 if (Tok.
is(tok::r_paren) && !HasInvalidAccessor &&
538 AccessorNames[AK_Put] ==
nullptr &&
539 AccessorNames[AK_Get] ==
nullptr) {
540 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
551 if (KindStr ==
"get") {
553 }
else if (KindStr ==
"put") {
557 }
else if (KindStr ==
"set") {
558 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
565 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
567 HasInvalidAccessor =
true;
568 goto next_property_accessor;
572 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
573 HasInvalidAccessor =
true;
592 if (!Tok.
is(tok::identifier)) {
597 if (Kind == AK_Invalid) {
599 }
else if (AccessorNames[Kind] !=
nullptr) {
601 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
607 next_property_accessor:
613 if (Tok.
is(tok::r_paren))
616 Diag(Tok.
getLocation(), diag::err_ms_property_expected_comma_or_rparen);
621 if (!HasInvalidAccessor)
623 AccessorNames[AK_Get], AccessorNames[AK_Put],
626 return !HasInvalidAccessor;
630 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
635 if (!Attrs.
empty() && Attrs.
begin()->getMaxArgs() && !NumArgs) {
636 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
650 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
651 assert(Tok.
is(tok::kw___declspec) &&
"Not a declspec!");
653 while (Tok.
is(tok::kw___declspec)) {
662 while (Tok.
isNot(tok::r_paren)) {
669 bool IsString = Tok.
getKind() == tok::string_literal;
670 if (!IsString && Tok.
getKind() != tok::identifier &&
671 Tok.
getKind() != tok::kw_restrict) {
672 Diag(Tok, diag::err_ms_declspec_type);
681 bool Invalid =
false;
682 StringRef Str = PP.
getSpelling(Tok, StrBuffer, &Invalid);
688 AttrNameLoc = ConsumeStringToken();
694 bool AttrHandled =
false;
697 if (Tok.
is(tok::l_paren))
698 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
699 else if (AttrName->
getName() ==
"property")
705 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
718 case tok::kw___fastcall:
719 case tok::kw___stdcall:
720 case tok::kw___thiscall:
721 case tok::kw___regcall:
722 case tok::kw___cdecl:
723 case tok::kw___vectorcall:
724 case tok::kw___ptr64:
726 case tok::kw___ptr32:
728 case tok::kw___uptr: {
731 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
741 void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
747 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) << Range;
757 case tok::kw_volatile:
758 case tok::kw___fastcall:
759 case tok::kw___stdcall:
760 case tok::kw___thiscall:
761 case tok::kw___cdecl:
762 case tok::kw___vectorcall:
763 case tok::kw___ptr32:
764 case tok::kw___ptr64:
766 case tok::kw___unaligned:
779 while (Tok.
is(tok::kw___pascal)) {
782 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
789 while (Tok.
is(tok::kw___kernel)) {
792 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
800 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
808 case tok::kw__Nonnull:
809 case tok::kw__Nullable:
810 case tok::kw__Null_unspecified: {
814 Diag(AttrNameLoc, diag::ext_nullability)
816 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
827 return (Separator ==
'.' || Separator ==
'_');
838 VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
841 if (!Tok.
is(tok::numeric_constant)) {
842 Diag(Tok, diag::err_expected_version);
845 return VersionTuple();
854 const char *ThisTokBegin = &Buffer[0];
857 bool Invalid =
false;
858 unsigned ActualLength = PP.
getSpelling(Tok, ThisTokBegin, &Invalid);
860 return VersionTuple();
863 unsigned AfterMajor = 0;
865 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
866 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
870 if (AfterMajor == 0) {
871 Diag(Tok, diag::err_expected_version);
874 return VersionTuple();
877 if (AfterMajor == ActualLength) {
882 Diag(Tok, diag::err_zero_version);
883 return VersionTuple();
886 return VersionTuple(Major);
889 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
891 || (AfterMajor + 1 == ActualLength)) {
892 Diag(Tok, diag::err_expected_version);
895 return VersionTuple();
899 unsigned AfterMinor = AfterMajor + 1;
901 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
902 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
906 if (AfterMinor == ActualLength) {
910 if (Major == 0 && Minor == 0) {
911 Diag(Tok, diag::err_zero_version);
912 return VersionTuple();
915 return VersionTuple(Major, Minor);
918 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
921 Diag(Tok, diag::err_expected_version);
924 return VersionTuple();
928 if (AfterMajorSeparator != AfterMinorSeparator)
929 Diag(Tok, diag::warn_expected_consistent_version_separator);
932 unsigned AfterSubminor = AfterMinor + 1;
933 unsigned Subminor = 0;
934 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
935 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
939 if (AfterSubminor != ActualLength) {
940 Diag(Tok, diag::err_expected_version);
943 return VersionTuple();
946 return VersionTuple(Major, Minor, Subminor);
974 void Parser::ParseAvailabilityAttribute(
IdentifierInfo &Availability,
981 enum { Introduced, Deprecated, Obsoleted, Unknown };
988 Diag(Tok, diag::err_expected) << tok::l_paren;
993 if (Tok.
isNot(tok::identifier)) {
994 Diag(Tok, diag::err_availability_expected_platform);
1001 if (Ident->getName() ==
"macosx")
1005 else if (Ident->getName() ==
"macosx_app_extension")
1009 AvailabilityAttr::canonicalizePlatformName(Ident->getName()));
1013 if (ExpectAndConsume(tok::comma)) {
1020 if (!Ident_introduced) {
1034 if (Tok.
isNot(tok::identifier)) {
1035 Diag(Tok, diag::err_availability_expected_change);
1042 if (Keyword == Ident_strict) {
1044 Diag(KeywordLoc, diag::err_availability_redundant)
1047 StrictLoc = KeywordLoc;
1051 if (Keyword == Ident_unavailable) {
1052 if (UnavailableLoc.
isValid()) {
1053 Diag(KeywordLoc, diag::err_availability_redundant)
1056 UnavailableLoc = KeywordLoc;
1060 if (Keyword == Ident_deprecated && Platform->
Ident &&
1063 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1064 Diag(KeywordLoc, diag::err_availability_redundant)
1071 Changes[Deprecated].
Version = VersionTuple(1);
1075 if (Tok.
isNot(tok::equal)) {
1076 Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
1081 if (Keyword == Ident_message || Keyword == Ident_replacement) {
1082 if (Tok.
isNot(tok::string_literal)) {
1083 Diag(Tok, diag::err_expected_string_literal)
1088 if (Keyword == Ident_message)
1089 MessageExpr = ParseStringLiteralExpression();
1091 ReplacementExpr = ParseStringLiteralExpression();
1094 cast_or_null<StringLiteral>(MessageExpr.
get())) {
1095 if (MessageStringLiteral->getCharByteWidth() != 1) {
1096 Diag(MessageStringLiteral->getSourceRange().getBegin(),
1097 diag::err_expected_string_literal)
1103 if (Keyword == Ident_message)
1111 if ((Keyword == Ident_introduced || Keyword == Ident_deprecated) &&
1112 Tok.
is(tok::identifier)) {
1116 if (Keyword == Ident_introduced)
1117 UnavailableLoc = KeywordLoc;
1123 VersionTuple Version = ParseVersionTuple(VersionRange);
1125 if (Version.empty()) {
1131 if (Keyword == Ident_introduced)
1133 else if (Keyword == Ident_deprecated)
1135 else if (Keyword == Ident_obsoleted)
1140 if (Index < Unknown) {
1141 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1142 Diag(KeywordLoc, diag::err_availability_redundant)
1145 Changes[Index].VersionRange.
getEnd());
1149 Changes[Index].
Version = Version;
1152 Diag(KeywordLoc, diag::err_availability_unknown_change)
1153 << Keyword << VersionRange;
1167 if (UnavailableLoc.
isValid()) {
1168 bool Complained =
false;
1169 for (
unsigned Index = Introduced; Index != Unknown; ++Index) {
1170 if (Changes[Index].KeywordLoc.
isValid()) {
1172 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1174 Changes[Index].VersionRange.getEnd());
1185 attrs.
addNew(&Availability,
1187 ScopeName, ScopeLoc,
1189 Changes[Introduced],
1190 Changes[Deprecated],
1192 UnavailableLoc, MessageExpr.
get(),
1193 Syntax, StrictLoc, ReplacementExpr.
get());
1209 void Parser::ParseExternalSourceSymbolAttribute(
1219 if (!Ident_language) {
1226 bool HasLanguage =
false;
1228 bool HasDefinedIn =
false;
1233 if (Tok.
isNot(tok::identifier)) {
1234 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1241 if (Keyword == Ident_generated_declaration) {
1242 if (GeneratedDeclaration) {
1243 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;
1247 GeneratedDeclaration = ParseIdentifierLoc();
1251 if (Keyword != Ident_language && Keyword != Ident_defined_in) {
1252 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1258 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1264 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn;
1265 if (Keyword == Ident_language)
1268 HasDefinedIn =
true;
1270 if (Tok.
isNot(tok::string_literal)) {
1271 Diag(Tok, diag::err_expected_string_literal)
1273 << (Keyword != Ident_language);
1277 if (Keyword == Ident_language) {
1279 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1281 ParseStringLiteralExpression();
1284 Language = ParseStringLiteralExpression();
1286 assert(Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1288 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1290 ParseStringLiteralExpression();
1293 DefinedInExpr = ParseStringLiteralExpression();
1304 GeneratedDeclaration};
1306 ScopeName, ScopeLoc, Args, llvm::array_lengthof(Args), Syntax);
1320 void Parser::ParseObjCBridgeRelatedAttribute(
IdentifierInfo &ObjCBridgeRelated,
1330 Diag(Tok, diag::err_expected) << tok::l_paren;
1335 if (Tok.
isNot(tok::identifier)) {
1336 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1341 if (ExpectAndConsume(tok::comma)) {
1350 if (Tok.
is(tok::identifier)) {
1351 ClassMethod = ParseIdentifierLoc();
1353 Diag(Tok, diag::err_objcbridge_related_selector_name);
1359 if (Tok.
is(tok::colon))
1360 Diag(Tok, diag::err_objcbridge_related_selector_name);
1362 Diag(Tok, diag::err_expected) << tok::comma;
1370 if (Tok.
is(tok::identifier))
1371 InstanceMethod = ParseIdentifierLoc();
1372 else if (Tok.
isNot(tok::r_paren)) {
1373 Diag(Tok, diag::err_expected) << tok::r_paren;
1386 attrs.
addNew(&ObjCBridgeRelated,
1388 ScopeName, ScopeLoc,
1398 void Parser::LateParsedDeclaration::ParseLexedAttributes() {}
1400 void Parser::LateParsedClass::ParseLexedAttributes() {
1401 Self->ParseLexedAttributes(*Class);
1404 void Parser::LateParsedAttribute::ParseLexedAttributes() {
1405 Self->ParseLexedAttribute(*
this,
true,
false);
1410 void Parser::ParseLexedAttributes(ParsingClass &Class) {
1413 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
1416 if (HasTemplateScope)
1420 bool AlreadyHasClassScope = Class.TopLevelClass;
1422 ParseScope ClassScope(
this, ScopeFlags, !AlreadyHasClassScope);
1423 ParseScopeFlags ClassScopeFlags(
this, ScopeFlags, AlreadyHasClassScope);
1426 if (!AlreadyHasClassScope)
1428 Class.TagOrTemplate);
1429 if (!Class.LateParsedDeclarations.empty()) {
1430 for (
unsigned i = 0, ni = Class.LateParsedDeclarations.size();
i < ni; ++
i){
1431 Class.LateParsedDeclarations[
i]->ParseLexedAttributes();
1435 if (!AlreadyHasClassScope)
1437 Class.TagOrTemplate);
1441 void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs,
Decl *D,
1443 assert(LAs.parseSoon() &&
1444 "Attribute list should be marked for immediate parsing.");
1445 for (
unsigned i = 0, ni = LAs.size();
i < ni; ++
i) {
1448 ParseLexedAttribute(*LAs[
i],
EnterScope, OnDefinition);
1459 void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
1468 LA.Toks.push_back(AttrEnd);
1472 LA.Toks.push_back(Tok);
1473 PP.EnterTokenStream(LA.Toks,
true,
true);
1480 if (LA.Decls.size() > 0) {
1481 Decl *D = LA.Decls[0];
1489 if (LA.Decls.size() == 1) {
1493 if (HasTemplateScope)
1504 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
1512 if (HasTemplateScope) {
1518 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
1523 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
1526 if (OnDefinition && !Attrs.
empty() && !Attrs.
begin()->isCXX11Attribute() &&
1527 Attrs.
begin()->isKnownToGCC())
1528 Diag(Tok, diag::warn_attribute_on_function_definition)
1531 for (
unsigned i = 0, ni = LA.Decls.size();
i < ni; ++
i)
1543 void Parser::ParseTypeTagForDatatypeAttribute(
IdentifierInfo &AttrName,
1550 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1555 if (Tok.
isNot(tok::identifier)) {
1556 Diag(Tok, diag::err_expected) << tok::identifier;
1562 if (ExpectAndConsume(tok::comma)) {
1574 bool LayoutCompatible =
false;
1575 bool MustBeNull =
false;
1577 if (Tok.
isNot(tok::identifier)) {
1578 Diag(Tok, diag::err_expected) << tok::identifier;
1583 if (Flag->
isStr(
"layout_compatible"))
1584 LayoutCompatible =
true;
1585 else if (Flag->
isStr(
"must_be_null"))
1588 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1595 if (!T.consumeClose()) {
1597 ArgumentKind, MatchingCType.
get(),
1598 LayoutCompatible, MustBeNull, Syntax);
1602 *EndLoc = T.getCloseLocation();
1613 bool Parser::DiagnoseProhibitedCXX11Attribute() {
1614 assert(Tok.
is(tok::l_square) &&
NextToken().
is(tok::l_square));
1616 switch (isCXX11AttributeSpecifier(
true)) {
1617 case CAK_NotAttributeSpecifier:
1621 case CAK_InvalidAttributeSpecifier:
1625 case CAK_AttributeSpecifier:
1630 assert(Tok.
is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1632 Diag(BeginLoc, diag::err_attributes_not_allowed)
1636 llvm_unreachable(
"All cases handled above.");
1643 void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
1645 assert((Tok.
is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1646 Tok.
is(tok::kw_alignas));
1650 ParseCXX11Attributes(Attrs);
1653 Diag(Loc, diag::err_attributes_not_allowed)
1658 void Parser::DiagnoseProhibitedAttributes(
1660 if (CorrectLocation.
isValid()) {
1662 Diag(CorrectLocation, diag::err_attributes_misplaced)
1666 Diag(Range.
getBegin(), diag::err_attributes_not_allowed) << Range;
1669 void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs,
1672 if (!AL.isCXX11Attribute() && !AL.isC2xAttribute())
1675 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL.getName();
1677 Diag(AL.getLoc(), DiagID) << AL.getName();
1690 void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
1699 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1700 AL.isDeclspecAttribute()) ||
1701 AL.isMicrosoftAttribute())
1702 ToBeMoved.push_back(&AL);
1729 ParsedAttributesWithRange &attrs) {
1735 Decl *SingleDecl =
nullptr;
1737 case tok::kw_template:
1738 case tok::kw_export:
1739 ProhibitAttributes(attrs);
1740 SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd, attrs);
1742 case tok::kw_inline:
1745 ProhibitAttributes(attrs);
1747 return ParseNamespace(Context, DeclEnd, InlineLoc);
1749 return ParseSimpleDeclaration(Context, DeclEnd, attrs,
1751 case tok::kw_namespace:
1752 ProhibitAttributes(attrs);
1753 return ParseNamespace(Context, DeclEnd);
1755 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1757 case tok::kw_static_assert:
1758 case tok::kw__Static_assert:
1759 ProhibitAttributes(attrs);
1760 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1763 return ParseSimpleDeclaration(Context, DeclEnd, attrs,
true);
1791 ParsedAttributesWithRange &Attrs,
1792 bool RequireSemi, ForRangeInit *FRI) {
1796 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1797 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(),
AS_none, DSContext);
1802 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1807 if (Tok.
is(tok::semi)) {
1808 ProhibitAttributes(Attrs);
1816 Decl* decls[] = {AnonRecord, TheDecl};
1823 return ParseDeclGroup(DS, Context, &DeclEnd, FRI);
1830 case tok::annot_cxxscope:
1831 case tok::annot_template_id:
1833 case tok::code_completion:
1834 case tok::coloncolon:
1836 case tok::kw___attribute:
1837 case tok::kw_operator:
1854 case tok::identifier:
1856 case tok::code_completion:
1857 case tok::coloncolon:
1860 case tok::equalequal:
1861 case tok::kw_alignas:
1863 case tok::kw___attribute:
1882 case tok::identifier:
1905 if (Tok.
isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
1929 case tok::kw_inline:
1934 (!ParsingInObjCContainer || CurParsedObjCImpl))
1938 case tok::kw_namespace:
1943 (!ParsingInObjCContainer || CurParsedObjCImpl))
1950 ParsingInObjCContainer)
1962 case tok::annot_module_begin:
1963 case tok::annot_module_end:
1964 case tok::annot_module_include:
1981 ForRangeInit *FRI) {
1995 LateParsedAttrList LateParsedAttrs(
true);
1997 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2002 if (Tok.
is(tok::kw__Noreturn)) {
2004 const char *PrevSpec;
2010 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2011 Fixit &= Tok.
isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2013 Diag(Loc, diag::err_c11_noreturn_misplaced)
2025 !isDeclarationAfterDeclarator()) {
2031 if (isStartOfFunctionDefinition(D)) {
2033 Diag(Tok, diag::err_function_declared_typedef);
2040 ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
2044 if (isDeclarationSpecifier()) {
2052 Diag(Tok, diag::err_expected_fn_body);
2057 if (Tok.
is(tok::l_brace)) {
2058 Diag(Tok, diag::err_function_definition_not_allowed);
2065 if (ParseAsmAttributesAfterDeclarator(D))
2074 if (FRI && (Tok.
is(tok::colon) || isTokIdentifier_in())) {
2075 bool IsForRangeLoop =
false;
2077 IsForRangeLoop =
true;
2078 if (Tok.
is(tok::l_brace))
2079 FRI->RangeExpr = ParseBraceInitializer();
2085 if (IsForRangeLoop) {
2089 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2090 VD->setObjCForDecl(
true);
2098 Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(
2099 D, ParsedTemplateInfo(), FRI);
2100 if (LateParsedAttrs.size() > 0)
2101 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2104 DeclsInGroup.push_back(FirstDecl);
2112 if (Tok.
isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2116 Diag(CommaLoc, diag::err_expected_semi_declaration)
2133 MaybeParseGNUAttributes(D);
2137 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2141 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
2144 DeclsInGroup.push_back(ThisDecl);
2153 ? diag::err_invalid_token_after_toplevel_declarator
2154 : diag::err_expected_semi_declaration)) {
2158 if (!isDeclarationSpecifier()) {
2169 bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2171 if (Tok.
is(tok::kw_asm)) {
2183 MaybeParseGNUAttributes(D);
2209 Decl *Parser::ParseDeclarationAfterDeclarator(
2210 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2211 if (ParseAsmAttributesAfterDeclarator(D))
2214 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2217 Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2218 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2220 struct InitializerScopeRAII {
2226 :
P(P), D(D), ThisDecl(ThisDecl) {
2236 ~InitializerScopeRAII() { pop(); }
2251 Decl *ThisDecl =
nullptr;
2252 switch (TemplateInfo.Kind) {
2253 case ParsedTemplateInfo::NonTemplate:
2254 ThisDecl = Actions.ActOnDeclarator(
getCurScope(), D);
2257 case ParsedTemplateInfo::Template:
2258 case ParsedTemplateInfo::ExplicitSpecialization: {
2259 ThisDecl = Actions.ActOnTemplateDeclarator(
getCurScope(),
2260 *TemplateInfo.TemplateParams,
2262 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl))
2265 ThisDecl = VT->getTemplatedDecl();
2268 case ParsedTemplateInfo::ExplicitInstantiation: {
2269 if (Tok.
is(tok::semi)) {
2270 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2271 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2276 ThisDecl = ThisRes.
get();
2284 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2286 ThisDecl = Actions.ActOnDeclarator(
getCurScope(), D);
2289 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2291 diag::err_explicit_instantiation_with_definition)
2297 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2299 LAngleLoc,
nullptr));
2302 Actions.ActOnTemplateDeclarator(
getCurScope(), FakedParamLists, D);
2311 if (isTokenEqualOrEqualTypo()) {
2314 if (Tok.
is(tok::kw_delete)) {
2320 }
else if (Tok.
is(tok::kw_default)) {
2327 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2329 if (Tok.
is(tok::code_completion)) {
2330 Actions.CodeCompleteInitializer(
getCurScope(), ThisDecl);
2331 Actions.FinalizeDeclaration(ThisDecl);
2336 PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl);
2342 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2346 FRI->ColonLoc = EqualLoc;
2348 FRI->RangeExpr = Init;
2355 StopTokens.push_back(tok::comma);
2358 StopTokens.push_back(tok::r_paren);
2360 Actions.ActOnInitializerError(ThisDecl);
2362 Actions.AddInitializerToDecl(ThisDecl, Init.
get(),
2365 }
else if (Tok.
is(tok::l_paren)) {
2373 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2375 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2376 auto RunSignatureHelp = [&]() {
2377 QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
2378 getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(),
2380 CalledSignatureHelp =
true;
2381 return PreferredType;
2383 auto SetPreferredType = [&] {
2384 PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);
2387 llvm::function_ref<void()> ExpressionStarts;
2393 ExpressionStarts = SetPreferredType;
2395 if (ParseExpressionList(Exprs, CommaLocs, ExpressionStarts)) {
2396 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2397 Actions.ProduceConstructorSignatureHelp(
2398 getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(),
2400 CalledSignatureHelp =
true;
2402 Actions.ActOnInitializerError(ThisDecl);
2408 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
2409 "Unexpected number of commas!");
2416 Actions.AddInitializerToDecl(ThisDecl, Initializer.
get(),
2419 }
else if (
getLangOpts().CPlusPlus11 && Tok.
is(tok::l_brace) &&
2422 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2424 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2431 Actions.ActOnInitializerError(ThisDecl);
2433 Actions.AddInitializerToDecl(ThisDecl, Init.
get(),
true);
2436 Actions.ActOnUninitializedDecl(ThisDecl);
2439 Actions.FinalizeDeclaration(ThisDecl);
2451 DeclSpecContext DSC) {
2455 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
2460 Diag(Tok, diag::err_expected_type);
2463 Diag(Tok, diag::err_typename_requires_specqual);
2474 diag::err_typename_invalid_storageclass);
2516 return T.
isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2517 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2531 const ParsedTemplateInfo &TemplateInfo,
2533 ParsedAttributesWithRange &Attrs) {
2534 assert(Tok.
is(tok::identifier) &&
"should have identifier");
2556 if (!isTypeSpecifier(DSC) && !
getLangOpts().CPlusPlus &&
2574 AnnotateScopeToken(*SS,
false);
2583 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2584 *Tok.getIdentifierInfo(), Tok.getLocation(),
2585 DSC == DeclSpecContext::DSC_template_type_arg)) {
2586 const char *PrevSpec;
2589 Actions.getASTContext().getPrintingPolicy());
2602 if (SS ==
nullptr) {
2603 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2606 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2609 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2611 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2613 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2615 TagName=
"__interface"; FixitTagName =
"__interface ";
2616 TagKind=tok::kw___interface;
break;
2618 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2626 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2627 << TokenName << TagName <<
getLangOpts().CPlusPlus
2630 if (Actions.LookupParsedName(R,
getCurScope(), SS)) {
2633 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2634 << TokenName << TagName;
2638 if (TagKind == tok::kw_enum)
2639 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2640 DeclSpecContext::DSC_normal);
2642 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2644 DeclSpecContext::DSC_normal, Attrs);
2651 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2652 DSC == DeclSpecContext::DSC_class)) {
2656 case tok::l_paren: {
2663 TentativeParsingAction PA(*
this);
2665 TPResult TPR = TryParseDeclarator(
false);
2668 if (TPR != TPResult::False) {
2676 if (DSC == DeclSpecContext::DSC_class ||
2677 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2679 if (Actions.isCurrentClassNameTypo(II, SS)) {
2680 Diag(Loc, diag::err_constructor_bad_name)
2681 << Tok.getIdentifierInfo() << II
2683 Tok.setIdentifierInfo(II);
2701 AnnotateScopeToken(*SS,
false);
2717 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS, T,
2723 const char *PrevSpec;
2726 Actions.getASTContext().getPrintingPolicy());
2731 }
else if (II != Tok.getIdentifierInfo()) {
2744 if (IsTemplateName) {
2746 TemplateArgList Args;
2747 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
2761 Parser::DeclSpecContext
2764 return DeclSpecContext::DSC_class;
2766 return DeclSpecContext::DSC_top_level;
2768 return DeclSpecContext::DSC_template_param;
2771 return DeclSpecContext::DSC_template_type_arg;
2774 return DeclSpecContext::DSC_trailing;
2777 return DeclSpecContext::DSC_alias_declaration;
2778 return DeclSpecContext::DSC_normal;
2793 if (isTypeIdInParens()) {
2797 ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc,
UETT_AlignOf,
true,
2818 assert(Tok.
isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
2819 "Not an alignment-specifier!");
2840 ArgExprs.push_back(ArgExpr.
get());
2841 Attrs.
addNew(KWName, KWLoc,
nullptr, KWLoc, ArgExprs.data(), 1,
2854 DeclSpecContext DSContext,
2855 LateParsedAttrList *LateAttrs) {
2858 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
2859 DSContext == DeclSpecContext::DSC_top_level);
2862 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
2863 tok::annot_template_id) &&
2869 bool HasScope = Tok.
is(tok::annot_cxxscope);
2875 bool MightBeDeclarator =
true;
2876 if (Tok.
isOneOf(tok::kw_typename, tok::annot_typename)) {
2878 MightBeDeclarator =
false;
2879 }
else if (AfterScope.
is(tok::annot_template_id)) {
2885 MightBeDeclarator =
false;
2886 }
else if (AfterScope.
is(tok::identifier)) {
2887 const Token &Next = HasScope ? GetLookAheadToken(2) :
NextToken();
2891 if (Next.
isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
2892 tok::annot_cxxscope, tok::coloncolon)) {
2894 MightBeDeclarator =
false;
2895 }
else if (HasScope) {
2900 Actions.RestoreNestedNameSpecifierAnnotation(
2901 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
2906 switch (Classification.
getKind()) {
2913 llvm_unreachable(
"typo correction and nested name specifiers not " 2919 MightBeDeclarator =
false;
2933 if (MightBeDeclarator)
2936 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
2938 diag::err_expected_after)
2949 ParsedTemplateInfo NotATemplate;
2950 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
2957 const char *&PrevSpec,
unsigned &DiagID,
2959 assert(!LangOpts.FixedPoint);
2960 DiagID = diag::err_fixed_point_not_enabled;
2992 void Parser::ParseDeclarationSpecifiers(
DeclSpec &DS,
2993 const ParsedTemplateInfo &TemplateInfo,
2995 DeclSpecContext DSContext,
2996 LateParsedAttrList *LateAttrs) {
3005 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3006 DSContext == DeclSpecContext::DSC_top_level);
3007 bool AttrsLastTime =
false;
3008 ParsedAttributesWithRange attrs(AttrFactory);
3013 bool isStorageClass =
false;
3014 const char *PrevSpec =
nullptr;
3015 unsigned DiagID = 0;
3031 Tok.setKind(tok::identifier);
3035 switch (Tok.getKind()) {
3039 ProhibitAttributes(attrs);
3044 ProhibitCXX11Attributes(attrs, diag::err_attribute_not_type_attr);
3051 DS.
Finish(Actions, Policy);
3055 case tok::kw_alignas:
3056 if (!standardAttributesAllowed() || !isCXX11AttributeSpecifier())
3057 goto DoneWithDeclSpec;
3059 ProhibitAttributes(attrs);
3066 ParseCXX11Attributes(attrs);
3067 AttrsLastTime =
true;
3070 case tok::code_completion: {
3073 bool AllowNonIdentifiers
3079 bool AllowNestedNameSpecifiers
3080 = DSContext == DeclSpecContext::DSC_top_level ||
3084 AllowNonIdentifiers,
3085 AllowNestedNameSpecifiers);
3086 return cutOffParsing();
3091 else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
3094 else if (DSContext == DeclSpecContext::DSC_class)
3096 else if (CurParsedObjCImpl)
3099 Actions.CodeCompleteOrdinaryName(
getCurScope(), CCC);
3100 return cutOffParsing();
3103 case tok::coloncolon:
3108 goto DoneWithDeclSpec;
3110 if (Tok.
is(tok::coloncolon))
3111 goto DoneWithDeclSpec;
3114 case tok::annot_cxxscope: {
3116 goto DoneWithDeclSpec;
3119 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3120 Tok.getAnnotationRange(),
3125 if (Next.
is(tok::annot_template_id) &&
3138 if ((DSContext == DeclSpecContext::DSC_top_level ||
3139 DSContext == DeclSpecContext::DSC_class) &&
3142 isConstructorDeclarator(
false)) {
3147 goto DoneWithDeclSpec;
3151 ConsumeAnnotationToken();
3152 assert(Tok.
is(tok::annot_template_id) &&
3153 "ParseOptionalCXXScopeSpecifier not working");
3154 AnnotateTemplateIdTokenAsType();
3158 if (Next.
is(tok::annot_typename)) {
3160 ConsumeAnnotationToken();
3161 if (Tok.getAnnotationValue()) {
3164 Tok.getAnnotationEndLoc(),
3165 PrevSpec, DiagID, T, Policy);
3172 ConsumeAnnotationToken();
3175 if (Next.
isNot(tok::identifier))
3176 goto DoneWithDeclSpec;
3181 if ((DSContext == DeclSpecContext::DSC_top_level ||
3182 DSContext == DeclSpecContext::DSC_class) &&
3185 isConstructorDeclarator(
false))
3186 goto DoneWithDeclSpec;
3193 isClassTemplateDeductionContext(DSContext));
3201 ConsumeAnnotationToken();
3202 ParsedAttributesWithRange Attrs(AttrFactory);
3203 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3204 if (!Attrs.empty()) {
3205 AttrsLastTime =
true;
3206 attrs.takeAllFrom(Attrs);
3210 goto DoneWithDeclSpec;
3214 ConsumeAnnotationToken();
3217 DiagID, TypeRep, Policy);
3227 case tok::annot_typename: {
3231 goto DoneWithDeclSpec;
3233 if (Tok.getAnnotationValue()) {
3244 ConsumeAnnotationToken();
3249 case tok::kw___is_signed:
3260 TryKeywordIdentFallback(
true);
3263 goto DoneWithDeclSpec;
3266 case tok::kw___super:
3267 case tok::kw_decltype:
3268 case tok::identifier: {
3273 goto DoneWithDeclSpec;
3279 if (!
getLangOpts().DeclSpecKeyword && Tok.
is(tok::identifier) &&
3280 Tok.getIdentifierInfo()->getName().equals(
"__declspec")) {
3281 Diag(Loc, diag::err_ms_attributes_not_enabled);
3292 assert(
false &&
"Not a left paren?");
3305 goto DoneWithDeclSpec;
3307 if (!Tok.
is(tok::identifier))
3312 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
3318 goto DoneWithDeclSpec;
3320 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3321 isObjCInstancetype()) {
3322 ParsedType TypeRep = Actions.ActOnObjCInstanceType(Loc);
3325 DiagID, TypeRep, Policy);
3337 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3338 isConstructorDeclarator(
true))
3339 goto DoneWithDeclSpec;
3342 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3343 false,
false,
nullptr,
false,
false,
3344 isClassTemplateDeductionContext(DSContext));
3349 ParsedAttributesWithRange Attrs(AttrFactory);
3350 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3351 if (!Attrs.empty()) {
3352 AttrsLastTime =
true;
3353 attrs.takeAllFrom(Attrs);
3357 goto DoneWithDeclSpec;
3363 (DSContext == DeclSpecContext::DSC_class ||
3364 DSContext == DeclSpecContext::DSC_top_level) &&
3365 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3366 Tok.getLocation()) &&
3367 isConstructorDeclarator(
true,
3369 goto DoneWithDeclSpec;
3372 DiagID, TypeRep, Policy);
3384 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3399 case tok::annot_template_id: {
3405 goto DoneWithDeclSpec;
3413 isConstructorDeclarator(TemplateId->
SS.
isEmpty()))
3414 goto DoneWithDeclSpec;
3418 AnnotateTemplateIdTokenAsType();
3423 case tok::kw___attribute:
3428 case tok::kw___declspec:
3433 case tok::kw___forceinline: {
3442 case tok::kw___unaligned:
3447 case tok::kw___sptr:
3448 case tok::kw___uptr:
3449 case tok::kw___ptr64:
3450 case tok::kw___ptr32:
3452 case tok::kw___cdecl:
3453 case tok::kw___stdcall:
3454 case tok::kw___fastcall:
3455 case tok::kw___thiscall:
3456 case tok::kw___regcall:
3457 case tok::kw___vectorcall:
3462 case tok::kw___pascal:
3467 case tok::kw___kernel:
3472 case tok::kw__Nonnull:
3473 case tok::kw__Nullable:
3474 case tok::kw__Null_unspecified:
3479 case tok::kw___kindof:
3486 case tok::kw_typedef:
3488 PrevSpec, DiagID, Policy);
3489 isStorageClass =
true;
3491 case tok::kw_extern:
3493 Diag(Tok, diag::ext_thread_before) <<
"extern";
3495 PrevSpec, DiagID, Policy);
3496 isStorageClass =
true;
3498 case tok::kw___private_extern__:
3500 Loc, PrevSpec, DiagID, Policy);
3501 isStorageClass =
true;
3503 case tok::kw_static:
3505 Diag(Tok, diag::ext_thread_before) <<
"static";
3507 PrevSpec, DiagID, Policy);
3508 isStorageClass =
true;
3512 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
3514 PrevSpec, DiagID, Policy);
3516 Diag(Tok, diag::ext_auto_storage_class)
3523 PrevSpec, DiagID, Policy);
3524 isStorageClass =
true;
3526 case tok::kw___auto_type:
3527 Diag(Tok, diag::ext_auto_type);
3531 case tok::kw_register:
3533 PrevSpec, DiagID, Policy);
3534 isStorageClass =
true;
3536 case tok::kw_mutable:
3538 PrevSpec, DiagID, Policy);
3539 isStorageClass =
true;
3541 case tok::kw___thread:
3544 isStorageClass =
true;
3546 case tok::kw_thread_local:
3549 isStorageClass =
true;
3551 case tok::kw__Thread_local:
3553 Loc, PrevSpec, DiagID);
3554 isStorageClass =
true;
3558 case tok::kw_inline:
3561 case tok::kw_virtual:
3565 DiagID = diag::err_openclcxx_virtual_function;
3566 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
3573 case tok::kw_explicit: {
3577 ConsumedEnd = ExplicitLoc;
3579 if (Tok.
is(tok::l_paren)) {
3581 ExprResult ExplicitExpr(static_cast<Expr *>(
nullptr));
3585 ConsumedEnd = Tok.getLocation();
3587 CloseParenLoc = Tok.getLocation();
3590 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.
get());
3594 Diag(Tok.getLocation(), diag::warn_cxx2a_compat_explicit_bool);
3597 ExplicitSpec, CloseParenLoc);
3600 case tok::kw__Noreturn:
3602 Diag(Loc, diag::ext_c11_noreturn);
3607 case tok::kw__Alignas:
3609 Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
3614 case tok::kw_friend:
3615 if (DSContext == DeclSpecContext::DSC_class)
3619 DiagID = diag::err_friend_invalid_in_context;
3625 case tok::kw___module_private__:
3630 case tok::kw_constexpr:
3635 case tok::kw_consteval:
3652 case tok::kw___int64:
3656 case tok::kw_signed:
3660 case tok::kw_unsigned:
3664 case tok::kw__Complex:
3668 case tok::kw__Imaginary:
3684 case tok::kw___int128:
3696 case tok::kw_double:
3700 case tok::kw__Float16:
3704 case tok::kw__Accum:
3712 case tok::kw__Fract:
3727 case tok::kw___float128:
3731 case tok::kw_wchar_t:
3735 case tok::kw_char8_t:
3739 case tok::kw_char16_t:
3743 case tok::kw_char32_t:
3749 if (Tok.
is(tok::kw_bool) &&
3753 DiagID = diag::err_bool_redeclaration;
3755 Tok.setKind(tok::identifier);
3762 case tok::kw__Decimal32:
3766 case tok::kw__Decimal64:
3770 case tok::kw__Decimal128:
3774 case tok::kw___vector:
3777 case tok::kw___pixel:
3780 case tok::kw___bool:
3788 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3789 goto DoneWithDeclSpec;
3791 isInvalid = DS.
SetTypePipe(
true, Loc, PrevSpec, DiagID, Policy);
3793 #define GENERIC_IMAGE_TYPE(ImgType, Id) \ 3794 case tok::kw_##ImgType##_t: \ 3795 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, \ 3798 #include "clang/Basic/OpenCLImageTypes.def" 3799 case tok::kw___unknown_anytype:
3801 PrevSpec, DiagID, Policy);
3806 case tok::kw_struct:
3807 case tok::kw___interface:
3808 case tok::kw_union: {
3815 ParsedAttributesWithRange Attributes(AttrFactory);
3816 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
3817 EnteringContext, DSContext, Attributes);
3821 if (!Attributes.empty()) {
3822 AttrsLastTime =
true;
3823 attrs.takeAllFrom(Attributes);
3831 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
3839 case tok::kw_volatile:
3843 case tok::kw_restrict:
3849 case tok::kw_typename:
3852 goto DoneWithDeclSpec;
3854 if (!Tok.
is(tok::kw_typename))
3859 case tok::kw_typeof:
3860 ParseTypeofSpecifier(DS);
3863 case tok::annot_decltype:
3864 ParseDecltypeSpecifier(DS);
3867 case tok::annot_pragma_pack:
3871 case tok::annot_pragma_ms_pragma:
3872 HandlePragmaMSPragma();
3875 case tok::annot_pragma_ms_vtordisp:
3876 HandlePragmaMSVtorDisp();
3879 case tok::annot_pragma_ms_pointers_to_members:
3880 HandlePragmaMSPointersToMembers();
3883 case tok::kw___underlying_type:
3884 ParseUnderlyingTypeSpecifier(DS);
3887 case tok::kw__Atomic:
3893 ParseAtomicSpecifier(DS);
3901 case tok::kw___generic:
3904 if (Actions.getLangOpts().OpenCLVersion < 200 &&
3905 !Actions.getLangOpts().OpenCLCPlusPlus) {
3906 DiagID = diag::err_opencl_unknown_type_specifier;
3907 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
3912 case tok::kw_private:
3913 case tok::kw___private:
3914 case tok::kw___global:
3915 case tok::kw___local:
3916 case tok::kw___constant:
3918 case tok::kw___read_only:
3919 case tok::kw___write_only:
3920 case tok::kw___read_write:
3929 goto DoneWithDeclSpec;
3936 PrevSpec, DiagID, Type.
get(),
3937 Actions.getASTContext().getPrintingPolicy()))
3938 Diag(StartLoc, DiagID) << PrevSpec;
3954 assert(PrevSpec &&
"Method did not return previous specifier!");
3957 if (DiagID == diag::ext_duplicate_declspec ||
3958 DiagID == diag::ext_warn_duplicate_declspec ||
3959 DiagID == diag::err_duplicate_declspec)
3960 Diag(Loc, DiagID) << PrevSpec
3963 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
3966 << PrevSpec << isStorageClass;
3968 Diag(Loc, DiagID) << PrevSpec;
3971 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
3975 AttrsLastTime =
false;
4000 void Parser::ParseStructDeclaration(
4004 if (Tok.
is(tok::kw___extension__)) {
4008 return ParseStructDeclaration(DS, FieldsCallback);
4012 ParsedAttributesWithRange Attrs(AttrFactory);
4013 MaybeParseCXX11Attributes(Attrs);
4017 ParseSpecifierQualifierList(DS);
4021 if (Tok.
is(tok::semi)) {
4025 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4031 bool FirstDeclarator =
true;
4038 if (!FirstDeclarator)
4039 MaybeParseGNUAttributes(DeclaratorInfo.
D);
4043 if (Tok.
isNot(tok::colon)) {
4046 ParseDeclarator(DeclaratorInfo.
D);
4059 MaybeParseGNUAttributes(DeclaratorInfo.
D);
4062 FieldsCallback(DeclaratorInfo);
4069 FirstDeclarator =
false;
4086 "parsing struct/union body");
4094 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4099 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
4104 if (Tok.
is(tok::semi)) {
4105 ConsumeExtraSemi(InsideStruct,
TagType);
4110 if (Tok.
is(tok::kw__Static_assert)) {
4112 ParseStaticAssertDeclaration(DeclEnd);
4116 if (Tok.
is(tok::annot_pragma_pack)) {
4121 if (Tok.
is(tok::annot_pragma_align)) {
4122 HandlePragmaAlign();
4126 if (Tok.
is(tok::annot_pragma_openmp)) {
4129 ParsedAttributesWithRange Attrs(AttrFactory);
4130 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4134 if (!Tok.
is(tok::at)) {
4140 FD.D, FD.BitfieldSize);
4141 FieldDecls.push_back(Field);
4147 ParseStructDeclaration(DS, CFieldCallback);
4151 Diag(Tok, diag::err_unexpected_at);
4156 ExpectAndConsume(tok::l_paren);
4157 if (!Tok.
is(tok::identifier)) {
4158 Diag(Tok, diag::err_expected) << tok::identifier;
4163 Actions.ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
4164 Tok.getIdentifierInfo(), Fields);
4165 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
4167 ExpectAndConsume(tok::r_paren);
4173 if (Tok.
is(tok::r_brace)) {
4174 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4178 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
4189 MaybeParseGNUAttributes(attrs);
4191 Actions.ActOnFields(
getCurScope(), RecordLoc, TagDecl, FieldDecls,
4228 const ParsedTemplateInfo &TemplateInfo,
4231 if (Tok.
is(tok::code_completion)) {
4234 return cutOffParsing();
4238 ParsedAttributesWithRange attrs(AttrFactory);
4239 MaybeParseGNUAttributes(attrs);
4240 MaybeParseCXX11Attributes(attrs);
4241 MaybeParseMicrosoftDeclSpecs(attrs);
4244 bool IsScopedUsingClassTag =
false;
4247 if (Tok.
isOneOf(tok::kw_class, tok::kw_struct)) {
4249 : diag::ext_scoped_enum);
4250 IsScopedUsingClassTag = Tok.
is(tok::kw_class);
4255 ProhibitAttributes(attrs);
4258 MaybeParseGNUAttributes(attrs);
4259 MaybeParseCXX11Attributes(attrs);
4260 MaybeParseMicrosoftDeclSpecs(attrs);
4269 bool shouldDelayDiagsInTag =
4270 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
4271 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
4275 bool AllowDeclaration = DSC != DeclSpecContext::DSC_trailing;
4284 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
4288 if (Spec.
isSet() && Tok.
isNot(tok::identifier)) {
4289 Diag(Tok, diag::err_expected) << tok::identifier;
4290 if (Tok.
isNot(tok::l_brace)) {
4302 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::l_brace) &&
4303 !(AllowDeclaration && Tok.
is(tok::colon))) {
4304 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
4314 if (Tok.
is(tok::identifier)) {
4315 Name = Tok.getIdentifierInfo();
4319 if (!Name && ScopedEnumKWLoc.
isValid()) {
4322 Diag(Tok, diag::err_scoped_enum_missing_identifier);
4324 IsScopedUsingClassTag =
false;
4329 if (shouldDelayDiagsInTag)
4330 diagsFromTag.
done();
4336 if (AllowDeclaration && Tok.
is(tok::colon)) {
4337 bool PossibleBitfield =
false;
4338 if (CanBeBitfield) {
4351 if (TPR == TPResult::True)
4352 PossibleBitfield =
true;
4357 else if (TPR == TPResult::False &&
4358 GetLookAheadToken(2).
getKind() == tok::semi) {
4365 TentativeParsingAction TPA(*
this);
4377 isCXXDeclarationSpecifier(TPResult::True) != TPResult::True) ||
4380 PossibleBitfield =
true;
4392 if (!PossibleBitfield) {
4398 Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
4400 Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type);
4402 Diag(StartLoc, diag::ext_ms_c_enum_fixed_underlying_type);
4404 Diag(StartLoc, diag::ext_clang_c_enum_fixed_underlying_type);
4420 if (!AllowDeclaration) {
4422 }
else if (Tok.
is(tok::l_brace)) {
4424 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
4432 }
else if (!isTypeSpecifier(DSC) &&
4433 (Tok.
is(tok::semi) ||
4434 (Tok.isAtStartOfLine() &&
4435 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
4437 if (Tok.
isNot(tok::semi)) {
4439 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
4440 PP.EnterToken(Tok,
true);
4441 Tok.setKind(tok::semi);
4454 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
4458 Diag(Tok, diag::err_enum_template);
4463 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
4466 Diag(StartLoc, diag::err_explicit_instantiation_enum);
4470 assert(TemplateInfo.TemplateParams &&
"no template parameters");
4472 TemplateInfo.TemplateParams->size());
4476 ProhibitAttributes(attrs);
4479 Diag(Tok, diag::err_enumerator_unnamed_no_def);
4486 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
4491 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
4496 bool IsDependent =
false;
4497 const char *PrevSpec =
nullptr;
4499 Decl *TagDecl = Actions.ActOnTag(
4502 ScopedEnumKWLoc, IsScopedUsingClassTag, BaseType,
4503 DSC == DeclSpecContext::DSC_type_specifier,
4504 DSC == DeclSpecContext::DSC_template_param ||
4505 DSC == DeclSpecContext::DSC_template_type_arg,
4516 NameLoc.
isValid() ? NameLoc : StartLoc,
4517 PrevSpec, DiagID, TagDecl, Owned,
4519 Diag(StartLoc, DiagID) << PrevSpec;
4528 Diag(Tok, diag::err_expected_type_name_after_typename);
4540 NameLoc.
isValid() ? NameLoc : StartLoc,
4541 PrevSpec, DiagID, Type.
get(),
4542 Actions.getASTContext().getPrintingPolicy()))
4543 Diag(StartLoc, DiagID) << PrevSpec;
4562 ParseEnumBody(StartLoc, D);
4564 !Actions.ActOnDuplicateDefinition(DS, TagDecl, SkipBody)) {
4571 NameLoc.
isValid() ? NameLoc : StartLoc,
4572 PrevSpec, DiagID, TagDecl, Owned,
4574 Diag(StartLoc, DiagID) << PrevSpec;
4590 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
4597 Diag(Tok, diag::err_empty_enum);
4602 Decl *LastEnumConstDecl =
nullptr;
4605 while (Tok.
isNot(tok::r_brace)) {
4608 if (Tok.
isNot(tok::identifier)) {
4609 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
4619 ParsedAttributesWithRange attrs(AttrFactory);
4620 MaybeParseGNUAttributes(attrs);
4621 ProhibitAttributes(attrs);
4622 if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) {
4625 ? diag::warn_cxx14_compat_ns_enum_attribute
4626 : diag::ext_ns_enum_attribute)
4628 ParseCXX11Attributes(attrs);
4633 EnumAvailabilityDiags.emplace_back(*
this);
4642 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
4643 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
4644 EqualLoc, AssignedVal.
get());
4645 EnumAvailabilityDiags.back().done();
4647 EnumConstantDecls.push_back(EnumConstDecl);
4648 LastEnumConstDecl = EnumConstDecl;
4650 if (Tok.
is(tok::identifier)) {
4653 Diag(Loc, diag::err_enumerator_list_missing_comma)
4663 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
4666 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
4676 if (Tok.
is(tok::r_brace) && CommaLoc.
isValid()) {
4679 diag::ext_enumerator_list_comma_cxx :
4680 diag::ext_enumerator_list_comma_c)
4683 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
4694 MaybeParseGNUAttributes(attrs);
4696 Actions.ActOnEnumBody(StartLoc, T.
getRange(), EnumDecl, EnumConstantDecls,
4700 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
4701 for (
size_t i = 0, e = EnumConstantDecls.size();
i != e; ++
i) {
4703 EnumAvailabilityDiags[
i].redelay();
4713 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
4714 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
4718 PP.EnterToken(Tok,
true);
4719 Tok.setKind(tok::semi);
4726 bool Parser::isKnownToBeTypeSpecifier(
const Token &Tok)
const {
4728 default:
return false;
4732 case tok::kw___int64:
4733 case tok::kw___int128:
4734 case tok::kw_signed:
4735 case tok::kw_unsigned:
4736 case tok::kw__Complex:
4737 case tok::kw__Imaginary:
4740 case tok::kw_wchar_t:
4741 case tok::kw_char8_t:
4742 case tok::kw_char16_t:
4743 case tok::kw_char32_t:
4747 case tok::kw_double:
4748 case tok::kw__Accum:
4749 case tok::kw__Fract:
4750 case tok::kw__Float16:
4751 case tok::kw___float128:
4754 case tok::kw__Decimal32:
4755 case tok::kw__Decimal64:
4756 case tok::kw__Decimal128:
4757 case tok::kw___vector:
4758 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 4759 #include "clang/Basic/OpenCLImageTypes.def" 4763 case tok::kw_struct:
4764 case tok::kw___interface:
4770 case tok::annot_typename:
4777 bool Parser::isTypeSpecifierQualifier() {
4779 default:
return false;
4781 case tok::identifier:
4782 if (TryAltiVecVectorToken())
4785 case tok::kw_typename:
4790 if (Tok.
is(tok::identifier))
4792 return isTypeSpecifierQualifier();
4794 case tok::coloncolon:
4801 return isTypeSpecifierQualifier();
4804 case tok::kw___attribute:
4806 case tok::kw_typeof:
4811 case tok::kw___int64:
4812 case tok::kw___int128:
4813 case tok::kw_signed:
4814 case tok::kw_unsigned:
4815 case tok::kw__Complex:
4816 case tok::kw__Imaginary:
4819 case tok::kw_wchar_t:
4820 case tok::kw_char8_t:
4821 case tok::kw_char16_t:
4822 case tok::kw_char32_t:
4826 case tok::kw_double:
4827 case tok::kw__Accum:
4828 case tok::kw__Fract:
4829 case tok::kw__Float16:
4830 case tok::kw___float128:
4833 case tok::kw__Decimal32:
4834 case tok::kw__Decimal64:
4835 case tok::kw__Decimal128:
4836 case tok::kw___vector:
4837 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 4838 #include "clang/Basic/OpenCLImageTypes.def" 4842 case tok::kw_struct:
4843 case tok::kw___interface:
4850 case tok::kw_volatile:
4851 case tok::kw_restrict:
4855 case tok::kw___unknown_anytype:
4858 case tok::annot_typename:
4865 case tok::kw___cdecl:
4866 case tok::kw___stdcall:
4867 case tok::kw___fastcall:
4868 case tok::kw___thiscall:
4869 case tok::kw___regcall:
4870 case tok::kw___vectorcall:
4872 case tok::kw___ptr64:
4873 case tok::kw___ptr32:
4874 case tok::kw___pascal:
4875 case tok::kw___unaligned:
4877 case tok::kw__Nonnull:
4878 case tok::kw__Nullable:
4879 case tok::kw__Null_unspecified:
4881 case tok::kw___kindof:
4883 case tok::kw___private:
4884 case tok::kw___local:
4885 case tok::kw___global:
4886 case tok::kw___constant:
4887 case tok::kw___generic:
4888 case tok::kw___read_only:
4889 case tok::kw___read_write:
4890 case tok::kw___write_only:
4893 case tok::kw_private:
4897 case tok::kw__Atomic:
4907 bool Parser::isDeclarationSpecifier(
bool DisambiguatingWithExpression) {
4909 default:
return false;
4915 case tok::identifier:
4919 if (TryAltiVecVectorToken())
4922 case tok::kw_decltype:
4923 case tok::kw_typename:
4928 if (Tok.
is(tok::identifier))
4936 if (DisambiguatingWithExpression &&
4937 isStartOfObjCClassMessageMissingOpenBracket())
4940 return isDeclarationSpecifier();
4942 case tok::coloncolon:
4951 return isDeclarationSpecifier();
4954 case tok::kw_typedef:
4955 case tok::kw_extern:
4956 case tok::kw___private_extern__:
4957 case tok::kw_static:
4959 case tok::kw___auto_type:
4960 case tok::kw_register:
4961 case tok::kw___thread:
4962 case tok::kw_thread_local:
4963 case tok::kw__Thread_local:
4966 case tok::kw___module_private__:
4969 case tok::kw___unknown_anytype:
4974 case tok::kw___int64:
4975 case tok::kw___int128:
4976 case tok::kw_signed:
4977 case tok::kw_unsigned:
4978 case tok::kw__Complex:
4979 case tok::kw__Imaginary:
4982 case tok::kw_wchar_t:
4983 case tok::kw_char8_t:
4984 case tok::kw_char16_t:
4985 case tok::kw_char32_t:
4990 case tok::kw_double:
4991 case tok::kw__Accum:
4992 case tok::kw__Fract:
4993 case tok::kw__Float16:
4994 case tok::kw___float128:
4997 case tok::kw__Decimal32:
4998 case tok::kw__Decimal64:
4999 case tok::kw__Decimal128:
5000 case tok::kw___vector:
5004 case tok::kw_struct:
5006 case tok::kw___interface:
5012 case tok::kw_volatile:
5013 case tok::kw_restrict:
5017 case tok::kw_inline:
5018 case tok::kw_virtual:
5019 case tok::kw_explicit:
5020 case tok::kw__Noreturn:
5023 case tok::kw__Alignas:
5026 case tok::kw_friend:
5029 case tok::kw__Static_assert:
5032 case tok::kw_typeof:
5035 case tok::kw___attribute:
5038 case tok::annot_decltype:
5039 case tok::kw_constexpr:
5042 case tok::kw_consteval:
5045 case tok::kw__Atomic:
5053 case tok::annot_typename:
5054 return !DisambiguatingWithExpression ||
5055 !isStartOfObjCClassMessageMissingOpenBracket();
5057 case tok::kw___declspec:
5058 case tok::kw___cdecl:
5059 case tok::kw___stdcall:
5060 case tok::kw___fastcall:
5061 case tok::kw___thiscall:
5062 case tok::kw___regcall:
5063 case tok::kw___vectorcall:
5065 case tok::kw___sptr:
5066 case tok::kw___uptr:
5067 case tok::kw___ptr64:
5068 case tok::kw___ptr32:
5069 case tok::kw___forceinline:
5070 case tok::kw___pascal:
5071 case tok::kw___unaligned:
5073 case tok::kw__Nonnull:
5074 case tok::kw__Nullable:
5075 case tok::kw__Null_unspecified:
5077 case tok::kw___kindof:
5079 case tok::kw___private:
5080 case tok::kw___local:
5081 case tok::kw___global:
5082 case tok::kw___constant:
5083 case tok::kw___generic:
5084 case tok::kw___read_only:
5085 case tok::kw___read_write:
5086 case tok::kw___write_only:
5087 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 5088 #include "clang/Basic/OpenCLImageTypes.def" 5092 case tok::kw_private:
5097 bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide) {
5098 TentativeParsingAction TPA(*
this);
5102 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
5109 if (Tok.
is(tok::identifier)) {
5113 }
else if (Tok.
is(tok::annot_template_id)) {
5114 ConsumeAnnotationToken();
5122 SkipCXX11Attributes();
5125 if (Tok.
isNot(tok::l_paren)) {
5133 if (Tok.
is(tok::r_paren) ||
5142 isCXX11AttributeSpecifier(
false,
5149 DeclaratorScopeObj DeclScopeObj(*
this, SS);
5151 DeclScopeObj.EnterDeclaratorScope();
5155 MaybeParseMicrosoftAttributes(Attrs);
5160 bool IsConstructor =
false;
5161 if (isDeclarationSpecifier())
5162 IsConstructor =
true;
5163 else if (Tok.
is(tok::identifier) ||
5164 (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
5169 if (Tok.
is(tok::annot_cxxscope))
5170 ConsumeAnnotationToken();
5182 case tok::coloncolon:
5195 SkipCXX11Attributes();
5197 if (DeductionGuide) {
5199 IsConstructor = Tok.
is(tok::arrow);
5202 if (Tok.
is(tok::colon) || Tok.
is(tok::kw_try)) {
5206 IsConstructor =
true;
5208 if (Tok.
is(tok::semi) || Tok.
is(tok::l_brace)) {
5221 IsConstructor = IsUnqualified;
5226 IsConstructor =
true;
5232 return IsConstructor;
5247 void Parser::ParseTypeQualifierListOpt(
5248 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicAllowed,
5249 bool IdentifierRequired,
5251 if (standardAttributesAllowed() && (AttrReqs & AR_CXX11AttributesParsed) &&
5252 isCXX11AttributeSpecifier()) {
5253 ParsedAttributesWithRange attrs(AttrFactory);
5254 ParseCXX11Attributes(attrs);
5262 const char *PrevSpec =
nullptr;
5263 unsigned DiagID = 0;
5267 case tok::code_completion:
5269 (*CodeCompletionHandler)();
5271 Actions.CodeCompleteTypeQualifiers(DS);
5272 return cutOffParsing();
5278 case tok::kw_volatile:
5282 case tok::kw_restrict:
5286 case tok::kw__Atomic:
5288 goto DoneWithTypeQuals;
5294 case tok::kw_private:
5296 goto DoneWithTypeQuals;
5298 case tok::kw___private:
5299 case tok::kw___global:
5300 case tok::kw___local:
5301 case tok::kw___constant:
5302 case tok::kw___generic:
5303 case tok::kw___read_only:
5304 case tok::kw___write_only:
5305 case tok::kw___read_write:
5309 case tok::kw___unaligned:
5313 case tok::kw___uptr:
5318 if (TryKeywordIdentFallback(
false))
5322 case tok::kw___sptr:
5324 case tok::kw___ptr64:
5325 case tok::kw___ptr32:
5326 case tok::kw___cdecl:
5327 case tok::kw___stdcall:
5328 case tok::kw___fastcall:
5329 case tok::kw___thiscall:
5330 case tok::kw___regcall:
5331 case tok::kw___vectorcall:
5332 if (AttrReqs & AR_DeclspecAttributesParsed) {
5336 goto DoneWithTypeQuals;
5337 case tok::kw___pascal:
5338 if (AttrReqs & AR_VendorAttributesParsed) {
5342 goto DoneWithTypeQuals;
5345 case tok::kw__Nonnull:
5346 case tok::kw__Nullable:
5347 case tok::kw__Null_unspecified:
5352 case tok::kw___kindof:
5358 case tok::kw___attribute:
5359 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
5361 Diag(Tok, diag::err_attributes_not_allowed);
5365 if (AttrReqs & AR_GNUAttributesParsed ||
5366 AttrReqs & AR_GNUAttributesParsedAndRejected) {
5376 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
5384 assert(PrevSpec &&
"Method did not return previous specifier!");
5385 Diag(Tok, DiagID) << PrevSpec;
5393 void Parser::ParseDeclarator(
Declarator &D) {
5396 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
5401 if (Kind == tok::star || Kind == tok::caret)
5404 if (Kind == tok::kw_pipe &&
5405 ((Lang.OpenCL && Lang.OpenCLVersion >= 200) || Lang.OpenCLCPlusPlus))
5408 if (!Lang.CPlusPlus)
5411 if (Kind == tok::amp)
5419 if (Kind == tok::ampamp)
5420 return Lang.CPlusPlus11 ||
5431 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
5463 void Parser::ParseDeclaratorInternal(
Declarator &D,
5464 DirectDeclParseFunction DirectDeclParser) {
5465 if (Diags.hasAllExtensionsSilenced())
5472 (Tok.
is(tok::coloncolon) || Tok.
is(tok::kw_decltype) ||
5473 (Tok.
is(tok::identifier) &&
5475 Tok.
is(tok::annot_cxxscope))) {
5476 bool EnteringContext =
5480 ParseOptionalCXXScopeSpecifier(SS,
nullptr, EnteringContext);
5483 if (Tok.
isNot(tok::star)) {
5488 AnnotateScopeToken(SS,
true);
5490 if (DirectDeclParser)
5491 (this->*DirectDeclParser)(D);
5498 ParseTypeQualifierListOpt(DS);
5502 ParseDeclaratorInternal(D, DirectDeclParser);
5518 ParseTypeQualifierListOpt(DS);
5527 if (DirectDeclParser)
5528 (this->*DirectDeclParser)(D);
5537 if (Kind == tok::star || Kind == tok::caret) {
5543 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
5545 ? AR_GNUAttributesParsed
5546 : AR_GNUAttributesParsedAndRejected);
5551 ParseDeclaratorInternal(D, DirectDeclParser);
5552 if (Kind == tok::star)
5570 if (Kind == tok::ampamp)
5572 diag::warn_cxx98_compat_rvalue_reference :
5573 diag::ext_rvalue_reference);
5576 ParseTypeQualifierListOpt(DS);
5585 diag::err_invalid_reference_qualifier_application) <<
"const";
5588 diag::err_invalid_reference_qualifier_application) <<
"volatile";
5592 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
5596 ParseDeclaratorInternal(D, DirectDeclParser);
5603 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
5606 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
5681 void Parser::ParseDirectDeclarator(
Declarator &D) {
5688 return ParseDecompositionDeclarator(D);
5700 bool EnteringContext =
5708 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
5712 DeclScopeObj.EnterDeclaratorScope();
5719 goto PastIdentifier;
5736 !Actions.containsUnexpandedParameterPacks(D) &&
5744 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
5754 if (Tok.
isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
5758 bool AllowConstructorName;
5759 bool AllowDeductionGuide;
5761 AllowConstructorName =
false;
5762 AllowDeductionGuide =
false;
5764 AllowConstructorName =
5767 AllowDeductionGuide =
false;
5769 AllowConstructorName =
5771 AllowDeductionGuide =
5779 true, AllowConstructorName,
5780 AllowDeductionGuide,
nullptr,
nullptr,
5793 DeclScopeObj.EnterDeclaratorScope();
5800 goto PastIdentifier;
5806 diag::err_expected_unqualified_id)
5809 goto PastIdentifier;
5813 "There's a C++-specific check for tok::identifier above");
5818 goto PastIdentifier;
5823 bool DiagnoseIdentifier =
false;
5827 DiagnoseIdentifier =
true;
5830 DiagnoseIdentifier =
5838 !isCXX11VirtSpecifier(Tok))
5840 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
5841 if (DiagnoseIdentifier) {
5846 goto PastIdentifier;
5850 if (Tok.
is(tok::l_paren)) {
5855 RevertingTentativeParsingAction PA(*
this);
5859 goto PastIdentifier;
5866 ParseParenDeclarator(D);
5879 DeclScopeObj.EnterDeclaratorScope();
5890 diag::ext_abstract_pack_declarator_parens);
5892 if (Tok.
getKind() == tok::annot_pragma_parser_crash)
5894 if (Tok.
is(tok::l_square))
5895 return ParseMisplacedBracketDeclarator(D);
5903 diag::err_expected_member_name_or_semi_objcxx_keyword)
5910 goto PastIdentifier;
5913 diag::err_expected_member_name_or_semi)
5917 if (Tok.
isOneOf(tok::period, tok::arrow))
5918 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.
is(tok::arrow);
5922 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
5926 diag::err_expected_unqualified_id)
5931 diag::err_expected_either)
5932 << tok::identifier << tok::l_paren;
5940 "Haven't past the location of the identifier yet?");
5944 MaybeParseCXX11Attributes(D);
5947 if (Tok.
is(tok::l_paren)) {
5950 ParseScope PrototypeScope(
this,
5958 bool IsAmbiguous =
false;
5962 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
5963 bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous);
5964 TentativelyDeclaredIdentifiers.pop_back();
5965 if (!IsFunctionDecl)
5971 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
5972 PrototypeScope.Exit();
5973 }
else if (Tok.
is(tok::l_square)) {
5974 ParseBracketDeclarator(D);
5981 void Parser::ParseDecompositionDeclarator(
Declarator &D) {
5982 assert(Tok.
is(tok::l_square));
5988 if (!(
NextToken().is(tok::identifier) &&
5989 GetLookAheadToken(2).
isOneOf(tok::comma, tok::r_square)) &&
5991 GetLookAheadToken(2).isOneOf(tok::equal, tok::l_brace)))
5992 return ParseMisplacedBracketDeclarator(D);
5998 while (Tok.
isNot(tok::r_square)) {
5999 if (!Bindings.empty()) {
6000 if (Tok.
is(tok::comma))
6003 if (Tok.
is(tok::identifier)) {
6005 Diag(EndLoc, diag::err_expected)
6008 Diag(Tok, diag::err_expected_comma_or_rsquare);
6011 SkipUntil(tok::r_square, tok::comma, tok::identifier,
6013 if (Tok.
is(tok::comma))
6015 else if (Tok.
isNot(tok::identifier))
6020 if (Tok.
isNot(tok::identifier)) {
6021 Diag(Tok, diag::err_expected) << tok::identifier;
6029 if (Tok.
isNot(tok::r_square))
6035 if (Bindings.empty())
6058 void Parser::ParseParenDeclarator(
Declarator &D) {
6062 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
6075 bool RequiresArg =
false;
6076 if (Tok.
is(tok::kw___attribute)) {
6077 ParseGNUAttributes(attrs);
6085 ParseMicrosoftTypeAttributes(attrs);
6088 if (Tok.
is(tok::kw___pascal))
6089 ParseBorlandTypeAttributes(attrs);
6101 }
else if (Tok.
is(tok::r_paren) ||
6104 isDeclarationSpecifier() ||
6105 isCXX11AttributeSpecifier()) {
6123 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6134 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6147 ParseScope PrototypeScope(
this,
6151 ParseFunctionDeclarator(D, attrs, T,
false, RequiresArg);
6152 PrototypeScope.Exit();
6174 void Parser::ParseFunctionDeclarator(
Declarator &D,
6179 assert(
getCurScope()->isFunctionPrototypeScope() &&
6180 "Should call from a Function scope");
6186 bool HasProto =
false;
6193 bool RefQualifierIsLValueRef =
true;
6201 ParsedAttributesWithRange FnAttrs(AttrFactory);
6210 StartLoc = LParenLoc;
6212 if (isFunctionDeclaratorIdentifierList()) {
6214 Diag(Tok, diag::err_argument_required_after_attribute);
6216 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
6220 LocalEndLoc = RParenLoc;
6225 MaybeParseCXX11Attributes(FnAttrs);
6226 ProhibitAttributes(FnAttrs);
6228 if (Tok.
isNot(tok::r_paren))
6229 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo,
6231 else if (RequiresArg)
6232 Diag(Tok, diag::err_argument_required_after_attribute);
6234 HasProto = ParamInfo.size() ||
getLangOpts().CPlusPlus
6240 LocalEndLoc = RParenLoc;
6249 ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed,
6252 llvm::function_ref<
void()>([&]() {
6253 Actions.CodeCompleteFunctionQualifiers(DS, D);
6260 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
6261 EndLoc = RefQualifierLoc;
6270 bool IsCXX11MemberFunction =
6277 Actions.CurContext->isRecord());
6289 LangAS ASIdx = attr.asOpenCLLangAS();
6291 Q.addAddressSpace(ASIdx);
6298 Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
6299 IsCXX11MemberFunction);
6304 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
6305 GetLookAheadToken(0).is(tok::kw_noexcept) &&
6306 GetLookAheadToken(1).is(tok::l_paren) &&
6307 GetLookAheadToken(2).is(tok::kw_noexcept) &&
6308 GetLookAheadToken(3).is(tok::l_paren) &&
6309 GetLookAheadToken(4).is(tok::identifier) &&
6310 GetLookAheadToken(4).getIdentifierInfo()->isStr(
"swap")) {
6321 ESpecType = tryParseExceptionSpecification(Delayed,
6324 DynamicExceptionRanges,
6326 ExceptionSpecTokens);
6328 EndLoc = ESpecRange.
getEnd();
6332 MaybeParseCXX11Attributes(FnAttrs);
6335 LocalEndLoc = EndLoc;
6337 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
6342 TrailingReturnType =
6346 }
else if (standardAttributesAllowed()) {
6347 MaybeParseCXX11Attributes(FnAttrs);
6360 if (!ND || isa<ParmVarDecl>(ND))
6362 DeclsInPrototype.push_back(ND);
6368 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
6369 ParamInfo.size(), EllipsisLoc, RParenLoc,
6370 RefQualifierIsLValueRef, RefQualifierLoc,
6372 ESpecType, ESpecRange, DynamicExceptions.data(),
6373 DynamicExceptionRanges.data(), DynamicExceptions.size(),
6374 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
6375 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
6376 LocalEndLoc, D, TrailingReturnType, &DS),
6377 std::move(FnAttrs), EndLoc);
6382 bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
6384 if (Tok.
isOneOf(tok::amp, tok::ampamp)) {
6386 diag::warn_cxx98_compat_ref_qualifier :
6387 diag::ext_ref_qualifier);
6389 RefQualifierIsLValueRef = Tok.
is(tok::amp);
6401 bool Parser::isFunctionDeclaratorIdentifierList() {
6403 && Tok.
is(tok::identifier)
6404 && !TryAltiVecVectorToken()
6433 void Parser::ParseFunctionDeclaratorIdentifierList(
6441 Diag(Tok, diag::ext_ident_list_in_param);
6444 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
6448 if (Tok.
isNot(tok::identifier)) {
6449 Diag(Tok, diag::err_expected) << tok::identifier;
6460 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
6463 if (!ParamsSoFar.insert(ParmII).second) {
6464 Diag(Tok, diag::err_param_redefinition) << ParmII;
6509 void Parser::ParseParameterDeclarationClause(
6539 ParseDeclarationSpecifiers(DS);
6549 ParseDeclarator(ParmDeclarator);
6552 MaybeParseGNUAttributes(ParmDeclarator);
6559 std::unique_ptr<CachedTokens> DefArgToks;
6563 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
6564 ParmDeclarator.getNumTypeObjects() == 0) {
6566 Diag(DSStart, diag::err_missing_param);
6573 if (Tok.
is(tok::ellipsis) &&
6575 (!ParmDeclarator.getEllipsisLoc().isValid() &&
6576 !Actions.isUnexpandedParameterPackPermitted())) &&
6577 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
6578 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
6582 Decl *Param = Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator);
6587 if (Tok.
is(tok::equal)) {
6598 if (!ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument)) {
6600 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc);
6602 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
6618 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
6619 DefArgResult = ParseBraceInitializer();
6622 DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult);
6624 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc);
6628 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
6629 DefArgResult.
get());
6635 ParmDeclarator.getIdentifierLoc(),
6636 Param, std::move(DefArgToks)));
6643 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
6645 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
6646 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
6650 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
6651 << ParmEllipsis.
isValid() << ParmEllipsis;
6654 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
6656 Diag(ParmDeclarator.getIdentifierLoc(),
6657 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
6660 << !ParmDeclarator.hasName();
6662 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
6681 void Parser::ParseBracketDeclarator(
Declarator &D) {
6682 if (CheckProhibitedCXX11Attribute())
6690 if (Tok.
getKind() == tok::r_square) {
6693 MaybeParseCXX11Attributes(attrs);
6701 }
else if (Tok.
getKind() == tok::numeric_constant &&
6702 GetLookAheadToken(1).is(tok::r_square)) {
6709 MaybeParseCXX11Attributes(attrs);
6717 }
else if (Tok.
getKind() == tok::code_completion) {
6718 Actions.CodeCompleteBracketDeclarator(
getCurScope());
6719 return cutOffParsing();
6729 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
6737 bool isStar =
false;
6744 if (Tok.
is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
6748 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
6752 }
else if (Tok.
isNot(tok::r_square)) {
6770 Diag(StaticLoc, diag::err_unspecified_size_with_static);
6796 void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
6797 assert(Tok.
is(tok::l_square) &&
"Missing opening bracket");
6803 while (Tok.
is(tok::l_square)) {
6804 ParseBracketDeclarator(TempDeclarator);
6810 if (Tok.
is(tok::semi))
6816 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6821 if (TempDeclarator.getNumTypeObjects() == 0)
6825 bool NeedParens =
false;
6850 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects();
i < e; ++
i) {
6863 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
6867 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
6875 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
6888 void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
6889 assert(Tok.
is(tok::kw_typeof) &&
"Not a typeof specifier");
6893 const bool hasParens = Tok.
is(tok::l_paren);
6902 ExprResult Operand = Actions.CorrectDelayedTyposInExpr(
6903 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
6919 const char *PrevSpec =
nullptr;
6924 Actions.getASTContext().getPrintingPolicy()))
6925 Diag(StartLoc, DiagID) << PrevSpec;
6936 Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.
get());
6942 const char *PrevSpec =
nullptr;
6946 DiagID, Operand.
get(),
6947 Actions.getASTContext().getPrintingPolicy()))
6948 Diag(StartLoc, DiagID) << PrevSpec;
6954 void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
6955 assert(Tok.
is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
6956 "Not an atomic specifier");
6978 const char *PrevSpec =
nullptr;
6981 DiagID, Result.
get(),
6982 Actions.getASTContext().getPrintingPolicy()))
6983 Diag(StartLoc, DiagID) << PrevSpec;
6988 bool Parser::TryAltiVecVectorTokenOutOfLine() {
6991 default:
return false;
6994 case tok::kw_signed:
6995 case tok::kw_unsigned:
7000 case tok::kw_double:
7002 case tok::kw___bool:
7003 case tok::kw___pixel:
7004 Tok.
setKind(tok::kw___vector);
7006 case tok::identifier:
7008 Tok.
setKind(tok::kw___vector);
7012 Tok.
setKind(tok::kw___vector);
7020 const char *&PrevSpec,
unsigned &DiagID,
7022 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
7028 case tok::kw_signed:
7029 case tok::kw_unsigned:
7034 case tok::kw_double:
7036 case tok::kw___bool:
7037 case tok::kw___pixel:
7040 case tok::identifier:
void ClearFunctionSpecs()
Defines the clang::ASTContext interface.
static bool isAttributeLateParsed(const IdentifierInfo &II)
isAttributeLateParsed - Return true if the attribute has arguments that require late parsing...
static Qualifiers fromCVRUMask(unsigned CVRU)
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
no exception specification
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
A (possibly-)qualified type.
This is a scope that corresponds to the parameters within a function prototype.
SourceLocation getEndOfPreviousToken()
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
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.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
bool SetTypeQual(TQ T, SourceLocation Loc)
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc...
IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
static const TST TST_wchar
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has a variadic identifier argument.
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 isEmpty() const
No scope specifier.
static const TST TST_typeofExpr
static const TST TST_char16
Decl - This represents one declaration (or definition), e.g.
RAII object used to inform the actions that we're currently parsing a declaration.
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.
The base class of the type hierarchy.
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
SourceLocation getCloseLocation() const
This indicates that the scope corresponds to a function, which means that labels are set here...
SourceLocation getBeginLoc() const LLVM_READONLY
One instance of this struct is used for each type in a declarator that is parsed. ...
Declaration of a variable template.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
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 getEndLoc() const LLVM_READONLY
SourceLocation getEndLoc() const LLVM_READONLY
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()
Store information needed for an explicit specifier.
Wrapper for void* pointer.
Parser - This implements a parser for the C family of languages.
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool hasExplicitSpecifier() const
TSCS getThreadStorageClassSpec() const
void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
SourceLocation getEndLoc() const
NameClassificationKind getKind() const
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion...
RAII object that enters a new expression evaluation context.
void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record)
Information about one declarator, including the parsed type information and the identifier.
void setTypeofParensRange(SourceRange range)
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
LangAS
Defines the address space values used by the address space qualifier of QualType. ...
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
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
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...
friend class ObjCDeclContextSwitch
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
Represents a parameter to a function.
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed...
tok::TokenKind getKind() const
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
enum clang::DeclaratorChunk::@217 Kind
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 ...
bool mayOmitIdentifier() const
mayOmitIdentifier - Return true if the identifier is either optional or not allowed.
The collection of all-type qualifiers we support.
Information about a template-id annotation token.
Base wrapper for a particular "section" of type source info.
SourceLocation getFriendSpecLoc() const
Represents a struct/union/class.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
bool TryConsumeToken(tok::TokenKind Expected)
One of these records is kept for each identifier that is lexed.
SourceLocation getBegin() const
static const TST TST_decimal32
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
static bool attributeHasIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
static const TST TST_char8
Lookup for the name failed, but we're assuming it was a template name anyway.
SourceLocation getTypeSpecTypeLoc() const
static const TST TST_class
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
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.
Token - This structure provides full information about a lexed token.
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 { ...
void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs)
ActOnFinishDelayedAttribute - Invoked when we have finished parsing an attribute for which parsing is...
bool hasTagDefinition() const
void ClearStorageClassSpecs()
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc)
Return a DeclaratorChunk for a pointer.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const LangOptions & getLangOpts() const
void * getAsOpaquePtr() const
static const TST TST_accum
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool isInvalidType() const
Code completion occurs at top-level or namespace context.
The controlling scope in a if/switch/while/for statement.
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
This is a scope that corresponds to a block/closure object.
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
static ParsedType getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
Represents the results of name lookup.
void setExtension(bool Val=true)
This scope corresponds to an enum.
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 ...
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
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.
bool isTypeSpecPipe() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl *> Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
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...
SourceRange getRange() const
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
const clang::PrintingPolicy & getPrintingPolicy() const
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasAttributes() const
Scope - A scope is a transient data structure that is used while parsing the program.
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)
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type...
SourceLocation getConstSpecLoc() const
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const
Return true if this token is a C++ keyword in the specified language.
void addAtEnd(ParsedAttr *newAttr)
static bool VersionNumberSeparator(const char Separator)
SourceRange getSourceRange() const LLVM_READONLY
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
VersionTuple getOpenCLVersionTuple() const
Return the OpenCL C or C++ version as a VersionTuple.
VersionTuple Version
The version number at which the change occurred.
IdentifierInfo * getIdentifier() const
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...
unsigned getFlags() const
getFlags - Return the flags for this scope.
Provides definitions for the various language-specific address spaces.
static const TSW TSW_long
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl *> DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
SourceLocation getUnalignedSpecLoc() const
bool hasConstexprSpecifier() const
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Syntax syntax)
Add type_tag_for_datatype attribute.
void ClearConstexprSpec()
bool mayBeFollowedByCXXDirectInit() const
mayBeFollowedByCXXDirectInit - Return true if the declarator can be followed by a C++ direct initiali...
A class for parsing a declarator.
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the name would appear...
void SetRangeStart(SourceLocation Loc)
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param)
This is used to implement the constant expression evaluation part of the attribute enable_if extensio...
TST getTypeSpecType() const
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Syntax syntaxUsed)
Add microsoft __delspec(property) attribute.
Decl * ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, RecordDecl *&AnonRecord)
ParsedFreeStandingDeclSpec - This method is invoked when a declspec with no declarator (e...
void setDecompositionBindings(SourceLocation LSquareLoc, ArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
Represents a character-granular source range.
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, ParsedType ObjectType, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
TypeResult ActOnTypeName(Scope *S, Declarator &D)
bool isTypeAltiVecVector() const
void setEofData(const void *D)
static bool isPipeDeclerator(const Declarator &D)
SourceLocation getVolatileSpecLoc() const
SourceLocation getThreadStorageClassSpecLoc() const
static constexpr bool isOneOf()
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
void setAsmLabel(Expr *E)
DeclContext * getDeclContext()
static const TST TST_decimal64
This is a compound statement scope.
SourceLocation getStorageClassSpecLoc() const
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7)...
void UpdateTypeRep(ParsedType Rep)
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
A class for parsing a field declarator.
bool isValid() const
Determine whether this availability change is valid.
SourceLocation Loc
Loc - The place where this type was defined.
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
void setEllipsisLoc(SourceLocation EL)
SourceLocation getEnd() const
bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getOpenLocation() const
static const TST TST_half
bool isFriendSpecified() const
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.
SourceRange VersionRange
The source range covering the version number.
static const TSW TSW_short
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
bool isFirstDeclarator() const
const LangOptions & getLangOpts() const
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 ...
This is a scope that corresponds to the parameters within a function prototype for a function declara...
bool hasGroupingParens() const
SourceManager & getSourceManager() const
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_char32
static const TST TST_fract
A class for parsing a DeclSpec.
bool isTemplateDecl() const
returns true if this declaration is a template
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
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.
SCS getStorageClassSpec() const
static const TST TST_float16
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
Encodes a location in the source.
void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record)
bool isTypeSpecOwned() const
static const TST TST_auto_type
bool TryAnnotateTypeOrScopeToken()
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
static void SetupFixedPointError(const LangOptions &LangOpts, const char *&PrevSpec, unsigned &DiagID, bool &isInvalid)
Syntax
The style used to specify an attribute.
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 LLVM_READONLY
SourceLocation getEndLoc() const LLVM_READONLY
static const TST TST_union
IdentifierInfo * getIdentifierInfo() const
ParsedAttr - Represents a syntactic attribute.
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...
bool isWrittenInBuiltinFile(SourceLocation Loc) const
Returns whether Loc is located in a <built-in> file.
static const TSS TSS_signed
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them...
void setGroupingParens(bool flag)
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
const void * getEofData() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
void remove(ParsedAttr *ToBeRemoved)
Decl * getRepAsDecl() const
static const TST TST_typeofType
Used for C's _Alignof and C++'s alignof.
Scope * getCurScope() const
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getInlineSpecLoc() const
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
SourceLocation getModulePrivateSpecLoc() const
StringRef getName() const
Return the actual identifier string.
The scope of a struct/union/class definition.
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
bool isNot(tok::TokenKind K) const
void ActOnReenterFunctionContext(Scope *S, Decl *D)
Push the parameters of D, which must be a function, into scope.
TSW getTypeSpecWidth() const
ParserCompletionContext
Describes the context in which code completion occurs.
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static bool isInvalid(LocType Loc, bool *Invalid)
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool expectAndConsume(unsigned DiagID=diag::err_expected, const char *Msg="", tok::TokenKind SkipToTok=tok::unknown)
static const TST TST_auto
static const TST TST_void
CXXScopeSpec SS
The nested-name-specifier that precedes the template name.
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
static const TST TST_int128
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
SourceLocation getPipeLoc() const
This is a scope that corresponds to the template parameters of a C++ template.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
The name refers to a template whose specialization produces a type.
static const TST TST_unspecified
unsigned getLength() const
bool isValid() const
A scope specifier is present, and it refers to a real scope.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
const TargetInfo & getTargetInfo() const
static const TST TST_decimal128
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void takeAttributesFrom(ParsedAttributes &attrs)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
static const TSCS TSCS___thread
SourceLocation getVirtualSpecLoc() const
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_typename
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
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)
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.
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
CharSourceRange getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
CXXScopeSpec & getTypeSpecScope()
This is a scope that can contain a declaration.
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getIdentifierLoc() const
bool isSet() const
Deprecated.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, ParsedAttr::Syntax syntaxUsed)
Add an attribute with a single type argument.
void setInvalidType(bool Val=true)
ExprResult ParseConstantExpression(TypeCastState isTypeCast=NotTypeCast)
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".
SourceLocation getRestrictSpecLoc() const
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef< Decl *> Group)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
static const TSCS TSCS_thread_local
SourceLocation getEllipsisLoc() const
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required. ...
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
static const TST TST_float128
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
static const TST TST_bool
bool isVirtualSpecified() const
bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc, SourceLocation EndLoc)
Check if the a start and end source location expand to the same macro.
Decl * getObjCDeclContext() const
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
A template-id, e.g., f<int>.
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.
bool isInlineSpecified() const
void ExtendWithDeclSpec(const DeclSpec &DS)
ExtendWithDeclSpec - Extend the declarator source range to include the given declspec, unless its location is invalid.
SourceLocation getAtomicSpecLoc() const
static const TSW TSW_longlong
static Decl::Kind getKind(const Decl *D)
SourceLocation getExplicitSpecLoc() const
SourceLocation getConstexprSpecLoc() const
static bool attributeIsTypeArgAttr(const IdentifierInfo &II)
Determine whether the given attribute parses a type argument.
static const TST TST_atomic
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II)
Determine whether the given attribute treats kw_this as an identifier.
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
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...
DeclaratorContext getContext() const
void setLocation(SourceLocation L)
A trivial tuple used to represent a source range.
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
This represents a decl that may have a name.
__ptr16, alignas(...), etc.
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
static const TSCS TSCS__Thread_local
Callback handler that receives notifications when performing code completion within the preprocessor...
void * getAnnotationValue() const
bool isFirstDeclarationOfMember()
Returns true if this declares a real member and not a friend.
void SetRangeEnd(SourceLocation Loc)
void addAttributes(ParsedAttributesView &AL)
Concatenates two attribute lists.
SourceLocation getBegin() const
ParsedAttributes - A collection of parsed attributes.
void setCommaLoc(SourceLocation CL)
This class handles loading and caching of source files into memory.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeNameContext, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
ParsedAttributes & getAttributes()
SourceLocation getLocation() const
void startToken()
Reset all flags to cleared.
Decl * ActOnDeclarator(Scope *S, Declarator &D)
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
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.
unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template)
SourceLocation getEndLoc() const