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.
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
This reverts commit af86957cbbffd3dfff3c6750ebddf118aebd0069.
Close https://github.com/llvm/llvm-project/issues/61733.
Previously I banned the eagerly loading for declarations from named
modules to speedup the process of reading modules. But I didn't think
about special decls like PragmaCommentDecl and PragmaDetectMismatchDecl.
So here is the issue https://github.com/llvm/llvm-project/issues/61733.
Note that the current behavior is still incorrect. Given:
```
// mod.cppm
module;
export module mod;
```
and
```
// user.cpp
import mod;
```
Now the IR of `user.cpp` will contain the metadata '!0 =
!{!"msvcprt.lib"}' incorrectly. The root cause of the problem is that
`EagerlyDeserializedDecls` is designed for headers and it didn't take
care for named modules. We need to redesign a new mechanism for named
modules.
Close https://github.com/llvm/llvm-project/issues/61064.
The root cause of the issue is that we will deserilize some declarations
eagerly when reading the BMI. However, many declarations in the BMI are
not necessary for the importer. So it wastes a lot of time.
Close https://github.com/llvm/llvm-project/issues/60693.
In this issue, we can find that the importer will try to generate the
template specialization again in the importer, which is not good and
wastes time. This patch tries to address the problem.
This re-commits part of c79635cce845. It is reverted since it contains
platform-inconsistent constant. Now the patch only contains constant
defined in DeclBase.h so it should be platform-independent. And this
should be still helpful.
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D141992
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
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
mention developers to remember to touch the serializer after them
modified the field of decls
It is easy for the developers to forget to touch the serializer after
they add new field to decls. Then if the existing tests fail to catch
such cases, it may be a bug report from users some day. And it is
time-consuming to solve such bugs.
To mitigate the problem, I add the static_asserts in the serializer. So
that the developers can understand they need to modify the serializer
after they saw the static assertion failure. Although this can't solve
all the problems, I feel the current status can be much better.
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D141992
Close https://github.com/llvm/llvm-project/issues/59719.
The root cause of the problem is that we forgot to serialize a new
introduced bit to FunctionDeclBits. Maybe we need to find some methods
to work for detecting this.
Closes https://github.com/llvm/llvm-project/issues/59780.
In this issue report, when we use full specialization of variable
templates in modules, we will meet the multiple definition errors.
The root cause of the problem is that when we see the full
specialization of the variable template in the importers, we will find
if it is already defined in the external sources and we failed to find
such definitions from external sources. So we generate the definition in
the current TU. We failed to find the definition in the external sources
because we restricted to not write it during writing. However, we don't
know why we restricted it and it doesn't make a lot sense to do such
restriction. Then no test fails after we remove such limitations. So
let's remove it now and add it back later if we found it is necessary
then we can add the corresponding test that time.
Note that the code is only applied to named modules and
PCHWithObjectFiles. So it won't affect the normal clang modules and
header units.
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.
This is part of an effort to migrate from llvm::Optional to
std::optional:
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
This patch teaches clang to parse statements on the global scope to allow:
```
./bin/clang-repl
clang-repl> int i = 12;
clang-repl> ++i;
clang-repl> extern "C" int printf(const char*,...);
clang-repl> printf("%d\n", i);
13
clang-repl> %quit
```
Generally, disambiguating between statements and declarations is a non-trivial
task for a C++ parser. The challenge is to allow both standard C++ to be
translated as if this patch does not exist and in the cases where the user typed
a statement to be executed as if it were in a function body.
Clang's Parser does pretty well in disambiguating between declarations and
expressions. We have added DisambiguatingWithExpression flag which allows us to
preserve the existing and optimized behavior where needed and implement the
extra rules for disambiguating. Only few cases require additional attention:
* Constructors/destructors -- Parser::isConstructorDeclarator was used in to
disambiguate between ctor-looking declarations and statements on the global
scope(eg. `Ns::f()`).
* The template keyword -- the template keyword can appear in both declarations
and statements. This patch considers the template keyword to be a declaration
starter which breaks a few cases in incremental mode which will be tackled
later.
* The inline (and similar) keyword -- looking at the first token in many cases
allows us to classify what is a declaration.
* Other language keywords and specifiers -- ObjC/ObjC++/OpenCL/OpenMP rely on
pragmas or special tokens which will be handled in subsequent patches.
The patch conceptually models a "top-level" statement into a TopLevelStmtDecl.
The TopLevelStmtDecl is lowered into a void function with no arguments.
We attach this function to the global initializer list to execute the statement
blocks in the correct order.
Differential revision: https://reviews.llvm.org/D127284
Adds support for NamespaceDecl to inform if its part of a nested namespace.
This flag only corresponds to the inner namespaces in a nested namespace declaration.
In this example:
namespace <X>::<Y>::<Z> {}
Only <Y> and <Z> will be classified as nested.
This flag isn't meant for assisting in building the AST, more for static analysis and refactorings.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D90568
This patch is a NFC prep for D136624, where we start adjusting offsets into `SourceManager`.
Depends on D137213.
Reviewed By: dexonsmith
Differential Revision: https://reviews.llvm.org/D137214
This reverts commit cecc9a92cfca71c1b6c2a35c5e302ab649496d11.
The problem ended up being how we were handling the lambda-context in
code generation: we were assuming any decl context here would be a
named-decl, but that isn't the case. Instead, we just replace it with
the concept's owning context.
Differential Revision: https://reviews.llvm.org/D136451
This reverts commit b876f6e2f28779211a829d7d4e841fe68885ae20.
Still getting build failures on PPC AIX that aren't obvious what is causing
them, so reverting while I try to figure this out.
This reverts commit b7c922607c5ba93db8b893d4ba461052af8317b5.
This seems to cause some problems with some modules related things,
which makes me think I should have updated the version-major in
ast-bit-codes? Going to revert to confirm this was a problem, then
change that and re-try a commit.
As that bug reports, the problem here is that the lambda's
'context-decl' was not set to the concept, and the lambda picked up
template arguments from the concept. SO, we failed to get the correct
template arguments in SemaTemplateInstantiate.
However, a Concept Specialization is NOT a decl, its an expression, so
we weren't able to put the concept in the decl tree like we needed.
This patch introduces a ConceptSpecializationDecl, which is the smallest
type possible to use for this purpose, containing only the template
arguments.
The net memory impliciation of this is turning a
trailing-objects into a pointer to a type with trailing-objects, so it
should be minor.
As future work, we may consider giving this type more responsibility, or
figuring out how to better merge duplicates, but as this is just a
template-argument collection at the moment, there isn't much value to
it.
Differential Revision: https://reviews.llvm.org/D136451
This is a change to how we represent type subsitution in the AST.
Instead of only storing the replaced type, we track the templated
entity we are substituting, plus an index.
We modify MLTAL to track the templated entity at each level.
Otherwise, it's much more expensive to go from the template parameter back
to the templated entity, and not possible to do in some cases, as when
we instantiate outer templates, parameters might still reference the
original entity.
This also allows us to very cheaply lookup the templated entity we saw in
the naming context and find the corresponding argument it was replaced
from, such as for implementing template specialization resugaring.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D131858
- store NestedNameSpecifier & Loc for the qualifiers
This information was entirely missing from the AST.
- expose the location information for qualifier/identifier/typedefs as typeloc
This allows many traversals/astmatchers etc to handle these generically along
with other references. The decl vs type split can help preserve typedef
sugar when https://github.com/llvm/llvm-project/issues/57659 is resolved.
- fix the SourceRange of UsingEnumDecl to include 'using'.
Fixes https://github.com/clangd/clangd/issues/1283
Differential Revision: https://reviews.llvm.org/D134303
Adds a fix to the diagnostic of replacing the `= default` to `= delete`
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D134549
This reverts commit 95d94a67755620c0a2871ac6f056ca8e9731d5e9.
This implements the deferred concepts instantiation, which should allow
the libstdc++ ranges to properly compile, and for the CRTP to work for
constrained functions.
Since the last attempt, this has fixed the issues from @wlei and
@mordante.
Differential Revision: https://reviews.llvm.org/D126907
This is first part for support cbuffer/tbuffer.
The format for cbuffer/tbuffer is
BufferType [Name] [: register(b#)] { VariableDeclaration [: packoffset(c#.xyzw)]; ... };
More details at https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-constants
New keyword 'cbuffer' and 'tbuffer' are added.
New AST node HLSLBufferDecl is added.
Build AST for simple cbuffer/tbuffer without attribute support.
The special thing is variables declared inside cbuffer is exposed into global scope.
So isTransparentContext should return true for HLSLBuffer.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D129883
In cases where a non-template function is defined inside a function
template, we don't have information about the original uninstantiated
version. In the case of concepts instantiation, we will need the
ability to get back to the original template. This patch splits a piece
of the deferred concepts instantaition patch off to accomplish the
storage of this, with minor runtime overhead, and zero additional
storage.
This reverts commit befa8cf087dbb8159a4d9dc8fa4d6748d6d5049a.
Apparently this breaks some libc++ builds with an apparent assertion,
so I'm looking into that .
This reverts commit d4d47e574ecae562ab32f8ac7fa3f4d424bb6574.
This fixes the lldb crash that was observed by ensuring that our
friend-'template contains reference to' TreeTransform properly handles a
TemplateDecl.
This reverts commit 2f207439521d62d9551b2884158368e8b34084e5 because it
triggers an assertion when building an LLDB test program:
Assertion failed: (InstantiatingSpecializations.empty() && "failed to
clean up an InstantiatingTemplate?"), function ~Sema, file
/Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/clang/lib/Sema/Sema.cpp,
line 458.
More details in https://reviews.llvm.org/D126907.
This reverts commit a425cac31e2e4cee8e14b7b9a99c8ba17c1ebb52.
There is another libc++ test, that this time causes us to hit an
assertion. Reverting, likely for a while this time.
This includes a fix for the libc++ issue I ran across with friend
declarations not properly being identified as overloads.
This reverts commit 45c07db31cc76802a1a2e41bed1ce9c1b8198181.
This reverts commit a97899108e495147985e5e9492e742d51d5cc97a.
The patch caused some problems with the libc++ `__range_adaptor_closure`
that I haven't been able to figure out the cause of, so I am reverting
while I figure out whether this is a solvable problem/issue with the
CFE, or libc++ depending on an older 'incorrect' behavior.
This reverts commit 0c31da48389754822dc3eecc4723160c295b9ab2.
I've solved the issue with the PointerUnion by making the
`FunctionTemplateDecl` pointer be a NamedDecl, that could be a
`FunctionDecl` or `FunctionTemplateDecl` depending. This is enforced
with an assert.
This reverts commit 4b6c2cd647e9e5a147954886338f97ffb6a1bcfb.
The patch caused numerous ARM 32 bit build failures, since we added a
5th item to the PointerUnion, and went over the 2-bits available in the
32 bit pointers.
As reported here: https://github.com/llvm/llvm-project/issues/44178
Concepts are not supposed to be instantiated until they are checked, so
this patch implements that and goes through significant amounts of work
to make sure we properly re-instantiate the concepts correctly.
Differential Revision: https://reviews.llvm.org/D119544
When exprs are written unabbreviated:
- these were encoded as 5 x vbr6 = 30 bits
- now they fit exactly into a one-chunk vbr = 6 bits
clangd --check=clangd/AST.cpp reports ~1% reduction in PCH size
(42826720->42474460)
Differential Revision: https://reviews.llvm.org/D124250
This builtin returns the address of a global instance of the
`std::source_location::__impl` type, which must be defined (with an
appropriate shape) before calling the builtin.
It will be used to implement std::source_location in libc++ in a
future change. The builtin is compatible with GCC's implementation,
and libstdc++'s usage. An intentional divergence is that GCC declares
the builtin's return type to be `const void*` (for
ease-of-implementation reasons), while Clang uses the actual type,
`const std::source_location::__impl*`.
In order to support this new functionality, I've also added a new
'UnnamedGlobalConstantDecl'. This artificial Decl is modeled after
MSGuidDecl, and is used to represent a generic concept of an lvalue
constant with global scope, deduplicated by its value. It's possible
that MSGuidDecl itself, or some of the other similar sorts of things
in Clang might be able to be refactored onto this more-generic
concept, but there's enough special-case weirdness in MSGuidDecl that
I gave up attempting to share code there, at least for now.
Finally, for compatibility with libstdc++'s <source_location> header,
I've added a second exception to the "cannot cast from void* to T* in
constant evaluation" rule. This seems a bit distasteful, but feels
like the best available option.
Reviewers: aaron.ballman, erichkeane
Differential Revision: https://reviews.llvm.org/D120159