Commit Graph

19 Commits

Author SHA1 Message Date
Richard Smith b12e473531 Allow dependent alias template specializations in the preferred_name
attribute.

This was intended to work, but didn't match the checks because these
types are modeled as TemplateSpecializationTypes not TypedefTypes.
2021-01-05 15:33:51 -08:00
Richard Smith 2a2c228c7a Add new 'preferred_name' attribute.
This attribute permits a typedef to be associated with a class template
specialization as a preferred way of naming that class template
specialization. This permits us to specify that (for example) the
preferred way to express 'std::basic_string<char>' is as 'std::string'.

The attribute is applied to the various class templates in libc++ that have
corresponding well-known typedef names.

This is a re-commit. The previous commit was reverted because it exposed
a pre-existing bug that has since been fixed / worked around; see
PR48434.

Differential Revision: https://reviews.llvm.org/D91311
2020-12-09 12:22:35 -08:00
Richard Smith a1344779ab Revert "Add new 'preferred_name' attribute."
This change exposed a pre-existing issue with deserialization cycles
caused by a combination of attributes and template instantiations
violating the deserialization ordering restrictions; see PR48434 for
details.

A previous commit attempted to work around PR48434, but appears to have
only been a partial fix, and fixing this properly seems non-trivial.
Backing out for now to unblock things.

This reverts commit 98f76adf4e and
commit a64c26a47a.
2020-12-08 00:42:48 -08:00
Richard Smith a64c26a47a Fix deserialization cycle in preferred_name attribute.
This is really just a workaround for a more fundamental issue in the way
we deserialize attributes. See PR48434 for details.

Also fix tablegen code generator to produce more correct indentation to
resolve buildbot issues with -Werror=misleading-indentation firing
inside the generated code.
2020-12-07 16:02:05 -08:00
Richard Smith 98f76adf4e Add new 'preferred_name' attribute.
This attribute permits a typedef to be associated with a class template
specialization as a preferred way of naming that class template
specialization. This permits us to specify that (for example) the
preferred way to express 'std::basic_string<char>' is as 'std::string'.

The attribute is applied to the various class templates in libc++ that have
corresponding well-known typedef names.

Differential Revision: https://reviews.llvm.org/D91311
2020-12-07 12:53:07 -08:00
Michael Kruse dc5ce72afa Append new attributes to the end of an AttributeList.
Recommit of r335084 after revert in r335516.

... 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 order, and therefore printed in the wrong order in
-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 effect, especially on
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 attributes' order was changed instead.

This unfortunately causes some 'previous occurrence here' hints to be
textually after the main marker. This typically happens when attributes
are merged, but are incompatible to each other. 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 reverse. 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.

Differential Revision: https://reviews.llvm.org/D48100

llvm-svn: 338800
2018-08-03 01:21:16 +00:00
Michael Kruse 41dd6ced2c Revert "Append new attributes to the end of an AttributeList."
This reverts commit r335084 as requested by David Jones and
Eric Christopher because of differences of emitted warnings.

llvm-svn: 335516
2018-06-25 20:06:13 +00:00
Michael Kruse ea31f0e4b8 Append new attributes to the end of an AttributeList.
... 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
2018-06-19 23:46:52 +00:00
Richard Smith 33bddbd64b Make attribute instantiation instantiate all attributes, not just the first of
each kind.

Attribute instantiation would previously default to instantiating each kind of
attribute only once. This was overridden by a flag whose intended purpose was
to permit attributes from a prior declaration to be inherited onto a new
declaration even if that new declaration had its own copy of the attribute.
This is the wrong behavior: when instantiating attributes from a template, we
should always instantiate all the attributes that were written on that
template.

This patch renames the flag in the Attr class (and TableGen sources) to more
clearly identify what it's actually for, and removes the usage of the flag from
template instantiation. I also removed the flag from AlignedAttr, which was
only added to work around the incorrect suppression of duplicate attribute
instantiation.

