[PATCH] D157270: [Clang][AArch64] Add diagnostic for calls from non-ZA to shared-ZA functions.

2023-08-07 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/test/Sema/aarch64-sme-func-attrs.c:181
 
+void non_za_definition(void) {
+  sme_arm_new_za(); // OK

sdesmalen wrote:
> rsandifo-arm wrote:
> > sdesmalen wrote:
> > > rsandifo-arm wrote:
> > > > Would be good to have some tests for indirect function calls too (via 
> > > > function pointers), to make sure that the diagnostic still works when 
> > > > no decl is available.
> > > > 
> > > > I suppose this applies to D157269 too.
> > > I'm not sure that's necessary because D127762 already added tests to 
> > > ensure the attributes propagate on pointer types, which then sets the 
> > > ExtProtoInfo for those values. This patch merely checks the SME attribute 
> > > fields from ExtProtoInfo. i.e. there is already nothing depending on a 
> > > declaration being available.
> > But `Sema::checkCall` does have some tests that depend on the decl rather 
> > than the type.  So the purpose of the test wouldn't be “does the attribute 
> > stick when applied to indirect function types?” (which I agree is already 
> > covered), but “does the new code correctly process the attribute on the 
> > target of a function pointer type?”
> The declaration is only relevant for the call-site, not the callee.
> 
>   if (ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateZASharedMask) {
> 
> The above line checks __arm_shared_za attribute of the callee (could be a 
> decl, or a function pointer, but in either case is a prototyped function with 
> the propagated attributes)
> 
>   if (auto *CallerFD = dyn_cast(CurContext)) {
> 
> The above line checks if the call-site context is a FunctionDecl (or 
> definition for that matter). If the call is not part of a declaration (e.g. 
> it's part of some global initialiser), we know it cannot have any live ZA 
> state (which I now realise is missing a test-case).
> 
> So I think that a test like this:
> 
>   __arm_new_za void foo(void (*f)() __arm_shared_za) { f(); }
> 
> is not testing anything that isn't already tested. But perhaps I'm still 
> misunderstanding your point. If so, could you give an example of a test you 
> have in mind?
That's the kind of test I had in mind.

checkCall does have some conditions that are based on the callee decl rather 
than the callee type.  That is, it does distinguish between direct calls and 
indirect calls.  It would have been easy for the code to be in a block that was 
guarded with FDecl.  Or it could be accidentally rearranged like that in 
future, especially if the function grows to have several more tests.

And yeah, I agree that the code as-written works, and so it doesn't fall into 
the trap that is being tested for.  But that's true of most tests that get 
written for new features. :)

So a test for both the direct and indirect cases seemed worthwhile.  If we were 
just going to have one, then I think testing the indirect case is more valuable 
than testing the direct case, since it's the type rather than the decl that 
matters.

I won't press the point further though.  Feel free to skip the comment if you'd 
rather keep the tests as they are.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157270/new/

https://reviews.llvm.org/D157270

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157269: [Clang][AArch64] Diagnostics for SME attributes when target doesn't have 'sme'

2023-08-07 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp:20
+
+// No code is generated for declarations, so it should be fine to declare 
using the attribute.
+void streaming_compatible_decl() __arm_streaming_compatible; // OK

aaron.ballman wrote:
> Is this a requirement of the specification? I guess I was surprised we're 
> going to these lengths rather than diagnosing the attribute in 
> SemaDeclAttr.cpp when sme is not enabled.
Yeah.  The problem is that it's possible (and reasonable!) to enable SME for 
only part of a translation unit.  E.g. an ifunc might have SME and non-SME 
implementations, with those implementations being in the same translation unit. 
 Things like the `target` and `target_version` attributes exist to allow this.

A function that's compiled with SME enabled might want to call streaming 
functions.  There therefore needs to be a way of declaring streaming functions 
without assuming that the whole TU is SME.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157269/new/

https://reviews.llvm.org/D157269

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157269: [Clang][AArch64] Diagnostics for SME attributes when target doesn't have 'sme'

2023-08-07 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

LGTM in terms of intent.




Comment at: clang/lib/Sema/SemaDecl.cpp:12092
+   diag::err_sme_definition_using_sm_in_non_sme_target);
+if (UsesZA)
+  Diag(NewFD->getLocation(),

Suggest making this an `else if`.  We only need to give one error for a call to 
a streaming shared-ZA function, since the underlying error is the same.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157269/new/

https://reviews.llvm.org/D157269

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157270: [Clang][AArch64] Add diagnostic for calls from non-ZA to shared-ZA functions.

2023-08-07 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/test/Sema/aarch64-sme-func-attrs.c:181
 
+void non_za_definition(void) {
+  sme_arm_new_za(); // OK

sdesmalen wrote:
> rsandifo-arm wrote:
> > Would be good to have some tests for indirect function calls too (via 
> > function pointers), to make sure that the diagnostic still works when no 
> > decl is available.
> > 
> > I suppose this applies to D157269 too.
> I'm not sure that's necessary because D127762 already added tests to ensure 
> the attributes propagate on pointer types, which then sets the ExtProtoInfo 
> for those values. This patch merely checks the SME attribute fields from 
> ExtProtoInfo. i.e. there is already nothing depending on a declaration being 
> available.
But `Sema::checkCall` does have some tests that depend on the decl rather than 
the type.  So the purpose of the test wouldn't be “does the attribute stick 
when applied to indirect function types?” (which I agree is already covered), 
but “does the new code correctly process the attribute on the target of a 
function pointer type?”


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157270/new/

https://reviews.llvm.org/D157270

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D127762: [Clang][AArch64] Add/implement ACLE keywords for SME.

2023-08-07 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm accepted this revision.
rsandifo-arm added a comment.

LGTM too, thanks.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127762/new/

https://reviews.llvm.org/D127762

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157270: [Clang][AArch64] Add diagnostic for calls from non-ZA to shared-ZA functions.

2023-08-07 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:6737
+else if (const auto *FPT = 
CallerFD->getType()->getAs())
+  CallerHasZAState |= FPT->getExtProtoInfo().AArch64SMEAttributes &
+  FunctionType::SME_PStateZASharedMask;

Very minor, but it looked odd to me to have `|=` in this statement and `=` 
above.



Comment at: clang/test/Sema/aarch64-sme-func-attrs.c:181
 
+void non_za_definition(void) {
+  sme_arm_new_za(); // OK

Would be good to have some tests for indirect function calls too (via function 
pointers), to make sure that the diagnostic still works when no decl is 
available.

I suppose this applies to D157269 too.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157270/new/

https://reviews.llvm.org/D157270

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157269: [Clang][AArch64] Diagnostics for SME attributes when target doesn't have 'sme'

2023-08-07 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

The intent looks good to me, but I'm not in a position to approve.  Very 
pedantic, sorry, but on the description, I think:

> Calls from non-streaming functions to streaming-functions require the 
> compiler to enable/disable streaming-SVE mode around the call-site.

would be more accurate as:

> Calls from non-streaming **mode** to streaming functions…

since it applies to calls from streaming-compatible functions too.  (Which is 
what the patch implements.)




Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:3629
+  "call to a streaming function requires sme">;
+def err_sme_definition_in_non_sme_target : Error<
+  "function executed in streaming-SVE mode or using ZA state, requires sme">;

Seems like we can easily split this into two and distinguish the cases, since 
the code that gives the error can always tell which case applies.  I think not 
having SME for streaming mode is logically more fundamental than not having SME 
for ZA.

I think `sme` should be SME (if it's referring to the ISA feature) or should be 
quoted (if it's referring to the feature syntax).



Comment at: clang/lib/Sema/SemaChecking.cpp:6631
 
 /// Handles the checks for format strings, non-POD arguments to vararg
 /// functions, NULL arguments passed to non-NULL parameters, and diagnose_if

I don't know the code well enough to know whether this is the right place to 
check this.  if it is, though, I suppose the comment needs to be updated too.

I agree the intention looks right from a spec POV.



Comment at: clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp:29
+
+void streaming_compatible_def2() {
+  non_streaming_decl(); // OK

Looks like this was intended to be `__arm_streaming_compatible`.



Comment at: llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td:158
+
+  // Rather than only allowing this instruction with '+sme', we also
+  // allow it with '+sve', such that we can still emit the instruction

I don't think even SVE is required.  A function like:
```
void foo() __arm_streaming_compatible {
   printf ("Hello, world!\n");
}
```
should be OK for base Armv8-A.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157269/new/

https://reviews.llvm.org/D157269

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139028: [RFC][clang] Add attribute-like keywords

2023-08-07 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm abandoned this revision.
rsandifo-arm added a comment.

Superceded by D148700 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139028/new/

https://reviews.llvm.org/D139028

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D127762: [Clang][AArch64] Add/implement ACLE keywords for SME.

2023-08-03 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Thanks for dropping the attribute requirements down to TargetAArch64.  But the 
offsetting requirement was that something somewhere (CodeGen?) must raise an 
error if code requires SME and SME isn't present.  I think that means:

1. SME is not enabled for an `__arm_streaming` or `__arm_locally_streaming` 
function definition.
2. SME is not enabled for a call to an `__arm_streaming` function.
3. SME is not enabled for an `__arm_shared_za` or `__arm_new_za` function 
definition.

(Calls to `__arm_shared_za` functions don't need to be listed explicitly, since 
only `__arm_shared_za` and `__arm_new_za` functions can make such calls.)

In all cases, the check would apply after `__attribute__((target_version))` is 
taken into account.

Perhaps that's a separate patch though.




Comment at: clang/include/clang/Basic/AttrDocs.td:6645
+responsibility to do this.  Clang will ensure that the generated code in
+streaming-compatible functions is valid in either mode (PSTATE.SM=0 or
+PSTATE.SM=1). For example, if an ``__arm_streaming_compatible`` function calls 
a





Comment at: clang/test/Sema/aarch64-sme-func-attrs.c:186
+struct S2_2 : public S {
+// expected-cpp-error@+2 {{virtual function 'shared_za_memberfn' has different 
attributes ('void () __arm_shared_za __arm_preserves_za') than the function it 
overrides (which has 'void () __arm_shared_za')}}
+// expected-cpp-note@-11 {{overridden virtual function is here}}

Thanks, this is indeed the case I was suggesting to test.  But my point was 
that it shouldn't be an error.  It's OK for an override to be 
`__arm_preserves_za` even if the function it overrides isn't.  Something that 
calls `shared_za_member` directly from an `S2_2` object can take advantage of 
the extra guarantee.

It's the other way that's wrong.  If a virtual function is `__arm_preserves_za` 
then any override must be too.

The principle is similar to covariant return types. E.g.:
```
struct S1 { virtual S1 *f(); };
struct S2 : S1 { S2 *f() override; }; // OK
struct S3 : S2 { S2 *f() override; }; // OK
struct S4 : S3 { S1 *f() override; }; // Error
```
An `__arm_preserves_za` function acts like functions that return `S2 *` in this 
example, and a non-`__arm_preserves_za` function acts like functions that 
return `S1 *`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127762/new/

https://reviews.llvm.org/D127762

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D127762: [Clang][AArch64] Add/implement ACLE keywords for SME.

2023-08-02 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Mostly LGTM from a spec POV, but some comments below.




Comment at: clang/include/clang/Basic/Attr.td:2439
 
 def ArmStreaming : TypeAttr, TargetSpecificAttr {
   let Spellings = [RegularKeyword<"__arm_streaming">];

In current main, this attribute is gated on TargetAArch64 rather than 
TargetAArch64SME.  The reason is that, from a QoI point of view, I don't think 
we should require the `+sme` extension in order to accept an `__arm_streaming` 
type.  `+sme` is instead required to compile a function with `__arm_streaming` 
type, or a call to a function with `__arm_streaming` type.  IMO those are more 
CodeGen rather than Sema restrictions.

E.g., if a header file contains
```
void sme_foo(void) __arm_streaming;
```
then an `__attribute__((target_version("sme")))` function should be able to 
call it.  But we shouldn't require `+sme` to be passed on the command line in 
order to compile the declaration of `sme_foo`.

I think the same principle applies to the other function-type attributes.  In 
particular, `__arm_preserves_za` functions and `__arm_streaming_compatible` 
functions do not require SME to be present.

I think we should also allow:
```
__arm_locally_streaming void __attribute__((target_version("sme"))) ifunc() { … 
}
```
since `__arm_locally_streaming` does not change the function signature.

So I think all of these attributes should be gated on TargetAArch64, with 
checks for SME made elsewhere where necessary.

(Unfortunately, since command-line options are out of scope for ACLE, I don't 
think it can really specify this.)



Comment at: clang/include/clang/Basic/AttrDocs.td:6588
 
-* the function requires the Scalable Matrix Extension (SME)
+* the function requires that the target processor implements the Scalable 
Matrix
+  Extension (SME).

The bullet was trying to describe the function's ABI.  I don't think “target” 
is appropriate in an ABI context (where you might be describing a binary that 
already exists, rather than a compilation).  So I've a slight preference for 
dropping “target”.

I see in another comment, Erich made a distinction between “target” and 
“run-time”.  If we do use one or the other, I think “run-time” is more correct.

“target” is right for `__arm_locally_streaming` and `__arm_new_za` though.



Comment at: clang/include/clang/Basic/AttrDocs.td:6623
+
+* the function may be entered in either normal mode (PSTATE.SM=0) or
+  in streaming mode (PSTATE.SM=1).

How about “non-streaming” rather than “normal”?



Comment at: clang/include/clang/Basic/AttrDocs.td:6626
+
+* the function must return in the same mode in which it entered the function.
+





Comment at: clang/include/clang/Basic/AttrDocs.td:
+
+* the function returns with ZA in an active state for normal returns.
+

The other type attributes also only describe normal returns.



Comment at: clang/include/clang/Basic/AttrDocs.td:6738
+
+* the function will commit any lazy-saves if available.
+

Just trying to avoid “if available”, since the saves aren't being provided for 
the benefit of anyone else.  Feel free to reword to something else.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:3608-3609
+def err_sme_attr_mismatch : Error<
+  "function declared '%0' was previously declared '%1'"
+  " with different SME function attributes">;
 def err_cconv_change : Error<





Comment at: clang/lib/AST/Type.cpp:3559
   //  bool*
   // Finally, we have the ext info and trailing return type flag:
   //  int bool

This comment probably needs updating for the new field, although the comment 
already seems pretty out of date.  (It looks like the separate bool was removed 
in 2011.)

I suppose the new field doesn't create any ambiguities because it's always 
present.  But given the comment about performance sensitivity, I wonder if we 
should combine the new field with the trailing return flag?



Comment at: clang/lib/AST/TypePrinter.cpp:943
+   FunctionType::SME_PStateSMCompatibleMask) &&
+  !InsideCCAttribute)
+OS << " __arm_streaming_compatible";

Are the `!InsideCCAttribute` conditions necessary?  AIUI, InsideCCAttribute 
exists to suppress the default calling convention when printing the type to 
which an explicit CC is added.  That doesn't apply to SME attributes, because 
they aren't modelled as traditional CCs, and because the default/normal case 
doesn't have any syntax associated with it.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:2291
 
+  // We only need to handle the 'arm_locally_streaming' attribute as a
+  // special case here (as opposed to e.g. 'arm_streaming'), because it

How about something like:
```
// Handle SME 

[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-06-13 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Hi @jyknight , @rsmith

Do you have any more thoughts on the above?  Quick version is:

1. Is it OK to have `[[…]]` attributes in the `arm` namespace that affect 
semantics?
2. Is it OK to raise an error for unrecognised attributes in the `arm` 
namespace (for a measure of future-proofing)?

Given the differing views, I'm unsure whether to revert the series and do (1) 
(and possibly (2)), or whether to leave things as they are.

Thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-06-07 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

In D148700#4401451 , @rsmith wrote:

> In D148700#4401353 , @jyknight 
> wrote:
>
>> Yes, standard attributes aren't supposed to be used for things which affect 
>> the type system (although, we certainly have many, already, which do, since 
>> we expose most GCC-syntax attributes also as C++-standard attribute syntax!)
>
> The rule that standard attributes don't affect semantics only applies to 
> attributes specified by the language standard. There is no expectation that 
> vendor attributes avoid such effects.

Ah.  Does that mean that, when the standard says (sorry for the direct latex 
quote):

> For an \grammarterm{attribute-token} (including an 
> \grammarterm{attribute-scoped-token}) not specified in this document, the 
> behavior is \impldef{behavior of non-standard attributes}; any such 
> \grammarterm{attribute-token} that is not recognized by the implementation is 
> ignored.

the “is ignored” rule only applies to unscoped attributes and to attributes in 
one of the std:: namespaces?  I.e. to things that could reasonably be 
standardised in future, rather than to vendor attributes?

> In particular, I'm concerned by this in the description of this change:
>
> In D148700 , @rsandifo-arm wrote:
>
>> Really, the “only” thing wrong with using standard attributes is that 
>> standard attributes cannot affect semantics.
>
> If the only reason for this patch series is an idea that vendor attributes 
> using `[[...]]` syntax can't affect program semantics, then I think this 
> change is not justified, because vendor attributes using `[[...]]` syntax can 
> and usually do affect program semantics. But the documentation change here 
> makes the point that using a keyword attribute may be as good idea in cases 
> where you would always want compilation to fail on a compiler that doesn't 
> understand the annotation, rather than the annotation being ignored (likely 
> with a warning), so maybe that's reasonable justification for this direction.

FWIW, the original plan had been to use standard attribute syntax with the 
`arm` vendor namespace.  We started out with things like `[[arm::streaming]]`, 
but then a colleague pointed out that standard attributes aren't supposed to 
affect semantics.  So then we switched to GNU attributes, which have long 
included things that can't be ignored (such as `vector_size`).  But there was 
pushback against that because even unrecognised GNU attributes only generate a 
warning.  (I think GCC made a mistake by establishing that unrecognised GNU 
attributes are only a warning.)

If using standard attributes with a vendor namespace is acceptable for things 
that affect semantics and ABI, then that would actually be more convenient, for 
a few reasons:

- It would provide proper scoping (via namespaces), rather than the clunky 
`__arm_` prefixes.  E.g. some of the ACLE intrinsics have `__arm_streaming 
__arm_shared_za __arm_preserves_za`, which is quite a mouthful :)

- It would allow other attribute-related features to be used, such as `#pragma 
clang attribute`

- It would allow attributes to take arguments, without any compatibility 
concerns.  Keyword attributes could support arguments, but the decision about 
whether an attribute takes arguments would probably have to be made when the 
attribute is first added.  Trying to retrofit arguments to a keyword attribute 
that didn't previously take arguments could lead to parsing ambiguities.  In 
contrast, the standard attribute syntax would allow optional arguments to be 
added later without any backward compatibility concerns.

The main drawback would still be that unrecognised attributes only generate a 
warning.  But if vendor attributes are allowed to affect semantics, we could 
“solve” the warning problem for current and future compilers by reporting an 
error for unrecognised `arm::` attributes.  That wouldn't help with older 
compilers, but TBH, I think older compilers would reject any practical use of 
SME attributes anyway.  E.g. the attributes would almost always (perhaps 
always) be used in conjunction with the `arm_sme.h` header, which older 
compilers don't provide.  We also provide a feature preprocessor macro that 
careful code can check.

So if using an `arm` namespace is acceptable, if the current line about what 
can affect semantics is likely to become more fuzzy, and if there's a risk that 
keyword attributes are a dead end that no-one else adopts, then TBH I'd still 
be in favour of using `arm` namespaces for SME.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-31 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang-tools-extra/pseudo/lib/grammar/CMakeLists.txt:5
-# Dependencies should be minimal to avoid long dep paths in the build graph.
-# It does use clangBasic headers (tok::TokenKind), but linking is not needed.
-# We have no transitive dependencies on tablegen files.

thakis wrote:
> Did whoever wrote this comment sign up its removal? Looks like it was 
> @sammccall in 
> https://github.com/llvm/llvm-project/commit/dc63ad8878de6d0b5dc1268691f48035e9234763
No, sorry, I should have checked.

The type referenced in the comment (`tok::TokenKind`) is the one that is now 
being partially generated by tablegen.  Given that, there didn't seem any way 
of avoiding the dependency.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148702: [clang] Add Parse and Sema support for RegularKeyword attributes

2023-05-31 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG33ee5c466346: [clang] Add Parse and Sema support for 
RegularKeyword attributes (authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148702/new/

https://reviews.llvm.org/D148702

Files:
  clang/examples/Attribute/Attribute.cpp
  clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/ParsedAttr.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaStmtAttr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/Parser/c2x-attribute-keywords.c
  clang/test/Parser/c2x-attribute-keywords.m
  clang/test/Parser/cxx0x-keyword-attributes.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3882,7 +3882,8 @@
   OS << "bool diagAppertainsToDecl(Sema , const ParsedAttr , ";
   OS << "const Decl *D) const override {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)\n";
-  OS << "<< AL << D->getLocation();\n";
+  OS << "<< AL << AL.isRegularKeywordAttribute() << "
+"D->getLocation();\n";
   OS << "  return false;\n";
   OS << "}\n\n";
 }
@@ -3911,7 +3912,7 @@
 OS << (Warn ? "warn_attribute_wrong_decl_type_str"
 : "err_attribute_wrong_decl_type_str");
 OS << ")\n";
-OS << "  << Attr << ";
+OS << "  << Attr << Attr.isRegularKeywordAttribute() << ";
 OS << CalculateDiagnostic(*SubjectObj) << ";\n";
 OS << "return false;\n";
 OS << "  }\n";
@@ -3926,7 +3927,8 @@
   OS << "bool diagAppertainsToStmt(Sema , const ParsedAttr , ";
   OS << "const Stmt *St) const override {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_decl_attribute_invalid_on_stmt)\n";
-  OS << "<< AL << St->getBeginLoc();\n";
+  OS << "<< AL << AL.isRegularKeywordAttribute() << "
+"St->getBeginLoc();\n";
   OS << "  return false;\n";
   OS << "}\n\n";
 }
@@ -3945,7 +3947,7 @@
 OS << (Warn ? "warn_attribute_wrong_decl_type_str"
 : "err_attribute_wrong_decl_type_str");
 OS << ")\n";
-OS << "  << Attr << ";
+OS << "  << Attr << Attr.isRegularKeywordAttribute() << ";
 OS << CalculateDiagnostic(*SubjectObj) << ";\n";
 OS << "return false;\n";
 OS << "  }\n";
@@ -4016,7 +4018,8 @@
 for (const std::string  : DeclAttrs) {
   OS << "if (const auto *A = D->getAttr<" << A << ">()) {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)"
- << " << AL << A;\n";
+ << " << AL << A << (AL.isRegularKeywordAttribute() ||"
+ << " A->isRegularKeywordAttribute());\n";
   OS << "  S.Diag(A->getLocation(), diag::note_conflicting_attribute);";
   OS << "  \nreturn false;\n";
   OS << "}\n";
@@ -4037,7 +4040,8 @@
 << ">()) {\n";
 MergeDeclOS << "  S.Diag(First->getLocation(), "
 << "diag::err_attributes_are_not_compatible) << First << "
-<< "Second;\n";
+<< "Second << (First->isRegularKeywordAttribute() || "
+<< "Second->isRegularKeywordAttribute());\n";
 MergeDeclOS << "  S.Diag(Second->getLocation(), "
 << "diag::note_conflicting_attribute);\n";
 MergeDeclOS << "  return false;\n";
@@ -4077,7 +4081,8 @@
 MergeStmtOS << "  if (Iter != C.end()) {\n";
 MergeStmtOS << "S.Diag((*Iter)->getLocation(), "
 << "diag::err_attributes_are_not_compatible) << *Iter << "
-<< "Second;\n";
+<< "Second << ((*Iter)->isRegularKeywordAttribute() || "
+<< "Second->isRegularKeywordAttribute());\n";
 MergeStmtOS << "S.Diag(Second->getLocation(), "
 << "diag::note_conflicting_attribute);\n";
 MergeStmtOS << "return false;\n";
Index: clang/test/Parser/cxx0x-keyword-attributes.cpp
===
--- /dev/null
+++ clang/test/Parser/cxx0x-keyword-attributes.cpp
@@ -0,0 +1,345 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fdeclspec 

[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-31 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG301eb6b68f30: [clang] Add support for “regular” keyword 
attributes (authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

Files:
  clang-tools-extra/pseudo/lib/grammar/CMakeLists.txt
  clang/docs/InternalsManual.rst
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/include/clang/Basic/CMakeLists.txt
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Basic/TokenKinds.h
  clang/include/clang/Lex/Token.h
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/unittests/AST/AttrTest.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp
  clang/utils/TableGen/TableGen.cpp
  clang/utils/TableGen/TableGenBackends.h

Index: clang/utils/TableGen/TableGenBackends.h
===
--- clang/utils/TableGen/TableGenBackends.h
+++ clang/utils/TableGen/TableGenBackends.h
@@ -43,6 +43,8 @@
llvm::raw_ostream );
 void EmitClangAttrPCHRead(llvm::RecordKeeper , llvm::raw_ostream );
 void EmitClangAttrPCHWrite(llvm::RecordKeeper , llvm::raw_ostream );
+void EmitClangAttrTokenKinds(llvm::RecordKeeper ,
+ llvm::raw_ostream );
 void EmitClangAttrHasAttrImpl(llvm::RecordKeeper ,
   llvm::raw_ostream );
 void EmitClangAttrSpellingListIndex(llvm::RecordKeeper ,
Index: clang/utils/TableGen/TableGen.cpp
===
--- clang/utils/TableGen/TableGen.cpp
+++ clang/utils/TableGen/TableGen.cpp
@@ -35,6 +35,7 @@
   GenClangAttrSubjectMatchRuleList,
   GenClangAttrPCHRead,
   GenClangAttrPCHWrite,
+  GenClangAttrTokenKinds,
   GenClangAttrHasAttributeImpl,
   GenClangAttrSpellingListIndex,
   GenClangAttrASTVisitor,
@@ -135,6 +136,8 @@
"Generate clang PCH attribute reader"),
 clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write",
"Generate clang PCH attribute writer"),
+clEnumValN(GenClangAttrTokenKinds, "gen-clang-attr-token-kinds",
+   "Generate a list of attribute-related clang tokens"),
 clEnumValN(GenClangAttrHasAttributeImpl,
"gen-clang-attr-has-attribute-impl",
"Generate a clang attribute spelling list"),
@@ -324,6 +327,9 @@
   case GenClangAttrPCHWrite:
 EmitClangAttrPCHWrite(Records, OS);
 break;
+  case GenClangAttrTokenKinds:
+EmitClangAttrTokenKinds(Records, OS);
+break;
   case GenClangAttrHasAttributeImpl:
 EmitClangAttrHasAttrImpl(Records, OS);
 break;
Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2381,6 +2381,11 @@
   OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n";
 }
 
+static bool isRegularKeywordAttribute(const FlattenedSpelling ) {
+  return (S.variety() == "Keyword" &&
+  !S.getSpellingRecord().getValueAsBit("HasOwnParseRules"));
+}
+
 static void emitFormInitializer(raw_ostream ,
 const FlattenedSpelling ,
 StringRef SpellingIndex) {
@@ -2388,7 +2393,9 @@
   (Spelling.variety() == "Keyword" && Spelling.name() == "alignas");
   OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
  << SpellingIndex << ", " << (IsAlignas ? "true" : "false")
- << " /*IsAlignas*/}";
+ << " /*IsAlignas*/, "
+ << (isRegularKeywordAttribute(Spelling) ? "true" : "false")
+ << " /*IsRegularKeywordAttribute*/}";
 }
 
 static void emitAttributes(RecordKeeper , raw_ostream ,
@@ -3407,6 +3414,26 @@
   OS << ".Default(0);\n";
 }
 
+// Emits the list of tokens for regular keyword attributes.
+void EmitClangAttrTokenKinds(RecordKeeper , raw_ostream ) {
+  emitSourceFileHeader("A list of tokens generated from the attribute"
+   " definitions",
+   OS);
+  // Assume for now that the same token is not used in multiple regular
+  // keyword attributes.
+  for (auto *R : Records.getAllDerivedDefinitions("Attr"))
+for (const auto  : GetFlattenedSpellings(*R))
+  if (isRegularKeywordAttribute(S)) {
+if (!R->getValueAsListOfDefs("Args").empty())
+  PrintError(R->getLoc(),
+ "RegularKeyword attributes with arguments are not "
+ "yet supported");
+OS << "KEYWORD_ATTRIBUTE("
+   << S.getSpellingRecord().getValueAsString("Name") << ")\n";
+  

[PATCH] D148699: [clang] Mark keywords that have their own parsing rules

2023-05-31 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGac5c996d5aaa: [clang] Mark keywords that have their own 
parsing rules (authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148699/new/

https://reviews.llvm.org/D148699

Files:
  clang/include/clang/Basic/Attr.td

Index: clang/include/clang/Basic/Attr.td
===
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -311,7 +311,13 @@
   string Namespace = namespace;
 }
 
-class Keyword : Spelling;
+class Keyword
+: Spelling {
+  bit HasOwnParseRules = hasOwnParseRules;
+}
+// A keyword that has its own individual parsing rules.
+class CustomKeyword : Keyword {}
+
 class Pragma : Spelling {
   string Namespace = namespace;
 }
@@ -709,13 +715,13 @@
 }
 
 def Aligned : InheritableAttr {
-  let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
-   Keyword<"_Alignas">];
+  let Spellings = [GCC<"aligned">, Declspec<"align">, CustomKeyword<"alignas">,
+   CustomKeyword<"_Alignas">];
   let Args = [AlignedArgument<"Alignment", 1>];
   let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>,
-   Accessor<"isC11", [Keyword<"_Alignas">]>,
-   Accessor<"isAlignas", [Keyword<"alignas">,
-  Keyword<"_Alignas">]>,
+   Accessor<"isC11", [CustomKeyword<"_Alignas">]>,
+   Accessor<"isAlignas", [CustomKeyword<"alignas">,
+  CustomKeyword<"_Alignas">]>,
Accessor<"isDeclspec",[Declspec<"align">]>];
   let Documentation = [Undocumented];
 }
@@ -756,7 +762,7 @@
 
 def AlwaysInline : DeclOrStmtAttr {
   let Spellings = [GCC<"always_inline">, CXX11<"clang", "always_inline">,
-   C2x<"clang", "always_inline">, Keyword<"__forceinline">];
+   C2x<"clang", "always_inline">, CustomKeyword<"__forceinline">];
   let Accessors = [Accessor<"isClangAlwaysInline", [CXX11<"clang", "always_inline">,
 C2x<"clang", "always_inline">]>];
   let Subjects = SubjectList<[Function, Stmt], WarnDiag,
@@ -879,7 +885,7 @@
 }
 
 def AsmLabel : InheritableAttr {
-  let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
+  let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm__">];
   let Args = [
 // Label specifies the mangled name for the decl.
 StringArgument<"Label">,
@@ -997,7 +1003,7 @@
 }
 
 def CDecl : DeclOrTypeAttr {
-  let Spellings = [GCC<"cdecl">, Keyword<"__cdecl">, Keyword<"_cdecl">];
+  let Spellings = [GCC<"cdecl">, CustomKeyword<"__cdecl">, CustomKeyword<"_cdecl">];
 //  let Subjects = [Function, ObjCMethod];
   let Documentation = [Undocumented];
 }
@@ -1122,10 +1128,10 @@
 def ConstInit : InheritableAttr {
   // This attribute does not have a C [[]] spelling because it requires the
   // CPlusPlus language option.
-  let Spellings = [Keyword<"constinit">,
+  let Spellings = [CustomKeyword<"constinit">,
Clang<"require_constant_initialization", 0>];
   let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
-  let Accessors = [Accessor<"isConstinit", [Keyword<"constinit">]>];
+  let Accessors = [Accessor<"isConstinit", [CustomKeyword<"constinit">]>];
   let Documentation = [ConstInitDocs];
   let LangOpts = [CPlusPlus];
   let SimpleHandler = 1;
@@ -1276,7 +1282,7 @@
 }
 
 def C11NoReturn : InheritableAttr {
-  let Spellings = [Keyword<"_Noreturn">];
+  let Spellings = [CustomKeyword<"_Noreturn">];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let SemaHandler = 0;
   let Documentation = [C11NoReturnDocs];
@@ -1292,7 +1298,7 @@
 // Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because
 // the specification does not expose them with one currently.
 def OpenCLKernel : InheritableAttr {
-  let Spellings = [Keyword<"__kernel">, Keyword<"kernel">];
+  let Spellings = [CustomKeyword<"__kernel">, CustomKeyword<"kernel">];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let Documentation = [Undocumented];
   let SimpleHandler = 1;
@@ -1316,26 +1322,28 @@
 // This attribute is both a type attribute, and a declaration attribute (for
 // parameter variables).
 def OpenCLAccess : Attr {
-  let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
-   Keyword<"__write_only">, Keyword<"write_only">,
-   Keyword<"__read_write">, Keyword<"read_write">];
+  let Spellings = [CustomKeyword<"__read_only">, CustomKeyword<"read_only">,
+   CustomKeyword<"__write_only">, CustomKeyword<"write_only">,
+   CustomKeyword<"__read_write">, CustomKeyword<"read_write">];
   let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag>;
-  let Accessors = [Accessor<"isReadOnly", 

[PATCH] D148699: [clang] Mark keywords that have their own parsing rules

2023-05-31 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 526944.
rsandifo-arm added a comment.

Update base commit.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148699/new/

https://reviews.llvm.org/D148699

Files:
  clang/include/clang/Basic/Attr.td

Index: clang/include/clang/Basic/Attr.td
===
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -311,7 +311,13 @@
   string Namespace = namespace;
 }
 
-class Keyword : Spelling;
+class Keyword
+: Spelling {
+  bit HasOwnParseRules = hasOwnParseRules;
+}
+// A keyword that has its own individual parsing rules.
+class CustomKeyword : Keyword {}
+
 class Pragma : Spelling {
   string Namespace = namespace;
 }
@@ -709,13 +715,13 @@
 }
 
 def Aligned : InheritableAttr {
-  let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
-   Keyword<"_Alignas">];
+  let Spellings = [GCC<"aligned">, Declspec<"align">, CustomKeyword<"alignas">,
+   CustomKeyword<"_Alignas">];
   let Args = [AlignedArgument<"Alignment", 1>];
   let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>,
-   Accessor<"isC11", [Keyword<"_Alignas">]>,
-   Accessor<"isAlignas", [Keyword<"alignas">,
-  Keyword<"_Alignas">]>,
+   Accessor<"isC11", [CustomKeyword<"_Alignas">]>,
+   Accessor<"isAlignas", [CustomKeyword<"alignas">,
+  CustomKeyword<"_Alignas">]>,
Accessor<"isDeclspec",[Declspec<"align">]>];
   let Documentation = [Undocumented];
 }
@@ -756,7 +762,7 @@
 
 def AlwaysInline : DeclOrStmtAttr {
   let Spellings = [GCC<"always_inline">, CXX11<"clang", "always_inline">,
-   C2x<"clang", "always_inline">, Keyword<"__forceinline">];
+   C2x<"clang", "always_inline">, CustomKeyword<"__forceinline">];
   let Accessors = [Accessor<"isClangAlwaysInline", [CXX11<"clang", "always_inline">,
 C2x<"clang", "always_inline">]>];
   let Subjects = SubjectList<[Function, Stmt], WarnDiag,
@@ -879,7 +885,7 @@
 }
 
 def AsmLabel : InheritableAttr {
-  let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
+  let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm__">];
   let Args = [
 // Label specifies the mangled name for the decl.
 StringArgument<"Label">,
@@ -997,7 +1003,7 @@
 }
 
 def CDecl : DeclOrTypeAttr {
-  let Spellings = [GCC<"cdecl">, Keyword<"__cdecl">, Keyword<"_cdecl">];
+  let Spellings = [GCC<"cdecl">, CustomKeyword<"__cdecl">, CustomKeyword<"_cdecl">];
 //  let Subjects = [Function, ObjCMethod];
   let Documentation = [Undocumented];
 }
@@ -1122,10 +1128,10 @@
 def ConstInit : InheritableAttr {
   // This attribute does not have a C [[]] spelling because it requires the
   // CPlusPlus language option.
-  let Spellings = [Keyword<"constinit">,
+  let Spellings = [CustomKeyword<"constinit">,
Clang<"require_constant_initialization", 0>];
   let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
-  let Accessors = [Accessor<"isConstinit", [Keyword<"constinit">]>];
+  let Accessors = [Accessor<"isConstinit", [CustomKeyword<"constinit">]>];
   let Documentation = [ConstInitDocs];
   let LangOpts = [CPlusPlus];
   let SimpleHandler = 1;
@@ -1276,7 +1282,7 @@
 }
 
 def C11NoReturn : InheritableAttr {
-  let Spellings = [Keyword<"_Noreturn">];
+  let Spellings = [CustomKeyword<"_Noreturn">];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let SemaHandler = 0;
   let Documentation = [C11NoReturnDocs];
@@ -1292,7 +1298,7 @@
 // Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because
 // the specification does not expose them with one currently.
 def OpenCLKernel : InheritableAttr {
-  let Spellings = [Keyword<"__kernel">, Keyword<"kernel">];
+  let Spellings = [CustomKeyword<"__kernel">, CustomKeyword<"kernel">];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let Documentation = [Undocumented];
   let SimpleHandler = 1;
@@ -1316,26 +1322,28 @@
 // This attribute is both a type attribute, and a declaration attribute (for
 // parameter variables).
 def OpenCLAccess : Attr {
-  let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
-   Keyword<"__write_only">, Keyword<"write_only">,
-   Keyword<"__read_write">, Keyword<"read_write">];
+  let Spellings = [CustomKeyword<"__read_only">, CustomKeyword<"read_only">,
+   CustomKeyword<"__write_only">, CustomKeyword<"write_only">,
+   CustomKeyword<"__read_write">, CustomKeyword<"read_write">];
   let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag>;
-  let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">,
-   Keyword<"read_only">]>,
- 

[PATCH] D148702: [clang] Add Parse and Sema support for RegularKeyword attributes

2023-05-31 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 526936.
rsandifo-arm marked an inline comment as done.
rsandifo-arm added a comment.

Rebase to account for a diagnostic that has moved.
No other changes from the previous version.

I'll wait for the build results before pushing.

Thanks for the review!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148702/new/

https://reviews.llvm.org/D148702

Files:
  clang/examples/Attribute/Attribute.cpp
  clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/ParsedAttr.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaStmtAttr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/Parser/c2x-attribute-keywords.c
  clang/test/Parser/c2x-attribute-keywords.m
  clang/test/Parser/cxx0x-keyword-attributes.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3882,7 +3882,8 @@
   OS << "bool diagAppertainsToDecl(Sema , const ParsedAttr , ";
   OS << "const Decl *D) const override {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)\n";
-  OS << "<< AL << D->getLocation();\n";
+  OS << "<< AL << AL.isRegularKeywordAttribute() << "
+"D->getLocation();\n";
   OS << "  return false;\n";
   OS << "}\n\n";
 }
@@ -3911,7 +3912,7 @@
 OS << (Warn ? "warn_attribute_wrong_decl_type_str"
 : "err_attribute_wrong_decl_type_str");
 OS << ")\n";
-OS << "  << Attr << ";
+OS << "  << Attr << Attr.isRegularKeywordAttribute() << ";
 OS << CalculateDiagnostic(*SubjectObj) << ";\n";
 OS << "return false;\n";
 OS << "  }\n";
@@ -3926,7 +3927,8 @@
   OS << "bool diagAppertainsToStmt(Sema , const ParsedAttr , ";
   OS << "const Stmt *St) const override {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_decl_attribute_invalid_on_stmt)\n";
-  OS << "<< AL << St->getBeginLoc();\n";
+  OS << "<< AL << AL.isRegularKeywordAttribute() << "
+"St->getBeginLoc();\n";
   OS << "  return false;\n";
   OS << "}\n\n";
 }
@@ -3945,7 +3947,7 @@
 OS << (Warn ? "warn_attribute_wrong_decl_type_str"
 : "err_attribute_wrong_decl_type_str");
 OS << ")\n";
-OS << "  << Attr << ";
+OS << "  << Attr << Attr.isRegularKeywordAttribute() << ";
 OS << CalculateDiagnostic(*SubjectObj) << ";\n";
 OS << "return false;\n";
 OS << "  }\n";
@@ -4016,7 +4018,8 @@
 for (const std::string  : DeclAttrs) {
   OS << "if (const auto *A = D->getAttr<" << A << ">()) {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)"
- << " << AL << A;\n";
+ << " << AL << A << (AL.isRegularKeywordAttribute() ||"
+ << " A->isRegularKeywordAttribute());\n";
   OS << "  S.Diag(A->getLocation(), diag::note_conflicting_attribute);";
   OS << "  \nreturn false;\n";
   OS << "}\n";
@@ -4037,7 +4040,8 @@
 << ">()) {\n";
 MergeDeclOS << "  S.Diag(First->getLocation(), "
 << "diag::err_attributes_are_not_compatible) << First << "
-<< "Second;\n";
+<< "Second << (First->isRegularKeywordAttribute() || "
+<< "Second->isRegularKeywordAttribute());\n";
 MergeDeclOS << "  S.Diag(Second->getLocation(), "
 << "diag::note_conflicting_attribute);\n";
 MergeDeclOS << "  return false;\n";
@@ -4077,7 +4081,8 @@
 MergeStmtOS << "  if (Iter != C.end()) {\n";
 MergeStmtOS << "S.Diag((*Iter)->getLocation(), "
 << "diag::err_attributes_are_not_compatible) << *Iter << "
-<< "Second;\n";
+<< "Second << ((*Iter)->isRegularKeywordAttribute() || "
+<< "Second->isRegularKeywordAttribute());\n";
 MergeStmtOS << "S.Diag(Second->getLocation(), "
 << "diag::note_conflicting_attribute);\n";
 MergeStmtOS << "return false;\n";
Index: clang/test/Parser/cxx0x-keyword-attributes.cpp
===
--- /dev/null
+++ 

[PATCH] D148702: [clang] Add Parse and Sema support for RegularKeyword attributes

2023-05-30 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm marked an inline comment as done.
rsandifo-arm added inline comments.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:2902
 S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
-<< AL << ExpectedTypeOrNamespace;
+<< AL << 0 << ExpectedTypeOrNamespace;
 return;

erichkeane wrote:
> Every where you are doing just a '0' in a diagnostic here it makes it 
> incredibly unreadable.  I'd prefer 1 of 2 solutions:
> 
> 1- Create an enum somewhere that encodes the meaning here, and use those 
> instead.
> 2- use a `/*Whatever*/` comment every place you're passing a raw literal.
Yeah, that's fair.  Sorry about that.  I got some of my own medicine reading 
the patch back after a while away from it.

Most of those `<< 0` come from looking at individual uses to see whether a 
regular keyword spelling is ever possible.  If it wasn't possible, `<< 0` was 
supposed to be a justification for not covering that line of code in the new 
test cases.

But I now think that was a mistake.  Using `isRegularKeywordAttribute()` is 
useful for readability even if we “know” what its value ahead of time.  And 
using it is more future-proof as well.

So this update converts most uses of `<< 0` to `<< 
Something.isRegulardKeywordAttribute` in cases where the appropriate 
`Something` is readily available.  There are a handful of cases where an 
immediate is still needed, so I went for option (2) and added a comment to 
those.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148702/new/

https://reviews.llvm.org/D148702

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148702: [clang] Add Parse and Sema support for RegularKeyword attributes

2023-05-30 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 526600.
rsandifo-arm added a comment.

Avoid most uses of `<< 0`.  Add comments to those that remain.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148702/new/

https://reviews.llvm.org/D148702

Files:
  clang/examples/Attribute/Attribute.cpp
  clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/ParsedAttr.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaStmtAttr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/Parser/c2x-attribute-keywords.c
  clang/test/Parser/c2x-attribute-keywords.m
  clang/test/Parser/cxx0x-keyword-attributes.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3879,7 +3879,8 @@
   OS << "bool diagAppertainsToDecl(Sema , const ParsedAttr , ";
   OS << "const Decl *D) const override {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)\n";
-  OS << "<< AL << D->getLocation();\n";
+  OS << "<< AL << AL.isRegularKeywordAttribute() << "
+"D->getLocation();\n";
   OS << "  return false;\n";
   OS << "}\n\n";
 }
@@ -3908,7 +3909,7 @@
 OS << (Warn ? "warn_attribute_wrong_decl_type_str"
 : "err_attribute_wrong_decl_type_str");
 OS << ")\n";
-OS << "  << Attr << ";
+OS << "  << Attr << Attr.isRegularKeywordAttribute() << ";
 OS << CalculateDiagnostic(*SubjectObj) << ";\n";
 OS << "return false;\n";
 OS << "  }\n";
@@ -3923,7 +3924,8 @@
   OS << "bool diagAppertainsToStmt(Sema , const ParsedAttr , ";
   OS << "const Stmt *St) const override {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_decl_attribute_invalid_on_stmt)\n";
-  OS << "<< AL << St->getBeginLoc();\n";
+  OS << "<< AL << AL.isRegularKeywordAttribute() << "
+"St->getBeginLoc();\n";
   OS << "  return false;\n";
   OS << "}\n\n";
 }
@@ -3942,7 +3944,7 @@
 OS << (Warn ? "warn_attribute_wrong_decl_type_str"
 : "err_attribute_wrong_decl_type_str");
 OS << ")\n";
-OS << "  << Attr << ";
+OS << "  << Attr << Attr.isRegularKeywordAttribute() << ";
 OS << CalculateDiagnostic(*SubjectObj) << ";\n";
 OS << "return false;\n";
 OS << "  }\n";
@@ -4013,7 +4015,8 @@
 for (const std::string  : DeclAttrs) {
   OS << "if (const auto *A = D->getAttr<" << A << ">()) {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)"
- << " << AL << A;\n";
+ << " << AL << A << (AL.isRegularKeywordAttribute() ||"
+ << " A->isRegularKeywordAttribute());\n";
   OS << "  S.Diag(A->getLocation(), diag::note_conflicting_attribute);";
   OS << "  \nreturn false;\n";
   OS << "}\n";
@@ -4034,7 +4037,8 @@
 << ">()) {\n";
 MergeDeclOS << "  S.Diag(First->getLocation(), "
 << "diag::err_attributes_are_not_compatible) << First << "
-<< "Second;\n";
+<< "Second << (First->isRegularKeywordAttribute() || "
+<< "Second->isRegularKeywordAttribute());\n";
 MergeDeclOS << "  S.Diag(Second->getLocation(), "
 << "diag::note_conflicting_attribute);\n";
 MergeDeclOS << "  return false;\n";
@@ -4074,7 +4078,8 @@
 MergeStmtOS << "  if (Iter != C.end()) {\n";
 MergeStmtOS << "S.Diag((*Iter)->getLocation(), "
 << "diag::err_attributes_are_not_compatible) << *Iter << "
-<< "Second;\n";
+<< "Second << ((*Iter)->isRegularKeywordAttribute() || "
+<< "Second->isRegularKeywordAttribute());\n";
 MergeStmtOS << "S.Diag(Second->getLocation(), "
 << "diag::note_conflicting_attribute);\n";
 MergeStmtOS << "return false;\n";
Index: clang/test/Parser/cxx0x-keyword-attributes.cpp
===
--- /dev/null
+++ clang/test/Parser/cxx0x-keyword-attributes.cpp
@@ -0,0 +1,345 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fdeclspec -fexceptions -fsyntax-only -verify -std=c++11 -Wc++14-compat 

[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-25 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Thanks @aaron.ballman and @erichkeane for your patience in reviewing the patch 
and steering me in the right direction.

What do you think about the other two patches in the series:

- https://reviews.llvm.org/D148699 (comes before this one)
- https://reviews.llvm.org/D148702 (comes after this one)

The first one is pretty mechanical.  The second is going to be a slog to 
review, sorry.  It's one of those things that's much easier to write than to 
check afterwards.  I've tried to capture all the potentially 
non-obvious/non-mechanical parts in the covering note, but a long covering note 
might just make the review even more painful.  I'm happy to try presenting it 
in a different form if you can think of one that would help.

Thanks again for accepting this patch, really appreciate it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148702: [clang] Add Parse and Sema support for RegularKeyword attributes

2023-05-23 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 524846.
rsandifo-arm marked an inline comment as done.
rsandifo-arm added a comment.

Update onto current main.  Only change is to replace C++2b with C++23.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148702/new/

https://reviews.llvm.org/D148702

Files:
  clang/examples/Attribute/Attribute.cpp
  clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/ParsedAttr.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaStmtAttr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/Parser/c2x-attribute-keywords.c
  clang/test/Parser/c2x-attribute-keywords.m
  clang/test/Parser/cxx0x-keyword-attributes.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3879,7 +3879,8 @@
   OS << "bool diagAppertainsToDecl(Sema , const ParsedAttr , ";
   OS << "const Decl *D) const override {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)\n";
-  OS << "<< AL << D->getLocation();\n";
+  OS << "<< AL << AL.isRegularKeywordAttribute() << "
+"D->getLocation();\n";
   OS << "  return false;\n";
   OS << "}\n\n";
 }
@@ -3908,7 +3909,7 @@
 OS << (Warn ? "warn_attribute_wrong_decl_type_str"
 : "err_attribute_wrong_decl_type_str");
 OS << ")\n";
-OS << "  << Attr << ";
+OS << "  << Attr << Attr.isRegularKeywordAttribute() << ";
 OS << CalculateDiagnostic(*SubjectObj) << ";\n";
 OS << "return false;\n";
 OS << "  }\n";
@@ -3923,7 +3924,8 @@
   OS << "bool diagAppertainsToStmt(Sema , const ParsedAttr , ";
   OS << "const Stmt *St) const override {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_decl_attribute_invalid_on_stmt)\n";
-  OS << "<< AL << St->getBeginLoc();\n";
+  OS << "<< AL << AL.isRegularKeywordAttribute() << "
+"St->getBeginLoc();\n";
   OS << "  return false;\n";
   OS << "}\n\n";
 }
@@ -3942,7 +3944,7 @@
 OS << (Warn ? "warn_attribute_wrong_decl_type_str"
 : "err_attribute_wrong_decl_type_str");
 OS << ")\n";
-OS << "  << Attr << ";
+OS << "  << Attr << Attr.isRegularKeywordAttribute() << ";
 OS << CalculateDiagnostic(*SubjectObj) << ";\n";
 OS << "return false;\n";
 OS << "  }\n";
@@ -4013,7 +4015,8 @@
 for (const std::string  : DeclAttrs) {
   OS << "if (const auto *A = D->getAttr<" << A << ">()) {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)"
- << " << AL << A;\n";
+ << " << AL << A << (AL.isRegularKeywordAttribute() ||"
+ << " A->isRegularKeywordAttribute());\n";
   OS << "  S.Diag(A->getLocation(), diag::note_conflicting_attribute);";
   OS << "  \nreturn false;\n";
   OS << "}\n";
@@ -4034,7 +4037,8 @@
 << ">()) {\n";
 MergeDeclOS << "  S.Diag(First->getLocation(), "
 << "diag::err_attributes_are_not_compatible) << First << "
-<< "Second;\n";
+<< "Second << (First->isRegularKeywordAttribute() || "
+<< "Second->isRegularKeywordAttribute());\n";
 MergeDeclOS << "  S.Diag(Second->getLocation(), "
 << "diag::note_conflicting_attribute);\n";
 MergeDeclOS << "  return false;\n";
@@ -4074,7 +4078,8 @@
 MergeStmtOS << "  if (Iter != C.end()) {\n";
 MergeStmtOS << "S.Diag((*Iter)->getLocation(), "
 << "diag::err_attributes_are_not_compatible) << *Iter << "
-<< "Second;\n";
+<< "Second << ((*Iter)->isRegularKeywordAttribute() || "
+<< "Second->isRegularKeywordAttribute());\n";
 MergeStmtOS << "S.Diag(Second->getLocation(), "
 << "diag::note_conflicting_attribute);\n";
 MergeStmtOS << "return false;\n";
Index: clang/test/Parser/cxx0x-keyword-attributes.cpp
===
--- /dev/null
+++ clang/test/Parser/cxx0x-keyword-attributes.cpp
@@ -0,0 +1,345 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fdeclspec 

[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-23 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm marked an inline comment as done.
rsandifo-arm added a comment.

In D148700#4364229 , @aaron.ballman 
wrote:

> This basically LGTM, but we should add documentation to the internals manual 
> too: https://clang.llvm.org/docs/InternalsManual.html#spellings

Oops, hadn't seen that documentation.  Added in the updated patch, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-23 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 524843.
rsandifo-arm added a comment.

Add internals documentation.  Add FIXME to temporary code.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

Files:
  clang-tools-extra/pseudo/lib/grammar/CMakeLists.txt
  clang/docs/InternalsManual.rst
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/include/clang/Basic/CMakeLists.txt
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Basic/TokenKinds.h
  clang/include/clang/Lex/Token.h
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/unittests/AST/AttrTest.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp
  clang/utils/TableGen/TableGen.cpp
  clang/utils/TableGen/TableGenBackends.h

Index: clang/utils/TableGen/TableGenBackends.h
===
--- clang/utils/TableGen/TableGenBackends.h
+++ clang/utils/TableGen/TableGenBackends.h
@@ -43,6 +43,8 @@
llvm::raw_ostream );
 void EmitClangAttrPCHRead(llvm::RecordKeeper , llvm::raw_ostream );
 void EmitClangAttrPCHWrite(llvm::RecordKeeper , llvm::raw_ostream );
+void EmitClangAttrTokenKinds(llvm::RecordKeeper ,
+ llvm::raw_ostream );
 void EmitClangAttrHasAttrImpl(llvm::RecordKeeper ,
   llvm::raw_ostream );
 void EmitClangAttrSpellingListIndex(llvm::RecordKeeper ,
Index: clang/utils/TableGen/TableGen.cpp
===
--- clang/utils/TableGen/TableGen.cpp
+++ clang/utils/TableGen/TableGen.cpp
@@ -35,6 +35,7 @@
   GenClangAttrSubjectMatchRuleList,
   GenClangAttrPCHRead,
   GenClangAttrPCHWrite,
+  GenClangAttrTokenKinds,
   GenClangAttrHasAttributeImpl,
   GenClangAttrSpellingListIndex,
   GenClangAttrASTVisitor,
@@ -131,6 +132,8 @@
"Generate clang PCH attribute reader"),
 clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write",
"Generate clang PCH attribute writer"),
+clEnumValN(GenClangAttrTokenKinds, "gen-clang-attr-token-kinds",
+   "Generate a list of attribute-related clang tokens"),
 clEnumValN(GenClangAttrHasAttributeImpl,
"gen-clang-attr-has-attribute-impl",
"Generate a clang attribute spelling list"),
@@ -312,6 +315,9 @@
   case GenClangAttrPCHWrite:
 EmitClangAttrPCHWrite(Records, OS);
 break;
+  case GenClangAttrTokenKinds:
+EmitClangAttrTokenKinds(Records, OS);
+break;
   case GenClangAttrHasAttributeImpl:
 EmitClangAttrHasAttrImpl(Records, OS);
 break;
Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2378,6 +2378,11 @@
   OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n";
 }
 
+static bool isRegularKeywordAttribute(const FlattenedSpelling ) {
+  return (S.variety() == "Keyword" &&
+  !S.getSpellingRecord().getValueAsBit("HasOwnParseRules"));
+}
+
 static void emitFormInitializer(raw_ostream ,
 const FlattenedSpelling ,
 StringRef SpellingIndex) {
@@ -2385,7 +2390,9 @@
   (Spelling.variety() == "Keyword" && Spelling.name() == "alignas");
   OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
  << SpellingIndex << ", " << (IsAlignas ? "true" : "false")
- << " /*IsAlignas*/}";
+ << " /*IsAlignas*/, "
+ << (isRegularKeywordAttribute(Spelling) ? "true" : "false")
+ << " /*IsRegularKeywordAttribute*/}";
 }
 
 static void emitAttributes(RecordKeeper , raw_ostream ,
@@ -3404,6 +3411,26 @@
   OS << ".Default(0);\n";
 }
 
+// Emits the list of tokens for regular keyword attributes.
+void EmitClangAttrTokenKinds(RecordKeeper , raw_ostream ) {
+  emitSourceFileHeader("A list of tokens generated from the attribute"
+   " definitions",
+   OS);
+  // Assume for now that the same token is not used in multiple regular
+  // keyword attributes.
+  for (auto *R : Records.getAllDerivedDefinitions("Attr"))
+for (const auto  : GetFlattenedSpellings(*R))
+  if (isRegularKeywordAttribute(S)) {
+if (!R->getValueAsListOfDefs("Args").empty())
+  PrintError(R->getLoc(),
+ "RegularKeyword attributes with arguments are not "
+ "yet supported");
+OS << "KEYWORD_ATTRIBUTE("
+   << S.getSpellingRecord().getValueAsString("Name") << ")\n";
+  }
+  OS << "#undef KEYWORD_ATTRIBUTE\n";
+}
+
 // Emits the list of spellings for attributes.
 

[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-23 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Hi @erichkeane  and @aaron.ballman.  Does the updated patch look OK?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-16 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm marked an inline comment as done.
rsandifo-arm added a comment.

Thanks @erichkeane .  Adding the documentation with that kind of disclaimer 
sounds good to me.  I've done that in the updated version, and also fixed the 
comment problem that Aaron pointed out.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-16 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 522703.
rsandifo-arm added a comment.

Add documentation.  Fix a comment cut-&-pasto that Aaron pointed out.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

Files:
  clang-tools-extra/pseudo/lib/grammar/CMakeLists.txt
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/include/clang/Basic/CMakeLists.txt
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Basic/TokenKinds.h
  clang/include/clang/Lex/Token.h
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/unittests/AST/AttrTest.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp
  clang/utils/TableGen/TableGen.cpp
  clang/utils/TableGen/TableGenBackends.h

Index: clang/utils/TableGen/TableGenBackends.h
===
--- clang/utils/TableGen/TableGenBackends.h
+++ clang/utils/TableGen/TableGenBackends.h
@@ -43,6 +43,8 @@
llvm::raw_ostream );
 void EmitClangAttrPCHRead(llvm::RecordKeeper , llvm::raw_ostream );
 void EmitClangAttrPCHWrite(llvm::RecordKeeper , llvm::raw_ostream );
+void EmitClangAttrTokenKinds(llvm::RecordKeeper ,
+ llvm::raw_ostream );
 void EmitClangAttrHasAttrImpl(llvm::RecordKeeper ,
   llvm::raw_ostream );
 void EmitClangAttrSpellingListIndex(llvm::RecordKeeper ,
Index: clang/utils/TableGen/TableGen.cpp
===
--- clang/utils/TableGen/TableGen.cpp
+++ clang/utils/TableGen/TableGen.cpp
@@ -35,6 +35,7 @@
   GenClangAttrSubjectMatchRuleList,
   GenClangAttrPCHRead,
   GenClangAttrPCHWrite,
+  GenClangAttrTokenKinds,
   GenClangAttrHasAttributeImpl,
   GenClangAttrSpellingListIndex,
   GenClangAttrASTVisitor,
@@ -128,6 +129,8 @@
"Generate clang PCH attribute reader"),
 clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write",
"Generate clang PCH attribute writer"),
+clEnumValN(GenClangAttrTokenKinds, "gen-clang-attr-token-kinds",
+   "Generate a list of attribute-related clang tokens"),
 clEnumValN(GenClangAttrHasAttributeImpl,
"gen-clang-attr-has-attribute-impl",
"Generate a clang attribute spelling list"),
@@ -303,6 +306,9 @@
   case GenClangAttrPCHWrite:
 EmitClangAttrPCHWrite(Records, OS);
 break;
+  case GenClangAttrTokenKinds:
+EmitClangAttrTokenKinds(Records, OS);
+break;
   case GenClangAttrHasAttributeImpl:
 EmitClangAttrHasAttrImpl(Records, OS);
 break;
Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2378,6 +2378,11 @@
   OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n";
 }
 
+static bool isRegularKeywordAttribute(const FlattenedSpelling ) {
+  return (S.variety() == "Keyword" &&
+  !S.getSpellingRecord().getValueAsBit("HasOwnParseRules"));
+}
+
 static void emitFormInitializer(raw_ostream ,
 const FlattenedSpelling ,
 StringRef SpellingIndex) {
@@ -2385,7 +2390,9 @@
   (Spelling.variety() == "Keyword" && Spelling.name() == "alignas");
   OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
  << SpellingIndex << ", " << (IsAlignas ? "true" : "false")
- << " /*IsAlignas*/}";
+ << " /*IsAlignas*/, "
+ << (isRegularKeywordAttribute(Spelling) ? "true" : "false")
+ << " /*IsRegularKeywordAttribute*/}";
 }
 
 static void emitAttributes(RecordKeeper , raw_ostream ,
@@ -3404,6 +3411,26 @@
   OS << ".Default(0);\n";
 }
 
+// Emits the list of tokens for regular keyword attributes.
+void EmitClangAttrTokenKinds(RecordKeeper , raw_ostream ) {
+  emitSourceFileHeader("A list of tokens generated from the attribute"
+   " definitions",
+   OS);
+  // Assume for now that the same token is not used in multiple regular
+  // keyword attributes.
+  for (auto *R : Records.getAllDerivedDefinitions("Attr"))
+for (const auto  : GetFlattenedSpellings(*R))
+  if (isRegularKeywordAttribute(S)) {
+if (!R->getValueAsListOfDefs("Args").empty())
+  PrintError(R->getLoc(),
+ "RegularKeyword attributes with arguments are not "
+ "yet supported");
+OS << "KEYWORD_ATTRIBUTE("
+   << S.getSpellingRecord().getValueAsString("Name") << ")\n";
+  }
+  OS << "#undef KEYWORD_ATTRIBUTE\n";
+}
+
 // Emits the list of spellings for attributes.
 void 

[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-16 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Hi @aaron.ballman and @erichkeane .  Do you have any more thoughts on this?  In 
principle, I'm happy to convert an existing attribute over to the new scheme, 
but in practice, I can't find one that seems to be suitable.  If we're going to 
do that, I think I'll need guidance as to which attribute to convert.

Alternatively, I could try to classify existing keywords into groups based on 
their current parsing rules and tablegen-ify them based on that.  E.g. I could 
add NullabilityKeyword for `_Nonnull`, `_Nullable`, `_Nullable_result`, 
`_Null_unspecified`, and for anything else that happens to use exactly those 
parsing rules.  I could then replace direct checks for the nullability keyword 
tokens with checks for a NullabilityKeyword spelling.

But the tablegen side wasn't really the main focus of this.  It's more the 
principle of having an optional, mechanical link between attribute keywords and 
the standard attribute parsing rules.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-10 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a subscriber: sdesmalen.
rsandifo-arm added a comment.

Thanks for the review.




Comment at: clang/include/clang/Basic/Attr.td:2427-2430
+def ArmStreaming : TypeAttr, TargetSpecificAttr {
+  let Spellings = [RegularKeyword<"__arm_streaming">];
+  let Documentation = [Undocumented];
+}

aaron.ballman wrote:
> I'd feel more comfortable switching an existing attribute over to use this 
> new functionality instead of introducing a new attribute at the same time. 
> (Also, we ask that there be no new undocumented attributes unless there's a 
> Very Good Reason to leave it undocumented.)
Could you suggest an attribute that would be suitable?  The problem is that, as 
far as I know, no existing keyword has parse rules that exactly match the rules 
for standard attributes.  (That, and the fact that different keywords have 
different rules, was one of the main motivations for the patch).  So I don't 
think it would be possible to adopt the new scheme for existing attributes 
without breaking compatiblity (both ways: some things would become valid that 
weren't before, and some things that were valid before would become invalid).

E.g.:

 __declspec

I don't think anyone was suggesting we try to convert this :-) but for 
completeness:

```
int __declspec(align(16)) a1; // OK, but standard attribute rules would say 
this appertains to the type
int a2 __declspec();  // Not valid, unlike for standard decl attributes
```

 __forceinline

```
int __forceinline a1() { return 1; } // OK, but standard attribute rules would 
say this appertains to the type
int a2 __forceinline() { return 1; } // Not valid, but would be for standard 
decl attributes
```

 Calling convention keywords

These are generally DeclOrType attributes, with attributes sliding from the 
decl to the type where necessary.

```
__stdcall int a1();   // OK, but appertains to the decl and relies on sliding 
behaviour
int a2 __stdcall();   // Not valid, but is another place to put standard decl 
attributes
int a3() __stdcall;   // Not valid, but is another place to put standard type 
attributes
int (__stdcall a4)(); // OK, but standard attributes aren't allowed in this 
position
extern int (*const __stdcall volatile a5) (); // OK, but standard attributes 
wouldn't be allowed here
```

 Nullability keywords

Like the calling-convention keywords, the nullability keywords appertain to 
types but are allowed in some (but not all) positions that would normally 
appertain to decls:

```
using ptr = int *;
_Nullable ptr a1; // OK, but appertains to the decl and relies on sliding 
behaviour
ptr a2 _Nullable; // Not valid, but is another place to put standard decl 
attributes
extern int *const _Nullable volatile a3; // OK, but a standard attribute 
wouldn't be allowed here
```

The same distinction applies to Microsoft pointer attributes.

On the documentation side: I admit this is one of the awkward things about 
using a new keyword to prove the system.  The series doesn't actually implement 
`__arm_streaming` (@sdesmalen has patches for that, and other SME stuff).  So 
it didn't seem appropriate to document the attribute until it was actually 
implemented.  But the implementation, when it comes, will/should have 
documentation.



Comment at: clang/lib/AST/TypePrinter.cpp:1724-1727
+  if (T->getAttrKind() == attr::ArmStreaming) {
+OS << "__arm_streaming";
+return;
+  }

aaron.ballman wrote:
> This seems like something that tablegen should automatically handle more 
> generally for these attributes.
I wondered about trying to use tablegen for TypePrinter::printAttributedAfter, 
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.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-05-09 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm marked an inline comment as done.
rsandifo-arm added a comment.

In D148700#4280833 , @erichkeane 
wrote:

> Generally ok with all of this, but want some time to think about it/give 
> aaron/etc time to see it.

Hi @erichkeane & @aaron.ballman   Thanks for the reviews so far.  Do you have 
any more thoughts on this series?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D149148: [Sema] Fix _Alignas/isCXX11Attribute() FIXME

2023-04-26 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG5794ea421a0d: [Sema] Fix _Alignas/isCXX11Attribute() FIXME 
(authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149148/new/

https://reviews.llvm.org/D149148

Files:
  clang/lib/Sema/SemaDeclAttr.cpp


Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -8591,13 +8591,7 @@
 
   // Ignore C++11 attributes on declarator chunks: they appertain to the type
   // instead.
-  // FIXME: We currently check the attribute syntax directly instead of using
-  // isCXX11Attribute(), which currently erroneously classifies the C11
-  // `_Alignas` attribute as a C++11 attribute. `_Alignas` can appear on the
-  // `DeclSpec`, so we need to let it through here to make sure it is processed
-  // appropriately. Once the behavior of isCXX11Attribute() is fixed, we can
-  // go back to using that here.
-  if (AL.getSyntax() == ParsedAttr::AS_CXX11 && 
!Options.IncludeCXX11Attributes)
+  if (AL.isCXX11Attribute() && !Options.IncludeCXX11Attributes)
 return;
 
   // Unknown attributes are automatically warned on. Target-specific attributes


Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -8591,13 +8591,7 @@
 
   // Ignore C++11 attributes on declarator chunks: they appertain to the type
   // instead.
-  // FIXME: We currently check the attribute syntax directly instead of using
-  // isCXX11Attribute(), which currently erroneously classifies the C11
-  // `_Alignas` attribute as a C++11 attribute. `_Alignas` can appear on the
-  // `DeclSpec`, so we need to let it through here to make sure it is processed
-  // appropriately. Once the behavior of isCXX11Attribute() is fixed, we can
-  // go back to using that here.
-  if (AL.getSyntax() == ParsedAttr::AS_CXX11 && !Options.IncludeCXX11Attributes)
+  if (AL.isCXX11Attribute() && !Options.IncludeCXX11Attributes)
 return;
 
   // Unknown attributes are automatically warned on. Target-specific attributes
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D149148: [Sema] Fix _Alignas/isCXX11Attribute() FIXME

2023-04-25 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added a reviewer: erichkeane.
Herald added a reviewer: aaron.ballman.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

When doing https://reviews.llvm.org/D148105 , I hadn't noticed that
there was also a FIXME about the misclassification of _Alignas in
ProcessDeclAttribute.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149148

Files:
  clang/lib/Sema/SemaDeclAttr.cpp


Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -8591,13 +8591,7 @@
 
   // Ignore C++11 attributes on declarator chunks: they appertain to the type
   // instead.
-  // FIXME: We currently check the attribute syntax directly instead of using
-  // isCXX11Attribute(), which currently erroneously classifies the C11
-  // `_Alignas` attribute as a C++11 attribute. `_Alignas` can appear on the
-  // `DeclSpec`, so we need to let it through here to make sure it is processed
-  // appropriately. Once the behavior of isCXX11Attribute() is fixed, we can
-  // go back to using that here.
-  if (AL.getSyntax() == ParsedAttr::AS_CXX11 && 
!Options.IncludeCXX11Attributes)
+  if (AL.isCXX11Attribute() && !Options.IncludeCXX11Attributes)
 return;
 
   // Unknown attributes are automatically warned on. Target-specific attributes


Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -8591,13 +8591,7 @@
 
   // Ignore C++11 attributes on declarator chunks: they appertain to the type
   // instead.
-  // FIXME: We currently check the attribute syntax directly instead of using
-  // isCXX11Attribute(), which currently erroneously classifies the C11
-  // `_Alignas` attribute as a C++11 attribute. `_Alignas` can appear on the
-  // `DeclSpec`, so we need to let it through here to make sure it is processed
-  // appropriately. Once the behavior of isCXX11Attribute() is fixed, we can
-  // go back to using that here.
-  if (AL.getSyntax() == ParsedAttr::AS_CXX11 && !Options.IncludeCXX11Attributes)
+  if (AL.isCXX11Attribute() && !Options.IncludeCXX11Attributes)
 return;
 
   // Unknown attributes are automatically warned on. Target-specific attributes
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-04-19 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm marked an inline comment as done.
rsandifo-arm added inline comments.



Comment at: clang/include/clang/Basic/TokenKinds.def:751
+// Keywords defined by Attr.td.
+#define KEYWORD_ATTRIBUTE(X) KEYWORD(X, KEYALL)
+#include "clang/Basic/AttrTokenKinds.inc"

erichkeane wrote:
> Probably should be: `#ifndef KEYWORD_ATTRIBUTE` here.
Oops, yes, sorry.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-04-19 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 515033.
rsandifo-arm marked an inline comment as done.
rsandifo-arm added a comment.

Add #ifndef guard.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

Files:
  clang-tools-extra/pseudo/lib/grammar/CMakeLists.txt
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/include/clang/Basic/CMakeLists.txt
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Basic/TokenKinds.h
  clang/include/clang/Lex/Token.h
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/unittests/AST/AttrTest.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp
  clang/utils/TableGen/TableGen.cpp
  clang/utils/TableGen/TableGenBackends.h

Index: clang/utils/TableGen/TableGenBackends.h
===
--- clang/utils/TableGen/TableGenBackends.h
+++ clang/utils/TableGen/TableGenBackends.h
@@ -43,6 +43,8 @@
llvm::raw_ostream );
 void EmitClangAttrPCHRead(llvm::RecordKeeper , llvm::raw_ostream );
 void EmitClangAttrPCHWrite(llvm::RecordKeeper , llvm::raw_ostream );
+void EmitClangAttrTokenKinds(llvm::RecordKeeper ,
+ llvm::raw_ostream );
 void EmitClangAttrHasAttrImpl(llvm::RecordKeeper ,
   llvm::raw_ostream );
 void EmitClangAttrSpellingListIndex(llvm::RecordKeeper ,
Index: clang/utils/TableGen/TableGen.cpp
===
--- clang/utils/TableGen/TableGen.cpp
+++ clang/utils/TableGen/TableGen.cpp
@@ -35,6 +35,7 @@
   GenClangAttrSubjectMatchRuleList,
   GenClangAttrPCHRead,
   GenClangAttrPCHWrite,
+  GenClangAttrTokenKinds,
   GenClangAttrHasAttributeImpl,
   GenClangAttrSpellingListIndex,
   GenClangAttrASTVisitor,
@@ -128,6 +129,8 @@
"Generate clang PCH attribute reader"),
 clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write",
"Generate clang PCH attribute writer"),
+clEnumValN(GenClangAttrTokenKinds, "gen-clang-attr-token-kinds",
+   "Generate a list of attribute-related clang tokens"),
 clEnumValN(GenClangAttrHasAttributeImpl,
"gen-clang-attr-has-attribute-impl",
"Generate a clang attribute spelling list"),
@@ -303,6 +306,9 @@
   case GenClangAttrPCHWrite:
 EmitClangAttrPCHWrite(Records, OS);
 break;
+  case GenClangAttrTokenKinds:
+EmitClangAttrTokenKinds(Records, OS);
+break;
   case GenClangAttrHasAttributeImpl:
 EmitClangAttrHasAttrImpl(Records, OS);
 break;
Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2378,6 +2378,11 @@
   OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n";
 }
 
+static bool isRegularKeywordAttribute(const FlattenedSpelling ) {
+  return (S.variety() == "Keyword" &&
+  !S.getSpellingRecord().getValueAsBit("HasOwnParseRules"));
+}
+
 static void emitFormInitializer(raw_ostream ,
 const FlattenedSpelling ,
 StringRef SpellingIndex) {
@@ -2385,7 +2390,9 @@
   (Spelling.variety() == "Keyword" && Spelling.name() == "alignas");
   OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
  << SpellingIndex << ", " << (IsAlignas ? "true" : "false")
- << " /*IsAlignas*/}";
+ << " /*IsAlignas*/, "
+ << (isRegularKeywordAttribute(Spelling) ? "true" : "false")
+ << " /*IsRegularKeywordAttribute*/}";
 }
 
 static void emitAttributes(RecordKeeper , raw_ostream ,
@@ -3404,6 +3411,26 @@
   OS << ".Default(0);\n";
 }
 
+// Emits the list of tokens for regular keyword attributes.
+void EmitClangAttrTokenKinds(RecordKeeper , raw_ostream ) {
+  emitSourceFileHeader("A list of tokens generated from the attribute"
+   " definitions",
+   OS);
+  // Assume for now that the same token is not used in multiple regular
+  // keyword attributes.
+  for (auto *R : Records.getAllDerivedDefinitions("Attr"))
+for (const auto  : GetFlattenedSpellings(*R))
+  if (isRegularKeywordAttribute(S)) {
+if (!R->getValueAsListOfDefs("Args").empty())
+  PrintError(R->getLoc(),
+ "RegularKeyword attributes with arguments are not "
+ "yet supported");
+OS << "KEYWORD_ATTRIBUTE("
+   << S.getSpellingRecord().getValueAsString("Name") << ")\n";
+  }
+  OS << "#undef KEYWORD_ATTRIBUTE\n";
+}
+
 // Emits the list of spellings for attributes.
 void EmitClangAttrHasAttrImpl(RecordKeeper , raw_ostream ) {
   

[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-04-19 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm marked an inline comment as done.
rsandifo-arm added inline comments.



Comment at: clang/include/clang/Basic/TokenKinds.h:106
+#include "clang/Basic/AttrTokenKinds.inc"
+#undef KEYWORD
+  );

erichkeane wrote:
> Does AttrTokenKinds.inc not do this undef for you?  Most of our 
> tablegen'ed/.td files tend to...
> 
> Edit now that I've gone through the whole patch:
> 
> I see the inclusion into TokenKinds.def makes adding one a pain, but I 
> suggest instead making these be KEYWORD_ATTRIBUTE(...), with all the 
> 'fixings' that comes in TokenKinds.def (see the defines at the top), and then 
> including TokenKinds.def here instead.
Ah, yeah, that's neater, thanks.  It also means that the KEYALL can be moved to 
TokenKinds.def until such time (hopefully never) as it becomes necessary to 
vary it based on attribute.

Done in the updated version.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-04-19 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 514993.
rsandifo-arm added a comment.

Make AttrTokenKinds.inc use a new KEYWORD_ATTRIBUTE macro, rather than
using KEYWORD directly.  Move the #undef to the .inc file.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148700/new/

https://reviews.llvm.org/D148700

Files:
  clang-tools-extra/pseudo/lib/grammar/CMakeLists.txt
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/include/clang/Basic/CMakeLists.txt
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Basic/TokenKinds.h
  clang/include/clang/Lex/Token.h
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/unittests/AST/AttrTest.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp
  clang/utils/TableGen/TableGen.cpp
  clang/utils/TableGen/TableGenBackends.h

Index: clang/utils/TableGen/TableGenBackends.h
===
--- clang/utils/TableGen/TableGenBackends.h
+++ clang/utils/TableGen/TableGenBackends.h
@@ -43,6 +43,8 @@
llvm::raw_ostream );
 void EmitClangAttrPCHRead(llvm::RecordKeeper , llvm::raw_ostream );
 void EmitClangAttrPCHWrite(llvm::RecordKeeper , llvm::raw_ostream );
+void EmitClangAttrTokenKinds(llvm::RecordKeeper ,
+ llvm::raw_ostream );
 void EmitClangAttrHasAttrImpl(llvm::RecordKeeper ,
   llvm::raw_ostream );
 void EmitClangAttrSpellingListIndex(llvm::RecordKeeper ,
Index: clang/utils/TableGen/TableGen.cpp
===
--- clang/utils/TableGen/TableGen.cpp
+++ clang/utils/TableGen/TableGen.cpp
@@ -35,6 +35,7 @@
   GenClangAttrSubjectMatchRuleList,
   GenClangAttrPCHRead,
   GenClangAttrPCHWrite,
+  GenClangAttrTokenKinds,
   GenClangAttrHasAttributeImpl,
   GenClangAttrSpellingListIndex,
   GenClangAttrASTVisitor,
@@ -128,6 +129,8 @@
"Generate clang PCH attribute reader"),
 clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write",
"Generate clang PCH attribute writer"),
+clEnumValN(GenClangAttrTokenKinds, "gen-clang-attr-token-kinds",
+   "Generate a list of attribute-related clang tokens"),
 clEnumValN(GenClangAttrHasAttributeImpl,
"gen-clang-attr-has-attribute-impl",
"Generate a clang attribute spelling list"),
@@ -303,6 +306,9 @@
   case GenClangAttrPCHWrite:
 EmitClangAttrPCHWrite(Records, OS);
 break;
+  case GenClangAttrTokenKinds:
+EmitClangAttrTokenKinds(Records, OS);
+break;
   case GenClangAttrHasAttributeImpl:
 EmitClangAttrHasAttrImpl(Records, OS);
 break;
Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2378,6 +2378,11 @@
   OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n";
 }
 
+static bool isRegularKeywordAttribute(const FlattenedSpelling ) {
+  return (S.variety() == "Keyword" &&
+  !S.getSpellingRecord().getValueAsBit("HasOwnParseRules"));
+}
+
 static void emitFormInitializer(raw_ostream ,
 const FlattenedSpelling ,
 StringRef SpellingIndex) {
@@ -2385,7 +2390,9 @@
   (Spelling.variety() == "Keyword" && Spelling.name() == "alignas");
   OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
  << SpellingIndex << ", " << (IsAlignas ? "true" : "false")
- << " /*IsAlignas*/}";
+ << " /*IsAlignas*/, "
+ << (isRegularKeywordAttribute(Spelling) ? "true" : "false")
+ << " /*IsRegularKeywordAttribute*/}";
 }
 
 static void emitAttributes(RecordKeeper , raw_ostream ,
@@ -3404,6 +3411,26 @@
   OS << ".Default(0);\n";
 }
 
+// Emits the list of tokens for regular keyword attributes.
+void EmitClangAttrTokenKinds(RecordKeeper , raw_ostream ) {
+  emitSourceFileHeader("A list of tokens generated from the attribute"
+   " definitions",
+   OS);
+  // Assume for now that the same token is not used in multiple regular
+  // keyword attributes.
+  for (auto *R : Records.getAllDerivedDefinitions("Attr"))
+for (const auto  : GetFlattenedSpellings(*R))
+  if (isRegularKeywordAttribute(S)) {
+if (!R->getValueAsListOfDefs("Args").empty())
+  PrintError(R->getLoc(),
+ "RegularKeyword attributes with arguments are not "
+ "yet supported");
+OS << "KEYWORD_ATTRIBUTE("
+   << S.getSpellingRecord().getValueAsString("Name") << ")\n";
+  }
+  OS << "#undef KEYWORD_ATTRIBUTE\n";
+}
+
 // Emits the list of spellings for attributes.
 void 

[PATCH] D148702: [clang] Add Parse and Sema support for RegularKeyword attributes

2023-04-19 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm marked an inline comment as done.
rsandifo-arm added a comment.

Thanks for the reviews!

In D148702#4280392 , @erichkeane 
wrote:

> So I don't mind the changes in this stack, though this doing a little bit of 
> a 'backdoor' way of getting the arm-streaming attribute in rubs me the wrong 
> way.  I'm not a huge fan that the solution we've got here only solves THIS 
> problem, and doesn't extend to improving the situation with older attributes 
> as well.

Yeah, it looks a bit over-the-top/special-purpose when `__arm_streaming` is the 
only thing using it.  But we (Arm) have other “semantic attributes” in the 
pipeline, and this would be useful for them too.  Hopefully other targets will 
find the same.

We could even go back and retroactively support keywords for some existing Arm 
semantic attributes.  E.g. maybe we could allow `__aarch64_vector_pcs` 
alongside `__attribute__((aarch64_vector_pcs))`.  I'd have to see what others 
think.

But as far as I could tell, there are no existing keyword attributes whose 
grammar is close enough to standard attributes for the keywords to use the new 
infrastructure.  E.g. many existing keywords are allowed between qualifiers, 
whereas standard attributes aren't:

  int (__stdcall a1)(); // OK, but standard attributes aren't allowed in this 
position
  extern int (*const __stdcall volatile a2) (); // OK, but standard attributes 
wouldn't be allowed here

I don't think we can retroactively forbid these.  But I don't think it makes 
sense to allow new attributes like `__arm_streaming` in these positions either.




Comment at: clang/lib/Sema/SemaDecl.cpp:5308
   for (const ParsedAttr  : DS.getAttributes())
-Diag(AL.getLoc(), diag::warn_declspec_attribute_ignored)
+Diag(AL.getLoc(), AL.isRegularKeywordAttribute()
+  ? diag::err_declspec_keyword_has_no_effect

erichkeane wrote:
> Is this function (isRegularKeywordAttribute) checking spellings?  If not, it 
> needs to.  
Yeah, this is checking the spelling.  In principle, the series supports 
attributes that have a RegularKeyword spelling and some other spelling, and in 
that case, this check would only include attributes that were written using the 
RegularKeyword spelling.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148702/new/

https://reviews.llvm.org/D148702

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148699: [clang] Mark keywords that have their own parsing rules

2023-04-19 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

See https://reviews.llvm.org/D139028 for previous discussion on this topic.  
https://reviews.llvm.org/D148700 contains the Attr.td support (and the main 
rationale) while https://reviews.llvm.org/D148702 contains the main Parse & 
Sema support.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148699/new/

https://reviews.llvm.org/D148699

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148702: [clang] Add Parse and Sema support for RegularKeyword attributes

2023-04-19 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: erichkeane, aaron.ballman.
Herald added subscribers: jdoerfert, kristof.beyls, dschuff.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added subscribers: cfe-commits, aheejin.
Herald added a project: clang.

This patch adds the Parse and Sema support for RegularKeyword attributes,
following on from a previous patch that added Attr.td support.

The patch is quite large.  However, nothing outside the tests is
specific to the first RegularKeyword attribute (__arm_streaming).
The patch should therefore be a one-off, up-front cost.  Other
attributes just need an entry in Attr.td and the usual Sema support.

The approach taken in the patch is that the keywords can be used with
any language version.  If standard attributes were added in language
version Y, the keyword rules for version Xhttps://reviews.llvm.org/D148702

Files:
  clang/examples/Attribute/Attribute.cpp
  clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/ParsedAttr.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaStmtAttr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/Parser/c2x-attribute-keywords.c
  clang/test/Parser/c2x-attribute-keywords.m
  clang/test/Parser/cxx0x-keyword-attributes.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3878,7 +3878,8 @@
   OS << "bool diagAppertainsToDecl(Sema , const ParsedAttr , ";
   OS << "const Decl *D) const override {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)\n";
-  OS << "<< AL << D->getLocation();\n";
+  OS << "<< AL << AL.isRegularKeywordAttribute() << "
+"D->getLocation();\n";
   OS << "  return false;\n";
   OS << "}\n\n";
 }
