diff options
author | Mike Rice <michael.p.rice@intel.com> | 2024-07-30 10:07:16 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-30 10:07:16 -0700 |
commit | 2acf77f987331c05520c5bfd849326909ffce983 (patch) | |
tree | 29b3bd05a41f54f18157dc734b16d9db8e3f8b71 /clang/lib/Parse/ParseDecl.cpp | |
parent | 39b6900852e7a1187bd742ba5c1387ca1be58e2c (diff) | |
download | llvm-2acf77f987331c05520c5bfd849326909ffce983.zip llvm-2acf77f987331c05520c5bfd849326909ffce983.tar.gz llvm-2acf77f987331c05520c5bfd849326909ffce983.tar.bz2 |
[clang] Update argument checking tablegen code to use a 'full' name (#99993)
In 92fc1eb0c1ae3813f2ac9208e2c74207aae9d23 the HLSLLoopHint attribute
was added with an 'unroll' spelling. There is an existing LoopHint
attribute with the same spelling. These attributes have different
arguments.
The tablegen used to produce checks on arguments uses only the attribute
name, making it impossible to return correct info for attribute with
different argument types but the same name.
Improve the situation by using a 'full' name that combines the syntax,
scope, and name. This allows, for example, #pragma unroll and
[[unroll(x)]] to coexist correctly even with different argument types.
Also fix a bug in the StrictEnumParameters tablegen. If will now
correctly specify each parameter instead of only the first.
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 114 |
1 files changed, 79 insertions, 35 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 8d7d37c..4a2d9a6 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -314,64 +314,92 @@ void Parser::ParseGNUAttributes(ParsedAttributes &Attrs, } /// Determine whether the given attribute has an identifier argument. -static bool attributeHasIdentifierArg(const IdentifierInfo &II) { +static bool attributeHasIdentifierArg(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_IDENTIFIER_ARG_LIST - return llvm::StringSwitch<bool>(normalizeAttrName(II.getName())) + return llvm::StringSwitch<bool>(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" - .Default(false); + .Default(false); #undef CLANG_ATTR_IDENTIFIER_ARG_LIST } /// Determine whether the given attribute has an identifier argument. static ParsedAttributeArgumentsProperties -attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II) { +attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_STRING_LITERAL_ARG_LIST - return llvm::StringSwitch<uint32_t>(normalizeAttrName(II.getName())) + return llvm::StringSwitch<uint32_t>(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" .Default(0); #undef CLANG_ATTR_STRING_LITERAL_ARG_LIST } /// Determine whether the given attribute has a variadic identifier argument. -static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II) { +static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST - return llvm::StringSwitch<bool>(normalizeAttrName(II.getName())) + return llvm::StringSwitch<bool>(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" - .Default(false); + .Default(false); #undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST } /// Determine whether the given attribute treats kw_this as an identifier. -static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II) { +static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST - return llvm::StringSwitch<bool>(normalizeAttrName(II.getName())) + return llvm::StringSwitch<bool>(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" - .Default(false); + .Default(false); #undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST } /// Determine if an attribute accepts parameter packs. -static bool attributeAcceptsExprPack(const IdentifierInfo &II) { +static bool attributeAcceptsExprPack(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_ACCEPTS_EXPR_PACK - return llvm::StringSwitch<bool>(normalizeAttrName(II.getName())) + return llvm::StringSwitch<bool>(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" .Default(false); #undef CLANG_ATTR_ACCEPTS_EXPR_PACK } /// Determine whether the given attribute parses a type argument. -static bool attributeIsTypeArgAttr(const IdentifierInfo &II) { +static bool attributeIsTypeArgAttr(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_TYPE_ARG_LIST - return llvm::StringSwitch<bool>(normalizeAttrName(II.getName())) + return llvm::StringSwitch<bool>(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" - .Default(false); + .Default(false); #undef CLANG_ATTR_TYPE_ARG_LIST } /// Determine whether the given attribute takes identifier arguments. -static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II) { +static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST - return (llvm::StringSwitch<uint64_t>(normalizeAttrName(II.getName())) + return (llvm::StringSwitch<uint64_t>(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" .Default(0)) != 0; #undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST @@ -380,9 +408,13 @@ static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II) { /// Determine whether the given attribute takes an identifier argument at a /// specific index static bool attributeHasStrictIdentifierArgAtIndex(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName, size_t argIndex) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST - return (llvm::StringSwitch<uint64_t>(normalizeAttrName(II.getName())) + return (llvm::StringSwitch<uint64_t>(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" .Default(0)) & (1ull << argIndex); @@ -391,11 +423,15 @@ static bool attributeHasStrictIdentifierArgAtIndex(const IdentifierInfo &II, /// Determine whether the given attribute requires parsing its arguments /// in an unevaluated context or not. -static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II) { +static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II, + ParsedAttr::Syntax Syntax, + IdentifierInfo *ScopeName) { + std::string FullName = + AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax); #define CLANG_ATTR_ARG_CONTEXT_LIST - return llvm::StringSwitch<bool>(normalizeAttrName(II.getName())) + return llvm::StringSwitch<bool>(FullName) #include "clang/Parse/AttrParserStringSwitches.inc" - .Default(false); + .Default(false); #undef CLANG_ATTR_ARG_CONTEXT_LIST } @@ -523,10 +559,12 @@ unsigned Parser::ParseAttributeArgsCommon( // Ignore the left paren location for now. ConsumeParen(); - bool ChangeKWThisToIdent = attributeTreatsKeywordThisAsIdentifier(*AttrName); - bool AttributeIsTypeArgAttr = attributeIsTypeArgAttr(*AttrName); + bool ChangeKWThisToIdent = attributeTreatsKeywordThisAsIdentifier( + *AttrName, Form.getSyntax(), ScopeName); + bool AttributeIsTypeArgAttr = + attributeIsTypeArgAttr(*AttrName, Form.getSyntax(), ScopeName); bool AttributeHasVariadicIdentifierArg = - attributeHasVariadicIdentifierArg(*AttrName); + attributeHasVariadicIdentifierArg(*AttrName, Form.getSyntax(), ScopeName); // Interpret "kw_this" as an identifier if the attributed requests it. if (ChangeKWThisToIdent && Tok.is(tok::kw_this)) @@ -535,8 +573,9 @@ unsigned Parser::ParseAttributeArgsCommon( ArgsVector ArgExprs; if (Tok.is(tok::identifier)) { // If this attribute wants an 'identifier' argument, make it so. - bool IsIdentifierArg = AttributeHasVariadicIdentifierArg || - attributeHasIdentifierArg(*AttrName); + bool IsIdentifierArg = + AttributeHasVariadicIdentifierArg || + attributeHasIdentifierArg(*AttrName, Form.getSyntax(), ScopeName); ParsedAttr::Kind AttrKind = ParsedAttr::getParsedKind(AttrName, ScopeName, Form.getSyntax()); @@ -568,7 +607,8 @@ unsigned Parser::ParseAttributeArgsCommon( if (T.isUsable()) TheParsedType = T.get(); } else if (AttributeHasVariadicIdentifierArg || - attributeHasStrictIdentifierArgs(*AttrName)) { + attributeHasStrictIdentifierArgs(*AttrName, Form.getSyntax(), + ScopeName)) { // Parse variadic identifier arg. This can either consume identifiers or // expressions. Variadic identifier args do not support parameter packs // because those are typically used for attributes with enumeration @@ -579,8 +619,9 @@ unsigned Parser::ParseAttributeArgsCommon( if (ChangeKWThisToIdent && Tok.is(tok::kw_this)) Tok.setKind(tok::identifier); - if (Tok.is(tok::identifier) && attributeHasStrictIdentifierArgAtIndex( - *AttrName, ArgExprs.size())) { + if (Tok.is(tok::identifier) && + attributeHasStrictIdentifierArgAtIndex( + *AttrName, Form.getSyntax(), ScopeName, ArgExprs.size())) { ArgExprs.push_back(ParseIdentifierLoc()); continue; } @@ -589,7 +630,8 @@ unsigned Parser::ParseAttributeArgsCommon( if (Tok.is(tok::identifier)) { ArgExprs.push_back(ParseIdentifierLoc()); } else { - bool Uneval = attributeParsedArgsUnevaluated(*AttrName); + bool Uneval = attributeParsedArgsUnevaluated( + *AttrName, Form.getSyntax(), ScopeName); EnterExpressionEvaluationContext Unevaluated( Actions, Uneval ? Sema::ExpressionEvaluationContext::Unevaluated @@ -610,7 +652,8 @@ unsigned Parser::ParseAttributeArgsCommon( } while (TryConsumeToken(tok::comma)); } else { // General case. Parse all available expressions. - bool Uneval = attributeParsedArgsUnevaluated(*AttrName); + bool Uneval = attributeParsedArgsUnevaluated(*AttrName, Form.getSyntax(), + ScopeName); EnterExpressionEvaluationContext Unevaluated( Actions, Uneval ? Sema::ExpressionEvaluationContext::Unevaluated @@ -621,7 +664,8 @@ unsigned Parser::ParseAttributeArgsCommon( ExprVector ParsedExprs; ParsedAttributeArgumentsProperties ArgProperties = - attributeStringLiteralListArg(getTargetInfo().getTriple(), *AttrName); + attributeStringLiteralListArg(getTargetInfo().getTriple(), *AttrName, + Form.getSyntax(), ScopeName); if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) { SkipUntil(tok::r_paren, StopAtSemi); return 0; @@ -632,7 +676,7 @@ unsigned Parser::ParseAttributeArgsCommon( if (!isa<PackExpansionExpr>(ParsedExprs[I])) continue; - if (!attributeAcceptsExprPack(*AttrName)) { + if (!attributeAcceptsExprPack(*AttrName, Form.getSyntax(), ScopeName)) { Diag(Tok.getLocation(), diag::err_attribute_argument_parm_pack_not_supported) << AttrName; @@ -696,7 +740,7 @@ void Parser::ParseGNUAttributeArgs( ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ScopeLoc, Form); return; - } else if (attributeIsTypeArgAttr(*AttrName)) { + } else if (attributeIsTypeArgAttr(*AttrName, Form.getSyntax(), ScopeName)) { ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc, Form); return; |