Skip to content

Commit 301eb6b

Browse files
committed
[clang] Add support for “regular” keyword attributes
Platform-specific language extensions often want to provide a way of indicating that certain functions should be called in a different way, compiled in a different way, or otherwise treated differently from a “normal” function. Honoring these indications is often required for correctness, rather being than an optimization/QoI thing. If a function declaration has a property P that matters for correctness, it will be ODR-incompatible with a function that does not have property P. If a function type has a property P that affects the calling convention, it will not be two-way compatible with a function type that does not have property P. These properties therefore affect language semantics. That in turn means that they cannot be treated as standard [[]] attributes. Until now, many of these properties have been specified using GNU-style attributes instead. GNU attributes have traditionally been more lax than standard attributes, with many of them having semantic meaning. Examples include calling conventions and the vector_size attribute. However, there is a big drawback to using GNU attributes for semantic information: compilers that don't understand the attributes will (by default) emit a warning rather than an error. They will go on to compile the code as though the attributes weren't present, which will inevitably lead to wrong code in most cases. For users who live dangerously and disable the warning, this wrong code could even be generated silently. A more robust approach would be to specify the properties using keywords, which older compilers would then reject. Some vendor-specific extensions have already taken this approach. But traditionally, each such keyword has been treated as a language extension in its own right. This has three major drawbacks: (1) The parsing rules need to be kept up-to-date as the language evolves. (2) There are often corner cases that similar extensions handle differently. (3) Each extension requires more custom code than a standard attribute. The underlying problem for all three is that, unlike for true attributes, there is no established template that extensions can reuse. The purpose of this patch series is to try to provide such a template. One option would have been to pick an existing keyword and do whatever that keyword does. The problem with that is that most keywords only apply to specific kinds of types, kinds of decls, etc., and so the parsing rules are (for good reason) not generally applicable to all types and decls. Really, the “only” thing wrong with using standard attributes is that standard attributes cannot affect semantics. In all other respects they provide exactly what we need: a well-defined grammar that evolves with the language, clear rules about what an attribute appertains to, and so on. This series therefore adds keyword “attributes” that can appear exactly where a standard attribute can appear and that appertain to exactly what a standard attribute would appertain to. The link is mechanical and no opt-outs or variations are allowed. This should make the keywords predictable for programmers who are already familiar with standard attributes. This does mean that these keywords will be accepted for parsing purposes in many more places than necessary. Inappropriate uses will then be diagnosed during semantic analysis. However, the compiler would need to reject the keywords in those positions whatever happens, and treating them as ostensible attributes shouldn't be any worse than the alternative. In some cases it might even be better. For example, SME's __arm_streaming attribute would make conceptual sense as a statement attribute, so someone who takes a “try-it-and-see” approach might write: __arm_streaming { …block-of-code…; } In fact, we did consider supporting this originally. The reason for rejecting it was that it was too difficult to implement, rather than because it didn't make conceptual sense. One slight disadvantage of the keyword-based approach is that it isn't possible to use #pragma clang attribute with the keywords. Perhaps we could add support for that in future, if it turns out to be useful. For want of a better term, I've called the new attributes "regular" keyword attributes (in the sense that their parsing is regular wrt standard attributes), as opposed to "custom" keyword attributes that have their own parsing rules. This patch adds the Attr.td support for regular keyword attributes. Adding an attribute with a RegularKeyword spelling causes tablegen to define the associated tokens and to record that attributes created with that syntax are regular keyword attributes rather than custom keyword attributes. A follow-on patch contains the main Parse and Sema support, which is enabled automatically by the Attr.td definition. Other notes: * The series does not allow regular keyword attributes to take arguments, but this could be added in future. * I wondered about trying to use tablegen for TypePrinter::printAttributedAfter too, but decided against it. RegularKeyword is really a spelling-level classification rather than an attribute-level classification, and in general, an attribute could have both GNU and RegularKeyword spellings. In contrast, printAttributedAfter is only given the attribute kind and the type that results from applying the attribute. AFAIK, it doesn't have access to the original attribute spelling. This means that some attribute-specific or type-specific knowledge might be needed to print the attribute in the best way. * Generating the tokens automatically from Attr.td means that pseudo's libgrammar does now depend on tablegen. * The patch uses the SME __arm_streaming attribute as an example for testing purposes. The attribute does not do anything at this stage. Later SME-specific patches will add proper semantics for it, and add other SME-related keyword attributes. Differential Revision: https://reviews.llvm.org/D148700
1 parent ac5c996 commit 301eb6b

