Since we permit using SOME attributes (at the moment, just 1) with
multiversioning, we should improve the message as it still implies that
no attributes should be combined with multiversioning.
This adds infrastructure for a multiversioning whitelist, plus adds
'used' to the allowed list with 'target'. The behavior here mirrors the
implementation in GCC, where 'used' only applies to the single
declaration and doesn't apply to the ifunc or resolver.
This is not being applied to cpu_dispatch and cpu_specific, since the
rules are more complicated for cpu_specific, which emits multiple
symbols. Additionally, the author isn't currently aware of uses in the
wild of this combination, but is aware of a number of target+used
combinations.
Declarations without the attribute were disallowed because it would be
ambiguous which 'target' it was supposed to be on. For example:
void ___attribute__((target("v1"))) foo();
void foo(); // Redecl of above, or fwd decl of below?
void ___attribute__((target("v2"))) foo();
However, a first declaration doesn't have that problem, and erroring
prevents it from working in cases where the forward declaration is
useful.
Additionally, a forward declaration of target==default wouldn't properly
cause multiversioning, so this patch fixes that.
The patch was not split since the 'default' fix would require
implementing the same check for that case, followed by undoing the same
change for the fwd-decl implementation.
Change-Id: I66f2c5bc2477bcd3f7544b9c16c83ece257077b0
llvm-svn: 347805
... instead of prepending it at the beginning (the original behavior
since implemented in r122535 2010-12-23). This builds up an
AttributeList in the the order in which the attributes appear in the
source.
The reverse order caused nodes for attributes in the AST (e.g. LoopHint)
to be in the reverse, and therefore printed in the wrong order by
-ast-dump. Some TODO comments mention this. The order was explicitly
reversed for enable_if attribute overload resolution and name mangling,
which is not necessary anymore with this patch.
The change unfortunately has some secondary effects, especially for
diagnostic output. In the simplest cases, the CHECK lines or expected
diagnostic were changed to the the new output. If the kind of
error/warning changed, the attribute's order was changed instead.
It also causes some 'previous occurrence here' hints to be textually
after the main marker. This typically happens when attributes are
merged, but are incompatible. Interchanging the role of the the main
and note SourceLocation will also cause the case where two different
declaration's attributes (in contrast to multiple attributes of the
same declaration) are merged to be reversed. There is no easy fix
because sometimes previous attributes are merged into a new
declaration's attribute list, sometimes new attributes are added to a
previous declaration's attribute list. Since 'previous occurrence here'
pointing to locations after the main marker is not rare, I left the
markers as-is; it is only relevant when the attributes are declared in
the same declaration anyway, which often is on the same line.
Differential Revision: https://reviews.llvm.org/D48100
llvm-svn: 335084
GCC's attribute 'target', in addition to being an optimization hint,
also allows function multiversioning. We currently have the former
implemented, this is the latter's implementation.
This works by enabling functions with the same name/signature to coexist,
so that they can all be emitted. Multiversion state is stored in the
FunctionDecl itself, and SemaDecl manages the definitions.
Note that it ends up having to permit redefinition of functions so
that they can all be emitted. Additionally, all versions of the function
must be emitted, so this also manages that.
Note that this includes some additional rules that GCC does not, since
defining something as a MultiVersion function after a usage has been made illegal.
The only 'history rewriting' that happens is if a function is emitted before
it has been converted to a multiversion'ed function, at which point its name
needs to be changed.
Function templates and virtual functions are NOT yet supported (not supported
in GCC either).
Additionally, constructors/destructors are disallowed, but the former is
planned.
llvm-svn: 322028