aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Serialization/ASTWriterDecl.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-07-10[Sema] Fix lifetime extension for temporaries in range-based for loops in ↵Marco Vitale1-0/+2
C++23 (#145164) C++23 mandates that temporaries used in range-based for loops are lifetime-extended to cover the full loop. This patch adds a check for loop variables and compiler- generated `__range` bindings to apply the correct extension. Includes test cases based on examples from CWG900/P2644R1. Fixes https://github.com/llvm/llvm-project/issues/109793
2025-07-07[clang] Remove source range from CXXOperatorCallExpr (#147028)Haojian Wu1-1/+0
This patch stops storing a source range in `CXXOperatorCallExpr` and keeps only the begin location. This change allows us to retain the optimization #141058 when switching to 64-bit source locations. Performance results: https://llvm-compile-time-tracker.com/compare.php?from=0588e8188c647460b641b09467fe6b13a8d510d5&to=5958f83476a8b8ba97936f262396d3ff98fb1662&stat=instructions:u
2025-07-03[Modules] Record side effect info in EvaluatedStmt (#146468)Henrik G. Olsson1-1/+0
All deserialized VarDecl initializers are EvaluatedStmt, but not all EvaluatedStmt initializers are from a PCH. Calling `VarDecl::hasInitWithSideEffects` can trigger constant evaluation, but it's hard to know ahead of time whether that will trigger deserialization - even if the initializer is fully deserialized, it may contain a call to a constructor whose body is not deserialized. By caching the result of `VarDecl::hasInitWithSideEffects` and populating that cache during deserialization we can guarantee that calling it won't trigger deserialization regardless of the state of the initializer. This also reduces memory usage by removing the `InitSideEffectVars` set in `ASTReader`. rdar://154717930
2025-06-28[clang] Remove unused includes (NFC) (#146254)Kazu Hirata1-1/+0
These are identified by misc-include-cleaner. I've filtered out those that break builds. Also, I'm staying away from llvm-config.h, config.h, and Compiler.h, which likely cause platform- or compiler-specific build failures.
2025-06-27[ADT] Deprecate MutableArrayRef(std::nullopt) (#146113)Kazu Hirata1-1/+1
ArrayRef(std::nullopt) just got deprecated. This patch does the same to MutableArrayRef(std::nullopt). Since there are only a couple of uses, this patch does migration and deprecation at the same time.
2025-06-23Reland "[Modules] Record whether VarDecl initializers contain side effects" ↵Henrik G. Olsson1-6/+8
(#145447) This reverts commit 329ae86 and adds an early exit for EvaluateInPlace when the expression's type is null.
2025-06-23Revert "[Modules] Record whether VarDecl initializers contain side effects" ↵Jonas Devlieghere1-8/+6
(#145407) Reverts llvm/llvm-project#143739 because it triggers an assert: ``` Assertion failed: (!isNull() && "Cannot retrieve a NULL type pointer"), function getCommonPtr, file Type.h, line 952. ```
2025-06-23[Modules] Record whether VarDecl initializers contain side effects (#143739)Henrik G. Olsson1-6/+8
Calling `DeclMustBeEmitted` should not lead to more deserialization, as it may occur before previous deserialization has finished. When passed a `VarDecl` with an initializer however, `DeclMustBeEmitted` needs to know whether that initializer contains side effects. When the `VarDecl` is deserialized but the initializer is not, this triggers deserialization of the initializer. To avoid this we add a bit to the serialization format for `VarDecl`s, indicating whether its initializer contains side effects or not, so that the `ASTReader` can query this information directly without deserializing the initializer. rdar://153085264
2025-06-19[NFC] [Serialization] Some Code Cleanups for Name lookup table thingsChuanqi Xu1-13/+4
2025-06-12[C++20] [Modules] [Reduced BMI] Don't write specializations with local argsChuanqi Xu1-0/+45
Close https://github.com/llvm/llvm-project/issues/119947 As discussed in the above thread, we shouldn't write specializations with local args in reduced BMI. Since users can't find such specializations any way.
2025-06-08[Clang] Support constexpr asm at global scope. (#143268)Corentin Jabot1-1/+1
I previously failed to realize this feature existed... Fixes #137459 Fixes #143242
2025-06-03[clang][modules] Fix lambda and its enclosing function are not loaded from ↵Haojian Wu1-1/+1
same module. (#142467) This is a follow-up fix to https://github.com/llvm/llvm-project/pull/109167. Previously, we stored a mapping between the enclosing function and the lambda class declaration. When loading the enclosing function, we also loaded the corresponding lambda class declaration. However, loading the lambda class declaration does not guarantee that its call operator (a `CXXMethodDecl`) is loaded as well. As a result, if the lambda call operator is later loaded from a different module, we can end up with a `DeclRefExpr` that refers to a `VarDecl` from a different module — leading to inconsistencies. To fix this, we should ensure the lambda call operator itself is loaded. Fixes #141582
2025-04-28[clang][NFC] Convert DeclUpdateKind to scoped enumVlad Serebrennikov1-1/+1
2025-04-24[clang][p2719] Module deserialization does not restore allocator flags (#137102)Oliver Hunt1-0/+2
When serializing and deserializing a FunctionDecl we don't recover whether or not the decl was a type aware allocator or destroying delete, because in the final PR that information was placed in a side table in ASTContext. In principle it should be possible to re-do the semantic checks to determine what these flags should be when deserializing, but it seems like the most robust path is simply recording the flags directly in the serialized AST.
2025-04-03[clang] NFC: introduce UnsignedOrNone as a replacement for ↵Matheus Izvekov1-6/+3
std::optional<unsigned> (#134142) This introduces a new class 'UnsignedOrNone', which models a lite version of `std::optional<unsigned>`, but has the same size as 'unsigned'. This replaces most uses of `std::optional<unsigned>`, and similar schemes utilizing 'int' and '-1' as sentinel. Besides the smaller size advantage, this is simpler to serialize, as its internal representation is a single unsigned int as well.
2025-04-03[clang] support pack expansions for trailing requires clauses (#133190)Matheus Izvekov1-1/+4
2025-04-01[clang] Concepts: support pack expansions for type constraints (#132626)Matheus Izvekov1-0/+1
This reverts an earlier attempt (adb0d8ddceb143749c519d14b8b31b481071da77 and 50e5411e4247421fd606f0a206682fcdf0303ae3) to support these expansions, which was limited to type arguments and which subverted the purpose of SubstTemplateTypeParmType. This propagates the ArgumentPackSubstitutionIndex along with the AssociatedConstraint, so that the pack expansion works, without needing any new transforms or otherwise any changes to the template instantiation process. This keeps the tests from the reverted commits, and adds a few more showing the new solution also works for NTTPs. Fixes https://github.com/llvm/llvm-project/issues/131798
2025-04-01[clang][Modules] Fix the Size of `RecordDecl`'s `BitCodeAbbrevOp` (#133500)Qiongsi Wu1-1/+1
https://github.com/llvm/llvm-project/pull/102040/files#diff-125f472e690aa3d973bc42aa3c5d580226c5c47661551aca2889f960681aa64dR2477 added 1 bit to `RecordDecl`'s serialization format, but did not increment its abbreviation size. This can lead to rare cases where a record may overflow if the `RecordDecl`'s `getArgPassingRestrictions()` returns something bigger than 1 (see [here](https://github.com/llvm/llvm-project/blob/b3f01a6aa45b00240cec1c64286b85d7ba87e2af/clang/lib/Serialization/ASTWriterDecl.cpp#L688)). rdar://143763558
2025-03-28[PATCH] [clang][frontend] Fix serialization for CXXConstructorDecl (refs ↵Paul Schwabauer1-1/+1
llvm#132794) (#133077) When retrieving the ExplicitSpecifier from a CXXConstructorDecl, one of its canonical declarations is returned. To correctly write the declaration record the ExplicitSpecifier of the current declaration must be used. Failing to do so results in a crash during deserialization.
2025-03-13[C++20] [Modules] Merge codes to decide if we should generate declChuanqi Xu1-51/+68
There are two piece of codes in ASTWriterDecl to decide whether or not we should generate a function or a variable in current module unit (or PCH with object file extension, which is rarely used). One is in Visit*Decl and One is in `CanElideDef`. Since they are similar it should be better to merge them. This was meant to be a NFC patch. But it seems it helped me to find an existing bug.
2025-03-13[C++20] [Modules] Don't add decls from other units to undefinedButUsed setChuanqi Xu1-12/+0
It is still better to elide the declaration if possible. To overcome the false positive undefinedButUsed diagnostic, it seems better to not add declaration from other units to the set actually.
2025-03-06[OpenACC] implement AST/Sema for 'routine' construct with argumenterichkeane1-0/+12
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.
2025-03-05[C++20] [Modules] Avoid use-but-not-defined errorChuanqi Xu1-0/+12
See the attached test for example.
2025-03-03[OpenACC] Implement 'declare' construct AST/Semaerichkeane1-0/+12
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.
2025-02-19[clang][Sema] Fix initialization of `NonTypeTemplateParmDecl`... (#121768)Alejandro Álvarez Ayllón1-4/+4
...when there are invalid constraints. When attaching a `TypeConstraint`, in case of error, the trailing pointer that is supposed to point to the constraint is left uninitialized. Sometimes the uninitialized value will be a `nullptr`, but at other times it will not. If we traverse the AST (for instance, dumping it, or when writing the BMI), we may get a crash depending on the value that was left. The serialization may also contain a bogus value. In this commit, we always initialize the `PlaceholderTypeConstraint` with `nullptr`, to avoid accessing this uninitialized memory. This does not affect only modules, but it causes a segfault more consistently when they are involved. The test case was reduced from `mp-units`. --------- Co-authored-by: Erich Keane <ekeane@nvidia.com>
2025-02-05Reland: [clang] Track function template instantiation from definition (#125266)Matheus Izvekov1-1/+2
2025-02-05[clang] NFC: rename MatchedPackOnParmToNonPackOnArg to StrictPackMatch (#125418)Matheus Izvekov1-1/+1
This rename follows the proposed wording in P3310R5, which introduces the term 'strict pack match' to refer to the same thing.
2025-02-05Reland: [clang] fix P3310 overload resolution flag propagation (#125791)Matheus Izvekov1-0/+1
Class templates might be only instantiated when they are required to be complete, but checking the template args against the primary template is immediate. This result is cached so that later when the class is instantiated, checking against the primary template is not repeated. The 'MatchedPackOnParmToNonPackOnArg' flag is also produced upon checking against the primary template, so it needs to be cached in the specialziation as well. This fixes a bug which has not been in any release, so there are no release notes. Fixes #125290
2025-02-04Revert "[clang] fix P3310 overload resolution flag propagation" (#125710)David Spickett1-1/+0
Reverts llvm/llvm-project#125372 due to lldb builds failing: https://lab.llvm.org/buildbot/#/builders/59/builds/12223 We need to decide how to update LLDB's code.
2025-02-04[clang] fix P3310 overload resolution flag propagation (#125372)Matheus Izvekov1-0/+1
2025-01-30Revert "[clang] Track function template instantiation from definition (#112241)"Martin Storsjö1-2/+1
This reverts commit 07a0e2be86f33beb6d519a3d466b95c2257e93cb. This change broke compiling Qt; see https://github.com/llvm/llvm-project/pull/112241 for details.
2025-01-29[clang] Track function template instantiation from definition (#112241)Matheus Izvekov1-1/+2
This fixes instantiation of definition for friend function templates, when the declaration found and the one containing the definition have different template contexts. In these cases, the the function declaration corresponding to the definition is not available; it may not even be instantiated at all. So this patch adds a bit which tracks which function template declaration was instantiated from the member template. It's used to find which primary template serves as a context for the purpose of obtainining the template arguments needed to instantiate the definition. Fixes #55509 Relanding patch, with no changes, after it was reverted due to revert of commit this patch depended on.
2025-01-27[clang] Track source deduction guide for alias template deduction guides ↵antangelo1-0/+3
(#123875) For deduction guides generated from alias template CTAD, store the deduction guide they were originated from. The source kind is also maintained for future expansion in CTAD from inherited constructors. This tracking is required to determine whether an alias template already has a deduction guide corresponding to some deduction guide on the original template, in order to support deduction guides for the alias from deduction guides declared after the initial usage.
2025-01-23[C++20][Modules] Fix crash/compiler error due broken AST links (#123648)Dmitry Polukhin1-11/+26
Summary: This PR fixes bugreport https://github.com/llvm/llvm-project/issues/122493 The root problem is the same as before lambda function and DeclRefExpr references a variable that does not belong to the same module as the enclosing function body. Therefore iteration over the function body doesn’t visit the VarDecl. Before this change RelatedDeclsMap was created only for canonical decl but in reality it has to be done for the definition of the function that does not always match the canonical decl. Test Plan: check-clang
2025-01-22[SYCL] AST support for SYCL kernel entry point functions. (#122379)Tom Honermann1-0/+11
A SYCL kernel entry point function is a non-member function or a static member function declared with the `sycl_kernel_entry_point` attribute. Such functions define a pattern for an offload kernel entry point function to be generated to enable execution of a SYCL kernel on a device. A SYCL library implementation orchestrates the invocation of these functions with corresponding SYCL kernel arguments in response to calls to SYCL kernel invocation functions specified by the SYCL 2020 specification. The offload kernel entry point function (sometimes referred to as the SYCL kernel caller function) is generated from the SYCL kernel entry point function by a transformation of the function parameters followed by a transformation of the function body to replace references to the original parameters with references to the transformed ones. Exactly how parameters are transformed will be explained in a future change that implements non-trivial transformations. For now, it suffices to state that a given parameter of the SYCL kernel entry point function may be transformed to multiple parameters of the offload kernel entry point as needed to satisfy offload kernel argument passing requirements. Parameters that are decomposed in this way are reconstituted as local variables in the body of the generated offload kernel entry point function. For example, given the following SYCL kernel entry point function definition: ``` template<typename KernelNameType, typename KernelType> [[clang::sycl_kernel_entry_point(KernelNameType)]] void sycl_kernel_entry_point(KernelType kernel) { kernel(); } ``` and the following call: ``` struct Kernel { int dm1; int dm2; void operator()() const; }; Kernel k; sycl_kernel_entry_point<class kernel_name>(k); ``` the corresponding offload kernel entry point function that is generated might look as follows (assuming `Kernel` is a type that requires decomposition): ``` void offload_kernel_entry_point_for_kernel_name(int dm1, int dm2) { Kernel kernel{dm1, dm2}; kernel(); } ``` Other details of the generated offload kernel entry point function, such as its name and calling convention, are implementation details that need not be reflected in the AST and may differ across target devices. For that reason, only the transformation described above is represented in the AST; other details will be filled in during code generation. These transformations are represented using new AST nodes introduced with this change. `OutlinedFunctionDecl` holds a sequence of `ImplicitParamDecl` nodes and a sequence of statement nodes that correspond to the transformed parameters and function body. `SYCLKernelCallStmt` wraps the original function body and associates it with an `OutlinedFunctionDecl` instance. For the example above, the AST generated for the `sycl_kernel_entry_point<kernel_name>` specialization would look as follows: ``` FunctionDecl 'sycl_kernel_entry_point<kernel_name>(Kernel)' TemplateArgument type 'kernel_name' TemplateArgument type 'Kernel' ParmVarDecl kernel 'Kernel' SYCLKernelCallStmt CompoundStmt <original statements> OutlinedFunctionDecl ImplicitParamDecl 'dm1' 'int' ImplicitParamDecl 'dm2' 'int' CompoundStmt VarDecl 'kernel' 'Kernel' <initialization of 'kernel' with 'dm1' and 'dm2'> <transformed statements with redirected references of 'kernel'> ``` Any ODR-use of the SYCL kernel entry point function will (with future changes) suffice for the offload kernel entry point to be emitted. An actual call to the SYCL kernel entry point function will result in a call to the function. However, evaluation of a `SYCLKernelCallStmt` statement is a no-op, so such calls will have no effect other than to trigger emission of the offload kernel entry point. Additionally, as a related change inspired by code review feedback, these changes disallow use of the `sycl_kernel_entry_point` attribute with functions defined with a _function-try-block_. The SYCL 2020 specification prohibits the use of C++ exceptions in device functions. Even if exceptions were not prohibited, it is unclear what the semantics would be for an exception that escapes the SYCL kernel entry point function; the boundary between host and device code could be an implicit noexcept boundary that results in program termination if violated, or the exception could perhaps be propagated to host code via the SYCL library. Pending support for C++ exceptions in device code and clear semantics for handling them at the host-device boundary, this change makes use of the `sycl_kernel_entry_point` attribute with a function defined with a _function-try-block_ an error.
2025-01-17[C++20] [Modules] Makes sure internal declaration won't be found by other TU ↵Chuanqi Xu1-1/+11
(#123059) Close https://github.com/llvm/llvm-project/issues/61427 And this is also helpful to implement https://github.com/llvm/llvm-project/issues/112294 partially. The implementation strategy mimics https://github.com/llvm/llvm-project/pull/122887. This patch split the internal declarations from the general lookup table so that other TU can't find the internal declarations.
2025-01-17[C++20] [Modules] Support module level lookup (#122887) (#123281)Chuanqi Xu1-2/+11
Close https://github.com/llvm/llvm-project/issues/90154 This patch is also an optimization to the lookup process to utilize the information provided by `export` keyword. Previously, in the lookup process, the `export` keyword only takes part in the check part, it doesn't get involved in the lookup process. That said, previously, in a name lookup for 'name', we would load all of declarations with the name 'name' and check if these declarations are valid or not. It works well. But it is inefficient since it may load declarations that may not be wanted. Note that this patch actually did a trick in the lookup process instead of bring module information to DeclarationName or considering module information when deciding if two declarations are the same. So it may not be a surprise to me if there are missing cases. But it is not a regression. It should be already the case. Issue reports are welcomed. In this patch, I tried to split the big lookup table into a lookup table as before and a module local lookup table, which takes a combination of the ID of the DeclContext and hash value of the primary module name as the key. And refactored `DeclContext::lookup()` method to take the module information. So that a lookup in a DeclContext won't load declarations that are local to **other** modules. And also I think it is already beneficial to split the big lookup table since it may reduce the conflicts during lookups in the hash table. BTW, this patch introduced a **regression** for a reachability rule in C++20 but it was false-negative. See 'clang/test/CXX/module/module.interface/p7.cpp' for details. This patch is not expected to introduce any other regressions for non-c++20-modules users since the module local lookup table should be empty for them.
2025-01-16Revert "[C++20] [Modules] Support module level lookup (#122887)"Chuanqi Xu1-11/+2
This reverts commit 7201cae106260aeb3e9bbbb7d5291ff30f05076a.
2025-01-15[C++20] [Modules] Support module level lookup (#122887)Chuanqi Xu1-2/+11
Close https://github.com/llvm/llvm-project/issues/90154 This patch is also an optimization to the lookup process to utilize the information provided by `export` keyword. Previously, in the lookup process, the `export` keyword only takes part in the check part, it doesn't get involved in the lookup process. That said, previously, in a name lookup for 'name', we would load all of declarations with the name 'name' and check if these declarations are valid or not. It works well. But it is inefficient since it may load declarations that may not be wanted. Note that this patch actually did a trick in the lookup process instead of bring module information to DeclarationName or considering module information when deciding if two declarations are the same. So it may not be a surprise to me if there are missing cases. But it is not a regression. It should be already the case. Issue reports are welcomed. In this patch, I tried to split the big lookup table into a lookup table as before and a module local lookup table, which takes a combination of the ID of the DeclContext and hash value of the primary module name as the key. And refactored `DeclContext::lookup()` method to take the module information. So that a lookup in a DeclContext won't load declarations that are local to **other** modules. And also I think it is already beneficial to split the big lookup table since it may reduce the conflicts during lookups in the hash table. BTW, this patch introduced a **regression** for a reachability rule in C++20 but it was false-negative. See 'clang/test/CXX/module/module.interface/p7.cpp' for details. This patch is not expected to introduce any other regressions for non-c++20-modules users since the module local lookup table should be empty for them. --- On the API side, this patch unfortunately add a maybe-confusing argument `Module *NamedModule` to `ExternalASTSource::FindExternalVisibleDeclsByName()`. People may think we can get the information from the first argument `const DeclContext *DC`. But sadly there are declarations (e.g., namespace) can appear in multiple different modules as a single declaration. So we have to add additional information to indicate this.
2025-01-14Add Clang attribute to ensure that fields are initialized explicitly (#102040)higher-performance1-1/+3
This is a new Clang-specific attribute to ensure that field initializations are performed explicitly. For example, if we have ``` struct B { [[clang::explicit]] int f1; }; ``` then the diagnostic would trigger if we do `B b{};`: ``` field 'f1' is left uninitialized, but was marked as requiring initialization ``` This prevents callers from accidentally forgetting to initialize fields, particularly when new fields are added to the class.
2025-01-08[Clang] Don't form a type constraint if the concept is invalid (#122065)Younan Zhang1-2/+3
After 0dedd6fe1 and 03229e7c0, invalid concept declarations might lack expressions for evaluation and normalization. This could make it crash in certain scenarios, apart from the one of evaluation concepts showed in 03229e7c0, there's also an issue when checking specializations where the normalization also relies on a non-null expression. This patch prevents that by avoiding building up a type constraint in such situations, thereafter the template parameter wouldn't have a concept specialization of a null expression. With this patch, the assumption in ASTWriterDecl is no longer valid. Namely, HasConstraint and TypeConstraintInitialized must now represent different meanings for both source fidelity and semantic requirements. Fixes https://github.com/llvm/llvm-project/issues/115004 Fixes https://github.com/llvm/llvm-project/issues/121980
2024-12-16[C++20][Modules] Load function body from the module that gives canonical ↵Dmitry Polukhin1-1/+12
decl (#111992) Summary: Fix crash from reproducer provided in https://github.com/llvm/llvm-project/pull/109167#issuecomment-2405289565 Also fix issues with merged inline friend functions merged during deserialization. Test Plan: check-clang
2024-12-11[Serialization] Support loading template specializations lazily (#119333)Chuanqi Xu1-31/+79
Reland https://github.com/llvm/llvm-project/pull/83237 --- (Original comments) Currently all the specializations of a template (including instantiation, specialization and partial specializations) will be loaded at once if we want to instantiate another instance for the template, or find instantiation for the template, or just want to complete the redecl chain. This means basically we need to load every specializations for the template once the template declaration got loaded. This is bad since when we load a specialization, we need to load all of its template arguments. Then we have to deserialize a lot of unnecessary declarations. For example, ``` // M.cppm export module M; export template <class T> class A {}; export class ShouldNotBeLoaded {}; export class Temp { A<ShouldNotBeLoaded> AS; }; // use.cpp import M; A<int> a; ``` We have a specialization ` A<ShouldNotBeLoaded>` in `M.cppm` and we instantiate the template `A` in `use.cpp`. Then we will deserialize `ShouldNotBeLoaded` surprisingly when compiling `use.cpp`. And this patch tries to avoid that. Given that the templates are heavily used in C++, this is a pain point for the performance. This patch adds MultiOnDiskHashTable for specializations in the ASTReader. Then we will only deserialize the specializations with the same template arguments. We made that by using ODRHash for the template arguments as the key of the hash table. To review this patch, I think `ASTReaderDecl::AddLazySpecializations` may be a good entry point.
2024-12-09[Serialization] Migrate away from PointerUnion::{is,get} (NFC) (#118948)Kazu Hirata1-3/+3
Note that PointerUnion::{is,get} have been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> I'm not touching PointerUnion::dyn_cast for now because it's a bit complicated; we could blindly migrate it to dyn_cast_if_present, but we should probably use dyn_cast when the operand is known to be non-null.
2024-12-06Revert "[Serialization] Support load lazy specialization lazily"Haowei Wu1-79/+31
This reverts commit b5bd19211118c6d43bc525a4e3fb65d2c750d61e. It brokes multiple llvm bots including clang-x64-windows-msvc
2024-12-06[Serialization] Support load lazy specialization lazilyChuanqi Xu1-31/+79
Currently all the specializations of a template (including instantiation, specialization and partial specializations) will be loaded at once if we want to instantiate another instance for the template, or find instantiation for the template, or just want to complete the redecl chain. This means basically we need to load every specializations for the template once the template declaration got loaded. This is bad since when we load a specialization, we need to load all of its template arguments. Then we have to deserialize a lot of unnecessary declarations. For example, ``` // M.cppm export module M; export template <class T> class A {}; export class ShouldNotBeLoaded {}; export class Temp { A<ShouldNotBeLoaded> AS; }; // use.cpp import M; A<int> a; ``` We should a specialization ` A<ShouldNotBeLoaded>` in `M.cppm` and we instantiate the template `A` in `use.cpp`. Then we will deserialize `ShouldNotBeLoaded` surprisingly when compiling `use.cpp`. And this patch tries to avoid that. Given that the templates are heavily used in C++, this is a pain point for the performance. This patch adds MultiOnDiskHashTable for specializations in the ASTReader. Then we will only deserialize the specializations with the same template arguments. We made that by using ODRHash for the template arguments as the key of the hash table. To review this patch, I think `ASTReaderDecl::AddLazySpecializations` may be a good entry point. The patch was reviewed in https://github.com/llvm/llvm-project/pull/83237 but that PR is a stacked PR. But I feel the intention of the stacked PRs get lost during the review process. So I feel it is better to merge the commits into a single commit instead of merging them in the PR page. It is better for us to cherry-pick and revert.
2024-11-07[clang][serialization] Pass `ASTContext` explicitly (#115235)Jan Svoboda1-25/+30
This patch removes `ASTWriter::Context` and starts passing `ASTContext &` explicitly to functions that actually need it. This is a non-functional change with the end-goal of being able to write lightweight PCM files with no `ASTContext` at all.
2024-11-06Revert "Reapply "[Clang][Sema] Refactor collection of multi-level template ↵Krystian Stasiowski1-7/+10
argument lists (#106585, #111173)" (#111852)" (#115159) This reverts commit 2bb3d3a3f32ffaef3d9b6a27db7f1941f0cb1136.
2024-11-06[Clang] Correctly initialize placeholder fields from their initializers ↵cor3ntin1-1/+1
(#114196) We made the incorrect assumption that names of fields are unique when creating their default initializers. We fix that by keeping track of the instantiaation pattern for field decls that are placeholder vars, like we already do for unamed fields. Fixes #114069
2024-10-24[clang] Use {} instead of std::nullopt to initialize empty ArrayRef (#109399)Jay Foad1-1/+1
Follow up to #109133.