File tree

18 files changed

+222
-53
lines changed

18 files changed

+222
-53
lines changed

clang-tools-extra/pseudo/lib/grammar/CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
set(LLVM_LINK_COMPONENTS Support)
22

3-
# This library is used by the clang-pseudo-gen tool which runs at build time.
4-
# Dependencies should be minimal to avoid long dep paths in the build graph.
5-
# It does use clangBasic headers (tok::TokenKind), but linking is not needed.
6-
# We have no transitive dependencies on tablegen files.
7-
list(REMOVE_ITEM LLVM_COMMON_DEPENDS clang-tablegen-targets)
83
add_clang_library(clangPseudoGrammar
94
Grammar.cpp
105
GrammarBNF.cpp

clang/docs/InternalsManual.rst

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2798,12 +2798,12 @@ and then the semantic handling of the attribute.
27982798
Parsing of the attribute is determined by the various syntactic forms attributes
27992799
can take, such as GNU, C++11, and Microsoft style attributes, as well as other
28002800
information provided by the table definition of the attribute. Ultimately, the
2801-
parsed representation of an attribute object is an ``ParsedAttr`` object.
2801+
parsed representation of an attribute object is a ``ParsedAttr`` object.
28022802
These parsed attributes chain together as a list of parsed attributes attached
28032803
to a declarator or declaration specifier. The parsing of attributes is handled
2804-
automatically by Clang, except for attributes spelled as keywords. When
2805-
implementing a keyword attribute, the parsing of the keyword and creation of the
2806-
``ParsedAttr`` object must be done manually.
2804+
automatically by Clang, except for attributes spelled as so-called “custom”
2805+
keywords. When implementing a custom keyword attribute, the parsing of the
2806+
keyword and creation of the ``ParsedAttr`` object must be done manually.
28072807

28082808
Eventually, ``Sema::ProcessDeclAttributeList()`` is called with a ``Decl`` and
28092809
a ``ParsedAttr``, at which point the parsed attribute can be transformed
@@ -2856,33 +2856,60 @@ may have a keyword spelling, as well as a C++11 spelling and a GNU spelling. An
28562856
empty spelling list is also permissible and may be useful for attributes which
28572857
are created implicitly. The following spellings are accepted:
28582858

2859-
============ ================================================================
2860-
Spelling Description
2861-
============ ================================================================
2862-
``GNU`` Spelled with a GNU-style ``__attribute__((attr))`` syntax and
2863-
placement.
2864-
``CXX11`` Spelled with a C++-style ``[[attr]]`` syntax with an optional
2865-
vendor-specific namespace.
2866-
``C2x`` Spelled with a C-style ``[[attr]]`` syntax with an optional
2867-
vendor-specific namespace.
2868-
``Declspec`` Spelled with a Microsoft-style ``__declspec(attr)`` syntax.
2869-
``Keyword`` The attribute is spelled as a keyword, and required custom
2870-
parsing.
2871-
``GCC`` Specifies two or three spellings: the first is a GNU-style
2872-
spelling, the second is a C++-style spelling with the ``gnu``
2873-
namespace, and the third is an optional C-style spelling with
2874-
the ``gnu`` namespace. Attributes should only specify this
2875-
spelling for attributes supported by GCC.
2876-
``Clang`` Specifies two or three spellings: the first is a GNU-style
2877-
spelling, the second is a C++-style spelling with the ``clang``
2878-
namespace, and the third is an optional C-style spelling with
2879-
the ``clang`` namespace. By default, a C-style spelling is
2880-
provided.
2881-
``Pragma`` The attribute is spelled as a ``#pragma``, and requires custom
2882-
processing within the preprocessor. If the attribute is meant to
2883-
be used by Clang, it should set the namespace to ``"clang"``.
2884-
Note that this spelling is not used for declaration attributes.
2885-
============ ================================================================
2859+
================== =========================================================
2860+
Spelling Description
2861+
================== =========================================================
2862+
``GNU`` Spelled with a GNU-style ``__attribute__((attr))``
2863+
syntax and placement.
2864+
``CXX11`` Spelled with a C++-style ``[[attr]]`` syntax with an
2865+
optional vendor-specific namespace.
2866+
``C2x`` Spelled with a C-style ``[[attr]]`` syntax with an
2867+
optional vendor-specific namespace.
2868+
``Declspec`` Spelled with a Microsoft-style ``__declspec(attr)``
2869+
syntax.
2870+
``CustomKeyword`` The attribute is spelled as a keyword, and requires
2871+
custom parsing.
2872+
``RegularKeyword`` The attribute is spelled as a keyword. It can be
2873+
used in exactly the places that the standard
2874+
``[[attr]]`` syntax can be used, and appertains to
2875+
exactly the same thing that a standard attribute
2876+
would appertain to. Lexing and parsing of the keyword
2877+
are handled automatically.
2878+
``GCC`` Specifies two or three spellings: the first is a
2879+
GNU-style spelling, the second is a C++-style spelling
2880+
with the ``gnu`` namespace, and the third is an optional
2881+
C-style spelling with the ``gnu`` namespace. Attributes
2882+
should only specify this spelling for attributes
2883+
supported by GCC.
2884+
``Clang`` Specifies two or three spellings: the first is a
2885+
GNU-style spelling, the second is a C++-style spelling
2886+
with the ``clang`` namespace, and the third is an
2887+
optional C-style spelling with the ``clang`` namespace.
2888+
By default, a C-style spelling is provided.
2889+
``Pragma`` The attribute is spelled as a ``#pragma``, and requires
2890+
custom processing within the preprocessor. If the
2891+
attribute is meant to be used by Clang, it should
2892+
set the namespace to ``"clang"``. Note that this
2893+
spelling is not used for declaration attributes.
2894+
================== =========================================================
2895+
2896+
The C++ standard specifies that “any [non-standard attribute] that is not
2897+
recognized by the implementation is ignored” (``[dcl.attr.grammar]``).
2898+
The rule for C is similar. This makes ``CXX11`` and ``C2x`` spellings
2899+
unsuitable for attributes that affect the type system, that change the
2900+
binary interface of the code, or that have other similar semantic meaning.
2901+
2902+
``RegularKeyword`` provides an alternative way of spelling such attributes.
2903+
It reuses the production rules for standard attributes, but it applies them
2904+
to plain keywords rather than to ``[[…]]`` sequences. Compilers that don't
2905+
recognize the keyword are likely to report an error of some kind.
2906+
2907+
For example, the ``ArmStreaming`` function type attribute affects
2908+
both the type system and the binary interface of the function.
2909+
It cannot therefore be spelled ``[[arm::streaming]]``, since compilers
2910+
that don't understand ``arm::streaming`` would ignore it and miscompile
2911+
the code. ``ArmStreaming`` is instead spelled ``__arm_streaming``, but it
2912+
can appear wherever a hypothetical ``[[arm::streaming]]`` could appear.
28862913

28872914
Subjects
28882915
~~~~~~~~

clang/include/clang/Basic/Attr.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,13 @@ class Keyword<string name, bit hasOwnParseRules>
315315
: Spelling<name, "Keyword"> {
316316
bit HasOwnParseRules = hasOwnParseRules;
317317
}
318+
319+
// A keyword that can appear wherever a standard attribute can appear,
320+
// and that appertains to whatever a standard attribute would appertain to.
321+
// This is useful for things that affect semantics but that should otherwise
322+
// be treated like standard attributes.
323+
class RegularKeyword<string name> : Keyword<name, 0> {}
324+
318325
// A keyword that has its own individual parsing rules.
319326
class CustomKeyword<string name> : Keyword<name, 1> {}
320327

@@ -2427,6 +2434,11 @@ def AArch64SVEPcs: DeclOrTypeAttr {
24272434
let Documentation = [AArch64SVEPcsDocs];
24282435
}
24292436

2437+
def ArmStreaming : TypeAttr, TargetSpecificAttr<TargetAArch64> {
2438+
let Spellings = [RegularKeyword<"__arm_streaming">];
2439+
let Documentation = [ArmStreamingDocs];
2440+
}
2441+
24302442
def Pure : InheritableAttr {
24312443
let Spellings = [GCC<"pure">];
24322444
let Documentation = [Undocumented];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6551,6 +6551,41 @@ Requirements on Development Tools - Engineering Specification Documentation
65516551
}];
65526552
}
65536553