@@ -3907,7 +3908,7 @@
 OS << (Warn ? "warn_attribute_wrong_decl_type_str"
 : "err_attribute_wrong_decl_type_str");
 OS << ")\n";
-OS << "  << Attr << ";
+OS << "  << Attr << Attr.isRegularKeywordAttribute() << ";
 OS << CalculateDiagnostic(*SubjectObj) << ";\n";
 OS << "return false;\n";
 OS << "  }\n";
@@ -3922,7 +3923,8 @@
   OS << "bool diagAppertainsToStmt(Sema , const ParsedAttr , ";
   OS << "const Stmt *St) const override {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_decl_attribute_invalid_on_stmt)\n";
-  OS << "<< AL << St->getBeginLoc();\n";
+  OS << "<< AL << AL.isRegularKeywordAttribute() << "
+"St->getBeginLoc();\n";
   OS << "  return false;\n";
   OS << "}\n\n";
 }
@@ -3941,7 +3943,7 @@
 OS << (Warn ? "warn_attribute_wrong_decl_type_str"
 : "err_attribute_wrong_decl_type_str");
 OS << ")\n";
-OS << "  << Attr << ";
+OS << "  << Attr << Attr.isRegularKeywordAttribute() << ";
 OS << CalculateDiagnostic(*SubjectObj) << ";\n";
 OS << "return false;\n";
 OS << "  }\n";
