[clang] Type safety tweak for AttributeCommonInfo::Form

This patch adds static functions for constructing most
AttributeCommonInfo::Forms.  Direct construction is only retained where
all fields (currently the syntax and spelling) are specified explicitly.

This is a wash on its own.  The purpose is to allow extra fields
to be added to Form without disrupting all callers.  In particular,
it allows extra information to be stored about keywords without
affecting non-keyword uses.

No functional change intended.

Differential Revision: https://reviews.llvm.org/D148104
This commit is contained in:
Richard Sandiford
2023-04-11 17:58:56 +01:00
parent 265d87e465
commit aec3f951bf
12 changed files with 47 additions and 32 deletions

View File

@@ -85,8 +85,7 @@ public:
/// including its syntax and spelling.
class Form {
public:
constexpr Form(Syntax SyntaxUsed,
unsigned SpellingIndex = SpellingNotCalculated)
constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex)
: SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex) {}
constexpr Form(tok::TokenKind)
: SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated) {}
@@ -94,7 +93,21 @@ public:
Syntax getSyntax() const { return Syntax(SyntaxUsed); }
unsigned getSpellingIndex() const { return SpellingIndex; }
static Form GNU() { return AS_GNU; }
static Form CXX11() { return AS_CXX11; }
static Form C2x() { return AS_C2x; }
static Form Declspec() { return AS_Declspec; }
static Form Microsoft() { return AS_Microsoft; }
static Form Keyword() { return AS_Keyword; }
static Form Pragma() { return AS_Pragma; }
static Form ContextSensitiveKeyword() { return AS_ContextSensitiveKeyword; }
static Form HLSLSemantic() { return AS_HLSLSemantic; }
static Form Implicit() { return AS_Implicit; }
private:
constexpr Form(Syntax SyntaxUsed)
: SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
unsigned SyntaxUsed : 4;
unsigned SpellingIndex : 4;
};

View File

@@ -748,7 +748,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
}
ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr,
nullptr, SourceLocation(), ParsedAttr::AS_GNU,
nullptr, SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
if (HasFunScope)
@@ -757,7 +757,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
// If there are multiple decls, then the decl cannot be within the
// function scope.
ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr,
nullptr, SourceLocation(), ParsedAttr::AS_GNU,
nullptr, SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
}
} else {

View File

@@ -214,14 +214,14 @@ void Parser::ParseGNUAttributes(ParsedAttributes &Attrs,
if (Tok.isNot(tok::l_paren)) {
Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
ParsedAttr::AS_GNU);
ParsedAttr::Form::GNU());
continue;
}
// Handle "parameterized" attributes
if (!LateAttrs || !isAttributeLateParsed(*AttrName)) {
ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc, nullptr,
SourceLocation(), ParsedAttr::AS_GNU, D);
SourceLocation(), ParsedAttr::Form::GNU(), D);
continue;
}
@@ -726,14 +726,14 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
if (!HasInvalidAccessor)
Attrs.addNewPropertyAttr(AttrName, AttrNameLoc, nullptr, SourceLocation(),
AccessorNames[AK_Get], AccessorNames[AK_Put],
ParsedAttr::AS_Declspec);
ParsedAttr::Form::Declspec());
T.skipToEnd();
return !HasInvalidAccessor;
}
unsigned NumArgs =
ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr,
SourceLocation(), ParsedAttr::AS_Declspec);
SourceLocation(), ParsedAttr::Form::Declspec());
// If this attribute's args were parsed, and it was expected to have
// arguments but none were provided, emit a diagnostic.
@@ -816,7 +816,7 @@ void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs) {
if (!AttrHandled)
Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
ParsedAttr::AS_Declspec);
ParsedAttr::Form::Declspec());
}
T.consumeClose();
EndLoc = T.getCloseLocation();

View File

@@ -4354,19 +4354,19 @@ bool Parser::ParseCXX11AttributeArgs(
assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");
SourceLocation LParenLoc = Tok.getLocation();
const LangOptions &LO = getLangOpts();
ParsedAttr::Syntax Syntax =
LO.CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x;
ParsedAttr::Form Form =
LO.CPlusPlus ? ParsedAttr::Form::CXX11() : ParsedAttr::Form::C2x();
// Try parsing microsoft attributes
if (getLangOpts().MicrosoftExt || getLangOpts().HLSL) {
if (hasAttribute(AttributeCommonInfo::Syntax::AS_Microsoft, ScopeName,
AttrName, getTargetInfo(), getLangOpts()))
Syntax = ParsedAttr::AS_Microsoft;
Form = ParsedAttr::Form::Microsoft();
}
// If the attribute isn't known, we will not attempt to parse any
// arguments.
if (Syntax != ParsedAttr::AS_Microsoft &&
if (Form.getSyntax() != ParsedAttr::AS_Microsoft &&
!hasAttribute(LO.CPlusPlus ? AttributeCommonInfo::Syntax::AS_CXX11
: AttributeCommonInfo::Syntax::AS_C2x,
ScopeName, AttrName, getTargetInfo(), getLangOpts())) {
@@ -4382,7 +4382,7 @@ bool Parser::ParseCXX11AttributeArgs(
// GNU-scoped attributes have some special cases to handle GNU-specific
// behaviors.
ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
ScopeLoc, Syntax, nullptr);
ScopeLoc, Form, nullptr);
return true;
}
@@ -4402,10 +4402,10 @@ bool Parser::ParseCXX11AttributeArgs(
// Some Clang-scoped attributes have some special parsing behavior.
if (ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang")))
NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
ScopeName, ScopeLoc, Form);
else
NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
ScopeName, ScopeLoc, Form);
if (!Attrs.empty() &&
IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
@@ -4555,7 +4555,8 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
AttrName,
SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc),
ScopeName, ScopeLoc, nullptr, 0,
getLangOpts().CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x);
getLangOpts().CPlusPlus ? ParsedAttr::Form::CXX11()
: ParsedAttr::Form::C2x());
AttrParsed = true;
}
@@ -4715,7 +4716,7 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
if (!T.consumeClose()) {
Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr,
SourceLocation(), ArgExprs.data(), ArgExprs.size(),
ParsedAttr::AS_Microsoft);
ParsedAttr::Form::Microsoft());
}
}
@@ -4771,7 +4772,7 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) {
}
if (!AttrParsed) {
Attrs.addNew(II, NameLoc, nullptr, SourceLocation(), nullptr, 0,
ParsedAttr::AS_Microsoft);
ParsedAttr::Form::Microsoft());
}
}
}

