Skip to content

Commit 3a913d3

Browse files
authored
[clang][NFC] Refactor Sema::TagUseKind (#92689)
This patch makes `TagUseKind` a scoped enumeration, and moves it outside of `Sema` class, making it eligible for forward declaring.
1 parent 3b3d622 commit 3a913d3

File tree

7 files changed

+160
-150
lines changed

7 files changed

+160
-150
lines changed

clang/include/clang/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2814,7 +2814,7 @@ class Parser : public CodeCompletionHandler {
28142814
SourceLocation CorrectLocation);
28152815

28162816
void stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs, DeclSpec &DS,
2817-
Sema::TagUseKind TUK);
2817+
TagUseKind TUK);
28182818

28192819
// FixItLoc = possible correct location for the attributes
28202820
void ProhibitAttributes(ParsedAttributes &Attrs,

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,13 @@ enum class CheckedConversionKind {
447447
ForBuiltinOverloadedOp
448448
};
449449

450+
enum class TagUseKind {
451+
Reference, // Reference to a tag: 'struct foo *X;'
452+
Declaration, // Fwd decl of a tag: 'struct foo;'
453+
Definition, // Definition of a tag: 'struct foo { int X; } Y;'
454+
Friend // Friend declaration: 'friend struct foo;'
455+
};
456+
450457
/// Sema - This implements semantic analysis and AST building for C.
451458
/// \nosubgrouping
452459
class Sema final : public SemaBase {
@@ -3168,13 +3175,6 @@ class Sema final : public SemaBase {
31683175
bool isDefinition, SourceLocation NewTagLoc,
31693176
const IdentifierInfo *Name);
31703177

3171-
enum TagUseKind {
3172-
TUK_Reference, // Reference to a tag: 'struct foo *X;'
3173-
TUK_Declaration, // Fwd decl of a tag: 'struct foo;'
3174-
TUK_Definition, // Definition of a tag: 'struct foo { int X; } Y;'
3175-
TUK_Friend // Friend declaration: 'friend struct foo;'
3176-
};
3177-
31783178
enum OffsetOfKind {
31793179
// Not parsing a type within __builtin_offsetof.
31803180
OOK_Outside,

clang/lib/Parse/ParseDecl.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,9 +1923,8 @@ void Parser::DiagnoseCXX11AttributeExtension(ParsedAttributes &Attrs) {
19231923
// variable.
19241924
// This function moves attributes that should apply to the type off DS to Attrs.
19251925
void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs,
1926-
DeclSpec &DS,
1927-
Sema::TagUseKind TUK) {
1928-
if (TUK == Sema::TUK_Reference)
1926+
DeclSpec &DS, TagUseKind TUK) {
1927+
if (TUK == TagUseKind::Reference)
19291928
return;
19301929

19311930
llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
@@ -5287,9 +5286,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
52875286
// enum foo {..}; void bar() { enum foo; } <- new foo in bar.
52885287
// enum foo {..}; void bar() { enum foo x; } <- use of old foo.
52895288
//
5290-
Sema::TagUseKind TUK;
5289+
TagUseKind TUK;
52915290
if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5292-
TUK = Sema::TUK_Reference;
5291+
TUK = TagUseKind::Reference;
52935292
else if (Tok.is(tok::l_brace)) {
52945293
if (DS.isFriendSpecified()) {
52955294
Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
@@ -5301,9 +5300,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
53015300
ScopedEnumKWLoc = SourceLocation();
53025301
IsScopedUsingClassTag = false;
53035302
BaseType = TypeResult();
5304-
TUK = Sema::TUK_Friend;
5303+
TUK = TagUseKind::Friend;
53055304
} else {
5306-
TUK = Sema::TUK_Definition;
5305+
TUK = TagUseKind::Definition;
53075306
}
53085307
} else if (!isTypeSpecifier(DSC) &&
53095308
(Tok.is(tok::semi) ||
@@ -5312,29 +5311,29 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
53125311
// An opaque-enum-declaration is required to be standalone (no preceding or
53135312
// following tokens in the declaration). Sema enforces this separately by
53145313
// diagnosing anything else in the DeclSpec.
5315-
TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
5314+
TUK = DS.isFriendSpecified() ? TagUseKind::Friend : TagUseKind::Declaration;
53165315
if (Tok.isNot(tok::semi)) {
53175316
// A semicolon was missing after this declaration. Diagnose and recover.
53185317
ExpectAndConsume(tok::semi, diag::err_expected_after, "enum");
53195318
PP.EnterToken(Tok, /*IsReinject=*/true);
53205319
Tok.setKind(tok::semi);
53215320
}
53225321
} else {
5323-
TUK = Sema::TUK_Reference;
5322+
TUK = TagUseKind::Reference;
53245323
}
53255324

53265325
bool IsElaboratedTypeSpecifier =
5327-
TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend;
5326+
TUK == TagUseKind::Reference || TUK == TagUseKind::Friend;
53285327

53295328
// If this is an elaborated type specifier nested in a larger declaration,
53305329
// and we delayed diagnostics before, just merge them into the current pool.
5331-
if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) {
5330+
if (TUK == TagUseKind::Reference && shouldDelayDiagsInTag) {
53325331
diagsFromTag.redelay();
53335332
}
53345333

53355334
MultiTemplateParamsArg TParams;
53365335
if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
5337-
TUK != Sema::TUK_Reference) {
5336+
TUK != TagUseKind::Reference) {
53385337
if (!getLangOpts().CPlusPlus11 || !SS.isSet()) {
53395338
// Skip the rest of this declarator, up until the comma or semicolon.
53405339
Diag(Tok, diag::err_enum_template);
@@ -5355,7 +5354,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
53555354
SS.setTemplateParamLists(TParams);
53565355
}
53575356

5358-
if (!Name && TUK != Sema::TUK_Definition) {
5357+
if (!Name && TUK != TagUseKind::Definition) {
53595358
Diag(Tok, diag::err_enumerator_unnamed_no_def);
53605359

53615360
DS.SetTypeSpecError();
@@ -5388,7 +5387,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
53885387
stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
53895388

53905389
SkipBodyInfo SkipBody;
5391-
if (!Name && TUK == Sema::TUK_Definition && Tok.is(tok::l_brace) &&
5390+
if (!Name && TUK == TagUseKind::Definition && Tok.is(tok::l_brace) &&
53925391
NextToken().is(tok::identifier))
53935392
SkipBody = Actions.shouldSkipAnonEnumBody(getCurScope(),
53945393
NextToken().getIdentifierInfo(),
@@ -5409,7 +5408,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
54095408
OffsetOfState, &SkipBody).get();
54105409

54115410
if (SkipBody.ShouldSkip) {
5412-
assert(TUK == Sema::TUK_Definition && "can only skip a definition");
5411+
assert(TUK == TagUseKind::Definition && "can only skip a definition");
54135412

54145413
BalancedDelimiterTracker T(*this, tok::l_brace);
54155414
T.consumeOpen();
@@ -5451,7 +5450,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
54515450
if (!TagDecl) {
54525451
// The action failed to produce an enumeration tag. If this is a
54535452
// definition, consume the entire definition.
5454-
if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
5453+
if (Tok.is(tok::l_brace) && TUK != TagUseKind::Reference) {
54555454
ConsumeBrace();
54565455
SkipUntil(tok::r_brace, StopAtSemi);
54575456
}
@@ -5460,7 +5459,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
54605459
return;
54615460
}
54625461

5463-
if (Tok.is(tok::l_brace) && TUK == Sema::TUK_Definition) {
5462+
if (Tok.is(tok::l_brace) && TUK == TagUseKind::Definition) {
54645463
Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
54655464
ParseEnumBody(StartLoc, D);
54665465
if (SkipBody.CheckSameAsPrevious &&

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,11 +1961,11 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
19611961
MaybeParseCXX11Attributes(Attributes);
19621962

19631963
const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
1964-
Sema::TagUseKind TUK;
1964+
TagUseKind TUK;
19651965
if (isDefiningTypeSpecifierContext(DSC, getLangOpts().CPlusPlus) ==
19661966
AllowDefiningTypeSpec::No ||
19671967
(getLangOpts().OpenMP && OpenMPDirectiveParsing))
1968-
TUK = Sema::TUK_Reference;
1968+
TUK = TagUseKind::Reference;
19691969
else if (Tok.is(tok::l_brace) ||
19701970
(DSC != DeclSpecContext::DSC_association &&
19711971
getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
@@ -1980,10 +1980,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
19801980
// Skip everything up to the semicolon, so that this looks like a proper
19811981
// friend class (or template thereof) declaration.
19821982
SkipUntil(tok::semi, StopBeforeMatch);
1983-
TUK = Sema::TUK_Friend;
1983+
TUK = TagUseKind::Friend;
19841984
} else {
19851985
// Okay, this is a class definition.
1986-
TUK = Sema::TUK_Definition;
1986+
TUK = TagUseKind::Definition;
19871987
}
19881988
} else if (isClassCompatibleKeyword() &&
19891989
(NextToken().is(tok::l_square) ||
@@ -2024,15 +2024,15 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
20242024
}
20252025

20262026
if (Tok.isOneOf(tok::l_brace, tok::colon))
2027-
TUK = Sema::TUK_Definition;
2027+
TUK = TagUseKind::Definition;
20282028
else
2029-
TUK = Sema::TUK_Reference;
2029+
TUK = TagUseKind::Reference;
20302030

20312031
PA.Revert();
20322032
} else if (!isTypeSpecifier(DSC) &&
20332033
(Tok.is(tok::semi) ||
20342034
(Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {
2035-
TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
2035+
TUK = DS.isFriendSpecified() ? TagUseKind::Friend : TagUseKind::Declaration;
20362036
if (Tok.isNot(tok::semi)) {
20372037
const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
20382038
// A semicolon was missing after this declaration. Diagnose and recover.
@@ -2042,11 +2042,11 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
20422042
Tok.setKind(tok::semi);
20432043
}
20442044
} else
2045-
TUK = Sema::TUK_Reference;
2045+
TUK = TagUseKind::Reference;
20462046

20472047
// Forbid misplaced attributes. In cases of a reference, we pass attributes
20482048
// to caller to handle.
2049-
if (TUK != Sema::TUK_Reference) {
2049+
if (TUK != TagUseKind::Reference) {
20502050
// If this is not a reference, then the only possible
20512051
// valid place for C++11 attributes to appear here
20522052
// is between class-key and class-name. If there are
@@ -2072,7 +2072,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
20722072

20732073
if (!Name && !TemplateId &&
20742074
(DS.getTypeSpecType() == DeclSpec::TST_error ||
2075-
TUK != Sema::TUK_Definition)) {
2075+
TUK != TagUseKind::Definition)) {
20762076
if (DS.getTypeSpecType() != DeclSpec::TST_error) {
20772077
// We have a declaration or reference to an anonymous class.
20782078
Diag(StartLoc, diag::err_anon_type_definition)
@@ -2082,7 +2082,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
20822082
// If we are parsing a definition and stop at a base-clause, continue on
20832083
// until the semicolon. Continuing from the comma will just trick us into
20842084
// thinking we are seeing a variable declaration.
2085-
if (TUK == Sema::TUK_Definition && Tok.is(tok::colon))
2085+
if (TUK == TagUseKind::Definition && Tok.is(tok::colon))
20862086
SkipUntil(tok::semi, StopBeforeMatch);
20872087
else
20882088
SkipUntil(tok::comma, StopAtSemi);
@@ -2103,7 +2103,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
21032103
if (TemplateId->isInvalid()) {
21042104
// Can't build the declaration.
21052105
} else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
2106-
TUK == Sema::TUK_Declaration) {
2106+
TUK == TagUseKind::Declaration) {
21072107
// This is an explicit instantiation of a class template.
21082108
ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
21092109
diag::err_keyword_not_allowed,
@@ -2119,8 +2119,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
21192119
// they have template headers, in which case they're ill-formed
21202120
// (FIXME: "template <class T> friend class A<T>::B<int>;").
21212121
// We diagnose this error in ActOnClassTemplateSpecialization.
2122-
} else if (TUK == Sema::TUK_Reference ||
2123-
(TUK == Sema::TUK_Friend &&
2122+
} else if (TUK == TagUseKind::Reference ||
2123+
(TUK == TagUseKind::Friend &&
21242124
TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
21252125
ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
21262126
diag::err_keyword_not_allowed,
@@ -2145,10 +2145,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
21452145
// It this is friend declaration however, since it cannot have a
21462146
// template header, it is most likely that the user meant to
21472147
// remove the 'template' keyword.
2148-
assert((TUK == Sema::TUK_Definition || TUK == Sema::TUK_Friend) &&
2148+
assert((TUK == TagUseKind::Definition || TUK == TagUseKind::Friend) &&
21492149
"Expected a definition here");
21502150

2151-
if (TUK == Sema::TUK_Friend) {
2151+
if (TUK == TagUseKind::Friend) {
21522152
Diag(DS.getFriendSpecLoc(), diag::err_friend_explicit_instantiation);
21532153
TemplateParams = nullptr;
21542154
} else {
@@ -2179,7 +2179,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
21792179
&SkipBody);
21802180
}
21812181
} else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
2182-
TUK == Sema::TUK_Declaration) {
2182+
TUK == TagUseKind::Declaration) {
21832183
// Explicit instantiation of a member of a class template
21842184
// specialization, e.g.,
21852185
//
@@ -2190,7 +2190,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
21902190
TagOrTempResult = Actions.ActOnExplicitInstantiation(
21912191
getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
21922192
TagType, StartLoc, SS, Name, NameLoc, attrs);
2193-
} else if (TUK == Sema::TUK_Friend &&
2193+
} else if (TUK == TagUseKind::Friend &&
21942194
TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
21952195
ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
21962196
diag::err_keyword_not_allowed,
@@ -2202,12 +2202,12 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
22022202
MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr,
22032203
TemplateParams ? TemplateParams->size() : 0));
22042204
} else {
2205-
if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition)
2205+
if (TUK != TagUseKind::Declaration && TUK != TagUseKind::Definition)
22062206
ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
22072207
diag::err_keyword_not_allowed,
22082208
/* DiagnoseEmptyAttrs=*/true);
22092209

2210-
if (TUK == Sema::TUK_Definition &&
2210+
if (TUK == TagUseKind::Definition &&
22112211
TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
22122212
// If the declarator-id is not a template-id, issue a diagnostic and
22132213
// recover by ignoring the 'template' keyword.
@@ -2222,7 +2222,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
22222222
// reference. For example, we don't need the template parameters here:
22232223
// template <class T> class A *makeA(T t);
22242224
MultiTemplateParamsArg TParams;
2225-
if (TUK != Sema::TUK_Reference && TemplateParams)
2225+
if (TUK != TagUseKind::Reference && TemplateParams)
22262226
TParams =
22272227
MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size());
22282228

@@ -2241,7 +2241,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
22412241
// If ActOnTag said the type was dependent, try again with the
22422242
// less common call.
22432243
if (IsDependent) {
2244-
assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend);
2244+
assert(TUK == TagUseKind::Reference || TUK == TagUseKind::Friend);
22452245
TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK, SS,
22462246
Name, StartLoc, NameLoc);
22472247
}
@@ -2252,13 +2252,13 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
22522252
// just merge them into the current pool.
22532253
if (shouldDelayDiagsInTag) {
22542254
diagsFromTag.done();
2255-
if (TUK == Sema::TUK_Reference &&
2255+
if (TUK == TagUseKind::Reference &&
22562256
TemplateInfo.Kind == ParsedTemplateInfo::Template)
22572257
diagsFromTag.redelay();
22582258
}
22592259

22602260
// If there is a body, parse it and inform the actions module.
2261-
if (TUK == Sema::TUK_Definition) {
2261+
if (TUK == TagUseKind::Definition) {
22622262
assert(Tok.is(tok::l_brace) ||
22632263
(getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
22642264
isClassCompatibleKeyword());
@@ -2316,7 +2316,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
23162316
//
23172317
// After a type-specifier, we don't expect a semicolon. This only happens in
23182318
// C, since definitions are not permitted in this context in C++.
2319-
if (TUK == Sema::TUK_Definition &&
2319+
if (TUK == TagUseKind::Definition &&
23202320
(getLangOpts().CPlusPlus || !isTypeSpecifier(DSC)) &&
23212321
(TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
23222322
if (Tok.isNot(tok::semi)) {

0 commit comments

Comments
 (0)