@@ -4012,7 +4014,8 @@
 for (const std::string  : DeclAttrs) {
   OS << "if (const auto *A = D->getAttr<" << A << ">()) {\n";
   OS << "  S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)"
- << " << AL << A;\n";
+ << " << AL << A << (AL.isRegularKeywordAttribute() ||"
+ << " A->isRegularKeywordAttribute());\n";
   OS << "  S.Diag(A->getLocation(), diag::note_conflicting_attribute);";
   OS << "  \nreturn false;\n";
   OS << "}\n";
@@ -4033,7 +4036,8 @@
 << ">()) {\n";
 MergeDeclOS << "  S.Diag(First->getLocation(), "
 << "diag::err_attributes_are_not_compatible) << First << "
-<< "Second;\n";
+<< "Second << (First->isRegularKeywordAttribute() || "
+<< "Second->isRegularKeywordAttribute());\n";
 MergeDeclOS << "  S.Diag(Second->getLocation(), "
 << "diag::note_conflicting_attribute);\n";
 MergeDeclOS << "  return false;\n";
@@ -4073,7 +4077,8 @@
 MergeStmtOS << "  if (Iter != C.end()) {\n";
 MergeStmtOS << "S.Diag((*Iter)->getLocation(), "
 << "diag::err_attributes_are_not_compatible) << *Iter << "
-

[PATCH] D148700: [clang] Add support for “regular” keyword attributes

2023-04-19 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: erichkeane, aaron.ballman.
Herald added subscribers: kristof.beyls, dschuff.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added subscribers: cfe-commits, aheejin.
Herald added projects: clang, clang-tools-extra.

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

[PATCH] D148699: [clang] Mark keywords that have their own parsing rules

2023-04-19 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch retroactively classified all existing keyword attributes
as “custom” keyword attributes, in the sense that the keywords have
their own custom parsing rules.  A follow-on patch will add an
alternative type of keyword.

No functional change intended.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148699

Files:
  clang/include/clang/Basic/Attr.td

Index: clang/include/clang/Basic/Attr.td
===
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -311,7 +311,13 @@
   string Namespace = namespace;
 }
 
-class Keyword : Spelling;
+class Keyword
+: Spelling {
+  bit HasOwnParseRules = hasOwnParseRules;
+}
+// A keyword that has its own individual parsing rules.
+class CustomKeyword : Keyword {}
+
 class Pragma : Spelling {
   string Namespace = namespace;
 }
@@ -709,13 +715,13 @@
 }
 
 def Aligned : InheritableAttr {
-  let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
-   Keyword<"_Alignas">];
+  let Spellings = [GCC<"aligned">, Declspec<"align">, CustomKeyword<"alignas">,
+   CustomKeyword<"_Alignas">];
   let Args = [AlignedArgument<"Alignment", 1>];
   let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>,
-   Accessor<"isC11", [Keyword<"_Alignas">]>,
-   Accessor<"isAlignas", [Keyword<"alignas">,
-  Keyword<"_Alignas">]>,
+   Accessor<"isC11", [CustomKeyword<"_Alignas">]>,
+   Accessor<"isAlignas", [CustomKeyword<"alignas">,
+  CustomKeyword<"_Alignas">]>,
Accessor<"isDeclspec",[Declspec<"align">]>];
   let Documentation = [Undocumented];
 }
@@ -756,7 +762,7 @@
 
 def AlwaysInline : DeclOrStmtAttr {
   let Spellings = [GCC<"always_inline">, CXX11<"clang", "always_inline">,
-   C2x<"clang", "always_inline">, Keyword<"__forceinline">];
+   C2x<"clang", "always_inline">, CustomKeyword<"__forceinline">];
   let Accessors = [Accessor<"isClangAlwaysInline", [CXX11<"clang", "always_inline">,
 C2x<"clang", "always_inline">]>];
   let Subjects = SubjectList<[Function, Stmt], WarnDiag,
