This policy causes DeclPrinter to skip attributes entirely when printing
attribute lists, for brevity.
Removing attributes from a printed Decl post-facto is very hard (tm),
especially in the presence of more complex declaration syntax, such as
template requires-expressions, alignas-expressions, default values, etc.
It suggested it would be better to print attributes before the decl
kind, to be consistent with value declarations.
But attributes are not accepted by the language before the decl kind:
[[deprecated]] class A;
__attribute__((deprecated)) class A;
__declspec(deprecated) class A;
are all invalid or ignored. The only way to put an attribute before the
decl kind is with something like:
[[deprecated]] struct A {} a;
But that declares a variable, not a record tyoe, and will be correctly
handled by the variable decl printer.
This was motivated by the decl printing for the alignas() keyword
attribute:
class alignas(1) Foo;
would be printed as:
class alignas(1) Foo;
with two spaces before class name.
Rather than trying to help `prettyPrintAttributes` guess what the caller
wants in terms of leading and trailing spaces, have it return an
`optional<string>` which is either the pretty-printed attributes for
Pos,
or `nullopt` if no attributes were found.
That way callers can compose and only print desired prefix/suffix if
they know there are attributes to print.
Add simple test cases for alignas.
This rename was made as part of
https://github.com/llvm/llvm-project/pull/147835 in order to ease
rebasing the PR, and give a nice window for other patches to get rebased
as well.
It has been a while already, so lets go ahead and rename it back.
Prior to this change, for the code like this:
```cpp
template <int, int = 0>
class Tpl;
template <int = 0, int>
class Tpl;
```
pretty-printing produced an uncompilable code:
```cpp
template <int, int = 0> class Tpl;
template <int = 0, int = 0> class Tpl;
```
This is a major change on how we represent nested name qualifications in
the AST.
* The nested name specifier itself and how it's stored is changed. The
prefixes for types are handled within the type hierarchy, which makes
canonicalization for them super cheap, no memory allocation required.
Also translating a type into nested name specifier form becomes a no-op.
An identifier is stored as a DependentNameType. The nested name
specifier gains a lightweight handle class, to be used instead of
passing around pointers, which is similar to what is implemented for
TemplateName. There is still one free bit available, and this handle can
be used within a PointerUnion and PointerIntPair, which should keep
bit-packing aficionados happy.
* The ElaboratedType node is removed, all type nodes in which it could
previously apply to can now store the elaborated keyword and name
qualifier, tail allocating when present.
* TagTypes can now point to the exact declaration found when producing
these, as opposed to the previous situation of there only existing one
TagType per entity. This increases the amount of type sugar retained,
and can have several applications, for example in tracking module
ownership, and other tools which care about source file origins, such as
IWYU. These TagTypes are lazily allocated, in order to limit the
increase in AST size.
This patch offers a great performance benefit.
It greatly improves compilation time for
[stdexec](https://github.com/NVIDIA/stdexec). For one datapoint, for
`test_on2.cpp` in that project, which is the slowest compiling test,
this patch improves `-c` compilation time by about 7.2%, with the
`-fsyntax-only` improvement being at ~12%.
This has great results on compile-time-tracker as well:

This patch also further enables other optimziations in the future, and
will reduce the performance impact of template specialization resugaring
when that lands.
It has some other miscelaneous drive-by fixes.
About the review: Yes the patch is huge, sorry about that. Part of the
reason is that I started by the nested name specifier part, before the
ElaboratedType part, but that had a huge performance downside, as
ElaboratedType is a big performance hog. I didn't have the steam to go
back and change the patch after the fact.
There is also a lot of internal API changes, and it made sense to remove
ElaboratedType in one go, versus removing it from one type at a time, as
that would present much more churn to the users. Also, the nested name
specifier having a different API avoids missing changes related to how
prefixes work now, which could make existing code compile but not work.
How to review: The important changes are all in
`clang/include/clang/AST` and `clang/lib/AST`, with also important
changes in `clang/lib/Sema/TreeTransform.h`.
The rest and bulk of the changes are mostly consequences of the changes
in API.
PS: TagType::getDecl is renamed to `getOriginalDecl` in this patch, just
for easier to rebasing. I plan to rename it back after this lands.
Fixes#136624
Fixes https://github.com/llvm/llvm-project/issues/43179
Fixes https://github.com/llvm/llvm-project/issues/68670
Fixes https://github.com/llvm/llvm-project/issues/92757
This patch extends the canonicalization printing policy to cover
expressions
and template names, and wires that up to the template argument printer,
covering expressions, and to the expression within a dependent decltype.
This is helpful for debugging, or if these expressions somehow end up
in diagnostics, as without this patch they can print as completely
unrelated
expressions, which can be quite confusing.
This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to
be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.
Fixes https://github.com/llvm/llvm-project/issues/92292
This is the last item of the OpenACC 3.3 spec. It includes the
implicit-name version of 'routine', plus significant refactorings to
make the two work together. The implicit name version is represented as
an attribute on the function call. This patch also implements the
clauses for the implicit-name version, as well as the A.3.4 warning.
These 4 clauses are mutually exclusive, AND require at least one of
them. Additionally, gang has some additional restrictions in that only
the 'dim' specifier is permitted. This patch implements all of this, and
ends up refactoring the handling of each of these clauses for
readabililty.
The 'routine' construct has two forms, one which takes the name of a
function that it applies to, and another where it implicitly figures it
out based on the next declaration. This patch implements the former with
the required restrictions on the name and the function-static-variables
as specified.
What has not been implemented is any clauses for this, any of the A.3.4
warnings, or the other form.
The 'declare' construct is the first of two 'declaration' level
constructs, so it is legal in any place a declaration is, including as a
statement, which this accomplishes by wrapping it in a DeclStmt. All
clauses on this have a 'same scope' requirement, which this enforces as
declaration context instead, which makes it possible to implement these
as a template.
The 'link' and 'device_resident' clauses are also added, which have some
similar/small restrictions, but are otherwise pretty rote.
This patch implements all of the above.
* Don't call raw_string_ostream::flush(), which is essentially a no-op.
* Strip unneeded calls to raw_string_ostream::str(), to avoid extra indirection.
Problem: the printer used to ignore all but the first declarator for
unbraced language linkage declarators. Furthemore, that one would be
printed without the final semicolon.
Solution: when there is more than one declarator, we print them in a
braced `extern <lang>` block. If the original declaration was unbraced
and there is one or less declarator, we omit the braces, but add the
semicolon.
**N.B.** We are printing braces which were, in some cases, absent from
the original CST. If that's an issue, I'll work on it. See the tests for
the examples.
This is an enabler for https://github.com/llvm/llvm-project/pull/92855
This allows an NTTP default argument to be set as an arbitrary
TemplateArgument, not just an expression.
This allows template parameter packs to have default arguments in the
AST, even though the language proper doesn't support the syntax for it.
This allows NTTP default arguments to be other kinds of arguments, like
packs, integral constants, and such.
This is an enabler for a future patch.
This allows an type-parameter default argument to be set as an arbitrary
TemplateArgument, not just a type.
This allows template parameter packs to have default arguments in the
AST, even though the language proper doesn't support the syntax for it.
This will be used in a later patch which synthesizes template parameter
lists with arbitrary default arguments taken from template
specializations.
There are a few places we used SubsType, because we only had a type, now
we use SubstTemplateArgument.
SubstTemplateArgument was missing arguments for setting Instantiation
location and entity names.
Adding those is needed so we don't regress in diagnostics.
Our current method of storing the template arguments as written for
`(Class/Var)Template(Partial)SpecializationDecl` suffers from a number
of flaws:
- We use `TypeSourceInfo` to store `TemplateArgumentLocs` for class
template/variable template partial/explicit specializations. For
variable template specializations, this is a rather unintuitive hack (as
we store a non-type specialization as a type). Moreover, we don't ever
*need* the type as written -- in almost all cases, we only want the
template arguments (e.g. in tooling use-cases).
- The template arguments as written are stored in a number of redundant
data members. For example, `(Class/Var)TemplatePartialSpecialization`
have their own `ArgsAsWritten` member that stores an
`ASTTemplateArgumentListInfo` (the template arguments).
`VarTemplateSpecializationDecl` has yet _another_ redundant member
"`TemplateArgsInfo`" that also stores an `ASTTemplateArgumentListInfo`.
This patch eliminates all
`(Class/Var)Template(Partial)SpecializationDecl` members which store the
template arguments as written, and turns the `ExplicitInfo` member into
a `llvm::PointerUnion<const ASTTemplateArgumentListInfo*,
ExplicitInstantiationInfo*>` (to avoid unnecessary allocations when the
declaration isn't an explicit instantiation). The template arguments as
written are now accessed via `getTemplateArgsWritten` in all cases.
The "most breaking" change is to AST Matchers, insofar that `hasTypeLoc`
will no longer match class template specializations (since they no
longer store the type as written).
This patch adds a `Typename` bit-field to `TemplateTemplateParmDecl`
which stores whether the template template parameter was declared with
the `typename` keyword.
Original commit message:
"
Commit https://github.com/llvm/llvm-project/commit/46f3ade introduced a notion
of printing the attributes on the left to improve the printing of attributes
attached to variable declarations. The intent was to produce more GCC compatible
code because clang tends to print the attributes on the right hand side which is
not accepted by gcc.
This approach has increased the complexity in tablegen and the attrubutes
themselves as now the are supposed to know where they could appear. That lead to
mishandling of the `override` keyword which is modelled as an attribute in
clang.
This patch takes an inspiration from the existing approach and tries to keep the
position of the attributes as they were written. To do so we use simpler
heuristic which checks if the source locations of the attribute precedes the
declaration. If so, it is considered to be printed before the declaration.
Fixes https://github.com/llvm/llvm-project/issues/87151
"
The reason for the bot breakage is that attributes coming from ApiNotes are not
marked implicit even though they do not have source locations. This caused an
assert to trigger. This patch forces attributes with no source location
information to be printed on the left. That change is consistent to the overall
intent of the change to increase the chances for attributes to compile across
toolchains and at the same time the produced code to be as close as possible to
the one written by the user.
Commit https://github.com/llvm/llvm-project/commit/46f3ade introduced a
notion of printing the attributes on the left to improve the printing of
attributes attached to variable declarations. The intent was to produce
more GCC compatible code because clang tends to print the attributes on
the right hand side which is not accepted by gcc.
This approach has increased the complexity in tablegen and the
attrubutes themselves as now the are supposed to know where they could
appear. That lead to mishandling of the `override` keyword which is
modelled as an attribute in clang.
This patch takes an inspiration from the existing approach and tries to
keep the position of the attributes as they were written. To do so we
use simpler heuristic which checks if the source locations of the
attribute precedes the declaration. If so, it is considered to be
printed before the declaration.
Fixes https://github.com/llvm/llvm-project/issues/87151
Predefined macro FUNCTION in clang is not returning the same string than
MS for templated functions.
See https://godbolt.org/z/q3EKn5zq4
For the same test case MSVC is returning:
function: TestClass::TestClass
function: TestStruct::TestStruct
function: TestEnum::TestEnum
The initial work for this was in the reverted patch
(https://github.com/llvm/llvm-project/pull/66120). This patch solves the
issues raised in the reverted patch.
According to [dcl.fct] p23:
> An abbreviated function template can have a _template-head_. The
invented _template-parameters_ are appended to the
_template-parameter-list_ after the explicitly declared
_template-parameters_.
`template<>` is not a _template-head_ -- a _template-head_ must have at
least one _template-parameter_. This patch corrects our current behavior
of appending the invented template parameters to the innermost template
parameter list, regardless of whether it is empty. Example:
```
template<typename T>
struct A
{
void f(auto);
};
template<>
void A<int>::f(auto); // ok
template<>
template<> // warning: extraneous template parameter list in template specialization
void A<int>::f(auto);
```
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.
I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
This patch converts `LinkageSpecDecl::LanguageIDs` into scoped enum, and moves it to namespace scope, so that it can be forward-declared where required.
This patch moves `OMPDeclareReductionDecl::InitKind` to DeclBase.h, so that it's complete at the point where corresponding bit-field is declared. This patch also converts it to scoped enum named `OMPDeclareReductionInitKind`
Currently there is no PrintOnLeft attribute set, which results in an
empty switch-case. When compiling this, MSVC issues a warning saying
that the switch-case is empty. Fix this by using a macro and checking
if this macro is defined or not.
Links to D157394
Previously clang AST prints the following declaration:
int fun_var_unused() {
int x __attribute__((unused)) = 0;
return x;
}
and
int __declspec(thread) x = 0;
as:
int fun_var_unused() {
int x = 0 __attribute__((unused));
return x;
}
and
int x = __declspec(thread) 0;
which is rejected by C/C++ parser. This patch modifies the logic to
print old C attributes for variables as:
int __attribute__((unused)) x = 0;
and the __declspec case as:
int __declspec(thread) x = 0;
Fixes: https://github.com/llvm/llvm-project/issues/59973
Previous version: D141714.
Differential Revision:https://reviews.llvm.org/D141714
DeclPrinter::PrintConstructorInitializers did output non-written constructor initiaizers. In particular, implicit constructor initializers of base classes were output.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D156523
DeclPrinter used FunctionDecl::isThisDeclarationADefinition to decide if the decl requires a semicolon at the end. However, there are several methods without body (that require a semicolon) that are definitions.
Fixes https://github.com/llvm/llvm-project/issues/62996
Initial commit had a failing test case on targets not supporting `__attribute__((alias))`. Added `-triple i386-linux-gnu` to the specific test case.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D156533