llvm-svn: 321834
2018-01-04 23:42:29 +00:00
Aaron Ballman 87e7dea2cd There is no such thing as __attribute__((align)); that's a __declspec attribute. Fixing these test cases to use the proper spelling for their syntax.
llvm-svn: 199141
2014-01-13 21:30:03 +00:00
Douglas Gregor d2472d4cdb Use attribute argument information to determine when to parse attribute arguments as expressions.
This change partly addresses a heinous problem we have with the
parsing of attribute arguments that are a lone identifier. Previously,
we would end up parsing the 'align' attribute of this as an expression
"(Align)":

 template<unsigned Size, unsigned Align>
 class my_aligned_storage
 {
   __attribute__((align((Align)))) char storage[Size];
 };

while this would parse as a "parameter name" 'Align':

 template<unsigned Size, unsigned Align>
 class my_aligned_storage
 {
   __attribute__((align(Align))) char storage[Size];
 };

The code that handles the alignment attribute would completely ignore
the parameter name, so the while the first of these would do what's
expected, the second would silently be equivalent to

 template<unsigned Size, unsigned Align>
 class my_aligned_storage
 {
   __attribute__((align)) char storage[Size];
 };

i.e., use the maximal alignment rather than the specified alignment.

Address this by sniffing the "Args" provided in the TableGen
description of attributes. If the first argument is "obviously"
something that should be treated as an expression (rather than an
identifier to be matched later), parse it as an expression.

Fixes <rdar://problem/13700933>.

llvm-svn: 180973
2013-05-02 23:25:32 +00:00
Douglas Gregor 33ebfe36e5 Revert r180970; it's causing breakage.
llvm-svn: 180972
2013-05-02 23:15:45 +00:00
Douglas Gregor 44dff3f2dc Use attribute argument information to determine when to parse attribute arguments as expressions.
This change partly addresses a heinous problem we have with the
parsing of attribute arguments that are a lone identifier. Previously,
we would end up parsing the 'align' attribute of this as an expression
"(Align)":

  template<unsigned Size, unsigned Align>
  class my_aligned_storage
  {
    __attribute__((align((Align)))) char storage[Size];
  };

while this would parse as a "parameter name" 'Align':

  template<unsigned Size, unsigned Align>
  class my_aligned_storage
  {
    __attribute__((align(Align))) char storage[Size];
  };

The code that handles the alignment attribute would completely ignore
the parameter name, so the while the first of these would do what's
expected, the second would silently be equivalent to

  template<unsigned Size, unsigned Align>
  class my_aligned_storage
  {
    __attribute__((align)) char storage[Size];
  };

i.e., use the maximal alignment rather than the specified alignment.

Address this by sniffing the "Args" provided in the TableGen
description of attributes. If the first argument is "obviously"
something that should be treated as an expression (rather than an
identifier to be matched later), parse it as an expression.

Fixes <rdar://problem/13700933>.

llvm-svn: 180970
2013-05-02 23:08:12 +00:00
Douglas Gregor f892c7fe60 For the various CF and NS attributes, don't complain if the parameter
or return types are dependent. Fixes PR9049.

llvm-svn: 141518
2011-10-09 22:26:49 +00:00
Chandler Carruth a92409c3ec Enhance the diagnostic for negative array sizes to include the
declaration name of the array when present. This ensures that
a poor-man's C++03 static_assert will include the user error message
often embedded in the name.

Update all the tests to reflect the new wording, and add a test for the
name behavior.

llvm-svn: 122802
2011-01-04 04:44:35 +00:00
Chandler Carruth f40c42f2cd Implement dependent alignment attribute support. This is a bit gross given the
current attribute system, but it is enough to handle class templates which
specify parts of their alignment in terms of their template parameters.

This also replaces the attributes test in SemaTemplate with one that actually
tests working attributes instead of broken ones. I plan to add more tests here
for non-dependent attributes in a subsequent patch.

Thanks to John for walking me through some of this. =D

llvm-svn: 106818
2010-06-25 03:22:07 +00:00
Douglas Gregor 6044d691bb Revert r104106; it's breaking linking of Boost.Serialization.
llvm-svn: 104121
2010-05-19 17:02:24 +00:00
Douglas Gregor 21553f5970 Teach clang to instantiate attributes on more declarations. Fixes PR7102.
llvm-svn: 104106
2010-05-19 03:39:53 +00:00
Douglas Gregor bdb604a806 Protect isIntegerConstantExpr from seeing type- or value-dependent
expressions in attributes, pragmas.

llvm-svn: 104083
2010-05-18 23:01:22 +00:00