@@ -879,7 +885,7 @@
 }
 
 def AsmLabel : InheritableAttr {
-  let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
+  let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm__">];
   let Args = [
 // Label specifies the mangled name for the decl.
 StringArgument<"Label">,
@@ -997,7 +1003,7 @@
 }
 
 def CDecl : DeclOrTypeAttr {
-  let Spellings = [GCC<"cdecl">, Keyword<"__cdecl">, Keyword<"_cdecl">];
+  let Spellings = [GCC<"cdecl">, CustomKeyword<"__cdecl">, CustomKeyword<"_cdecl">];
 //  let Subjects = [Function, ObjCMethod];
   let Documentation = [Undocumented];
 }
@@ -1122,10 +1128,10 @@
 def ConstInit : InheritableAttr {
   // This attribute does not have a C [[]] spelling because it requires the
   // CPlusPlus language option.
-  let Spellings = [Keyword<"constinit">,
+  let Spellings = [CustomKeyword<"constinit">,
Clang<"require_constant_initialization", 0>];
   let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
-  let Accessors = [Accessor<"isConstinit", [Keyword<"constinit">]>];
+  let Accessors = [Accessor<"isConstinit", [CustomKeyword<"constinit">]>];
   let Documentation = [ConstInitDocs];
   let LangOpts = [CPlusPlus];
   let SimpleHandler = 1;
@@ -1276,7 +1282,7 @@
 }
 
 def C11NoReturn : InheritableAttr {
-  let Spellings = [Keyword<"_Noreturn">];
+  let Spellings = [CustomKeyword<"_Noreturn">];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let SemaHandler = 0;
   let Documentation = [C11NoReturnDocs];
@@ -1292,7 +1298,7 @@
 // Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because
 // the specification does not expose them with one currently.
 def OpenCLKernel : InheritableAttr {
-  let Spellings = [Keyword<"__kernel">, Keyword<"kernel">];
+  let Spellings = [CustomKeyword<"__kernel">, CustomKeyword<"kernel">];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let Documentation = [Undocumented];
   let SimpleHandler = 1;
@@ -1316,26 +1322,28 @@
 // This attribute is both a type attribute, and a declaration attribute (for
 // parameter variables).
 def OpenCLAccess : Attr {
-  let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
-   Keyword<"__write_only">, Keyword<"write_only">,
-   Keyword<"__read_write">, Keyword<"read_write">];
+  let Spellings = [CustomKeyword<"__read_only">, CustomKeyword<"read_only">,
+   

[PATCH] D148148: [clang] Bump AS_GNU to 1

2023-04-13 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG053bdb77b0ce: [clang] Bump AS_GNU to 1 (authored by 
rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148148/new/

https://reviews.llvm.org/D148148

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h


Index: clang/include/clang/Basic/AttributeCommonInfo.h
===
--- clang/include/clang/Basic/AttributeCommonInfo.h
+++ clang/include/clang/Basic/AttributeCommonInfo.h
@@ -25,7 +25,7 @@
   /// The style used to specify an attribute.
   enum Syntax {
 /// __attribute__((...))
-AS_GNU,
+AS_GNU = 1,
 
 /// [[...]]
 AS_CXX11,
@@ -122,37 +122,32 @@
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Form FormUsed)
+  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
   : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc),
-AttrKind(getParsedKind(AttrName, ScopeName, FormUsed.getSyntax())),
+ScopeLoc(ScopeLoc), AttrKind(AttrKind),
 SyntaxUsed(FormUsed.getSyntax()),
 SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+IsAlignas(FormUsed.isAlignas()) {
+assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
+   "Invalid syntax!");
+  }
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
-  : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc), AttrKind(AttrKind),
-SyntaxUsed(FormUsed.getSyntax()),
-SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+  SourceLocation ScopeLoc, Form FormUsed)
+  : AttributeCommonInfo(
+AttrName, ScopeName, AttrRange, ScopeLoc,
+getParsedKind(AttrName, ScopeName, FormUsed.getSyntax()),
+FormUsed) {}
 
   AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange,
   Form FormUsed)
-  : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange),
-ScopeLoc(),
-AttrKind(getParsedKind(AttrName, ScopeName, FormUsed.getSyntax())),
-SyntaxUsed(FormUsed.getSyntax()),
-SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+  : AttributeCommonInfo(AttrName, nullptr, AttrRange, SourceLocation(),
+FormUsed) {}
 
   AttributeCommonInfo(SourceRange AttrRange, Kind K, Form FormUsed)
-  : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), 
ScopeLoc(),
-AttrKind(K), SyntaxUsed(FormUsed.getSyntax()),
-SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+  : AttributeCommonInfo(nullptr, nullptr, AttrRange, SourceLocation(), K,
+FormUsed) {}
 
   AttributeCommonInfo(AttributeCommonInfo &&) = default;
   AttributeCommonInfo(const AttributeCommonInfo &) = default;


Index: clang/include/clang/Basic/AttributeCommonInfo.h
===
--- clang/include/clang/Basic/AttributeCommonInfo.h
+++ clang/include/clang/Basic/AttributeCommonInfo.h
@@ -25,7 +25,7 @@
   /// The style used to specify an attribute.
   enum Syntax {
 /// __attribute__((...))
-AS_GNU,
+AS_GNU = 1,
 
 /// [[...]]
 AS_CXX11,
@@ -122,37 +122,32 @@
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Form FormUsed)
+  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
   : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc),
-AttrKind(getParsedKind(AttrName, ScopeName, FormUsed.getSyntax())),
+ScopeLoc(ScopeLoc), AttrKind(AttrKind),
 SyntaxUsed(FormUsed.getSyntax()),
 SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+IsAlignas(FormUsed.isAlignas()) {
+assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
+   "Invalid syntax!");
+  }
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
-  : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc), 

[PATCH] D148105: [clang] Fix FIXME in isAlignasAttribute()

2023-04-13 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbd41371be02f: [clang] Fix FIXME in isAlignasAttribute() 
(authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148105/new/

https://reviews.llvm.org/D148105

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2381,8 +2381,11 @@
 static void emitFormInitializer(raw_ostream ,
 const FlattenedSpelling ,
 StringRef SpellingIndex) {
+  bool IsAlignas =
+  (Spelling.variety() == "Keyword" && Spelling.name() == "alignas");
   OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
- << SpellingIndex << "}";
+ << SpellingIndex << ", " << (IsAlignas ? "true" : "false")
+ << " /*IsAlignas*/}";
 }
 
 static void emitAttributes(RecordKeeper , raw_ostream ,
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3091,11 +3091,14 @@
   unsigned ParsedKind = Record.readInt();
   unsigned Syntax = Record.readInt();
   unsigned SpellingIndex = Record.readInt();
+  bool IsAlignas = (ParsedKind == AttributeCommonInfo::AT_Aligned &&
+Syntax == AttributeCommonInfo::AS_Keyword &&
+SpellingIndex == AlignedAttr::Keyword_alignas);
 
   AttributeCommonInfo Info(
   AttrName, ScopeName, AttrRange, ScopeLoc,
   AttributeCommonInfo::Kind(ParsedKind),
-  {AttributeCommonInfo::Syntax(Syntax), SpellingIndex});
+  {AttributeCommonInfo::Syntax(Syntax), SpellingIndex, IsAlignas});
 
 #include "clang/Serialization/AttrPCHRead.inc"
 
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -4893,9 +4893,9 @@
 
 // If we're supposed to infer nullability, do so now.
 if (inferNullability && !inferNullabilityInnerOnlyComplete) {
-  ParsedAttr::Form form = inferNullabilityCS
-  ? ParsedAttr::Form::ContextSensitiveKeyword()
-  : ParsedAttr::Form::Keyword();
+  ParsedAttr::Form form =
+  inferNullabilityCS ? ParsedAttr::Form::ContextSensitiveKeyword()
+ : ParsedAttr::Form::Keyword(false /*IsAlignAs*/);
   ParsedAttr *nullabilityAttr = Pool.create(
   S.getNullabilityKeyword(*inferNullability), SourceRange(pointerLoc),
   nullptr, SourceLocation(), nullptr, 0, form);
Index: clang/include/clang/Basic/AttributeCommonInfo.h
===
--- clang/include/clang/Basic/AttributeCommonInfo.h
+++ clang/include/clang/Basic/AttributeCommonInfo.h
@@ -76,6 +76,7 @@
   /// Corresponds to the Syntax enum.
   unsigned SyntaxUsed : 4;
   unsigned SpellingIndex : 4;
+  unsigned IsAlignas : 1;
 
 protected:
   static constexpr unsigned SpellingNotCalculated = 0xf;
@@ -85,20 +86,25 @@
   /// including its syntax and spelling.
   class Form {
   public:
-constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex)
-: SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex) {}
-constexpr Form(tok::TokenKind)
-: SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated) {}
+constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex, bool IsAlignas)
+: SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex),
+  IsAlignas(IsAlignas) {}
+constexpr Form(tok::TokenKind Tok)
+: SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated),
+  IsAlignas(Tok == tok::kw_alignas) {}
 
 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
 unsigned getSpellingIndex() const { return SpellingIndex; }
+bool isAlignas() const { return IsAlignas; }
 
 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 Keyword(bool IsAlignas) {
+  return Form(AS_Keyword, SpellingNotCalculated, IsAlignas);
+}
 static Form Pragma() { return AS_Pragma; }
 static Form ContextSensitiveKeyword() { return AS_ContextSensitiveKeyword; }
 static Form HLSLSemantic() { return AS_HLSLSemantic; }
@@ -106,10 +112,12 @@
 
   private:
 constexpr Form(Syntax SyntaxUsed)
-: 

[PATCH] D148104: [clang] Type safety tweak for AttributeCommonInfo::Form

2023-04-13 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGaec3f951bf36: [clang] Type safety tweak for 
AttributeCommonInfo::Form (authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148104/new/

https://reviews.llvm.org/D148104

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseHLSL.cpp
  clang/lib/Parse/ParseObjc.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2621,7 +2621,7 @@
 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");
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -4893,12 +4893,12 @@
 
 // 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 @@
   ParsedAttr *attr = D.getAttributePool().create(
   ("objc_ownership"), SourceLocation(),
   /*scope*/ nullptr, SourceLocation(),
-  /*args*/ , 1, ParsedAttr::AS_GNU);
+  /*args*/ , 1, ParsedAttr::Form::GNU());
   chunk.getAttrs().addAtEnd(attr);
   // TODO: mark whether we did this inference?
 }
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -19862,7 +19862,7 @@
   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);
 
Index: clang/lib/Sema/SemaAttr.cpp
===
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -860,7 +860,7 @@
 return;
 
   AttributeCommonInfo Info(Ident, SourceRange(Loc),
-   AttributeCommonInfo::AS_Pragma);
+   AttributeCommonInfo::Form::Pragma());
   D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info));
 }
 
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -2411,7 +2411,7 @@
 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.
Index: clang/lib/Parse/ParsePragma.cpp
===
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -1850,11 +1850,12 @@
 
   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(),
+  

[PATCH] D148103: [clang] Allow attributes to be constructed from keyword tokens

2023-04-13 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG265d87e46535: [clang] Allow attributes to be constructed 
from keyword tokens (authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148103/new/

https://reviews.llvm.org/D148103

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp

Index: clang/lib/Parse/ParseExprCXX.cpp
===
--- clang/lib/Parse/ParseExprCXX.cpp
+++ clang/lib/Parse/ParseExprCXX.cpp
@@ -1300,7 +1300,7 @@
 SourceLocation AttrNameLoc = ConsumeToken();
 Attributes.addNew(AttrName, AttrNameLoc, /*ScopeName=*/nullptr,
   AttrNameLoc, /*ArgsUnion=*/nullptr,
-  /*numArgs=*/0, ParsedAttr::AS_Keyword);
+  /*numArgs=*/0, tok::kw___noinline__);
   } else if (Tok.is(tok::kw___attribute))
 ParseGNUAttributes(Attributes, /*LatePArsedAttrList=*/nullptr, );
   else
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -1370,9 +1370,9 @@
  tok::kw___multiple_inheritance,
  tok::kw___virtual_inheritance)) {
 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+auto Kind = Tok.getKind();
 SourceLocation AttrNameLoc = ConsumeToken();
-attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- ParsedAttr::AS_Keyword);
+attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);
   }
 }
 
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -828,7 +828,8 @@
 void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes ) {
   // Treat these like attributes
   while (true) {
-switch (Tok.getKind()) {
+auto Kind = Tok.getKind();
+switch (Kind) {
 case tok::kw___fastcall:
 case tok::kw___stdcall:
 case tok::kw___thiscall:
@@ -843,7 +844,7 @@
   IdentifierInfo *AttrName = Tok.getIdentifierInfo();
   SourceLocation AttrNameLoc = ConsumeToken();
   attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
-   ParsedAttr::AS_Keyword);
+   Kind);
   break;
 }
 default:
@@ -865,7 +866,7 @@
   SourceLocation AttrNameLoc = ConsumeToken();
   attrs.addNew(AttrName, AttrNameLoc, /*ScopeName=*/nullptr,
/*ScopeLoc=*/SourceLocation{}, /*Args=*/nullptr, /*numArgs=*/0,
-   ParsedAttr::AS_Keyword);
+   tok::kw___funcref);
 }
 
 void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
@@ -910,7 +911,7 @@
 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
 SourceLocation AttrNameLoc = ConsumeToken();
 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- ParsedAttr::AS_Keyword);
+ tok::kw___pascal);
   }
 }
 
@@ -920,7 +921,7 @@
 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
 SourceLocation AttrNameLoc = ConsumeToken();
 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- ParsedAttr::AS_Keyword);
+ tok::kw___kernel);
   }
 }
 
@@ -929,7 +930,7 @@
 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
 SourceLocation AttrNameLoc = ConsumeToken();
 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- ParsedAttr::AS_Keyword);
+ tok::kw___noinline__);
   }
 }
 
@@ -937,7 +938,7 @@
   IdentifierInfo *AttrName = Tok.getIdentifierInfo();
   SourceLocation AttrNameLoc = Tok.getLocation();
   Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
-   ParsedAttr::AS_Keyword);
+   Tok.getKind());
 }
 
 bool Parser::isHLSLQualifier(const Token ) const {
@@ -946,15 +947,16 @@
 
 void Parser::ParseHLSLQualifiers(ParsedAttributes ) {
   IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+  auto Kind = Tok.getKind();
   SourceLocation AttrNameLoc = ConsumeToken();
-  Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
-   ParsedAttr::AS_Keyword);
+  Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);
 }
 
 void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes ) {
   // Treat these like attributes, even though they're type specifiers.
   while (true) {
-switch (Tok.getKind()) {
+auto Kind = Tok.getKind();
+switch (Kind) {
 case tok::kw__Nonnull:
 case tok::kw__Nullable:
 case tok::kw__Nullable_result:
@@ -965,7 +967,7 @@
 Diag(AttrNameLoc, diag::ext_nullability)
 

[PATCH] D148102: [clang] Specify attribute syntax & spelling with a single argument

2023-04-13 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb6d4d51f8f5a: [clang] Specify attribute syntax  
spelling with a single argument (authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148102/new/

https://reviews.llvm.org/D148102

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/ParsedAttr.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/HLSLExternalSemaSource.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaObjCProperty.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2378,6 +2378,13 @@
   OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n";
 }
 
+static void emitFormInitializer(raw_ostream ,
+const FlattenedSpelling ,
+StringRef SpellingIndex) {
+  OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
+ << SpellingIndex << "}";
+}
+
 static void emitAttributes(RecordKeeper , raw_ostream ,
bool Header) {
   std::vector Attrs = Records.getAllDerivedDefinitions("Attr");
@@ -2595,14 +2602,9 @@
   if (Header)
 OS << " = {}";
   if (Spellings.size() > 1) {
-OS << ", AttributeCommonInfo::Syntax Syntax";
+OS << ", Spelling S";
 if (Header)
-  OS << " = AttributeCommonInfo::AS_" << Spellings[0].variety();
-  }
-  if (!ElideSpelling) {
-OS << ", " << R.getName() << "Attr::Spelling S";
-if (Header)
-  OS << " = static_cast(SpellingNotCalculated)";
+  OS << " = " << SemanticToSyntacticMap[0];
   }
   OS << ")";
   if (Header) {
@@ -2618,15 +2620,31 @@
   else
 OS << "NoSemaHandlerAttribute";
 
-  if (Spellings.size() == 0)
+  if (Spellings.size() == 0) {
 OS << ", AttributeCommonInfo::AS_Implicit";
-  else if (Spellings.size() == 1)
-OS << ", AttributeCommonInfo::AS_" << Spellings[0].variety();
-  else
-OS << ", Syntax";
+  } else if (Spellings.size() == 1) {
+OS << ", ";
+emitFormInitializer(OS, Spellings[0], "0");
+  } else {
+OS << ", (\n";
+std::set Uniques;
+unsigned Idx = 0;
+for (auto I = Spellings.begin(), E = Spellings.end(); I != E;
+ ++I, ++Idx) {
+  const FlattenedSpelling  = *I;
+  const auto  = SemanticToSyntacticMap[Idx];
+  if (Uniques.insert(Name).second) {
+OS << "S == " << Name << " ? AttributeCommonInfo::Form";
+emitFormInitializer(OS, S, Name);
+OS << " :\n";
+  }
+}
+OS << "(llvm_unreachable(\"Unknown attribute spelling!\"), "
+   << " AttributeCommonInfo::Form";
+emitFormInitializer(OS, Spellings[0], "0");
+OS << "))";
+  }
 
-  if (!ElideSpelling)
-OS << ", S";
   OS << ");\n";
   OS << "  return Create";
   if (Implicit)
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3092,9 +3092,10 @@
   unsigned Syntax = Record.readInt();
   unsigned SpellingIndex = Record.readInt();
 
-  AttributeCommonInfo Info(AttrName, ScopeName, AttrRange, ScopeLoc,
-   AttributeCommonInfo::Kind(ParsedKind),
-   AttributeCommonInfo::Syntax(Syntax), SpellingIndex);
+  AttributeCommonInfo Info(
+  AttrName, ScopeName, AttrRange, ScopeLoc,
+  AttributeCommonInfo::Kind(ParsedKind),
+  {AttributeCommonInfo::Syntax(Syntax), SpellingIndex});
 
 #include "clang/Serialization/AttrPCHRead.inc"
 
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -8970,8 +8970,7 @@
   ? S.ImplicitMSInheritanceAttrLoc
   : RD->getSourceRange();
 RD->addAttr(MSInheritanceAttr::CreateImplicit(
-S.getASTContext(), BestCase, Loc, AttributeCommonInfo::AS_Microsoft,
-MSInheritanceAttr::Spelling(IM)));
+S.getASTContext(), BestCase, Loc, MSInheritanceAttr::Spelling(IM)));
 S.Consumer.AssignInheritanceModel(RD);
   }
 }
Index: clang/lib/Sema/SemaOpenMP.cpp

[PATCH] D148101: [clang] Ensure that Attr::Create(Implicit) chooses a valid syntax

2023-04-13 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGe841d5092634: [clang] Ensure that Attr::Create(Implicit) 
chooses a valid syntax (authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148101/new/

https://reviews.llvm.org/D148101

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/unittests/AST/DeclTest.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2505,15 +2505,8 @@
   return  == P.second;
 });
 
-enum class CreateKind {
-  WithAttributeCommonInfo,
-  WithSourceRange,
-  WithNoArgs,
-};
-
 // Emit CreateImplicit factory methods.
-auto emitCreate = [&](bool Implicit, bool DelayedArgsOnly,
-  bool emitFake, CreateKind Kind) {
+auto emitCreate = [&](bool Implicit, bool DelayedArgsOnly, bool emitFake) {
   if (Header)
 OS << "  static ";
   OS << R.getName() << "Attr *";
@@ -2537,10 +2530,7 @@
 OS << ", ";
 DelayedArgs->writeCtorParameters(OS);
   }
-  if (Kind == CreateKind::WithAttributeCommonInfo)
-OS << ", const AttributeCommonInfo ";
-  else if (Kind == CreateKind::WithSourceRange)
-OS << ", SourceRange R";
+  OS << ", const AttributeCommonInfo ";
   OS << ")";
   if (Header) {
 OS << ";\n";
@@ -2549,12 +2539,7 @@
 
   OS << " {\n";
   OS << "  auto *A = new (Ctx) " << R.getName();
-  if (Kind == CreateKind::WithAttributeCommonInfo)
-OS << "Attr(Ctx, CommonInfo";
-  else if (Kind == CreateKind::WithSourceRange)
-OS << "Attr(Ctx, AttributeCommonInfo{R}";
-  else if (Kind == CreateKind::WithNoArgs)
-OS << "Attr(Ctx, AttributeCommonInfo{SourceLocation{}}";
+  OS << "Attr(Ctx, CommonInfo";
 
   if (!DelayedArgsOnly) {
 for (auto const  : Args) {
@@ -2606,7 +2591,14 @@
 OS << ", ";
 DelayedArgs->writeCtorParameters(OS);
   }
-  OS << ", SourceRange Range, AttributeCommonInfo::Syntax Syntax";
+  OS << ", SourceRange Range";
+  if (Header)
+OS << " = {}";
+  if (Spellings.size() > 1) {
+OS << ", AttributeCommonInfo::Syntax Syntax";
+if (Header)
+  OS << " = AttributeCommonInfo::AS_" << Spellings[0].variety();
+  }
   if (!ElideSpelling) {
 OS << ", " << R.getName() << "Attr::Spelling S";
 if (Header)
@@ -2626,7 +2618,13 @@
   else
 OS << "NoSemaHandlerAttribute";
 
-  OS << ", Syntax";
+  if (Spellings.size() == 0)
+OS << ", AttributeCommonInfo::AS_Implicit";
+  else if (Spellings.size() == 1)
+OS << ", AttributeCommonInfo::AS_" << Spellings[0].variety();
+  else
+OS << ", Syntax";
+
   if (!ElideSpelling)
 OS << ", S";
   OS << ");\n";
@@ -2651,19 +2649,9 @@
   OS << "}\n\n";
 };
 
-auto emitBothImplicitAndNonCreates = [&](bool DelayedArgsOnly,
- bool emitFake, CreateKind Kind) {
-  emitCreate(true, DelayedArgsOnly, emitFake, Kind);
-  emitCreate(false, DelayedArgsOnly, emitFake, Kind);
-};
-
 auto emitCreates = [&](bool DelayedArgsOnly, bool emitFake) {
-  emitBothImplicitAndNonCreates(DelayedArgsOnly, emitFake,
-CreateKind::WithNoArgs);
-  emitBothImplicitAndNonCreates(DelayedArgsOnly, emitFake,
-CreateKind::WithAttributeCommonInfo);
-  emitBothImplicitAndNonCreates(DelayedArgsOnly, emitFake,
-CreateKind::WithSourceRange);
+  emitCreate(true, DelayedArgsOnly, emitFake);
+  emitCreate(false, DelayedArgsOnly, emitFake);
   emitCreateNoCI(true, DelayedArgsOnly, emitFake);
   emitCreateNoCI(false, DelayedArgsOnly, emitFake);
 };
@@ -3468,6 +3456,10 @@
   OS << "case AttributeCommonInfo::Syntax::AS_ContextSensitiveKeyword:\n";
   OS << "  llvm_unreachable(\"hasAttribute not supported for keyword\");\n";
   OS << "  return 0;\n";
+  OS << "case AttributeCommonInfo::Syntax::AS_Implicit:\n";
+  OS << "  llvm_unreachable (\"hasAttribute not supported for "
+"AS_Implicit\");\n";
+  OS << "  return 0;\n";
 
   OS << "}\n";
 }
Index: clang/unittests/AST/DeclTest.cpp
===
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -88,12 +88,8 @@
   NamedDecl *DeclG = *(++DeclS->method_begin());
 
   // Attach asm labels to the decls: one literal, and one not.
-  DeclF->addAttr(::new 

[PATCH] D148102: [clang] Specify attribute syntax & spelling with a single argument

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 512993.
rsandifo-arm added a comment.

Tweak initializer to avoid an MSVC error: https://godbolt.org/z/sMxsW8G8j


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148102/new/

https://reviews.llvm.org/D148102

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/ParsedAttr.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/HLSLExternalSemaSource.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaObjCProperty.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2378,6 +2378,13 @@
   OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n";
 }
 
+static void emitFormInitializer(raw_ostream ,
+const FlattenedSpelling ,
+StringRef SpellingIndex) {
+  OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
+ << SpellingIndex << "}";
+}
+
 static void emitAttributes(RecordKeeper , raw_ostream ,
bool Header) {
   std::vector Attrs = Records.getAllDerivedDefinitions("Attr");
@@ -2595,14 +2602,9 @@
   if (Header)
 OS << " = {}";
   if (Spellings.size() > 1) {
-OS << ", AttributeCommonInfo::Syntax Syntax";
+OS << ", Spelling S";
 if (Header)
-  OS << " = AttributeCommonInfo::AS_" << Spellings[0].variety();
-  }
-  if (!ElideSpelling) {
-OS << ", " << R.getName() << "Attr::Spelling S";
-if (Header)
-  OS << " = static_cast(SpellingNotCalculated)";
+  OS << " = " << SemanticToSyntacticMap[0];
   }
   OS << ")";
   if (Header) {
@@ -2618,15 +2620,31 @@
   else
 OS << "NoSemaHandlerAttribute";
 
-  if (Spellings.size() == 0)
+  if (Spellings.size() == 0) {
 OS << ", AttributeCommonInfo::AS_Implicit";
-  else if (Spellings.size() == 1)
-OS << ", AttributeCommonInfo::AS_" << Spellings[0].variety();
-  else
-OS << ", Syntax";
+  } else if (Spellings.size() == 1) {
+OS << ", ";
+emitFormInitializer(OS, Spellings[0], "0");
+  } else {
+OS << ", (\n";
+std::set Uniques;
+unsigned Idx = 0;
+for (auto I = Spellings.begin(), E = Spellings.end(); I != E;
+ ++I, ++Idx) {
+  const FlattenedSpelling  = *I;
+  const auto  = SemanticToSyntacticMap[Idx];
+  if (Uniques.insert(Name).second) {
+OS << "S == " << Name << " ? AttributeCommonInfo::Form";
+emitFormInitializer(OS, S, Name);
+OS << " :\n";
+  }
+}
+OS << "(llvm_unreachable(\"Unknown attribute spelling!\"), "
+   << " AttributeCommonInfo::Form";
+emitFormInitializer(OS, Spellings[0], "0");
+OS << "))";
+  }
 
-  if (!ElideSpelling)
-OS << ", S";
   OS << ");\n";
   OS << "  return Create";
   if (Implicit)
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3092,9 +3092,10 @@
   unsigned Syntax = Record.readInt();
   unsigned SpellingIndex = Record.readInt();
 
-  AttributeCommonInfo Info(AttrName, ScopeName, AttrRange, ScopeLoc,
-   AttributeCommonInfo::Kind(ParsedKind),
-   AttributeCommonInfo::Syntax(Syntax), SpellingIndex);
+  AttributeCommonInfo Info(
+  AttrName, ScopeName, AttrRange, ScopeLoc,
+  AttributeCommonInfo::Kind(ParsedKind),
+  {AttributeCommonInfo::Syntax(Syntax), SpellingIndex});
 
 #include "clang/Serialization/AttrPCHRead.inc"
 
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -8981,8 +8981,7 @@
   ? S.ImplicitMSInheritanceAttrLoc
   : RD->getSourceRange();
 RD->addAttr(MSInheritanceAttr::CreateImplicit(
-S.getASTContext(), BestCase, Loc, AttributeCommonInfo::AS_Microsoft,
-MSInheritanceAttr::Spelling(IM)));
+S.getASTContext(), BestCase, Loc, MSInheritanceAttr::Spelling(IM)));
 S.Consumer.AssignInheritanceModel(RD);
   }
 }
Index: clang/lib/Sema/SemaOpenMP.cpp
===
--- 

[PATCH] D148148: [clang] Bump AS_GNU to 1

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 512947.
rsandifo-arm added a comment.

Gah, sorry.  Due to a botched git operation, I posted a first cut with a stupid 
typo, rather than the version that passed testing.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148148/new/

https://reviews.llvm.org/D148148

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h


Index: clang/include/clang/Basic/AttributeCommonInfo.h
===
--- clang/include/clang/Basic/AttributeCommonInfo.h
+++ clang/include/clang/Basic/AttributeCommonInfo.h
@@ -25,7 +25,7 @@
   /// The style used to specify an attribute.
   enum Syntax {
 /// __attribute__((...))
-AS_GNU,
+AS_GNU = 1,
 
 /// [[...]]
 AS_CXX11,
@@ -122,37 +122,32 @@
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Form FormUsed)
+  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
   : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc),
-AttrKind(getParsedKind(AttrName, ScopeName, FormUsed.getSyntax())),
+ScopeLoc(ScopeLoc), AttrKind(AttrKind),
 SyntaxUsed(FormUsed.getSyntax()),
 SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+IsAlignas(FormUsed.isAlignas()) {
+assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
+   "Invalid syntax!");
+  }
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
-  : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc), AttrKind(AttrKind),
-SyntaxUsed(FormUsed.getSyntax()),
-SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+  SourceLocation ScopeLoc, Form FormUsed)
+  : AttributeCommonInfo(
+AttrName, ScopeName, AttrRange, ScopeLoc,
+getParsedKind(AttrName, ScopeName, FormUsed.getSyntax()),
+FormUsed) {}
 
   AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange,
   Form FormUsed)
-  : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange),
-ScopeLoc(),
-AttrKind(getParsedKind(AttrName, ScopeName, FormUsed.getSyntax())),
-SyntaxUsed(FormUsed.getSyntax()),
-SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+  : AttributeCommonInfo(AttrName, nullptr, AttrRange, SourceLocation(),
+FormUsed) {}
 
   AttributeCommonInfo(SourceRange AttrRange, Kind K, Form FormUsed)
-  : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), 
ScopeLoc(),
-AttrKind(K), SyntaxUsed(FormUsed.getSyntax()),
-SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+  : AttributeCommonInfo(nullptr, nullptr, AttrRange, SourceLocation(), K,
+FormUsed) {}
 
   AttributeCommonInfo(AttributeCommonInfo &&) = default;
   AttributeCommonInfo(const AttributeCommonInfo &) = default;


