Mercurial > hg > CbC > CbC_llvm
comparison clang/lib/Parse/ParseDecl.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | dd44ba33042e 5f17cb93ff66 |
comparison
equal
deleted
inserted
replaced
173:0572611fdcc8 | 207:2e18cbf3894f |
---|---|
21 #include "clang/Basic/TargetInfo.h" | 21 #include "clang/Basic/TargetInfo.h" |
22 #include "clang/Parse/ParseDiagnostic.h" | 22 #include "clang/Parse/ParseDiagnostic.h" |
23 #include "clang/Sema/Lookup.h" | 23 #include "clang/Sema/Lookup.h" |
24 #include "clang/Sema/ParsedTemplate.h" | 24 #include "clang/Sema/ParsedTemplate.h" |
25 #include "clang/Sema/Scope.h" | 25 #include "clang/Sema/Scope.h" |
26 #include "clang/Sema/SemaDiagnostic.h" | |
26 #include "llvm/ADT/Optional.h" | 27 #include "llvm/ADT/Optional.h" |
27 #include "llvm/ADT/SmallSet.h" | 28 #include "llvm/ADT/SmallSet.h" |
28 #include "llvm/ADT/SmallString.h" | 29 #include "llvm/ADT/SmallString.h" |
29 #include "llvm/ADT/StringSwitch.h" | 30 #include "llvm/ADT/StringSwitch.h" |
30 | 31 |
98 bool AttrStartIsInMacro = | 99 bool AttrStartIsInMacro = |
99 Lexer::isAtStartOfMacroExpansion(StartLoc, SM, PP.getLangOpts()); | 100 Lexer::isAtStartOfMacroExpansion(StartLoc, SM, PP.getLangOpts()); |
100 bool AttrEndIsInMacro = | 101 bool AttrEndIsInMacro = |
101 Lexer::isAtEndOfMacroExpansion(EndLoc, SM, PP.getLangOpts()); | 102 Lexer::isAtEndOfMacroExpansion(EndLoc, SM, PP.getLangOpts()); |
102 return AttrStartIsInMacro && AttrEndIsInMacro; | 103 return AttrStartIsInMacro && AttrEndIsInMacro; |
104 } | |
105 | |
106 void Parser::ParseAttributes(unsigned WhichAttrKinds, | |
107 ParsedAttributesWithRange &Attrs, | |
108 SourceLocation *End, | |
109 LateParsedAttrList *LateAttrs) { | |
110 bool MoreToParse; | |
111 do { | |
112 // Assume there's nothing left to parse, but if any attributes are in fact | |
113 // parsed, loop to ensure all specified attribute combinations are parsed. | |
114 MoreToParse = false; | |
115 if (WhichAttrKinds & PAKM_CXX11) | |
116 MoreToParse |= MaybeParseCXX11Attributes(Attrs, End); | |
117 if (WhichAttrKinds & PAKM_GNU) | |
118 MoreToParse |= MaybeParseGNUAttributes(Attrs, End, LateAttrs); | |
119 if (WhichAttrKinds & PAKM_Declspec) | |
120 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs, End); | |
121 } while (MoreToParse); | |
103 } | 122 } |
104 | 123 |
105 /// ParseGNUAttributes - Parse a non-empty attributes list. | 124 /// ParseGNUAttributes - Parse a non-empty attributes list. |
106 /// | 125 /// |
107 /// [GNU] attributes: | 126 /// [GNU] attributes: |
141 /// and the attribute *wants* an identifier, it is parsed as an identifier. | 160 /// and the attribute *wants* an identifier, it is parsed as an identifier. |
142 /// At block scope, any additional tokens between the identifier and the | 161 /// At block scope, any additional tokens between the identifier and the |
143 /// ',' or ')' are ignored, otherwise they produce a parse error. | 162 /// ',' or ')' are ignored, otherwise they produce a parse error. |
144 /// | 163 /// |
145 /// We follow the C++ model, but don't allow junk after the identifier. | 164 /// We follow the C++ model, but don't allow junk after the identifier. |
146 void Parser::ParseGNUAttributes(ParsedAttributes &attrs, | 165 void Parser::ParseGNUAttributes(ParsedAttributesWithRange &Attrs, |
147 SourceLocation *endLoc, | 166 SourceLocation *EndLoc, |
148 LateParsedAttrList *LateAttrs, | 167 LateParsedAttrList *LateAttrs, Declarator *D) { |
149 Declarator *D) { | |
150 assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!"); | 168 assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!"); |
169 | |
170 SourceLocation StartLoc = Tok.getLocation(), Loc; | |
171 | |
172 if (!EndLoc) | |
173 EndLoc = &Loc; | |
151 | 174 |
152 while (Tok.is(tok::kw___attribute)) { | 175 while (Tok.is(tok::kw___attribute)) { |
153 SourceLocation AttrTokLoc = ConsumeToken(); | 176 SourceLocation AttrTokLoc = ConsumeToken(); |
154 unsigned OldNumAttrs = attrs.size(); | 177 unsigned OldNumAttrs = Attrs.size(); |
155 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0; | 178 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0; |
156 | 179 |
157 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, | 180 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, |
158 "attribute")) { | 181 "attribute")) { |
159 SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ; | 182 SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ; |
177 break; | 200 break; |
178 | 201 |
179 SourceLocation AttrNameLoc = ConsumeToken(); | 202 SourceLocation AttrNameLoc = ConsumeToken(); |
180 | 203 |
181 if (Tok.isNot(tok::l_paren)) { | 204 if (Tok.isNot(tok::l_paren)) { |
182 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, | 205 Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, |
183 ParsedAttr::AS_GNU); | 206 ParsedAttr::AS_GNU); |
184 continue; | 207 continue; |
185 } | 208 } |
186 | 209 |
187 // Handle "parameterized" attributes | 210 // Handle "parameterized" attributes |
188 if (!LateAttrs || !isAttributeLateParsed(*AttrName)) { | 211 if (!LateAttrs || !isAttributeLateParsed(*AttrName)) { |
189 ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc, nullptr, | 212 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, nullptr, |
190 SourceLocation(), ParsedAttr::AS_GNU, D); | 213 SourceLocation(), ParsedAttr::AS_GNU, D); |
191 continue; | 214 continue; |
192 } | 215 } |
193 | 216 |
194 // Handle attributes with arguments that require late parsing. | 217 // Handle attributes with arguments that require late parsing. |
217 if (ExpectAndConsume(tok::r_paren)) | 240 if (ExpectAndConsume(tok::r_paren)) |
218 SkipUntil(tok::r_paren, StopAtSemi); | 241 SkipUntil(tok::r_paren, StopAtSemi); |
219 SourceLocation Loc = Tok.getLocation(); | 242 SourceLocation Loc = Tok.getLocation(); |
220 if (ExpectAndConsume(tok::r_paren)) | 243 if (ExpectAndConsume(tok::r_paren)) |
221 SkipUntil(tok::r_paren, StopAtSemi); | 244 SkipUntil(tok::r_paren, StopAtSemi); |
222 if (endLoc) | 245 if (EndLoc) |
223 *endLoc = Loc; | 246 *EndLoc = Loc; |
224 | 247 |
225 // If this was declared in a macro, attach the macro IdentifierInfo to the | 248 // If this was declared in a macro, attach the macro IdentifierInfo to the |
226 // parsed attribute. | 249 // parsed attribute. |
227 auto &SM = PP.getSourceManager(); | 250 auto &SM = PP.getSourceManager(); |
228 if (!SM.isWrittenInBuiltinFile(SM.getSpellingLoc(AttrTokLoc)) && | 251 if (!SM.isWrittenInBuiltinFile(SM.getSpellingLoc(AttrTokLoc)) && |
230 CharSourceRange ExpansionRange = SM.getExpansionRange(AttrTokLoc); | 253 CharSourceRange ExpansionRange = SM.getExpansionRange(AttrTokLoc); |
231 StringRef FoundName = | 254 StringRef FoundName = |
232 Lexer::getSourceText(ExpansionRange, SM, PP.getLangOpts()); | 255 Lexer::getSourceText(ExpansionRange, SM, PP.getLangOpts()); |
233 IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName); | 256 IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName); |
234 | 257 |
235 for (unsigned i = OldNumAttrs; i < attrs.size(); ++i) | 258 for (unsigned i = OldNumAttrs; i < Attrs.size(); ++i) |
236 attrs[i].setMacroIdentifier(MacroII, ExpansionRange.getBegin()); | 259 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.getBegin()); |
237 | 260 |
238 if (LateAttrs) { | 261 if (LateAttrs) { |
239 for (unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i) | 262 for (unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i) |
240 (*LateAttrs)[i]->MacroII = MacroII; | 263 (*LateAttrs)[i]->MacroII = MacroII; |
241 } | 264 } |
242 } | 265 } |
243 } | 266 } |
267 | |
268 Attrs.Range = SourceRange(StartLoc, *EndLoc); | |
244 } | 269 } |
245 | 270 |
246 /// Determine whether the given attribute has an identifier argument. | 271 /// Determine whether the given attribute has an identifier argument. |
247 static bool attributeHasIdentifierArg(const IdentifierInfo &II) { | 272 static bool attributeHasIdentifierArg(const IdentifierInfo &II) { |
248 #define CLANG_ATTR_IDENTIFIER_ARG_LIST | 273 #define CLANG_ATTR_IDENTIFIER_ARG_LIST |
450 return; | 475 return; |
451 } else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) { | 476 } else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) { |
452 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, | 477 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, |
453 ScopeName, ScopeLoc, Syntax); | 478 ScopeName, ScopeLoc, Syntax); |
454 return; | 479 return; |
480 } else if (AttrKind == ParsedAttr::AT_SwiftNewType) { | |
481 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, | |
482 ScopeLoc, Syntax); | |
483 return; | |
455 } else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) { | 484 } else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) { |
456 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, | 485 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, |
457 ScopeName, ScopeLoc, Syntax); | 486 ScopeName, ScopeLoc, Syntax); |
458 return; | 487 return; |
459 } else if (attributeIsTypeArgAttr(*AttrName)) { | 488 } else if (attributeIsTypeArgAttr(*AttrName)) { |
503 ScopeLoc, Syntax); | 532 ScopeLoc, Syntax); |
504 break; | 533 break; |
505 case ParsedAttr::AT_ObjCBridgeRelated: | 534 case ParsedAttr::AT_ObjCBridgeRelated: |
506 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, | 535 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, |
507 ScopeName, ScopeLoc, Syntax); | 536 ScopeName, ScopeLoc, Syntax); |
537 break; | |
538 case ParsedAttr::AT_SwiftNewType: | |
539 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, | |
540 ScopeLoc, Syntax); | |
508 break; | 541 break; |
509 case ParsedAttr::AT_TypeTagForDatatype: | 542 case ParsedAttr::AT_TypeTagForDatatype: |
510 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, | 543 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, |
511 ScopeName, ScopeLoc, Syntax); | 544 ScopeName, ScopeLoc, Syntax); |
512 break; | 545 break; |
822 // Treat these like attributes, even though they're type specifiers. | 855 // Treat these like attributes, even though they're type specifiers. |
823 while (true) { | 856 while (true) { |
824 switch (Tok.getKind()) { | 857 switch (Tok.getKind()) { |
825 case tok::kw__Nonnull: | 858 case tok::kw__Nonnull: |
826 case tok::kw__Nullable: | 859 case tok::kw__Nullable: |
860 case tok::kw__Nullable_result: | |
827 case tok::kw__Null_unspecified: { | 861 case tok::kw__Null_unspecified: { |
828 IdentifierInfo *AttrName = Tok.getIdentifierInfo(); | 862 IdentifierInfo *AttrName = Tok.getIdentifierInfo(); |
829 SourceLocation AttrNameLoc = ConsumeToken(); | 863 SourceLocation AttrNameLoc = ConsumeToken(); |
830 if (!getLangOpts().ObjC) | 864 if (!getLangOpts().ObjC) |
831 Diag(AttrNameLoc, diag::ext_nullability) | 865 Diag(AttrNameLoc, diag::ext_nullability) |
1107 else | 1141 else |
1108 ReplacementExpr = ParseStringLiteralExpression(); | 1142 ReplacementExpr = ParseStringLiteralExpression(); |
1109 // Also reject wide string literals. | 1143 // Also reject wide string literals. |
1110 if (StringLiteral *MessageStringLiteral = | 1144 if (StringLiteral *MessageStringLiteral = |
1111 cast_or_null<StringLiteral>(MessageExpr.get())) { | 1145 cast_or_null<StringLiteral>(MessageExpr.get())) { |
1112 if (MessageStringLiteral->getCharByteWidth() != 1) { | 1146 if (!MessageStringLiteral->isAscii()) { |
1113 Diag(MessageStringLiteral->getSourceRange().getBegin(), | 1147 Diag(MessageStringLiteral->getSourceRange().getBegin(), |
1114 diag::err_expected_string_literal) | 1148 diag::err_expected_string_literal) |
1115 << /*Source='availability attribute'*/ 2; | 1149 << /*Source='availability attribute'*/ 2; |
1116 SkipUntil(tok::r_paren, StopAtSemi); | 1150 SkipUntil(tok::r_paren, StopAtSemi); |
1117 return; | 1151 return; |
1407 ClassMethod, | 1441 ClassMethod, |
1408 InstanceMethod, | 1442 InstanceMethod, |
1409 Syntax); | 1443 Syntax); |
1410 } | 1444 } |
1411 | 1445 |
1412 // Late Parsed Attributes: | 1446 |
1413 // See other examples of late parsing in lib/Parse/ParseCXXInlineMethods | 1447 void Parser::ParseSwiftNewTypeAttribute( |
1414 | 1448 IdentifierInfo &AttrName, SourceLocation AttrNameLoc, |
1415 void Parser::LateParsedDeclaration::ParseLexedAttributes() {} | 1449 ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName, |
1416 | 1450 SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax) { |
1417 void Parser::LateParsedClass::ParseLexedAttributes() { | 1451 BalancedDelimiterTracker T(*this, tok::l_paren); |
1418 Self->ParseLexedAttributes(*Class); | 1452 |
1419 } | 1453 // Opening '(' |
1420 | 1454 if (T.consumeOpen()) { |
1421 void Parser::LateParsedAttribute::ParseLexedAttributes() { | 1455 Diag(Tok, diag::err_expected) << tok::l_paren; |
1422 Self->ParseLexedAttribute(*this, true, false); | 1456 return; |
1423 } | 1457 } |
1424 | 1458 |
1425 /// Wrapper class which calls ParseLexedAttribute, after setting up the | 1459 if (Tok.is(tok::r_paren)) { |
1426 /// scope appropriately. | 1460 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute); |
1427 void Parser::ParseLexedAttributes(ParsingClass &Class) { | 1461 T.consumeClose(); |
1428 // Deal with templates | 1462 return; |
1429 // FIXME: Test cases to make sure this does the right thing for templates. | 1463 } |
1430 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; | 1464 if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) { |
1431 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, | 1465 Diag(Tok, diag::warn_attribute_type_not_supported) |
1432 HasTemplateScope); | 1466 << &AttrName << Tok.getIdentifierInfo(); |
1433 if (HasTemplateScope) | 1467 if (!isTokenSpecial()) |
1434 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); | 1468 ConsumeToken(); |
1435 | 1469 T.consumeClose(); |
1436 // Set or update the scope flags. | 1470 return; |
1437 bool AlreadyHasClassScope = Class.TopLevelClass; | 1471 } |
1438 unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; | 1472 |
1439 ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); | 1473 auto *SwiftType = IdentifierLoc::create(Actions.Context, Tok.getLocation(), |
1440 ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); | 1474 Tok.getIdentifierInfo()); |
1441 | 1475 ConsumeToken(); |
1442 // Enter the scope of nested classes | 1476 |
1443 if (!AlreadyHasClassScope) | 1477 // Closing ')' |
1444 Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), | 1478 if (T.consumeClose()) |
1445 Class.TagOrTemplate); | 1479 return; |
1446 if (!Class.LateParsedDeclarations.empty()) { | 1480 if (EndLoc) |
1447 for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){ | 1481 *EndLoc = T.getCloseLocation(); |
1448 Class.LateParsedDeclarations[i]->ParseLexedAttributes(); | 1482 |
1449 } | 1483 ArgsUnion Args[] = {SwiftType}; |
1450 } | 1484 Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, T.getCloseLocation()), |
1451 | 1485 ScopeName, ScopeLoc, Args, llvm::array_lengthof(Args), Syntax); |
1452 if (!AlreadyHasClassScope) | 1486 } |
1453 Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), | 1487 |
1454 Class.TagOrTemplate); | |
1455 } | |
1456 | |
1457 /// Parse all attributes in LAs, and attach them to Decl D. | |
1458 void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, | |
1459 bool EnterScope, bool OnDefinition) { | |
1460 assert(LAs.parseSoon() && | |
1461 "Attribute list should be marked for immediate parsing."); | |
1462 for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { | |
1463 if (D) | |
1464 LAs[i]->addDecl(D); | |
1465 ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); | |
1466 delete LAs[i]; | |
1467 } | |
1468 LAs.clear(); | |
1469 } | |
1470 | |
1471 /// Finish parsing an attribute for which parsing was delayed. | |
1472 /// This will be called at the end of parsing a class declaration | |
1473 /// for each LateParsedAttribute. We consume the saved tokens and | |
1474 /// create an attribute with the arguments filled in. We add this | |
1475 /// to the Attribute list for the decl. | |
1476 void Parser::ParseLexedAttribute(LateParsedAttribute &LA, | |
1477 bool EnterScope, bool OnDefinition) { | |
1478 // Create a fake EOF so that attribute parsing won't go off the end of the | |
1479 // attribute. | |
1480 Token AttrEnd; | |
1481 AttrEnd.startToken(); | |
1482 AttrEnd.setKind(tok::eof); | |
1483 AttrEnd.setLocation(Tok.getLocation()); | |
1484 AttrEnd.setEofData(LA.Toks.data()); | |
1485 LA.Toks.push_back(AttrEnd); | |
1486 | |
1487 // Append the current token at the end of the new token stream so that it | |
1488 // doesn't get lost. | |
1489 LA.Toks.push_back(Tok); | |
1490 PP.EnterTokenStream(LA.Toks, true, /*IsReinject=*/true); | |
1491 // Consume the previously pushed token. | |
1492 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); | |
1493 | |
1494 ParsedAttributes Attrs(AttrFactory); | |
1495 SourceLocation endLoc; | |
1496 | |
1497 if (LA.Decls.size() > 0) { | |
1498 Decl *D = LA.Decls[0]; | |
1499 NamedDecl *ND = dyn_cast<NamedDecl>(D); | |
1500 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); | |
1501 | |
1502 // Allow 'this' within late-parsed attributes. | |
1503 Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(), | |
1504 ND && ND->isCXXInstanceMember()); | |
1505 | |
1506 if (LA.Decls.size() == 1) { | |
1507 // If the Decl is templatized, add template parameters to scope. | |
1508 bool HasTemplateScope = EnterScope && D->isTemplateDecl(); | |
1509 ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope); | |
1510 if (HasTemplateScope) | |
1511 Actions.ActOnReenterTemplateScope(Actions.CurScope, D); | |
1512 | |
1513 // If the Decl is on a function, add function parameters to the scope. | |
1514 bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); | |
1515 ParseScope FnScope( | |
1516 this, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope, | |
1517 HasFunScope); | |
1518 if (HasFunScope) | |
1519 Actions.ActOnReenterFunctionContext(Actions.CurScope, D); | |
1520 | |
1521 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, | |
1522 nullptr, SourceLocation(), ParsedAttr::AS_GNU, | |
1523 nullptr); | |
1524 | |
1525 if (HasFunScope) { | |
1526 Actions.ActOnExitFunctionContext(); | |
1527 FnScope.Exit(); // Pop scope, and remove Decls from IdResolver | |
1528 } | |
1529 if (HasTemplateScope) { | |
1530 TempScope.Exit(); | |
1531 } | |
1532 } else { | |
1533 // If there are multiple decls, then the decl cannot be within the | |
1534 // function scope. | |
1535 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, | |
1536 nullptr, SourceLocation(), ParsedAttr::AS_GNU, | |
1537 nullptr); | |
1538 } | |
1539 } else { | |
1540 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); | |
1541 } | |
1542 | |
1543 if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() && | |
1544 Attrs.begin()->isKnownToGCC()) | |
1545 Diag(Tok, diag::warn_attribute_on_function_definition) | |
1546 << &LA.AttrName; | |
1547 | |
1548 for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) | |
1549 Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs); | |
1550 | |
1551 // Due to a parsing error, we either went over the cached tokens or | |
1552 // there are still cached tokens left, so we skip the leftover tokens. | |
1553 while (Tok.isNot(tok::eof)) | |
1554 ConsumeAnyToken(); | |
1555 | |
1556 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()) | |
1557 ConsumeAnyToken(); | |
1558 } | |
1559 | 1488 |
1560 void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, | 1489 void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, |
1561 SourceLocation AttrNameLoc, | 1490 SourceLocation AttrNameLoc, |
1562 ParsedAttributes &Attrs, | 1491 ParsedAttributes &Attrs, |
1563 SourceLocation *EndLoc, | 1492 SourceLocation *EndLoc, |
1682 } else | 1611 } else |
1683 Diag(Range.getBegin(), diag::err_attributes_not_allowed) << Range; | 1612 Diag(Range.getBegin(), diag::err_attributes_not_allowed) << Range; |
1684 } | 1613 } |
1685 | 1614 |
1686 void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, | 1615 void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, |
1687 unsigned DiagID) { | 1616 unsigned DiagID, bool DiagnoseEmptyAttrs) { |
1617 | |
1618 if (DiagnoseEmptyAttrs && Attrs.empty() && Attrs.Range.isValid()) { | |
1619 // An attribute list has been parsed, but it was empty. | |
1620 // This is the case for [[]]. | |
1621 const auto &LangOpts = getLangOpts(); | |
1622 auto &SM = PP.getSourceManager(); | |
1623 Token FirstLSquare; | |
1624 Lexer::getRawToken(Attrs.Range.getBegin(), FirstLSquare, SM, LangOpts); | |
1625 | |
1626 if (FirstLSquare.is(tok::l_square)) { | |
1627 llvm::Optional<Token> SecondLSquare = | |
1628 Lexer::findNextToken(FirstLSquare.getLocation(), SM, LangOpts); | |
1629 | |
1630 if (SecondLSquare && SecondLSquare->is(tok::l_square)) { | |
1631 // The attribute range starts with [[, but is empty. So this must | |
1632 // be [[]], which we are supposed to diagnose because | |
1633 // DiagnoseEmptyAttrs is true. | |
1634 Diag(Attrs.Range.getBegin(), DiagID) << Attrs.Range; | |
1635 return; | |
1636 } | |
1637 } | |
1638 } | |
1639 | |
1688 for (const ParsedAttr &AL : Attrs) { | 1640 for (const ParsedAttr &AL : Attrs) { |
1689 if (!AL.isCXX11Attribute() && !AL.isC2xAttribute()) | 1641 if (!AL.isCXX11Attribute() && !AL.isC2xAttribute()) |
1690 continue; | 1642 continue; |
1691 if (AL.getKind() == ParsedAttr::UnknownAttribute) | 1643 if (AL.getKind() == ParsedAttr::UnknownAttribute) |
1692 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) << AL; | 1644 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) |
1645 << AL << AL.getRange(); | |
1693 else { | 1646 else { |
1694 Diag(AL.getLoc(), DiagID) << AL; | 1647 Diag(AL.getLoc(), DiagID) << AL; |
1695 AL.setInvalid(); | 1648 AL.setInvalid(); |
1696 } | 1649 } |
1650 } | |
1651 } | |
1652 | |
1653 void Parser::DiagnoseCXX11AttributeExtension(ParsedAttributesWithRange &Attrs) { | |
1654 for (const ParsedAttr &PA : Attrs) { | |
1655 if (PA.isCXX11Attribute() || PA.isC2xAttribute()) | |
1656 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement) << PA << PA.getRange(); | |
1697 } | 1657 } |
1698 } | 1658 } |
1699 | 1659 |
1700 // Usually, `__attribute__((attrib)) class Foo {} var` means that attribute | 1660 // Usually, `__attribute__((attrib)) class Foo {} var` means that attribute |
1701 // applies to var, not the type Foo. | 1661 // applies to var, not the type Foo. |
1867 case tok::amp: | 1827 case tok::amp: |
1868 case tok::ampamp: | 1828 case tok::ampamp: |
1869 return getLangOpts().CPlusPlus; | 1829 return getLangOpts().CPlusPlus; |
1870 | 1830 |
1871 case tok::l_square: // Might be an attribute on an unnamed bit-field. | 1831 case tok::l_square: // Might be an attribute on an unnamed bit-field. |
1872 return Context == DeclaratorContext::MemberContext && | 1832 return Context == DeclaratorContext::Member && getLangOpts().CPlusPlus11 && |
1873 getLangOpts().CPlusPlus11 && NextToken().is(tok::l_square); | 1833 NextToken().is(tok::l_square); |
1874 | 1834 |
1875 case tok::colon: // Might be a typo for '::' or an unnamed bit-field. | 1835 case tok::colon: // Might be a typo for '::' or an unnamed bit-field. |
1876 return Context == DeclaratorContext::MemberContext || | 1836 return Context == DeclaratorContext::Member || getLangOpts().CPlusPlus; |
1877 getLangOpts().CPlusPlus; | |
1878 | 1837 |
1879 case tok::identifier: | 1838 case tok::identifier: |
1880 switch (NextToken().getKind()) { | 1839 switch (NextToken().getKind()) { |
1881 case tok::code_completion: | 1840 case tok::code_completion: |
1882 case tok::coloncolon: | 1841 case tok::coloncolon: |
1898 | 1857 |
1899 case tok::colon: | 1858 case tok::colon: |
1900 // At namespace scope, 'identifier:' is probably a typo for 'identifier::' | 1859 // At namespace scope, 'identifier:' is probably a typo for 'identifier::' |
1901 // and in block scope it's probably a label. Inside a class definition, | 1860 // and in block scope it's probably a label. Inside a class definition, |
1902 // this is a bit-field. | 1861 // this is a bit-field. |
1903 return Context == DeclaratorContext::MemberContext || | 1862 return Context == DeclaratorContext::Member || |
1904 (getLangOpts().CPlusPlus && | 1863 (getLangOpts().CPlusPlus && Context == DeclaratorContext::File); |
1905 Context == DeclaratorContext::FileContext); | |
1906 | 1864 |
1907 case tok::identifier: // Possible virt-specifier. | 1865 case tok::identifier: // Possible virt-specifier. |
1908 return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken()); | 1866 return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken()); |
1909 | 1867 |
1910 default: | 1868 default: |
2044 : FixItHint()); | 2002 : FixItHint()); |
2045 } | 2003 } |
2046 } | 2004 } |
2047 | 2005 |
2048 // Check to see if we have a function *definition* which must have a body. | 2006 // Check to see if we have a function *definition* which must have a body. |
2049 if (D.isFunctionDeclarator() && | 2007 if (D.isFunctionDeclarator()) { |
2050 // Look at the next token to make sure that this isn't a function | 2008 if (Tok.is(tok::equal) && NextToken().is(tok::code_completion)) { |
2051 // declaration. We have to check this because __attribute__ might be the | 2009 cutOffParsing(); |
2052 // start of a function definition in GCC-extended K&R C. | 2010 Actions.CodeCompleteAfterFunctionEquals(D); |
2053 !isDeclarationAfterDeclarator()) { | 2011 return nullptr; |
2054 | 2012 } |
2055 // Function definitions are only allowed at file scope and in C++ classes. | 2013 // Look at the next token to make sure that this isn't a function |
2056 // The C++ inline method definition case is handled elsewhere, so we only | 2014 // declaration. We have to check this because __attribute__ might be the |
2057 // need to handle the file scope definition case. | 2015 // start of a function definition in GCC-extended K&R C. |
2058 if (Context == DeclaratorContext::FileContext) { | 2016 if (!isDeclarationAfterDeclarator()) { |
2059 if (isStartOfFunctionDefinition(D)) { | 2017 |
2060 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { | 2018 // Function definitions are only allowed at file scope and in C++ classes. |
2061 Diag(Tok, diag::err_function_declared_typedef); | 2019 // The C++ inline method definition case is handled elsewhere, so we only |
2062 | 2020 // need to handle the file scope definition case. |
2063 // Recover by treating the 'typedef' as spurious. | 2021 if (Context == DeclaratorContext::File) { |
2064 DS.ClearStorageClassSpecs(); | 2022 if (isStartOfFunctionDefinition(D)) { |
2023 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { | |
2024 Diag(Tok, diag::err_function_declared_typedef); | |
2025 | |
2026 // Recover by treating the 'typedef' as spurious. | |
2027 DS.ClearStorageClassSpecs(); | |
2028 } | |
2029 | |
2030 Decl *TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(), | |
2031 &LateParsedAttrs); | |
2032 return Actions.ConvertDeclToDeclGroup(TheDecl); | |
2065 } | 2033 } |
2066 | 2034 |
2067 Decl *TheDecl = | 2035 if (isDeclarationSpecifier()) { |
2068 ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs); | 2036 // If there is an invalid declaration specifier right after the |
2069 return Actions.ConvertDeclToDeclGroup(TheDecl); | 2037 // function prototype, then we must be in a missing semicolon case |
2070 } | 2038 // where this isn't actually a body. Just fall through into the code |
2071 | 2039 // that handles it as a prototype, and let the top-level code handle |
2072 if (isDeclarationSpecifier()) { | 2040 // the erroneous declspec where it would otherwise expect a comma or |
2073 // If there is an invalid declaration specifier right after the | 2041 // semicolon. |
2074 // function prototype, then we must be in a missing semicolon case | 2042 } else { |
2075 // where this isn't actually a body. Just fall through into the code | 2043 Diag(Tok, diag::err_expected_fn_body); |
2076 // that handles it as a prototype, and let the top-level code handle | 2044 SkipUntil(tok::semi); |
2077 // the erroneous declspec where it would otherwise expect a comma or | 2045 return nullptr; |
2078 // semicolon. | 2046 } |
2079 } else { | 2047 } else { |
2080 Diag(Tok, diag::err_expected_fn_body); | 2048 if (Tok.is(tok::l_brace)) { |
2081 SkipUntil(tok::semi); | 2049 Diag(Tok, diag::err_function_definition_not_allowed); |
2082 return nullptr; | 2050 SkipMalformedDecl(); |
2083 } | 2051 return nullptr; |
2084 } else { | 2052 } |
2085 if (Tok.is(tok::l_brace)) { | |
2086 Diag(Tok, diag::err_function_definition_not_allowed); | |
2087 SkipMalformedDecl(); | |
2088 return nullptr; | |
2089 } | 2053 } |
2090 } | 2054 } |
2091 } | 2055 } |
2092 | 2056 |
2093 if (ParseAsmAttributesAfterDeclarator(D)) | 2057 if (ParseAsmAttributesAfterDeclarator(D)) |
2131 ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false); | 2095 ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false); |
2132 D.complete(FirstDecl); | 2096 D.complete(FirstDecl); |
2133 if (FirstDecl) | 2097 if (FirstDecl) |
2134 DeclsInGroup.push_back(FirstDecl); | 2098 DeclsInGroup.push_back(FirstDecl); |
2135 | 2099 |
2136 bool ExpectSemi = Context != DeclaratorContext::ForContext; | 2100 bool ExpectSemi = Context != DeclaratorContext::ForInit; |
2137 | 2101 |
2138 // If we don't have a comma, it is either the end of the list (a ';') or an | 2102 // If we don't have a comma, it is either the end of the list (a ';') or an |
2139 // error, bail out. | 2103 // error, bail out. |
2140 SourceLocation CommaLoc; | 2104 SourceLocation CommaLoc; |
2141 while (TryConsumeToken(tok::comma, CommaLoc)) { | 2105 while (TryConsumeToken(tok::comma, CommaLoc)) { |
2182 } | 2146 } |
2183 | 2147 |
2184 if (DeclEnd) | 2148 if (DeclEnd) |
2185 *DeclEnd = Tok.getLocation(); | 2149 *DeclEnd = Tok.getLocation(); |
2186 | 2150 |
2187 if (ExpectSemi && | 2151 if (ExpectSemi && ExpectAndConsumeSemi( |
2188 ExpectAndConsumeSemi(Context == DeclaratorContext::FileContext | 2152 Context == DeclaratorContext::File |
2189 ? diag::err_invalid_token_after_toplevel_declarator | 2153 ? diag::err_invalid_token_after_toplevel_declarator |
2190 : diag::err_expected_semi_declaration)) { | 2154 : diag::err_expected_semi_declaration)) { |
2191 // Okay, there was no semicolon and one was expected. If we see a | 2155 // Okay, there was no semicolon and one was expected. If we see a |
2192 // declaration specifier, just assume it was missing and continue parsing. | 2156 // declaration specifier, just assume it was missing and continue parsing. |
2193 // Otherwise things are very confused and we skip to recover. | 2157 // Otherwise things are very confused and we skip to recover. |
2194 if (!isDeclarationSpecifier()) { | 2158 if (!isDeclarationSpecifier()) { |
2195 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); | 2159 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); |
2281 } | 2245 } |
2282 ThisDecl = nullptr; | 2246 ThisDecl = nullptr; |
2283 } | 2247 } |
2284 }; | 2248 }; |
2285 | 2249 |
2286 // Inform the current actions module that we just parsed this declarator. | 2250 enum class InitKind { Uninitialized, Equal, CXXDirect, CXXBraced }; |
2251 InitKind TheInitKind; | |
2252 // If a '==' or '+=' is found, suggest a fixit to '='. | |
2253 if (isTokenEqualOrEqualTypo()) | |
2254 TheInitKind = InitKind::Equal; | |
2255 else if (Tok.is(tok::l_paren)) | |
2256 TheInitKind = InitKind::CXXDirect; | |
2257 else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) && | |
2258 (!CurParsedObjCImpl || !D.isFunctionDeclarator())) | |
2259 TheInitKind = InitKind::CXXBraced; | |
2260 else | |
2261 TheInitKind = InitKind::Uninitialized; | |
2262 if (TheInitKind != InitKind::Uninitialized) | |
2263 D.setHasInitializer(); | |
2264 | |
2265 // Inform Sema that we just parsed this declarator. | |
2287 Decl *ThisDecl = nullptr; | 2266 Decl *ThisDecl = nullptr; |
2267 Decl *OuterDecl = nullptr; | |
2288 switch (TemplateInfo.Kind) { | 2268 switch (TemplateInfo.Kind) { |
2289 case ParsedTemplateInfo::NonTemplate: | 2269 case ParsedTemplateInfo::NonTemplate: |
2290 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); | 2270 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); |
2291 break; | 2271 break; |
2292 | 2272 |
2293 case ParsedTemplateInfo::Template: | 2273 case ParsedTemplateInfo::Template: |
2294 case ParsedTemplateInfo::ExplicitSpecialization: { | 2274 case ParsedTemplateInfo::ExplicitSpecialization: { |
2295 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), | 2275 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), |
2296 *TemplateInfo.TemplateParams, | 2276 *TemplateInfo.TemplateParams, |
2297 D); | 2277 D); |
2298 if (VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) | 2278 if (VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) { |
2299 // Re-direct this decl to refer to the templated decl so that we can | 2279 // Re-direct this decl to refer to the templated decl so that we can |
2300 // initialize it. | 2280 // initialize it. |
2301 ThisDecl = VT->getTemplatedDecl(); | 2281 ThisDecl = VT->getTemplatedDecl(); |
2282 OuterDecl = VT; | |
2283 } | |
2302 break; | 2284 break; |
2303 } | 2285 } |
2304 case ParsedTemplateInfo::ExplicitInstantiation: { | 2286 case ParsedTemplateInfo::ExplicitInstantiation: { |
2305 if (Tok.is(tok::semi)) { | 2287 if (Tok.is(tok::semi)) { |
2306 DeclResult ThisRes = Actions.ActOnExplicitInstantiation( | 2288 DeclResult ThisRes = Actions.ActOnExplicitInstantiation( |
2340 } | 2322 } |
2341 break; | 2323 break; |
2342 } | 2324 } |
2343 } | 2325 } |
2344 | 2326 |
2327 switch (TheInitKind) { | |
2345 // Parse declarator '=' initializer. | 2328 // Parse declarator '=' initializer. |
2346 // If a '==' or '+=' is found, suggest a fixit to '='. | 2329 case InitKind::Equal: { |
2347 if (isTokenEqualOrEqualTypo()) { | |
2348 SourceLocation EqualLoc = ConsumeToken(); | 2330 SourceLocation EqualLoc = ConsumeToken(); |
2349 | 2331 |
2350 if (Tok.is(tok::kw_delete)) { | 2332 if (Tok.is(tok::kw_delete)) { |
2351 if (D.isFunctionDeclarator()) | 2333 if (D.isFunctionDeclarator()) |
2352 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) | 2334 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) |
2362 << getLangOpts().CPlusPlus20; | 2344 << getLangOpts().CPlusPlus20; |
2363 } else { | 2345 } else { |
2364 InitializerScopeRAII InitScope(*this, D, ThisDecl); | 2346 InitializerScopeRAII InitScope(*this, D, ThisDecl); |
2365 | 2347 |
2366 if (Tok.is(tok::code_completion)) { | 2348 if (Tok.is(tok::code_completion)) { |
2349 cutOffParsing(); | |
2367 Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); | 2350 Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); |
2368 Actions.FinalizeDeclaration(ThisDecl); | 2351 Actions.FinalizeDeclaration(ThisDecl); |
2369 cutOffParsing(); | |
2370 return nullptr; | 2352 return nullptr; |
2371 } | 2353 } |
2372 | 2354 |
2373 PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl); | 2355 PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl); |
2374 ExprResult Init = ParseInitializer(); | 2356 ExprResult Init = ParseInitializer(); |
2388 InitScope.pop(); | 2370 InitScope.pop(); |
2389 | 2371 |
2390 if (Init.isInvalid()) { | 2372 if (Init.isInvalid()) { |
2391 SmallVector<tok::TokenKind, 2> StopTokens; | 2373 SmallVector<tok::TokenKind, 2> StopTokens; |
2392 StopTokens.push_back(tok::comma); | 2374 StopTokens.push_back(tok::comma); |
2393 if (D.getContext() == DeclaratorContext::ForContext || | 2375 if (D.getContext() == DeclaratorContext::ForInit || |
2394 D.getContext() == DeclaratorContext::InitStmtContext) | 2376 D.getContext() == DeclaratorContext::SelectionInit) |
2395 StopTokens.push_back(tok::r_paren); | 2377 StopTokens.push_back(tok::r_paren); |
2396 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch); | 2378 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch); |
2397 Actions.ActOnInitializerError(ThisDecl); | 2379 Actions.ActOnInitializerError(ThisDecl); |
2398 } else | 2380 } else |
2399 Actions.AddInitializerToDecl(ThisDecl, Init.get(), | 2381 Actions.AddInitializerToDecl(ThisDecl, Init.get(), |
2400 /*DirectInit=*/false); | 2382 /*DirectInit=*/false); |
2401 } | 2383 } |
2402 } else if (Tok.is(tok::l_paren)) { | 2384 break; |
2385 } | |
2386 case InitKind::CXXDirect: { | |
2403 // Parse C++ direct initializer: '(' expression-list ')' | 2387 // Parse C++ direct initializer: '(' expression-list ')' |
2404 BalancedDelimiterTracker T(*this, tok::l_paren); | 2388 BalancedDelimiterTracker T(*this, tok::l_paren); |
2405 T.consumeOpen(); | 2389 T.consumeOpen(); |
2406 | 2390 |
2407 ExprVector Exprs; | 2391 ExprVector Exprs; |
2451 T.getCloseLocation(), | 2435 T.getCloseLocation(), |
2452 Exprs); | 2436 Exprs); |
2453 Actions.AddInitializerToDecl(ThisDecl, Initializer.get(), | 2437 Actions.AddInitializerToDecl(ThisDecl, Initializer.get(), |
2454 /*DirectInit=*/true); | 2438 /*DirectInit=*/true); |
2455 } | 2439 } |
2456 } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) && | 2440 break; |
2457 (!CurParsedObjCImpl || !D.isFunctionDeclarator())) { | 2441 } |
2442 case InitKind::CXXBraced: { | |
2458 // Parse C++0x braced-init-list. | 2443 // Parse C++0x braced-init-list. |
2459 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); | 2444 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); |
2460 | 2445 |
2461 InitializerScopeRAII InitScope(*this, D, ThisDecl); | 2446 InitializerScopeRAII InitScope(*this, D, ThisDecl); |
2462 | 2447 |
2467 | 2452 |
2468 if (Init.isInvalid()) { | 2453 if (Init.isInvalid()) { |
2469 Actions.ActOnInitializerError(ThisDecl); | 2454 Actions.ActOnInitializerError(ThisDecl); |
2470 } else | 2455 } else |
2471 Actions.AddInitializerToDecl(ThisDecl, Init.get(), /*DirectInit=*/true); | 2456 Actions.AddInitializerToDecl(ThisDecl, Init.get(), /*DirectInit=*/true); |
2472 | 2457 break; |
2473 } else { | 2458 } |
2459 case InitKind::Uninitialized: { | |
2474 Actions.ActOnUninitializedDecl(ThisDecl); | 2460 Actions.ActOnUninitializedDecl(ThisDecl); |
2461 break; | |
2462 } | |
2475 } | 2463 } |
2476 | 2464 |
2477 Actions.FinalizeDeclaration(ThisDecl); | 2465 Actions.FinalizeDeclaration(ThisDecl); |
2478 | 2466 return OuterDecl ? OuterDecl : ThisDecl; |
2479 return ThisDecl; | |
2480 } | 2467 } |
2481 | 2468 |
2482 /// ParseSpecifierQualifierList | 2469 /// ParseSpecifierQualifierList |
2483 /// specifier-qualifier-list: | 2470 /// specifier-qualifier-list: |
2484 /// type-specifier specifier-qualifier-list[opt] | 2471 /// type-specifier specifier-qualifier-list[opt] |
2525 } | 2512 } |
2526 | 2513 |
2527 // Issue diagnostic and remove constexpr specifier if present. | 2514 // Issue diagnostic and remove constexpr specifier if present. |
2528 if (DS.hasConstexprSpecifier() && DSC != DeclSpecContext::DSC_condition) { | 2515 if (DS.hasConstexprSpecifier() && DSC != DeclSpecContext::DSC_condition) { |
2529 Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr) | 2516 Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr) |
2530 << DS.getConstexprSpecifier(); | 2517 << static_cast<int>(DS.getConstexprSpecifier()); |
2531 DS.ClearConstexprSpec(); | 2518 DS.ClearConstexprSpec(); |
2532 } | 2519 } |
2533 } | 2520 } |
2534 | 2521 |
2535 /// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the | 2522 /// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the |
2796 /// | 2783 /// |
2797 /// \param Context the declarator context, which is one of the | 2784 /// \param Context the declarator context, which is one of the |
2798 /// DeclaratorContext enumerator values. | 2785 /// DeclaratorContext enumerator values. |
2799 Parser::DeclSpecContext | 2786 Parser::DeclSpecContext |
2800 Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) { | 2787 Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) { |
2801 if (Context == DeclaratorContext::MemberContext) | 2788 if (Context == DeclaratorContext::Member) |
2802 return DeclSpecContext::DSC_class; | 2789 return DeclSpecContext::DSC_class; |
2803 if (Context == DeclaratorContext::FileContext) | 2790 if (Context == DeclaratorContext::File) |
2804 return DeclSpecContext::DSC_top_level; | 2791 return DeclSpecContext::DSC_top_level; |
2805 if (Context == DeclaratorContext::TemplateParamContext) | 2792 if (Context == DeclaratorContext::TemplateParam) |
2806 return DeclSpecContext::DSC_template_param; | 2793 return DeclSpecContext::DSC_template_param; |
2807 if (Context == DeclaratorContext::TemplateArgContext || | 2794 if (Context == DeclaratorContext::TemplateArg || |
2808 Context == DeclaratorContext::TemplateTypeArgContext) | 2795 Context == DeclaratorContext::TemplateTypeArg) |
2809 return DeclSpecContext::DSC_template_type_arg; | 2796 return DeclSpecContext::DSC_template_type_arg; |
2810 if (Context == DeclaratorContext::TrailingReturnContext || | 2797 if (Context == DeclaratorContext::TrailingReturn || |
2811 Context == DeclaratorContext::TrailingReturnVarContext) | 2798 Context == DeclaratorContext::TrailingReturnVar) |
2812 return DeclSpecContext::DSC_trailing; | 2799 return DeclSpecContext::DSC_trailing; |
2813 if (Context == DeclaratorContext::AliasDeclContext || | 2800 if (Context == DeclaratorContext::AliasDecl || |
2814 Context == DeclaratorContext::AliasTemplateContext) | 2801 Context == DeclaratorContext::AliasTemplate) |
2815 return DeclSpecContext::DSC_alias_declaration; | 2802 return DeclSpecContext::DSC_alias_declaration; |
2816 return DeclSpecContext::DSC_normal; | 2803 return DeclSpecContext::DSC_normal; |
2817 } | 2804 } |
2818 | 2805 |
2819 /// ParseAlignArgument - Parse the argument to an alignment-specifier. | 2806 /// ParseAlignArgument - Parse the argument to an alignment-specifier. |
2977 break; | 2964 break; |
2978 | 2965 |
2979 case Sema::NC_Unknown: | 2966 case Sema::NC_Unknown: |
2980 case Sema::NC_NonType: | 2967 case Sema::NC_NonType: |
2981 case Sema::NC_DependentNonType: | 2968 case Sema::NC_DependentNonType: |
2982 case Sema::NC_ContextIndependentExpr: | 2969 case Sema::NC_OverloadSet: |
2983 case Sema::NC_VarTemplate: | 2970 case Sema::NC_VarTemplate: |
2984 case Sema::NC_FunctionTemplate: | 2971 case Sema::NC_FunctionTemplate: |
2985 case Sema::NC_Concept: | 2972 case Sema::NC_Concept: |
2986 // Might be a redeclaration of a prior entity. | 2973 // Might be a redeclaration of a prior entity. |
2987 break; | 2974 break; |
3089 !DS.hasTypeSpecifier() && GetLookAheadToken(1).is(tok::less)) | 3076 !DS.hasTypeSpecifier() && GetLookAheadToken(1).is(tok::less)) |
3090 Tok.setKind(tok::identifier); | 3077 Tok.setKind(tok::identifier); |
3091 | 3078 |
3092 SourceLocation Loc = Tok.getLocation(); | 3079 SourceLocation Loc = Tok.getLocation(); |
3093 | 3080 |
3081 // Helper for image types in OpenCL. | |
3082 auto handleOpenCLImageKW = [&] (StringRef Ext, TypeSpecifierType ImageTypeSpec) { | |
3083 // Check if the image type is supported and otherwise turn the keyword into an identifier | |
3084 // because image types from extensions are not reserved identifiers. | |
3085 if (!StringRef(Ext).empty() && !getActions().getOpenCLOptions().isSupported(Ext, getLangOpts())) { | |
3086 Tok.getIdentifierInfo()->revertTokenIDToIdentifier(); | |
3087 Tok.setKind(tok::identifier); | |
3088 return false; | |
3089 } | |
3090 isInvalid = DS.SetTypeSpecType(ImageTypeSpec, Loc, PrevSpec, DiagID, Policy); | |
3091 return true; | |
3092 }; | |
3093 | |
3094 switch (Tok.getKind()) { | 3094 switch (Tok.getKind()) { |
3095 default: | 3095 default: |
3096 DoneWithDeclSpec: | 3096 DoneWithDeclSpec: |
3097 if (!AttrsLastTime) | 3097 if (!AttrsLastTime) |
3098 ProhibitAttributes(attrs); | 3098 ProhibitAttributes(attrs); |
3137 Scope::AtCatchScope)) == 0; | 3137 Scope::AtCatchScope)) == 0; |
3138 bool AllowNestedNameSpecifiers | 3138 bool AllowNestedNameSpecifiers |
3139 = DSContext == DeclSpecContext::DSC_top_level || | 3139 = DSContext == DeclSpecContext::DSC_top_level || |
3140 (DSContext == DeclSpecContext::DSC_class && DS.isFriendSpecified()); | 3140 (DSContext == DeclSpecContext::DSC_class && DS.isFriendSpecified()); |
3141 | 3141 |
3142 cutOffParsing(); | |
3142 Actions.CodeCompleteDeclSpec(getCurScope(), DS, | 3143 Actions.CodeCompleteDeclSpec(getCurScope(), DS, |
3143 AllowNonIdentifiers, | 3144 AllowNonIdentifiers, |
3144 AllowNestedNameSpecifiers); | 3145 AllowNestedNameSpecifiers); |
3145 return cutOffParsing(); | 3146 return; |
3146 } | 3147 } |
3147 | 3148 |
3148 if (getCurScope()->getFnParent() || getCurScope()->getBlockParent()) | 3149 if (getCurScope()->getFnParent() || getCurScope()->getBlockParent()) |
3149 CCC = Sema::PCC_LocalDeclarationSpecifiers; | 3150 CCC = Sema::PCC_LocalDeclarationSpecifiers; |
3150 else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) | 3151 else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) |
3153 else if (DSContext == DeclSpecContext::DSC_class) | 3154 else if (DSContext == DeclSpecContext::DSC_class) |
3154 CCC = Sema::PCC_Class; | 3155 CCC = Sema::PCC_Class; |
3155 else if (CurParsedObjCImpl) | 3156 else if (CurParsedObjCImpl) |
3156 CCC = Sema::PCC_ObjCImplementation; | 3157 CCC = Sema::PCC_ObjCImplementation; |
3157 | 3158 |
3159 cutOffParsing(); | |
3158 Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); | 3160 Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); |
3159 return cutOffParsing(); | 3161 return; |
3160 } | 3162 } |
3161 | 3163 |
3162 case tok::coloncolon: // ::foo::bar | 3164 case tok::coloncolon: // ::foo::bar |
3163 // C++ scope specifier. Annotate and loop, or bail out on error. | 3165 // C++ scope specifier. Annotate and loop, or bail out on error. |
3164 if (TryAnnotateCXXScopeToken(EnteringContext)) { | 3166 if (TryAnnotateCXXScopeToken(EnteringContext)) { |
3550 CXXScopeSpec SS; | 3552 CXXScopeSpec SS; |
3551 AnnotateTemplateIdTokenAsType(SS); | 3553 AnnotateTemplateIdTokenAsType(SS); |
3552 continue; | 3554 continue; |
3553 } | 3555 } |
3554 | 3556 |
3555 // GNU attributes support. | 3557 // Attributes support. |
3556 case tok::kw___attribute: | 3558 case tok::kw___attribute: |
3557 ParseGNUAttributes(DS.getAttributes(), nullptr, LateAttrs); | |
3558 continue; | |
3559 | |
3560 // Microsoft declspec support. | |
3561 case tok::kw___declspec: | 3559 case tok::kw___declspec: |
3562 ParseMicrosoftDeclSpecs(DS.getAttributes()); | 3560 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.getAttributes(), nullptr, |
3561 LateAttrs); | |
3563 continue; | 3562 continue; |
3564 | 3563 |
3565 // Microsoft single token adornments. | 3564 // Microsoft single token adornments. |
3566 case tok::kw___forceinline: { | 3565 case tok::kw___forceinline: { |
3567 isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID); | 3566 isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID); |
3602 continue; | 3601 continue; |
3603 | 3602 |
3604 // Nullability type specifiers. | 3603 // Nullability type specifiers. |
3605 case tok::kw__Nonnull: | 3604 case tok::kw__Nonnull: |
3606 case tok::kw__Nullable: | 3605 case tok::kw__Nullable: |
3606 case tok::kw__Nullable_result: | |
3607 case tok::kw__Null_unspecified: | 3607 case tok::kw__Null_unspecified: |
3608 ParseNullabilityTypeSpecifiers(DS.getAttributes()); | 3608 ParseNullabilityTypeSpecifiers(DS.getAttributes()); |
3609 continue; | 3609 continue; |
3610 | 3610 |
3611 // Objective-C 'kindof' types. | 3611 // Objective-C 'kindof' types. |
3694 isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID); | 3694 isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID); |
3695 break; | 3695 break; |
3696 case tok::kw_virtual: | 3696 case tok::kw_virtual: |
3697 // C++ for OpenCL does not allow virtual function qualifier, to avoid | 3697 // C++ for OpenCL does not allow virtual function qualifier, to avoid |
3698 // function pointers restricted in OpenCL v2.0 s6.9.a. | 3698 // function pointers restricted in OpenCL v2.0 s6.9.a. |
3699 if (getLangOpts().OpenCLCPlusPlus) { | 3699 if (getLangOpts().OpenCLCPlusPlus && |
3700 !getActions().getOpenCLOptions().isAvailableOption( | |
3701 "__cl_clang_function_pointers", getLangOpts())) { | |
3700 DiagID = diag::err_openclcxx_virtual_function; | 3702 DiagID = diag::err_openclcxx_virtual_function; |
3701 PrevSpec = Tok.getIdentifierInfo()->getNameStart(); | 3703 PrevSpec = Tok.getIdentifierInfo()->getNameStart(); |
3702 isInvalid = true; | 3704 isInvalid = true; |
3703 } | 3705 } else { |
3704 else { | |
3705 isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID); | 3706 isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID); |
3706 } | 3707 } |
3707 break; | 3708 break; |
3708 case tok::kw_explicit: { | 3709 case tok::kw_explicit: { |
3709 SourceLocation ExplicitLoc = Loc; | 3710 SourceLocation ExplicitLoc = Loc; |
3766 isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID); | 3767 isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID); |
3767 break; | 3768 break; |
3768 | 3769 |
3769 // constexpr, consteval, constinit specifiers | 3770 // constexpr, consteval, constinit specifiers |
3770 case tok::kw_constexpr: | 3771 case tok::kw_constexpr: |
3771 isInvalid = DS.SetConstexprSpec(CSK_constexpr, Loc, PrevSpec, DiagID); | 3772 isInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Constexpr, Loc, |
3773 PrevSpec, DiagID); | |
3772 break; | 3774 break; |
3773 case tok::kw_consteval: | 3775 case tok::kw_consteval: |
3774 isInvalid = DS.SetConstexprSpec(CSK_consteval, Loc, PrevSpec, DiagID); | 3776 isInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Consteval, Loc, |
3777 PrevSpec, DiagID); | |
3775 break; | 3778 break; |
3776 case tok::kw_constinit: | 3779 case tok::kw_constinit: |
3777 isInvalid = DS.SetConstexprSpec(CSK_constinit, Loc, PrevSpec, DiagID); | 3780 isInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Constinit, Loc, |
3781 PrevSpec, DiagID); | |
3778 break; | 3782 break; |
3779 | 3783 |
3780 // type-specifier | 3784 // type-specifier |
3781 case tok::kw_short: | 3785 case tok::kw_short: |
3782 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, | 3786 isInvalid = DS.SetTypeSpecWidth(TypeSpecifierWidth::Short, Loc, PrevSpec, |
3783 DiagID, Policy); | 3787 DiagID, Policy); |
3784 break; | 3788 break; |
3785 case tok::kw_long: | 3789 case tok::kw_long: |
3786 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long) | 3790 if (DS.getTypeSpecWidth() != TypeSpecifierWidth::Long) |
3787 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, | 3791 isInvalid = DS.SetTypeSpecWidth(TypeSpecifierWidth::Long, Loc, PrevSpec, |
3788 DiagID, Policy); | 3792 DiagID, Policy); |
3789 else | 3793 else |
3790 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, | 3794 isInvalid = DS.SetTypeSpecWidth(TypeSpecifierWidth::LongLong, Loc, |
3791 DiagID, Policy); | 3795 PrevSpec, DiagID, Policy); |
3792 break; | 3796 break; |
3793 case tok::kw___int64: | 3797 case tok::kw___int64: |
3794 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, | 3798 isInvalid = DS.SetTypeSpecWidth(TypeSpecifierWidth::LongLong, Loc, |
3795 DiagID, Policy); | 3799 PrevSpec, DiagID, Policy); |
3796 break; | 3800 break; |
3797 case tok::kw_signed: | 3801 case tok::kw_signed: |
3798 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, | 3802 isInvalid = |
3799 DiagID); | 3803 DS.SetTypeSpecSign(TypeSpecifierSign::Signed, Loc, PrevSpec, DiagID); |
3800 break; | 3804 break; |
3801 case tok::kw_unsigned: | 3805 case tok::kw_unsigned: |
3802 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, | 3806 isInvalid = DS.SetTypeSpecSign(TypeSpecifierSign::Unsigned, Loc, PrevSpec, |
3803 DiagID); | 3807 DiagID); |
3804 break; | 3808 break; |
3805 case tok::kw__Complex: | 3809 case tok::kw__Complex: |
3806 if (!getLangOpts().C99) | 3810 if (!getLangOpts().C99) |
3807 Diag(Tok, diag::ext_c99_feature) << Tok.getName(); | 3811 Diag(Tok, diag::ext_c99_feature) << Tok.getName(); |
3838 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, | 3842 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, |
3839 DiagID, Policy); | 3843 DiagID, Policy); |
3840 break; | 3844 break; |
3841 case tok::kw_half: | 3845 case tok::kw_half: |
3842 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, | 3846 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, |
3847 DiagID, Policy); | |
3848 break; | |
3849 case tok::kw___bf16: | |
3850 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_BFloat16, Loc, PrevSpec, | |
3843 DiagID, Policy); | 3851 DiagID, Policy); |
3844 break; | 3852 break; |
3845 case tok::kw_float: | 3853 case tok::kw_float: |
3846 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, | 3854 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, |
3847 DiagID, Policy); | 3855 DiagID, Policy); |
3937 isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID, Policy); | 3945 isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID, Policy); |
3938 break; | 3946 break; |
3939 case tok::kw_pipe: | 3947 case tok::kw_pipe: |
3940 if (!getLangOpts().OpenCL || (getLangOpts().OpenCLVersion < 200 && | 3948 if (!getLangOpts().OpenCL || (getLangOpts().OpenCLVersion < 200 && |
3941 !getLangOpts().OpenCLCPlusPlus)) { | 3949 !getLangOpts().OpenCLCPlusPlus)) { |
3942 // OpenCL 2.0 defined this keyword. OpenCL 1.2 and earlier should | 3950 // OpenCL 2.0 and later define this keyword. OpenCL 1.2 and earlier |
3943 // support the "pipe" word as identifier. | 3951 // should support the "pipe" word as identifier. |
3944 Tok.getIdentifierInfo()->revertTokenIDToIdentifier(); | 3952 Tok.getIdentifierInfo()->revertTokenIDToIdentifier(); |
3953 Tok.setKind(tok::identifier); | |
3945 goto DoneWithDeclSpec; | 3954 goto DoneWithDeclSpec; |
3946 } | 3955 } |
3947 isInvalid = DS.SetTypePipe(true, Loc, PrevSpec, DiagID, Policy); | 3956 isInvalid = DS.SetTypePipe(true, Loc, PrevSpec, DiagID, Policy); |
3948 break; | 3957 break; |
3949 #define GENERIC_IMAGE_TYPE(ImgType, Id) \ | 3958 // We only need to enumerate each image type once. |
3950 case tok::kw_##ImgType##_t: \ | 3959 #define IMAGE_READ_WRITE_TYPE(Type, Id, Ext) |
3951 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, \ | 3960 #define IMAGE_WRITE_TYPE(Type, Id, Ext) |
3952 DiagID, Policy); \ | 3961 #define IMAGE_READ_TYPE(ImgType, Id, Ext) \ |
3953 break; | 3962 case tok::kw_##ImgType##_t: \ |
3963 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \ | |
3964 goto DoneWithDeclSpec; \ | |
3965 break; | |
3954 #include "clang/Basic/OpenCLImageTypes.def" | 3966 #include "clang/Basic/OpenCLImageTypes.def" |
3955 case tok::kw___unknown_anytype: | 3967 case tok::kw___unknown_anytype: |
3956 isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, | 3968 isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, |
3957 PrevSpec, DiagID, Policy); | 3969 PrevSpec, DiagID, Policy); |
3958 break; | 3970 break; |
4058 | 4070 |
4059 // OpenCL address space qualifiers: | 4071 // OpenCL address space qualifiers: |
4060 case tok::kw___generic: | 4072 case tok::kw___generic: |
4061 // generic address space is introduced only in OpenCL v2.0 | 4073 // generic address space is introduced only in OpenCL v2.0 |
4062 // see OpenCL C Spec v2.0 s6.5.5 | 4074 // see OpenCL C Spec v2.0 s6.5.5 |
4063 if (Actions.getLangOpts().OpenCLVersion < 200 && | 4075 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) { |
4064 !Actions.getLangOpts().OpenCLCPlusPlus) { | |
4065 DiagID = diag::err_opencl_unknown_type_specifier; | 4076 DiagID = diag::err_opencl_unknown_type_specifier; |
4066 PrevSpec = Tok.getIdentifierInfo()->getNameStart(); | 4077 PrevSpec = Tok.getIdentifierInfo()->getNameStart(); |
4067 isInvalid = true; | 4078 isInvalid = true; |
4068 break; | 4079 break; |
4069 } | 4080 } |
4197 while (1) { | 4208 while (1) { |
4198 ParsingFieldDeclarator DeclaratorInfo(*this, DS); | 4209 ParsingFieldDeclarator DeclaratorInfo(*this, DS); |
4199 DeclaratorInfo.D.setCommaLoc(CommaLoc); | 4210 DeclaratorInfo.D.setCommaLoc(CommaLoc); |
4200 | 4211 |
4201 // Attributes are only allowed here on successive declarators. | 4212 // Attributes are only allowed here on successive declarators. |
4202 if (!FirstDeclarator) | 4213 if (!FirstDeclarator) { |
4214 // However, this does not apply for [[]] attributes (which could show up | |
4215 // before or after the __attribute__ attributes). | |
4216 DiagnoseAndSkipCXX11Attributes(); | |
4203 MaybeParseGNUAttributes(DeclaratorInfo.D); | 4217 MaybeParseGNUAttributes(DeclaratorInfo.D); |
4218 DiagnoseAndSkipCXX11Attributes(); | |
4219 } | |
4204 | 4220 |
4205 /// struct-declarator: declarator | 4221 /// struct-declarator: declarator |
4206 /// struct-declarator: declarator[opt] ':' constant-expression | 4222 /// struct-declarator: declarator[opt] ':' constant-expression |
4207 if (Tok.isNot(tok::colon)) { | 4223 if (Tok.isNot(tok::colon)) { |
4208 // Don't parse FOO:BAR as if it were a typo for FOO::BAR. | 4224 // Don't parse FOO:BAR as if it were a typo for FOO::BAR. |
4236 | 4252 |
4237 /// ParseStructUnionBody | 4253 /// ParseStructUnionBody |
4238 /// struct-contents: | 4254 /// struct-contents: |
4239 /// struct-declaration-list | 4255 /// struct-declaration-list |
4240 /// [EXT] empty | 4256 /// [EXT] empty |
4241 /// [GNU] "struct-declaration-list" without terminatoring ';' | 4257 /// [GNU] "struct-declaration-list" without terminating ';' |
4242 /// struct-declaration-list: | 4258 /// struct-declaration-list: |
4243 /// struct-declaration | 4259 /// struct-declaration |
4244 /// struct-declaration-list struct-declaration | 4260 /// struct-declaration-list struct-declaration |
4245 /// [OBC] '@' 'defs' '(' class-name ')' | 4261 /// [OBC] '@' 'defs' '(' class-name ')' |
4246 /// | 4262 /// |
4247 void Parser::ParseStructUnionBody(SourceLocation RecordLoc, | 4263 void Parser::ParseStructUnionBody(SourceLocation RecordLoc, |
4248 DeclSpec::TST TagType, Decl *TagDecl) { | 4264 DeclSpec::TST TagType, RecordDecl *TagDecl) { |
4249 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc, | 4265 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc, |
4250 "parsing struct/union body"); | 4266 "parsing struct/union body"); |
4251 assert(!getLangOpts().CPlusPlus && "C++ declarations not supported"); | 4267 assert(!getLangOpts().CPlusPlus && "C++ declarations not supported"); |
4252 | 4268 |
4253 BalancedDelimiterTracker T(*this, tok::l_brace); | 4269 BalancedDelimiterTracker T(*this, tok::l_brace); |
4254 if (T.consumeOpen()) | 4270 if (T.consumeOpen()) |
4255 return; | 4271 return; |
4256 | 4272 |
4257 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope); | 4273 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope); |
4258 Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); | 4274 Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); |
4259 | |
4260 SmallVector<Decl *, 32> FieldDecls; | |
4261 | 4275 |
4262 // While we still have something to read, read the declarations in the struct. | 4276 // While we still have something to read, read the declarations in the struct. |
4263 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && | 4277 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && |
4264 Tok.isNot(tok::eof)) { | 4278 Tok.isNot(tok::eof)) { |
4265 // Each iteration of this loop reads one struct-declaration. | 4279 // Each iteration of this loop reads one struct-declaration. |
4269 ConsumeExtraSemi(InsideStruct, TagType); | 4283 ConsumeExtraSemi(InsideStruct, TagType); |
4270 continue; | 4284 continue; |
4271 } | 4285 } |
4272 | 4286 |
4273 // Parse _Static_assert declaration. | 4287 // Parse _Static_assert declaration. |
4274 if (Tok.is(tok::kw__Static_assert)) { | 4288 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) { |
4275 SourceLocation DeclEnd; | 4289 SourceLocation DeclEnd; |
4276 ParseStaticAssertDeclaration(DeclEnd); | 4290 ParseStaticAssertDeclaration(DeclEnd); |
4277 continue; | 4291 continue; |
4278 } | 4292 } |
4279 | 4293 |
4308 // Install the declarator into the current TagDecl. | 4322 // Install the declarator into the current TagDecl. |
4309 Decl *Field = | 4323 Decl *Field = |
4310 Actions.ActOnField(getCurScope(), TagDecl, | 4324 Actions.ActOnField(getCurScope(), TagDecl, |
4311 FD.D.getDeclSpec().getSourceRange().getBegin(), | 4325 FD.D.getDeclSpec().getSourceRange().getBegin(), |
4312 FD.D, FD.BitfieldSize); | 4326 FD.D, FD.BitfieldSize); |
4313 FieldDecls.push_back(Field); | |
4314 FD.complete(Field); | 4327 FD.complete(Field); |
4315 }; | 4328 }; |
4316 | 4329 |
4317 // Parse all the comma separated declarators. | 4330 // Parse all the comma separated declarators. |
4318 ParsingDeclSpec DS(*this); | 4331 ParsingDeclSpec DS(*this); |
4332 continue; | 4345 continue; |
4333 } | 4346 } |
4334 SmallVector<Decl *, 16> Fields; | 4347 SmallVector<Decl *, 16> Fields; |
4335 Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), | 4348 Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), |
4336 Tok.getIdentifierInfo(), Fields); | 4349 Tok.getIdentifierInfo(), Fields); |
4337 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end()); | |
4338 ConsumeToken(); | 4350 ConsumeToken(); |
4339 ExpectAndConsume(tok::r_paren); | 4351 ExpectAndConsume(tok::r_paren); |
4340 } | 4352 } |
4341 | 4353 |
4342 if (TryConsumeToken(tok::semi)) | 4354 if (TryConsumeToken(tok::semi)) |
4357 T.consumeClose(); | 4369 T.consumeClose(); |
4358 | 4370 |
4359 ParsedAttributes attrs(AttrFactory); | 4371 ParsedAttributes attrs(AttrFactory); |
4360 // If attributes exist after struct contents, parse them. | 4372 // If attributes exist after struct contents, parse them. |
4361 MaybeParseGNUAttributes(attrs); | 4373 MaybeParseGNUAttributes(attrs); |
4374 | |
4375 SmallVector<Decl *, 32> FieldDecls(TagDecl->field_begin(), | |
4376 TagDecl->field_end()); | |
4362 | 4377 |
4363 Actions.ActOnFields(getCurScope(), RecordLoc, TagDecl, FieldDecls, | 4378 Actions.ActOnFields(getCurScope(), RecordLoc, TagDecl, FieldDecls, |
4364 T.getOpenLocation(), T.getCloseLocation(), attrs); | 4379 T.getOpenLocation(), T.getCloseLocation(), attrs); |
4365 StructScope.Exit(); | 4380 StructScope.Exit(); |
4366 Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange()); | 4381 Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange()); |
4400 const ParsedTemplateInfo &TemplateInfo, | 4415 const ParsedTemplateInfo &TemplateInfo, |
4401 AccessSpecifier AS, DeclSpecContext DSC) { | 4416 AccessSpecifier AS, DeclSpecContext DSC) { |
4402 // Parse the tag portion of this. | 4417 // Parse the tag portion of this. |
4403 if (Tok.is(tok::code_completion)) { | 4418 if (Tok.is(tok::code_completion)) { |
4404 // Code completion for an enum name. | 4419 // Code completion for an enum name. |
4420 cutOffParsing(); | |
4405 Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum); | 4421 Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum); |
4406 return cutOffParsing(); | 4422 return; |
4407 } | 4423 } |
4408 | 4424 |
4409 // If attributes exist after tag, parse them. | 4425 // If attributes exist after tag, parse them. |
4410 ParsedAttributesWithRange attrs(AttrFactory); | 4426 ParsedAttributesWithRange attrs(AttrFactory); |
4411 MaybeParseGNUAttributes(attrs); | 4427 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs); |
4412 MaybeParseCXX11Attributes(attrs); | |
4413 MaybeParseMicrosoftDeclSpecs(attrs); | |
4414 | 4428 |
4415 SourceLocation ScopedEnumKWLoc; | 4429 SourceLocation ScopedEnumKWLoc; |
4416 bool IsScopedUsingClassTag = false; | 4430 bool IsScopedUsingClassTag = false; |
4417 | 4431 |
4418 // In C++11, recognize 'enum class' and 'enum struct'. | 4432 // In C++11, recognize 'enum class' and 'enum struct'. |
4425 // Attributes are not allowed between these keywords. Diagnose, | 4439 // Attributes are not allowed between these keywords. Diagnose, |
4426 // but then just treat them like they appeared in the right place. | 4440 // but then just treat them like they appeared in the right place. |
4427 ProhibitAttributes(attrs); | 4441 ProhibitAttributes(attrs); |
4428 | 4442 |
4429 // They are allowed afterwards, though. | 4443 // They are allowed afterwards, though. |
4430 MaybeParseGNUAttributes(attrs); | 4444 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs); |
4431 MaybeParseCXX11Attributes(attrs); | |
4432 MaybeParseMicrosoftDeclSpecs(attrs); | |
4433 } | 4445 } |
4434 | 4446 |
4435 // C++11 [temp.explicit]p12: | 4447 // C++11 [temp.explicit]p12: |
4436 // The usual access controls do not apply to names used to specify | 4448 // The usual access controls do not apply to names used to specify |
4437 // explicit instantiations. | 4449 // explicit instantiations. |
4552 // because under -fms-extensions, | 4564 // because under -fms-extensions, |
4553 // enum E : int *p; | 4565 // enum E : int *p; |
4554 // declares 'enum E : int; E *p;' not 'enum E : int*; E p;'. | 4566 // declares 'enum E : int; E *p;' not 'enum E : int*; E p;'. |
4555 DeclSpec DS(AttrFactory); | 4567 DeclSpec DS(AttrFactory); |
4556 ParseSpecifierQualifierList(DS, AS, DeclSpecContext::DSC_type_specifier); | 4568 ParseSpecifierQualifierList(DS, AS, DeclSpecContext::DSC_type_specifier); |
4557 Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); | 4569 Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); |
4558 BaseType = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); | 4570 BaseType = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); |
4559 | 4571 |
4560 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd()); | 4572 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd()); |
4561 | 4573 |
4562 if (!getLangOpts().ObjC) { | 4574 if (!getLangOpts().ObjC) { |
4669 // | 4681 // |
4670 // MSVC and (for now at least) Objective-C permit a full enum-specifier | 4682 // MSVC and (for now at least) Objective-C permit a full enum-specifier |
4671 // or opaque-enum-declaration anywhere. | 4683 // or opaque-enum-declaration anywhere. |
4672 if (IsElaboratedTypeSpecifier && !getLangOpts().MicrosoftExt && | 4684 if (IsElaboratedTypeSpecifier && !getLangOpts().MicrosoftExt && |
4673 !getLangOpts().ObjC) { | 4685 !getLangOpts().ObjC) { |
4674 ProhibitAttributes(attrs); | 4686 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, |
4687 /*DiagnoseEmptyAttrs=*/true); | |
4675 if (BaseType.isUsable()) | 4688 if (BaseType.isUsable()) |
4676 Diag(BaseRange.getBegin(), diag::ext_enum_base_in_type_specifier) | 4689 Diag(BaseRange.getBegin(), diag::ext_enum_base_in_type_specifier) |
4677 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange; | 4690 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange; |
4678 else if (ScopedEnumKWLoc.isValid()) | 4691 else if (ScopedEnumKWLoc.isValid()) |
4679 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class) | 4692 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class) |
4813 SourceLocation IdentLoc = ConsumeToken(); | 4826 SourceLocation IdentLoc = ConsumeToken(); |
4814 | 4827 |
4815 // If attributes exist after the enumerator, parse them. | 4828 // If attributes exist after the enumerator, parse them. |
4816 ParsedAttributesWithRange attrs(AttrFactory); | 4829 ParsedAttributesWithRange attrs(AttrFactory); |
4817 MaybeParseGNUAttributes(attrs); | 4830 MaybeParseGNUAttributes(attrs); |
4818 ProhibitAttributes(attrs); // GNU-style attributes are prohibited. | |
4819 if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) { | 4831 if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) { |
4820 if (getLangOpts().CPlusPlus) | 4832 if (getLangOpts().CPlusPlus) |
4821 Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 | 4833 Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 |
4822 ? diag::warn_cxx14_compat_ns_enum_attribute | 4834 ? diag::warn_cxx14_compat_ns_enum_attribute |
4823 : diag::ext_ns_enum_attribute) | 4835 : diag::ext_ns_enum_attribute) |
4940 case tok::kw_char8_t: | 4952 case tok::kw_char8_t: |
4941 case tok::kw_char16_t: | 4953 case tok::kw_char16_t: |
4942 case tok::kw_char32_t: | 4954 case tok::kw_char32_t: |
4943 case tok::kw_int: | 4955 case tok::kw_int: |
4944 case tok::kw__ExtInt: | 4956 case tok::kw__ExtInt: |
4957 case tok::kw___bf16: | |
4945 case tok::kw_half: | 4958 case tok::kw_half: |
4946 case tok::kw_float: | 4959 case tok::kw_float: |
4947 case tok::kw_double: | 4960 case tok::kw_double: |
4948 case tok::kw__Accum: | 4961 case tok::kw__Accum: |
4949 case tok::kw__Fract: | 4962 case tok::kw__Fract: |
5021 case tok::kw_char16_t: | 5034 case tok::kw_char16_t: |
5022 case tok::kw_char32_t: | 5035 case tok::kw_char32_t: |
5023 case tok::kw_int: | 5036 case tok::kw_int: |
5024 case tok::kw__ExtInt: | 5037 case tok::kw__ExtInt: |
5025 case tok::kw_half: | 5038 case tok::kw_half: |
5039 case tok::kw___bf16: | |
5026 case tok::kw_float: | 5040 case tok::kw_float: |
5027 case tok::kw_double: | 5041 case tok::kw_double: |
5028 case tok::kw__Accum: | 5042 case tok::kw__Accum: |
5029 case tok::kw__Fract: | 5043 case tok::kw__Fract: |
5030 case tok::kw__Float16: | 5044 case tok::kw__Float16: |
5075 case tok::kw___pascal: | 5089 case tok::kw___pascal: |
5076 case tok::kw___unaligned: | 5090 case tok::kw___unaligned: |
5077 | 5091 |
5078 case tok::kw__Nonnull: | 5092 case tok::kw__Nonnull: |
5079 case tok::kw__Nullable: | 5093 case tok::kw__Nullable: |
5094 case tok::kw__Nullable_result: | |
5080 case tok::kw__Null_unspecified: | 5095 case tok::kw__Null_unspecified: |
5081 | 5096 |
5082 case tok::kw___kindof: | 5097 case tok::kw___kindof: |
5083 | 5098 |
5084 case tok::kw___private: | 5099 case tok::kw___private: |
5108 bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { | 5123 bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { |
5109 switch (Tok.getKind()) { | 5124 switch (Tok.getKind()) { |
5110 default: return false; | 5125 default: return false; |
5111 | 5126 |
5112 case tok::kw_pipe: | 5127 case tok::kw_pipe: |
5113 return (getLangOpts().OpenCL && getLangOpts().OpenCLVersion >= 200) || | 5128 return getLangOpts().OpenCLPipe; |
5114 getLangOpts().OpenCLCPlusPlus; | |
5115 | 5129 |
5116 case tok::identifier: // foo::bar | 5130 case tok::identifier: // foo::bar |
5117 // Unfortunate hack to support "Class.factoryMethod" notation. | 5131 // Unfortunate hack to support "Class.factoryMethod" notation. |
5118 if (getLangOpts().ObjC && NextToken().is(tok::period)) | 5132 if (getLangOpts().ObjC && NextToken().is(tok::period)) |
5119 return false; | 5133 return false; |
5188 case tok::kw_char32_t: | 5202 case tok::kw_char32_t: |
5189 | 5203 |
5190 case tok::kw_int: | 5204 case tok::kw_int: |
5191 case tok::kw__ExtInt: | 5205 case tok::kw__ExtInt: |
5192 case tok::kw_half: | 5206 case tok::kw_half: |
5207 case tok::kw___bf16: | |
5193 case tok::kw_float: | 5208 case tok::kw_float: |
5194 case tok::kw_double: | 5209 case tok::kw_double: |
5195 case tok::kw__Accum: | 5210 case tok::kw__Accum: |
5196 case tok::kw__Fract: | 5211 case tok::kw__Fract: |
5197 case tok::kw__Float16: | 5212 case tok::kw__Float16: |
5228 | 5243 |
5229 // friend keyword. | 5244 // friend keyword. |
5230 case tok::kw_friend: | 5245 case tok::kw_friend: |
5231 | 5246 |
5232 // static_assert-declaration | 5247 // static_assert-declaration |
5248 case tok::kw_static_assert: | |
5233 case tok::kw__Static_assert: | 5249 case tok::kw__Static_assert: |
5234 | 5250 |
5235 // GNU typeof support. | 5251 // GNU typeof support. |
5236 case tok::kw_typeof: | 5252 case tok::kw_typeof: |
5237 | 5253 |
5301 case tok::kw___pascal: | 5317 case tok::kw___pascal: |
5302 case tok::kw___unaligned: | 5318 case tok::kw___unaligned: |
5303 | 5319 |
5304 case tok::kw__Nonnull: | 5320 case tok::kw__Nonnull: |
5305 case tok::kw__Nullable: | 5321 case tok::kw__Nullable: |
5322 case tok::kw__Nullable_result: | |
5306 case tok::kw__Null_unspecified: | 5323 case tok::kw__Null_unspecified: |
5307 | 5324 |
5308 case tok::kw___kindof: | 5325 case tok::kw___kindof: |
5309 | 5326 |
5310 case tok::kw___private: | 5327 case tok::kw___private: |
5495 unsigned DiagID = 0; | 5512 unsigned DiagID = 0; |
5496 SourceLocation Loc = Tok.getLocation(); | 5513 SourceLocation Loc = Tok.getLocation(); |
5497 | 5514 |
5498 switch (Tok.getKind()) { | 5515 switch (Tok.getKind()) { |
5499 case tok::code_completion: | 5516 case tok::code_completion: |
5517 cutOffParsing(); | |
5500 if (CodeCompletionHandler) | 5518 if (CodeCompletionHandler) |
5501 (*CodeCompletionHandler)(); | 5519 (*CodeCompletionHandler)(); |
5502 else | 5520 else |
5503 Actions.CodeCompleteTypeQualifiers(DS); | 5521 Actions.CodeCompleteTypeQualifiers(DS); |
5504 return cutOffParsing(); | 5522 return; |
5505 | 5523 |
5506 case tok::kw_const: | 5524 case tok::kw_const: |
5507 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID, | 5525 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID, |
5508 getLangOpts()); | 5526 getLangOpts()); |
5509 break; | 5527 break; |
5576 goto DoneWithTypeQuals; | 5594 goto DoneWithTypeQuals; |
5577 | 5595 |
5578 // Nullability type specifiers. | 5596 // Nullability type specifiers. |
5579 case tok::kw__Nonnull: | 5597 case tok::kw__Nonnull: |
5580 case tok::kw__Nullable: | 5598 case tok::kw__Nullable: |
5599 case tok::kw__Nullable_result: | |
5581 case tok::kw__Null_unspecified: | 5600 case tok::kw__Null_unspecified: |
5582 ParseNullabilityTypeSpecifiers(DS.getAttributes()); | 5601 ParseNullabilityTypeSpecifiers(DS.getAttributes()); |
5583 continue; | 5602 continue; |
5584 | 5603 |
5585 // Objective-C 'kindof' types. | 5604 // Objective-C 'kindof' types. |
5633 static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, | 5652 static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, |
5634 DeclaratorContext TheContext) { | 5653 DeclaratorContext TheContext) { |
5635 if (Kind == tok::star || Kind == tok::caret) | 5654 if (Kind == tok::star || Kind == tok::caret) |
5636 return true; | 5655 return true; |
5637 | 5656 |
5638 if (Kind == tok::kw_pipe && | 5657 if (Kind == tok::kw_pipe && Lang.OpenCLPipe) |
5639 ((Lang.OpenCL && Lang.OpenCLVersion >= 200) || Lang.OpenCLCPlusPlus)) | |
5640 return true; | 5658 return true; |
5641 | 5659 |
5642 if (!Lang.CPlusPlus) | 5660 if (!Lang.CPlusPlus) |
5643 return false; | 5661 return false; |
5644 | 5662 |
5649 // But we must not parse them in conversion-type-ids and new-type-ids, since | 5667 // But we must not parse them in conversion-type-ids and new-type-ids, since |
5650 // those can be legitimately followed by a && operator. | 5668 // those can be legitimately followed by a && operator. |
5651 // (The same thing can in theory happen after a trailing-return-type, but | 5669 // (The same thing can in theory happen after a trailing-return-type, but |
5652 // since those are a C++11 feature, there is no rejects-valid issue there.) | 5670 // since those are a C++11 feature, there is no rejects-valid issue there.) |
5653 if (Kind == tok::ampamp) | 5671 if (Kind == tok::ampamp) |
5654 return Lang.CPlusPlus11 || | 5672 return Lang.CPlusPlus11 || (TheContext != DeclaratorContext::ConversionId && |
5655 (TheContext != DeclaratorContext::ConversionIdContext && | 5673 TheContext != DeclaratorContext::CXXNew); |
5656 TheContext != DeclaratorContext::CXXNewContext); | |
5657 | 5674 |
5658 return false; | 5675 return false; |
5659 } | 5676 } |
5660 | 5677 |
5661 // Indicates whether the given declarator is a pipe declarator. | 5678 // Indicates whether the given declarator is a pipe declarator. |
5705 if (getLangOpts().CPlusPlus && | 5722 if (getLangOpts().CPlusPlus && |
5706 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) || | 5723 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) || |
5707 (Tok.is(tok::identifier) && | 5724 (Tok.is(tok::identifier) && |
5708 (NextToken().is(tok::coloncolon) || NextToken().is(tok::less))) || | 5725 (NextToken().is(tok::coloncolon) || NextToken().is(tok::less))) || |
5709 Tok.is(tok::annot_cxxscope))) { | 5726 Tok.is(tok::annot_cxxscope))) { |
5710 bool EnteringContext = | 5727 bool EnteringContext = D.getContext() == DeclaratorContext::File || |
5711 D.getContext() == DeclaratorContext::FileContext || | 5728 D.getContext() == DeclaratorContext::Member; |
5712 D.getContext() == DeclaratorContext::MemberContext; | |
5713 CXXScopeSpec SS; | 5729 CXXScopeSpec SS; |
5714 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, | 5730 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, |
5715 /*ObjectHadErrors=*/false, EnteringContext); | 5731 /*ObjectHadErrors=*/false, EnteringContext); |
5716 | 5732 |
5717 if (SS.isNotEmpty()) { | 5733 if (SS.isNotEmpty()) { |
5725 if (DirectDeclParser) | 5741 if (DirectDeclParser) |
5726 (this->*DirectDeclParser)(D); | 5742 (this->*DirectDeclParser)(D); |
5727 return; | 5743 return; |
5728 } | 5744 } |
5729 | 5745 |
5746 if (SS.isValid()) { | |
5747 checkCompoundToken(SS.getEndLoc(), tok::coloncolon, | |
5748 CompoundToken::MemberPtr); | |
5749 } | |
5750 | |
5730 SourceLocation StarLoc = ConsumeToken(); | 5751 SourceLocation StarLoc = ConsumeToken(); |
5731 D.SetRangeEnd(StarLoc); | 5752 D.SetRangeEnd(StarLoc); |
5732 DeclSpec DS(AttrFactory); | 5753 DeclSpec DS(AttrFactory); |
5733 ParseTypeQualifierListOpt(DS); | 5754 ParseTypeQualifierListOpt(DS); |
5734 D.ExtendWithDeclSpec(DS); | 5755 D.ExtendWithDeclSpec(DS); |
5774 DeclSpec DS(AttrFactory); | 5795 DeclSpec DS(AttrFactory); |
5775 | 5796 |
5776 // GNU attributes are not allowed here in a new-type-id, but Declspec and | 5797 // GNU attributes are not allowed here in a new-type-id, but Declspec and |
5777 // C++11 attributes are allowed. | 5798 // C++11 attributes are allowed. |
5778 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed | | 5799 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed | |
5779 ((D.getContext() != DeclaratorContext::CXXNewContext) | 5800 ((D.getContext() != DeclaratorContext::CXXNew) |
5780 ? AR_GNUAttributesParsed | 5801 ? AR_GNUAttributesParsed |
5781 : AR_GNUAttributesParsedAndRejected); | 5802 : AR_GNUAttributesParsedAndRejected); |
5782 ParseTypeQualifierListOpt(DS, Reqs, true, !D.mayOmitIdentifier()); | 5803 ParseTypeQualifierListOpt(DS, Reqs, true, !D.mayOmitIdentifier()); |
5783 D.ExtendWithDeclSpec(DS); | 5804 D.ExtendWithDeclSpec(DS); |
5784 | 5805 |
5924 | 5945 |
5925 // Don't parse FOO:BAR as if it were a typo for FOO::BAR inside a class, in | 5946 // Don't parse FOO:BAR as if it were a typo for FOO::BAR inside a class, in |
5926 // this context it is a bitfield. Also in range-based for statement colon | 5947 // this context it is a bitfield. Also in range-based for statement colon |
5927 // may delimit for-range-declaration. | 5948 // may delimit for-range-declaration. |
5928 ColonProtectionRAIIObject X( | 5949 ColonProtectionRAIIObject X( |
5929 *this, D.getContext() == DeclaratorContext::MemberContext || | 5950 *this, D.getContext() == DeclaratorContext::Member || |
5930 (D.getContext() == DeclaratorContext::ForContext && | 5951 (D.getContext() == DeclaratorContext::ForInit && |
5931 getLangOpts().CPlusPlus11)); | 5952 getLangOpts().CPlusPlus11)); |
5932 | 5953 |
5933 // ParseDeclaratorInternal might already have parsed the scope. | 5954 // ParseDeclaratorInternal might already have parsed the scope. |
5934 if (D.getCXXScopeSpec().isEmpty()) { | 5955 if (D.getCXXScopeSpec().isEmpty()) { |
5935 bool EnteringContext = | 5956 bool EnteringContext = D.getContext() == DeclaratorContext::File || |
5936 D.getContext() == DeclaratorContext::FileContext || | 5957 D.getContext() == DeclaratorContext::Member; |
5937 D.getContext() == DeclaratorContext::MemberContext; | |
5938 ParseOptionalCXXScopeSpecifier( | 5958 ParseOptionalCXXScopeSpecifier( |
5939 D.getCXXScopeSpec(), /*ObjectType=*/nullptr, | 5959 D.getCXXScopeSpec(), /*ObjectType=*/nullptr, |
5940 /*ObjectHadErrors=*/false, EnteringContext); | 5960 /*ObjectHadErrors=*/false, EnteringContext); |
5941 } | 5961 } |
5942 | 5962 |
5962 // the ellipsis is parsed as part of the abstract-declarator if the type | 5982 // the ellipsis is parsed as part of the abstract-declarator if the type |
5963 // of the parameter either names a template parameter pack that has not | 5983 // of the parameter either names a template parameter pack that has not |
5964 // been expanded or contains auto; otherwise, it is parsed as part of the | 5984 // been expanded or contains auto; otherwise, it is parsed as part of the |
5965 // parameter-declaration-clause. | 5985 // parameter-declaration-clause. |
5966 if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() && | 5986 if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() && |
5967 !((D.getContext() == DeclaratorContext::PrototypeContext || | 5987 !((D.getContext() == DeclaratorContext::Prototype || |
5968 D.getContext() == DeclaratorContext::LambdaExprParameterContext || | 5988 D.getContext() == DeclaratorContext::LambdaExprParameter || |
5969 D.getContext() == DeclaratorContext::BlockLiteralContext) && | 5989 D.getContext() == DeclaratorContext::BlockLiteral) && |
5970 NextToken().is(tok::r_paren) && | 5990 NextToken().is(tok::r_paren) && !D.hasGroupingParens() && |
5971 !D.hasGroupingParens() && | |
5972 !Actions.containsUnexpandedParameterPacks(D) && | 5991 !Actions.containsUnexpandedParameterPacks(D) && |
5973 D.getDeclSpec().getTypeSpecType() != TST_auto)) { | 5992 D.getDeclSpec().getTypeSpecType() != TST_auto)) { |
5974 SourceLocation EllipsisLoc = ConsumeToken(); | 5993 SourceLocation EllipsisLoc = ConsumeToken(); |
5975 if (isPtrOperatorToken(Tok.getKind(), getLangOpts(), D.getContext())) { | 5994 if (isPtrOperatorToken(Tok.getKind(), getLangOpts(), D.getContext())) { |
5976 // The ellipsis was put in the wrong place. Recover, and explain to | 5995 // The ellipsis was put in the wrong place. Recover, and explain to |
5995 bool AllowDeductionGuide; | 6014 bool AllowDeductionGuide; |
5996 if (D.getDeclSpec().hasTypeSpecifier()) { | 6015 if (D.getDeclSpec().hasTypeSpecifier()) { |
5997 AllowConstructorName = false; | 6016 AllowConstructorName = false; |
5998 AllowDeductionGuide = false; | 6017 AllowDeductionGuide = false; |
5999 } else if (D.getCXXScopeSpec().isSet()) { | 6018 } else if (D.getCXXScopeSpec().isSet()) { |
6000 AllowConstructorName = | 6019 AllowConstructorName = (D.getContext() == DeclaratorContext::File || |
6001 (D.getContext() == DeclaratorContext::FileContext || | 6020 D.getContext() == DeclaratorContext::Member); |
6002 D.getContext() == DeclaratorContext::MemberContext); | |
6003 AllowDeductionGuide = false; | 6021 AllowDeductionGuide = false; |
6004 } else { | 6022 } else { |
6005 AllowConstructorName = | 6023 AllowConstructorName = (D.getContext() == DeclaratorContext::Member); |
6006 (D.getContext() == DeclaratorContext::MemberContext); | 6024 AllowDeductionGuide = (D.getContext() == DeclaratorContext::File || |
6007 AllowDeductionGuide = | 6025 D.getContext() == DeclaratorContext::Member); |
6008 (D.getContext() == DeclaratorContext::FileContext || | |
6009 D.getContext() == DeclaratorContext::MemberContext); | |
6010 } | 6026 } |
6011 | 6027 |
6012 bool HadScope = D.getCXXScopeSpec().isValid(); | 6028 bool HadScope = D.getCXXScopeSpec().isValid(); |
6013 if (ParseUnqualifiedId(D.getCXXScopeSpec(), | 6029 if (ParseUnqualifiedId(D.getCXXScopeSpec(), |
6014 /*ObjectType=*/nullptr, | 6030 /*ObjectType=*/nullptr, |
6060 bool DiagnoseIdentifier = false; | 6076 bool DiagnoseIdentifier = false; |
6061 if (D.hasGroupingParens()) | 6077 if (D.hasGroupingParens()) |
6062 // An identifier within parens is unlikely to be intended to be anything | 6078 // An identifier within parens is unlikely to be intended to be anything |
6063 // other than a name being "declared". | 6079 // other than a name being "declared". |
6064 DiagnoseIdentifier = true; | 6080 DiagnoseIdentifier = true; |
6065 else if (D.getContext() == DeclaratorContext::TemplateArgContext) | 6081 else if (D.getContext() == DeclaratorContext::TemplateArg) |
6066 // T<int N> is an accidental identifier; T<int N indicates a missing '>'. | 6082 // T<int N> is an accidental identifier; T<int N indicates a missing '>'. |
6067 DiagnoseIdentifier = | 6083 DiagnoseIdentifier = |
6068 NextToken().isOneOf(tok::comma, tok::greater, tok::greatergreater); | 6084 NextToken().isOneOf(tok::comma, tok::greater, tok::greatergreater); |
6069 else if (D.getContext() == DeclaratorContext::AliasDeclContext || | 6085 else if (D.getContext() == DeclaratorContext::AliasDecl || |
6070 D.getContext() == DeclaratorContext::AliasTemplateContext) | 6086 D.getContext() == DeclaratorContext::AliasTemplate) |
6071 // The most likely error is that the ';' was forgotten. | 6087 // The most likely error is that the ';' was forgotten. |
6072 DiagnoseIdentifier = NextToken().isOneOf(tok::comma, tok::semi); | 6088 DiagnoseIdentifier = NextToken().isOneOf(tok::comma, tok::semi); |
6073 else if ((D.getContext() == DeclaratorContext::TrailingReturnContext || | 6089 else if ((D.getContext() == DeclaratorContext::TrailingReturn || |
6074 D.getContext() == DeclaratorContext::TrailingReturnVarContext) && | 6090 D.getContext() == DeclaratorContext::TrailingReturnVar) && |
6075 !isCXX11VirtSpecifier(Tok)) | 6091 !isCXX11VirtSpecifier(Tok)) |
6076 DiagnoseIdentifier = NextToken().isOneOf( | 6092 DiagnoseIdentifier = NextToken().isOneOf( |
6077 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try); | 6093 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try); |
6078 if (DiagnoseIdentifier) { | 6094 if (DiagnoseIdentifier) { |
6079 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id) | 6095 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id) |
6128 } else { | 6144 } else { |
6129 if (Tok.getKind() == tok::annot_pragma_parser_crash) | 6145 if (Tok.getKind() == tok::annot_pragma_parser_crash) |
6130 LLVM_BUILTIN_TRAP; | 6146 LLVM_BUILTIN_TRAP; |
6131 if (Tok.is(tok::l_square)) | 6147 if (Tok.is(tok::l_square)) |
6132 return ParseMisplacedBracketDeclarator(D); | 6148 return ParseMisplacedBracketDeclarator(D); |
6133 if (D.getContext() == DeclaratorContext::MemberContext) { | 6149 if (D.getContext() == DeclaratorContext::Member) { |
6134 // Objective-C++: Detect C++ keywords and try to prevent further errors by | 6150 // Objective-C++: Detect C++ keywords and try to prevent further errors by |
6135 // treating these keyword as valid member names. | 6151 // treating these keyword as valid member names. |
6136 if (getLangOpts().ObjC && getLangOpts().CPlusPlus && | 6152 if (getLangOpts().ObjC && getLangOpts().CPlusPlus && |
6137 Tok.getIdentifierInfo() && | 6153 Tok.getIdentifierInfo() && |
6138 Tok.getIdentifierInfo()->isCPlusPlusKeyword(getLangOpts())) { | 6154 Tok.getIdentifierInfo()->isCPlusPlusKeyword(getLangOpts())) { |
6419 // template of a class X, the expression this is a prvalue of type | 6435 // template of a class X, the expression this is a prvalue of type |
6420 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq | 6436 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq |
6421 // and the end of the function-definition, member-declarator, or | 6437 // and the end of the function-definition, member-declarator, or |
6422 // declarator. | 6438 // declarator. |
6423 // FIXME: currently, "static" case isn't handled correctly. | 6439 // FIXME: currently, "static" case isn't handled correctly. |
6424 bool IsCXX11MemberFunction = getLangOpts().CPlusPlus11 && | 6440 bool IsCXX11MemberFunction = |
6425 D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef && | 6441 getLangOpts().CPlusPlus11 && |
6426 (D.getContext() == DeclaratorContext::MemberContext | 6442 D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef && |
6427 ? !D.getDeclSpec().isFriendSpecified() | 6443 (D.getContext() == DeclaratorContext::Member |
6428 : D.getContext() == DeclaratorContext::FileContext && | 6444 ? !D.getDeclSpec().isFriendSpecified() |
6429 D.getCXXScopeSpec().isValid() && | 6445 : D.getContext() == DeclaratorContext::File && |
6430 Actions.CurContext->isRecord()); | 6446 D.getCXXScopeSpec().isValid() && |
6447 Actions.CurContext->isRecord()); | |
6431 if (!IsCXX11MemberFunction) | 6448 if (!IsCXX11MemberFunction) |
6432 return; | 6449 return; |
6433 | 6450 |
6434 Qualifiers Q = Qualifiers::fromCVRUMask(DS.getTypeQualifiers()); | 6451 Qualifiers Q = Qualifiers::fromCVRUMask(DS.getTypeQualifiers()); |
6435 if (D.getDeclSpec().hasConstexprSpecifier() && !getLangOpts().CPlusPlus14) | 6452 if (D.getDeclSpec().hasConstexprSpecifier() && !getLangOpts().CPlusPlus14) |
6499 SmallVector<SourceRange, 2> DynamicExceptionRanges; | 6516 SmallVector<SourceRange, 2> DynamicExceptionRanges; |
6500 ExprResult NoexceptExpr; | 6517 ExprResult NoexceptExpr; |
6501 CachedTokens *ExceptionSpecTokens = nullptr; | 6518 CachedTokens *ExceptionSpecTokens = nullptr; |
6502 ParsedAttributesWithRange FnAttrs(AttrFactory); | 6519 ParsedAttributesWithRange FnAttrs(AttrFactory); |
6503 TypeResult TrailingReturnType; | 6520 TypeResult TrailingReturnType; |
6521 SourceLocation TrailingReturnTypeLoc; | |
6504 | 6522 |
6505 /* LocalEndLoc is the end location for the local FunctionTypeLoc. | 6523 /* LocalEndLoc is the end location for the local FunctionTypeLoc. |
6506 EndLoc is the end location for the function declarator. | 6524 EndLoc is the end location for the function declarator. |
6507 They differ for trailing return types. */ | 6525 They differ for trailing return types. */ |
6508 SourceLocation StartLoc, LocalEndLoc, EndLoc; | 6526 SourceLocation StartLoc, LocalEndLoc, EndLoc; |
6563 | 6581 |
6564 llvm::Optional<Sema::CXXThisScopeRAII> ThisScope; | 6582 llvm::Optional<Sema::CXXThisScopeRAII> ThisScope; |
6565 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope); | 6583 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope); |
6566 | 6584 |
6567 // Parse exception-specification[opt]. | 6585 // Parse exception-specification[opt]. |
6586 // FIXME: Per [class.mem]p6, all exception-specifications at class scope | |
6587 // should be delayed, including those for non-members (eg, friend | |
6588 // declarations). But only applying this to member declarations is | |
6589 // consistent with what other implementations do. | |
6568 bool Delayed = D.isFirstDeclarationOfMember() && | 6590 bool Delayed = D.isFirstDeclarationOfMember() && |
6569 D.isFunctionDeclaratorAFunctionDeclaration(); | 6591 D.isFunctionDeclaratorAFunctionDeclaration(); |
6570 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) && | 6592 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) && |
6571 GetLookAheadToken(0).is(tok::kw_noexcept) && | 6593 GetLookAheadToken(0).is(tok::kw_noexcept) && |
6572 GetLookAheadToken(1).is(tok::l_paren) && | 6594 GetLookAheadToken(1).is(tok::l_paren) && |
6605 StartLoc = D.getDeclSpec().getTypeSpecTypeLoc(); | 6627 StartLoc = D.getDeclSpec().getTypeSpecTypeLoc(); |
6606 LocalEndLoc = Tok.getLocation(); | 6628 LocalEndLoc = Tok.getLocation(); |
6607 SourceRange Range; | 6629 SourceRange Range; |
6608 TrailingReturnType = | 6630 TrailingReturnType = |
6609 ParseTrailingReturnType(Range, D.mayBeFollowedByCXXDirectInit()); | 6631 ParseTrailingReturnType(Range, D.mayBeFollowedByCXXDirectInit()); |
6632 TrailingReturnTypeLoc = Range.getBegin(); | |
6610 EndLoc = Range.getEnd(); | 6633 EndLoc = Range.getEnd(); |
6611 } | 6634 } |
6612 } else if (standardAttributesAllowed()) { | 6635 } else if (standardAttributesAllowed()) { |
6613 MaybeParseCXX11Attributes(FnAttrs); | 6636 MaybeParseCXX11Attributes(FnAttrs); |
6614 } | 6637 } |
6637 /*MutableLoc=*/SourceLocation(), | 6660 /*MutableLoc=*/SourceLocation(), |
6638 ESpecType, ESpecRange, DynamicExceptions.data(), | 6661 ESpecType, ESpecRange, DynamicExceptions.data(), |
6639 DynamicExceptionRanges.data(), DynamicExceptions.size(), | 6662 DynamicExceptionRanges.data(), DynamicExceptions.size(), |
6640 NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, | 6663 NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, |
6641 ExceptionSpecTokens, DeclsInPrototype, StartLoc, | 6664 ExceptionSpecTokens, DeclsInPrototype, StartLoc, |
6642 LocalEndLoc, D, TrailingReturnType, &DS), | 6665 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc, |
6666 &DS), | |
6643 std::move(FnAttrs), EndLoc); | 6667 std::move(FnAttrs), EndLoc); |
6644 } | 6668 } |
6645 | 6669 |
6646 /// ParseRefQualifier - Parses a member function ref-qualifier. Returns | 6670 /// ParseRefQualifier - Parses a member function ref-qualifier. Returns |
6647 /// true if a ref-qualifier is found. | 6671 /// true if a ref-qualifier is found. |
6820 | 6844 |
6821 // Parse the declarator. This is "PrototypeContext" or | 6845 // Parse the declarator. This is "PrototypeContext" or |
6822 // "LambdaExprParameterContext", because we must accept either | 6846 // "LambdaExprParameterContext", because we must accept either |
6823 // 'declarator' or 'abstract-declarator' here. | 6847 // 'declarator' or 'abstract-declarator' here. |
6824 Declarator ParmDeclarator( | 6848 Declarator ParmDeclarator( |
6825 DS, DeclaratorCtx == DeclaratorContext::RequiresExprContext | 6849 DS, DeclaratorCtx == DeclaratorContext::RequiresExpr |
6826 ? DeclaratorContext::RequiresExprContext | 6850 ? DeclaratorContext::RequiresExpr |
6827 : DeclaratorCtx == DeclaratorContext::LambdaExprContext | 6851 : DeclaratorCtx == DeclaratorContext::LambdaExpr |
6828 ? DeclaratorContext::LambdaExprParameterContext | 6852 ? DeclaratorContext::LambdaExprParameter |
6829 : DeclaratorContext::PrototypeContext); | 6853 : DeclaratorContext::Prototype); |
6830 ParseDeclarator(ParmDeclarator); | 6854 ParseDeclarator(ParmDeclarator); |
6831 | 6855 |
6832 // Parse GNU attributes, if present. | 6856 // Parse GNU attributes, if present. |
6833 MaybeParseGNUAttributes(ParmDeclarator); | 6857 MaybeParseGNUAttributes(ParmDeclarator); |
6834 | 6858 |
6903 // C. | 6927 // C. |
6904 if (Tok.is(tok::equal)) { | 6928 if (Tok.is(tok::equal)) { |
6905 SourceLocation EqualLoc = Tok.getLocation(); | 6929 SourceLocation EqualLoc = Tok.getLocation(); |
6906 | 6930 |
6907 // Parse the default argument | 6931 // Parse the default argument |
6908 if (DeclaratorCtx == DeclaratorContext::MemberContext) { | 6932 if (DeclaratorCtx == DeclaratorContext::Member) { |
6909 // If we're inside a class definition, cache the tokens | 6933 // If we're inside a class definition, cache the tokens |
6910 // corresponding to the default argument. We'll actually parse | 6934 // corresponding to the default argument. We'll actually parse |
6911 // them when we see the end of the class definition. | 6935 // them when we see the end of the class definition. |
6912 DefArgToks.reset(new CachedTokens); | 6936 DefArgToks.reset(new CachedTokens); |
6913 | 6937 |
7030 T.getOpenLocation(), | 7054 T.getOpenLocation(), |
7031 T.getCloseLocation()), | 7055 T.getCloseLocation()), |
7032 std::move(attrs), T.getCloseLocation()); | 7056 std::move(attrs), T.getCloseLocation()); |
7033 return; | 7057 return; |
7034 } else if (Tok.getKind() == tok::code_completion) { | 7058 } else if (Tok.getKind() == tok::code_completion) { |
7059 cutOffParsing(); | |
7035 Actions.CodeCompleteBracketDeclarator(getCurScope()); | 7060 Actions.CodeCompleteBracketDeclarator(getCurScope()); |
7036 return cutOffParsing(); | 7061 return; |
7037 } | 7062 } |
7038 | 7063 |
7039 // If valid, this location is the position where we read the 'static' keyword. | 7064 // If valid, this location is the position where we read the 'static' keyword. |
7040 SourceLocation StaticLoc; | 7065 SourceLocation StaticLoc; |
7041 TryConsumeToken(tok::kw_static, StaticLoc); | 7066 TryConsumeToken(tok::kw_static, StaticLoc); |
7314 case tok::kw_char: | 7339 case tok::kw_char: |
7315 case tok::kw_int: | 7340 case tok::kw_int: |
7316 case tok::kw_float: | 7341 case tok::kw_float: |
7317 case tok::kw_double: | 7342 case tok::kw_double: |
7318 case tok::kw_bool: | 7343 case tok::kw_bool: |
7344 case tok::kw__Bool: | |
7319 case tok::kw___bool: | 7345 case tok::kw___bool: |
7320 case tok::kw___pixel: | 7346 case tok::kw___pixel: |
7321 Tok.setKind(tok::kw___vector); | 7347 Tok.setKind(tok::kw___vector); |
7322 return true; | 7348 return true; |
7323 case tok::identifier: | 7349 case tok::identifier: |
7324 if (Next.getIdentifierInfo() == Ident_pixel) { | 7350 if (Next.getIdentifierInfo() == Ident_pixel) { |
7325 Tok.setKind(tok::kw___vector); | 7351 Tok.setKind(tok::kw___vector); |
7326 return true; | 7352 return true; |
7327 } | 7353 } |
7328 if (Next.getIdentifierInfo() == Ident_bool) { | 7354 if (Next.getIdentifierInfo() == Ident_bool || |
7355 Next.getIdentifierInfo() == Ident_Bool) { | |
7329 Tok.setKind(tok::kw___vector); | 7356 Tok.setKind(tok::kw___vector); |
7330 return true; | 7357 return true; |
7331 } | 7358 } |
7332 return false; | 7359 return false; |
7333 } | 7360 } |
7348 case tok::kw_char: | 7375 case tok::kw_char: |
7349 case tok::kw_int: | 7376 case tok::kw_int: |
7350 case tok::kw_float: | 7377 case tok::kw_float: |
7351 case tok::kw_double: | 7378 case tok::kw_double: |
7352 case tok::kw_bool: | 7379 case tok::kw_bool: |
7380 case tok::kw__Bool: | |
7353 case tok::kw___bool: | 7381 case tok::kw___bool: |
7354 case tok::kw___pixel: | 7382 case tok::kw___pixel: |
7355 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID, Policy); | 7383 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID, Policy); |
7356 return true; | 7384 return true; |
7357 case tok::identifier: | 7385 case tok::identifier: |
7358 if (Next.getIdentifierInfo() == Ident_pixel) { | 7386 if (Next.getIdentifierInfo() == Ident_pixel) { |
7359 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID,Policy); | 7387 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID,Policy); |
7360 return true; | 7388 return true; |
7361 } | 7389 } |
7362 if (Next.getIdentifierInfo() == Ident_bool) { | 7390 if (Next.getIdentifierInfo() == Ident_bool || |
7363 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID,Policy); | 7391 Next.getIdentifierInfo() == Ident_Bool) { |
7392 isInvalid = | |
7393 DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID, Policy); | |
7364 return true; | 7394 return true; |
7365 } | 7395 } |
7366 break; | 7396 break; |
7367 default: | 7397 default: |
7368 break; | 7398 break; |