The comment here was introduced in
a3e01cf822 and suggests that we should
handle declaration statements and non-declaration statements the same,
but don't because ProhibitAttributes() can't handle GNU attributes. That
has recently changed, so remove the comment and handle all statements
the same.
Differential Revision: https://reviews.llvm.org/D99936
GCC 8 introduced these new pragmas to control loop unrolling. We should support them for compatibility reasons and the implementation itself requires few lines of code, since everything needed is already implemented for #pragma unroll/nounroll.
Double square bracket attribute arguments can be arbitrarily complex,
and the attribute argument parsing logic recovers by skipping tokens.
As a fallback recovery mechanism, parse recovery stops before reading a
semicolon. This could lead to an infinite loop in the attribute list
parsing logic.
These proposals make the same changes to both C++ and C and remove a
restriction on standard attributes appearing multiple times in the same
attribute list.
We could warn on the duplicate attributes, but do not. This is for
consistency as we do not warn on attributes duplicated within the
attribute specifier sequence. If we want to warn on duplicated
standard attributes, we should do so both for both situations:
[[foo, foo]] and [[foo]][[foo]].
Clang currently has a bug where it allows you to write [[foo bar]] and
both attributes are silently accepted. This patch corrects the comma
parsing rules for such attributes and handles the test case fallout, as
a few tests were accidentally doing this.
This changes our approach to processing statement attributes to be more
similar to how we process declaration attributes. Namely,
ActOnAttributedStmt() now calls ProcessStmtAttributes() instead of
vice-versa, and there is now an interface split between building an
attributed statement where you already have a list of semantic
attributes and building an attributed statement with attributes from
the parser.
This should make it easier to support statement attributes that are
dependent on a template. In that case, you would add a
TransformFooAttr() function in TreeTransform.h to perform the semantic
checking (morally similar to how Sema::InstantiateAttrs() already works
for declaration attributes) when transforming the semantic attribute at
instantiation time.
Set the source ranges for parsed GNU-style attributes in
ParseGNUAttributes(), the same way that ParseCXX11Attributes() does it.
Differential Revision: https://reviews.llvm.org/D75844
Set the source ranges for parsed GNU-style attributes in
ParseGNUAttributes(), the same way that ParseCXX11Attributes() does it.
Differential Revision: https://reviews.llvm.org/D75844
... instantiations
They are currently not being diagnosed because ProhibitAttributes() does
not handle attribute lists with an invalid source range. But once it
does, we need to allow GNU attributes in this place.
Additionally, start optionally diagnosing empty attr lists in
ProhibitCXX11Attributes(), since ProhibitAttribute() does it.
Differential Revision: https://reviews.llvm.org/D97362
This line has a TODO comment, but the answer to it seems to be "no"
given that clang itself uses attributes on @try statements in its tests.
This ProhibitAttributes() statement is also dead code since
ProhibitAttributs() does not handle GNU attributes at the moment but
those are the only attributes valid in objc.
Differential Revision: https://reviews.llvm.org/D97371
Added basic parsing/sema/serialization support to extend the
existing 'destroy' clause for use with the 'interop' directive.
Differential Revision: https://reviews.llvm.org/D98834
The condition variable is in scope in the loop increment, so we need to
emit the jump destination from wthin the scope of the condition
variable.
For GCC compatibility (and compatibility with real-world 'FOR_EACH'
macros), 'continue' is permitted in a statement expression within the
condition of a for loop, though, so there are two cases here:
* If the for loop has no condition variable, we can emit the jump
destination before emitting the condition.
* If the for loop has a condition variable, we must defer emitting the
jump destination until after emitting the variable. We diagnose a
'continue' appearing in the initializer of the condition variable,
because it would jump past the initializer into the scope of that
variable.
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D98816
Added basic parsing/sema/serialization support for interop directive.
Support for the 'init' clause.
Differential Revision: https://reviews.llvm.org/D98558
Somewhat surprisingly, signature help is emitted as a side-effect of
computing the expected type of a function argument.
The reason is that both actions require enumerating the possible
function signatures and running partial overload resolution, and doing
this twice would be wasteful and complicated.
Change #1: document this, it's subtle :-)
However, sometimes we need to compute the expected type without having
reached the code completion cursor yet - in particular to allow
completion of designators.
eb4ab3358c did this but introduced a
regression - it emits signature help in the wrong location as a side-effect.
Change #2: only emit signature help if the code completion cursor was reached.
Currently there is PP.isCodeCompletionReached(), but we can't use it
because it's set *after* running code completion.
It'd be nice to set this implicitly when the completion token is lexed,
but ConsumeCodeCompletionToken() makes this complicated.
Change #3: call cutOffParsing() *first* when seeing a completion token.
After this, the fact that the Sema::Produce*SignatureHelp() functions
are even more confusing, as they only sometimes do that.
I don't want to rename them in this patch as it's another large
mechanical change, but we should soon.
Change #4: prepare to rename ProduceSignatureHelp() to GuessArgumentType() etc.
Differential Revision: https://reviews.llvm.org/D98488
Previously, the CurFPFeatures state was set to command line settings before
semantic analysis of the nested member functions and initialization
expressions, that's not correct, it should use the pragma state which
is in effect at the lexical position.
Reviewed By: Erich Keane, Aaron Ballman
Differential Revision: https://reviews.llvm.org/D98211
There is no need to check for enabled pragma for core or optional core features,
thus this check is removed
Reviewed By: Anastasia
Differential Revision: https://reviews.llvm.org/D97058
Nested `omp [begin|end] declare variant` inherit the selectors from
surrounding `omp (begin|end) declare variant` constructs. To stop such
propagation the user can add the `disable_selector_propagation` to the
`extension` set in the `implementation` selector.
Reviewed By: tianshilei1992
Differential Revision: https://reviews.llvm.org/D95765
If we have nested declare variant context, it doesn't make sense to
inherit the match extension from the parent. Instead, just skip it.
Reviewed By: JonChesterfield
Differential Revision: https://reviews.llvm.org/D95764
Initial support for using the OpenMPIRBuilder by clang to generate loops using the OpenMPIRBuilder. This initial support is intentionally limited to:
* Only the worksharing-loop directive.
* Recognizes only the nowait clause.
* No loop nests with more than one loop.
* Untested with templates, exceptions.
* Semantic checking left to the existing infrastructure.
This patch introduces a new AST node, OMPCanonicalLoop, which becomes parent of any loop that has to adheres to the restrictions as specified by the OpenMP standard. These restrictions allow OMPCanonicalLoop to provide the following additional information that depends on base language semantics:
* The distance function: How many loop iterations there will be before entering the loop nest.
* The loop variable function: Conversion from a logical iteration number to the loop variable.
These allow the OpenMPIRBuilder to act solely using logical iteration numbers without needing to be concerned with iterator semantics between calling the distance function and determining what the value of the loop variable ought to be. Any OpenMP logical should be done by the OpenMPIRBuilder such that it can be reused MLIR OpenMP dialect and thus by flang.
The distance and loop variable function are implemented using lambdas (or more exactly: CapturedStmt because lambda implementation is more interviewed with the parser). It is up to the OpenMPIRBuilder how they are called which depends on what is done with the loop. By default, these are emitted as outlined functions but we might think about emitting them inline as the OpenMPRuntime does.
For compatibility with the current OpenMP implementation, even though not necessary for the OpenMPIRBuilder, OMPCanonicalLoop can still be nested within OMPLoopDirectives' CapturedStmt. Although OMPCanonicalLoop's are not currently generated when the OpenMPIRBuilder is not enabled, these can just be skipped when not using the OpenMPIRBuilder in case we don't want to make the AST dependent on the EnableOMPBuilder setting.
Loop nests with more than one loop require support by the OpenMPIRBuilder (D93268). A simple implementation of non-rectangular loop nests would add another lambda function that returns whether a loop iteration of the rectangular overapproximation is also within its non-rectangular subset.
Reviewed By: jdenny
Differential Revision: https://reviews.llvm.org/D94973
https://wg21.link/P2173 is making its way through WG21 currently and
has not been formally adopted yet. This feature provides very useful
functionality in that you can specify attributes on the various
function *declarations* generated by a lambda expression, where the
current C++ grammar only allows attributes which apply to the various
function *types* so generated.
This patch implements P2173 on the assumption that it will be adopted
by WG21 with this syntax for C++23.
This commit refactors extension support to allow
specifying whether pragma is needed or not explicitly.
For backward compatibility pragmas are set to required
for all extensions that were added prior to this but
not for OpenCL 3.0 features.
Differential Revision: https://reviews.llvm.org/D97052
Our diagnostics relating to static assertions were a bit confused. For
instance, when in MS compatibility mode in C (where we accept
static_assert even without including <assert.h>), we would fail
to warn the user that they were using the wrong spelling (even in
pedantic mode), we were missing a compatibility warning about using
_Static_assert in earlier standards modes, diagnostics for the optional
message were not reflected in C as they were in C++, etc.
When '__cl_clang_function_pointers' extension is enabled
the parser should allow obtaining the function address.
This fixes PR49264!
Differential Revision: https://reviews.llvm.org/D97203
GNU-style attribute in enum bodies are allowed (and used by several
tests), and this call to ProhibitAttributes() was dead code.
Differential Revision: https://reviews.llvm.org/D97271
If a static assert has a message as the right side of an and condition, suggest a fix it of replacing the '&&' to ','.
`static_assert(cond && "Failed Cond")` -> `static_assert(cond, "Failed cond")`
This use case comes up when lazily replacing asserts with static asserts.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D89065
The tile directive is in OpenMP's Technical Report 8 and foreseeably will be part of the upcoming OpenMP 5.1 standard.
This implementation is based on an AST transformation providing a de-sugared loop nest. This makes it simple to forward the de-sugared transformation to loop associated directives taking the tiled loops. In contrast to other loop associated directives, the OMPTileDirective does not use CapturedStmts. Letting loop associated directives consume loops from different capture context would be difficult.
A significant amount of code generation logic is taking place in the Sema class. Eventually, I would prefer if these would move into the CodeGen component such that we could make use of the OpenMPIRBuilder, together with flang. Only expressions converting between the language's iteration variable and the logical iteration space need to take place in the semantic analyzer: Getting the of iterations (e.g. the overload resolution of `std::distance`) and converting the logical iteration number to the iteration variable (e.g. overload resolution of `iteration + .omp.iv`). In clang, only CXXForRangeStmt is also represented by its de-sugared components. However, OpenMP loop are not defined as syntatic sugar. Starting with an AST-based approach allows us to gradually move generated AST statements into CodeGen, instead all at once.
I would also like to refactor `checkOpenMPLoop` into its functionalities in a follow-up. In this patch it is used twice. Once for checking proper nesting and emitting diagnostics, and additionally for deriving the logical iteration space per-loop (instead of for the loop nest).
Differential Revision: https://reviews.llvm.org/D76342
Before this commit, expression statements could not be annotated
with statement attributes. Whenever parser found attribute, it
unconditionally assumed that it was followed by a declaration.
This not only doesn't allow expression attributes to have attributes,
but also produces spurious error diagnostics.
In order to maintain all previously compiled code, we still assume
that GNU attributes are followed by declarations unless ALL of those
are statement attributes. And even in this case we are not forcing
the parser to think that it should parse a statement, but rather
let it proceed as if no attributes were found.
Differential Revision: https://reviews.llvm.org/D93630
The attribute definition claimed the attribute was inheritable (which
only applies to declaration attributes) and not a statement attribute.
Further, it treats subject appertainment errors as being parse errors
rather than semantic errors, which leads to us accepting invalid code.
For instance, we currently fail to reject:
void foo() {
int i = 1000;
__attribute__((nomerge, opencl_unroll_hint(8)))
if (i) { foo(); }
}
This addresses the issues by clarifying that opencl_unroll_hint is a
statement attribute and handles its appertainment checks in the
semantic layer instead of the parsing layer. This changes the output of
the diagnostic text to be more consistent with other appertainment
errors.
OpenCL keywords 'pipe' and 'generic' are unconditionally
supported for OpenCL C 2.0 or in OpenCL C++ mode. In OpenCL C 3.0
these keywords are available if corresponding optional core
feature is supported.
Reviewed By: Anastasia, svenvh
Differential Revision: https://reviews.llvm.org/D95778
In Clang today, we parse the different attribute syntaxes
(__attribute__, __declspec, and [[]]) in a fairly rigid order. This
leads to confusion for users when they guess the order incorrectly,
and leads to bug reports like PR24559 or necessitates changes like
D94788.
This patch adds a helper function to allow us to more easily parse
attributes in arbitrary order, and then updates all of the places
where we would parse two or more different syntaxes in a rigid order to
use the helper method. The patch does not attempt to handle Microsoft
attributes ([]) because those are ambiguous with other code constructs
and we don't have any attributes that use the syntax.
Currently, there is some refactoring needed in existing interface of OpenCL option
settings to support OpenCL C 3.0. The problem is that OpenCL extensions and features
are not only determined by the target platform but also by the OpenCL version.
Also, there are core extensions/features which are supported unconditionally in
specific OpenCL C version. In fact, these rules are not being followed for all targets.
For example, there are some targets (as nvptx and r600) which don't support
OpenCL C 2.0 core features (nvptx.languageOptsOpenCL.cl, r600.languageOptsOpenCL.cl).
After the change there will be explicit differentiation between optional core and core
OpenCL features which allows giving diagnostics if target doesn't support any of
necessary core features for specific OpenCL version.
This patch also eliminates `OpenCLOptions` instance duplication from `TargetOptions`.
`OpenCLOptions` instance should take place in `Sema` as it's going to be modified
during parsing. Removing this duplication will also allow to generally simplify
`OpenCLOptions` class for parsing purposes.
Reviewed By: Anastasia
Differential Revision: https://reviews.llvm.org/D92277
Currently, there are many instances where `SourceLocation` objects are
converted to raw representation to be stored in structs that are
used as fields of tagged unions.
This is done to make the corresponding structs trivial.
Triviality allows avoiding undefined behavior when implicitly changing
the active member of the union.
However, in most cases, we can explicitly construct an active member
using placement new. This patch adds the required active member
selections and replaces `SourceLocation`-s represented as
`unsigned int` with proper `SourceLocation`-s.
One notable exception is `DeclarationNameLoc`: the objects of this class
are often not properly initialized (so the code currently relies on
its default constructor which uses memset). This class will be fixed
in a separate patch.
Reviewed By: dblaikie
Differential Revision: https://reviews.llvm.org/D94237
This patch adds support for two new variants of the vectorize_width
pragma:
1. vectorize_width(X[, fixed|scalable]) where an optional second
parameter is passed to the vectorize_width pragma, which indicates if
the user wishes to use fixed width or scalable vectorization. For
example the user can now write something like:
#pragma clang loop vectorize_width(4, fixed)
or
#pragma clang loop vectorize_width(4, scalable)
In the absence of a second parameter it is assumed the user wants
fixed width vectorization, in order to maintain compatibility with
existing code.
2. vectorize_width(fixed|scalable) where the width is left unspecified,
but the user hints what type of vectorization they prefer, either
fixed width or scalable.
I have implemented this by making use of the LLVM loop hint attribute:
llvm.loop.vectorize.scalable.enable
Tests were added to
clang/test/CodeGenCXX/pragma-loop.cpp
for both the 'fixed' and 'scalable' optional parameter.
See this thread for context: http://lists.llvm.org/pipermail/cfe-dev/2020-November/067262.html
Differential Revision: https://reviews.llvm.org/D89031