6554+
def ArmStreamingDocs : Documentation {
6555+
let Category = DocCatType;
6556+
let Content = [{
6557+
.. Note:: This attribute has not been implemented yet, but once it is
6558+
implemented, it will behave as described below.
6559+
6560+
The ``__arm_streaming`` keyword is only available on AArch64 targets.
6561+
It applies to function types and specifies that the function has a
6562+
“streaming interface”. This means that:
6563+
6564+
* the function requires the Scalable Matrix Extension (SME)
6565+
6566+
* the function must be entered in streaming mode (that is, with PSTATE.SM
6567+
set to 1)
6568+
6569+
* the function must return in streaming mode
6570+
6571+
See `Procedure Call Standard for the Arm® 64-bit Architecture (AArch64)
6572+
<https://github.com/ARM-software/abi-aa>`_ for more details about
6573+
streaming-interface functions.
6574+
6575+
Clang manages PSTATE.SM automatically; it is not the source code's
6576+
responsibility to do this. For example, if a normal non-streaming
6577+
function calls an ``__arm_streaming`` function, Clang generates code
6578+
that switches into streaming mode before calling the function and
6579+
switches back to non-streaming mode on return.
6580+
6581+
``__arm_streaming`` can appear anywhere that a standard ``[[…]]`` type
6582+
attribute can appear.
6583+
6584+
See `Arm C Language Extensions <https://github.com/ARM-software/acle>`_
6585+
for more details about this extension, and for other related SME features.
6586+
}];
6587+
}
6588+
65546589
def AlwaysInlineDocs : Documentation {
65556590
let Category = DocCatFunction;
65566591
let Content = [{

clang/include/clang/Basic/AttributeCommonInfo.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class AttributeCommonInfo {
7777
unsigned SyntaxUsed : 4;
7878
unsigned SpellingIndex : 4;
7979
unsigned IsAlignas : 1;
80+
unsigned IsRegularKeywordAttribute : 1;
8081

8182
protected:
8283
static constexpr unsigned SpellingNotCalculated = 0xf;
@@ -86,24 +87,29 @@ class AttributeCommonInfo {
8687
/// including its syntax and spelling.
8788
class Form {
8889
public:
89-
constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex, bool IsAlignas)
90+
constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex, bool IsAlignas,
91+
bool IsRegularKeywordAttribute)
9092
: SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex),
91-
IsAlignas(IsAlignas) {}
93+
IsAlignas(IsAlignas),
94+
IsRegularKeywordAttribute(IsRegularKeywordAttribute) {}
9295
constexpr Form(tok::TokenKind Tok)
9396
: SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated),
94-
IsAlignas(Tok == tok::kw_alignas) {}
97+
IsAlignas(Tok == tok::kw_alignas),
98+
IsRegularKeywordAttribute(tok::isRegularKeywordAttribute(Tok)) {}
9599

96100
Syntax getSyntax() const { return Syntax(SyntaxUsed); }
97101
unsigned getSpellingIndex() const { return SpellingIndex; }
98102
bool isAlignas() const { return IsAlignas; }
103+
bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
99104

100105
static Form GNU() { return AS_GNU; }
101106
static Form CXX11() { return AS_CXX11; }
102107
static Form C2x() { return AS_C2x; }
103108
static Form Declspec() { return AS_Declspec; }
104109
static Form Microsoft() { return AS_Microsoft; }
105-
static Form Keyword(bool IsAlignas) {
106-
return Form(AS_Keyword, SpellingNotCalculated, IsAlignas);
110+
static Form Keyword(bool IsAlignas, bool IsRegularKeywordAttribute) {
111+
return Form(AS_Keyword, SpellingNotCalculated, IsAlignas,
112+
IsRegularKeywordAttribute);
107113
}
108114
static Form Pragma() { return AS_Pragma; }
109115
static Form ContextSensitiveKeyword() { return AS_ContextSensitiveKeyword; }
@@ -113,11 +119,12 @@ class AttributeCommonInfo {
113119
private:
114120
constexpr Form(Syntax SyntaxUsed)
115121
: SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated),
116-
IsAlignas(0) {}
122+
IsAlignas(0), IsRegularKeywordAttribute(0) {}
117123

118124
unsigned SyntaxUsed : 4;
119125
unsigned SpellingIndex : 4;
120126
unsigned IsAlignas : 1;
127+
unsigned IsRegularKeywordAttribute : 1;
121128
};
122129

123130
AttributeCommonInfo(const IdentifierInfo *AttrName,
@@ -127,7 +134,8 @@ class AttributeCommonInfo {
127134
ScopeLoc(ScopeLoc), AttrKind(AttrKind),
128135
SyntaxUsed(FormUsed.getSyntax()),
129136
SpellingIndex(FormUsed.getSpellingIndex()),
130-
IsAlignas(FormUsed.isAlignas()) {
137+
IsAlignas(FormUsed.isAlignas()),
138+
IsRegularKeywordAttribute(FormUsed.isRegularKeywordAttribute()) {
131139
assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
132140
"Invalid syntax!");
133141
}
@@ -154,7 +162,10 @@ class AttributeCommonInfo {
154162

155163
Kind getParsedKind() const { return Kind(AttrKind); }
156164
Syntax getSyntax() const { return Syntax(SyntaxUsed); }
157-
Form getForm() const { return Form(getSyntax(), SpellingIndex, IsAlignas); }
165+
Form getForm() const {
166+
return Form(getSyntax(), SpellingIndex, IsAlignas,
167+
IsRegularKeywordAttribute);
168+
}
158169
const IdentifierInfo *getAttrName() const { return AttrName; }
159170
SourceLocation getLoc() const { return AttrRange.getBegin(); }
160171
SourceRange getRange() const { return AttrRange; }
@@ -191,6 +202,8 @@ class AttributeCommonInfo {
191202
return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
192203
}
193204

205+
bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
206+
194207
bool isContextSensitiveKeywordAttribute() const {
195208
return SyntaxUsed == AS_ContextSensitiveKeyword;
196209
}

clang/include/clang/Basic/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ clang_tablegen(AttrSubMatchRulesList.inc -gen-clang-attr-subject-match-rule-list
3535
SOURCE Attr.td
3636
TARGET ClangAttrSubjectMatchRuleList)
3737

38+
clang_tablegen(AttrTokenKinds.inc -gen-clang-attr-token-kinds
39+
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
40+
SOURCE Attr.td
41+
TARGET ClangAttrTokenKinds
42+
)
43+
3844
clang_tablegen(AttrHasAttributeImpl.inc -gen-clang-attr-has-attribute-impl
3945
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
4046
SOURCE Attr.td

clang/include/clang/Basic/TokenKinds.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,12 @@ KEYWORD(__builtin_bit_cast , KEYALL)
748748
KEYWORD(__builtin_available , KEYALL)
749749
KEYWORD(__builtin_sycl_unique_stable_name, KEYSYCL)
750750

751+
// Keywords defined by Attr.td.
752+
#ifndef KEYWORD_ATTRIBUTE
753+
#define KEYWORD_ATTRIBUTE(X) KEYWORD(X, KEYALL)
754+
#endif
755+
#include "clang/Basic/AttrTokenKinds.inc"
756+
751757
// Clang-specific keywords enabled only in testing.
752758
TESTING_KEYWORD(__unknown_anytype , KEYALL)
753759

clang/include/clang/Basic/TokenKinds.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ bool isAnnotation(TokenKind K);
9999
/// Return true if this is an annotation token representing a pragma.
100100
bool isPragmaAnnotation(TokenKind K);
101101

102+
inline constexpr bool isRegularKeywordAttribute(TokenKind K) {
103+
return (false
104+
#define KEYWORD_ATTRIBUTE(X) || (K == tok::kw_##X)
105+
#include "clang/Basic/AttrTokenKinds.inc"
106+
);
107+
}
108+
102109
} // end namespace tok
103110
} // end namespace clang
104111

clang/include/clang/Lex/Token.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,13 @@ class Token {
117117
}
118118

119119
/// Return true if this is any of tok::annot_* kind tokens.
120-
bool isAnnotation() const {
121-
return tok::isAnnotation(getKind());
120+
bool isAnnotation() const { return tok::isAnnotation(getKind()); }
121+
122+
/// Return true if the token is a keyword that is parsed in the same
123+
/// position as a standard attribute, but that has semantic meaning
124+
/// and so cannot be a true attribute.
125+
bool isRegularKeywordAttribute() const {
126+
return tok::isRegularKeywordAttribute(getKind());
122127
}
123128

124129
/// Return a source location identifier for the specified

clang/lib/AST/TypePrinter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,11 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
17571757
return;
17581758
}
17591759

1760+
if (T->getAttrKind() == attr::ArmStreaming) {
1761+
OS << "__arm_streaming";
1762+
return;
1763+
}
1764+
17601765
OS << " __attribute__((";
17611766
switch (T->getAttrKind()) {
17621767
#define TYPE_ATTR(NAME)
@@ -1797,6 +1802,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
17971802
case attr::CmseNSCall:
17981803
case attr::AnnotateType:
17991804
case attr::WebAssemblyFuncref:
1805+
case attr::ArmStreaming:
18001806
llvm_unreachable("This attribute should have been handled already");
18011807

18021808
case attr::NSReturnsRetained:

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5328,6 +5328,9 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
53285328
case ParsedAttr::AT_AArch64SVEPcs:
53295329
CC = CC_AArch64SVEPCS;
53305330
break;
5331+
case ParsedAttr::AT_ArmStreaming:
5332+
CC = CC_C; // FIXME: placeholder until real SME support is added.
5333+
break;
53315334
case ParsedAttr::AT_AMDGPUKernelCall:
53325335
CC = CC_AMDGPUKernelCall;
53335336
break;

clang/lib/Sema/SemaType.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr,
126126
case ParsedAttr::AT_VectorCall: \
127127
case ParsedAttr::AT_AArch64VectorPcs: \
128128
case ParsedAttr::AT_AArch64SVEPcs: \
129+
case ParsedAttr::AT_ArmStreaming: \
129130
case ParsedAttr::AT_AMDGPUKernelCall: \
130131
case ParsedAttr::AT_MSABI: \
131132
case ParsedAttr::AT_SysVABI: \
@@ -4895,8 +4896,10 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
48954896
// If we're supposed to infer nullability, do so now.
48964897
if (inferNullability && !inferNullabilityInnerOnlyComplete) {
48974898
ParsedAttr::Form form =
4898-
inferNullabilityCS ? ParsedAttr::Form::ContextSensitiveKeyword()
4899-
: ParsedAttr::Form::Keyword(false /*IsAlignAs*/);
4899+
inferNullabilityCS
4900+
? ParsedAttr::Form::ContextSensitiveKeyword()
4901+
: ParsedAttr::Form::Keyword(false /*IsAlignAs*/,
4902+
false /*IsRegularKeywordAttribute*/);
49004903
ParsedAttr *nullabilityAttr = Pool.create(
49014904
S.getNullabilityKeyword(*inferNullability), SourceRange(pointerLoc),
49024905
nullptr, SourceLocation(), nullptr, 0, form);
@@ -7710,6 +7713,8 @@ static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) {
77107713
return createSimpleAttr<AArch64VectorPcsAttr>(Ctx, Attr);
77117714
case ParsedAttr::AT_AArch64SVEPcs:
77127715
return createSimpleAttr<AArch64SVEPcsAttr>(Ctx, Attr);
7716+
case ParsedAttr::AT_ArmStreaming:
7717+
return createSimpleAttr<ArmStreamingAttr>(Ctx, Attr);
77137718
case ParsedAttr::AT_AMDGPUKernelCall:
77147719
return createSimpleAttr<AMDGPUKernelCallAttr>(Ctx, Attr);
77157720
case ParsedAttr::AT_Pcs: {

0 commit comments

Comments
 (0)