-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[C23] Complete support for WG14 N2508 #71398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
1d54a5c
683ef4e
532b1ea
b2c9965
8981b9e
2a3f06a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -235,10 +235,7 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( | |||||||||||||||||||
auto IsStmtAttr = [](ParsedAttr &Attr) { return Attr.isStmtAttr(); }; | ||||||||||||||||||||
bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) && | ||||||||||||||||||||
llvm::all_of(GNUAttrs, IsStmtAttr); | ||||||||||||||||||||
if ((getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt || | ||||||||||||||||||||
(StmtCtx & ParsedStmtContext::AllowDeclarationsInC) != | ||||||||||||||||||||
ParsedStmtContext()) && | ||||||||||||||||||||
((GNUAttributeLoc.isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) || | ||||||||||||||||||||
if (((GNUAttributeLoc.isValid() && !(HaveAttrs && AllAttrsAreStmtAttrs)) || | ||||||||||||||||||||
isDeclarationStatement())) { | ||||||||||||||||||||
SourceLocation DeclStart = Tok.getLocation(), DeclEnd; | ||||||||||||||||||||
DeclGroupPtrTy Decl; | ||||||||||||||||||||
|
@@ -698,6 +695,19 @@ StmtResult Parser::ParseSEHLeaveStatement() { | |||||||||||||||||||
return Actions.ActOnSEHLeaveStmt(LeaveLoc, getCurScope()); | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
static void DiagnoseLabelFollowedByDecl(Parser &P, const Stmt *SubStmt) { | ||||||||||||||||||||
// When in C mode (but not Microsoft extensions mode), diagnose use of a | ||||||||||||||||||||
// label that is followed by a declaration rather than a statement. | ||||||||||||||||||||
if (!P.getLangOpts().CPlusPlus && !P.getLangOpts().MicrosoftExt && | ||||||||||||||||||||
isa<DeclStmt>(SubStmt)) { | ||||||||||||||||||||
if (P.getLangOpts().C23) | ||||||||||||||||||||
P.Diag(SubStmt->getBeginLoc(), | ||||||||||||||||||||
diag::warn_c23_compat_label_followed_by_declaration); | ||||||||||||||||||||
else | ||||||||||||||||||||
P.Diag(SubStmt->getBeginLoc(), diag::ext_c_label_followed_by_declaration); | ||||||||||||||||||||
} | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
/// ParseLabeledStatement - We have an identifier and a ':' after it. | ||||||||||||||||||||
/// | ||||||||||||||||||||
/// label: | ||||||||||||||||||||
|
@@ -712,9 +722,7 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes &Attrs, | |||||||||||||||||||
assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() && | ||||||||||||||||||||
"Not an identifier!"); | ||||||||||||||||||||
|
||||||||||||||||||||
// The substatement is always a 'statement', not a 'declaration', but is | ||||||||||||||||||||
// otherwise in the same context as the labeled-statement. | ||||||||||||||||||||
StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC; | ||||||||||||||||||||
StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives; | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this deserves a comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||||||||||||||||
|
||||||||||||||||||||
Token IdentTok = Tok; // Save the whole token. | ||||||||||||||||||||
ConsumeToken(); // eat the identifier. | ||||||||||||||||||||
|
@@ -763,6 +771,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes &Attrs, | |||||||||||||||||||
if (SubStmt.isInvalid()) | ||||||||||||||||||||
SubStmt = Actions.ActOnNullStmt(ColonLoc); | ||||||||||||||||||||
|
||||||||||||||||||||
DiagnoseLabelFollowedByDecl(*this, SubStmt.get()); | ||||||||||||||||||||
|
||||||||||||||||||||
LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(), | ||||||||||||||||||||
IdentTok.getLocation()); | ||||||||||||||||||||
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs); | ||||||||||||||||||||
|
@@ -781,9 +791,7 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, | |||||||||||||||||||
bool MissingCase, ExprResult Expr) { | ||||||||||||||||||||
assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!"); | ||||||||||||||||||||
|
||||||||||||||||||||
// The substatement is always a 'statement', not a 'declaration', but is | ||||||||||||||||||||
// otherwise in the same context as the labeled-statement. | ||||||||||||||||||||
StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC; | ||||||||||||||||||||
StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives; | ||||||||||||||||||||
|
||||||||||||||||||||
// It is very common for code to contain many case statements recursively | ||||||||||||||||||||
// nested, as in (but usually without indentation): | ||||||||||||||||||||
|
@@ -909,6 +917,7 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, | |||||||||||||||||||
// Broken sub-stmt shouldn't prevent forming the case statement properly. | ||||||||||||||||||||
if (SubStmt.isInvalid()) | ||||||||||||||||||||
SubStmt = Actions.ActOnNullStmt(SourceLocation()); | ||||||||||||||||||||
DiagnoseLabelFollowedByDecl(*this, SubStmt.get()); | ||||||||||||||||||||
Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get()); | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
|
@@ -924,9 +933,7 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, | |||||||||||||||||||
StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) { | ||||||||||||||||||||
assert(Tok.is(tok::kw_default) && "Not a default stmt!"); | ||||||||||||||||||||
|
||||||||||||||||||||
// The substatement is always a 'statement', not a 'declaration', but is | ||||||||||||||||||||
// otherwise in the same context as the labeled-statement. | ||||||||||||||||||||
StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC; | ||||||||||||||||||||
StmtCtx &= ~ParsedStmtContext::AllowStandaloneOpenMPDirectives; | ||||||||||||||||||||
|
||||||||||||||||||||
SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'. | ||||||||||||||||||||
|
||||||||||||||||||||
|
@@ -960,6 +967,7 @@ StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) { | |||||||||||||||||||
if (SubStmt.isInvalid()) | ||||||||||||||||||||
SubStmt = Actions.ActOnNullStmt(ColonLoc); | ||||||||||||||||||||
|
||||||||||||||||||||
DiagnoseLabelFollowedByDecl(*this, SubStmt.get()); | ||||||||||||||||||||
return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc, | ||||||||||||||||||||
SubStmt.get(), getCurScope()); | ||||||||||||||||||||
} | ||||||||||||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.