View File

@@ -196,5 +196,5 @@ void Parser::ParseHLSLSemantics(ParsedAttributes &Attrs,
}
Attrs.addNew(II, Loc, nullptr, SourceLocation(), ArgExprs.data(),
ArgExprs.size(), ParsedAttr::AS_HLSLSemantic);
ArgExprs.size(), ParsedAttr::Form::HLSLSemantic());
}

View File

@@ -408,7 +408,7 @@ static void addContextSensitiveTypeNullability(Parser &P,
auto getNullabilityAttr = [&](AttributePool &Pool) -> ParsedAttr * {
return Pool.create(P.getNullabilityKeyword(nullability),
SourceRange(nullabilityLoc), nullptr, SourceLocation(),
nullptr, 0, ParsedAttr::AS_ContextSensitiveKeyword);
nullptr, 0, ParsedAttr::Form::ContextSensitiveKeyword());
};
if (D.getNumTypeObjects() > 0) {

View File

@@ -1850,11 +1850,12 @@ void Parser::HandlePragmaAttribute() {
if (Tok.isNot(tok::l_paren))
Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
ParsedAttr::AS_GNU);
ParsedAttr::Form::GNU());
else
ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
/*ScopeName=*/nullptr,
/*ScopeLoc=*/SourceLocation(), ParsedAttr::AS_GNU,
/*ScopeLoc=*/SourceLocation(),
ParsedAttr::Form::GNU(),
/*Declarator=*/nullptr);
} while (TryConsumeToken(tok::comma));

View File

@@ -2411,7 +2411,7 @@ StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
ArgsUnion(Hint.ValueExpr)};
TempAttrs.addNew(Hint.PragmaNameLoc->Ident, Hint.Range, nullptr,
Hint.PragmaNameLoc->Loc, ArgHints, 4,
ParsedAttr::AS_Pragma);
ParsedAttr::Form::Pragma());
}
// Get the next statement.

View File

@@ -860,7 +860,7 @@ void Sema::AddCFAuditedAttribute(Decl *D) {
return;
AttributeCommonInfo Info(Ident, SourceRange(Loc),
AttributeCommonInfo::AS_Pragma);
AttributeCommonInfo::Form::Pragma());
D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info));
}

View File

@@ -19862,7 +19862,7 @@ void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name,
NamedDecl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc,
LookupOrdinaryName);
AttributeCommonInfo Info(AliasName, SourceRange(AliasNameLoc),
AttributeCommonInfo::AS_Pragma);
AttributeCommonInfo::Form::Pragma());
AsmLabelAttr *Attr = AsmLabelAttr::CreateImplicit(
Context, AliasName->getName(), /*IsLiteralLabel=*/true, Info);

View File

@@ -4893,12 +4893,12 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// If we're supposed to infer nullability, do so now.
if (inferNullability && !inferNullabilityInnerOnlyComplete) {
ParsedAttr::Syntax syntax = inferNullabilityCS
? ParsedAttr::AS_ContextSensitiveKeyword
: ParsedAttr::AS_Keyword;
ParsedAttr::Form form = inferNullabilityCS
? ParsedAttr::Form::ContextSensitiveKeyword()
: ParsedAttr::Form::Keyword();
ParsedAttr *nullabilityAttr = Pool.create(
S.getNullabilityKeyword(*inferNullability), SourceRange(pointerLoc),
nullptr, SourceLocation(), nullptr, 0, syntax);
nullptr, SourceLocation(), nullptr, 0, form);
attrs.addAtEnd(nullabilityAttr);
@@ -6014,7 +6014,7 @@ static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state,
ParsedAttr *attr = D.getAttributePool().create(
&S.Context.Idents.get("objc_ownership"), SourceLocation(),
/*scope*/ nullptr, SourceLocation(),
/*args*/ &Args, 1, ParsedAttr::AS_GNU);
/*args*/ &Args, 1, ParsedAttr::Form::GNU());
chunk.getAttrs().addAtEnd(attr);
// TODO: mark whether we did this inference?
}

View File

@@ -2621,7 +2621,7 @@ static void emitAttributes(RecordKeeper &Records, raw_ostream &OS,
OS << "NoSemaHandlerAttribute";
if (Spellings.size() == 0) {
OS << ", AttributeCommonInfo::AS_Implicit";
OS << ", AttributeCommonInfo::Form::Implicit()";
} else if (Spellings.size() == 1) {
OS << ", ";
emitFormInitializer(OS, Spellings[0], "0");