Index: clang/include/clang/Basic/AttributeCommonInfo.h
===
--- clang/include/clang/Basic/AttributeCommonInfo.h
+++ clang/include/clang/Basic/AttributeCommonInfo.h
@@ -25,7 +25,7 @@
   /// The style used to specify an attribute.
   enum Syntax {
 /// __attribute__((...))
-AS_GNU,
+AS_GNU = 1,
 
 /// [[...]]
 AS_CXX11,
@@ -122,37 +122,32 @@
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Form FormUsed)
+  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
   : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc),
-AttrKind(getParsedKind(AttrName, ScopeName, FormUsed.getSyntax())),
+ScopeLoc(ScopeLoc), AttrKind(AttrKind),
 SyntaxUsed(FormUsed.getSyntax()),
 SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+IsAlignas(FormUsed.isAlignas()) {
+assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
+   "Invalid syntax!");
+  }
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
-  : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc), 

[PATCH] D148148: [clang] Bump AS_GNU to 1

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/include/clang/Basic/AttributeCommonInfo.h:135
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,

erichkeane wrote:
> Did these two ctors swap places somehow?  There's something goofy going on 
> here?  Or is this just to make the delegation of ctors more sensible? 
Ah, yeah, I should have mentioned that, sorry.  The most general constructor 
was previously the second in the list.  Like you say, I moved it up to make the 
delegation more obvious.  The other three keep their relative order.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148148/new/

https://reviews.llvm.org/D148148

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148101: [clang] Ensure that Attr::Create(Implicit) chooses a valid syntax

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/include/clang/Basic/AttributeCommonInfo.h:55
+
+/// The attibute has no source code manifestation and is only created
+/// implicitly.

erichkeane wrote:
> If I recall, there was some pretty awful funny business in some attributes, 
> which would explicitly use '0' instead of AS_GNU as implicit.  Did you run 
> into any of these?
> 
> Would it make sense to make AS_Implicit 'first' here to catch those?  Or 
> perhaps make '0' ill-formed (and assert?) and make this '1'?
Thanks for the reviews!

Bumping the values to 1 sounds good to me.  I've created 
https://reviews.llvm.org/D148148 for that.  I kept AS_GNU first due to:
```
// Note TableGen depends on the order above.  Do not add or change the order
// without adding related code to TableGen/ClangAttrEmitter.cpp.
```

(I don't know whether that still applies, but it seemed better to keep the 
tablegen-sensitive stuff at “one end” of the enum.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148101/new/

https://reviews.llvm.org/D148101

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148148: [clang] Bump AS_GNU to 1

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Following a suggestion from Erich in https://reviews.llvm.org/D148101,
this patch bumps AS_GNU to 1 so that syntax 0 is invalid.  It also
asserts that the syntax is in range.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148148

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h


Index: clang/include/clang/Basic/AttributeCommonInfo.h
===
--- clang/include/clang/Basic/AttributeCommonInfo.h
+++ clang/include/clang/Basic/AttributeCommonInfo.h
@@ -25,7 +25,7 @@
   /// The style used to specify an attribute.
   enum Syntax {
 /// __attribute__((...))
-AS_GNU,
+AS_GNU = 1,
 
 /// [[...]]
 AS_CXX11,
@@ -122,37 +122,32 @@
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Form FormUsed)
+  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
   : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc),
-AttrKind(getParsedKind(AttrName, ScopeName, FormUsed.getSyntax())),
+ScopeLoc(ScopeLoc), AttrKind(AttrKind),
 SyntaxUsed(FormUsed.getSyntax()),
 SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+IsAlignas(FormUsed.isAlignas()) {
+assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
+   "Invalid syntax!");
+  }
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
-  : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc), AttrKind(AttrKind),
-SyntaxUsed(FormUsed.getSyntax()),
-SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+  SourceLocation ScopeLoc, Form FormUsed)
+  : AttributeCommonInfo(
+AttrName, ScopeName, AttrRange, ScopeLoc,
+getParsedKind(AttrName, ScopeName, FormUsed.getSyntax()),
+FormUsed) {}
 
   AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange,
   Form FormUsed)
-  : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange),
-ScopeLoc(),
-AttrKind(getParsedKind(AttrName, ScopeName, FormUsed.getSyntax())),
-SyntaxUsed(FormUsed.getSyntax()),
-SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+  : AttributeCommonInfo(AttrName, nullptr, AttrRange, ScopeLoc(),
+FormUsed) {}
 
   AttributeCommonInfo(SourceRange AttrRange, Kind K, Form FormUsed)
-  : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), 
ScopeLoc(),
-AttrKind(K), SyntaxUsed(FormUsed.getSyntax()),
-SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+  : AttributeCommonInfo(nullptr, nullptr, AttrRange, ScopeLoc(), K,
+FormUsed) {}
 
   AttributeCommonInfo(AttributeCommonInfo &&) = default;
   AttributeCommonInfo(const AttributeCommonInfo &) = default;


Index: clang/include/clang/Basic/AttributeCommonInfo.h
===
--- clang/include/clang/Basic/AttributeCommonInfo.h
+++ clang/include/clang/Basic/AttributeCommonInfo.h
@@ -25,7 +25,7 @@
   /// The style used to specify an attribute.
   enum Syntax {
 /// __attribute__((...))
-AS_GNU,
+AS_GNU = 1,
 
 /// [[...]]
 AS_CXX11,
@@ -122,37 +122,32 @@
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Form FormUsed)
+  SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
   : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
-ScopeLoc(ScopeLoc),
-AttrKind(getParsedKind(AttrName, ScopeName, FormUsed.getSyntax())),
+ScopeLoc(ScopeLoc), AttrKind(AttrKind),
 SyntaxUsed(FormUsed.getSyntax()),
 SpellingIndex(FormUsed.getSpellingIndex()),
-IsAlignas(FormUsed.isAlignas()) {}
+IsAlignas(FormUsed.isAlignas()) {
+assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
+   "Invalid syntax!");
+  }
 
   AttributeCommonInfo(const IdentifierInfo *AttrName,
   const IdentifierInfo *ScopeName, SourceRange AttrRange,
-  SourceLocation ScopeLoc, Kind AttrKind, Form 

[PATCH] D148105: [clang] Fix FIXME in isAlignasAttribute()

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

FWIW, the original reason for looking at this was to explore ways of removing 
`AS_AttributeLikeKeyword` from https://reviews.llvm.org/D139028 .  I wanted to 
find a way of conveying extra information about a spelling without having to 
change the existing enums.  It seemed like that was essentially the same 
problem as the one described in the FIXME being fixed here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148105/new/

https://reviews.llvm.org/D148105

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148105: [clang] Fix FIXME in isAlignasAttribute()

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

AttributeCommonInfo::isAlignasAttribute() was used in one place:
isCXX11Attribute().  The intention was for isAlignasAttribute()
to return true for the C++ alignas keyword.  However, as a FIXME
noted, the function also returned true for the C _Alignas keyword.
This meant that isCXX11Attribute() returned true for _Alignas as
well as for alignas.

AttributeCommonInfos are now always constructed with an
AttributeCommonInfo::Form.  We can use that Form to convey whether
a keyword is alignas or not.

The patch uses 1 bit of an 8-bit hole in the current layout
of AttributeCommonInfo.  This might not be the best long-term design,
but it should be easy to adapt the layout if necessary (that is,
if other uses are found for the spare bits).

I don't know of a way of testing this (other than grep -c FIXME)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148105

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2381,8 +2381,11 @@
 static void emitFormInitializer(raw_ostream ,
 const FlattenedSpelling ,
 StringRef SpellingIndex) {
+  bool IsAlignas =
+  (Spelling.variety() == "Keyword" && Spelling.name() == "alignas");
   OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
- << SpellingIndex << "}";
+ << SpellingIndex << ", " << (IsAlignas ? "true" : "false")
+ << " /*IsAlignas*/}";
 }
 
 static void emitAttributes(RecordKeeper , raw_ostream ,
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3091,11 +3091,14 @@
   unsigned ParsedKind = Record.readInt();
   unsigned Syntax = Record.readInt();
   unsigned SpellingIndex = Record.readInt();
+  bool IsAlignas = (ParsedKind == AttributeCommonInfo::AT_Aligned &&
+Syntax == AttributeCommonInfo::AS_Keyword &&
+SpellingIndex == AlignedAttr::Keyword_alignas);
 
   AttributeCommonInfo Info(
   AttrName, ScopeName, AttrRange, ScopeLoc,
   AttributeCommonInfo::Kind(ParsedKind),
-  {AttributeCommonInfo::Syntax(Syntax), SpellingIndex});
+  {AttributeCommonInfo::Syntax(Syntax), SpellingIndex, IsAlignas});
 
 #include "clang/Serialization/AttrPCHRead.inc"
 
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -4893,9 +4893,9 @@
 
 // If we're supposed to infer nullability, do so now.
 if (inferNullability && !inferNullabilityInnerOnlyComplete) {
-  ParsedAttr::Form form = inferNullabilityCS
-  ? ParsedAttr::Form::ContextSensitiveKeyword()
-  : ParsedAttr::Form::Keyword();
+  ParsedAttr::Form form =
+  inferNullabilityCS ? ParsedAttr::Form::ContextSensitiveKeyword()
+ : ParsedAttr::Form::Keyword(false /*IsAlignAs*/);
   ParsedAttr *nullabilityAttr = Pool.create(
   S.getNullabilityKeyword(*inferNullability), SourceRange(pointerLoc),
   nullptr, SourceLocation(), nullptr, 0, form);
Index: clang/include/clang/Basic/AttributeCommonInfo.h
===
--- clang/include/clang/Basic/AttributeCommonInfo.h
+++ clang/include/clang/Basic/AttributeCommonInfo.h
@@ -76,6 +76,7 @@
   /// Corresponds to the Syntax enum.
   unsigned SyntaxUsed : 4;
   unsigned SpellingIndex : 4;
+  unsigned IsAlignas : 1;
 
 protected:
   static constexpr unsigned SpellingNotCalculated = 0xf;
@@ -85,20 +86,25 @@
   /// including its syntax and spelling.
   class Form {
   public:
-constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex)
-: SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex) {}
-constexpr Form(tok::TokenKind)
-: SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated) {}
+constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex, bool IsAlignas)
+: SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex),
+  IsAlignas(IsAlignas) {}
+constexpr Form(tok::TokenKind Tok)
+: SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated),
+  IsAlignas(Tok == tok::kw_alignas) {}
 
 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
 

[PATCH] D148104: [clang] Type safety tweak for AttributeCommonInfo::Form

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148104

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseHLSL.cpp
  clang/lib/Parse/ParseObjc.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2621,7 +2621,7 @@
 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");
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -4893,12 +4893,12 @@
 
 // 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);
 
@@ -6025,7 +6025,7 @@
   ParsedAttr *attr = D.getAttributePool().create(
   ("objc_ownership"), SourceLocation(),
   /*scope*/ nullptr, SourceLocation(),
-  /*args*/ , 1, ParsedAttr::AS_GNU);
+  /*args*/ , 1, ParsedAttr::Form::GNU());
   chunk.getAttrs().addAtEnd(attr);
   // TODO: mark whether we did this inference?
 }
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -19862,7 +19862,7 @@
   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);
 
Index: clang/lib/Sema/SemaAttr.cpp
===
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -860,7 +860,7 @@
 return;
 
   AttributeCommonInfo Info(Ident, SourceRange(Loc),
-   AttributeCommonInfo::AS_Pragma);
+   AttributeCommonInfo::Form::Pragma());
   D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info));
 }
 
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -2411,7 +2411,7 @@
 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.
Index: clang/lib/Parse/ParsePragma.cpp
===
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -1850,11 +1850,12 @@
 
   if (Tok.isNot(tok::l_paren))
 Attrs.addNew(AttrName, AttrNameLoc, nullptr, 

[PATCH] D148103: [clang] Allow attributes to be constructed from keyword tokens

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch adds an extra AttributeCommonInfo::Form constructor
for keywords, represented by their TokenKind.  This isn't a
win on its own, but it helps with later patches.

No functional change intended.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148103

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp

Index: clang/lib/Parse/ParseExprCXX.cpp
===
--- clang/lib/Parse/ParseExprCXX.cpp
+++ clang/lib/Parse/ParseExprCXX.cpp
@@ -1300,7 +1300,7 @@
 SourceLocation AttrNameLoc = ConsumeToken();
 Attributes.addNew(AttrName, AttrNameLoc, /*ScopeName=*/nullptr,
   AttrNameLoc, /*ArgsUnion=*/nullptr,
-  /*numArgs=*/0, ParsedAttr::AS_Keyword);
+  /*numArgs=*/0, tok::kw___noinline__);
   } else if (Tok.is(tok::kw___attribute))
 ParseGNUAttributes(Attributes, /*LatePArsedAttrList=*/nullptr, );
   else
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -1370,9 +1370,9 @@
  tok::kw___multiple_inheritance,
  tok::kw___virtual_inheritance)) {
 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+auto Kind = Tok.getKind();
 SourceLocation AttrNameLoc = ConsumeToken();
-attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- ParsedAttr::AS_Keyword);
+attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);
   }
 }
 
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -828,7 +828,8 @@
 void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes ) {
   // Treat these like attributes
   while (true) {
-switch (Tok.getKind()) {
+auto Kind = Tok.getKind();
+switch (Kind) {
 case tok::kw___fastcall:
 case tok::kw___stdcall:
 case tok::kw___thiscall:
@@ -843,7 +844,7 @@
   IdentifierInfo *AttrName = Tok.getIdentifierInfo();
   SourceLocation AttrNameLoc = ConsumeToken();
   attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
-   ParsedAttr::AS_Keyword);
+   Kind);
   break;
 }
 default:
@@ -865,7 +866,7 @@
   SourceLocation AttrNameLoc = ConsumeToken();
   attrs.addNew(AttrName, AttrNameLoc, /*ScopeName=*/nullptr,
/*ScopeLoc=*/SourceLocation{}, /*Args=*/nullptr, /*numArgs=*/0,
-   ParsedAttr::AS_Keyword);
+   tok::kw___funcref);
 }
 
 void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
@@ -910,7 +911,7 @@
 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
 SourceLocation AttrNameLoc = ConsumeToken();
 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- ParsedAttr::AS_Keyword);
+ tok::kw___pascal);
   }
 }
 
@@ -920,7 +921,7 @@
 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
 SourceLocation AttrNameLoc = ConsumeToken();
 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- ParsedAttr::AS_Keyword);
+ tok::kw___kernel);
   }
 }
 
@@ -929,7 +930,7 @@
 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
 SourceLocation AttrNameLoc = ConsumeToken();
 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
- ParsedAttr::AS_Keyword);
+ tok::kw___noinline__);
   }
 }
 
@@ -937,7 +938,7 @@
   IdentifierInfo *AttrName = Tok.getIdentifierInfo();
   SourceLocation AttrNameLoc = Tok.getLocation();
   Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
-   ParsedAttr::AS_Keyword);
+   Tok.getKind());
 }
 
 bool Parser::isHLSLQualifier(const Token ) const {
@@ -946,15 +947,16 @@
 
 void Parser::ParseHLSLQualifiers(ParsedAttributes ) {
   IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+  auto Kind = Tok.getKind();
   SourceLocation AttrNameLoc = ConsumeToken();
-  Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
-   ParsedAttr::AS_Keyword);
+  Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);
 }
 
 void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes ) {
   // Treat these like attributes, even though they're type specifiers.
   while (true) {
-switch (Tok.getKind()) {
+auto Kind = Tok.getKind();
+   

[PATCH] D148102: [clang] Specify attribute syntax & spelling with a single argument

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: erichkeane, aaron.ballman.
Herald added a subscriber: martong.
Herald added a reviewer: shafik.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

When constructing an attribute, the syntactic form was specified
using two arguments: an attribute-independent syntax type and an
attribute-specific spelling index.  This patch replaces them with
a single argument.

In most cases, that's done using a new Form class that combines the
syntax and spelling into a single object.  This has the minor benefit
of removing a couple of constructors.  But the main purpose is to allow
additional information to be stored as well, beyond just the syntax and
spelling enums.

In the case of the attribute-specific Create and CreateImplicit
functions, the patch instead uses the attribute-specific spelling
enum.  This helps to ensure that the syntax and spelling are
consistent with each other and with the Attr.td definition.

If a Create or CreateImplicit caller specified a syntax and
a spelling, the patch drops the syntax argument and keeps the
spelling.  If the caller instead specified only a syntax
(so that the spelling was SpellingNotCalculated), the patch
simply drops the syntax argument.

There were two cases of the latter: TargetVersion and Weak.
TargetVersionAttrs were created with GNU syntax, which matches
their definition in Attr.td, but which is also the default.
WeakAttrs were created with Pragma syntax, which does not match
their definition in Attr.td.  Dropping the argument switches
them to AS_GNU too (to match [GCC<"weak">]).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148102

Files:
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/ParsedAttr.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/HLSLExternalSemaSource.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaObjCProperty.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2378,6 +2378,13 @@
   OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n";
 }
 
+static void emitFormInitializer(raw_ostream ,
+const FlattenedSpelling ,
+StringRef SpellingIndex) {
+  OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
+ << SpellingIndex << "}";
+}
+
 static void emitAttributes(RecordKeeper , raw_ostream ,
bool Header) {
   std::vector Attrs = Records.getAllDerivedDefinitions("Attr");
@@ -2595,14 +2602,9 @@
   if (Header)
 OS << " = {}";
   if (Spellings.size() > 1) {
-OS << ", AttributeCommonInfo::Syntax Syntax";
+OS << ", Spelling S";
 if (Header)
-  OS << " = AttributeCommonInfo::AS_" << Spellings[0].variety();
-  }
-  if (!ElideSpelling) {
-OS << ", " << R.getName() << "Attr::Spelling S";
-if (Header)
-  OS << " = static_cast(SpellingNotCalculated)";
+  OS << " = " << SemanticToSyntacticMap[0];
   }
   OS << ")";
   if (Header) {
@@ -2618,15 +2620,31 @@
   else
 OS << "NoSemaHandlerAttribute";
 
-  if (Spellings.size() == 0)
+  if (Spellings.size() == 0) {
 OS << ", AttributeCommonInfo::AS_Implicit";
-  else if (Spellings.size() == 1)
-OS << ", AttributeCommonInfo::AS_" << Spellings[0].variety();
-  else
-OS << ", Syntax";
+  } else if (Spellings.size() == 1) {
+OS << ", ";
+emitFormInitializer(OS, Spellings[0], "0");
+  } else {
+OS << ", (\n";
+std::set Uniques;
+unsigned Idx = 0;
+for (auto I = Spellings.begin(), E = Spellings.end(); I != E;
+ ++I, ++Idx) {
+  const FlattenedSpelling  = *I;
+  const auto  = SemanticToSyntacticMap[Idx];
+  if (Uniques.insert(Name).second) {
+OS << "S == " << Name << " ? AttributeCommonInfo::Form";
+emitFormInitializer(OS, S, "S");
+OS << " :\n";
+  }
+}
+OS << "(llvm_unreachable(\"Unknown attribute spelling!\"), "
+   << " AttributeCommonInfo::Form";
+emitFormInitializer(OS, Spellings[0], "0");
+OS << "))";
+  }
 
-  if (!ElideSpelling)
-OS << ", S";
   OS << ");\n";
   OS << "  return Create";
   if (Implicit)
Index: 

[PATCH] D148101: [clang] Ensure that Attr::Create(Implicit) chooses a valid syntax

2023-04-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The purpose of this patch and follow-on patches is to ensure that
AttributeCommonInfos always have a syntax that is appropriate for
their kind (i.e. that it matches one of the entries in Attr.td).

The attribute-specific Create and CreateImplicit methods had four
overloads, based on their tail arguments:

(1) no extra arguments
(2) an AttributeCommonInfo
(3) a SourceRange
(4) a SourceRange, a syntax, and (where necessary) a spelling

When (4) had a spelling argument, it defaulted to
SpellingNotCalculated.

One disadvantage of this was that (1) and (3) zero-initialized
the syntax field of the AttributeCommonInfo, which corresponds
to AS_GNU.  But AS_GNU isn't always listed as a possibility
in Attr.td.

This patch therefore removes (1) and (3) and instead provides
the same functionality using default arguments on (4) (a bit
like the existing default argument for the spelling).
The default syntax is taken from the attribute's first valid
spelling.

Doing that raises the question: what should happen for attributes
like AlignNatural and CUDAInvalidTarget that are only ever created
implicitly, and so have no source-code manifestation at all?
The patch adds a new AS_Implicit "syntax" for that case.
The patch also removes the syntax argument for these attributes,
since the syntax must always be AS_Implicit.

For similar reasons, the patch removes the syntax argument if
there is exactly one valid spelling.

Doing this means that AttributeCommonInfo no longer needs the
single-argument constructors.  It is always given a syntax instead.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148101

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttributeCommonInfo.h
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/unittests/AST/DeclTest.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2505,15 +2505,8 @@
   return  == P.second;
 });
 
-enum class CreateKind {
-  WithAttributeCommonInfo,
-  WithSourceRange,
-  WithNoArgs,
-};
-
 // Emit CreateImplicit factory methods.
-auto emitCreate = [&](bool Implicit, bool DelayedArgsOnly,
-  bool emitFake, CreateKind Kind) {
+auto emitCreate = [&](bool Implicit, bool DelayedArgsOnly, bool emitFake) {
   if (Header)
 OS << "  static ";
   OS << R.getName() << "Attr *";
@@ -2537,10 +2530,7 @@
 OS << ", ";
 DelayedArgs->writeCtorParameters(OS);
   }
-  if (Kind == CreateKind::WithAttributeCommonInfo)
-OS << ", const AttributeCommonInfo ";
-  else if (Kind == CreateKind::WithSourceRange)
-OS << ", SourceRange R";
+  OS << ", const AttributeCommonInfo ";
   OS << ")";
   if (Header) {
 OS << ";\n";
@@ -2549,12 +2539,7 @@
 
   OS << " {\n";
   OS << "  auto *A = new (Ctx) " << R.getName();
-  if (Kind == CreateKind::WithAttributeCommonInfo)
-OS << "Attr(Ctx, CommonInfo";
-  else if (Kind == CreateKind::WithSourceRange)
-OS << "Attr(Ctx, AttributeCommonInfo{R}";
-  else if (Kind == CreateKind::WithNoArgs)
-OS << "Attr(Ctx, AttributeCommonInfo{SourceLocation{}}";
+  OS << "Attr(Ctx, CommonInfo";
 
   if (!DelayedArgsOnly) {
 for (auto const  : Args) {
@@ -2606,7 +2591,14 @@
 OS << ", ";
 DelayedArgs->writeCtorParameters(OS);
   }
-  OS << ", SourceRange Range, AttributeCommonInfo::Syntax Syntax";
+  OS << ", SourceRange Range";
+  if (Header)
+OS << " = {}";
+  if (Spellings.size() > 1) {
+OS << ", AttributeCommonInfo::Syntax Syntax";
+if (Header)
+  OS << " = AttributeCommonInfo::AS_" << Spellings[0].variety();
+  }
   if (!ElideSpelling) {
 OS << ", " << R.getName() << "Attr::Spelling S";
 if (Header)
@@ -2626,7 +2618,13 @@
   else
 OS << "NoSemaHandlerAttribute";
 
-  OS << ", Syntax";
+  if (Spellings.size() == 0)
+OS << ", AttributeCommonInfo::AS_Implicit";
+  else if (Spellings.size() == 1)
+OS << ", AttributeCommonInfo::AS_" << Spellings[0].variety();
+  else
+OS << ", Syntax";
+
   if (!ElideSpelling)
 OS << ", S";
   OS << ");\n";
@@ -2651,19 +2649,9 @@
   OS << "}\n\n";
 };
 
-auto emitBothImplicitAndNonCreates = [&](bool DelayedArgsOnly,
- bool emitFake, CreateKind Kind) {
-  emitCreate(true, 

[PATCH] D147661: [Sema] Tweak merging of availability attributes

2023-04-10 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

> I threw together a patch to make the constructors `explicit` and the only two 
> compile failures I have are with what you're fixing in this patch. If you'd 
> like, I can commandeer this patch and subsume it with the larger refactor. 
> Alternatively, we can land this (I'd drop the test though) and I can rebase 
> on top of your changes. Either is fine by me.

Yeah, please feel free to commandeer it.  My original motivation for doing this 
was to remove the single-argument constructors rather than keep them.  However, 
I agree that making them explicit in the meantime would ensure forward 
progress, if what I'm doing in the follow-on patches turns out not to be 
acceptable.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147661/new/

https://reviews.llvm.org/D147661

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147661: [Sema] Tweak merging of availability attributes

2023-04-06 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

In D147661#4249004 , @erichkeane 
wrote:

> This test doesn't show a change in behavior.

Yeah.  Is there a way to force the syntax and spelling fields to be dumped, 
even for implicit attributes?  I was struggling to find one, which is why I 
wasn't sure this made a difference in practice.

The patch is supposed to be a minor clean-up, since similar calls in 
surrounding code uses `AL` rather than `AL.getRange()`.  The reason I 
originally hit this was that the series I'm working on removes the:

  AttributeCommonInfo(SourceRange)
  AttributeCommonInfo(SourceLocation)

constructors (but keeps the ability to use `FooAttr::CreateImplicit` without 
more than a source range).  It might be easier to explain why that seemed a 
good idea alongside the patches themselves.

The two main uses of these constructors outside tablegen-generated code were 
the two in this patch and the one in https://reviews.llvm.org/D147657.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147661/new/

https://reviews.llvm.org/D147661

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147661: [Sema] Tweak merging of availability attributes

2023-04-06 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

In D147661#4248574 , @erichkeane 
wrote:

> I think the change is probably fine,

Thanks!

> but can you add an AST-dump test for this one?

Sure.  How does this look?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147661/new/

https://reviews.llvm.org/D147661

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147661: [Sema] Tweak merging of availability attributes

2023-04-06 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 511425.
rsandifo-arm added a comment.

Add AST dump test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147661/new/

https://reviews.llvm.org/D147661

Files:
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/Sema/attr-availability-maccatalyst-dump.c


Index: clang/test/Sema/attr-availability-maccatalyst-dump.c
===
--- /dev/null
+++ clang/test/Sema/attr-availability-maccatalyst-dump.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 "-triple" "x86_64-apple-ios13.1-macabi" -std=c2x 
-fsyntax-only -ast-dump %s | FileCheck %s
+
+void foo() __attribute__((availability(ios,introduced=2.0)));
+void bar [[clang::availability(ios,introduced=2.0)]] ();
+
+// CHECK: FunctionDecl 0x{{[^ ]*}} <{{[^:]*}}:3:1, col:60> col:6 foo
+// CHECK: AvailabilityAttr 0x{{[^ ]*}}  Implicit maccatalyst 
13.1 0 0 "" "" 2
+// CHECK: FunctionDecl 0x{{[^ ]*}} <{{[^:]*}}:4:1, col:55> col:6 bar
+// CHECK: AvailabilityAttr 0x{{[^ ]*}}  Implicit maccatalyst 
13.1 0 0 "" "" 2
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -2775,7 +2775,7 @@
 return V;
   };
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-  ND, AL.getRange(), NewII, true /*Implicit*/,
+  ND, AL, NewII, true /*Implicit*/,
   MinMacCatalystVersion(Introduced.Version),
   MinMacCatalystVersion(Deprecated.Version),
   MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
@@ -2817,7 +2817,7 @@
 return V ? *V : VersionTuple();
   };
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-  ND, AL.getRange(), NewII, true /*Implicit*/,
+  ND, AL, NewII, true /*Implicit*/,
   VersionOrEmptyVersion(NewIntroduced),
   VersionOrEmptyVersion(NewDeprecated),
   VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, 
Str,


Index: clang/test/Sema/attr-availability-maccatalyst-dump.c
===
--- /dev/null
+++ clang/test/Sema/attr-availability-maccatalyst-dump.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 "-triple" "x86_64-apple-ios13.1-macabi" -std=c2x -fsyntax-only -ast-dump %s | FileCheck %s
+
+void foo() __attribute__((availability(ios,introduced=2.0)));
+void bar [[clang::availability(ios,introduced=2.0)]] ();
+
+// CHECK: FunctionDecl 0x{{[^ ]*}} <{{[^:]*}}:3:1, col:60> col:6 foo
+// CHECK: AvailabilityAttr 0x{{[^ ]*}}  Implicit maccatalyst 13.1 0 0 "" "" 2
+// CHECK: FunctionDecl 0x{{[^ ]*}} <{{[^:]*}}:4:1, col:55> col:6 bar
+// CHECK: AvailabilityAttr 0x{{[^ ]*}}  Implicit maccatalyst 13.1 0 0 "" "" 2
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -2775,7 +2775,7 @@
 return V;
   };
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-  ND, AL.getRange(), NewII, true /*Implicit*/,
+  ND, AL, NewII, true /*Implicit*/,
   MinMacCatalystVersion(Introduced.Version),
   MinMacCatalystVersion(Deprecated.Version),
   MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
@@ -2817,7 +2817,7 @@
 return V ? *V : VersionTuple();
   };
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-  ND, AL.getRange(), NewII, true /*Implicit*/,
+  ND, AL, NewII, true /*Implicit*/,
   VersionOrEmptyVersion(NewIntroduced),
   VersionOrEmptyVersion(NewDeprecated),
   VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147657: [Sema] Fix reporting of invalid shader attribute on HLSL entry function

2023-04-06 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG03a9a1e664de: [Sema] Fix reporting of invalid shader 
attribute on HLSL entry function (authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147657/new/

https://reviews.llvm.org/D147657

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaHLSL/entry_shader.hlsl


Index: clang/test/SemaHLSL/entry_shader.hlsl
===
--- /dev/null
+++ clang/test/SemaHLSL/entry_shader.hlsl
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -hlsl-entry 
foo  -o - %s -DSHADER='"anyHit"' -verify
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -hlsl-entry 
foo  -o - %s -DSHADER='"compute"'
+
+// expected-error@+1 {{'shader' attribute on entry function does not match the 
pipeline stage}}
+[numthreads(1,1,1), shader(SHADER)]
+void foo() {
+
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -10205,14 +10205,19 @@
   CheckHLSLEntryPoint(NewFD);
   if (!NewFD->isInvalidDecl()) {
 auto Env = TargetInfo.getTriple().getEnvironment();
-AttributeCommonInfo AL(NewFD->getBeginLoc());
 HLSLShaderAttr::ShaderType ShaderType =
 static_cast(
 hlsl::getStageFromEnvironment(Env));
 // To share code with HLSLShaderAttr, add HLSLShaderAttr to entry
 // function.
-if (HLSLShaderAttr *Attr = mergeHLSLShaderAttr(NewFD, AL, ShaderType))
-  NewFD->addAttr(Attr);
+if (HLSLShaderAttr *NT = NewFD->getAttr()) {
+  if (NT->getType() != ShaderType)
+Diag(NT->getLocation(), diag::err_hlsl_entry_shader_attr_mismatch)
+<< NT;
+} else {
+  NewFD->addAttr(HLSLShaderAttr::Create(Context, ShaderType,
+NewFD->getBeginLoc()));
+}
   }
 }
 // HLSL does not support specifying an address space on a function return
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11752,6 +11752,8 @@
"attribute %0 only applies to a field or parameter of type '%1'">;
 def err_hlsl_attr_invalid_ast_node : Error<
"attribute %0 only applies to %1">;
+def err_hlsl_entry_shader_attr_mismatch : Error<
+   "%0 attribute on entry function does not match the pipeline stage">;
 def err_hlsl_numthreads_argument_oor : Error<"argument '%select{X|Y|Z}0' to 
numthreads attribute cannot exceed %1">;
 def err_hlsl_numthreads_invalid : Error<"total number of threads cannot exceed 
%0">;
 def err_hlsl_missing_numthreads : Error<"missing numthreads attribute for %0 
shader entry">;


Index: clang/test/SemaHLSL/entry_shader.hlsl
===
--- /dev/null
+++ clang/test/SemaHLSL/entry_shader.hlsl
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -hlsl-entry foo  -o - %s -DSHADER='"anyHit"' -verify
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -hlsl-entry foo  -o - %s -DSHADER='"compute"'
+
+// expected-error@+1 {{'shader' attribute on entry function does not match the pipeline stage}}
+[numthreads(1,1,1), shader(SHADER)]
+void foo() {
+
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -10205,14 +10205,19 @@
   CheckHLSLEntryPoint(NewFD);
   if (!NewFD->isInvalidDecl()) {
 auto Env = TargetInfo.getTriple().getEnvironment();
-AttributeCommonInfo AL(NewFD->getBeginLoc());
 HLSLShaderAttr::ShaderType ShaderType =
 static_cast(
 hlsl::getStageFromEnvironment(Env));
 // To share code with HLSLShaderAttr, add HLSLShaderAttr to entry
 // function.
-if (HLSLShaderAttr *Attr = mergeHLSLShaderAttr(NewFD, AL, ShaderType))
-  NewFD->addAttr(Attr);
+if (HLSLShaderAttr *NT = NewFD->getAttr()) {
+  if (NT->getType() != ShaderType)
+Diag(NT->getLocation(), diag::err_hlsl_entry_shader_attr_mismatch)
+<< NT;
+} else {
+  NewFD->addAttr(HLSLShaderAttr::Create(Context, ShaderType,
+NewFD->getBeginLoc()));
+}
   }
 }
 // HLSL does not support specifying an address space on a function return
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td

[PATCH] D147661: [Sema] Tweak merging of availability attributes

2023-04-05 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: arphaman, erichkeane.
Herald added a reviewer: aaron.ballman.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Two calls to mergeAvailabilityAttr dropped the original
AttributeCommonInfo and created a new one from just the range.
This new attribute would have a 0 kind (rather than AT_Availability)
and a 0 syntax (GNU).  I don't have any proof that this makes a
difference in practice.

Noticed while doing some changes to the attribute handling.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147661

Files:
  clang/lib/Sema/SemaDeclAttr.cpp


Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -2775,7 +2775,7 @@
 return V;
   };
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-  ND, AL.getRange(), NewII, true /*Implicit*/,
+  ND, AL, NewII, true /*Implicit*/,
   MinMacCatalystVersion(Introduced.Version),
   MinMacCatalystVersion(Deprecated.Version),
   MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
@@ -2817,7 +2817,7 @@
 return V ? *V : VersionTuple();
   };
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-  ND, AL.getRange(), NewII, true /*Implicit*/,
+  ND, AL, NewII, true /*Implicit*/,
   VersionOrEmptyVersion(NewIntroduced),
   VersionOrEmptyVersion(NewDeprecated),
   VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, 
Str,


Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -2775,7 +2775,7 @@
 return V;
   };
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-  ND, AL.getRange(), NewII, true /*Implicit*/,
+  ND, AL, NewII, true /*Implicit*/,
   MinMacCatalystVersion(Introduced.Version),
   MinMacCatalystVersion(Deprecated.Version),
   MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
