aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/DeclBase.cpp
AgeCommit message (Collapse)AuthorFilesLines
2024-04-25[NFC] [Serialization] Avoid using DeclID directly as much as possibleChuanqi Xu1-3/+3
This patch tries to remove all the direct use of DeclID except the real low level reading and writing. All the use of DeclID is converted to the use of LocalDeclID or GlobalDeclID. This is helpful to increase the readability and type safety.
2024-04-25Revert "[NFC] [Serialization] Avoid using DeclID directly as much as possible"Chuanqi Xu1-3/+3
This reverts commit 42070a5c092ed420bf92ebf38229c594885e94c7. I forgot to touch lldb.
2024-04-25[NFC] [Serialization] Avoid using DeclID directly as much as possibleChuanqi Xu1-3/+3
This patch tries to remove all the direct use of DeclID except the real low level reading and writing. All the use of DeclID is converted to the use of LocalDeclID or GlobalDeclID. This is helpful to increase the readability and type safety.
2024-04-25[NFC] Move DeclID from serialization/ASTBitCodes.h to AST/DeclID.h (#89873)Chuanqi Xu1-2/+2
Previously, the DeclID is defined in serialization/ASTBitCodes.h under clang::serialization namespace. However, actually the DeclID is not purely used in serialization part. The DeclID is already widely used in AST and all around the clang project via classes like `LazyPtrDecl` or calling `ExternalASTSource::getExernalDecl()`. All such uses are via the raw underlying type of `DeclID` as `uint32_t`. This is not pretty good. This patch moves the DeclID class family to a new header `AST/DeclID.h` so that the whole project can use the wrapped class `DeclID`, `GlobalDeclID` and `LocalDeclID` instead of the raw underlying type. This can improve the readability and the type safety.
2024-04-19[NFC] [Serialization] Use semantical type 'DeclID' for 'CreateDeserialized'Chuanqi Xu1-1/+1
Previously we use 'unsigned' as the type of ID in 'CreateDeserialized'. And the type of `DeclID` in serialization is 'uint32_t', so there is minor inconsistency. Also more importantly, if we want to extend the type of DeclID from uint32_t to uint64_t, we may be in trouble due to we forgot updating the a lot of 'CreateDeserialized'. So this patch tries to use semantical type 'DeclID' for '*Decl::CreateDeserialized' to make sure it is tightly consistent.
2024-04-16[StmtProfile] Don't profile the body of lambda expressionsChuanqi Xu1-5/+0
Close https://github.com/llvm/llvm-project/issues/87609 We tried to profile the body of the lambda expressions in https://reviews.llvm.org/D153957. But as the original comments show, it is indeed dangerous. After we tried to skip calculating the ODR hash values recently, we have fall into this trap twice. So in this patch, I choose to not profile the body of the lambda expression. The signature of the lambda is still profiled.
2024-04-14Revert "[Clang] Reduce the size of Decl and classes derived from it" (#88654)Nikolas Klauser1-22/+9
Reverts llvm/llvm-project#87361 On 32 bit platforms there is only a single bit available in the `DeclCtx`, resulting in an assertion failure.
2024-04-14[Clang] Reduce the size of Decl and classes derived from it (#87361)Nikolas Klauser1-9/+22
Class | Old size (in bytes) | New size (in bytes) ----------------------------------|---------------------|-------------------- Decl | 40 | 32 AccessSpecDecl | 40 | 40 BlockDecl | 128 | 120 CapturedDecl | 88 | 80 EmptyDecl | 40 | 32 ExportDecl | 80 | 72 ExternCContextDecl | 72 | 64 FileScopeAsmDecl | 56 | 48 FriendDecl | 64 | 56 FriendTemplateDecl | 64 | 64 ImplicitConceptSpecializationDecl | 40 | 40 ImportDecl | 56 | 48 LifetimeExtendedTemporaryDecl | 72 | 64 LinkageSpecDecl | 80 | 72 NamedDecl | 48 | 40 ObjCPropertyImplDecl | 96 | 88 PragmaCommentDecl | 40 | 40 PragmaDetectMismatchDecl | 48 | 40 RequiresExprBodyDecl | 72 | 64 StaticAssertDecl | 64 | 56 TopLevelStmtDecl | 88 | 80 TranslationUnitDecl | 104 | 96 BaseUsingDecl | 56 | 48 UsingDecl | 88 | 80 UsingEnumDecl | 72 | 64 HLSLBufferDecl | 96 | 88 LabelDecl | 80 | 72 NamespaceAliasDecl | 96 | 88 NamespaceDecl | 112 | 104 ObjCCompatibleAliasDecl | 56 | 48 ObjCContainerDecl | 88 | 80 ObjCMethodDecl | 136 | 128 ObjCPropertyDecl | 128 | 120 TemplateDecl | 64 | 56 BuiltinTemplateDecl | 72 | 64 TypeDecl | 64 | 56 UnresolvedUsingIfExistsDecl | 48 | 40 UsingDirectiveDecl | 88 | 80 UsingPackDecl | 64 | 56 UsingShadowDecl | 80 | 72 ValueDecl | 56 | 48 When parsing libc++'s `<string>` header the used memory is reduced from 42.8MB to 42.5MB.
2024-04-03[NFC] Make `DeclContext::noload_lookup()` accept transparent contextChuanqi Xu1-3/+3
Now the `DeclContext::noload_lookup()` asserts that 'this' is not a transparent context. However, this is not consistent with `DeclContext::lookup()`, which will lookup into its parent context if 'this' is a transparent context. This patch makes the behavior of `DeclContext::noload_lookup()` to be consistent with `DeclContext::lookup()`, to lookup into the parent context if 'this' is a transparent context.
2024-03-29[NFC] [Decl] Introduce Decl::isFromExplicitGlobalModuleChuanqi Xu1-2/+6
Introduce `Decl::isFromExplicitGlobalModule` to replace the `D->getOwningModule() && D->getOwningModule()->isExplicitGlobalModule()` pattern to save some typings.
2024-03-11[C++20] [Moduls] Avoid computing odr hash for functions from comparing ↵Chuanqi Xu1-0/+5
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-07[clang-repl] Names declared in if conditions and for-init statements are ↵Stefan Gränitz1-0/+1
local to the inner context (#84150) Make TopLevelStmtDecl a DeclContext so that variables defined in statements are attached to the TopLevelDeclContext. This fixes redefinition errors from variables declared in if conditions and for-init statements. These must be local to the inner context (C++ 3.3.2p4), but they had generated definitions on global scope instead. This PR makes the TopLevelStmtDecl looking more like a FunctionDecl and that's fine because the FunctionDecl is very close in terms of semantics. Additionally, ActOnForStmt() requires a CompoundScope when processing a NullStmt body. --------- Co-authored-by: Vassil Vassilev <v.g.vassilev@gmail.com>
2024-02-15[clang] Fix isInStdNamespace for Decl flagged extern c++ (#81776)Fred Tingaud1-1/+1
The MSVC STL implementation declares multiple classes using: ```cpp namespace std { extern "C++" class locale { ... }; } ``` `isInStdNamespace` uses the first DeclContext to check whether a Decl is inside the `std` namespace. Here, the first DeclContext of the `locale` Decl is a LinkageSpecDecl so the method will return false. We need to skip this LinkageSpecDecl to find the first DeclContext of type Namespace and actually check whether we're in the `std` namespace.
2024-01-16[Clang] Implement the 'counted_by' attribute (#76348)Bill Wendling1-1/+73
The 'counted_by' attribute is used on flexible array members. The argument for the attribute is the name of the field member holding the count of elements in the flexible array. This information is used to improve the results of the array bound sanitizer and the '__builtin_dynamic_object_size' builtin. The 'count' field member must be within the same non-anonymous, enclosing struct as the flexible array member. For example: ``` struct bar; struct foo { int count; struct inner { struct { int count; /* The 'count' referenced by 'counted_by' */ }; struct { /* ... */ struct bar *array[] __attribute__((counted_by(count))); }; } baz; }; ``` This example specifies that the flexible array member 'array' has the number of elements allocated for it in 'count': ``` struct bar; struct foo { size_t count; /* ... */ struct bar *array[] __attribute__((counted_by(count))); }; ``` This establishes a relationship between 'array' and 'count'; specifically that 'p->array' must have *at least* 'p->count' number of elements available. It's the user's responsibility to ensure that this relationship is maintained throughout changes to the structure. In the following, the allocated array erroneously has fewer elements than what's specified by 'p->count'. This would result in an out-of-bounds access not not being detected: ``` struct foo *p; void foo_alloc(size_t count) { p = malloc(MAX(sizeof(struct foo), offsetof(struct foo, array[0]) + count * sizeof(struct bar *))); p->count = count + 42; } ``` The next example updates 'p->count', breaking the relationship requirement that 'p->array' must have at least 'p->count' number of elements available: ``` void use_foo(int index, int val) { p->count += 42; p->array[index] = val; /* The sanitizer can't properly check this access */ } ``` In this example, an update to 'p->count' maintains the relationship requirement: ``` void use_foo(int index, int val) { if (p->count == 0) return; --p->count; p->array[index] = val; } ```
2024-01-15Revert "[Clang] Implement the 'counted_by' attribute (#76348)"Rashmi Mudduluru1-73/+1
This reverts commit 164f85db876e61cf4a3c34493ed11e8f5820f968.
2024-01-10[Clang] Implement the 'counted_by' attribute (#76348)Bill Wendling1-1/+73
The 'counted_by' attribute is used on flexible array members. The argument for the attribute is the name of the field member holding the count of elements in the flexible array. This information is used to improve the results of the array bound sanitizer and the '__builtin_dynamic_object_size' builtin. The 'count' field member must be within the same non-anonymous, enclosing struct as the flexible array member. For example: ``` struct bar; struct foo { int count; struct inner { struct { int count; /* The 'count' referenced by 'counted_by' */ }; struct { /* ... */ struct bar *array[] __attribute__((counted_by(count))); }; } baz; }; ``` This example specifies that the flexible array member 'array' has the number of elements allocated for it in 'count': ``` struct bar; struct foo { size_t count; /* ... */ struct bar *array[] __attribute__((counted_by(count))); }; ``` This establishes a relationship between 'array' and 'count'; specifically that 'p->array' must have *at least* 'p->count' number of elements available. It's the user's responsibility to ensure that this relationship is maintained throughout changes to the structure. In the following, the allocated array erroneously has fewer elements than what's specified by 'p->count'. This would result in an out-of-bounds access not not being detected: ``` struct foo *p; void foo_alloc(size_t count) { p = malloc(MAX(sizeof(struct foo), offsetof(struct foo, array[0]) + count * sizeof(struct bar *))); p->count = count + 42; } ``` The next example updates 'p->count', breaking the relationship requirement that 'p->array' must have at least 'p->count' number of elements available: ``` void use_foo(int index, int val) { p->count += 42; p->array[index] = val; /* The sanitizer can't properly check this access */ } ``` In this example, an update to 'p->count' maintains the relationship requirement: ``` void use_foo(int index, int val) { if (p->count == 0) return; --p->count; p->array[index] = val; } ```
2024-01-10Revert "[Clang] Implement the 'counted_by' attribute (#76348)"Nico Weber1-73/+1
This reverts commit fefdef808c230c79dca2eb504490ad0f17a765a5. Breaks check-clang, see https://github.com/llvm/llvm-project/pull/76348#issuecomment-1886029515 Also revert follow-on "[Clang] Update 'counted_by' documentation" This reverts commit 4a3fb9ce27dda17e97341f28005a28836c909cfc.
2024-01-10[Clang] Implement the 'counted_by' attribute (#76348)Bill Wendling1-1/+73
The 'counted_by' attribute is used on flexible array members. The argument for the attribute is the name of the field member holding the count of elements in the flexible array. This information is used to improve the results of the array bound sanitizer and the '__builtin_dynamic_object_size' builtin. The 'count' field member must be within the same non-anonymous, enclosing struct as the flexible array member. For example: ``` struct bar; struct foo { int count; struct inner { struct { int count; /* The 'count' referenced by 'counted_by' */ }; struct { /* ... */ struct bar *array[] __attribute__((counted_by(count))); }; } baz; }; ``` This example specifies that the flexible array member 'array' has the number of elements allocated for it in 'count': ``` struct bar; struct foo { size_t count; /* ... */ struct bar *array[] __attribute__((counted_by(count))); }; ``` This establishes a relationship between 'array' and 'count'; specifically that 'p->array' must have *at least* 'p->count' number of elements available. It's the user's responsibility to ensure that this relationship is maintained throughout changes to the structure. In the following, the allocated array erroneously has fewer elements than what's specified by 'p->count'. This would result in an out-of-bounds access not not being detected: ``` struct foo *p; void foo_alloc(size_t count) { p = malloc(MAX(sizeof(struct foo), offsetof(struct foo, array[0]) + count * sizeof(struct bar *))); p->count = count + 42; } ``` The next example updates 'p->count', breaking the relationship requirement that 'p->array' must have at least 'p->count' number of elements available: ``` void use_foo(int index, int val) { p->count += 42; p->array[index] = val; /* The sanitizer can't properly check this access */ } ``` In this example, an update to 'p->count' maintains the relationship requirement: ``` void use_foo(int index, int val) { if (p->count == 0) return; --p->count; p->array[index] = val; } ```
2024-01-04[clang] Optimize castToDeclContext for 2% improvement in build times (#76825)Pol M1-34/+16
Optimize castToDeclContext for 2% improvement in build times castToDeclContext is a heavily used function, and as such, it needs to be kept as slim as feasible to preserve as much performance as possible. To this end, it was observed that the function was generating suboptimal assembly code, and putting the most common execution path in the longest sequence of instructions. This patch addresses this by guiding the compiler towards generating a lookup table of offsets, which can be used to perform an addition on the pointer. This results in a 1-2% improvement on debug builds (and a negligible improvement on release). To achieve this, the switch was simplified to flatten the if statements in the default branch. In order to make the values of the switch more compact, encouraging LLVM to generate a look-up table instead of a jump table, the AST TableGen generator was modified so it can take order priority based on class inheritance. This combination allowed for a more optimal generation of the function. Of note, 2 other functions with an equivalent structure also needed to be modified. Fixes #76824
2023-12-18Revert counted_by attribute feature (#75857)Bill Wendling1-73/+1
There are many issues that popped up with the counted_by feature. The patch #73730 has grown too large and approval is blocking Linux testing. Includes reverts of: commit 769bc11f684d ("[Clang] Implement the 'counted_by' attribute (#68750)") commit bc09ec696209 ("[CodeGen] Revamp counted_by calculations (#70606)") commit 1a09cfb2f35d ("[Clang] counted_by attr can apply only to C99 flexible array members (#72347)") commit a76adfb992c6 ("[NFC][Clang] Refactor code to calculate flexible array member size (#72790)") commit d8447c78ab16 ("[Clang] Correct handling of negative and out-of-bounds indices (#71877)") Partial commit b31cd07de5b7 ("[Clang] Regenerate test checks (NFC)") Closes #73168 Closes #75173
2023-11-15[Clang] counted_by attr can apply only to C99 flexible array members (#72347)Bill Wendling1-3/+0
Ensure that we're dealing only with C99 flexible array members. I.e. ones with incomplete types: struct s { int count; char array[]; /* note: no size specified */ }; Authored-by: Bill Wendling <isanbard@gmail.com>
2023-11-09[C++20] [Modules] Allow export from language linkageChuanqi Xu1-1/+1
Close https://github.com/llvm/llvm-project/issues/71347 Previously I misread the concept of module purview. I thought if a declaration attached to a unnamed module, it can't be part of the module purview. But after the issue report, I recognized that module purview is more of a concept about locations instead of semantics. Concretely, the things in the language linkage after module declarations can be exported. This patch refactors `Module::isModulePurview()` and introduces some possible code cleanups.
2023-11-01[clang][NFC] Refactor `LinkageSpecDecl::LanguageIDs`Vlad Serebrennikov1-4/+4
This patch converts `LinkageSpecDecl::LanguageIDs` into scoped enum, and moves it to namespace scope, so that it can be forward-declared where required.
2023-10-14[Clang] Implement the 'counted_by' attribute (#68750)Bill Wendling1-1/+76
The 'counted_by' attribute is used on flexible array members. The argument for the attribute is the name of the field member in the same structure holding the count of elements in the flexible array. This information can be used to improve the results of the array bound sanitizer and the '__builtin_dynamic_object_size' builtin. This example specifies the that the flexible array member 'array' has the number of elements allocated for it in 'count': struct bar; struct foo { size_t count; /* ... */ struct bar *array[] __attribute__((counted_by(count))); }; This establishes a relationship between 'array' and 'count', specifically that 'p->array' must have *at least* 'p->count' number of elements available. It's the user's responsibility to ensure that this relationship is maintained through changes to the structure. In the following, the allocated array erroneously has fewer elements than what's specified by 'p->count'. This would result in an out-of-bounds access not not being detected: struct foo *p; void foo_alloc(size_t count) { p = malloc(MAX(sizeof(struct foo), offsetof(struct foo, array[0]) + count * sizeof(struct bar *))); p->count = count + 42; } The next example updates 'p->count', breaking the relationship requirement that 'p->array' must have at least 'p->count' number of elements available: struct foo *p; void foo_alloc(size_t count) { p = malloc(MAX(sizeof(struct foo), offsetof(struct foo, array[0]) + count * sizeof(struct bar *))); p->count = count + 42; } void use_foo(int index) { p->count += 42; p->array[index] = 0; /* The sanitizer cannot properly check this access */ } Reviewed By: nickdesaulniers, aaron.ballman Differential Revision: https://reviews.llvm.org/D148381
2023-10-09Revert "[Clang] Implement the 'counted_by' attribute" (#68603)alexfh1-75/+1
This reverts commit 9a954c693573281407f6ee3f4eb1b16cc545033d, which causes clang crashes when compiling with `-fsanitize=bounds`. See https://github.com/llvm/llvm-project/commit/9a954c693573281407f6ee3f4eb1b16cc545033d#commitcomment-129529574 for details.
2023-10-07[clang] remove ClassScopeFunctionSpecializationDecl (#66636)Krystian Stasiowski1-4/+1
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-04[Clang] Implement the 'counted_by' attributeBill Wendling1-1/+75
The 'counted_by' attribute is used on flexible array members. The argument for the attribute is the name of the field member in the same structure holding the count of elements in the flexible array. This information can be used to improve the results of the array bound sanitizer and the '__builtin_dynamic_object_size' builtin. This example specifies the that the flexible array member 'array' has the number of elements allocated for it in 'count': struct bar; struct foo { size_t count; /* ... */ struct bar *array[] __attribute__((counted_by(count))); }; This establishes a relationship between 'array' and 'count', specifically that 'p->array' must have *at least* 'p->count' number of elements available. It's the user's responsibility to ensure that this relationship is maintained through changes to the structure. In the following, the allocated array erroneously has fewer elements than what's specified by 'p->count'. This would result in an out-of-bounds access not not being detected: struct foo *p; void foo_alloc(size_t count) { p = malloc(MAX(sizeof(struct foo), offsetof(struct foo, array[0]) + count * sizeof(struct bar *))); p->count = count + 42; } The next example updates 'p->count', breaking the relationship requirement that 'p->array' must have at least 'p->count' number of elements available: struct foo *p; void foo_alloc(size_t count) { p = malloc(MAX(sizeof(struct foo), offsetof(struct foo, array[0]) + count * sizeof(struct bar *))); p->count = count + 42; } void use_foo(int index) { p->count += 42; p->array[index] = 0; /* The sanitizer cannot properly check this access */ } Reviewed By: nickdesaulniers, aaron.ballman Differential Revision: https://reviews.llvm.org/D148381
2023-05-23[NFC] [C++20] [Modules] Refactor Sema::isModuleUnitOfCurrentTU intoChuanqi Xu1-0/+23
Decl::isInAnotherModuleUnit Refactor `Sema::isModuleUnitOfCurrentTU` to `Decl::isInAnotherModuleUnit` to make code simpler a little bit. Note that although this patch introduces a FIXME, this is an existing issue and this patch just tries to describe it explicitly.
2023-05-16Revert "[NFC] [C++20] [Modules] Refactor Sema::isModuleUnitOfCurrentTU into"Chuanqi Xu1-23/+0
This reverts commit f109b1016801e2b0dbee278f3c517057c0b1d441 as required in https://github.com/llvm/llvm-project/commit/f109b1016801e2b0dbee278f3c517057c0b1d441#commitcomment-113477829.
2023-05-10[C++20] [Modules] Don't generate unused variables in other module unitsChuanqi Xu1-5/+7
even if its initializer has side effects Close https://github.com/llvm/llvm-project/issues/61892 The variables whose initializer has side effects will be emitted even if it is not used. But it shouldn't be true after we introduced modules. The variables in other modules shouldn't be emitted if it is not used even if its initializer has size effects. Also this patch rename `Decl::isInCurrentModuleUnit` to `Decl::isInAnotherModuleUnit` to make it closer to the semantics.
2023-05-10[NFC] [C++20] [Modules] Refactor Sema::isModuleUnitOfCurrentTU intoChuanqi Xu1-0/+21
Decl::isInCurrentModuleUnit Refactor `Sema::isModuleUnitOfCurrentTU` to `Decl::isInCurrentModuleUnit` to make code simpler a little bit. Note that although this patch introduces a FIXME, this is an existing issue and this patch just tries to describe it explicitly.
2023-03-17[clang][WebAssembly] Initial support for reference type funcref in clangPaulo Matos1-0/+12
This is the funcref counterpart to 890146b. We introduce a new attribute that marks a function pointer as a funcref. It also implements builtin __builtin_wasm_ref_null_func(), that returns a null funcref value. Differential Revision: https://reviews.llvm.org/D128440
2022-12-03[clang-repl] Support statements on global scope in incremental mode.Vassil Vassilev1-0/+1
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
2022-10-24"Reapply "GH58368: Correct concept checking in a lambda defined in concept""Erich Keane1-0/+1
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
2022-10-24Revert "Reapply "GH58368: Correct concept checking in a lambda defined in ↵Erich Keane1-1/+0
concept""" 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.
2022-10-24Reapply "GH58368: Correct concept checking in a lambda defined in concept""Erich Keane1-0/+1
This reverts commit 52930162870fee52d0d9c07c5d66e5dce32b08e8. Now with updating the ASTBitcodes to show that this AST is incompatible from the last.
2022-10-24Revert "GH58368: Correct concept checking in a lambda defined in concept"Erich Keane1-1/+0
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.
2022-10-24GH58368: Correct concept checking in a lambda defined in conceptErich Keane1-0/+1
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
2022-10-06[NFC] Replace use of !isTranslationUnit && !isNamespace with !isFileContextErich Keane1-2/+1
isFileContext is exactly equal to these two, so simplify the function.
2022-10-04[clang] Correct handling of lambdas in lambda default arguments in dependent ↵Tom Honermann1-4/+4
contexts. Previously, a lambda expression in a dependent context with a default argument containing an immediately invoked lambda expression would produce a closure class object that, if invoked such that the default argument was used, resulted in a compiler crash or one of the following assertion failures during code generation. The failures occurred regardless of whether the lambda expressions were dependent. clang/lib/CodeGen/CGCall.cpp: Assertion `(isGenericMethod || Ty->isVariablyModifiedType() || Ty.getNonReferenceType()->isObjCRetainableType() || getContext() .getCanonicalType(Ty.getNonReferenceType()) .getTypePtr() == getContext().getCanonicalType((*Arg)->getType()).getTypePtr()) && "type mismatch in call argument!"' failed. clang/lib/AST/Decl.cpp: Assertion `!Init->isValueDependent()' failed. Default arguments in declarations in local context are instantiated along with their enclosing function or variable template (since such declarations can't be explicitly specialized). Previously, such instantiations were performed at the same time that their associated parameters were instantiated. However, that approach fails in cases like the following in which the context for the inner lambda is the outer lambda, but construction of the outer lambda is dependent on the parameters of the inner lambda. This change resolves this dependency by delyaing instantiation of default arguments in local contexts until after construction of the enclosing context. template <typename T> auto f() { return [](T = []{ return T{}; }()) { return 0; }; } Refactoring included with this change results in the same code now being used to instantiate default arguments that appear in local context and those that are only instantiated when used at a call site; previously, such code was duplicated and out of sync. Fixes https://github.com/llvm/llvm-project/issues/49178 Reviewed By: erichkeane Differential Revision: https://reviews.llvm.org/D133500
2022-10-03[clang]: Add DeclContext::dumpAsDecl().Tom Honermann1-0/+9
This change enables a declaration to be conveniently displayed within a debugger when only a pointer to its DeclContext is available. For example, in gdb: (gdb) p Ctx $1 = (const clang::DeclContext *) 0x14c1a580 (gdb) p Ctx->dumpAsDecl() ClassTemplateSpecializationDecl 0x14c1a540 <t.cpp:1:1, line:7:1> line:2:8 struct ct `-TemplateArgument type 'int' `-BuiltinType 0x14bac420 'int' $2 = void In the event that the pointed to DeclContext is invalid (that it has an invalid DeclKind as a result of a dangling pointer, memory corruption, etc...) it is not possible to dump its associated declaration. In this case, the DeclContext will be reported as invalid. For example, in gdb: (gdb) p Ctx->dumpAsDecl() DeclContext 0x14c1a580 <unrecognized Decl kind 127> $3 = void
2022-10-03[Concepts] Fix Concepts on generic lambda in a VarTemplateSpecDeclErich Keane1-0/+5
As fallout of the Deferred Concept Instantiation patch (babdef27c5), we got a number of reports of a regression, where we asserted when instantiating a constraint on a generic lambda inside of a variable template. See: https://github.com/llvm/llvm-project/issues/57958 The problem was that getTemplateInstantiationArgs function only walked up declaration contexts, and missed that this is not necessarily the case with a lambda (which can ALSO be in a separate context). This patch refactors the getTemplateInstantiationArgs function in a way that is hopefully more readable, and fixes the problem with the concepts on a generic lambda. Differential Revision: https://reviews.llvm.org/D134874
2022-09-21[HLSL] Support cbuffer/tbuffer for hlsl.Xiang Li1-1/+11
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
2022-09-16[clang][ASTImporter] DeclContext::localUncachedLookup: Continue lookup into ↵Michael Buch1-1/+2
decl chain when regular lookup fails The uncached lookup is mainly used in the ASTImporter/LLDB code-path where we're not allowed to load from external storage. When importing a FieldDecl with a DeclContext that had no external visible storage (but came from a Clang module or PCH) the above call to `lookup(Name)` the regular `DeclContext::lookup` fails because: 1. `DeclContext::buildLookup` doesn't set `LookupPtr` for decls that came from a module 2. LLDB doesn't use the `SharedImporterState` In such a case we would never continue with the "slow" path of iterating through the decl chain on the DeclContext. In some cases this means that ASTNodeImporter::VisitFieldDecl ends up importing a decl into the DeclContext a second time. The patch removes the short-circuit in the case where we don't find any decls via the regular lookup. **Tests** * Un-skip the failing LLDB API tests Differential Revision: https://reviews.llvm.org/D133945
2022-08-12[AST] [Modules] Introduce Decl::getNonTransparentDeclContext to handle ↵Chuanqi Xu1-0/+5
exported friends Closing https://github.com/llvm/llvm-project/issues/56826. The root cause for pr56826 is: when we collect the template args for the friend, we need to judge if the friend lives in file context. However, if the friend lives in ExportDecl lexically, the judgement here is invalid. The solution is easy. We should judge the non transparent context and the ExportDecl is transparent context. So the solution should be good. A main concern may be the patch doesn't handle all the places of the same defect. I think it might not be bad since the patch itself should be innocent. Reviewed By: erichkeane Differential Revision: https://reviews.llvm.org/D131651
2022-07-22[NFC] give getParentFunctionOrMethod a 'Lexical' parameterErich Keane1-2/+3
Split up from the deferred concepts implementation, this function is useful for determining the containing function of a different function. However, in some cases it is valuable to instead get the lexical parent. This adds a parameter to the existing function to allow a 'Lexical' parameter to instead select the lexical parent.
2022-07-01Revert "Re-apply "Deferred Concept Instantiation Implementation"""Erich Keane1-3/+2
This reverts commit befa8cf087dbb8159a4d9dc8fa4d6748d6d5049a. Apparently this breaks some libc++ builds with an apparent assertion, so I'm looking into that .
2022-07-01Re-apply "Deferred Concept Instantiation Implementation""Erich Keane1-2/+3
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.
2022-06-30Revert "Deferred Concept Instantiation Implementation"Jonas Devlieghere1-3/+2
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.
2022-06-30Deferred Concept Instantiation ImplementationErich Keane1-2/+3
This is a continuation of D119544. Based on @rsmith 's feed back showing me https://eel.is/c++draft/temp#friend-9, We should properly handle friend functions now. Differential Revision: https://reviews.llvm.org/D126907