901 Commits

Author SHA1 Message Date
Chuanqi Xu
45aec9a0b5 [NFC] [Serialization] Remove redundant hasPendingBody member
The hasPendingBody member is redundant with the
PendingBodies.count(Decl*) method. This patch removes the redundant
hasPendingBody member and the corresponding InterestingDecl struct.
2024-04-09 17:50:23 +08:00
Chuanqi Xu
3f6bc1adf8 [C++20] [Moduls] Avoid computing odr hash for functions from comparing constraint expression
Previously we disabled to compute ODR hash for declarations from the
global module fragment. However, we missed the case that the functions
lives in the concept requiments (see the attached the test files for
example). And the mismatch causes the potential crashment.

Due to we will set the function body as lazy after we deserialize it and
we will only take its body when needed. However, we don't allow to take
the body during deserializing. So it is actually potentially problematic
if we set the body as lazy first and computing the hash value of the
function, which requires to deserialize its body. So we will meet a
crash here.

This patch tries to solve the issue by not taking the body of the
function from GMF. Note that we can't skip comparing the constraint
expression from the GMF directly since it is an key part of the
function selecting and it may be the reason why we can't return 0
directly for `FunctionDecl::getODRHash()` from the GMF.
2024-03-11 11:39:21 +08:00
Chuanqi Xu
49775b1dc0
[Serialization] Record whether the ODR is skipped (#82302)
Close https://github.com/llvm/llvm-project/issues/80570.

In

a0b6747804,
we skipped ODR checks for decls in GMF. Then it should be natural to
skip storing the ODR values in BMI.

Generally it should be fine as long as the writer and the reader keep
consistent.

However, the use of preamble in clangd shows the tricky part.

For,

```
// test.cpp
module;

// any one off these is enough to crash clangd
// #include <iostream>
// #include <string_view>
// #include <cmath>
// #include <system_error>
// #include <new>
// #include <bit>
// probably many more

// only ok with libc++, not the system provided libstdc++ 13.2.1

// these are ok

export module test;
```

clangd will store the headers as preamble to speedup the parsing and the
preamble reuses the serialization techniques. (Generally we'd call the
preamble as PCH. However it is not true strictly. I've tested the PCH
wouldn't be problematic.) However, the tricky part is that the preamble
is not modules. It literally serialiaze and deserialize things. So
before clangd parsing the above test module, clangd will serialize the
headers into the preamble. Note that there is no concept like GMF now.
So the ODR bits are stored. However, when clangd parse the file
actually, the decls from preamble are thought as in GMF literally, then
hte ODR bits are skipped. Then mismatch happens.

To solve the problem, this patch adds another bit for decls to record
whether or not the ODR bits are skipped.
2024-02-20 13:31:28 +08:00
Chuanqi Xu
8eea582dcb
[C++20] [Modules] Introduce -fskip-odr-check-in-gmf (#79959)
Close https://github.com/llvm/llvm-project/issues/79240

Cite the comment from @mizvekov in
//github.com/llvm/llvm-project/issues/79240:

> There are two kinds of bugs / issues relevant here:
>
> Clang bugs that this change hides
> Here we can add a Frontend flag that disables the GMF ODR check, just
> so
> we can keep tracking, testing and fixing these issues.
> The Driver would just always pass that flag.
> We could add that flag in this current issue.
> Bugs in user code:
> I don't think it's worth adding a corresponding Driver flag for
> controlling the above Frontend flag, since we intend it's behavior to
> become default as we fix the problems, and users interested in testing
> the more strict behavior can just use the Frontend flag directly.

This patch follows the suggestion:
- Introduce the CC1 flag `-fskip-odr-check-in-gmf` which is by default
off, so that the every existing test will still be tested with checking
ODR violations.
- Passing `-fskip-odr-check-in-gmf` in the driver to keep the behavior
we intended.
- Edit the document to tell the users who are still interested in more
strict checks can use `-Xclang -fno-skip-odr-check-in-gmf` to get the
existing behavior.
2024-02-01 13:44:32 +08:00
Chuanqi Xu
a0b6747804 [C++20] [Modules] Don't perform ODR checks in GMF
Close https://github.com/llvm/llvm-project/issues/79240.

See the linked issue for details. Given the frequency of issue reporting
about false positive ODR checks (I received private issue reports too),
I'd like to backport this to 18.x too.
2024-01-29 11:44:59 +08:00
Chuanqi Xu
dd3e6c87f3
Support C++20 Modules in clang-repl (#79261)
This comes from when I playing around clang-repl with moduels : )

I succeeded to import std with https://libcxx.llvm.org/Modules.html and
calling `std::printf` after this patch.

I want to put the documentation part to
https://clang.llvm.org/docs/StandardCPlusPlusModules.html in a separate
commit.
2024-01-24 15:45:05 +08:00
cor3ntin
e90e43fb9c
[Clang][NFC] Rename CXXMethodDecl::isPure -> is VirtualPure (#78463)
To avoid any possible confusion with the notion of pure function and the
gnu::pure attribute.
2024-01-18 15:30:58 +01:00
Egor Zhdan
77d21e758e
[APINotes] Upstream dependencies of Sema logic to apply API Notes to decls
This upstreams more of the Clang API Notes functionality that is
currently implemented in the Apple fork:
https://github.com/apple/llvm-project/tree/next/clang/lib/APINotes

This is the largest chunk of the API Notes functionality in the
upstreaming process. I will soon submit a follow-up patch to actually
enable usage of this functionality by having a Clang driver flag that
enables API Notes, along with tests.
2024-01-17 13:13:10 +00:00
Craig Topper
142f270c27 Recommit "[AST] Use APIntStorage to fix memory leak in EnumConstantDecl. (#78311)"
With lldb build fix.

Original message:

EnumConstantDecl is allocated by the ASTContext allocator so the
destructor is never called.

This patch takes a similar approach to IntegerLiteral by using
APIntStorage to allocate large APSInts using the ASTContext allocator as
well.

The downside is that an additional heap allocation and copy of the data
needs to be made when calling getInitValue if the APSInt is large.

Fixes #78160.
2024-01-16 13:52:17 -08:00
Craig Topper
f3d534c425 Revert "[AST] Use APIntStorage to fix memory leak in EnumConstantDecl. (#78311)"
This reverts commit 4737959d91fab7673b1bb642f88658bb2a24d723.

Missed an lldb update.
2024-01-16 12:39:47 -08:00
Craig Topper
4737959d91
[AST] Use APIntStorage to fix memory leak in EnumConstantDecl. (#78311)
EnumConstantDecl is allocated by the ASTContext allocator so the
destructor is never called.

This patch takes a similar approach to IntegerLiteral by using
APIntStorage to allocate large APSInts using the ASTContext allocator as
well.

The downside is that an additional heap allocation and copy of the data
needs to be made when calling getInitValue if the APSInt is large.

Fixes #78160.
2024-01-16 12:10:38 -08:00
Chuanqi Xu
52770d83bf [Serialization] Don't pack bits for the function scope index of ParmVarDecl
Close https://github.com/llvm/llvm-project/issues/76443

Previously we assume the bits of the function scope index of ParmVarDecl
won't exceed 8. But this is a misreading. See the implementation of
`ParmVarDecl::getParameterIndex()`, which may
exceed the size of the normal bitfield. So it may be better to not
pack these bits.
2023-12-28 11:04:11 +08:00
Chuanqi Xu
2203a4e6e0 [NFC] [Serialization] Improve AST serialization by reordering packed
bits and extract big bits from packed bits

Previously I tried to improve the size of .pcm files by introducing
packed bits. And I find we can improve it further by reordering the
bits.

The secret comes from the VBR format. We can find the formal definition
of VBR format in the doc of LLVM. The VBR format will be pretty
efficicent for small numbers.

For example, if we need to pack 8 bits into a value and the stored value
is 0xf0, the actual stored value will be 0b000111'110000, which takes 12
bits actually. However, if we changed the order to be 0x0f, then we
can store it as 0b001111, which takes 6 bits only now.

So we can improve the size by placing bits with lower probability to be
1 in the higher bits and extract bit bigs from the packed bits to make
it possible to be optimized by VBR.

After this patch, the size of std module becomes to 27.7MB from 28.1MB.
2023-12-21 16:35:20 +08:00
Chuanqi Xu
565e5e861f Recommit [NFC] [Serialization] Packing more bits and refactor AbbrevToUse
This patch tries to pack more bits into a value to reduce the size of
.pcm files. Also, after we introduced BitsPackers, it may slightly
better to adjust the way we use Abbrev.

After this patch, the size of the BMI for std module reduce from 28.94MB
to 28.1 MB.

This was reverted due to it broke the build of lldb. The reason that we
skip the serialization of a source location incorrectly. And this patch
now fixes that.
2023-12-21 10:30:12 +08:00
Augusto Noronha
eccc1cca71 Revert "[NFC] [Serialization] Packing more bits and refactor AbbrevToUse"
This reverts commit 9cdb825a4f1bf9e75829d03879620c6144d0b7bc.
2023-12-15 14:43:25 -08:00
Chuanqi Xu
9cdb825a4f [NFC] [Serialization] Packing more bits and refactor AbbrevToUse
This patch tries to pack more bits into a value to reduce the size of
.pcm files. Also, after we introduced BitsPackers, it may slightly
better to adjust the way we use Abbrev.

After this patch, the size of the BMI for std module reduce from 28.94MB
to 28.1 MB.
2023-12-15 11:12:52 +08:00
Chuanqi Xu
65b12a8af3 Recommit [NFC] [Serialization] Packing more bits
This patch tries to reduce the size of the BMIs by packing more bits
into an unsigned integer.

This patch was reverted due to buildbot failure report. But it should be
irrevelent after I took a double look. So I tried to recommit this NFC
change again.
2023-12-11 16:47:51 +08:00
Chuanqi Xu
8c33462781 Revert "[NFC] [Serialization] Packing more bits"
This reverts commit 9406ea3fe32e59a7d28de0dcbd0317b4cdfa4c62.

There are build bots complaining this. Revert it first to try to keep
the bots green.
2023-12-11 14:06:32 +08:00
Chuanqi Xu
9406ea3fe3 [NFC] [Serialization] Packing more bits
This patch tries to reduce the size of the BMIs by packing more bits
into an unsigned integer.
2023-12-11 10:18:12 +08:00
Chuanqi Xu
649e8111a9 [C++20] [Modules] Handling capturing strucuted bindings
Close https://github.com/llvm/llvm-project/issues/72828.

This should be an overlook that we extend the type of captures but we
forgot to fix it in deserializer side.
2023-11-29 11:45:31 +08:00
Vlad Serebrennikov
edd690b02e
[clang][NFC] Refactor TagTypeKind (#71160)
This patch converts TagTypeKind into scoped enum. Among other benefits,
this allows us to forward-declare it where necessary.
2023-11-03 21:45:39 +04:00
Chuanqi Xu
48be81e172
[NFC] [Serializer] Pack information in serializer (#69287)
Previously, the boolean values will occupy spaces that can contain
integers. It wastes the spaces especially if the boolean values are
serialized consecutively. The patch tries to pack such consecutive
boolean values (and enum values) so that we can save more spaces and so
the times.

Before the patch, we need 4.478s (in my machine) to build the std module
(https://libcxx.llvm.org/Modules.html) with 28712 bytes for size of the
BMI. After the patch, the time becomes to 4.374s and the size becomes to
27388 bytes for the size of the BMI.

This is intended to be a NFC patch.

This patch doesn't optimize all such cases. We can do it later after we
have consensus on this.
2023-11-03 21:59:44 +08:00
Vlad Serebrennikov
8775947633
[clang][NFC] Refactor clang::Linkage (#71049)
This patch introduces a new enumerator `Invalid = 0`, shifting other enumerators by +1. Contrary to how it might sound, this actually affirms status quo of how this enum is stored in `clang::Decl`:
```
  /// If 0, we have not computed the linkage of this declaration.
  /// Otherwise, it is the linkage + 1.
  mutable unsigned CacheValidAndLinkage : 3;
```
This patch makes debuggers to not be mistaken about enumerator stored in this bit-field. It also converts `clang::Linkage` to a scoped enum.
2023-11-02 20:57:29 +04:00
Vlad Serebrennikov
a8ead56068
[clang][NFC] Rename ArgPassingKind to RecordArgPassingKind (#70955)
During the recent refactoring (b120fe8d3288c4dca1b5427ca34839ce8833f71c) this enum was moved out of `RecordDecl`. During post-commit review it was found out that its association with `RecordDecl` should be expressed in the name.
2023-11-01 20:38:28 +04:00
Vlad Serebrennikov
65761200ce [clang][NFC] Refactor LinkageSpecDecl::LanguageIDs
This patch converts `LinkageSpecDecl::LanguageIDs` into scoped enum, and moves it to namespace scope, so that it can be forward-declared where required.
2023-11-01 16:44:34 +03:00
Vlad Serebrennikov
aaba3761db [clang][NFC] Refactor ObjCMethodDecl::ImplementationControl
This patch moves `ObjCMethodDecl::ImplementationControl` to a DeclBase.h so that it's complete at the point where corresponsing bit-field is declared. This patch also converts it to a scoped enum `clang::ObjCImplementationControl`.
2023-11-01 13:40:11 +03:00
Vlad Serebrennikov
50dec541f3 [clang][NFC] Refactor OMPDeclareReductionDecl::InitKind
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`
2023-11-01 12:40:13 +03:00
Vlad Serebrennikov
b120fe8d32 [clang][NFC] Refactor ArgPassingKind
This patch moves `RecordDecl::ArgPassingKind` to DeclBase.h to namespace scope, so that it's complete at the time bit-field is declared.
2023-11-01 11:49:59 +03:00
Krystian Stasiowski
3a3b84b180
[clang] remove ClassScopeFunctionSpecializationDecl (#66636)
This removes the `ClassScopeFunctionSpecializationDecl` `Decl` node, and
instead uses `DependentFunctionTemplateSpecializationInfo` to handle
such declarations. `DependentFunctionTemplateSpecializationInfo` is also
changed to store a `const ASTTemplateArgumentListInfo*` to be more in
line with `FunctionTemplateSpecializationInfo`.

This also changes `FunctionDecl::isFunctionTemplateSpecialization` to
return `true` for dependent specializations, and
`FunctionDecl::getTemplateSpecializationKind`/`FunctionDecl::getTemplateSpecializationKindForInstantiation`
to return `TSK_ExplicitSpecialization` for non-friend dependent
specializations (the same behavior as dependent class scope
`ClassTemplateSepcializationDecl` & `VarTemplateSepcializationDecl`).
2023-10-07 10:55:31 +04:00
Vlad Serebrennikov
99e6ef3e7c
[clang][NFC] Add missing placement-new after Allocate() calls (#68382)
While working on #68377 inspecting `Allocate()` calls, I found out that
there are couple of places where we forget to use placement-new to
create objects in the allocated memory.
2023-10-06 07:50:07 -04:00
Corentin Jabot
af4751738d [C++] Implement "Deducing this" (P0847R7)
This patch implements P0847R7 (partially),
CWG2561 and CWG2653.

Reviewed By: aaron.ballman, #clang-language-wg

Differential Revision: https://reviews.llvm.org/D140828
2023-10-02 14:33:02 +02:00
Jens Massberg
c2bf9baf59 Add a concept AST node.
This patch adds a concept AST node (`ConceptLoc`) and uses it at the corresponding places.

There are three objects that might have constraints via concepts:
`TypeConstraint`,  `ConceptSpecializationExpr` and `AutoTypeLoc`.
The first two inherit from `ConceptReference` while the latter has
the information about a possible constraint directly stored in `AutoTypeLocInfo`. It would be nice if the concept information would be stored the same way in all three cases.

Moreover the current structure makes it difficult to deal with these concepts. For example in Clangd accessing the locations of constraints of a `AutoTypeLoc` can only be done with quite ugly hacks.

So we think that it makes sense to create a new AST node for such concepts.

In details we propose the following:
- Rename `ConceptReference` to `ConceptLoc` (or something else what is approriate)
and make it the new AST node.
- `TypeConstraint` and `ConceptSpecializationExpr` do not longer inherit from `ConceptReference` but store a pointer to a `ConceptLoc`.
- `AutoTypeLoc` stores a pointer to `ConceptLoc` instead of storing the concept info in `AutoTypeLocInfo`.

This patch implements a first version of this idea which compiles and where the existing tests pass.
To make this patch as small as possible we keep the existing member functions to access concept data. Later these can be replaced by directly calling the corresponding functions of the `ConceptLoc`s.

Differential Revision: https://reviews.llvm.org/D155858
2023-08-31 10:22:21 +02:00
Elizabeth Andrews
c70dab026d [NFC][Clang] Fix static analyzer concern about null value dereference
Differential Revision: https://reviews.llvm.org/D157885
2023-08-14 13:07:24 -07:00
Richard Smith
61c7a9140b Commit to a primary definition for a class when we load its first
member.

Previously, we wouldn't do this if the first member loaded is within a
definition that's added to a class via an update record, which happens
when template instantiation adds a class definition to a declaration
that was imported from an AST file.

This would lead to classes having member functions whose getParent
returned a class declaration that wasn't the primary definition, which
in turn caused the vtable builder to build broken vtables.

I don't yet have a reduced testcase for the wrong-code bug here, because
the setup required to get us into the broken state is very subtle, but
have confirmed that this fixes it.
2023-07-25 15:59:21 -07:00
Sindhu Chittireddy
5942ae8681 [NFC] Initialize class member pointers to nullptr.
Reviewed here: https://reviews.llvm.org/D153926
2023-07-10 11:38:55 -07:00
Yuanfang Chen
632dd6a4ca [Clang] Implements CTAD for aggregates P1816R0 and P2082R1
Differential Revision: https://reviews.llvm.org/D139837
2023-06-29 14:22:24 -07:00
Manna, Soumi
5e12f5ab2d [CLANG] Fix uninitialized scalar field issues
Reviewed By: erichkeane, steakhal, tahonermann, shafik

Differential Revision: https://reviews.llvm.org/D150744
2023-06-22 12:09:14 -07:00
Richard Sandiford
301eb6b68f [clang] Add support for “regular” keyword attributes
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
keyword attributes.

A follow-on patch contains the main Parse and Sema support,
which is enabled automatically by the Attr.td definition.

Other notes:

* The series does not allow regular keyword attributes to take
arguments, but this could be added in future.

* I wondered about trying to use tablegen for
TypePrinter::printAttributedAfter too, 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.

* Generating the tokens automatically from Attr.td means that
pseudo's libgrammar does now depend on tablegen.

* The patch uses the SME __arm_streaming attribute as an example
for testing purposes.  The attribute does not do anything at this
stage.  Later SME-specific patches will add proper semantics for it,
and add other SME-related keyword attributes.

Differential Revision: https://reviews.llvm.org/D148700
2023-05-31 10:43:10 +01:00
Chuanqi Xu
1c9a8004ed Recommit [C++20] [Modules] Serialize the evaluated constant values for VarDecl
Close https://github.com/llvm/llvm-project/issues/62796.

Previously, we didn't serialize the evaluated result for VarDecl. This
caused the compilation of template metaprogramming become slower than
expect. This patch fixes the issue.

This is a recommit tested with asan built clang.
2023-05-24 15:45:16 +08:00
Chuanqi Xu
651b40e8ff Revert "[C++20] [Modules] Serialize the evaluated constant values for VarDecl"
This reverts commit c0d6f85e3ae8bcfdb7217d165314f01c1a4af9ae. The asan
bot detected a memory leak after this patch. Revert it for now.
2023-05-24 13:56:09 +08:00
Chuanqi Xu
c0d6f85e3a [C++20] [Modules] Serialize the evaluated constant values for VarDecl
Close https://github.com/llvm/llvm-project/issues/62796.

Previously, we didn't serialize the evaluated result for VarDecl. This
caused the compilation of template metaprogramming become slower than
expect. This patch fixes the issue.
2023-05-24 10:17:33 +08:00
Richard Sandiford
bd41371be0 [clang] Fix FIXME in isAlignasAttribute()
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)

Differential Revision: https://reviews.llvm.org/D148105
2023-04-13 10:14:50 +01:00
Richard Sandiford
b6d4d51f8f [clang] Specify attribute syntax & spelling with a single argument
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">]).

Differential Revision: https://reviews.llvm.org/D148102
2023-04-13 10:14:49 +01:00
Richard Sandiford
e841d50926 [clang] Ensure that Attr::Create(Implicit) chooses a valid syntax
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.

Differential Revision: https://reviews.llvm.org/D148101
2023-04-13 10:14:48 +01:00
Richard Smith
3242934191 Lazily deserialize default member initializers.
This is important to break deserialization cycles, where a lambda in a
default member initializer can refer to the field as its context
declaration, and the initializer of the field can refer back to the
lambda.

This is a follow-up to bc73ef0031b5, which applied the same fix to
variable declarations for the same reason.
2023-04-05 15:46:13 -07:00
Richard Smith
bc73ef0031 PR60985: Fix merging of lambda closure types across modules.
Previously, distinct lambdas would get merged, and multiple definitions
of the same lambda would not get merged, because we attempted to
identify lambdas by their ordinal position within their lexical
DeclContext. This failed for lambdas within namespace-scope variables
and within variable templates, where the lexical position in the context
containing the variable didn't uniquely identify the lambda.

In this patch, we instead identify lambda closure types by index within
their context declaration, which does uniquely identify them in a way
that's consistent across modules.

This change causes a deserialization cycle between the type of a
variable with deduced type and a lambda appearing as the initializer of
the variable -- reading the variable's type requires reading and merging
the lambda, and reading the lambda requires reading and merging the
variable. This is addressed by deferring loading the deduced type of a
variable until after we finish recursive deserialization.

This also exposes a pre-existing subtle issue where loading a
variable declaration would trigger immediate loading of its initializer,
which could recursively refer back to properties of the variable. This
particularly causes problems if the initializer contains a
lambda-expression, but can be problematic in general. That is addressed
by switching to lazily loading the initializers of variables rather than
always loading them with the variable declaration. As well as fixing a
deserialization cycle, that should improve laziness of deserialization
in general.

LambdaDefinitionData had 63 spare bits in it, presumably caused by an
off-by-one-error in some previous change. This change claims 32 of those bits
as a counter for the lambda within its context. We could probably move the
numbering to separate storage, like we do for the device-side mangling number,
to optimize the likely-common case where all three numbers (host-side mangling
number, device-side mangling number, and index within the context declaration)
are zero, but that's not done in this change.

Fixes #60985.

Reviewed By: #clang-language-wg, aaron.ballman

Differential Revision: https://reviews.llvm.org/D145737
2023-03-30 14:22:40 -07:00
Kazu Hirata
7eaa7b0553 [clang] Use *{Map,Set}::contains (NFC) 2023-03-15 18:06:34 -07:00
Volodymyr Sapsai
2893d55f8f [Serialization] Don't warn when a deserialized category is equivalent to an existing one.
A single class allows multiple categories to be defined for it. But if
two of such categories have the same name, we emit a warning. It's not a
hard error but a good indication of a potential mistake.

With modules, we can end up with the same category in different modules.
Diagnosing such a situation has little value as the categories in
different modules are equivalent and don't reflect the usage of the same
name for different purposes. When we deserialize a duplicate category,
compare it to an existing one and warn only when the new one is
different.

rdar://104582081

Differential Revision: https://reviews.llvm.org/D144149
2023-02-22 11:01:40 -08:00
Volodymyr Sapsai
6ba4afb4d6 [ODRHash] Hash ObjCInterfaceDecl and diagnose discovered mismatches.
When two modules contain interfaces with the same name, check the
definitions are equivalent and diagnose if they are not.

Differential Revision: https://reviews.llvm.org/D140073
2023-01-20 10:18:18 -06:00
Volodymyr Sapsai
160bc160b9 [ODRHash] Hash RecordDecl and diagnose discovered mismatches.
When two modules contain struct/union with the same name, check the
definitions are equivalent and diagnose if they are not. This is similar
to `CXXRecordDecl` where we already discover and diagnose mismatches.

rdar://problem/56764293

Differential Revision: https://reviews.llvm.org/D71734
2023-01-19 15:57:48 -06:00