@@ -2817,7 +2817,7 @@
 return V ? *V : VersionTuple();
   };
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-  ND, AL.getRange(), NewII, true /*Implicit*/,
+  ND, AL, NewII, true /*Implicit*/,
   VersionOrEmptyVersion(NewIntroduced),
   VersionOrEmptyVersion(NewDeprecated),
   VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147657: [Sema] Fix reporting of invalid shader attribute on HLSL entry function

2023-04-05 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
rsandifo-arm added reviewers: python3kgae, erichkeane.
Herald added a subscriber: Anastasia.
Herald added a project: All.
rsandifo-arm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

If the HLSL entry function had a shader attribute that conflicted
with the pipeline stage specified in the target triple, Clang
would emit:

  error: (null) attribute parameters do not match the previous declaration
  conflicting attribute is here

(where the second line doesn't reference an attribute).

This was because the code constructed a dummy attribute that had
only a source location, but no kind or syntax.

Noticed while doing some changes to the attribute handling.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147657

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaHLSL/entry_shader.hlsl


Index: clang/test/SemaHLSL/entry_shader.hlsl
===
--- /dev/null
+++ clang/test/SemaHLSL/entry_shader.hlsl
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -hlsl-entry 
foo  -o - %s -DSHADER='"anyHit"' -verify
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -hlsl-entry 
foo  -o - %s -DSHADER='"compute"'
+
+// expected-error@+1 {{'shader' attribute on entry function does not match the 
pipeline stage}}
+[numthreads(1,1,1), shader(SHADER)]
+void foo() {
+
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -10205,14 +10205,19 @@
   CheckHLSLEntryPoint(NewFD);
   if (!NewFD->isInvalidDecl()) {
 auto Env = TargetInfo.getTriple().getEnvironment();
-AttributeCommonInfo AL(NewFD->getBeginLoc());
 HLSLShaderAttr::ShaderType ShaderType =
 static_cast(
 hlsl::getStageFromEnvironment(Env));
 // To share code with HLSLShaderAttr, add HLSLShaderAttr to entry
 // function.
-if (HLSLShaderAttr *Attr = mergeHLSLShaderAttr(NewFD, AL, ShaderType))
-  NewFD->addAttr(Attr);
+if (HLSLShaderAttr *NT = NewFD->getAttr()) {
+  if (NT->getType() != ShaderType)
+Diag(NT->getLocation(), diag::err_hlsl_entry_shader_attr_mismatch)
+<< NT;
+} else {
+  NewFD->addAttr(HLSLShaderAttr::Create(Context, ShaderType,
+NewFD->getBeginLoc()));
+}
   }
 }
 // HLSL does not support specifying an address space on a function return
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11752,6 +11752,8 @@
"attribute %0 only applies to a field or parameter of type '%1'">;
 def err_hlsl_attr_invalid_ast_node : Error<
"attribute %0 only applies to %1">;
+def err_hlsl_entry_shader_attr_mismatch : Error<
+   "%0 attribute on entry function does not match the pipeline stage">;
 def err_hlsl_numthreads_argument_oor : Error<"argument '%select{X|Y|Z}0' to 
numthreads attribute cannot exceed %1">;
 def err_hlsl_numthreads_invalid : Error<"total number of threads cannot exceed 
%0">;
 def err_hlsl_missing_numthreads : Error<"missing numthreads attribute for %0 
shader entry">;


