aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2022-06-06 07:17:35 -0400
committerAaron Ballman <aaron@aaronballman.com>2022-06-06 07:17:35 -0400
commit881125ad9178120acef186f579e36ced0888dfdb (patch)
tree1a9b07e2437733a30739705a291bdaf6a6c41efa /clang/lib/Parse/ParseDecl.cpp
parent4ea1b43527c9a845942dbbc27e022d74d72728e6 (diff)
downloadllvm-881125ad9178120acef186f579e36ced0888dfdb.zip
llvm-881125ad9178120acef186f579e36ced0888dfdb.tar.gz
llvm-881125ad9178120acef186f579e36ced0888dfdb.tar.bz2
Allow use of an elaborated type specifier in a _Generic association in C++
Currently, Clang accepts this code in C mode (where the tag is required to be used) but rejects it in C++ mode thinking that the association is defining a new type. void foo(void) { struct S { int a; }; _Generic(something, struct S : 1); } Clang thinks this in C++ because it sees struct S : when parsing the class specifier and decides that must be a type definition (because the colon signifies the presence of a base class type). This patch adds a new declarator context to represent a _Generic association so that we can distinguish these situations properly. Fixes #55562 Differential Revision: https://reviews.llvm.org/D126969
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp4
1 files changed, 3 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 18f4f12..0cdf915 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2870,6 +2870,8 @@ Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) {
if (Context == DeclaratorContext::AliasDecl ||
Context == DeclaratorContext::AliasTemplate)
return DeclSpecContext::DSC_alias_declaration;
+ if (Context == DeclaratorContext::Association)
+ return DeclSpecContext::DSC_association;
return DeclSpecContext::DSC_normal;
}
@@ -4573,7 +4575,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// Determine whether this declaration is permitted to have an enum-base.
AllowDefiningTypeSpec AllowEnumSpecifier =
- isDefiningTypeSpecifierContext(DSC);
+ isDefiningTypeSpecifierContext(DSC, getLangOpts().CPlusPlus);
bool CanBeOpaqueEnumDeclaration =
DS.isEmpty() && isOpaqueEnumDeclarationContext(DSC);
bool CanHaveEnumBase = (getLangOpts().CPlusPlus11 || getLangOpts().ObjC ||