Skip to content

[clang][NFC] Refactor Sema::TagUseKind #92689

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

Merged
merged 3 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -2814,7 +2814,7 @@ class Parser : public CodeCompletionHandler {
SourceLocation CorrectLocation);

void stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs, DeclSpec &DS,
Sema::TagUseKind TUK);
TagUseKind TUK);

// FixItLoc = possible correct location for the attributes
void ProhibitAttributes(ParsedAttributes &Attrs,
Expand Down
14 changes: 7 additions & 7 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,13 @@ enum class CheckedConversionKind {
ForBuiltinOverloadedOp
};

enum class TagUseKind {
Reference, // Reference to a tag: 'struct foo *X;'
Declaration, // Fwd decl of a tag: 'struct foo;'
Definition, // Definition of a tag: 'struct foo { int X; } Y;'
Friend // Friend declaration: 'friend struct foo;'
};

/// Sema - This implements semantic analysis and AST building for C.
/// \nosubgrouping
class Sema final : public SemaBase {
Expand Down Expand Up @@ -3162,13 +3169,6 @@ class Sema final : public SemaBase {
bool isDefinition, SourceLocation NewTagLoc,
const IdentifierInfo *Name);

enum TagUseKind {
TUK_Reference, // Reference to a tag: 'struct foo *X;'
TUK_Declaration, // Fwd decl of a tag: 'struct foo;'
TUK_Definition, // Definition of a tag: 'struct foo { int X; } Y;'
TUK_Friend // Friend declaration: 'friend struct foo;'
};

enum OffsetOfKind {
// Not parsing a type within __builtin_offsetof.
OOK_Outside,
Expand Down
33 changes: 16 additions & 17 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1923,9 +1923,8 @@ void Parser::DiagnoseCXX11AttributeExtension(ParsedAttributes &Attrs) {
// variable.
// This function moves attributes that should apply to the type off DS to Attrs.
void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs,
DeclSpec &DS,
Sema::TagUseKind TUK) {
if (TUK == Sema::TUK_Reference)
DeclSpec &DS, TagUseKind TUK) {
if (TUK == TagUseKind::Reference)
return;

llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
Expand Down Expand Up @@ -5287,9 +5286,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// enum foo {..}; void bar() { enum foo; } <- new foo in bar.
// enum foo {..}; void bar() { enum foo x; } <- use of old foo.
//
Sema::TagUseKind TUK;
TagUseKind TUK;
if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
TUK = Sema::TUK_Reference;
TUK = TagUseKind::Reference;
else if (Tok.is(tok::l_brace)) {
if (DS.isFriendSpecified()) {
Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
Expand All @@ -5301,9 +5300,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
ScopedEnumKWLoc = SourceLocation();
IsScopedUsingClassTag = false;
BaseType = TypeResult();
TUK = Sema::TUK_Friend;
TUK = TagUseKind::Friend;
} else {
TUK = Sema::TUK_Definition;
TUK = TagUseKind::Definition;
}
} else if (!isTypeSpecifier(DSC) &&
(Tok.is(tok::semi) ||
Expand All @@ -5312,29 +5311,29 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// An opaque-enum-declaration is required to be standalone (no preceding or
// following tokens in the declaration). Sema enforces this separately by
// diagnosing anything else in the DeclSpec.
TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
TUK = DS.isFriendSpecified() ? TagUseKind::Friend : TagUseKind::Declaration;
if (Tok.isNot(tok::semi)) {
// A semicolon was missing after this declaration. Diagnose and recover.
ExpectAndConsume(tok::semi, diag::err_expected_after, "enum");
PP.EnterToken(Tok, /*IsReinject=*/true);
Tok.setKind(tok::semi);
}
} else {
TUK = Sema::TUK_Reference;
TUK = TagUseKind::Reference;
}

bool IsElaboratedTypeSpecifier =
TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend;
TUK == TagUseKind::Reference || TUK == TagUseKind::Friend;

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

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

if (!Name && TUK != Sema::TUK_Definition) {
if (!Name && TUK != TagUseKind::Definition) {
Diag(Tok, diag::err_enumerator_unnamed_no_def);

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

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

if (SkipBody.ShouldSkip) {
assert(TUK == Sema::TUK_Definition && "can only skip a definition");
assert(TUK == TagUseKind::Definition && "can only skip a definition");

BalancedDelimiterTracker T(*this, tok::l_brace);
T.consumeOpen();
Expand Down Expand Up @@ -5451,7 +5450,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
if (!TagDecl) {
// The action failed to produce an enumeration tag. If this is a
// definition, consume the entire definition.
if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
if (Tok.is(tok::l_brace) && TUK != TagUseKind::Reference) {
ConsumeBrace();
SkipUntil(tok::r_brace, StopAtSemi);
}
Expand All @@ -5460,7 +5459,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
return;
}

if (Tok.is(tok::l_brace) && TUK == Sema::TUK_Definition) {
if (Tok.is(tok::l_brace) && TUK == TagUseKind::Definition) {
Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
ParseEnumBody(StartLoc, D);
if (SkipBody.CheckSameAsPrevious &&
Expand Down
50 changes: 25 additions & 25 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1961,11 +1961,11 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
MaybeParseCXX11Attributes(Attributes);

const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
Sema::TagUseKind TUK;
TagUseKind TUK;
if (isDefiningTypeSpecifierContext(DSC, getLangOpts().CPlusPlus) ==
AllowDefiningTypeSpec::No ||
(getLangOpts().OpenMP && OpenMPDirectiveParsing))
TUK = Sema::TUK_Reference;
TUK = TagUseKind::Reference;
else if (Tok.is(tok::l_brace) ||
(DSC != DeclSpecContext::DSC_association &&
getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
Expand All @@ -1980,10 +1980,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// Skip everything up to the semicolon, so that this looks like a proper
// friend class (or template thereof) declaration.
SkipUntil(tok::semi, StopBeforeMatch);
TUK = Sema::TUK_Friend;
TUK = TagUseKind::Friend;
} else {
// Okay, this is a class definition.
TUK = Sema::TUK_Definition;
TUK = TagUseKind::Definition;
}
} else if (isClassCompatibleKeyword() &&
(NextToken().is(tok::l_square) ||
Expand Down Expand Up @@ -2024,15 +2024,15 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
}

if (Tok.isOneOf(tok::l_brace, tok::colon))
TUK = Sema::TUK_Definition;
TUK = TagUseKind::Definition;
else
TUK = Sema::TUK_Reference;
TUK = TagUseKind::Reference;

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

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

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

if (TUK == Sema::TUK_Friend) {
if (TUK == TagUseKind::Friend) {
Diag(DS.getFriendSpecLoc(), diag::err_friend_explicit_instantiation);
TemplateParams = nullptr;
} else {
Expand Down Expand Up @@ -2179,7 +2179,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
&SkipBody);
}
} else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
TUK == Sema::TUK_Declaration) {
TUK == TagUseKind::Declaration) {
// Explicit instantiation of a member of a class template
// specialization, e.g.,
//
Expand All @@ -2190,7 +2190,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
TagOrTempResult = Actions.ActOnExplicitInstantiation(
getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
TagType, StartLoc, SS, Name, NameLoc, attrs);
} else if (TUK == Sema::TUK_Friend &&
} else if (TUK == TagUseKind::Friend &&
TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
diag::err_keyword_not_allowed,
Expand All @@ -2202,12 +2202,12 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr,
TemplateParams ? TemplateParams->size() : 0));
} else {
if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition)
if (TUK != TagUseKind::Declaration && TUK != TagUseKind::Definition)
ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
diag::err_keyword_not_allowed,
/* DiagnoseEmptyAttrs=*/true);

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

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

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