Index: clang/test/SemaHLSL/entry_shader.hlsl
===
--- /dev/null
+++ clang/test/SemaHLSL/entry_shader.hlsl
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -hlsl-entry foo  -o - %s -DSHADER='"anyHit"' -verify
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -hlsl-entry foo  -o - %s -DSHADER='"compute"'
+
+// expected-error@+1 {{'shader' attribute on entry function does not match the pipeline stage}}
+[numthreads(1,1,1), shader(SHADER)]
+void foo() {
+
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -10205,14 +10205,19 @@
   CheckHLSLEntryPoint(NewFD);
   if (!NewFD->isInvalidDecl()) {
 auto Env = TargetInfo.getTriple().getEnvironment();
-AttributeCommonInfo AL(NewFD->getBeginLoc());
 HLSLShaderAttr::ShaderType ShaderType =
 static_cast(
 hlsl::getStageFromEnvironment(Env));
 // To share code with HLSLShaderAttr, add HLSLShaderAttr to entry
 // function.
-if (HLSLShaderAttr *Attr = mergeHLSLShaderAttr(NewFD, AL, ShaderType))
-  NewFD->addAttr(Attr);
+if (HLSLShaderAttr *NT = NewFD->getAttr()) {
+  if (NT->getType() != ShaderType)
+Diag(NT->getLocation(), 

[PATCH] D139028: [RFC][clang] Add attribute-like keywords

2023-02-28 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Thanks @aaron.ballman and @erichkeane for the comments.  I'll split it into 
stages and use tablegen more, like you say.

In D139028#4150761 , @aaron.ballman 
wrote:

> One thing that might also help is to split this into a few stages. 1) Add the 
> new general functionality, 2) Replacing the existing implementation of 
> keyword attributes with the new functionality where possible, 3) Add new 
> attributes using the new functionality. It seems to me that we should be able 
> to replace a bunch of our existing keyword attributes with the newer 
> generalized approach (I'm thinking about ones like the calling convention 
> attributes specifically, but we've got others as well), and that will help us 
> prove the design as well as simplify the compiler implementation. WDYT?

I've tried to go through the existing keyword attributes, but unfortunately, I 
don't think any of them match the new scheme exactly:

__declspec
--

I don't think anyone was suggesting we try to convert this :-) but for 
completeness:

  int __declspec(align(16)) a1; // OK, but standard attribute rules would say 
this appertains to the type
  int a2 __declspec();  // Not valid, unlike for standard decl 
attributes



__forceinline
-

  int __forceinline a1() { return 1; } // OK, but standard attribute rules 
would say this appertains to the type
  int a2 __forceinline() { return 1; } // Not valid, but would be for standard 
decl attributes



Calling convention keywords
---

These are generally DeclOrType attributes, with attributes sliding from the 
decl to the type where necessary.

  __stdcall int a1();   // OK, but appertains to the decl and relies on sliding 
behaviour
  int a2 __stdcall();   // Not valid, but is another place to put standard decl 
attributes
  int a3() __stdcall;   // Not valid, but is another place to put standard type 
attributes
  int (__stdcall a4)(); // OK, but standard attributes aren't allowed in this 
position
  extern int (*const __stdcall volatile a5) (); // OK, but standard attributes 
wouldn't be allowed here



Nullability keywords


Like the calling-convention keywords, the nullability keywords appertain to 
types but are allowed in some (but not all) positions that would normally 
appertain to decls:

  using ptr = int *;
  _Nullable ptr a1; // OK, but appertains to the decl and relies on sliding 
behaviour
  ptr a2 _Nullable; // Not valid, but is another place to put standard decl 
attributes
  extern int *const _Nullable volatile a3; // OK, but a standard attribute 
wouldn't be allowed here

The same distinction applies to Microsoft pointer attributes.

Would it be OK just to use the new scheme for new attributes?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139028/new/

https://reviews.llvm.org/D139028

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D139028: [RFC][clang] Add attribute-like keywords

2023-01-25 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Ping.  If this approach is acceptable, I think we could use it for future ACLE 
features too (rather than the GNU attributes that we've used previously).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139028/new/

https://reviews.llvm.org/D139028

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D127762: [Clang][AArch64] Add ACLE attributes for SME.

2023-01-04 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

In D127762#4023803 , @aaron.ballman 
wrote:

> In D127762#3960906 , @rsandifo-arm 
> wrote:
>
>> Thanks @aaron.ballman for the feedback about spellings.  I've gone with the 
>> lower-case names like `__arm_streaming` in what follows, as a plausible 
>> strawman.
>>
>> My main concern with keywords is:
>>
>>> This approach means there's plenty of flexibility available to parse the 
>>> keyword where you think it makes sense.
>>
>> If everyone parses keywords where it makes sense to them personally, for 
>> their specific use case, I'm worried that we'll end up with a lot of 
>> slightly different rules.  (This tended to happen for pre-standard features, 
>> and like you say, is still the case for GNU attribute handling between Clang 
>> and GCC, given GCC's poorly-defined rules.)
>
> Ah, I meant more that we have flexibility on what we want the grammar of the 
> extension to be. If other implementations wanted to pick up the 
> functionality, hopefully they'd pick up the same grammar as well.

Yeah, that's also how I was interpreting your comment.  But my point is that, 
as the definers of this extension, we didn't really come into this 
needing/wanting custom grammar rules.  The grammar for standard attributes 
would have been fine for us.  We can't use those because standard attributes 
aren't allowed to affect semantics, but that's a rule imposed on us by the 
standard rather than a rule that we're imposing on ourselves.  The grammar 
rules and the appurtenance rules would have been fine.

In other words, I agree that we have the flexibility to define specific rules 
for this extension that do whatever we want.  But I don't think the extension 
is unusual enough to need that flexibility.  There doesn't seem to be anything 
about the semantic function type properties in this extension that would 
require different grammar rules from other semantic function type properties.  
It seems better to have a generic way of attaching target-specific semantic 
information to types (and objects), just like the standard provides a generic 
way of attaching target-specific non-semantic information.

>> For example, a type property like `__arm_streaming` only applies to 
>> functions, so it wouldn't make sense for bespoke rules to allow the keyword 
>> in tagged types or in array types.  If a property only applies to object 
>> types then it wouldn't make sense for bespoke rules to allow the keyword 
>> after a parameter list.
>
> Agreed, but that's a semantic property of the attribute rather than a 
> syntactic property. We have control over both, of course, because this is our 
> extension and we can define it how we like. But I was expecting we'd define a 
> syntactic location to parse the attribute and we'd handle appertainance 
> issues in SemaDeclAttr.cpp when deciding whether to convert the parsed 
> attribute into a semantic attribute or not.

Like you say, I think we're in agreement here, but approaching it from 
different angles.  What I meant is that, if we add grammar rules that apply 
only to the keywords defined in this extension, those grammar rules would 
probably not allow the keyword to appear in things like tagged types or array 
types, because they would never be needed there.  If each extension defines its 
own grammar rules, those rules would generally not allow keywords to appear in 
places where the keywords are always semantically invalid (although see below). 
 This reduces the extent to which bespoke grammar rules for one extension can 
be cut-&-pasted into another extension.

Having grammar rules that are defined robotically based on the standard 
attribute grammar rules, rather than trying to tailor the grammar rules 
specifically to SME, should make it much more likely that the same grammar 
rules can be reused by later extensions.  Doing that moves all of the 
extension-specific constraint checking to semantic analysis, rather than 
splitting it between parsing and semantic analysis.

>> So I think it makes sense to try to make the SME attributes an instance of a 
>> (new) generic solution.  I think we want something “like standard 
>> attributes, but for semantic information”.  That might sound like wanting 
>> something “like ice, but not cold”.  But a lot of valuable work went into 
>> defining the parsing rules for standard attributes, and defining what they 
>> appertain to.  It seems like a good idea to reuse those parts rather than 
>> reinvent the wheel.
>>
>> https://reviews.llvm.org/D139028 is an RFC for adding “attribute-like 
>> keywords”: keywords that can appear exactly where a standard attribute can 
>> appear.  This means that the keywords are syntactically valid in far more 
>> places than necessary for this initial use case, but it provides a simple 
>> and mechanical rule.  And the keywords would have to be rejected in those 
>> additional places anyway, 

[PATCH] D127762: [Clang][AArch64] Add ACLE attributes for SME.

2022-11-30 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Thanks @aaron.ballman for the feedback about spellings.  I've gone with the 
lower-case names like `__arm_streaming` in what follows, as a plausible 
strawman.

My main concern with keywords is:

> This approach means there's plenty of flexibility available to parse the 
> keyword where you think it makes sense.

If everyone parses keywords where it makes sense to them personally, for their 
specific use case, I'm worried that we'll end up with a lot of slightly 
different rules.  (This tended to happen for pre-standard features, and like 
you say, is still the case for GNU attribute handling between Clang and GCC, 
given GCC's poorly-defined rules.)

For example, a type property like `__arm_streaming` only applies to functions, 
so it wouldn't make sense for bespoke rules to allow the keyword in tagged 
types or in array types.  If a property only applies to object types then it 
wouldn't make sense for bespoke rules to allow the keyword after a parameter 
list.

So I think it makes sense to try to make the SME attributes an instance of a 
(new) generic solution.  I think we want something “like standard attributes, 
but for semantic information”.  That might sound like wanting something “like 
ice, but not cold”.  But a lot of valuable work went into defining the parsing 
rules for standard attributes, and defining what they appertain to.  It seems 
like a good idea to reuse those parts rather than reinvent the wheel.

https://reviews.llvm.org/D139028 is an RFC for adding “attribute-like 
keywords”: keywords that can appear exactly where a standard attribute can 
appear.  This means that the keywords are syntactically valid in far more 
places than necessary for this initial use case, but it provides a simple and 
mechanical rule.  And the keywords would have to be rejected in those 
additional places anyway, even if we don't parse them as attributes.

The covering note has a lot more justification (too much, sorry!).  Does this 
look like a possible way forward?

Previously I was arguing in favour of the decl-to-type sliding rule, because:

> From discussions I've had with people who will write/are writing SME code, 
> the distinction between arm_locally_streamng being a property of the 
> definition and arm_streaming being a property of the type seems contrived to 
> them, especially when the usage of SME is private to a single translation 
> unit.

Taking the RFC approach involves abandoning that and sticking strictly to the 
standard appurtenance rules.  But hopefully it's a reasonable trade-off.  The 
sliding rule is clearly going against the direction of travel anyway, so I'm 
probably being too Luddite there.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127762/new/

https://reviews.llvm.org/D127762

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D127762: [Clang][AArch64] Add ACLE attributes for SME.

2022-11-22 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2000
   "overridden virtual function is here">;
+def err_conflicting_overriding_attributes : Error<
+  "virtual function %0 has different attributes "

aaron.ballman wrote:
> rsandifo-arm wrote:
> > rsandifo-arm wrote:
> > > aaron.ballman wrote:
> > > > aaron.ballman wrote:
> > > > > rsandifo-arm wrote:
> > > > > > sdesmalen wrote:
> > > > > > > aaron.ballman wrote:
> > > > > > > > sdesmalen wrote:
> > > > > > > > > aaron.ballman wrote:
> > > > > > > > > > This error and the one below make me wonder whether an 
> > > > > > > > > > attribute spelling is the appropriate way to surface this 
> > > > > > > > > > functionality as opposed to a keyword. Attributes don't 
> > > > > > > > > > typically don't cause errors in these situations, but 
> > > > > > > > > > because these attributes are strongly coupled to their type 
> > > > > > > > > > system effects I can see why you want these to be errors.
> > > > > > > > > > This error and the one below make me wonder whether an 
> > > > > > > > > > attribute spelling is the appropriate way to surface this 
> > > > > > > > > > functionality as opposed to a keyword. 
> > > > > > > > > I'm not sure I understand what you mean, do you have an 
> > > > > > > > > example?
> > > > > > > > `override` and `final` could have been surfaced via attributes, 
> > > > > > > > and in Clang we semantically express them as such (see `Final` 
> > > > > > > > and `Override` in Attr.td), but instead they are surfaced to 
> > > > > > > > the user as keywords in the language standard. You're not under 
> > > > > > > > the same constraints as the standard (you're making a 
> > > > > > > > vendor-specific attribute). We're not super consistent with 
> > > > > > > > whether we use the same approach as the standard (we have some 
> > > > > > > > type attributes that are spelled as attributes like 
> > > > > > > > `vector_size` and others that are spelled via keywords like 
> > > > > > > > `_Nullable`.
> > > > > > > > 
> > > > > > > > So you could spell your type attributes the way you have been 
> > > > > > > > with `__attribute__`, or you could come up with keywords for 
> > > > > > > > them (so instead of using `GNU<"whatever">` for the attribute, 
> > > > > > > > you could use `Keyword<_Whatever>` or `Keyword<__whatever>` 
> > > > > > > > (you'd also need to add them as recognized keyword tokens, 
> > > > > > > > parse them as appropriate, etc).
> > > > > > > > 
> > > > > > > > Note: I don't insist on you using a keyword for these, but I am 
> > > > > > > > wondering if that approach was considered or not given how 
> > > > > > > > non-portable the attributes are (if an implementation ignores 
> > > > > > > > this attribute, it sounds like the program semantics are 
> > > > > > > > unlikely to be correct).
> > > > > > > @rsandifo-arm can you shed some light on whether using a keyword 
> > > > > > > instead of an `attribute` was considered?
> > > > > > Thanks @aaron.ballman for the reviews.
> > > > > >  
> > > > > > Yeah, we did consider using keywords instead.  The main reason for 
> > > > > > sticking with GNU attributes is that they were specifically 
> > > > > > designed as an extensible way of attaching information or 
> > > > > > requirements to the source code, and they provide well-settled 
> > > > > > semantics.  It seemed better to reuse an existing mechanism rather 
> > > > > > than invent something new.
> > > > > > 
> > > > > > Also, as C++ evolves, the semantics of GNU attributes evolve to 
> > > > > > match.  If we surface the SME features as GNU attributes, we 
> > > > > > inherit this development in the underlying semantics, without 
> > > > > > having to maintain our own evolving specification for where the 
> > > > > > keywords can be placed.  For example, when lambdas were introduced, 
> > > > > > GNU attributes were extended to support lambdas.  Something similar 
> > > > > > could happen in future.
> > > > > > 
> > > > > > We could have defined the semantics of the keywords to be that they 
> > > > > > behave exactly like GNU attributes.  However:
> > > > > > 
> > > > > > # If we do that, the advantage of using a keyword is less obvious.  
> > > > > > (I can see the argument that the syntax looks nicer though.)
> > > > > > # Like you say in the review, the semantics of GNU attributes carry 
> > > > > > some historical baggage.  If would be difficult to justify keeping 
> > > > > > that historical baggage for something that is ostensibly new and 
> > > > > > not a GNU attribute as such.
> > > > > > 
> > > > > > A minor, but still nontrivial, reason is that there is less 
> > > > > > appetite in the GCC community for supporting target-specific 
> > > > > > extensions to the core language.  Adding a target-specific keyword 
> > > > > > is likely to be rejected.  It would be acceptable to make the 
> > > > > > “keyword” be a predefined macro 

[PATCH] D127762: [Clang][AArch64] Add ACLE attributes for SME.

2022-11-16 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2000
   "overridden virtual function is here">;
+def err_conflicting_overriding_attributes : Error<
+  "virtual function %0 has different attributes "

rsandifo-arm wrote:
> aaron.ballman wrote:
> > aaron.ballman wrote:
> > > rsandifo-arm wrote:
> > > > sdesmalen wrote:
> > > > > aaron.ballman wrote:
> > > > > > sdesmalen wrote:
> > > > > > > aaron.ballman wrote:
> > > > > > > > This error and the one below make me wonder whether an 
> > > > > > > > attribute spelling is the appropriate way to surface this 
> > > > > > > > functionality as opposed to a keyword. Attributes don't 
> > > > > > > > typically don't cause errors in these situations, but because 
> > > > > > > > these attributes are strongly coupled to their type system 
> > > > > > > > effects I can see why you want these to be errors.
> > > > > > > > This error and the one below make me wonder whether an 
> > > > > > > > attribute spelling is the appropriate way to surface this 
> > > > > > > > functionality as opposed to a keyword. 
> > > > > > > I'm not sure I understand what you mean, do you have an example?
> > > > > > `override` and `final` could have been surfaced via attributes, and 
> > > > > > in Clang we semantically express them as such (see `Final` and 
> > > > > > `Override` in Attr.td), but instead they are surfaced to the user 
> > > > > > as keywords in the language standard. You're not under the same 
> > > > > > constraints as the standard (you're making a vendor-specific 
> > > > > > attribute). We're not super consistent with whether we use the same 
> > > > > > approach as the standard (we have some type attributes that are 
> > > > > > spelled as attributes like `vector_size` and others that are 
> > > > > > spelled via keywords like `_Nullable`.
> > > > > > 
> > > > > > So you could spell your type attributes the way you have been with 
> > > > > > `__attribute__`, or you could come up with keywords for them (so 
> > > > > > instead of using `GNU<"whatever">` for the attribute, you could use 
> > > > > > `Keyword<_Whatever>` or `Keyword<__whatever>` (you'd also need to 
> > > > > > add them as recognized keyword tokens, parse them as appropriate, 
> > > > > > etc).
> > > > > > 
> > > > > > Note: I don't insist on you using a keyword for these, but I am 
> > > > > > wondering if that approach was considered or not given how 
> > > > > > non-portable the attributes are (if an implementation ignores this 
> > > > > > attribute, it sounds like the program semantics are unlikely to be 
> > > > > > correct).
> > > > > @rsandifo-arm can you shed some light on whether using a keyword 
> > > > > instead of an `attribute` was considered?
> > > > Thanks @aaron.ballman for the reviews.
> > > >  
> > > > Yeah, we did consider using keywords instead.  The main reason for 
> > > > sticking with GNU attributes is that they were specifically designed as 
> > > > an extensible way of attaching information or requirements to the 
> > > > source code, and they provide well-settled semantics.  It seemed better 
> > > > to reuse an existing mechanism rather than invent something new.
> > > > 
> > > > Also, as C++ evolves, the semantics of GNU attributes evolve to match.  
> > > > If we surface the SME features as GNU attributes, we inherit this 
> > > > development in the underlying semantics, without having to maintain our 
> > > > own evolving specification for where the keywords can be placed.  For 
> > > > example, when lambdas were introduced, GNU attributes were extended to 
> > > > support lambdas.  Something similar could happen in future.
> > > > 
> > > > We could have defined the semantics of the keywords to be that they 
> > > > behave exactly like GNU attributes.  However:
> > > > 
> > > > # If we do that, the advantage of using a keyword is less obvious.  (I 
> > > > can see the argument that the syntax looks nicer though.)
> > > > # Like you say in the review, the semantics of GNU attributes carry 
> > > > some historical baggage.  If would be difficult to justify keeping that 
> > > > historical baggage for something that is ostensibly new and not a GNU 
> > > > attribute as such.
> > > > 
> > > > A minor, but still nontrivial, reason is that there is less appetite in 
> > > > the GCC community for supporting target-specific extensions to the core 
> > > > language.  Adding a target-specific keyword is likely to be rejected.  
> > > > It would be acceptable to make the “keyword” be a predefined macro that 
> > > > expands to a GNU attribute under the hood, but I don't think that would 
> > > > address the core issue.
> > > > 
> > > > I can definitely understand the unease about using attributes for 
> > > > things that affect semantics.  Like you say, that's going against a 
> > > > core principle of the standard-defined attributes.  But I think in a 
> > > > way, it's unfortunate that GNU-style 

[PATCH] D127762: [Clang][AArch64] Add ACLE attributes for SME.

2022-11-16 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2000
   "overridden virtual function is here">;
+def err_conflicting_overriding_attributes : Error<
+  "virtual function %0 has different attributes "

aaron.ballman wrote:
> aaron.ballman wrote:
> > rsandifo-arm wrote:
> > > sdesmalen wrote:
> > > > aaron.ballman wrote:
> > > > > sdesmalen wrote:
> > > > > > aaron.ballman wrote:
> > > > > > > This error and the one below make me wonder whether an attribute 
> > > > > > > spelling is the appropriate way to surface this functionality as 
> > > > > > > opposed to a keyword. Attributes don't typically don't cause 
> > > > > > > errors in these situations, but because these attributes are 
> > > > > > > strongly coupled to their type system effects I can see why you 
> > > > > > > want these to be errors.
> > > > > > > This error and the one below make me wonder whether an attribute 
> > > > > > > spelling is the appropriate way to surface this functionality as 
> > > > > > > opposed to a keyword. 
> > > > > > I'm not sure I understand what you mean, do you have an example?
> > > > > `override` and `final` could have been surfaced via attributes, and 
> > > > > in Clang we semantically express them as such (see `Final` and 
> > > > > `Override` in Attr.td), but instead they are surfaced to the user as 
> > > > > keywords in the language standard. You're not under the same 
> > > > > constraints as the standard (you're making a vendor-specific 
> > > > > attribute). We're not super consistent with whether we use the same 
> > > > > approach as the standard (we have some type attributes that are 
> > > > > spelled as attributes like `vector_size` and others that are spelled 
> > > > > via keywords like `_Nullable`.
> > > > > 
> > > > > So you could spell your type attributes the way you have been with 
> > > > > `__attribute__`, or you could come up with keywords for them (so 
> > > > > instead of using `GNU<"whatever">` for the attribute, you could use 
> > > > > `Keyword<_Whatever>` or `Keyword<__whatever>` (you'd also need to add 
> > > > > them as recognized keyword tokens, parse them as appropriate, etc).
> > > > > 
> > > > > Note: I don't insist on you using a keyword for these, but I am 
> > > > > wondering if that approach was considered or not given how 
> > > > > non-portable the attributes are (if an implementation ignores this 
> > > > > attribute, it sounds like the program semantics are unlikely to be 
> > > > > correct).
> > > > @rsandifo-arm can you shed some light on whether using a keyword 
> > > > instead of an `attribute` was considered?
> > > Thanks @aaron.ballman for the reviews.
> > >  
> > > Yeah, we did consider using keywords instead.  The main reason for 
> > > sticking with GNU attributes is that they were specifically designed as 
> > > an extensible way of attaching information or requirements to the source 
> > > code, and they provide well-settled semantics.  It seemed better to reuse 
> > > an existing mechanism rather than invent something new.
> > > 
> > > Also, as C++ evolves, the semantics of GNU attributes evolve to match.  
> > > If we surface the SME features as GNU attributes, we inherit this 
> > > development in the underlying semantics, without having to maintain our 
> > > own evolving specification for where the keywords can be placed.  For 
> > > example, when lambdas were introduced, GNU attributes were extended to 
> > > support lambdas.  Something similar could happen in future.
> > > 
> > > We could have defined the semantics of the keywords to be that they 
> > > behave exactly like GNU attributes.  However:
> > > 
> > > # If we do that, the advantage of using a keyword is less obvious.  (I 
> > > can see the argument that the syntax looks nicer though.)
> > > # Like you say in the review, the semantics of GNU attributes carry some 
> > > historical baggage.  If would be difficult to justify keeping that 
> > > historical baggage for something that is ostensibly new and not a GNU 
> > > attribute as such.
> > > 
> > > A minor, but still nontrivial, reason is that there is less appetite in 
> > > the GCC community for supporting target-specific extensions to the core 
> > > language.  Adding a target-specific keyword is likely to be rejected.  It 
> > > would be acceptable to make the “keyword” be a predefined macro that 
> > > expands to a GNU attribute under the hood, but I don't think that would 
> > > address the core issue.
> > > 
> > > I can definitely understand the unease about using attributes for things 
> > > that affect semantics.  Like you say, that's going against a core 
> > > principle of the standard-defined attributes.  But I think in a way, it's 
> > > unfortunate that GNU-style attributes and standard-defined attributes are 
> > > both called “attributes”, because I don't think there's a prohibition 
> > > (even in theory) against GNU attributes affecting 

[PATCH] D127762: [Clang][AArch64] Add ACLE attributes for SME.

2022-10-28 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2000
   "overridden virtual function is here">;
+def err_conflicting_overriding_attributes : Error<
+  "virtual function %0 has different attributes "

sdesmalen wrote:
> aaron.ballman wrote:
> > sdesmalen wrote:
> > > aaron.ballman wrote:
> > > > This error and the one below make me wonder whether an attribute 
> > > > spelling is the appropriate way to surface this functionality as 
> > > > opposed to a keyword. Attributes don't typically don't cause errors in 
> > > > these situations, but because these attributes are strongly coupled to 
> > > > their type system effects I can see why you want these to be errors.
> > > > This error and the one below make me wonder whether an attribute 
> > > > spelling is the appropriate way to surface this functionality as 
> > > > opposed to a keyword. 
> > > I'm not sure I understand what you mean, do you have an example?
> > `override` and `final` could have been surfaced via attributes, and in 
> > Clang we semantically express them as such (see `Final` and `Override` in 
> > Attr.td), but instead they are surfaced to the user as keywords in the 
> > language standard. You're not under the same constraints as the standard 
> > (you're making a vendor-specific attribute). We're not super consistent 
> > with whether we use the same approach as the standard (we have some type 
> > attributes that are spelled as attributes like `vector_size` and others 
> > that are spelled via keywords like `_Nullable`.
> > 
> > So you could spell your type attributes the way you have been with 
> > `__attribute__`, or you could come up with keywords for them (so instead of 
> > using `GNU<"whatever">` for the attribute, you could use 
> > `Keyword<_Whatever>` or `Keyword<__whatever>` (you'd also need to add them 
> > as recognized keyword tokens, parse them as appropriate, etc).
> > 
> > Note: I don't insist on you using a keyword for these, but I am wondering 
> > if that approach was considered or not given how non-portable the 
> > attributes are (if an implementation ignores this attribute, it sounds like 
> > the program semantics are unlikely to be correct).
> @rsandifo-arm can you shed some light on whether using a keyword instead of 
> an `attribute` was considered?
Thanks @aaron.ballman for the reviews.
 
Yeah, we did consider using keywords instead.  The main reason for sticking 
with GNU attributes is that they were specifically designed as an extensible 
way of attaching information or requirements to the source code, and they 
provide well-settled semantics.  It seemed better to reuse an existing 
mechanism rather than invent something new.

Also, as C++ evolves, the semantics of GNU attributes evolve to match.  If we 
surface the SME features as GNU attributes, we inherit this development in the 
underlying semantics, without having to maintain our own evolving specification 
for where the keywords can be placed.  For example, when lambdas were 
introduced, GNU attributes were extended to support lambdas.  Something similar 
could happen in future.

We could have defined the semantics of the keywords to be that they behave 
exactly like GNU attributes.  However:

# If we do that, the advantage of using a keyword is less obvious.  (I can see 
the argument that the syntax looks nicer though.)
# Like you say in the review, the semantics of GNU attributes carry some 
historical baggage.  If would be difficult to justify keeping that historical 
baggage for something that is ostensibly new and not a GNU attribute as such.

A minor, but still nontrivial, reason is that there is less appetite in the GCC 
community for supporting target-specific extensions to the core language.  
Adding a target-specific keyword is likely to be rejected.  It would be 
acceptable to make the “keyword” be a predefined macro that expands to a GNU 
attribute under the hood, but I don't think that would address the core issue.

I can definitely understand the unease about using attributes for things that 
affect semantics.  Like you say, that's going against a core principle of the 
standard-defined attributes.  But I think in a way, it's unfortunate that 
GNU-style attributes and standard-defined attributes are both called 
“attributes”, because I don't think there's a prohibition (even in theory) 
against GNU attributes affecting semantics.  I think GNU attributes are 
designed to be more general than that, probably through historical accretion 
rather than an up-front choice.

Like you say, `vector_size` is one example of something that significantly 
affect semantics.  But there are quite a few others too.  For example:
* GNU targets traditionally provide access to naked functions and interrupt 
handlers through attributes.
* Different calling conventions also use attributes.
* The `target` attribute switches between ISAs in ways that do affect semantics.
* 

[PATCH] D134681: [Clang][AArch64] Add SME outer product intrinsics

2022-10-14 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Thanks for the patch.  This is going to be inconvenient, sorry, but: while 
implementing the specification in GCC, I noticed that the ZA functions weren't 
consistent about whether they had an `_m` suffix.  `svwrite` (MOVA) had one, 
but the MOP intrinsics that you're implementing here didn't.  Since SME2 does 
have some unpredicated instructions, it seems like it would be better to make 
the MOP intrinsics consistent with `svwrite`, with an `_m` suffix.

I've created https://github.com/ARM-software/acle/pull/218 for that change.  
Please let me know if it looks reasonable to you.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134681/new/

https://reviews.llvm.org/D134681

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D113779: [Clang] Add mfp16, mfp16fml and mdotprod flags for ARM target features.

2022-09-08 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

I can see at least three ways of handling this:

1. @paulwalker-arm's suggestion to allow `-march=` without a base architecture 
(or with a dummy base architecture that means “no change”)
2. a single new option `-mfoo=` that applies on top of `-march` and can be used 
to add or remove architecture features
3. individual `-m` and `-mno-` options for each ISA feature.

I think all three achieve the same objective.

I assume for (1) that `-march=` options would apply in-order, so that an 
`-march=` without a base architecture would apply on top of any previous 
`-march=`, whereas an `-march=` with a base architecture would override all 
previous `-march=` options (both old-style and new-style).  This behaviour 
might be an advantage in some situations and a disadvantage in others.  Build 
systems would need to be careful about where in the command line the extra 
features go (but most probably are).

For (2) we could say that all `-mfoo=` options apply (cumulatively, in order) 
to the final `-march` option, even if the `-march` option comes later than some 
of the `-mfoo=` options.  This too could be an advantage in some situations and 
a disadvantage in others (as a reversal of the situation for (1)).

The architecture can already be set by two options rather than one: `-march=` 
and `-mcpu=`.  Currently (at least in GCC), `-march=` trumps the architecture 
effects of `-mcpu=`, even if `-mcpu=` is specified after `-march=`.  I suppose 
the difficulty for (1) is then deciding what should happen if an `-march=` 
without a base architecture is specified alongside an `-mcpu=`.  Does the 
`-march=` option apply to the `-mcpu=` choice of architecture even if the 
`-mcpu=` appears later?  If so, `-march=` options without a base architecture 
would sometimes have a cumulative effect with later (`-mcpu=`) options as well 
as earlier (`-march=` or `-mcpu=`) ones.  This might be non-intuitive and would 
be another way in which `-mcpu=` is not exactly equivalent to the associated 
`-march=` and `-mtune=` options.

So perhaps one advantage of (2) over (1) is that the semantics are easier to 
describe.  `-mfoo=` options apply cumulatively to the command line's final 
choice of base architecture, however that choice is specified.

Personally I'm not very keen on (3).  Reasons:

- (1) and (2) collect the (subtle) semantics about option precedence in a 
single place.  (3) distributes it among many individual options.
- There are a lot of supported ISA features, so there would be a lot of `-m` 
and `-mno-` options to document.  It would become harder to separate out `-m` 
options related to architecture selection from `-m` options that do other 
things.
- With (3) it becomes much harder to check that every supported feature has an 
associated option.  With (1) and (2) this would be guaranteed by construction.
- The `+feature` and `+nofeature` style is also used in things like `#pragma 
GCC target`, which is another mechanism for changing ISA features without 
changing the base architecture.  It feels like the new options are equivalent 
to sticking such pragmas at the start of the translation unit, so it would be 
good for them to use a consistent style.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113779/new/

https://reviews.llvm.org/D113779

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D129135: [doc][ReleaseNotes] Document AArch64 SVE ABI fix from D127209

2022-07-05 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/docs/ReleaseNotes.rst:503
+- Targeting AArch64, since D127209 LLVM now only preserves the z8-z23
+  and p4-p15 registers across a call if the registers z0-z7 or p0-p4 are
+  used to pass data into or out of a subroutine. The new behavior

Should be p0-p3 rather than p0-p4.  LGTM with that change.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D129135/new/

https://reviews.llvm.org/D129135

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D129135: [doc][ReleaseNotes] Document AArch64 SVE ABI fix from D127209

2022-07-05 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/docs/ReleaseNotes.rst:503
+- Targeting AArch64, LLVM now only preserves the z8-z23 registers across
+  a call if the registers z0-z7 are used to pass data into or out of a
+  subroutine. This new behavior now matches the AAPCS. Previously LLVM

Pedantically, I think it should be “the registers z0-z7 or p0-p3”.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D129135/new/

https://reviews.llvm.org/D129135

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103603: [Sema][RISCV] Allow ?: to select Typedef BuiltinType in C

2021-06-03 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Thanks for the fix.  I agree this is the right behaviour FWIW.  I held off 
approving it in case there's another idiom that's preferred when comparing 
canonical types.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103603/new/

https://reviews.llvm.org/D103603

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77056: [Sema] Allow non-member operators for sizeless SVE types

2021-01-11 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

In D77056#2487754 , @rsmith wrote:

> In D77056#2465936 , @rsandifo-arm 
> wrote:
>
>> Either way, I realise this isn't great style.  It just seems like a 
>> practical compromise between the rock of classes having a constant size and 
>> the hard place of vectors having a variable length.
>
> I don't think this is just a question of style; it's a severe limitation to 
> language functionality. In a very broad sense, you would not be able to use 
> these types with templates. For example, even if you define an `operator<` 
> between `svint8_t`, you can't use `std::min` between two `svint8_t`'s. And 
> people are going to try to work around that by defining the operators first, 
> then `#include`ing the algorithms in question, which will lead to ODR issues, 
> will break when C++ modules is enabled, and so on.

I agree that, even after disallowing definitions in the global namespace, the 
feature could still be abused to cause ODR violations.  If that's a showstopper 
then I guess the patch can't go forward.  But it seems like the feature would 
have legitimate uses too.

> It's also a little unclear to me what the motivation for this is. Do you 
> really want to permit (for example) an `operator+` between sizeless vectors 
> that does something other than element-wise addition? If not, then why do we 
> not instead directly provide built-in support for these operators, as we do 
> for all our other vector types?

The aim of the patch is to allow SIMD frameworks like 
https://github.com/google/highway to be ported to SVE.

Most C++ SIMD wrappers are class based, using member functions (including 
member operator functions) for most operations.  `std::simd` is an obvious 
example of this.  This style of framework can't be ported to length-agnostic 
SVE because classes must be a constant size.  But frameworks like Highway 
instead use non-member functions and non-member operator overloads.  That 
approach is compatible with sizeless types.

We'd also like to maintain the current separation between the SIMD library and 
the underlying architecture support.  At it's heart, the SVE ACLE is just a set 
of low-level, machine-specific intrinsic functions.  t's not supposed to be a 
new generic language extension.

I agree the separation between the compiler and the library isn't too important 
for things like `operator+` on uniform types, since the operation only has one 
sensible implementation.  But some areas do provide an element of choice.  E.g.:

- Should `operator&` be defined for float vectors?
- Should `operator%` be implemented, even though it's not a native operation?
- What operators should be defined for `bfloat16_t` vectors?  At the moment, 
even scalar `bfloat16_t` supports very few “native” operations, but SIMD 
frameworks might want to provide more (now or in the future).
- Should `operator[]` be defined for `svbool_t`, and if so, what type should it 
return when applied to lvalues?
- Should mixtures of float and integer types be supported?

Leaving these decisions to the library means that the library can provide a 
consistent interface for multiple targets.  If we pick one behaviour for SVE, 
the library would need to pick the same behaviour for other vector 
architectures or force users to live with the inconsistency.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77056/new/

https://reviews.llvm.org/D77056

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77056: [Sema] Allow non-member operators for sizeless SVE types

2021-01-08 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Ping.  Also, please let me know if the response above doesn't answer the 
concerns and if you'd like more info/justification.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77056/new/

https://reviews.llvm.org/D77056

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77056: [Sema] Allow non-member operators for sizeless SVE types

2020-12-21 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Thanks for the reviews.

In D77056#2463959 , @rsmith wrote:

> That said, I'm concerned that the design of this feature will severely limit 
> its utility. For classes and enums, operators are typically defined in an 
> associated namespace so that they can be found by ADL. For these types, there 
> are no associated namespaces, so user-defined operators for them can never be 
> found by ADL, and such operators are essentially never going to work in 
> generic code. Maybe that's not something you care too much about for the 
> intended use cases?

Yeah, we don't expect the intended use cases would depend on ADL.  The main aim 
is to support a style of SIMD framework in which all operations are performed 
using operators or using non-member functions.  The SIMD framework would then 
have two choices:

1. If all those non-member functions belong to a namespace `foo` and if the 
SIMD framework expects users to be `using namespace foo`, the non-member 
operator overloads can simply be defined in `foo` and be brough into scope that 
way.
2. Otherwise, the framework could handle non-member operator overloads in one 
of the following ways:
  - define the overloads to be static (perhaps the least likely)
  - define the overloads in an anonymous namespace
  - define the overloads in an internal namespace and make the header file use 
that namespace at global scope

The second choice would be awkward if a header file wanted to use the SIMD 
framework internally but leave the user free to use a different SIMD framework. 
 That sort of use case would require the first choice instead.  However, we 
expect in practice this feature will mostly be used in well-controlled 
environments where there is no risk of a clash between SIMD frameworks within a 
package.  Requiring the overloads to be static or defined within a namespace is 
just to prevent accidental ODR violations between packages that are linked 
together.

Either way, I realise this isn't great style.  It just seems like a practical 
compromise between the rock of classes having a constant size and the hard 
place of vectors having a variable length.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77056/new/

https://reviews.llvm.org/D77056

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77056: [Sema] Allow non-member operators for sizeless SVE types

2020-12-18 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.
Herald added a subscriber: NickHung.

Ping.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77056/new/

https://reviews.llvm.org/D77056

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D92222: [Sema] Make more overload candidate types use iterator_ranges (NFC)

2020-12-07 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGfd14a2753368: [Sema] Make more overload candidate types use 
iterator_ranges (NFC) (authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D9/new/

https://reviews.llvm.org/D9

Files:
  clang/lib/Sema/SemaOverload.cpp

Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -7843,26 +7843,14 @@
  bool AllowExplicitConversions,
  const Qualifiers );
 
-  /// pointer_begin - First pointer type found;
-  iterator pointer_begin() { return PointerTypes.begin(); }
-
-  /// pointer_end - Past the last pointer type found;
-  iterator pointer_end() { return PointerTypes.end(); }
-
-  /// member_pointer_begin - First member pointer type found;
-  iterator member_pointer_begin() { return MemberPointerTypes.begin(); }
-
-  /// member_pointer_end - Past the last member pointer type found;
-  iterator member_pointer_end() { return MemberPointerTypes.end(); }
-
-  /// enumeration_begin - First enumeration type found;
-  iterator enumeration_begin() { return EnumerationTypes.begin(); }
-
-  /// enumeration_end - Past the last enumeration type found;
-  iterator enumeration_end() { return EnumerationTypes.end(); }
-
+  llvm::iterator_range pointer_types() { return PointerTypes; }
+  llvm::iterator_range member_pointer_types() {
+return MemberPointerTypes;
+  }
+  llvm::iterator_range enumeration_types() {
+return EnumerationTypes;
+  }
   llvm::iterator_range vector_types() { return VectorTypes; }
-
   llvm::iterator_range matrix_types() { return MatrixTypes; }
 
   bool containsMatrixType(QualType Ty) const { return MatrixTypes.count(Ty); }
@@ -8346,19 +8334,17 @@
   //   T* operator++(T*VQ&, int);
   //   T* operator--(T*VQ&, int);
   void addPlusPlusMinusMinusPointerOverloads() {
-for (BuiltinCandidateTypeSet::iterator
-  Ptr = CandidateTypes[0].pointer_begin(),
-   PtrEnd = CandidateTypes[0].pointer_end();
- Ptr != PtrEnd; ++Ptr) {
+for (QualType PtrTy : CandidateTypes[0].pointer_types()) {
   // Skip pointer types that aren't pointers to object types.
-  if (!(*Ptr)->getPointeeType()->isObjectType())
+  if (!PtrTy->getPointeeType()->isObjectType())
 continue;
 
-  addPlusPlusMinusMinusStyleOverloads(*Ptr,
-(!(*Ptr).isVolatileQualified() &&
- VisibleTypeConversionsQuals.hasVolatile()),
-(!(*Ptr).isRestrictQualified() &&
- VisibleTypeConversionsQuals.hasRestrict()));
+  addPlusPlusMinusMinusStyleOverloads(
+  PtrTy,
+  (!PtrTy.isVolatileQualified() &&
+   VisibleTypeConversionsQuals.hasVolatile()),
+  (!PtrTy.isRestrictQualified() &&
+   VisibleTypeConversionsQuals.hasRestrict()));
 }
   }
 
@@ -8373,11 +8359,7 @@
   //   ref-qualifier, there exist candidate operator functions of the form
   //   T& operator*(T*);
   void addUnaryStarPointerOverloads() {
-for (BuiltinCandidateTypeSet::iterator
-  Ptr = CandidateTypes[0].pointer_begin(),
-   PtrEnd = CandidateTypes[0].pointer_end();
- Ptr != PtrEnd; ++Ptr) {
-  QualType ParamTy = *Ptr;
+for (QualType ParamTy : CandidateTypes[0].pointer_types()) {
   QualType PointeeTy = ParamTy->getPointeeType();
   if (!PointeeTy->isObjectType() && !PointeeTy->isFunctionType())
 continue;
@@ -8417,13 +8399,8 @@
   //
   //   T* operator+(T*);
   void addUnaryPlusPointerOverloads() {
-for (BuiltinCandidateTypeSet::iterator
-  Ptr = CandidateTypes[0].pointer_begin(),
-   PtrEnd = CandidateTypes[0].pointer_end();
- Ptr != PtrEnd; ++Ptr) {
-  QualType ParamTy = *Ptr;
+for (QualType ParamTy : CandidateTypes[0].pointer_types())
   S.AddBuiltinCandidate(, Args, CandidateSet);
-}
   }
 
   // C++ [over.built]p10:
@@ -8457,16 +8434,12 @@
 llvm::SmallPtrSet AddedTypes;
 
 for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
-  for (BuiltinCandidateTypeSet::iterator
-MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(),
- MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end();
-   MemPtr != MemPtrEnd;
-   ++MemPtr) {
+  for (QualType MemPtrTy : CandidateTypes[ArgIdx].member_pointer_types()) {
 // Don't add the same builtin candidate twice.
-if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)).second)
+if (!AddedTypes.insert(S.Context.getCanonicalType(MemPtrTy)).second)
   continue;
 
-QualType ParamTypes[2] = { *MemPtr, *MemPtr };
+QualType ParamTypes[2] = {MemPtrTy, MemPtrTy};
 S.AddBuiltinCandidate(ParamTypes, Args, 

[PATCH] D77056: [Sema] Allow non-member operators for sizeless SVE types

2020-11-27 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

Sorry for reviving this after so long, but I'd like to bump it from an RFC to 
an RFA.  As the new covering message says, the spec is now part of the ACLE 
specification.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77056/new/

https://reviews.llvm.org/D77056

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77056: [Sema][SVE] Allow non-member operators for SVE types

2020-11-27 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm updated this revision to Diff 308073.
rsandifo-arm added a comment.

Rebase onto current trunk, and also on top of:
https://reviews.llvm.org/D9


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77056/new/

https://reviews.llvm.org/D77056

Files:
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Basic/Targets/AArch64.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaCXX/sizeless-1.cpp

Index: clang/test/SemaCXX/sizeless-1.cpp
===
--- clang/test/SemaCXX/sizeless-1.cpp
+++ clang/test/SemaCXX/sizeless-1.cpp
@@ -3,6 +3,10 @@
 // RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++17 %s
 // RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=gnu++17 %s
 
+#if __ARM_FEATURE_SVE_NONMEMBER_OPERATORS != 1
+#error "__ARM_FEATURE_SVE_NONMEMBER_OPERATORS should be defined"
+#endif
+
 namespace std {
 struct type_info;
 }
@@ -461,7 +465,7 @@
   local_int16 = wrapper(); // expected-error {{assigning to 'svint16_t' (aka '__SVInt16_t') from incompatible type 'wrapper'}}
 
   svint8_t _int8 = local_int8;
-  ref_int8 = ref_int8; // expected-warning {{explicitly assigning value of variable of type 'svint8_t' (aka '__SVInt8_t') to itself}}
+  ref_int8 = ref_int8; // expected-warning + {{explicitly assigning value of variable of type 'svint8_t' (aka '__SVInt8_t') to itself}}
   ref_int8 = local_int8;
   local_int8 = ref_int8;
 
@@ -626,3 +630,247 @@
 void incompat_init() { __attribute__((unused)) svint8_t foo = {}; } // expected-warning {{initializing 'svint8_t' (aka '__SVInt8_t') from an empty initializer list is incompatible with C++98}}
 
 #endif
+
+struct struct1 {};
+struct struct2 {};
+
+svint8_t operator()(svint8_t);// expected-error {{must be a non-static member function}}
+svint8_t operator()(svint8_t, int, int, int); // expected-error {{must be a non-static member function}}
+svint8_t operator[](svint8_t, int);   // expected-error {{must be a non-static member function}}
+svint8_t operator->(svint8_t);// expected-error {{must be a non-static member function}}
+static svint8_t operator~(svint8_t);
+namespace {
+svint8_t operator!(svint8_t);
+}
+namespace operators {
+svint8_t operator+(svint8_t); // expected-note + {{not viable}}
+svint8_t operator-(svint8_t); // expected-note + {{not viable}}
+svint8_t operator&(svint8_t &);
+svint8_t operator+(svint8_t, svint8_t);  // expected-note + {{not viable}}
+svint8_t operator-(svint8_t, int);   // expected-note + {{not viable}}
+svint8_t operator-(int, svint8_t);   // expected-note + {{not viable}}
+svint8_t operator*(svint8_t, int);   // expected-note + {{not viable}}
+svint8_t operator*(svint8_t, svint16_t); // expected-note + {{not viable}}
+svint8_t operator/(svint8_t, svint8_t);
+svint8_t operator/(svint8_t, svint16_t); // expected-note + {{not viable}}
+svint8_t operator/(svint16_t, svint8_t); // expected-note + {{not viable}}
+svint8_t operator%(svint8_t, svint8_t);
+svint8_t operator%(svint8_t, svint16_t);
+svint8_t operator%(svint16_t, svint8_t);
+svint8_t operator%(svint16_t, svint16_t);
+svint8_t operator^(svint8_t, svint8_t);
+svint8_t operator&(svint8_t, svint8_t);
+svint8_t operator|(svint8_t, svint8_t);
+svint8_t =(svint8_t &, svint8_t); // expected-error {{must be a non-static member function}}
+svint8_t +=(svint8_t &, int); // expected-note + {{not viable}}
+svint8_t =(svint8_t &, int);
+svint8_t *=(svint8_t &, svint16_t);
+svint8_t /=(svint8_t &, svint8_t);
+svint8_t %=(svint8_t &, svint8_t);
+svint8_t ^=(svint8_t &, svint8_t);
+svint8_t &=(svint8_t &, svint8_t);
+svint8_t |=(svint8_t &, svint8_t);
+bool operator==(svint8_t, svint8_t);  // expected-note + {{not viable}}
+bool operator!=(svint8_t, svint16_t); // expected-note + {{not viable}}
+bool operator<(svint8_t, svint8_t);
+bool operator<(svint8_t, svint16_t);
+bool operator>(svint8_t, svint8_t);
+bool operator>(svint8_t, svint16_t);
+bool operator<=(svint8_t, svint8_t);
+bool operator>=(svint8_t, svint8_t);
+svint8_t operator<<(svint8_t, svint8_t);
+svint8_t operator<<(int, svint8_t);
+svint8_t operator>>(svint8_t, svint8_t);
+svint8_t operator>>(int, svint8_t);
+svint8_t <<=(svint8_t &, svint8_t); // expected-note + {{not viable}}
+svint8_t >>=(svint8_t &, int);  // expected-note + {{not viable}}
+svint8_t ++(svint8_t &);
+svint8_t (svint8_t &, int);
+int operator,(svint8_t, svint8_t);
+} // namespace operators
+
+svint8_t operator-(svint8_t); // expected-error {{overloads of 'operator-' for sizeless types must either be declared 'static' or be declared inside a namespace}}
+
+int operator<<(svint8_t, struct1);
+int operator<<(struct1, svint8_t);
+int 

[PATCH] D92222: [Sema] Make more overload candidate types use iterator_ranges (NFC)

2020-11-27 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
rsandifo-arm requested review of this revision.

I have a patch that adds another group of candidate types to
BuiltinCandidateTypeSet.  Currently two styles are in use: the older
begin/end pairs and the newer iterator_range approach.  I think the
group of candidates that I want to add should use iterator ranges,
but I'd also like to consolidate the handling of the new candidates
with some existing code that uses begin/end pairs.  This patch therefore
converts the begin/end pairs to iterator ranges as a first step.

No functional change intended.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D9

Files:
  clang/lib/Sema/SemaOverload.cpp

Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -7843,26 +7843,14 @@
  bool AllowExplicitConversions,
  const Qualifiers );
 
-  /// pointer_begin - First pointer type found;
-  iterator pointer_begin() { return PointerTypes.begin(); }
-
-  /// pointer_end - Past the last pointer type found;
-  iterator pointer_end() { return PointerTypes.end(); }
-
-  /// member_pointer_begin - First member pointer type found;
-  iterator member_pointer_begin() { return MemberPointerTypes.begin(); }
-
-  /// member_pointer_end - Past the last member pointer type found;
-  iterator member_pointer_end() { return MemberPointerTypes.end(); }
-
-  /// enumeration_begin - First enumeration type found;
-  iterator enumeration_begin() { return EnumerationTypes.begin(); }
-
-  /// enumeration_end - Past the last enumeration type found;
-  iterator enumeration_end() { return EnumerationTypes.end(); }
-
+  llvm::iterator_range pointer_types() { return PointerTypes; }
+  llvm::iterator_range member_pointer_types() {
+return MemberPointerTypes;
+  }
+  llvm::iterator_range enumeration_types() {
+return EnumerationTypes;
+  }
   llvm::iterator_range vector_types() { return VectorTypes; }
-
   llvm::iterator_range matrix_types() { return MatrixTypes; }
 
   bool containsMatrixType(QualType Ty) const { return MatrixTypes.count(Ty); }
@@ -8346,19 +8334,17 @@
   //   T* operator++(T*VQ&, int);
   //   T* operator--(T*VQ&, int);
   void addPlusPlusMinusMinusPointerOverloads() {
-for (BuiltinCandidateTypeSet::iterator
-  Ptr = CandidateTypes[0].pointer_begin(),
-   PtrEnd = CandidateTypes[0].pointer_end();
- Ptr != PtrEnd; ++Ptr) {
+for (QualType PtrTy : CandidateTypes[0].pointer_types()) {
   // Skip pointer types that aren't pointers to object types.
-  if (!(*Ptr)->getPointeeType()->isObjectType())
+  if (!PtrTy->getPointeeType()->isObjectType())
 continue;
 
-  addPlusPlusMinusMinusStyleOverloads(*Ptr,
-(!(*Ptr).isVolatileQualified() &&
- VisibleTypeConversionsQuals.hasVolatile()),
-(!(*Ptr).isRestrictQualified() &&
- VisibleTypeConversionsQuals.hasRestrict()));
+  addPlusPlusMinusMinusStyleOverloads(
+  PtrTy,
+  (!PtrTy.isVolatileQualified() &&
+   VisibleTypeConversionsQuals.hasVolatile()),
+  (!PtrTy.isRestrictQualified() &&
+   VisibleTypeConversionsQuals.hasRestrict()));
 }
   }
 
@@ -8373,11 +8359,7 @@
   //   ref-qualifier, there exist candidate operator functions of the form
   //   T& operator*(T*);
   void addUnaryStarPointerOverloads() {
-for (BuiltinCandidateTypeSet::iterator
-  Ptr = CandidateTypes[0].pointer_begin(),
-   PtrEnd = CandidateTypes[0].pointer_end();
- Ptr != PtrEnd; ++Ptr) {
-  QualType ParamTy = *Ptr;
+for (QualType ParamTy : CandidateTypes[0].pointer_types()) {
   QualType PointeeTy = ParamTy->getPointeeType();
   if (!PointeeTy->isObjectType() && !PointeeTy->isFunctionType())
 continue;
@@ -8417,13 +8399,8 @@
   //
   //   T* operator+(T*);
   void addUnaryPlusPointerOverloads() {
-for (BuiltinCandidateTypeSet::iterator
-  Ptr = CandidateTypes[0].pointer_begin(),
-   PtrEnd = CandidateTypes[0].pointer_end();
- Ptr != PtrEnd; ++Ptr) {
-  QualType ParamTy = *Ptr;
+for (QualType ParamTy : CandidateTypes[0].pointer_types())
   S.AddBuiltinCandidate(, Args, CandidateSet);
-}
   }
 
   // C++ [over.built]p10:
@@ -8457,16 +8434,12 @@
 llvm::SmallPtrSet AddedTypes;
 
 for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
-  for (BuiltinCandidateTypeSet::iterator
-MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(),
- MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end();
-   MemPtr != MemPtrEnd;
-   ++MemPtr) {
+  for (QualType MemPtrTy : CandidateTypes[ArgIdx].member_pointer_types()) {
 

[PATCH] D62962: Clang implementation of sizeless types

2020-11-27 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm abandoned this revision.
rsandifo-arm added a comment.

Was superceded by later revisions, but I forgot to close this one.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62962/new/

https://reviews.llvm.org/D62962

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D62961: [AST] Add new Type queries for sizeless types

2020-11-27 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm abandoned this revision.
rsandifo-arm added a comment.

Was superceded by later revisions, but I forgot to close this one.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62961/new/

https://reviews.llvm.org/D62961

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79584: [SVE] Add a couple of extra sizeless type tests

2020-11-27 Thread Richard Sandiford via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa2d561f1a336: [SVE] Add a couple of extra sizeless type 
tests (authored by rsandifo-arm).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79584/new/

https://reviews.llvm.org/D79584

Files:
  clang/test/Sema/sizeless-1.c
  clang/test/SemaCXX/sizeless-1.cpp


Index: clang/test/SemaCXX/sizeless-1.cpp
===
--- clang/test/SemaCXX/sizeless-1.cpp
+++ clang/test/SemaCXX/sizeless-1.cpp
@@ -379,6 +379,8 @@
 extern array_alias *array_alias_int8_ptr; // expected-note {{in 
instantiation of template type alias 'array_alias' requested here}}
 #endif
 
+extern "C" svint8_t c_return_int8();
+
 void cxx_only(int sel) {
   svint8_t local_int8;
   svint16_t local_int16;
Index: clang/test/Sema/sizeless-1.c
===
--- clang/test/Sema/sizeless-1.c
+++ clang/test/Sema/sizeless-1.c
@@ -290,4 +290,10 @@
   int a3[_Generic(0, svint8_t : 1, svint16_t : 2, default : 3) == 3 ? 1 : -1];
   (void)_Generic(0, svint8_t : 1, svint8_t : 2, default : 3); // 
expected-error {{type 'svint8_t' (aka '__SVInt8_t') in generic association 
compatible with previously specified type 'svint8_t'}} expected-note 
{{compatible type}}
 }
+
+void test_compound_literal(void) {
+  svint8_t local_int8;
+
+  (void)(svint8_t){local_int8};
+}
 #endif


Index: clang/test/SemaCXX/sizeless-1.cpp
===
--- clang/test/SemaCXX/sizeless-1.cpp
+++ clang/test/SemaCXX/sizeless-1.cpp
@@ -379,6 +379,8 @@
 extern array_alias *array_alias_int8_ptr; // expected-note {{in instantiation of template type alias 'array_alias' requested here}}
 #endif
 
+extern "C" svint8_t c_return_int8();
+
 void cxx_only(int sel) {
   svint8_t local_int8;
   svint16_t local_int16;
Index: clang/test/Sema/sizeless-1.c
===
--- clang/test/Sema/sizeless-1.c
+++ clang/test/Sema/sizeless-1.c
@@ -290,4 +290,10 @@
   int a3[_Generic(0, svint8_t : 1, svint16_t : 2, default : 3) == 3 ? 1 : -1];
   (void)_Generic(0, svint8_t : 1, svint8_t : 2, default : 3); // expected-error {{type 'svint8_t' (aka '__SVInt8_t') in generic association compatible with previously specified type 'svint8_t'}} expected-note {{compatible type}}
 }
+
+void test_compound_literal(void) {
+  svint8_t local_int8;
+
+  (void)(svint8_t){local_int8};
+}
 #endif
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D90956: [clang][SVE] Activate macro `__ARM_FEATURE_SVE_VECTOR_OPERATORS`.

2020-11-11 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

The tests look good to me FWIW.  The Sema side is already covered by 
`Sema/attr-arm-sve-vector-bits.c` and the patch seems to test for the important 
ABI bits.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90956/new/

https://reviews.llvm.org/D90956

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86065: [SVE] Make ElementCount members private

2020-08-28 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

In D86065#2241146 , @david-arm wrote:

> Hi @ctetreau, ok for now I'm going to completely remove the operators and 
> revert the code using those operators to how it was before. I'm not sure what 
> you mean about the predicate functions so I've left those for now, since they 
> aren't needed for this patch. The purpose of this patch was originally 
> supposed to be mechanical anyway - just making members private. I only added 
> the operators as an after-thought really, just to be consistent with how 
> TypeSize dealt with the identical problem. For what it's worth, I believe 
> that GCC solved this exact same problem by adding two types of comparison 
> functions - one set that absolutely wanted an answer to ">,<,>=,<=" and 
> asserted if it wasn't known at compile time, and another set of comparison 
> functions that returned an additional boolean value indicating whether the 
> answer was known or not. Perhaps my knowledge is out of date, but I believe 
> this was the accepted solution and seemed to work well.

FWIW, the GCC scheme is to have one set of functions `maybe_` that are 
true if a condition *might* hold (i.e. would hold for one possible value of the 
runtime indeterminates), and another set of functions `known_` 
(originally `must_`) that are true if a condition *always* holds (i.e. 
would hold for all possible values of the runtime indeterminates).  `known_le` 
is a partial order but `maybe_le` is not (because it isn't antisymmetric).  
Having both is redundant with `!`, since e.g. `known_le` is the opposite of 
`maybe_gt`, but it seemed more readable to allow every condition to be 
expressed positively.

Like you say, there is also a test for whether two values are ordered by 
`known_le`, and there are also some operations like `ordered_min` and 
`ordered_max` that assert if the values aren't ordered by `known_le`.

[Sorry for the post-commit comment, but it's related to something that wasn't 
part of the commit.]


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86065/new/

https://reviews.llvm.org/D86065

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D81083: [Clang] Allow "vector_size" applied to Booleans

2020-08-21 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:492
+
+The memory representation of a boolean vector is the smallest fitting
+power-of-two integer. The alignment is the alignment of that integer type.  
This

simoll wrote:
> rsandifo-arm wrote:
> > It might be worth clarifying this.  With the alignment referring 
> > specifically to “integer type”, I wasn't sure what something like:
> > 
> >   bool __attribute__((vector_size(256)))
> > 
> > would mean on targets that don't provide 256-byte integer types.  Is the 
> > type still 256-byte aligned?
> Not exactly: It is the alignment of the corresponding integer type.
> For example the following C code:
> 
> typedef bool bool256 __attribute__((vector_size(256)));
> bool256 P;
> 
> gives you (x86_64 host, no machine flags specified):
> 
> %P = alloca i2048, align 32
I guess my point is pedantic, but what I meant was: does the concept of “the 
corresponding integer type” necessarily exist at the C/C++ level?  E.g. how 
would you end up with the same LLVM IR statement using C integer types instead 
of vectors?

My worry was that “the alignment of the corresponding integer type” would only 
be meaningful to the user if they could identify what the corresponding (C) 
integer type actually was, and be able to determine its alignment that way.



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81083/new/

https://reviews.llvm.org/D81083

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D85736: [Sema][AArch64] Support arm_sve_vector_bits attribute

2020-08-20 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

LGTM from a spec point of view, but I don't think I should be the one to 
approve.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85736/new/

https://reviews.llvm.org/D85736

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D81083: [Clang] Allow "vector_size" applied to Booleans

2020-08-20 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a comment.

I'm not qualified to review the CodeGen stuff (or accept the patch, obvs. :-)) 
but FWIW, here are some comments on the doc and Sema side.

It might be good to have more Sema tests for valid and invalid usage, e.g. for 
which operators are valid and which aren't.

Thanks again for doing this btw.




Comment at: clang/docs/LanguageExtensions.rst:459
+
+Different than GCC, Clang also allows the attribute to be used with boolean
+element types. For example:

Maybe “Unlike GCC,”?  Not much in it though.



Comment at: clang/docs/LanguageExtensions.rst:489
+  packing).
+* Bitwise `~`, `|`, `&`, `^` and `~` are the only allowed operators on boolean
+  vectors.

`~` is listed twice.  I guess “operators” (without qualification) might make 
people think of the C++ keyword, in which case assignment and `[]` are allowed 
too.



Comment at: clang/docs/LanguageExtensions.rst:492
+
+The memory representation of a boolean vector is the smallest fitting
+power-of-two integer. The alignment is the alignment of that integer type.  
This

It might be worth clarifying this.  With the alignment referring specifically 
to “integer type”, I wasn't sure what something like:

  bool __attribute__((vector_size(256)))

would mean on targets that don't provide 256-byte integer types.  Is the type 
still 256-byte aligned?



Comment at: clang/include/clang/AST/Type.h:3248
 
+  bool isVectorSizeBoolean() const {
+return (getVectorKind() == VectorKind::GenericVector) &&

Maybe isGenericBooleanVector(), so that the terminology is consistent?  Just a 
suggestion though, not sure if it's an improvement.



Comment at: clang/lib/Sema/SemaExpr.cpp:9779
+  return Ty->isBooleanType() ||
+ (Ty->isVectorType() &&
+  Ty->getAs()->getElementType()->isBooleanType());

Is this deliberately wider than isVectorSizeBoolean(), or does it amount to the 
same thing?



Comment at: clang/lib/Sema/SemaExpr.cpp:11929
  VectorType::GenericVector);
+  else if (TypeSize == Context.getTypeSize(Context.BoolTy))
+return Context.getVectorType(Context.BoolTy, VTy->getNumElements(),

In practice, won't this either be a no-op (e.g. for 4-byte-per-bool targets) or 
always trump the fallback CharTy case?  I wasn't sure why the case was needed.



Comment at: clang/lib/Sema/SemaExpr.cpp:11956
+  /*AllowBoolConversions*/ getLangOpts().ZVector,
+  /*AllowBooleanOperation*/ false);
   if (vType.isNull())

Seems like it might be useful to support comparisons too (with false < true, as 
for scalars).  E.g. I guess x == y would otherwise need to be written ~(x ^ y), 
which seems less readable.  Supporting more operators would also help in 
templated contexts.



Comment at: clang/lib/Sema/SemaExprCXX.cpp:6271
+   /*AllowBoolConversions*/ false,
+   /*AllowBoolOperator*/ false);
 

Any reason not to support this for booleans?  ?: seems like a natural operation 
for all vector element types.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81083/new/

https://reviews.llvm.org/D81083

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86101: [AArch64][SVE] Add missing debug info for ACLE types.

2020-08-19 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/lib/CodeGen/CGDebugInfo.cpp:748
+  llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
+  llvm::DIType *ElemTy =
+  getOrCreateType(Info.ElementType, TheCU->getFile());

I might be misreading the code, but if we're representing svbool_t as a bitmask 
(which is a good approach IMO), would it be better to pass UnsignedCharTy 
rather than BoolTy here?  It seems odd to represent the type as  
“bools”.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86101/new/

https://reviews.llvm.org/D86101

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D85736: [Sema][AArch64] Support arm_sve_vector_bits attribute

2020-08-12 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/include/clang/AST/Type.h:1897
+  /// 'arm_sve_vector_bits' type attribute as VectorType.
+  QualType getFixedLengthSveEltType(const ASTContext ) const;
+

It feels to me like the information is more general than that, since the type 
of the element is meaningful independently of the new attribute.  How about 
just getSveEltType instead?



Comment at: clang/lib/AST/ASTContext.cpp:1941
+// Adjust the alignment for fixed-length SVE predicates.
+if (VT->getVectorKind() == VectorType::SveFixedLengthPredicateVector)
+  Align = 16;

The alignment of the SVE data vectors should be 128 too (see the alignof stuff 
in the ACLE doc).  FWIW, there were two reasons for defining it like that:
  - the fixed-length types map to the same ABI machine type as the 
variable-length types
  - the length isn't required to be a power of 2: an implementation that 
supports fixed-length 384-bit vectors could define `__ARM_FEATURE_SVE_BITS` to 
384.






Comment at: clang/lib/AST/TextNodeDumper.cpp:1413
+  case VectorType::SveFixedLengthPredicateVector:
+OS << " fixed-length sve";
   }

Is it worth distinguishing these, similarly to altivec?



Comment at: clang/lib/AST/Type.cpp:2338
+  case BuiltinType::SveUint32:
+return Ctx.UnsignedIntTy;
+  case BuiltinType::SveInt64:

This is just a note, not sure what can be done about it, but:

The element types are defined in terms of the stdint.h types.  One snag is that 
ILP32 newlib defines `int32_t` to be UnsignedLongTy instead of UnsignedIntTy, 
and defines `uint64_t` to UnsignedLongLongTy.

In GCC we got away with this because GCC already has hard-coded knowledge about 
the target C library's choices.  I don't think that information is available 
here though.

Like I say, there's nothing that necessarily needs to be “fixed”/dealt-with 
now, just thought it was worth mentioning.



Comment at: clang/lib/Sema/SemaExpr.cpp:8934
+  ASTContext ) {
+  auto IsValidCast = [](QualType LHSType, QualType RHSType,
+ASTContext ) {

I guess this is personal preference, but it seems more natural to use `[&]` and 
not pass the context.  Maybe different names from LHSType and RHSType would be 
better for the nested function, since it's called with both orders.



Comment at: clang/lib/Sema/SemaExpr.cpp:8942
+VT->getVectorKind() == VectorType::SveFixedLengthPredicateVector &&
+isVector(RHSType, LHSType->getFixedLengthSveEltType(Context)))
+  return true;

Is the isVector just being defensive?  I'd have expected it to be redundant, 
since we shouldn't create SveFixedLengthPredicateVectors with invalid element 
types.



Comment at: clang/lib/Sema/SemaExpr.cpp:8945
+
+if (VT->getVectorKind() == VectorType::SveFixedLengthDataVector &&
+isVector(RHSType, LHSType->getFixedLengthSveEltType(Context)))

It looks like this could still trigger for SveBools.  Maybe it would be better 
to have:

  if (BT->getKind() == BuiltinType::SveBool) {
…
  } else {
…
  }

instead.  Perhaps it'd also be worth having an assert to show that we've 
already checked that any builtin type is an SVE type.



Comment at: clang/lib/Sema/SemaExpr.cpp:9968
+  if ((LHSVecType &&
+   ((LHSVecType->getVectorKind() == VectorType::SveFixedLengthDataVector) 
||
+(LHSVecType->getVectorKind() ==

Seems like it might be useful to have a helper function for testing this pair 
of vector kinds.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85736/new/

https://reviews.llvm.org/D85736

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D81083: [Clang] Allow "vector_size" applied to Booleans

2020-08-04 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:473
+architectures.  The size parameter of a boolean vector type is the number of
+bits in the vector (for all non-bool vectors, the number refers to the number
+of bytes in the vector).

simoll wrote:
> rsandifo-arm wrote:
> > simoll wrote:
> > > rsandifo-arm wrote:
> > > > simoll wrote:
> > > > > rsandifo-arm wrote:
> > > > > > simoll wrote:
> > > > > > > lenary wrote:
> > > > > > > > It would be nice if this aside about non-bool vectors was more 
> > > > > > > > prominently displayed - it's something I hadn't realised before.
> > > > > > > Yep. that caught me by surprise too. I'll move that sentence to 
> > > > > > > the paragraph about GCC vectors above.
> > > > > > Sorry for the extremely late comment.  Like @lenary I hadn't 
> > > > > > thought about this.  I'd assumed that the vector woiuld still be a 
> > > > > > multiple of 8 bits in size, but I agree that's probably too 
> > > > > > restrictive to be the only option available.
> > > > > > 
> > > > > > In that case, would it make sense to add a separate attribute 
> > > > > > instead?  I think it's too surprising to change the units of the 
> > > > > > existing attribute based on the element type.  Perhaps we should 
> > > > > > even make it take two parameters: the total number of elements, and 
> > > > > > the number of bits per element.  That might be more natural for 
> > > > > > some AVX and SVE combinations.  We wouldn't need to supporrt all 
> > > > > > combinations from the outset, it's just a question whether we 
> > > > > > should make the syntax general enough to support it in future.
> > > > > > 
> > > > > > Perhaps we could do both: support `vector_size` for `bool` using 
> > > > > > byte sizes (and not allowing subbyte vector lengths), and add a 
> > > > > > new, more general attribute that allows subbyte lengths and 
> > > > > > explicit subbyte element sizes.
> > > > > > In that case, would it make sense to add a separate attribute 
> > > > > > instead? I think it's too surprising to change the units of the 
> > > > > > existing attribute based on the element type. Perhaps we should 
> > > > > > even make it take two parameters: the total number of elements, and 
> > > > > > the number of bits per element. That might be more natural for some 
> > > > > > AVX and SVE combinations. We wouldn't need to supporrt all 
> > > > > > combinations from the outset, it's just a question whether we 
> > > > > > should make the syntax general enough to support it in future.
> > > > > 
> > > > > I guess adding a new attribute makes sense mid to long term. For now, 
> > > > > i'd want something that just does the job... ie, what is proposed 
> > > > > here. We should absolutely document the semantics of vector_size 
> > > > > properly.. it already is counterintuitive (broken, if you ask me).
> > > > > 
> > > > > 
> > > > > > Perhaps we could do both: support vector_size for bool using byte 
> > > > > > sizes (and not allowing subbyte vector lengths), and add a new, 
> > > > > > more general attribute that allows subbyte lengths and explicit 
> > > > > > subbyte element sizes.
> > > > > 
> > > > > Disallowing subbyte bool vectors actually makes this more complicated 
> > > > > because these types are produced implicitly by compares of (legal) 
> > > > > vector types. Consider this:
> > > > > 
> > > > >   typedef int int3 __attribute__((vector_size(3 * sizeof(int;
> > > > >   int3 A = ...;
> > > > >   int3 B = ...;
> > > > >   auto Z = A < B; // vector compare yielding a `bool 
> > > > > vector_size(3)`-typed value.
> > > > > 
> > > > > 
> > > > > Regarding your proposal for a separate subbyte element size and 
> > > > > subbyte length, that may or may not make sense but it is surely 
> > > > > something that should be discussed more broadly with its own proposal.
> > > > > > Perhaps we could do both: support vector_size for bool using byte 
> > > > > > sizes (and not allowing subbyte vector lengths), and add a new, 
> > > > > > more general attribute that allows subbyte lengths and explicit 
> > > > > > subbyte element sizes.
> > > > > 
> > > > > Disallowing subbyte bool vectors actually makes this more complicated 
> > > > > because these types are produced implicitly by compares of (legal) 
> > > > > vector types. Consider this:
> > > > > 
> > > > >   typedef int int3 __attribute__((vector_size(3 * sizeof(int;
> > > > >   int3 A = ...;
> > > > >   int3 B = ...;
> > > > >   auto Z = A < B; // vector compare yielding a `bool 
> > > > > vector_size(3)`-typed value.
> > > > 
> > > > Yeah, I understand the need for some way of creating subbyte vectors.  
> > > > I'm just not sure using the existing `vector_size` attribute would be 
> > > > the best choice for that case.  I.e. the objection wasn't based on 
> > > > “keeping things simple” but more “keeping things consistent“.
> > > > 
> > > > That doesn't mean that the above 

[PATCH] D81083: [Clang] Allow "vector_size" applied to Booleans

2020-08-04 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:473
+architectures.  The size parameter of a boolean vector type is the number of
+bits in the vector (for all non-bool vectors, the number refers to the number
+of bytes in the vector).

simoll wrote:
> rsandifo-arm wrote:
> > simoll wrote:
> > > rsandifo-arm wrote:
> > > > simoll wrote:
> > > > > lenary wrote:
> > > > > > It would be nice if this aside about non-bool vectors was more 
> > > > > > prominently displayed - it's something I hadn't realised before.
> > > > > Yep. that caught me by surprise too. I'll move that sentence to the 
> > > > > paragraph about GCC vectors above.
> > > > Sorry for the extremely late comment.  Like @lenary I hadn't thought 
> > > > about this.  I'd assumed that the vector woiuld still be a multiple of 
> > > > 8 bits in size, but I agree that's probably too restrictive to be the 
> > > > only option available.
> > > > 
> > > > In that case, would it make sense to add a separate attribute instead?  
> > > > I think it's too surprising to change the units of the existing 
> > > > attribute based on the element type.  Perhaps we should even make it 
> > > > take two parameters: the total number of elements, and the number of 
> > > > bits per element.  That might be more natural for some AVX and SVE 
> > > > combinations.  We wouldn't need to supporrt all combinations from the 
> > > > outset, it's just a question whether we should make the syntax general 
> > > > enough to support it in future.
> > > > 
> > > > Perhaps we could do both: support `vector_size` for `bool` using byte 
> > > > sizes (and not allowing subbyte vector lengths), and add a new, more 
> > > > general attribute that allows subbyte lengths and explicit subbyte 
> > > > element sizes.
> > > > In that case, would it make sense to add a separate attribute instead? 
> > > > I think it's too surprising to change the units of the existing 
> > > > attribute based on the element type. Perhaps we should even make it 
> > > > take two parameters: the total number of elements, and the number of 
> > > > bits per element. That might be more natural for some AVX and SVE 
> > > > combinations. We wouldn't need to supporrt all combinations from the 
> > > > outset, it's just a question whether we should make the syntax general 
> > > > enough to support it in future.
> > > 
> > > I guess adding a new attribute makes sense mid to long term. For now, i'd 
> > > want something that just does the job... ie, what is proposed here. We 
> > > should absolutely document the semantics of vector_size properly.. it 
> > > already is counterintuitive (broken, if you ask me).
> > > 
> > > 
> > > > Perhaps we could do both: support vector_size for bool using byte sizes 
> > > > (and not allowing subbyte vector lengths), and add a new, more general 
> > > > attribute that allows subbyte lengths and explicit subbyte element 
> > > > sizes.
> > > 
> > > Disallowing subbyte bool vectors actually makes this more complicated 
> > > because these types are produced implicitly by compares of (legal) vector 
> > > types. Consider this:
> > > 
> > >   typedef int int3 __attribute__((vector_size(3 * sizeof(int;
> > >   int3 A = ...;
> > >   int3 B = ...;
> > >   auto Z = A < B; // vector compare yielding a `bool 
> > > vector_size(3)`-typed value.
> > > 
> > > 
> > > Regarding your proposal for a separate subbyte element size and subbyte 
> > > length, that may or may not make sense but it is surely something that 
> > > should be discussed more broadly with its own proposal.
> > > > Perhaps we could do both: support vector_size for bool using byte sizes 
> > > > (and not allowing subbyte vector lengths), and add a new, more general 
> > > > attribute that allows subbyte lengths and explicit subbyte element 
> > > > sizes.
> > > 
> > > Disallowing subbyte bool vectors actually makes this more complicated 
> > > because these types are produced implicitly by compares of (legal) vector 
> > > types. Consider this:
> > > 
> > >   typedef int int3 __attribute__((vector_size(3 * sizeof(int;
> > >   int3 A = ...;
> > >   int3 B = ...;
> > >   auto Z = A < B; // vector compare yielding a `bool 
> > > vector_size(3)`-typed value.
> > 
> > Yeah, I understand the need for some way of creating subbyte vectors.  I'm 
> > just not sure using the existing `vector_size` attribute would be the best 
> > choice for that case.  I.e. the objection wasn't based on “keeping things 
> > simple” but more “keeping things consistent“.
> > 
> > That doesn't mean that the above code should be invalid.  It just means 
> > that it wouldn't be possible to write the type of Z using the existing 
> > `vector_size` attribute.
> > 
> > (FWIW, `vector_size` was originally a GNUism and GCC stil requires vector 
> > sizes to be a power of 2, but I realise that isn't relevant here.  And the 
> > same principle applies with s/3/4 in the above example 

[PATCH] D81083: [Clang] Allow "vector_size" applied to Booleans

2020-08-04 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:473
+architectures.  The size parameter of a boolean vector type is the number of
+bits in the vector (for all non-bool vectors, the number refers to the number
+of bytes in the vector).

simoll wrote:
> rsandifo-arm wrote:
> > simoll wrote:
> > > lenary wrote:
> > > > It would be nice if this aside about non-bool vectors was more 
> > > > prominently displayed - it's something I hadn't realised before.
> > > Yep. that caught me by surprise too. I'll move that sentence to the 
> > > paragraph about GCC vectors above.
> > Sorry for the extremely late comment.  Like @lenary I hadn't thought about 
> > this.  I'd assumed that the vector woiuld still be a multiple of 8 bits in 
> > size, but I agree that's probably too restrictive to be the only option 
> > available.
> > 
> > In that case, would it make sense to add a separate attribute instead?  I 
> > think it's too surprising to change the units of the existing attribute 
> > based on the element type.  Perhaps we should even make it take two 
> > parameters: the total number of elements, and the number of bits per 
> > element.  That might be more natural for some AVX and SVE combinations.  We 
> > wouldn't need to supporrt all combinations from the outset, it's just a 
> > question whether we should make the syntax general enough to support it in 
> > future.
> > 
> > Perhaps we could do both: support `vector_size` for `bool` using byte sizes 
> > (and not allowing subbyte vector lengths), and add a new, more general 
> > attribute that allows subbyte lengths and explicit subbyte element sizes.
> > In that case, would it make sense to add a separate attribute instead? I 
> > think it's too surprising to change the units of the existing attribute 
> > based on the element type. Perhaps we should even make it take two 
> > parameters: the total number of elements, and the number of bits per 
> > element. That might be more natural for some AVX and SVE combinations. We 
> > wouldn't need to supporrt all combinations from the outset, it's just a 
> > question whether we should make the syntax general enough to support it in 
> > future.
> 
> I guess adding a new attribute makes sense mid to long term. For now, i'd 
> want something that just does the job... ie, what is proposed here. We should 
> absolutely document the semantics of vector_size properly.. it already is 
> counterintuitive (broken, if you ask me).
> 
> 
> > Perhaps we could do both: support vector_size for bool using byte sizes 
> > (and not allowing subbyte vector lengths), and add a new, more general 
> > attribute that allows subbyte lengths and explicit subbyte element sizes.
> 
> Disallowing subbyte bool vectors actually makes this more complicated because 
> these types are produced implicitly by compares of (legal) vector types. 
> Consider this:
> 
>   typedef int int3 __attribute__((vector_size(3 * sizeof(int;
>   int3 A = ...;
>   int3 B = ...;
>   auto Z = A < B; // vector compare yielding a `bool vector_size(3)`-typed 
> value.
> 
> 
> Regarding your proposal for a separate subbyte element size and subbyte 
> length, that may or may not make sense but it is surely something that should 
> be discussed more broadly with its own proposal.
> > Perhaps we could do both: support vector_size for bool using byte sizes 
> > (and not allowing subbyte vector lengths), and add a new, more general 
> > attribute that allows subbyte lengths and explicit subbyte element sizes.
> 
> Disallowing subbyte bool vectors actually makes this more complicated because 
> these types are produced implicitly by compares of (legal) vector types. 
> Consider this:
> 
>   typedef int int3 __attribute__((vector_size(3 * sizeof(int;
>   int3 A = ...;
>   int3 B = ...;
>   auto Z = A < B; // vector compare yielding a `bool vector_size(3)`-typed 
> value.

Yeah, I understand the need for some way of creating subbyte vectors.  I'm just 
not sure using the existing `vector_size` attribute would be the best choice 
for that case.  I.e. the objection wasn't based on “keeping things simple” but 
more “keeping things consistent“.

That doesn't mean that the above code should be invalid.  It just means that it 
wouldn't be possible to write the type of Z using the existing `vector_size` 
attribute.

(FWIW, `vector_size` was originally a GNUism and GCC stil requires vector sizes 
to be a power of 2, but I realise that isn't relevant here.  And the same 
principle applies with s/3/4 in the above example anyway.)

> Regarding your proposal for a separate subbyte element size and subbyte 
> length, that may or may not make sense but it is surely something that should 
> be discussed more broadly with its own proposal.

Yeah, I agree any new attribute would need to be discussed more widely.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81083/new/


[PATCH] D81083: [Clang] Allow "vector_size" applied to Booleans

2020-07-31 Thread Richard Sandiford via Phabricator via cfe-commits
rsandifo-arm added a subscriber: lenary.
rsandifo-arm added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:473
+architectures.  The size parameter of a boolean vector type is the number of
+bits in the vector (for all non-bool vectors, the number refers to the number
+of bytes in the vector).

simoll wrote:
> lenary wrote:
> > It would be nice if this aside about non-bool vectors was more prominently 
> > displayed - it's something I hadn't realised before.
> Yep. that caught me by surprise too. I'll move that sentence to the paragraph 
> about GCC vectors above.
Sorry for the extremely late comment.  Like @lenary I hadn't thought about 
this.  I'd assumed that the vector woiuld still be a multiple of 8 bits in 
size, but I agree that's probably too restrictive to be the only option 
available.

In that case, would it make sense to add a separate attribute instead?  I think 
it's too surprising to change the units of the existing attribute based on the 
element type.  Perhaps we should even make it take two parameters: the total 
number of elements, and the number of bits per element.  That might be more 
natural for some AVX and SVE combinations.  We wouldn't need to supporrt all 
combinations from the outset, it's just a question whether we should make the 
syntax general enough to support it in future.

Perhaps we could do both: support `vector_size` for `bool` using byte sizes 
(and not allowing subbyte vector lengths), and add a new, more general 
attribute that allows subbyte lengths and explicit subbyte element sizes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81083/new/

https://reviews.llvm.org/D81083

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   >