[clang] [Clang][Sema] Revisit the fix for the lambda within a type alias template decl (PR #89934)
@@ -91,15 +91,60 @@ void bar() { namespace GH82104 { -template int Zero = 0; +template int Value = sizeof...(D); -template -using T14 = decltype([]() { return Zero; }()); +template +using T14 = decltype([](auto Param) { + return Value + V + (int)sizeof(Param); +}("hello")); template using T15 = T14; static_assert(__is_same(T15, int)); +// FIXME: This still crashes because we can't extract template arguments T and U +// outside of the instantiation context of T16. +#if 0 +template +using T16 = decltype([](auto Param) requires (sizeof(Param) != 1 && sizeof...(U) > 0) { + return Value + sizeof(Param); +}); +static_assert(T16()(42) == 2 + sizeof(42)); +#endif mizvekov wrote: This test case passes with my current WIP contextdecl patch. By the way, `Value` needs to be constexpr in order for that `static_assert` to work. https://github.com/llvm/llvm-project/pull/89934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Revisit the fix for the lambda within a type alias template decl (PR #89934)
https://github.com/mizvekov approved this pull request. I agree this is not the long term way forward, but it improves the current interim solution, so LGTM, minus nit. https://github.com/llvm/llvm-project/pull/89934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Revisit the fix for the lambda within a type alias template decl (PR #89934)
@@ -91,15 +91,84 @@ void bar() { namespace GH82104 { -template int Zero = 0; +template int Value = sizeof...(D); mizvekov wrote: ```suggestion template constexpr int Value = sizeof...(D); ``` https://github.com/llvm/llvm-project/pull/89934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Revisit the fix for the lambda within a type alias template decl (PR #89934)
https://github.com/mizvekov edited https://github.com/llvm/llvm-project/pull/89934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Use the correct lookup context when building overloaded 'operator->' in the current instantiation (PR #104458)
sdkrystian wrote: @cor3ntin What's the deadline? https://github.com/llvm/llvm-project/pull/104458 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Use upper case letters for bool conversion suffix (PR #104882)
carlosgalvezp wrote: @Da-Viper I believe there's some merge conflicts to fix before being able to merge :) https://github.com/llvm/llvm-project/pull/104882 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [ubsan] Display correct runtime messages for negative _BitInt (PR #96240)
@@ -103,6 +103,13 @@ class TypeDescriptor { /// representation is that of bitcasting the floating-point value to an /// integer type. TK_Float = 0x0001, +/// An _BitInt(N) type. Lowest bit is 1 for a signed value, 0 for an +/// unsigned value. Remaining bits are log_2(bit_width). The value earnol wrote: It's interesting problem. I have not changed the way _BitInts are encoded in the memory. My understanding is that might not be right approach to have too many meanings embedded into one field depending on the context. Please note we have only 15 bits here (lowest bit is a sign). Standard requires us to support N up to BITINT_MAXWIDTH which is quite high. The standard says: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2709.pdf _The macro BITINT_MAXWIDTH represents the maximum width N supported in the declaration of a bit-precise integer type (6.2.5) in the type specifier _BitInt(N). The value BITINT_MAXWIDTH shall expand to a value that is greater than or equal to the value of ULLONG_WIDTH._ It means it will not fit :( Also why we do need endianess? Cannot we always use endianess of the target platform? We always know it at the moment of code generation. https://github.com/llvm/llvm-project/pull/96240 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [ubsan] Display correct runtime messages for negative _BitInt (PR #96240)
https://github.com/earnol edited https://github.com/llvm/llvm-project/pull/96240 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang] C++20 Coroutines: Introduce Frontend Attribute [[clang::coro_await_elidable]] (PR #99282)
yuxuanchen1997 wrote: Hello! Requesting upstream to take a look again as I believe all feedback at the moment has been addressed. Please let me know if I still miss anything. https://github.com/llvm/llvm-project/pull/99282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [ubsan] Display correct runtime messages for negative _BitInt (PR #96240)
https://github.com/earnol edited https://github.com/llvm/llvm-project/pull/96240 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [ubsan] Display correct runtime messages for negative _BitInt (PR #96240)
https://github.com/earnol edited https://github.com/llvm/llvm-project/pull/96240 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [ubsan] Display correct runtime messages for negative _BitInt (PR #96240)
https://github.com/earnol edited https://github.com/llvm/llvm-project/pull/96240 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Concepts] Fix the constraint equivalence checking involving parameter packs (PR #102131)
@@ -972,8 +972,30 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction( // equivalence. LocalInstantiationScope ScopeForParameters(S); if (auto *FD = DeclInfo.getDecl()->getAsFunction()) -for (auto *PVD : FD->parameters()) - ScopeForParameters.InstantiatedLocal(PVD, PVD); +for (auto *PVD : FD->parameters()) { + if (!PVD->isParameterPack()) { +ScopeForParameters.InstantiatedLocal(PVD, PVD); +continue; + } + // This is hacky: we're mapping the parameter pack to a size-of-1 argument + // to avoid building SubstTemplateTypeParmPackTypes for + // PackExpansionTypes. The SubstTemplateTypeParmPackType node would + // otherwise reference the AssociatedDecl of the template arguments, which + // is, in this case, the template declaration. + // + // However, as we're also calculating the redeclarations of the template, + // the canonical declarations thereof are actually themselves at the + // moment. So if we didn't expand these packs, we would end up with an + // incorrect profile difference because we will be profiling the + // canonical types! + // + // FIXME: Improve the "no-transform" machinery in FindInstantiatedDecl so + // that we can eliminate the Scope in the cases where the declarations are + // not necessarily instantiated. It would also benefit the noexcept + // specifier comparison. mizvekov wrote: I think the solution in this patch improves on the existing one, even if interim, as the idea is to not have TransformDecl change these inserted declarations at all, which we failed to do for packs. So I like it more, as it just adds to existing workarounds, instead of adding a new one. https://github.com/llvm/llvm-project/pull/102131 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Report violations of the "returns_nonnull" attribute (PR #106048)
https://github.com/NagyDonat edited https://github.com/llvm/llvm-project/pull/106048 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Report violations of the "returns_nonnull" attribute (PR #106048)
https://github.com/NagyDonat commented: Thanks for the updates! https://github.com/llvm/llvm-project/pull/106048 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Report violations of the "returns_nonnull" attribute (PR #106048)
@@ -588,8 +588,8 @@ Warns when a null pointer is passed to a pointer which has a _Nonnull type. .. _nullability-NullReturnedFromNonnull: -nullability.NullReturnedFromNonnull (ObjC) -"" +nullability.NullReturnedFromNonnull +""" NagyDonat wrote: ```suggestion nullability.NullReturnedFromNonnull (C, C++, ObjC) "" ``` This is how other checkers are marked. (Do I understand correctly that `__attribute__((returns_nonnull))` is relevant both under C and C++?) https://github.com/llvm/llvm-project/pull/106048 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Report violations of the "returns_nonnull" attribute (PR #106048)
@@ -51,3 +54,15 @@ int *cannot_return_null() { __attribute__((returns_nonnull)) int *passthrough(int *p) { return p; // no-warning: we have no evidence that `p` is null, i.e., violating the contract } + +__attribute__((noreturn)) +void exit(int); NagyDonat wrote: Is this declaration used somehow? https://github.com/llvm/llvm-project/pull/106048 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Remove an incorrect assertion in ConstantFoldAttrs (PR #105789)
Sirraide wrote: > Hm, what comment are you referring to exactly? Ah, this one: https://github.com/llvm/llvm-project/blob/d88876e74f7882643546becc544a771a5e5e9787/clang/include/clang/Sema/Sema.h#L1838-L1842 The main thing I’m (if only a bit) worried about is that some code somewhere might be expecting a `ConstantExpr` to always be there if the thing isn’t dependent, so an ‘empty’ `ConstantExpr` might be necessary if that’s the case, but then again, if everything works then it’s probably fine? > We could of course also just reject void expressions I mean, I think accepting them is fine (some attributes might have a use for them maybe?); just wondering how to best represent them in the AST. https://github.com/llvm/llvm-project/pull/105789 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add tests for CWG issues about friend declaration matching (PR #106117)
https://github.com/Endilll created https://github.com/llvm/llvm-project/pull/106117 This patch covers CWG issues regarding declaration matching when `friend` declarations are involved: [CWG138](https://cplusplus.github.io/CWG/issues/138.html), [CWG386](https://cplusplus.github.io/CWG/issues/386.html), and [CWG1477](https://cplusplus.github.io/CWG/issues/1477.html). Atypical for our CWG tests, the ones in this patch are quite extensively commented in-line, explaining the mechanics. PR description focuses on high-level concerns and references. [CWG138](https://cplusplus.github.io/CWG/issues/138.html) "Friend declaration name lookup" --- [P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html): > [CWG138](https://cplusplus.github.io/CWG/issues/138.html) is resolved > according to [N1229](http://wg21.link/n1229), except that using-directives > that nominate nested namespaces are considered. I find it hard to pin down the scope of this issue, so I'm relying on three examples from the filing to define it. Because of that, it's also hard to pinpoint exact wording changes that resolve it. Relevant references are: [[dcl.meaning.general]/2](http://eel.is/c++draft/dcl.meaning#general-2), [[namespace.udecl]/10](https://eel.is/c++draft/namespace.udecl#10), [[dcl.type.elab]/3](https://eel.is/c++draft/dcl.type.elab#3), [[basic.lookup.elab]/1](https://eel.is/c++draft/basic.lookup.elab#1). [CWG386](https://cplusplus.github.io/CWG/issues/386.html) "Friend declaration of name brought in by _using-declaration_" --- [P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html): > [CWG386](https://cplusplus.github.io/CWG/issues/386.html), > [CWG1839](https://cplusplus.github.io/CWG/issues/1839.html), > [CWG1818](https://cplusplus.github.io/CWG/issues/1818.html), > [CWG2058](https://cplusplus.github.io/CWG/issues/2058.html), > [CWG1900](https://cplusplus.github.io/CWG/issues/1900.html), and Richard’s > observation in [“are non-type names ignored in a class-head-name or > enum-head-name?”](http://lists.isocpp.org/core/2017/01/1604.php) are resolved > by describing the limited lookup that occurs for a declarator-id, including > the changes in Richard’s [proposed resolution for > CWG1839](http://wiki.edg.com/pub/Wg21cologne2019/CoreWorkingGroup/cwg1839.html) > (which also resolves CWG1818 and what of CWG2058 was not resolved along with > CWG2059) and rejecting the example from > [CWG1477](https://cplusplus.github.io/CWG/issues/1477.html). Wording ([[dcl.meaning.general]/2](http://eel.is/c++draft/dcl.meaning#general-2)): > — If the > [id-expression](http://eel.is/c++draft/expr.prim.id.general#nt:id-expression) > E in the > [declarator-id](http://eel.is/c++draft/dcl.decl.general#nt:declarator-id) of > the [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) is a > [qualified-id](http://eel.is/c++draft/expr.prim.id.qual#nt:qualified-id) or a > [template-id](http://eel.is/c++draft/temp.names#nt:template-id): > — [...] > — The > [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) shall > correspond to one or more declarations found by the lookup; they shall all > have the same target scope, and the target scope of the > [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) is that > scope[.](http://eel.is/c++draft/dcl.meaning#general-2.2.2.sentence-1) This issue focuses on interaction of `friend` declarations with template-id and qualified-id with using-declarations. The short answer is that terminal name in such declarations undergo lookup, and using-declarations do what they usually do helping that lookup. Target scope of such friend declaration is the target scope of lookup result, so no conflicts arise with the using-declarations. [CWG1477](https://cplusplus.github.io/CWG/issues/1477.html) "Definition of a `friend` outside its namespace" --- [P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html): > [...] and rejecting the example from > [CWG1477](https://cplusplus.github.io/CWG/issues/1477.html). Wording ([[dcl.meaning.general]/3.4](http://eel.is/c++draft/dcl.meaning#general-3.4)): > Otherwise, the terminal name of the > [declarator-id](http://eel.is/c++draft/dcl.decl.general#nt:declarator-id) is > not looked up[.](http://eel.is/c++draft/dcl.meaning#general-3.4.sentence-1) If it is a qualified name, the [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) shall correspond to one or more declarations nominable in S; all the declarations shall have the same target scope and the target scope of the [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) is that scope[.](http://eel.is/c++draft/dcl.meaning#general-3.4.sentence-2) This issue focuses on befriending a function in one scope, then defining it from other scope using qualified-id. Contrary to what P1787R6 says in prose, this example is acc
[clang] [clang] Add tests for CWG issues about friend declaration matching (PR #106117)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Vlad Serebrennikov (Endilll) Changes This patch covers CWG issues regarding declaration matching when `friend` declarations are involved: [CWG138](https://cplusplus.github.io/CWG/issues/138.html), [CWG386](https://cplusplus.github.io/CWG/issues/386.html), and [CWG1477](https://cplusplus.github.io/CWG/issues/1477.html). Atypical for our CWG tests, the ones in this patch are quite extensively commented in-line, explaining the mechanics. PR description focuses on high-level concerns and references. [CWG138](https://cplusplus.github.io/CWG/issues/138.html) "Friend declaration name lookup" --- [P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html): > [CWG138](https://cplusplus.github.io/CWG/issues/138.html) is resolved according to [N1229](http://wg21.link/n1229), except that using-directives that nominate nested namespaces are considered. I find it hard to pin down the scope of this issue, so I'm relying on three examples from the filing to define it. Because of that, it's also hard to pinpoint exact wording changes that resolve it. Relevant references are: [[dcl.meaning.general]/2](http://eel.is/c++draft/dcl.meaning#general-2), [[namespace.udecl]/10](https://eel.is/c++draft/namespace.udecl#10), [[dcl.type.elab]/3](https://eel.is/c++draft/dcl.type.elab#3), [[basic.lookup.elab]/1](https://eel.is/c++draft/basic.lookup.elab#1). [CWG386](https://cplusplus.github.io/CWG/issues/386.html) "Friend declaration of name brought in by _using-declaration_" --- [P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html): > [CWG386](https://cplusplus.github.io/CWG/issues/386.html), [CWG1839](https://cplusplus.github.io/CWG/issues/1839.html), [CWG1818](https://cplusplus.github.io/CWG/issues/1818.html), [CWG2058](https://cplusplus.github.io/CWG/issues/2058.html), [CWG1900](https://cplusplus.github.io/CWG/issues/1900.html), and Richard’s observation in [“are non-type names ignored in a class-head-name or enum-head-name?”](http://lists.isocpp.org/core/2017/01/1604.php) are resolved by describing the limited lookup that occurs for a declarator-id, including the changes in Richard’s [proposed resolution for CWG1839](http://wiki.edg.com/pub/Wg21cologne2019/CoreWorkingGroup/cwg1839.html) (which also resolves CWG1818 and what of CWG2058 was not resolved along with CWG2059) and rejecting the example from [CWG1477](https://cplusplus.github.io/CWG/issues/1477.html). Wording ([[dcl.meaning.general]/2](http://eel.is/c++draft/dcl.meaning#general-2)): > — If the [id-expression](http://eel.is/c++draft/expr.prim.id.general#nt:id-expression) E in the [declarator-id](http://eel.is/c++draft/dcl.decl.general#nt:declarator-id) of the [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) is a [qualified-id](http://eel.is/c++draft/expr.prim.id.qual#nt:qualified-id) or a [template-id](http://eel.is/c++draft/temp.names#nt:template-id): > — [...] > — The [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) shall correspond to one or more declarations found by the lookup; they shall all have the same target scope, and the target scope of the [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) is that scope[.](http://eel.is/c++draft/dcl.meaning#general-2.2.2.sentence-1) This issue focuses on interaction of `friend` declarations with template-id and qualified-id with using-declarations. The short answer is that terminal name in such declarations undergo lookup, and using-declarations do what they usually do helping that lookup. Target scope of such friend declaration is the target scope of lookup result, so no conflicts arise with the using-declarations. [CWG1477](https://cplusplus.github.io/CWG/issues/1477.html) "Definition of a `friend` outside its namespace" --- [P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html): > [...] and rejecting the example from [CWG1477](https://cplusplus.github.io/CWG/issues/1477.html). Wording ([[dcl.meaning.general]/3.4](http://eel.is/c++draft/dcl.meaning#general-3.4)): > Otherwise, the terminal name of the [declarator-id](http://eel.is/c++draft/dcl.decl.general#nt:declarator-id) is not looked up[.](http://eel.is/c++draft/dcl.meaning#general-3.4.sentence-1) If it is a qualified name, the [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) shall correspond to one or more declarations nominable in S; all the declarations shall have the same target scope and the target scope of the [declarator](http://eel.is/c++draft/dcl.decl.general#nt:declarator) is that scope[.](http://eel.is/c++draft/dcl.meaning#general-3.4.sentence-2) This issue focuses on befriending a function in one scope, then defining it from other scope using qualified-id. Contrary to what P1787R6 says in prose, this example is accepted b
[clang] [clang][FMV] Pass the '+fmv' target-feature when FMV is enabled. (PR #87942)
Sirraide wrote: Makes sense; I was just going through some of the old prs w/ little activity to make sure we haven’t forgotten about them ;Þ https://github.com/llvm/llvm-project/pull/87942 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] Use CLANG_RESOURCE_DIR more consistently (PR #103388)
kimgr wrote: Thanks! https://github.com/llvm/llvm-project/pull/103388 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Headers][X86] Add a couple of tests for MMX/SSE intrinsics (PR #105852)
@@ -0,0 +1,105 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -target-feature +mmx \ +// RUN: -target-feature +sse2 -O0 -emit-llvm %s -o - | FileCheck %s + +// Test that mmx/sse2 shift intrinsics map to the expected builtins. + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include + +__m64 check__mm_slli_pi16(__m64 m) { + // CHECK-LABEL: @check__mm_slli_pi16 + // CHECK: @llvm.x86.sse2.pslli.w(<8 x i16> %{{.*}}, i32 {{.*}}) + return _mm_slli_pi16(m, 8); pogo59 wrote: You are correct, sorry for not checking! https://github.com/llvm/llvm-project/pull/105852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Headers][X86] Add a couple of tests for MMX/SSE intrinsics (PR #105852)
@@ -0,0 +1,387 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only \ pogo59 wrote: Okay. https://github.com/llvm/llvm-project/pull/105852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Headers][X86] Add a couple of tests for MMX/SSE intrinsics (PR #105852)
https://github.com/pogo59 updated https://github.com/llvm/llvm-project/pull/105852 >From fbdf1c4a2bc88e1872bb6b91265b142319b7ccc8 Mon Sep 17 00:00:00 2001 From: Paul Robinson Date: Fri, 23 Aug 2024 09:40:08 -0700 Subject: [PATCH 1/2] [Headers][X86] Add a couple of tests for MMX/SSE intrinsics Certain intrinsics map to builtins that require an immediate (literal) argument; make sure we report non-literal arguments. Also verify that shift intrinsics map to the expected builtins. These have been kicking around downstream for a while, and the recent removal of the MMX builtins caused me to notice them again. --- .../CodeGen/X86/mmx-sse2-shift-with-imm.c | 105 + clang/test/Headers/x86-intrinsics-imm.c | 387 ++ 2 files changed, 492 insertions(+) create mode 100644 clang/test/CodeGen/X86/mmx-sse2-shift-with-imm.c create mode 100644 clang/test/Headers/x86-intrinsics-imm.c diff --git a/clang/test/CodeGen/X86/mmx-sse2-shift-with-imm.c b/clang/test/CodeGen/X86/mmx-sse2-shift-with-imm.c new file mode 100644 index 00..3b386de50fa478 --- /dev/null +++ b/clang/test/CodeGen/X86/mmx-sse2-shift-with-imm.c @@ -0,0 +1,105 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -target-feature +mmx \ +// RUN: -target-feature +sse2 -O0 -emit-llvm %s -o - | FileCheck %s + +// Test that mmx/sse2 shift intrinsics map to the expected builtins. + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include + +__m64 check__mm_slli_pi16(__m64 m) { + // CHECK-LABEL: @check__mm_slli_pi16 + // CHECK: @llvm.x86.sse2.pslli.w(<8 x i16> %{{.*}}, i32 {{.*}}) + return _mm_slli_pi16(m, 8); +} + +__m64 check__mm_slli_pi32(__m64 m) { + // CHECK-LABEL: @check__mm_slli_pi32 + // CHECK: @llvm.x86.sse2.pslli.d(<4 x i32> %{{.*}}, i32 {{.*}}) + return _mm_slli_pi32(m, 8); +} + +__m64 check__mm_slli_si64(__m64 m) { + // CHECK-LABEL: @check__mm_slli_si64 + // CHECK: @llvm.x86.sse2.pslli.q(<2 x i64> %{{.*}}, i32 {{.*}}) + return _mm_slli_si64(m, 8); +} + +__m64 check__mm_srai_pi16(__m64 m) { + // CHECK-LABEL: @check__mm_srai_pi16 + // CHECK: @llvm.x86.sse2.psrai.w(<8 x i16> %{{.*}}, i32 {{.*}}) + return _mm_srai_pi16(m, 8); +} + +__m64 check__mm_srai_pi32(__m64 m) { + // CHECK-LABEL: @check__mm_srai_pi32 + // CHECK: @llvm.x86.sse2.psrai.d(<4 x i32> %{{.*}}, i32 {{.*}}) + return _mm_srai_pi32(m, 8); +} + +__m64 check__mm_srli_pi16(__m64 m) { + // CHECK-LABEL: @check__mm_srli_pi16 + // CHECK: @llvm.x86.sse2.psrli.w(<8 x i16> %{{.*}}, i32 {{.*}}) + return _mm_srli_pi16(m, 8); +} + +__m64 check__mm_srli_pi32(__m64 m) { + // CHECK-LABEL: @check__mm_srli_pi32 + // CHECK: @llvm.x86.sse2.psrli.d(<4 x i32> %{{.*}}, i32 {{.*}}) + return _mm_srli_pi32(m, 8); +} + +__m64 check__mm_srli_si64(__m64 m) { + // CHECK-LABEL: @check__mm_srli_si64 + // CHECK: @llvm.x86.sse2.psrli.q(<2 x i64> %{{.*}}, i32 {{.*}}) + return _mm_srli_si64(m, 8); +} + +__m128i check__mm_slli_epi16(__m128i a, const int b) { + // CHECK-LABEL: @check__mm_slli_epi16 + // CHECK: @llvm.x86.sse2.pslli.w(<8 x i16> %{{.*}}, i32 {{.*}}) + return _mm_slli_epi16(a, b); +} + +__m128i check__mm_slli_epi32(__m128i a, const int b) { + // CHECK-LABEL: @check__mm_slli_epi32 + // CHECK: @llvm.x86.sse2.pslli.d(<4 x i32> %{{.*}}, i32 {{.*}}) + return _mm_slli_epi32(a, b); +} + +__m128i check__mm_slli_epi64(__m128i a, const int b) { + // CHECK-LABEL: @check__mm_slli_epi64 + // CHECK: @llvm.x86.sse2.pslli.q(<2 x i64> %{{.*}}, i32 {{.*}}) + return _mm_slli_epi64(a, b); +} + +__m128i check__mm_srai_epi16(__m128i a, const int b) { + // CHECK-LABEL: @check__mm_srai_epi16 + // CHECK: @llvm.x86.sse2.psrai.w(<8 x i16> %{{.*}}, i32 {{.*}}) + return _mm_srai_epi16(a, b); +} + +__m128i check__mm_srai_epi32(__m128i a, const int b) { + // CHECK-LABEL: @check__mm_srai_epi32 + // CHECK: @llvm.x86.sse2.psrai.d(<4 x i32> %{{.*}}, i32 {{.*}}) + return _mm_srai_epi32(a, b); +} + +__m128i check__mm_srli_epi16(__m128i a, const int b) { + // CHECK-LABEL: @check__mm_srli_epi16 + // CHECK: @llvm.x86.sse2.psrli.w(<8 x i16> %{{.*}}, i32 {{.*}}) + return _mm_srli_epi16(a, b); +} + +__m128i check__mm_srli_epi32(__m128i a, const int b) { + // CHECK-LABEL: @check__mm_srli_epi32 + // CHECK: @llvm.x86.sse2.psrli.d(<4 x i32> %{{.*}}, i32 {{.*}}) + return _mm_srli_epi32(a, b); +} + +__m128i check__mm_srli_epi64(__m128i a, const int b) { + // CHECK-LABEL: @check__mm_srli_epi64 + // CHECK: @llvm.x86.sse2.psrli.q(<2 x i64> %{{.*}}, i32 {{.*}}) + return _mm_srli_epi64(a, b); +} diff --git a/clang/test/Headers/x86-intrinsics-imm.c b/clang/test/Headers/x86-intrinsics-imm.c new file mode 100644 index 00..58bcf187b6f44f --- /dev/null +++ b/clang/test/Headers/x86-intrinsics-imm.c @@ -0,0 +1,387 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only \ +// RUN: -target-feature +f16c -target-feature +avx -target-feature +sse4a \ +// RUN: -target-feature +aes -target-feature +xop -target-feature +avx2 \ +// RU
[clang] [Headers][X86] Add a couple of tests for MMX/SSE intrinsics (PR #105852)
https://github.com/pogo59 edited https://github.com/llvm/llvm-project/pull/105852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Headers][X86] Add a couple of tests for MMX/SSE intrinsics (PR #105852)
https://github.com/pogo59 edited https://github.com/llvm/llvm-project/pull/105852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Use upper case letters for bool conversion suffix (PR #104882)
https://github.com/Da-Viper updated https://github.com/llvm/llvm-project/pull/104882 >From 5ca62897b62306958a67e0534a96909ea5c704de Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Sun, 11 Aug 2024 21:39:35 +0100 Subject: [PATCH 01/14] [clang-tidy] use upper cace letters for bool conversion suffix When readability-implicit-bool-conversion-check and readability-uppercase-literal-suffix-check is enabled this will cause you to apply a fix twice from (!i) -> (i == 0u) to (i == 0U) twice instead will skip the middle one --- .../readability/ImplicitBoolConversionCheck.cpp | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp index aa115cd450c4f6..258cec80dd0bac 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -43,10 +43,10 @@ StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind, ASTContext &Context) { switch (CastExprKind) { case CK_IntegralToBoolean: -return Type->isUnsignedIntegerType() ? "0u" : "0"; +return Type->isUnsignedIntegerType() ? "0U" : "0"; case CK_FloatingToBoolean: -return Context.hasSameType(Type, Context.FloatTy) ? "0.0f" : "0.0"; +return Context.hasSameType(Type, Context.FloatTy) ? "0.0F" : "0.0"; case CK_PointerToBoolean: case CK_MemberPointerToBoolean: // Fall-through on purpose. @@ -202,13 +202,13 @@ StringRef getEquivalentForBoolLiteral(const CXXBoolLiteralExpr *BoolLiteral, if (DestType->isFloatingType()) { if (Context.hasSameType(DestType, Context.FloatTy)) { - return BoolLiteral->getValue() ? "1.0f" : "0.0f"; + return BoolLiteral->getValue() ? "1.0F" : "0.0F"; } return BoolLiteral->getValue() ? "1.0" : "0.0"; } if (DestType->isUnsignedIntegerType()) { -return BoolLiteral->getValue() ? "1u" : "0u"; +return BoolLiteral->getValue() ? "1U" : "0U"; } return BoolLiteral->getValue() ? "1" : "0"; } >From 83f38ddfbfd01586b9eaec4c80be6213189d4a73 Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Tue, 13 Aug 2024 00:49:41 +0100 Subject: [PATCH 02/14] Update test cases --- .../readability/implicit-bool-conversion.c| 14 +- .../readability/implicit-bool-conversion.cpp | 28 +-- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c index a8c69858f76b61..29869b100894f4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c @@ -94,7 +94,7 @@ void implicitConversionFromBoolLiterals() { functionTakingUnsignedLong(false); // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'bool' -> 'unsigned long' - // CHECK-FIXES: functionTakingUnsignedLong(0u); + // CHECK-FIXES: functionTakingUnsignedLong(0U); functionTakingSignedChar(true); // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion 'bool' -> 'signed char' @@ -102,7 +102,7 @@ void implicitConversionFromBoolLiterals() { functionTakingFloat(false); // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'float' - // CHECK-FIXES: functionTakingFloat(0.0f); + // CHECK-FIXES: functionTakingFloat(0.0F); functionTakingDouble(true); // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'double' @@ -159,12 +159,12 @@ void implicitConversionToBoolSimpleCases() { unsigned long unsignedLong = 10; functionTakingBool(unsignedLong); // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'unsigned long' -> 'bool' - // CHECK-FIXES: functionTakingBool(unsignedLong != 0u); + // CHECK-FIXES: functionTakingBool(unsignedLong != 0U); float floating = 0.0f; functionTakingBool(floating); // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool' - // CHECK-FIXES: functionTakingBool(floating != 0.0f); + // CHECK-FIXES: functionTakingBool(floating != 0.0F); double doubleFloating = 1.0f; functionTakingBool(doubleFloating); @@ -193,7 +193,7 @@ void implicitConversionToBoolInSingleExpressions() { bool boolComingFromFloat; boolComingFromFloat = floating; // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'float' -> 'bool' - // CHECK-FIXES: boolComingFromFloat = (floating != 0.0f); + // CHECK-FIXES: boolComingFromFloat = (floating != 0.0F); signed char character = 'a'; bool boolComingFromChar; @@ -231,7 +231,7 @@ bool implicitConversionToBoolInReturnValue() { float floating = 1.0f; return float
[clang] [clang][test] add TestLanguage.def to specify all tested language versions (PR #94243)
@@ -11,99 +11,84 @@ #include "llvm/Support/ErrorHandling.h" namespace clang { +std::vector getCOrLater(const int MinimumStd) { + std::vector Result{}; + +#define TESTLANGUAGE(lang, version, std_flag, version_index) +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + if (version >= MinimumStd) \ +Result.push_back(Lang_##lang##version); +#include "clang/Testing/TestLanguage.def" + + return Result; +} +std::vector getCXXOrLater(const int MinimumStd) { + std::vector Result{}; + +#define TESTLANGUAGE(lang, version, std_flag, version_index) +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ + if (version >= MinimumStd) \ +Result.push_back(Lang_##lang##version); +#include "clang/Testing/TestLanguage.def" + + return Result; +} std::vector getCommandLineArgsForTesting(TestLanguage Lang) { - std::vector Args; // Test with basic arguments. switch (Lang) { - case Lang_C89: -Args = {"-x", "c", "-std=c89"}; -break; - case Lang_C99: -Args = {"-x", "c", "-std=c99"}; -break; - case Lang_CXX03: -Args = {"-std=c++03", "-frtti"}; -break; - case Lang_CXX11: -Args = {"-std=c++11", "-frtti"}; -break; - case Lang_CXX14: -Args = {"-std=c++14", "-frtti"}; -break; - case Lang_CXX17: -Args = {"-std=c++17", "-frtti"}; -break; - case Lang_CXX20: -Args = {"-std=c++20", "-frtti"}; -break; - case Lang_CXX23: -Args = {"-std=c++23", "-frtti"}; -break; +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + case Lang_##lang##version: \ +return { "-x", "c", "-std=" #std_flag }; +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ + case Lang_##lang##version: \ +return { "-std=" #std_flag, "-frtti" }; +#include "clang/Testing/TestLanguage.def" + case Lang_OBJC: -Args = {"-x", "objective-c", "-frtti", "-fobjc-nonfragile-abi"}; -break; +return {"-x", "objective-c", "-frtti", "-fobjc-nonfragile-abi"}; case Lang_OBJCXX: -Args = {"-x", "objective-c++", "-frtti"}; -break; +return {"-x", "objective-c++", "-frtti"}; case Lang_OpenCL: llvm_unreachable("Not implemented yet!"); } - return Args; + llvm_unreachable("Not implemented yet!"); Sirraide wrote: ```suggestion llvm_unreachable("Invalid language"); ``` The message as-is suggests that there is more that needs to be done here, which isn’t really the case at the moment. https://github.com/llvm/llvm-project/pull/94243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][test] add TestLanguage.def to specify all tested language versions (PR #94243)
@@ -27,37 +27,117 @@ struct TestClangConfig { /// The argument of the `-target` command line flag. std::string Target; - bool isC() const { return Language == Lang_C89 || Language == Lang_C99; } - - bool isC99OrLater() const { return Language == Lang_C99; } - - bool isCXX() const { -return Language == Lang_CXX03 || Language == Lang_CXX11 || - Language == Lang_CXX14 || Language == Lang_CXX17 || - Language == Lang_CXX20 || Language == Lang_CXX23; + bool isC() const { +return false +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + || Language == Lang_##lang##version +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +; } - bool isCXX11OrLater() const { -return Language == Lang_CXX11 || Language == Lang_CXX14 || - Language == Lang_CXX17 || Language == Lang_CXX20 || - Language == Lang_CXX23; + bool isCOrLater(int MinimumStdVersion) const { +const auto MinimumStdVersionIndex = 0 +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + +(MinimumStdVersion == version ? version_index : 0) +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +; +switch (Language) { +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + case Lang_##lang##version: \ +return MinimumStdVersionIndex <= version_index; +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +default: + return false; +} } - bool isCXX14OrLater() const { -return Language == Lang_CXX14 || Language == Lang_CXX17 || - Language == Lang_CXX20 || Language == Lang_CXX23; + bool isC99OrLater() const { return isCOrLater(99); } + + bool isCOrEarlier(int MaximumStdVersion) const { +const auto MaximumStdVersionIndex = 0 +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + +(MaximumStdVersion == version ? version_index : 0) +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +; +switch (Language) { +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + case Lang_##lang##version: \ +return MaximumStdVersionIndex >= version_index; +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +default: + return false; +} } - bool isCXX17OrLater() const { -return Language == Lang_CXX17 || Language == Lang_CXX20 || - Language == Lang_CXX23; + bool isCXX() const { +return false +#define TESTLANGUAGE +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ + || Language == Lang_##lang##version +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +; } - bool isCXX20OrLater() const { -return Language == Lang_CXX20 || Language == Lang_CXX23; + bool isCXXOrLater(int MinimumStdVersion) const { +const auto MinimumStdVersionIndex = 0 +#define TESTLANGUAGE +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ + +(MinimumStdVersion == version ? version_index : 0) +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +; +switch (Language) { +#define TESTLANGUAGE +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ + case Lang_##lang##version: \ +return MinimumStdVersionIndex <= version_index; +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +default: + return false; +} } - bool isCXX23OrLater() const { return Language == Lang_CXX23; } + bool isCXX11OrLater() const { return isCXXOrLater(11); } + + bool isCXX14OrLater() const { return isCXXOrLater(14); } + + bool isCXX17OrLater() const { return isCXXOrLater(17); } + + bool isCXX20OrLater() const { return isCXXOrLater(20); } + + bool isCXX23OrLater() const { return isCXXOrLater(23); } + + bool isCXXOrEarlier(int MaximumStdVersion) const { +const auto MaximumStdVersionIndex = 0 Sirraide wrote: Just a random thought, but couldn’t we simply do this here? ```c++ return isCXX() && !isCXXOrLater(MaximumStdVersion + 1); ``` https://github.com/llvm/llvm-project/pull/94243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][test] add TestLanguage.def to specify all tested language versions (PR #94243)
@@ -0,0 +1,47 @@ + +//===-- TestLanguage.def - Language Versions for Testing *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +// The TESTLANGUAGE(-C/-CXX) macros have four parameters: +// the language, the standard version, the corresponding compile-flag, +// and an index of the language version for each language. +// The standard version is used to compare a standard version numerically, +// and the index is used to impose ordering for the language versions +// with respect to each language. + +#ifndef TESTLANGUAGE +#error "TESTLANGUAGE must be defined before including this file" +#endif + +#ifndef TESTLANGUAGE_C +#define TESTLANGUAGE_C TESTLANGUAGE +#endif + +#ifndef TESTLANGUAGE_CXX +#define TESTLANGUAGE_CXX TESTLANGUAGE +#endif Sirraide wrote: ```suggestion #ifndef TESTLANGUAGE # define TESTLANGUAGE(...) #endif #ifndef TESTLANGUAGE_C # define TESTLANGUAGE_C(...) TESTLANGUAGE(__VA_ARGS__) #endif #ifndef TESTLANGUAGE_CXX # define TESTLANGUAGE_CXX(...) TESTLANGUAGE(__VA_ARGS__) #endif ``` This would be more consistent with what we do elsewhere (e.g. `StmtNodes.inc`) and would make using this easier since you can now just define the one you care about instead of having to potentially define all three of them. https://github.com/llvm/llvm-project/pull/94243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][test] add TestLanguage.def to specify all tested language versions (PR #94243)
@@ -11,99 +11,84 @@ #include "llvm/Support/ErrorHandling.h" namespace clang { +std::vector getCOrLater(const int MinimumStd) { + std::vector Result{}; + +#define TESTLANGUAGE(lang, version, std_flag, version_index) +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + if (version >= MinimumStd) \ +Result.push_back(Lang_##lang##version); +#include "clang/Testing/TestLanguage.def" + + return Result; +} +std::vector getCXXOrLater(const int MinimumStd) { + std::vector Result{}; + +#define TESTLANGUAGE(lang, version, std_flag, version_index) +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ + if (version >= MinimumStd) \ +Result.push_back(Lang_##lang##version); +#include "clang/Testing/TestLanguage.def" + + return Result; +} std::vector getCommandLineArgsForTesting(TestLanguage Lang) { - std::vector Args; // Test with basic arguments. switch (Lang) { - case Lang_C89: -Args = {"-x", "c", "-std=c89"}; -break; - case Lang_C99: -Args = {"-x", "c", "-std=c99"}; -break; - case Lang_CXX03: -Args = {"-std=c++03", "-frtti"}; -break; - case Lang_CXX11: -Args = {"-std=c++11", "-frtti"}; -break; - case Lang_CXX14: -Args = {"-std=c++14", "-frtti"}; -break; - case Lang_CXX17: -Args = {"-std=c++17", "-frtti"}; -break; - case Lang_CXX20: -Args = {"-std=c++20", "-frtti"}; -break; - case Lang_CXX23: -Args = {"-std=c++23", "-frtti"}; -break; +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + case Lang_##lang##version: \ +return { "-x", "c", "-std=" #std_flag }; +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ + case Lang_##lang##version: \ +return { "-std=" #std_flag, "-frtti" }; +#include "clang/Testing/TestLanguage.def" + case Lang_OBJC: -Args = {"-x", "objective-c", "-frtti", "-fobjc-nonfragile-abi"}; -break; +return {"-x", "objective-c", "-frtti", "-fobjc-nonfragile-abi"}; case Lang_OBJCXX: -Args = {"-x", "objective-c++", "-frtti"}; -break; +return {"-x", "objective-c++", "-frtti"}; case Lang_OpenCL: llvm_unreachable("Not implemented yet!"); } - return Args; + llvm_unreachable("Not implemented yet!"); Sirraide wrote: (That applies to all of these `llvm_unreachable` calls, not just here) https://github.com/llvm/llvm-project/pull/94243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][test] add TestLanguage.def to specify all tested language versions (PR #94243)
@@ -27,37 +27,117 @@ struct TestClangConfig { /// The argument of the `-target` command line flag. std::string Target; - bool isC() const { return Language == Lang_C89 || Language == Lang_C99; } - - bool isC99OrLater() const { return Language == Lang_C99; } - - bool isCXX() const { -return Language == Lang_CXX03 || Language == Lang_CXX11 || - Language == Lang_CXX14 || Language == Lang_CXX17 || - Language == Lang_CXX20 || Language == Lang_CXX23; + bool isC() const { +return false +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + || Language == Lang_##lang##version +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" Sirraide wrote: ```suggestion return false #define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ || Language == Lang_##lang##version #include "clang/Testing/TestLanguage.def" ``` Just to illustrate what I meant in the previous comment (the same applies to other cases below as well) https://github.com/llvm/llvm-project/pull/94243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][test] add TestLanguage.def to specify all tested language versions (PR #94243)
@@ -1224,7 +1224,7 @@ TEST_P(ASTMatchersTest, CastExpression_MatchesImplicitCasts) { } TEST_P(ASTMatchersTest, CastExpr_DoesNotMatchNonCasts) { - if (GetParam().Language == Lang_C89 || GetParam().Language == Lang_C99) { + if (GetParam().isC()) { Sirraide wrote: Don’t we need `isCOrEarlier()` here? https://github.com/llvm/llvm-project/pull/94243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][test] add TestLanguage.def to specify all tested language versions (PR #94243)
@@ -27,37 +27,117 @@ struct TestClangConfig { /// The argument of the `-target` command line flag. std::string Target; - bool isC() const { return Language == Lang_C89 || Language == Lang_C99; } - - bool isC99OrLater() const { return Language == Lang_C99; } - - bool isCXX() const { -return Language == Lang_CXX03 || Language == Lang_CXX11 || - Language == Lang_CXX14 || Language == Lang_CXX17 || - Language == Lang_CXX20 || Language == Lang_CXX23; + bool isC() const { +return false +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + || Language == Lang_##lang##version +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +; } - bool isCXX11OrLater() const { -return Language == Lang_CXX11 || Language == Lang_CXX14 || - Language == Lang_CXX17 || Language == Lang_CXX20 || - Language == Lang_CXX23; + bool isCOrLater(int MinimumStdVersion) const { +const auto MinimumStdVersionIndex = 0 +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + +(MinimumStdVersion == version ? version_index : 0) +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +; +switch (Language) { +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + case Lang_##lang##version: \ +return MinimumStdVersionIndex <= version_index; +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +default: + return false; +} } - bool isCXX14OrLater() const { -return Language == Lang_CXX14 || Language == Lang_CXX17 || - Language == Lang_CXX20 || Language == Lang_CXX23; + bool isC99OrLater() const { return isCOrLater(99); } + + bool isCOrEarlier(int MaximumStdVersion) const { +const auto MaximumStdVersionIndex = 0 +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + +(MaximumStdVersion == version ? version_index : 0) +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +; +switch (Language) { +#define TESTLANGUAGE +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ + case Lang_##lang##version: \ +return MaximumStdVersionIndex >= version_index; +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +default: + return false; +} } - bool isCXX17OrLater() const { -return Language == Lang_CXX17 || Language == Lang_CXX20 || - Language == Lang_CXX23; + bool isCXX() const { +return false +#define TESTLANGUAGE +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ + || Language == Lang_##lang##version +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +; } - bool isCXX20OrLater() const { -return Language == Lang_CXX20 || Language == Lang_CXX23; + bool isCXXOrLater(int MinimumStdVersion) const { +const auto MinimumStdVersionIndex = 0 +#define TESTLANGUAGE +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ + +(MinimumStdVersion == version ? version_index : 0) +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +; +switch (Language) { +#define TESTLANGUAGE +#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ + case Lang_##lang##version: \ +return MinimumStdVersionIndex <= version_index; +#define TESTLANGUAGE_C(lang, version, std_flag, version_index) +#include "clang/Testing/TestLanguage.def" +default: + return false; +} } - bool isCXX23OrLater() const { return Language == Lang_CXX23; } + bool isCXX11OrLater() const { return isCXXOrLater(11); } + + bool isCXX14OrLater() const { return isCXXOrLater(14); } + + bool isCXX17OrLater() const { return isCXXOrLater(17); } + + bool isCXX20OrLater() const { return isCXXOrLater(20); } + + bool isCXX23OrLater() const { return isCXXOrLater(23); } + + bool isCXXOrEarlier(int MaximumStdVersion) const { +const auto MaximumStdVersionIndex = 0 Sirraide wrote: Ah, actually, no, this is passing in the version not the version index, so I’m not sure it would. https://github.com/llvm/llvm-project/pull/94243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][test] Rewrote test to work with lit internal shell syntax (PR #105902)
https://github.com/connieyzhu updated https://github.com/llvm/llvm-project/pull/105902 >From 5801e58f5e89fb90a3b18414e1cb959d027b4fee Mon Sep 17 00:00:00 2001 From: Connie Zhu Date: Fri, 23 Aug 2024 17:23:22 + Subject: [PATCH 1/2] [clang][test] Rewrote test to work with lit internal shell syntax This patch rewrites a test that uses command substitution $() and the stat command, which are not supported by lit's internal shell. Instead of using this syntax to perform the file size comparison done in this test, a Python script is used instead to perform the same operation. --- clang/test/Modules/compare-file-size.py | 22 ++ clang/test/Modules/reduced-bmi-size.cppm | 3 +-- clang/test/lit.cfg.py| 2 ++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 clang/test/Modules/compare-file-size.py diff --git a/clang/test/Modules/compare-file-size.py b/clang/test/Modules/compare-file-size.py new file mode 100644 index 00..ca3b16442353c7 --- /dev/null +++ b/clang/test/Modules/compare-file-size.py @@ -0,0 +1,22 @@ +import argparse +import os + +def get_file_size(file_path): +try: +return os.path.getsize(file_path) +except: +print(f"Unable to get file size of {file_path}") +return None + +def main(): +parser = argparse.ArgumentParser() + +parser.add_argument("file1", type=str) +parser.add_argument("file2", type=str) + +args = parser.parse_args() + +return get_file_size(args.file1) < get_file_size(args.file2) + +if __name__ == "__main__": +main() diff --git a/clang/test/Modules/reduced-bmi-size.cppm b/clang/test/Modules/reduced-bmi-size.cppm index 664f45f5c6a5a7..6d62573bc7aa39 100644 --- a/clang/test/Modules/reduced-bmi-size.cppm +++ b/clang/test/Modules/reduced-bmi-size.cppm @@ -10,7 +10,6 @@ // RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -o %t/a.pcm // RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %s -o %t/a.reduced.pcm // -// %s implies the current source file. So we can't use it directly. -// RUN: [ $(stat -c%\s "%t/a.pcm") -le $(stat -c%\s "%t/a.reduced.pcm") ] +// RUN: %{python} %S/compare-file-size.py %t/a.pcm %t/a.reduced.pcm export module a; diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py index 92a3361ce672e2..59330a6d51a611 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -74,6 +74,8 @@ config.substitutions.append(("%PATH%", config.environment["PATH"])) +config.substitutions.append(("%{python}", '"%s"' % (sys.executable))) + # For each occurrence of a clang tool name, replace it with the full path to # the build directory holding that tool. We explicitly specify the directories >From fa882e33eaab820219a704ba15a1cc10f2f93b07 Mon Sep 17 00:00:00 2001 From: Connie Zhu Date: Mon, 26 Aug 2024 18:47:31 + Subject: [PATCH 2/2] [clang][test] Modified python program to return error code when failing to get file size This patch removes the print statement that executes in the case of exceptions, opting to let the system return its own error code when failing to get the file size of a certain file. There are also some NFC changes: adding description for compare-file-size.py and changing the %{python} syntax to use the exisitng lit substitution %python. --- clang/test/Modules/compare-file-size.py | 24 clang/test/Modules/reduced-bmi-size.cppm | 2 +- clang/test/lit.cfg.py| 2 -- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/clang/test/Modules/compare-file-size.py b/clang/test/Modules/compare-file-size.py index ca3b16442353c7..30319726eff861 100644 --- a/clang/test/Modules/compare-file-size.py +++ b/clang/test/Modules/compare-file-size.py @@ -1,22 +1,14 @@ +# This program takes in two file path arguments and returns true if the +# file size of the first file is smaller than the file size of the second file + import argparse import os -def get_file_size(file_path): -try: -return os.path.getsize(file_path) -except: -print(f"Unable to get file size of {file_path}") -return None - -def main(): -parser = argparse.ArgumentParser() - -parser.add_argument("file1", type=str) -parser.add_argument("file2", type=str) +parser = argparse.ArgumentParser() -args = parser.parse_args() +parser.add_argument("file1", type=str) +parser.add_argument("file2", type=str) -return get_file_size(args.file1) < get_file_size(args.file2) +args = parser.parse_args() -if __name__ == "__main__": -main() +return os.path.getsize(args.file1) < os.path.getsize(args.file2) diff --git a/clang/test/Modules/reduced-bmi-size.cppm b/clang/test/Modules/reduced-bmi-size.cppm index 6d62573bc7aa39..6e3323266561e8 100644 --- a/clang/test/Modules/reduced-bmi-size.cppm +++ b/clang/test/Modules/reduced-bmi-size.cppm @@ -10,6 +10,6 @@ // RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -o %t/a.pcm // RUN: %clang_cc1 -std=c
[clang] [clang][test] Rewrote test to work with lit internal shell syntax (PR #105902)
@@ -0,0 +1,22 @@ +import argparse +import os + +def get_file_size(file_path): +try: +return os.path.getsize(file_path) +except: +print(f"Unable to get file size of {file_path}") +return None connieyzhu wrote: Now that I look at it again, I think having an unhandled exception would be better. I didn't realize that my implementation doesn't actually return an error code, but I would think having the error code would be better for debugging. https://github.com/llvm/llvm-project/pull/105902 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][test] Rewrote test to work with lit internal shell syntax (PR #105902)
https://github.com/connieyzhu updated https://github.com/llvm/llvm-project/pull/105902 >From 5801e58f5e89fb90a3b18414e1cb959d027b4fee Mon Sep 17 00:00:00 2001 From: Connie Zhu Date: Fri, 23 Aug 2024 17:23:22 + Subject: [PATCH 1/3] [clang][test] Rewrote test to work with lit internal shell syntax This patch rewrites a test that uses command substitution $() and the stat command, which are not supported by lit's internal shell. Instead of using this syntax to perform the file size comparison done in this test, a Python script is used instead to perform the same operation. --- clang/test/Modules/compare-file-size.py | 22 ++ clang/test/Modules/reduced-bmi-size.cppm | 3 +-- clang/test/lit.cfg.py| 2 ++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 clang/test/Modules/compare-file-size.py diff --git a/clang/test/Modules/compare-file-size.py b/clang/test/Modules/compare-file-size.py new file mode 100644 index 00..ca3b16442353c7 --- /dev/null +++ b/clang/test/Modules/compare-file-size.py @@ -0,0 +1,22 @@ +import argparse +import os + +def get_file_size(file_path): +try: +return os.path.getsize(file_path) +except: +print(f"Unable to get file size of {file_path}") +return None + +def main(): +parser = argparse.ArgumentParser() + +parser.add_argument("file1", type=str) +parser.add_argument("file2", type=str) + +args = parser.parse_args() + +return get_file_size(args.file1) < get_file_size(args.file2) + +if __name__ == "__main__": +main() diff --git a/clang/test/Modules/reduced-bmi-size.cppm b/clang/test/Modules/reduced-bmi-size.cppm index 664f45f5c6a5a7..6d62573bc7aa39 100644 --- a/clang/test/Modules/reduced-bmi-size.cppm +++ b/clang/test/Modules/reduced-bmi-size.cppm @@ -10,7 +10,6 @@ // RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -o %t/a.pcm // RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %s -o %t/a.reduced.pcm // -// %s implies the current source file. So we can't use it directly. -// RUN: [ $(stat -c%\s "%t/a.pcm") -le $(stat -c%\s "%t/a.reduced.pcm") ] +// RUN: %{python} %S/compare-file-size.py %t/a.pcm %t/a.reduced.pcm export module a; diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py index 92a3361ce672e2..59330a6d51a611 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -74,6 +74,8 @@ config.substitutions.append(("%PATH%", config.environment["PATH"])) +config.substitutions.append(("%{python}", '"%s"' % (sys.executable))) + # For each occurrence of a clang tool name, replace it with the full path to # the build directory holding that tool. We explicitly specify the directories >From fa882e33eaab820219a704ba15a1cc10f2f93b07 Mon Sep 17 00:00:00 2001 From: Connie Zhu Date: Mon, 26 Aug 2024 18:47:31 + Subject: [PATCH 2/3] [clang][test] Modified python program to return error code when failing to get file size This patch removes the print statement that executes in the case of exceptions, opting to let the system return its own error code when failing to get the file size of a certain file. There are also some NFC changes: adding description for compare-file-size.py and changing the %{python} syntax to use the exisitng lit substitution %python. --- clang/test/Modules/compare-file-size.py | 24 clang/test/Modules/reduced-bmi-size.cppm | 2 +- clang/test/lit.cfg.py| 2 -- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/clang/test/Modules/compare-file-size.py b/clang/test/Modules/compare-file-size.py index ca3b16442353c7..30319726eff861 100644 --- a/clang/test/Modules/compare-file-size.py +++ b/clang/test/Modules/compare-file-size.py @@ -1,22 +1,14 @@ +# This program takes in two file path arguments and returns true if the +# file size of the first file is smaller than the file size of the second file + import argparse import os -def get_file_size(file_path): -try: -return os.path.getsize(file_path) -except: -print(f"Unable to get file size of {file_path}") -return None - -def main(): -parser = argparse.ArgumentParser() - -parser.add_argument("file1", type=str) -parser.add_argument("file2", type=str) +parser = argparse.ArgumentParser() -args = parser.parse_args() +parser.add_argument("file1", type=str) +parser.add_argument("file2", type=str) -return get_file_size(args.file1) < get_file_size(args.file2) +args = parser.parse_args() -if __name__ == "__main__": -main() +return os.path.getsize(args.file1) < os.path.getsize(args.file2) diff --git a/clang/test/Modules/reduced-bmi-size.cppm b/clang/test/Modules/reduced-bmi-size.cppm index 6d62573bc7aa39..6e3323266561e8 100644 --- a/clang/test/Modules/reduced-bmi-size.cppm +++ b/clang/test/Modules/reduced-bmi-size.cppm @@ -10,6 +10,6 @@ // RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -o %t/a.pcm // RUN: %clang_cc1 -std=c
[clang] [clang][Sema] Fix particular operator overload crash (PR #105976)
@@ -7425,6 +7425,13 @@ void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, /*ExplicitArgs*/ nullptr, ObjectType, ObjectClassification, Args, CandidateSet, SuppressUserConversions, false, PO); + } else if (UsingDecl *UD = dyn_cast(Decl)) { +for (auto *Shadow : UD->shadows()) { + AddMethodCandidate(cast(Shadow->getTargetDecl()), + FoundDecl, ActingContext, ObjectType, + ObjectClassification, Args, CandidateSet, + SuppressUserConversions, false, std::nullopt, PO); mizvekov wrote: I think this needs better investigation why that commit introduced this change. One concerns is that the target decl could be a FunctionTemplate as well. https://github.com/llvm/llvm-project/pull/105976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][test] Rewrote test to work with lit internal shell syntax (PR #105902)
@@ -0,0 +1,22 @@ +import argparse ilovepi wrote: > Test files generally do not have license headers. Ah, right. I was thinking of them differently, since they're not par to of the test per se, but now that you spell it out, that makes sense. Thanks. https://github.com/llvm/llvm-project/pull/105902 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Fix particular operator overload crash (PR #105976)
@@ -7425,6 +7425,13 @@ void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, /*ExplicitArgs*/ nullptr, ObjectType, ObjectClassification, Args, CandidateSet, SuppressUserConversions, false, PO); + } else if (UsingDecl *UD = dyn_cast(Decl)) { +for (auto *Shadow : UD->shadows()) { + AddMethodCandidate(cast(Shadow->getTargetDecl()), + FoundDecl, ActingContext, ObjectType, + ObjectClassification, Args, CandidateSet, + SuppressUserConversions, false, std::nullopt, PO); nicovank wrote: Thanks, correct, template operators still cause a crash. I'll spend a bit of time digging into the original problematic commit. https://github.com/llvm/llvm-project/pull/105976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Correctly finds subexpressions of immediate invocations (PR #106055)
https://github.com/Sirraide approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/106055 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Implement '__builtin_hlsl_is_intangible' type trait (PR #104544)
https://github.com/pow2clk commented: Looks good overall. I have some areas where I still feel confused though https://github.com/llvm/llvm-project/pull/104544 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Implement '__builtin_hlsl_is_intangible' type trait (PR #104544)
@@ -1154,3 +1156,70 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { } return false; } + +static bool calculateIsIntangibleType(QualType Ty) { + Ty = Ty->getCanonicalTypeUnqualified(); + if (Ty->isBuiltinType()) +return Ty->isHLSLSpecificType(); + + llvm::SmallVector TypesToScan; + TypesToScan.push_back(Ty); + while (!TypesToScan.empty()) { +QualType T = TypesToScan.pop_back_val(); +assert(T == T->getCanonicalTypeUnqualified() && "expected sugar-free type"); +assert(!isa(T) && "Matrix types not yet supported in HLSL"); + +if (const auto *AT = dyn_cast(T)) { + QualType ElTy = AT->getElementType()->getCanonicalTypeUnqualified(); + if (ElTy->isBuiltinType()) +return ElTy->isHLSLSpecificType(); + TypesToScan.push_back(ElTy); + continue; +} + +if (const auto *VT = dyn_cast(T)) { + QualType ElTy = VT->getElementType()->getCanonicalTypeUnqualified(); + assert(ElTy->isBuiltinType() && "vectors can only contain builtin types"); + if (ElTy->isHLSLSpecificType()) pow2clk wrote: Expanding vectors to be able to contain intangible types seems pretty disruptive. Is there a proposal to do that? https://github.com/llvm/llvm-project/pull/104544 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Implement '__builtin_hlsl_is_intangible' type trait (PR #104544)
@@ -1154,3 +1156,70 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { } return false; } + +static bool calculateIsIntangibleType(QualType Ty) { + Ty = Ty->getCanonicalTypeUnqualified(); + if (Ty->isBuiltinType()) +return Ty->isHLSLSpecificType(); + + llvm::SmallVector TypesToScan; + TypesToScan.push_back(Ty); + while (!TypesToScan.empty()) { +QualType T = TypesToScan.pop_back_val(); +assert(T == T->getCanonicalTypeUnqualified() && "expected sugar-free type"); +assert(!isa(T) && "Matrix types not yet supported in HLSL"); pow2clk wrote: I don't think matrices will be intangible types nor can they contain them anyway? https://github.com/llvm/llvm-project/pull/104544 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Implement '__builtin_hlsl_is_intangible' type trait (PR #104544)
@@ -1154,3 +1156,70 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { } return false; } + +static bool calculateIsIntangibleType(QualType Ty) { + Ty = Ty->getCanonicalTypeUnqualified(); + if (Ty->isBuiltinType()) +return Ty->isHLSLSpecificType(); + + llvm::SmallVector TypesToScan; + TypesToScan.push_back(Ty); + while (!TypesToScan.empty()) { +QualType T = TypesToScan.pop_back_val(); +assert(T == T->getCanonicalTypeUnqualified() && "expected sugar-free type"); +assert(!isa(T) && "Matrix types not yet supported in HLSL"); + +if (const auto *AT = dyn_cast(T)) { + QualType ElTy = AT->getElementType()->getCanonicalTypeUnqualified(); + if (ElTy->isBuiltinType()) +return ElTy->isHLSLSpecificType(); pow2clk wrote: Currently `isHLSLSPecificType` seems to be synonymous with `isHLSLIntangibleType`, but the name suggests it might extend beyond intangible types in the future. If it is meant to only check for intangible types, perhaps it should be renamed. https://github.com/llvm/llvm-project/pull/104544 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Implement '__builtin_hlsl_is_intangible' type trait (PR #104544)
https://github.com/pow2clk edited https://github.com/llvm/llvm-project/pull/104544 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Implement '__builtin_hlsl_is_intangible' type trait (PR #104544)
@@ -1154,3 +1156,70 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { } return false; } + +static bool calculateIsIntangibleType(QualType Ty) { + Ty = Ty->getCanonicalTypeUnqualified(); + if (Ty->isBuiltinType()) +return Ty->isHLSLSpecificType(); + + llvm::SmallVector TypesToScan; + TypesToScan.push_back(Ty); + while (!TypesToScan.empty()) { +QualType T = TypesToScan.pop_back_val(); +assert(T == T->getCanonicalTypeUnqualified() && "expected sugar-free type"); pow2clk wrote: Is a sugar-free type an artificial sweetener type? 😆 https://github.com/llvm/llvm-project/pull/104544 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Implement '__builtin_hlsl_is_intangible' type trait (PR #104544)
@@ -5683,6 +5685,14 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, return true; return false; } + case UTT_IsIntangibleType: +if (!T->isVoidType() && !T->isIncompleteArrayType()) + if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T, + diag::err_incomplete_type)) +return false; +DiagnoseVLAInCXXTypeTrait(Self, TInfo, + tok::kw___builtin_hlsl_is_intangible); +return Self.HLSL().IsIntangibleType(T); pow2clk wrote: I'm afraid that this and the change above are confusing me. Can you explain a bit what purpose these functions serve? I'm not even sure what returning true really means. This is why I favor negatable verbs at the start of functions returning bool like `has`* or `is`* . I don't know what to expect from `Check`* or `Evaluate`* 😒 https://github.com/llvm/llvm-project/pull/104544 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Implement '__builtin_hlsl_is_intangible' type trait (PR #104544)
@@ -1154,3 +1156,70 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { } return false; } + +static bool calculateIsIntangibleType(QualType Ty) { + Ty = Ty->getCanonicalTypeUnqualified(); + if (Ty->isBuiltinType()) +return Ty->isHLSLSpecificType(); + + llvm::SmallVector TypesToScan; + TypesToScan.push_back(Ty); + while (!TypesToScan.empty()) { +QualType T = TypesToScan.pop_back_val(); +assert(T == T->getCanonicalTypeUnqualified() && "expected sugar-free type"); +assert(!isa(T) && "Matrix types not yet supported in HLSL"); + +if (const auto *AT = dyn_cast(T)) { + QualType ElTy = AT->getElementType()->getCanonicalTypeUnqualified(); + if (ElTy->isBuiltinType()) +return ElTy->isHLSLSpecificType(); + TypesToScan.push_back(ElTy); + continue; +} + +if (const auto *VT = dyn_cast(T)) { + QualType ElTy = VT->getElementType()->getCanonicalTypeUnqualified(); + assert(ElTy->isBuiltinType() && "vectors can only contain builtin types"); + if (ElTy->isHLSLSpecificType()) +return true; + continue; +} + +if (const auto *RT = dyn_cast(T)) { + const RecordDecl *RD = RT->getDecl(); + for (const auto *FD : RD->fields()) { +QualType FieldTy = FD->getType()->getCanonicalTypeUnqualified(); +if (FieldTy->isBuiltinType()) { + if (FieldTy->isHLSLSpecificType()) pow2clk wrote: It's a very minor nit, but given the repetition of this check, we could just test this at the top of the loop after popping it off the work queue instead of testing it before insertion. https://github.com/llvm/llvm-project/pull/104544 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Implement '__builtin_hlsl_is_intangible' type trait (PR #104544)
@@ -1154,3 +1156,70 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { } return false; } + +static bool calculateIsIntangibleType(QualType Ty) { + Ty = Ty->getCanonicalTypeUnqualified(); + if (Ty->isBuiltinType()) +return Ty->isHLSLSpecificType(); + + llvm::SmallVector TypesToScan; + TypesToScan.push_back(Ty); + while (!TypesToScan.empty()) { +QualType T = TypesToScan.pop_back_val(); +assert(T == T->getCanonicalTypeUnqualified() && "expected sugar-free type"); +assert(!isa(T) && "Matrix types not yet supported in HLSL"); + +if (const auto *AT = dyn_cast(T)) { + QualType ElTy = AT->getElementType()->getCanonicalTypeUnqualified(); + if (ElTy->isBuiltinType()) +return ElTy->isHLSLSpecificType(); pow2clk wrote: This duplicates the [comment ](https://github.com/llvm/llvm-project/pull/104544#discussion_r1731610819) Justin made https://github.com/llvm/llvm-project/pull/104544 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Correctly finds subexpressions of immediate invocations (PR #106055)
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/106055 >From 33ff4f03257c9af03192b92cbd425b731e0f238c Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Mon, 26 Aug 2024 12:28:07 +0200 Subject: [PATCH 1/2] [Clang] Correctly finds subexpressions of immediate invocations We were not correctly ignoring implicit casts. Fixes #105558 --- clang/docs/ReleaseNotes.rst| 1 + clang/lib/Sema/SemaExpr.cpp| 17 ++--- clang/test/AST/ByteCode/new-delete.cpp | 16 +--- clang/test/SemaCXX/cxx2a-consteval.cpp | 23 +++ 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8f98167dff31ef..7d3eebb604a244 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -292,6 +292,7 @@ Bug Fixes to C++ Support - Correctly check constraints of explicit instantiations of member functions. (#GH46029) - Fixed an assertion failure about a constraint of a friend function template references to a value with greater template depth than the friend function template. (#GH98258) +- Correctly handle subexpressions of an immediate invocation in the presence of implicit casts. (#GH105558) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c67183df335dd5..1dd0f4bd717c3f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -17464,11 +17464,22 @@ static void RemoveNestedImmediateInvocation( ExprResult TransformInitializer(Expr *Init, bool NotCopyInit) { if (!Init) return Init; + + // We cannot use IgnoreImpCasts because we need to preserve + // full expressions. + while (true) { +if (auto *ICE = dyn_cast(Init)) + Init = ICE->getSubExpr(); +else if (auto *ICE = dyn_cast(Init)) + Init = ICE->getSubExpr(); +else + break; + } /// ConstantExpr are the first layer of implicit node to be removed so if /// Init isn't a ConstantExpr, no ConstantExpr will be skipped. - if (auto *CE = dyn_cast(Init)) -if (CE->isImmediateInvocation()) - RemoveImmediateInvocation(CE); + if (auto *CE = dyn_cast(Init); + CE && CE->isImmediateInvocation()) +RemoveImmediateInvocation(CE); return Base::TransformInitializer(Init, NotCopyInit); } ExprResult TransformDeclRefExpr(DeclRefExpr *E) { diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp index 6bb30bc19f110c..b90897d66795f3 100644 --- a/clang/test/AST/ByteCode/new-delete.cpp +++ b/clang/test/AST/ByteCode/new-delete.cpp @@ -404,7 +404,7 @@ constexpr typename std::remove_reference::type&& move(T &&t) noexcept { namespace cxx2a { struct A { - int* p = new int(42); // both-note 7{{heap allocation performed here}} + int* p = new int(42); // both-note 3{{heap allocation performed here}} consteval int ret_i() const { return p ? *p : 0; } consteval A ret_a() const { return A{}; } constexpr ~A() { delete p; } @@ -433,9 +433,7 @@ void test() { { A k = to_lvalue_ref(A()); } // both-error {{'cxx2a::to_lvalue_ref' is not a constant expression}} \ // both-note {{reference to temporary is not a constant expression}} \ // both-note {{temporary created here}} - { A k = to_lvalue_ref(A().ret_a()); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \ -// both-note {{heap-allocated object is not a constant expression}} \ -// both-error {{'cxx2a::to_lvalue_ref' is not a constant expression}} \ + { A k = to_lvalue_ref(A().ret_a()); } // both-error {{'cxx2a::to_lvalue_ref' is not a constant expression}} \ // both-note {{reference to temporary is not a constant expression}} \ // both-note {{temporary created here}} { int k = A().ret_a().ret_i(); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \ @@ -445,19 +443,15 @@ void test() { { int k = const_a_ref(a); } { int k = rvalue_ref(A()); } { int k = rvalue_ref(std::move(a)); } - { int k = const_a_ref(A().ret_a()); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \ -// both-note {{is not a constant expression}} - { int k = const_a_ref(to_lvalue_ref(A().ret_a())); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \ - // both-note {{is not a constant expression}} + { int k = const_a_ref(A().ret_a()); } + { int k = const_a_ref(to_lvalue_ref(A().ret_a())); } { int k = const_a_ref(to_lvalue_ref(std::move(a))); } { int k = by_value_a(A().ret_a()); } { in
[clang] Allow installation of Clang .cfg files if they where generated. (PR #105580)
https://github.com/vvereschaka updated https://github.com/llvm/llvm-project/pull/105580 >From b34482f4f9e1273f69d47b2d500989a5c3c857df Mon Sep 17 00:00:00 2001 From: Vladimir Vereschaka Date: Wed, 21 Aug 2024 13:37:47 -0700 Subject: [PATCH] Allow installation of Clang .cfg files if they where generated. Add 'install-clang-configs' target to install generated configuration files into the destination 'bin' folder together with clang[++] executables. --- clang/CMakeLists.txt | 16 1 file changed, 16 insertions(+) diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index c6496167d3828b..f3494ab9e3f207 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -413,6 +413,22 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) endif() endif() +# Install build-generated Clang configuration files (if presented). +install(DIRECTORY ${LLVM_BINARY_DIR}/bin/ + TYPE BIN + COMPONENT clang-configs + FILES_MATCHING + PATTERN "*.cfg" + ) +add_custom_target(clang-configs DEPENDS clang) +set_target_properties(clang-configs PROPERTIES FOLDER "Clang/Configurations") +if(NOT LLVM_ENABLE_IDE) + # Add a dummy target so this can be used with LLVM_DISTRIBUTION_COMPONENTS. + add_llvm_install_targets(install-clang-configs + DEPENDS clang-configs + COMPONENT clang-configs) +endif() + option(CLANG_BUILD_TOOLS "Build the Clang tools. If OFF, just generate build targets." ON) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] prevent assertion failure when converting vectors to int/float with invalid expressions (PR #105727)
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/105727 >From d8bed3f4db8056a6afa9bd7eae5d4a8361f83086 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 22 Aug 2024 23:25:31 +0300 Subject: [PATCH] [Clang] prevent assertion failure when converting vectors to int/float with invalid expressions --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaExpr.cpp | 6 ++ clang/test/SemaCXX/vector.cpp | 14 ++ 3 files changed, 21 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 12a924acc14331..27aac987011dea 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -296,6 +296,7 @@ Bug Fixes to C++ Support template depth than the friend function template. (#GH98258) - Clang now rebuilds the template parameters of out-of-line declarations and specializations in the context of the current instantiation in all cases. +- Fixed an assertion failure when converting vectors to int/float with invalid expressions. (#GH105486) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c67183df335dd5..58825ef89213d2 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -9889,6 +9889,9 @@ static ExprResult convertVector(Expr *E, QualType ElementType, Sema &S) { /// IntTy without losing precision. static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int, QualType OtherIntTy) { + if (Int->get()->isValueDependent()) +return false; + QualType IntTy = Int->get()->getType().getUnqualifiedType(); // Reject cases where the value of the Int is unknown as that would @@ -9927,6 +9930,9 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int, /// FloatTy without losing precision. static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int, QualType FloatTy) { + if (Int->get()->isValueDependent()) +return false; + QualType IntTy = Int->get()->getType().getUnqualifiedType(); // Determine if the integer constant can be expressed as a floating point diff --git a/clang/test/SemaCXX/vector.cpp b/clang/test/SemaCXX/vector.cpp index 7c8ee89814e578..808bdb679b09cd 100644 --- a/clang/test/SemaCXX/vector.cpp +++ b/clang/test/SemaCXX/vector.cpp @@ -772,3 +772,17 @@ void test_scoped_enum_vector(EnumClass ea, v2u v2ua) { } #endif } + +namespace GH105486 { +__attribute__((__vector_size__(sizeof(double double a; +double b = a - (long)(*0); // expected-error {{indirection requires pointer operand ('int' invalid)}} \ + // expected-error {{cannot initialize a variable of type 'double' with an rvalue of type '__attribute__((__vector_size__(1 * sizeof(double double' (vector of 1 'double' value)}} + +__attribute__((__vector_size__(sizeof(long long c; +long d = c - (long)(*0); // expected-error {{indirection requires pointer operand ('int' invalid)}} \ + // expected-error {{cannot initialize a variable of type 'long' with an rvalue of type '__attribute__((__vector_size__(1 * sizeof(long long' (vector of 1 'long' value)}} + +const long long e = *0; // expected-error {{indirection requires pointer operand ('int' invalid)}} +double f = a - e; // expected-error {{cannot initialize a variable of type 'double' with an rvalue of type '__attribute__((__vector_size__(1 * sizeof(double double' (vector of 1 'double' value)}} +int h = c - e; // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type '__attribute__((__vector_size__(1 * sizeof(long long' (vector of 1 'long' value)}} +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Bugfixes and improved support for `AttributedType`s in lambdas (PR #85325)
https://github.com/Sirraide updated https://github.com/llvm/llvm-project/pull/85325 >From 907210a3ad3d829a8e49a5c976d129f8653801bf Mon Sep 17 00:00:00 2001 From: Sirraide Date: Thu, 14 Mar 2024 18:24:37 +0100 Subject: [PATCH 01/15] [Clang] Add `dump()` method for `Attr` --- clang/include/clang/AST/Attr.h | 2 ++ clang/lib/AST/ASTDumper.cpp| 8 2 files changed, 10 insertions(+) diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index 8e9b7ad8b46826..6400023947863f 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -112,6 +112,8 @@ class Attr : public AttributeCommonInfo { // Pretty print this attribute. void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const; + void dump() const; + static StringRef getDocumentation(attr::Kind); }; diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index 6efc5bb92e28d2..8d8b8621341ef7 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -361,3 +361,11 @@ LLVM_DUMP_METHOD void ConceptReference::dump(raw_ostream &OS) const { ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors()); P.Visit(this); } + +//===--===// +// Attr method implementations +//===--===// +LLVM_DUMP_METHOD void Attr::dump() const { + ASTDumper P(llvm::errs(), /*ShowColors=*/false); + P.Visit(this); +} >From d719a7605c89ed4ea88734b5386b6009931450f6 Mon Sep 17 00:00:00 2001 From: Sirraide Date: Thu, 14 Mar 2024 18:25:18 +0100 Subject: [PATCH 02/15] [Clang] Do not instantiate the same (FunctionProto)Type twice --- clang/lib/Sema/TreeTransform.h | 22 -- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 2d22692f3ab750..cf781792935f18 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7231,12 +7231,22 @@ QualType TreeTransform::TransformAttributedType( // FIXME: dependent operand expressions? if (getDerived().AlwaysRebuild() || modifiedType != oldType->getModifiedType()) { -TypeLocBuilder AuxiliaryTLB; -AuxiliaryTLB.reserve(TL.getFullDataSize()); -QualType equivalentType = -getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc()); -if (equivalentType.isNull()) - return QualType(); +// Do not transform the equivalent type if it is equal to the modified type. +// +// This is because, 1. it’s the same type, instantiating it again will yield +// the same result anyway, and if it doesn't, then that could be a bug in +// and of itself, and 2. instantiating the same TypeLoc twice is a really +// bad idea if it's a FunctionProtoType, because instantiating the same +// ParmVarDecls twice will cause assertion failures. +QualType equivalentType = modifiedType; +if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) { + TypeLocBuilder AuxiliaryTLB; + AuxiliaryTLB.reserve(TL.getFullDataSize()); + equivalentType = + getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc()); + if (equivalentType.isNull()) +return QualType(); +} // Check whether we can add nullability; it is only represented as // type sugar, and therefore cannot be diagnosed in any other way. >From a9c753ab46b40bd7da6f27eb11655fe43acb11de Mon Sep 17 00:00:00 2001 From: Sirraide Date: Thu, 14 Mar 2024 21:40:41 +0100 Subject: [PATCH 03/15] [Clang] Refactor instantiation of a lambda's FunctionProtoType - Co-authored-by: Yuxuan Chen --- clang/include/clang/Sema/Template.h| 14 +++- clang/lib/Sema/SemaTemplateInstantiate.cpp | 13 +++- clang/lib/Sema/TreeTransform.h | 90 +++--- 3 files changed, 49 insertions(+), 68 deletions(-) diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h index ce44aca797b0fb..8c379f51ca3d5d 100644 --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -411,6 +411,11 @@ enum class TemplateSubstitutionKind : char { /// lookup will search our outer scope. bool CombineWithOuterScope; +/// Whether this scope is being used to instantiate a lambda expression, +/// in which case it should be reused for instantiating the lambda's +/// FunctionProtoType. +bool InstantiatingLambda = false; + /// If non-NULL, the template parameter pack that has been /// partially substituted per C++0x [temp.arg.explicit]p9. NamedDecl *PartiallySubstitutedPack = nullptr; @@ -425,9 +430,11 @@ enum class TemplateSubstitutionKind : char { unsigned NumArgsInPartiallySubstitutedPack; public: -LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) +LocalInstantiationScop
[clang] [Clang] prevent assertion failure when converting vectors to int/float with invalid expressions (PR #105727)
a-tarasyuk wrote: @AaronBallman could you review these changes? https://github.com/llvm/llvm-project/issues/105486#issuecomment-2308879407 thanks https://github.com/llvm/llvm-project/pull/105727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Bugfixes and improved support for `AttributedType`s in lambdas (PR #85325)
@@ -13830,61 +13820,27 @@ TreeTransform::TransformLambdaExpr(LambdaExpr *E) { getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class, TPL); - // Transform the type of the original lambda's call operator. - // The transformation MUST be done in the CurrentInstantiationScope since - // it introduces a mapping of the original to the newly created - // transformed parameters. Sirraide wrote: Done https://github.com/llvm/llvm-project/pull/85325 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Bugfixes and improved support for `AttributedType`s in lambdas (PR #85325)
@@ -361,3 +361,11 @@ LLVM_DUMP_METHOD void ConceptReference::dump(raw_ostream &OS) const { ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors()); P.Visit(this); } + +//===--===// +// Attr method implementations +//===--===// +LLVM_DUMP_METHOD void Attr::dump() const { + ASTDumper P(llvm::errs(), /*ShowColors=*/false); Sirraide wrote: I’ve removed this from this pr. https://github.com/llvm/llvm-project/pull/85325 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Bugfixes and improved support for `AttributedType`s in lambdas (PR #85325)
@@ -3140,13 +3184,20 @@ const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T, return cast(Result.getTypePtr()); } +QualType ASTContext::adjustFunctionResultType(QualType FunctionType, + QualType ResultType) { + return adjustType(FunctionType, [&](QualType Orig) { +const auto *FPT = Orig->castAs(); Sirraide wrote: This now handles `FunctionNoProtoType`s as well. https://github.com/llvm/llvm-project/pull/85325 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Bugfixes and improved support for `AttributedType`s in lambdas (PR #85325)
@@ -7231,12 +7226,16 @@ QualType TreeTransform::TransformAttributedType( // FIXME: dependent operand expressions? if (getDerived().AlwaysRebuild() || modifiedType != oldType->getModifiedType()) { -TypeLocBuilder AuxiliaryTLB; -AuxiliaryTLB.reserve(TL.getFullDataSize()); -QualType equivalentType = -getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc()); -if (equivalentType.isNull()) - return QualType(); +// Do not transform the equivalent type if it is equal to the modified type. Sirraide wrote: I’ve expanded the comment a bit to make this a bit more informative (hopefully). https://github.com/llvm/llvm-project/pull/85325 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][HLSL] Update DXIL/SPIRV hybird CodeGen tests to use temp var (PR #105930)
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/105930 >From cd1c20ce8856ca24ffea6db22a758e588f0398e2 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sat, 24 Aug 2024 10:08:23 +0200 Subject: [PATCH] [clang][HLSL] Update DXIL/SPIRV hybird CodeGen tests to use temp var Update all hybird DXIL/SPIRV codegen tests to use temp variable representing interchange target --- .../builtins/RWBuffer-constructor.hlsl| 10 +- clang/test/CodeGenHLSL/builtins/all.hlsl | 134 ++ clang/test/CodeGenHLSL/builtins/any.hlsl | 134 ++ clang/test/CodeGenHLSL/builtins/frac.hlsl | 38 ++--- clang/test/CodeGenHLSL/builtins/lerp.hlsl | 56 +++- clang/test/CodeGenHLSL/builtins/mad.hlsl | 16 +-- .../test/CodeGenHLSL/builtins/normalize.hlsl | 39 ++--- clang/test/CodeGenHLSL/builtins/rsqrt.hlsl| 38 ++--- clang/test/CodeGenHLSL/builtins/saturate.hlsl | 64 - .../semantics/DispatchThreadID.hlsl | 10 +- 10 files changed, 205 insertions(+), 334 deletions(-) diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl index e51eac7f57c2d3..e3fa0d2c3083fd 100644 --- a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl @@ -1,12 +1,12 @@ -// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-SPIRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=DXCHECK + +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=SPVCHECK RWBuffer Buf; // CHECK: define linkonce_odr noundef ptr @"??0?$RWBuffer@M@hlsl@@QAA@XZ" // CHECK-NEXT: entry: -// CHECK: %[[HandleRes:[0-9]+]] = call ptr @llvm.dx.create.handle(i8 1) +// DXCHECK: %[[HandleRes:[0-9]+]] = call ptr @llvm.dx.create.handle(i8 1) +// SPVCHECK: %[[HandleRes:[0-9]+]] = call ptr @llvm.spv.create.handle(i8 1) // CHECK: store ptr %[[HandleRes]], ptr %h, align 4 - -// CHECK-SPIRV: %[[HandleRes:[0-9]+]] = call ptr @llvm.spv.create.handle(i8 1) -// CHECK-SPIRV: store ptr %[[HandleRes]], ptr %h, align 8 diff --git a/clang/test/CodeGenHLSL/builtins/all.hlsl b/clang/test/CodeGenHLSL/builtins/all.hlsl index b48daa287480ff..f431aa8eb692dd 100644 --- a/clang/test/CodeGenHLSL/builtins/all.hlsl +++ b/clang/test/CodeGenHLSL/builtins/all.hlsl @@ -16,262 +16,220 @@ #ifdef __HLSL_ENABLE_16_BIT // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.i16 +// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF:dx]].all.i16 +// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF:spv]].all.i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t(int16_t p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v2i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v2i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v2i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t2(int16_t2 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v3i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v3i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v3i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t3(int16_t3 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v4i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v4i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v4i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t4(int16_t4 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_uint16_t(uint16_t p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v2i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v2i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v2i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_uint16_t2(uint16_t2 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF
[clang] [clang][HLSL] Update DXIL/SPIRV hybird CodeGen tests to use temp var (PR #105930)
@@ -15,70 +15,70 @@ // DXIL_NATIVE_HALF: define noundef half @ // SPIR_NATIVE_HALF: define spir_func noundef half @ -// DXIL_NATIVE_HALF: %hlsl.frac = call half @llvm.dx.frac.f16( -// SPIR_NATIVE_HALF: %hlsl.frac = call half @llvm.spv.frac.f16( +// DXIL_NATIVE_HALF: %hlsl.frac = call half @llvm.[[ICF:dx]].frac.f16( +// SPIR_NATIVE_HALF: %hlsl.frac = call half @llvm.[[ICF:spv]].frac.f16( // NATIVE_HALF: ret half %hlsl.frac // DXIL_NO_HALF: define noundef float @ // SPIR_NO_HALF: define spir_func noundef float @ -// DXIL_NO_HALF: %hlsl.frac = call float @llvm.dx.frac.f32( -// SPIR_NO_HALF: %hlsl.frac = call float @llvm.spv.frac.f32( +// DXIL_NO_HALF: %hlsl.frac = call float @llvm.[[ICF:dx]].frac.f32( +// SPIR_NO_HALF: %hlsl.frac = call float @llvm.[[ICF:spv]].frac.f32( // NO_HALF: ret float %hlsl.frac half test_frac_half(half p0) { return frac(p0); } // DXIL_NATIVE_HALF: define noundef <2 x half> @ // SPIR_NATIVE_HALF: define spir_func noundef <2 x half> @ -// DXIL_NATIVE_HALF: %hlsl.frac = call <2 x half> @llvm.dx.frac.v2f16 -// SPIR_NATIVE_HALF: %hlsl.frac = call <2 x half> @llvm.spv.frac.v2f16 +// DXIL_NATIVE_HALF: %hlsl.frac = call <2 x half> @llvm.[[ICF:dx]].frac.v2f16 +// SPIR_NATIVE_HALF: %hlsl.frac = call <2 x half> @llvm.[[ICF:spv]].frac.v2f16 // NATIVE_HALF: ret <2 x half> %hlsl.frac // DXIL_NO_HALF: define noundef <2 x float> @ // SPIR_NO_HALF: define spir_func noundef <2 x float> @ -// DXIL_NO_HALF: %hlsl.frac = call <2 x float> @llvm.dx.frac.v2f32( -// SPIR_NO_HALF: %hlsl.frac = call <2 x float> @llvm.spv.frac.v2f32( +// DXIL_NO_HALF: %hlsl.frac = call <2 x float> @llvm.[[ICF:dx]].frac.v2f32( +// SPIR_NO_HALF: %hlsl.frac = call <2 x float> @llvm.[[ICF:spv]].frac.v2f32( // NO_HALF: ret <2 x float> %hlsl.frac half2 test_frac_half2(half2 p0) { return frac(p0); } // DXIL_NATIVE_HALF: define noundef <3 x half> @ // SPIR_NATIVE_HALF: define spir_func noundef <3 x half> @ -// DXIL_NATIVE_HALF: %hlsl.frac = call <3 x half> @llvm.dx.frac.v3f16 -// SPIR_NATIVE_HALF: %hlsl.frac = call <3 x half> @llvm.spv.frac.v3f16 +// DXIL_NATIVE_HALF: %hlsl.frac = call <3 x half> @llvm.[[ICF:dx]].frac.v3f16 +// SPIR_NATIVE_HALF: %hlsl.frac = call <3 x half> @llvm.[[ICF:spv]].frac.v3f16 // NATIVE_HALF: ret <3 x half> %hlsl.frac // DXIL_NO_HALF: define noundef <3 x float> @ // SPIR_NO_HALF: define spir_func noundef <3 x float> @ -// DXIL_NO_HALF: %hlsl.frac = call <3 x float> @llvm.dx.frac.v3f32( -// SPIR_NO_HALF: %hlsl.frac = call <3 x float> @llvm.spv.frac.v3f32( +// DXIL_NO_HALF: %hlsl.frac = call <3 x float> @llvm.[[ICF:dx]].frac.v3f32( +// SPIR_NO_HALF: %hlsl.frac = call <3 x float> @llvm.[[ICF:spv]].frac.v3f32( // NO_HALF: ret <3 x float> %hlsl.frac half3 test_frac_half3(half3 p0) { return frac(p0); } // DXIL_NATIVE_HALF: define noundef <4 x half> @ // SPIR_NATIVE_HALF: define spir_func noundef <4 x half> @ -// DXIL_NATIVE_HALF: %hlsl.frac = call <4 x half> @llvm.dx.frac.v4f16 -// SPIR_NATIVE_HALF: %hlsl.frac = call <4 x half> @llvm.spv.frac.v4f16 +// DXIL_NATIVE_HALF: %hlsl.frac = call <4 x half> @llvm.[[ICF:dx]].frac.v4f16 +// SPIR_NATIVE_HALF: %hlsl.frac = call <4 x half> @llvm.[[ICF:spv]].frac.v4f16 // NATIVE_HALF: ret <4 x half> %hlsl.frac // DXIL_NO_HALF: define noundef <4 x float> @ // SPIR_NO_HALF: define spir_func noundef <4 x float> @ -// DXIL_NO_HALF: %hlsl.frac = call <4 x float> @llvm.dx.frac.v4f32( -// SPIR_NO_HALF: %hlsl.frac = call <4 x float> @llvm.spv.frac.v4f32( +// DXIL_NO_HALF: %hlsl.frac = call <4 x float> @llvm.[[ICF:dx]].frac.v4f32( +// SPIR_NO_HALF: %hlsl.frac = call <4 x float> @llvm.[[ICF:spv]].frac.v4f32( // NO_HALF: ret <4 x float> %hlsl.frac half4 test_frac_half4(half4 p0) { return frac(p0); } // DXIL_CHECK: define noundef float @ // SPIR_CHECK: define spir_func noundef float @ -// DXIL_CHECK: %hlsl.frac = call float @llvm.dx.frac.f32( -// SPIR_CHECK: %hlsl.frac = call float @llvm.spv.frac.f32( +// DXIL_CHECK: %hlsl.frac = call float @llvm.[[ICF:dx]].frac.f32( +// SPIR_CHECK: %hlsl.frac = call float @llvm.[[ICF:spv]].frac.f32( // CHECK: ret float %hlsl.frac float test_frac_float(float p0) { return frac(p0); } // DXIL_CHECK: define noundef <2 x float> @ // SPIR_CHECK: define spir_func noundef <2 x float> @ -// DXIL_CHECK: %hlsl.frac = call <2 x float> @llvm.dx.frac.v2f32 -// SPIR_CHECK: %hlsl.frac = call <2 x float> @llvm.spv.frac.v2f32 +// DXIL_CHECK: %hlsl.frac = call <2 x float> @llvm.[[ICF:dx]].frac.v2f32 +// SPIR_CHECK: %hlsl.frac = call <2 x float> @llvm.[[ICF:spv]].frac.v2f32 // CHECK: ret <2 x float> %hlsl.frac float2 test_frac_float2(float2 p0) { return frac(p0); } // DXIL_CHECK: define noundef <3 x float> @ // SPIR_CHECK: define spir_func noundef <3 x float> @ -// DXIL_CHECK: %hlsl.frac = call <3 x float> @llvm.dx.frac.v3f32 -// SPIR_CHECK: %hlsl.frac = call <3 x float> @llvm.spv.frac.v3f32 +// DXIL_CHECK: %hlsl.frac = call <3 x float> @llvm.[[ICF:dx]].frac.v3f32 +// SPIR_CHECK: %hlsl.frac = call <3 x float> @llvm.[[IC
[clang] [clang][HLSL] Update DXIL/SPIRV hybird CodeGen tests to use temp var (PR #105930)
@@ -25,7 +25,7 @@ void main(unsigned GI : SV_GroupIndex) {} //CHECK-NEXT: entry: //CHECK-NEXT: call void @"?call_me_first@@YAXXZ"() //CHECK-NEXT: call void @"?then_call_me@@YAXXZ"() -//CHECK-NEXT: %0 = call i32 @llvm.dx.flattened.thread.id.in.group() +//CHECK-NEXT: %0 = call i32 @llvm.[[ICF:dx]].flattened.thread.id.in.group() AmrDeveloper wrote: Thank you done https://github.com/llvm/llvm-project/pull/105930 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Bugfixes and improved support for `AttributedType`s in lambdas (PR #85325)
https://github.com/Sirraide updated https://github.com/llvm/llvm-project/pull/85325 >From 907210a3ad3d829a8e49a5c976d129f8653801bf Mon Sep 17 00:00:00 2001 From: Sirraide Date: Thu, 14 Mar 2024 18:24:37 +0100 Subject: [PATCH 01/16] [Clang] Add `dump()` method for `Attr` --- clang/include/clang/AST/Attr.h | 2 ++ clang/lib/AST/ASTDumper.cpp| 8 2 files changed, 10 insertions(+) diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index 8e9b7ad8b46826..6400023947863f 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -112,6 +112,8 @@ class Attr : public AttributeCommonInfo { // Pretty print this attribute. void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const; + void dump() const; + static StringRef getDocumentation(attr::Kind); }; diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index 6efc5bb92e28d2..8d8b8621341ef7 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -361,3 +361,11 @@ LLVM_DUMP_METHOD void ConceptReference::dump(raw_ostream &OS) const { ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors()); P.Visit(this); } + +//===--===// +// Attr method implementations +//===--===// +LLVM_DUMP_METHOD void Attr::dump() const { + ASTDumper P(llvm::errs(), /*ShowColors=*/false); + P.Visit(this); +} >From d719a7605c89ed4ea88734b5386b6009931450f6 Mon Sep 17 00:00:00 2001 From: Sirraide Date: Thu, 14 Mar 2024 18:25:18 +0100 Subject: [PATCH 02/16] [Clang] Do not instantiate the same (FunctionProto)Type twice --- clang/lib/Sema/TreeTransform.h | 22 -- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 2d22692f3ab750..cf781792935f18 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7231,12 +7231,22 @@ QualType TreeTransform::TransformAttributedType( // FIXME: dependent operand expressions? if (getDerived().AlwaysRebuild() || modifiedType != oldType->getModifiedType()) { -TypeLocBuilder AuxiliaryTLB; -AuxiliaryTLB.reserve(TL.getFullDataSize()); -QualType equivalentType = -getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc()); -if (equivalentType.isNull()) - return QualType(); +// Do not transform the equivalent type if it is equal to the modified type. +// +// This is because, 1. it’s the same type, instantiating it again will yield +// the same result anyway, and if it doesn't, then that could be a bug in +// and of itself, and 2. instantiating the same TypeLoc twice is a really +// bad idea if it's a FunctionProtoType, because instantiating the same +// ParmVarDecls twice will cause assertion failures. +QualType equivalentType = modifiedType; +if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) { + TypeLocBuilder AuxiliaryTLB; + AuxiliaryTLB.reserve(TL.getFullDataSize()); + equivalentType = + getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc()); + if (equivalentType.isNull()) +return QualType(); +} // Check whether we can add nullability; it is only represented as // type sugar, and therefore cannot be diagnosed in any other way. >From a9c753ab46b40bd7da6f27eb11655fe43acb11de Mon Sep 17 00:00:00 2001 From: Sirraide Date: Thu, 14 Mar 2024 21:40:41 +0100 Subject: [PATCH 03/16] [Clang] Refactor instantiation of a lambda's FunctionProtoType - Co-authored-by: Yuxuan Chen --- clang/include/clang/Sema/Template.h| 14 +++- clang/lib/Sema/SemaTemplateInstantiate.cpp | 13 +++- clang/lib/Sema/TreeTransform.h | 90 +++--- 3 files changed, 49 insertions(+), 68 deletions(-) diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h index ce44aca797b0fb..8c379f51ca3d5d 100644 --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -411,6 +411,11 @@ enum class TemplateSubstitutionKind : char { /// lookup will search our outer scope. bool CombineWithOuterScope; +/// Whether this scope is being used to instantiate a lambda expression, +/// in which case it should be reused for instantiating the lambda's +/// FunctionProtoType. +bool InstantiatingLambda = false; + /// If non-NULL, the template parameter pack that has been /// partially substituted per C++0x [temp.arg.explicit]p9. NamedDecl *PartiallySubstitutedPack = nullptr; @@ -425,9 +430,11 @@ enum class TemplateSubstitutionKind : char { unsigned NumArgsInPartiallySubstitutedPack; public: -LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) +LocalInstantiationScop
[clang] [clang][HLSL] Update DXIL/SPIRV hybird CodeGen tests to use temp var (PR #105930)
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/105930 >From f161a06ef18e52fd03809a7b73cc0aa978513344 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sat, 24 Aug 2024 10:08:23 +0200 Subject: [PATCH] [clang][HLSL] Update DXIL/SPIRV hybird CodeGen tests to use temp var Update all hybird DXIL/SPIRV codegen tests to use temp variable representing interchange target --- .../builtins/RWBuffer-constructor.hlsl| 10 +- clang/test/CodeGenHLSL/builtins/all.hlsl | 134 ++ clang/test/CodeGenHLSL/builtins/any.hlsl | 134 ++ clang/test/CodeGenHLSL/builtins/frac.hlsl | 38 ++--- clang/test/CodeGenHLSL/builtins/lerp.hlsl | 56 +++- clang/test/CodeGenHLSL/builtins/mad.hlsl | 16 +-- .../test/CodeGenHLSL/builtins/normalize.hlsl | 39 ++--- clang/test/CodeGenHLSL/builtins/rsqrt.hlsl| 38 ++--- clang/test/CodeGenHLSL/builtins/saturate.hlsl | 64 - .../semantics/DispatchThreadID.hlsl | 10 +- 10 files changed, 205 insertions(+), 334 deletions(-) diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl index e51eac7f57c2d3..e3fa0d2c3083fd 100644 --- a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl @@ -1,12 +1,12 @@ -// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-SPIRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=DXCHECK + +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=SPVCHECK RWBuffer Buf; // CHECK: define linkonce_odr noundef ptr @"??0?$RWBuffer@M@hlsl@@QAA@XZ" // CHECK-NEXT: entry: -// CHECK: %[[HandleRes:[0-9]+]] = call ptr @llvm.dx.create.handle(i8 1) +// DXCHECK: %[[HandleRes:[0-9]+]] = call ptr @llvm.dx.create.handle(i8 1) +// SPVCHECK: %[[HandleRes:[0-9]+]] = call ptr @llvm.spv.create.handle(i8 1) // CHECK: store ptr %[[HandleRes]], ptr %h, align 4 - -// CHECK-SPIRV: %[[HandleRes:[0-9]+]] = call ptr @llvm.spv.create.handle(i8 1) -// CHECK-SPIRV: store ptr %[[HandleRes]], ptr %h, align 8 diff --git a/clang/test/CodeGenHLSL/builtins/all.hlsl b/clang/test/CodeGenHLSL/builtins/all.hlsl index b48daa287480ff..f431aa8eb692dd 100644 --- a/clang/test/CodeGenHLSL/builtins/all.hlsl +++ b/clang/test/CodeGenHLSL/builtins/all.hlsl @@ -16,262 +16,220 @@ #ifdef __HLSL_ENABLE_16_BIT // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.i16 +// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF:dx]].all.i16 +// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF:spv]].all.i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t(int16_t p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v2i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v2i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v2i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t2(int16_t2 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v3i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v3i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v3i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t3(int16_t3 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v4i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v4i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v4i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t4(int16_t4 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_uint16_t(uint16_t p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v2i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v2i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v2i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_uint16_t2(uint16_t2 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF
[clang] [clang] Add support for omitting only global destructors (PR #104899)
https://github.com/smeenai closed https://github.com/llvm/llvm-project/pull/104899 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7945435 - [clang] Add support for omitting only global destructors (#104899)
Author: Shoaib Meenai Date: 2024-08-26T13:11:05-07:00 New Revision: 7945435f46c4b0a9fd08c6d76eee8ea8f5e37bca URL: https://github.com/llvm/llvm-project/commit/7945435f46c4b0a9fd08c6d76eee8ea8f5e37bca DIFF: https://github.com/llvm/llvm-project/commit/7945435f46c4b0a9fd08c6d76eee8ea8f5e37bca.diff LOG: [clang] Add support for omitting only global destructors (#104899) For mobile applications, it's common for global destructors to never be called (because the applications have their own lifecycle independent of the standard C runtime), but threads are created and destroyed as normal and so thread-local destructors are still called. -fno-static-c++-destructors omits unnecessary global destructors, which is useful for code size, but it also omits thread-local destructors, which is unsuitable. Add a ternary `-fc++-static-destructors={all,none,thread-local}` option instead to allow omitting only global destructors. Added: clang/test/Driver/cxx-static-destructors.cpp Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/LangOptions.def clang/include/clang/Basic/LangOptions.h clang/include/clang/Driver/Options.td clang/lib/AST/Decl.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/test/CodeGenCXX/always_destroy.cpp clang/test/CodeGenCXX/attr-no-destroy-d54344.cpp clang/test/SemaCXX/no_destroy.cpp Removed: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7a9e7f0b4eba69..0a31953ab87005 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -173,6 +173,13 @@ Non-comprehensive list of changes in this release New Compiler Flags -- +- The ``-fc++-static-destructors={all,thread-local,none}`` flag was + added to control which C++ variables have static destructors + registered: all (the default) does so for all variables, thread-local + only for thread-local variables, and none (which corresponds to the + existing ``-fno-c++-static-destructors`` flag) skips all static + destructors registration. + Deprecated Compiler Flags - diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 956d9a2d2434c4..fd3346d29f26a3 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -464,7 +464,9 @@ LANGOPT(FixedPoint, 1, 0, "fixed point types") LANGOPT(PaddingOnUnsignedFixedPoint, 1, 0, "unsigned fixed point types having one extra padding bit") -LANGOPT(RegisterStaticDestructors, 1, 1, "Register C++ static destructors") +ENUM_LANGOPT(RegisterStaticDestructors, RegisterStaticDestructorsKind, 2, + RegisterStaticDestructorsKind::All, + "Register C++ static destructors") LANGOPT(RegCall4, 1, 0, "Set __regcall4 as a default calling convention to respect __regcall ABI v.4") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 1c80ee89837cb3..51a34686ad7e1d 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -458,6 +458,16 @@ class LangOptionsBase { CX_None }; + /// Controls which variables have static destructors registered. + enum class RegisterStaticDestructorsKind { +/// Register static destructors for all variables. +All, +/// Register static destructors only for thread-local variables. +ThreadLocal, +/// Don't register static destructors for any variables. +None, + }; + // Define simple language options (with no accessors). #define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits; #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 1b9b3f2c6600a3..83cf753e824845 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2302,11 +2302,18 @@ defm fixed_point : BoolFOption<"fixed-point", PosFlag, NegFlag, BothFlags<[], [ClangOption], " fixed point types">>; -defm cxx_static_destructors : BoolFOption<"c++-static-destructors", - LangOpts<"RegisterStaticDestructors">, DefaultTrue, - NegFlag, - PosFlag>; +def cxx_static_destructors_EQ : Joined<["-"], "fc++-static-destructors=">, Group, + HelpText<"Controls which variables C++ static destructors are registered for">, + Values<"all,thread-local,none">, + NormalizedValues<["All", "ThreadLocal", "None"]>, + NormalizedValuesScope<"LangOptions::RegisterStaticDestructorsKind">, + MarshallingInfoEnum, "All">, + Visibility<[ClangOption, CC1Option]>; +def cxx_static_destructors : Flag<["-"], "fc++-static-destructors">, Group, + Alias, AliasArgs<["all"]>; +def no_cxx_static_destructors : Flag<["-"], "fno-c++-static-destructors">, Group, + Alias, AliasArgs<["none"]>, + HelpText<"Disable C++ static
[clang] [HLSL] Apply NoRecurse attrib to all HLSL functions (PR #105907)
https://github.com/bob80905 approved this pull request. https://github.com/llvm/llvm-project/pull/105907 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [llvm] [llvm] add support for mustache templating language (PR #105893)
@@ -0,0 +1,109 @@ +//===--- Mustache.h -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// Implementation of the Mustache templating language supports version 1.4.2 +// (https://mustache.github.io/mustache.5.html). +// +//===--===// + +#ifndef LLVM_SUPPORT_MUSTACHE +#define LLVM_SUPPORT_MUSTACHE + +#include "Error.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/JSON.h" +#include +#include +#include + +namespace llvm { +namespace mustache { + +using Accessor = std::vector; + +class Token { +public: + enum class Type { +Text, +Variable, +Partial, +SectionOpen, +SectionClose, +InvertSectionOpen, +UnescapeVariable, +Comment, + }; + + Token(std::string Str); + ilovepi wrote: Here and elsewhere in this patch it would be preferabel to use the llvm versions for things like strings in compliance w/ https://llvm.org/docs/ProgrammersManual.html https://github.com/llvm/llvm-project/pull/105893 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [llvm] [llvm] add support for mustache templating language (PR #105893)
@@ -0,0 +1,276 @@ +//===-- Mustache.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/Support/Mustache.h" +#include "llvm/Support/Error.h" +#include +#include +#include + +using namespace llvm; +using namespace llvm::json; +using namespace llvm::mustache; + +std::string escapeHtml(const std::string &Input) { + DenseMap HtmlEntities = {{'&', "&"}, + {'<', "<"}, + {'>', ">"}, + {'"', """}, + {'"', "'"}}; + std::string EscapedString; + EscapedString.reserve(Input.size()); + + for (char C : Input) { +if (HtmlEntities.find(C) != HtmlEntities.end()) { + EscapedString += HtmlEntities[C]; +} else { + EscapedString += C; +} + } + + return EscapedString; +} + +std::vector split(const std::string &Str, char Delimiter) { + std::vector Tokens; + std::string Token; + std::stringstream SS(Str); + if (Str == ".") { +Tokens.push_back(Str); +return Tokens; + } + while (std::getline(SS, Token, Delimiter)) { +Tokens.push_back(Token); + } + return Tokens; +} + +Token::Token(std::string Str, char Identifier) { + switch (Identifier) { + case '#': +TokenType = Type::SectionOpen; +break; + case '/': +TokenType = Type::SectionClose; +break; + case '^': +TokenType = Type::InvertSectionOpen; +break; + case '!': +TokenType = Type::Comment; +break; + case '>': +TokenType = Type::Partial; +break; + case '&': +TokenType = Type::UnescapeVariable; +break; + default: +TokenType = Type::Variable; + } + if (TokenType == Type::Comment) +return; + + TokenBody = Str; + std::string AccessorStr = Str; + if (TokenType != Type::Variable) { +AccessorStr = Str.substr(1); + } + Accessor = split(StringRef(AccessorStr).trim().str(), '.'); +} + +Token::Token(std::string Str) +: TokenType(Type::Text), TokenBody(Str), Accessor({}) {} + +std::vector tokenize(std::string Template) { + std::vector Tokens; + std::regex Re(R"(\{\{(.*?)\}\})"); + std::sregex_token_iterator Iter(Template.begin(), Template.end(), Re, + {-1, 0}); + std::sregex_token_iterator End; + + for (; Iter != End; ++Iter) { +if (!Iter->str().empty()) { + std::string Token = *Iter; + std::smatch Match; + if (std::regex_match(Token, Match, Re)) { +std::string Group = Match[1]; +Tokens.emplace_back(Group, Group[0]); + } else { +Tokens.emplace_back(Token); + } +} + } + + return Tokens; +} + +class Parser { +public: + Parser(std::string TemplateStr) : TemplateStr(TemplateStr) {} + + std::shared_ptr parse(); + +private: + void parseMustache(std::shared_ptr Parent); + + std::vector Tokens; + std::size_t CurrentPtr; + std::string TemplateStr; +}; + +std::shared_ptr Parser::parse() { + Tokens = tokenize(TemplateStr); + CurrentPtr = 0; + std::shared_ptr Root = std::make_shared(); + parseMustache(Root); + return Root; +} + +void Parser::parseMustache(std::shared_ptr Parent) { + + while (CurrentPtr < Tokens.size()) { +Token CurrentToken = Tokens[CurrentPtr]; +CurrentPtr++; +Accessor A = CurrentToken.getAccessor(); +std::shared_ptr CurrentNode; + +switch (CurrentToken.getType()) { +case Token::Type::Text: { + CurrentNode = + std::make_shared(CurrentToken.getTokenBody(), Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::Variable: { + CurrentNode = std::make_shared(ASTNode::Variable, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::UnescapeVariable: { + CurrentNode = + std::make_shared(ASTNode::UnescapeVariable, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::Partial: { + CurrentNode = std::make_shared(ASTNode::Partial, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::SectionOpen: { + CurrentNode = std::make_shared(ASTNode::Section, A, Parent); + parseMustache(CurrentNode); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::InvertSectionOpen: { + CurrentNode = + std::make_shared(ASTNode::InvertSection, A, Parent); + parseMustache(CurrentNode); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::SectionClose: { + return; +} +default: + break; +} + } +} + +Expected Template::createTemplate(std::string TemplateStr)
[clang-tools-extra] [llvm] [llvm] add support for mustache templating language (PR #105893)
@@ -0,0 +1,276 @@ +//===-- Mustache.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/Support/Mustache.h" +#include "llvm/Support/Error.h" +#include +#include +#include + +using namespace llvm; +using namespace llvm::json; +using namespace llvm::mustache; + +std::string escapeHtml(const std::string &Input) { + DenseMap HtmlEntities = {{'&', "&"}, + {'<', "<"}, + {'>', ">"}, + {'"', """}, + {'"', "'"}}; + std::string EscapedString; + EscapedString.reserve(Input.size()); + + for (char C : Input) { +if (HtmlEntities.find(C) != HtmlEntities.end()) { + EscapedString += HtmlEntities[C]; +} else { + EscapedString += C; +} + } + + return EscapedString; +} + +std::vector split(const std::string &Str, char Delimiter) { + std::vector Tokens; + std::string Token; + std::stringstream SS(Str); + if (Str == ".") { +Tokens.push_back(Str); +return Tokens; + } + while (std::getline(SS, Token, Delimiter)) { +Tokens.push_back(Token); + } + return Tokens; +} + +Token::Token(std::string Str, char Identifier) { + switch (Identifier) { + case '#': +TokenType = Type::SectionOpen; +break; + case '/': +TokenType = Type::SectionClose; +break; + case '^': +TokenType = Type::InvertSectionOpen; +break; + case '!': +TokenType = Type::Comment; +break; + case '>': +TokenType = Type::Partial; +break; + case '&': +TokenType = Type::UnescapeVariable; +break; + default: +TokenType = Type::Variable; + } + if (TokenType == Type::Comment) +return; + + TokenBody = Str; + std::string AccessorStr = Str; + if (TokenType != Type::Variable) { +AccessorStr = Str.substr(1); + } + Accessor = split(StringRef(AccessorStr).trim().str(), '.'); +} + +Token::Token(std::string Str) +: TokenType(Type::Text), TokenBody(Str), Accessor({}) {} + +std::vector tokenize(std::string Template) { + std::vector Tokens; + std::regex Re(R"(\{\{(.*?)\}\})"); + std::sregex_token_iterator Iter(Template.begin(), Template.end(), Re, + {-1, 0}); + std::sregex_token_iterator End; ilovepi wrote: Not completely sure we want to use regular expressions here. They're powerful, but have performance tradeoffs, and can be hard to use. Doesn't `End` need to be initialized to refer to the same thing as `It`? nit: s/Iter/It https://github.com/llvm/llvm-project/pull/105893 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [llvm] [llvm] add support for mustache templating language (PR #105893)
@@ -0,0 +1,276 @@ +//===-- Mustache.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/Support/Mustache.h" +#include "llvm/Support/Error.h" +#include +#include +#include + +using namespace llvm; +using namespace llvm::json; +using namespace llvm::mustache; + +std::string escapeHtml(const std::string &Input) { + DenseMap HtmlEntities = {{'&', "&"}, + {'<', "<"}, + {'>', ">"}, + {'"', """}, + {'"', "'"}}; + std::string EscapedString; + EscapedString.reserve(Input.size()); + + for (char C : Input) { +if (HtmlEntities.find(C) != HtmlEntities.end()) { + EscapedString += HtmlEntities[C]; +} else { + EscapedString += C; +} + } + + return EscapedString; +} + +std::vector split(const std::string &Str, char Delimiter) { + std::vector Tokens; + std::string Token; + std::stringstream SS(Str); + if (Str == ".") { +Tokens.push_back(Str); +return Tokens; + } + while (std::getline(SS, Token, Delimiter)) { +Tokens.push_back(Token); + } + return Tokens; +} + +Token::Token(std::string Str, char Identifier) { + switch (Identifier) { + case '#': +TokenType = Type::SectionOpen; +break; + case '/': +TokenType = Type::SectionClose; +break; + case '^': +TokenType = Type::InvertSectionOpen; +break; + case '!': +TokenType = Type::Comment; +break; + case '>': +TokenType = Type::Partial; +break; + case '&': +TokenType = Type::UnescapeVariable; +break; + default: +TokenType = Type::Variable; + } + if (TokenType == Type::Comment) +return; + + TokenBody = Str; + std::string AccessorStr = Str; + if (TokenType != Type::Variable) { +AccessorStr = Str.substr(1); + } + Accessor = split(StringRef(AccessorStr).trim().str(), '.'); +} + +Token::Token(std::string Str) +: TokenType(Type::Text), TokenBody(Str), Accessor({}) {} + +std::vector tokenize(std::string Template) { + std::vector Tokens; + std::regex Re(R"(\{\{(.*?)\}\})"); + std::sregex_token_iterator Iter(Template.begin(), Template.end(), Re, + {-1, 0}); + std::sregex_token_iterator End; + + for (; Iter != End; ++Iter) { +if (!Iter->str().empty()) { + std::string Token = *Iter; + std::smatch Match; + if (std::regex_match(Token, Match, Re)) { +std::string Group = Match[1]; +Tokens.emplace_back(Group, Group[0]); + } else { +Tokens.emplace_back(Token); + } +} + } + + return Tokens; +} + +class Parser { +public: + Parser(std::string TemplateStr) : TemplateStr(TemplateStr) {} + + std::shared_ptr parse(); + +private: + void parseMustache(std::shared_ptr Parent); + + std::vector Tokens; + std::size_t CurrentPtr; + std::string TemplateStr; +}; + +std::shared_ptr Parser::parse() { + Tokens = tokenize(TemplateStr); + CurrentPtr = 0; + std::shared_ptr Root = std::make_shared(); + parseMustache(Root); + return Root; +} + +void Parser::parseMustache(std::shared_ptr Parent) { + + while (CurrentPtr < Tokens.size()) { +Token CurrentToken = Tokens[CurrentPtr]; +CurrentPtr++; +Accessor A = CurrentToken.getAccessor(); +std::shared_ptr CurrentNode; + +switch (CurrentToken.getType()) { +case Token::Type::Text: { + CurrentNode = + std::make_shared(CurrentToken.getTokenBody(), Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::Variable: { + CurrentNode = std::make_shared(ASTNode::Variable, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::UnescapeVariable: { + CurrentNode = + std::make_shared(ASTNode::UnescapeVariable, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::Partial: { + CurrentNode = std::make_shared(ASTNode::Partial, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::SectionOpen: { + CurrentNode = std::make_shared(ASTNode::Section, A, Parent); + parseMustache(CurrentNode); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::InvertSectionOpen: { + CurrentNode = + std::make_shared(ASTNode::InvertSection, A, Parent); + parseMustache(CurrentNode); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::SectionClose: { + return; +} +default: + break; +} + } +} + +Expected Template::createTemplate(std::string TemplateStr)
[clang-tools-extra] [llvm] [llvm] add support for mustache templating language (PR #105893)
@@ -0,0 +1,276 @@ +//===-- Mustache.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/Support/Mustache.h" +#include "llvm/Support/Error.h" +#include +#include +#include + +using namespace llvm; +using namespace llvm::json; +using namespace llvm::mustache; + +std::string escapeHtml(const std::string &Input) { + DenseMap HtmlEntities = {{'&', "&"}, + {'<', "<"}, + {'>', ">"}, + {'"', """}, + {'"', "'"}}; + std::string EscapedString; + EscapedString.reserve(Input.size()); + + for (char C : Input) { +if (HtmlEntities.find(C) != HtmlEntities.end()) { + EscapedString += HtmlEntities[C]; +} else { + EscapedString += C; +} + } + + return EscapedString; +} + +std::vector split(const std::string &Str, char Delimiter) { + std::vector Tokens; + std::string Token; + std::stringstream SS(Str); + if (Str == ".") { +Tokens.push_back(Str); +return Tokens; + } + while (std::getline(SS, Token, Delimiter)) { +Tokens.push_back(Token); + } + return Tokens; +} + +Token::Token(std::string Str, char Identifier) { + switch (Identifier) { + case '#': +TokenType = Type::SectionOpen; +break; + case '/': +TokenType = Type::SectionClose; +break; + case '^': +TokenType = Type::InvertSectionOpen; +break; + case '!': +TokenType = Type::Comment; +break; + case '>': +TokenType = Type::Partial; +break; + case '&': +TokenType = Type::UnescapeVariable; +break; + default: +TokenType = Type::Variable; + } + if (TokenType == Type::Comment) +return; + + TokenBody = Str; + std::string AccessorStr = Str; + if (TokenType != Type::Variable) { +AccessorStr = Str.substr(1); + } + Accessor = split(StringRef(AccessorStr).trim().str(), '.'); +} + +Token::Token(std::string Str) +: TokenType(Type::Text), TokenBody(Str), Accessor({}) {} + +std::vector tokenize(std::string Template) { + std::vector Tokens; + std::regex Re(R"(\{\{(.*?)\}\})"); + std::sregex_token_iterator Iter(Template.begin(), Template.end(), Re, + {-1, 0}); + std::sregex_token_iterator End; + + for (; Iter != End; ++Iter) { +if (!Iter->str().empty()) { + std::string Token = *Iter; + std::smatch Match; + if (std::regex_match(Token, Match, Re)) { +std::string Group = Match[1]; +Tokens.emplace_back(Group, Group[0]); + } else { +Tokens.emplace_back(Token); + } +} + } + + return Tokens; +} + +class Parser { +public: + Parser(std::string TemplateStr) : TemplateStr(TemplateStr) {} + + std::shared_ptr parse(); + +private: + void parseMustache(std::shared_ptr Parent); + + std::vector Tokens; + std::size_t CurrentPtr; + std::string TemplateStr; +}; + +std::shared_ptr Parser::parse() { + Tokens = tokenize(TemplateStr); + CurrentPtr = 0; + std::shared_ptr Root = std::make_shared(); + parseMustache(Root); + return Root; +} + +void Parser::parseMustache(std::shared_ptr Parent) { + + while (CurrentPtr < Tokens.size()) { +Token CurrentToken = Tokens[CurrentPtr]; +CurrentPtr++; +Accessor A = CurrentToken.getAccessor(); +std::shared_ptr CurrentNode; + +switch (CurrentToken.getType()) { +case Token::Type::Text: { + CurrentNode = + std::make_shared(CurrentToken.getTokenBody(), Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::Variable: { + CurrentNode = std::make_shared(ASTNode::Variable, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::UnescapeVariable: { + CurrentNode = + std::make_shared(ASTNode::UnescapeVariable, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::Partial: { + CurrentNode = std::make_shared(ASTNode::Partial, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::SectionOpen: { + CurrentNode = std::make_shared(ASTNode::Section, A, Parent); + parseMustache(CurrentNode); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::InvertSectionOpen: { + CurrentNode = + std::make_shared(ASTNode::InvertSection, A, Parent); + parseMustache(CurrentNode); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::SectionClose: { + return; +} +default: + break; +} + } +} + +Expected Template::createTemplate(std::string TemplateStr)
[clang-tools-extra] [llvm] [llvm] add support for mustache templating language (PR #105893)
@@ -0,0 +1,135 @@ +//===- llvm/unittest/Support/MustacheTest.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// Test conforming to Mustache 1.4.2 spec found here: +// https://github.com/mustache/spec +// +//===--===// + +#include "llvm/Support/Mustache.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::mustache; +using namespace llvm::json; + +TEST(MustacheInterpolation, NoInterpolation) { + // Mustache-free templates should render as-is. + Value D = {}; + auto T = Template::createTemplate("Hello from {Mustache}!\n"); + auto Out = T.get().render(D); + EXPECT_EQ("Hello from {Mustache}!\n", Out); +} + +TEST(MustacheInterpolation, BasicInterpolation) { + // Unadorned tags should interpolate content into the template. + Value D = Object{{"subject", "World"}}; + auto T = Template::createTemplate("Hello, {{subject}}!"); + auto Out = T.get().render(D); + EXPECT_EQ("Hello, World!", Out); +} + +TEST(MustacheInterpolation, NoReinterpolation) { + // Interpolated tag output should not be re-interpolated. + Value D = Object{{"template", "{{planet}}"}, {"planet", "Earth"}}; + auto T = Template::createTemplate("{{template}}: {{planet}}"); + auto Out = T.get().render(D); + EXPECT_EQ("{{planet}}: Earth", Out); +} + +TEST(MustacheInterpolation, HTMLEscaping) { + // Interpolated tag output should not be re-interpolated. + Value D = Object{ + {"forbidden", "& \" < >"}, + }; + auto T = Template::createTemplate( + "These characters should be HTML escaped: {{forbidden}}\n"); + auto Out = T.get().render(D); + EXPECT_EQ("These characters should be HTML escaped: & " < >\n", +Out); +} + +TEST(MustacheInterpolation, Ampersand) { + // Interpolated tag output should not be re-interpolated. + Value D = Object{ + {"forbidden", "& \" < >"}, + }; + auto T = Template::createTemplate( + "These characters should not be HTML escaped: {{&forbidden}}\n"); + auto Out = T.get().render(D); + EXPECT_EQ("These characters should not be HTML escaped: & \" < >\n", Out); +} + +TEST(MustacheInterpolation, BasicIntegerInterpolation) { + Value D = Object{{"mph", 85}}; + auto T = Template::createTemplate("{{mph}} miles an hour!"); + auto Out = T.get().render(D); + EXPECT_EQ("85 miles an hour!", Out); +} + +TEST(MustacheInterpolation, BasicDecimalInterpolation) { + Value D = Object{{"power", 1.21}}; + auto T = Template::createTemplate("{{power}} jiggawatts!"); + auto Out = T.get().render(D); + EXPECT_EQ("1.21 jiggawatts!", Out); +} + +TEST(MustacheInterpolation, BasicNullInterpolation) { + Value D = Object{{"cannot", nullptr}}; + auto T = Template::createTemplate("I ({{cannot}}) be seen!"); + auto Out = T.get().render(D); + EXPECT_EQ("I () be seen!", Out); +} + +TEST(MustacheInterpolation, BasicContextMissInterpolation) { + Value D = Object{}; + auto T = Template::createTemplate("I ({{cannot}}) be seen!"); + auto Out = T.get().render(D); + EXPECT_EQ("I () be seen!", Out); +} + +TEST(MustacheInterpolation, DottedNamesBasicInterpolation) { + Value D = Object{{"person", Object{{"name", "Joe"; + auto T = Template::createTemplate( + "{{person.name}} == {{#person}}{{name}}{{/person}}"); + auto Out = T.get().render(D); + EXPECT_EQ("Joe == Joe", Out); +} + +TEST(MustacheInterpolation, DottedNamesArbitraryDepth) { + Value D = Object{ + {"a", + Object{{"b", + Object{{"c", + Object{{"d", + Object{{"e", Object{{"name", "Phil"; + auto T = Template::createTemplate("{{a.b.c.d.e.name}} == Phil"); + auto Out = T.get().render(D); + EXPECT_EQ("Phil == Phil", Out); +} + +TEST(MustacheInterpolation, ImplicitIteratorsBasicInterpolation) { + Value D = "world"; + auto T = Template::createTemplate("Hello, {{.}}!\n"); + auto Out = T.get().render(D); + EXPECT_EQ("Hello, world!\n", Out); +} + +TEST(MustacheInterpolation, InterpolationSurroundingWhitespace) { + Value D = Object{{"string", "---"}}; + auto T = Template::createTemplate("| {{string}} |"); + auto Out = T.get().render(D); + EXPECT_EQ("| --- |", Out); +} + +TEST(MustacheInterpolation, InterpolationWithPadding) { + Value D = Object{{"string", "---"}}; + auto T = Template::createTemplate("|{{ string }}|"); + auto Out = T.get().render(D); + EXPECT_EQ("|---|", Out); +} ilovepi wrote: Probably also test some text w/ newlines, and other special characters? Perhaps parameterizing some of the tests would be useful (e.g. test all whitespace by substituting in difference whitespace characters. IIRC the JSON tests have some of these.
[clang-tools-extra] [llvm] [llvm] add support for mustache templating language (PR #105893)
@@ -0,0 +1,276 @@ +//===-- Mustache.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/Support/Mustache.h" +#include "llvm/Support/Error.h" +#include +#include +#include + +using namespace llvm; +using namespace llvm::json; +using namespace llvm::mustache; + +std::string escapeHtml(const std::string &Input) { + DenseMap HtmlEntities = {{'&', "&"}, + {'<', "<"}, + {'>', ">"}, + {'"', """}, + {'"', "'"}}; + std::string EscapedString; + EscapedString.reserve(Input.size()); + + for (char C : Input) { +if (HtmlEntities.find(C) != HtmlEntities.end()) { + EscapedString += HtmlEntities[C]; +} else { + EscapedString += C; +} + } + + return EscapedString; +} + +std::vector split(const std::string &Str, char Delimiter) { + std::vector Tokens; + std::string Token; + std::stringstream SS(Str); + if (Str == ".") { +Tokens.push_back(Str); +return Tokens; + } + while (std::getline(SS, Token, Delimiter)) { +Tokens.push_back(Token); + } + return Tokens; +} + +Token::Token(std::string Str, char Identifier) { + switch (Identifier) { + case '#': +TokenType = Type::SectionOpen; +break; + case '/': +TokenType = Type::SectionClose; +break; + case '^': +TokenType = Type::InvertSectionOpen; +break; + case '!': +TokenType = Type::Comment; +break; + case '>': +TokenType = Type::Partial; +break; + case '&': +TokenType = Type::UnescapeVariable; +break; + default: +TokenType = Type::Variable; + } + if (TokenType == Type::Comment) +return; + + TokenBody = Str; + std::string AccessorStr = Str; + if (TokenType != Type::Variable) { +AccessorStr = Str.substr(1); + } + Accessor = split(StringRef(AccessorStr).trim().str(), '.'); +} + +Token::Token(std::string Str) +: TokenType(Type::Text), TokenBody(Str), Accessor({}) {} + +std::vector tokenize(std::string Template) { + std::vector Tokens; + std::regex Re(R"(\{\{(.*?)\}\})"); + std::sregex_token_iterator Iter(Template.begin(), Template.end(), Re, + {-1, 0}); + std::sregex_token_iterator End; + + for (; Iter != End; ++Iter) { +if (!Iter->str().empty()) { + std::string Token = *Iter; + std::smatch Match; + if (std::regex_match(Token, Match, Re)) { +std::string Group = Match[1]; +Tokens.emplace_back(Group, Group[0]); + } else { +Tokens.emplace_back(Token); + } +} + } + + return Tokens; +} + +class Parser { +public: + Parser(std::string TemplateStr) : TemplateStr(TemplateStr) {} + + std::shared_ptr parse(); + +private: + void parseMustache(std::shared_ptr Parent); + + std::vector Tokens; + std::size_t CurrentPtr; + std::string TemplateStr; +}; + +std::shared_ptr Parser::parse() { + Tokens = tokenize(TemplateStr); + CurrentPtr = 0; + std::shared_ptr Root = std::make_shared(); ilovepi wrote: can these be `unique_ptr`? Do users need the owning reference? https://github.com/llvm/llvm-project/pull/105893 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [llvm] [llvm] add support for mustache templating language (PR #105893)
@@ -0,0 +1,276 @@ +//===-- Mustache.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/Support/Mustache.h" +#include "llvm/Support/Error.h" +#include +#include +#include + +using namespace llvm; +using namespace llvm::json; +using namespace llvm::mustache; + +std::string escapeHtml(const std::string &Input) { + DenseMap HtmlEntities = {{'&', "&"}, + {'<', "<"}, + {'>', ">"}, + {'"', """}, + {'"', "'"}}; + std::string EscapedString; + EscapedString.reserve(Input.size()); + + for (char C : Input) { +if (HtmlEntities.find(C) != HtmlEntities.end()) { + EscapedString += HtmlEntities[C]; +} else { + EscapedString += C; +} + } + + return EscapedString; +} + +std::vector split(const std::string &Str, char Delimiter) { + std::vector Tokens; + std::string Token; + std::stringstream SS(Str); + if (Str == ".") { +Tokens.push_back(Str); +return Tokens; + } + while (std::getline(SS, Token, Delimiter)) { +Tokens.push_back(Token); + } + return Tokens; +} + +Token::Token(std::string Str, char Identifier) { + switch (Identifier) { + case '#': +TokenType = Type::SectionOpen; +break; + case '/': +TokenType = Type::SectionClose; +break; + case '^': +TokenType = Type::InvertSectionOpen; +break; + case '!': +TokenType = Type::Comment; +break; + case '>': +TokenType = Type::Partial; +break; + case '&': +TokenType = Type::UnescapeVariable; +break; + default: +TokenType = Type::Variable; + } + if (TokenType == Type::Comment) +return; + + TokenBody = Str; + std::string AccessorStr = Str; + if (TokenType != Type::Variable) { +AccessorStr = Str.substr(1); + } + Accessor = split(StringRef(AccessorStr).trim().str(), '.'); +} + +Token::Token(std::string Str) +: TokenType(Type::Text), TokenBody(Str), Accessor({}) {} + +std::vector tokenize(std::string Template) { + std::vector Tokens; + std::regex Re(R"(\{\{(.*?)\}\})"); + std::sregex_token_iterator Iter(Template.begin(), Template.end(), Re, + {-1, 0}); + std::sregex_token_iterator End; + + for (; Iter != End; ++Iter) { +if (!Iter->str().empty()) { + std::string Token = *Iter; + std::smatch Match; + if (std::regex_match(Token, Match, Re)) { +std::string Group = Match[1]; +Tokens.emplace_back(Group, Group[0]); + } else { +Tokens.emplace_back(Token); + } +} + } + + return Tokens; +} + +class Parser { +public: + Parser(std::string TemplateStr) : TemplateStr(TemplateStr) {} + + std::shared_ptr parse(); + +private: + void parseMustache(std::shared_ptr Parent); + + std::vector Tokens; + std::size_t CurrentPtr; + std::string TemplateStr; +}; + +std::shared_ptr Parser::parse() { + Tokens = tokenize(TemplateStr); + CurrentPtr = 0; + std::shared_ptr Root = std::make_shared(); + parseMustache(Root); + return Root; +} + +void Parser::parseMustache(std::shared_ptr Parent) { + + while (CurrentPtr < Tokens.size()) { +Token CurrentToken = Tokens[CurrentPtr]; +CurrentPtr++; +Accessor A = CurrentToken.getAccessor(); +std::shared_ptr CurrentNode; + +switch (CurrentToken.getType()) { +case Token::Type::Text: { + CurrentNode = + std::make_shared(CurrentToken.getTokenBody(), Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::Variable: { + CurrentNode = std::make_shared(ASTNode::Variable, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::UnescapeVariable: { + CurrentNode = + std::make_shared(ASTNode::UnescapeVariable, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::Partial: { + CurrentNode = std::make_shared(ASTNode::Partial, A, Parent); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::SectionOpen: { + CurrentNode = std::make_shared(ASTNode::Section, A, Parent); + parseMustache(CurrentNode); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::InvertSectionOpen: { + CurrentNode = + std::make_shared(ASTNode::InvertSection, A, Parent); + parseMustache(CurrentNode); + Parent->addChild(CurrentNode); + break; +} +case Token::Type::SectionClose: { + return; +} +default: + break; +} + } +} + +Expected Template::createTemplate(std::string TemplateStr)
[clang-tools-extra] [llvm] [llvm] add support for mustache templating language (PR #105893)
@@ -0,0 +1,135 @@ +//===- llvm/unittest/Support/MustacheTest.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// Test conforming to Mustache 1.4.2 spec found here: +// https://github.com/mustache/spec +// +//===--===// + +#include "llvm/Support/Mustache.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::mustache; +using namespace llvm::json; + +TEST(MustacheInterpolation, NoInterpolation) { + // Mustache-free templates should render as-is. + Value D = {}; + auto T = Template::createTemplate("Hello from {Mustache}!\n"); + auto Out = T.get().render(D); + EXPECT_EQ("Hello from {Mustache}!\n", Out); +} + +TEST(MustacheInterpolation, BasicInterpolation) { + // Unadorned tags should interpolate content into the template. + Value D = Object{{"subject", "World"}}; + auto T = Template::createTemplate("Hello, {{subject}}!"); + auto Out = T.get().render(D); + EXPECT_EQ("Hello, World!", Out); +} + +TEST(MustacheInterpolation, NoReinterpolation) { + // Interpolated tag output should not be re-interpolated. + Value D = Object{{"template", "{{planet}}"}, {"planet", "Earth"}}; + auto T = Template::createTemplate("{{template}}: {{planet}}"); + auto Out = T.get().render(D); + EXPECT_EQ("{{planet}}: Earth", Out); +} + +TEST(MustacheInterpolation, HTMLEscaping) { + // Interpolated tag output should not be re-interpolated. + Value D = Object{ + {"forbidden", "& \" < >"}, + }; + auto T = Template::createTemplate( + "These characters should be HTML escaped: {{forbidden}}\n"); + auto Out = T.get().render(D); + EXPECT_EQ("These characters should be HTML escaped: & " < >\n", +Out); +} + +TEST(MustacheInterpolation, Ampersand) { + // Interpolated tag output should not be re-interpolated. + Value D = Object{ + {"forbidden", "& \" < >"}, + }; + auto T = Template::createTemplate( + "These characters should not be HTML escaped: {{&forbidden}}\n"); + auto Out = T.get().render(D); + EXPECT_EQ("These characters should not be HTML escaped: & \" < >\n", Out); +} + +TEST(MustacheInterpolation, BasicIntegerInterpolation) { + Value D = Object{{"mph", 85}}; + auto T = Template::createTemplate("{{mph}} miles an hour!"); + auto Out = T.get().render(D); + EXPECT_EQ("85 miles an hour!", Out); +} + +TEST(MustacheInterpolation, BasicDecimalInterpolation) { + Value D = Object{{"power", 1.21}}; + auto T = Template::createTemplate("{{power}} jiggawatts!"); + auto Out = T.get().render(D); + EXPECT_EQ("1.21 jiggawatts!", Out); +} + +TEST(MustacheInterpolation, BasicNullInterpolation) { + Value D = Object{{"cannot", nullptr}}; + auto T = Template::createTemplate("I ({{cannot}}) be seen!"); + auto Out = T.get().render(D); + EXPECT_EQ("I () be seen!", Out); +} + +TEST(MustacheInterpolation, BasicContextMissInterpolation) { + Value D = Object{}; + auto T = Template::createTemplate("I ({{cannot}}) be seen!"); + auto Out = T.get().render(D); + EXPECT_EQ("I () be seen!", Out); +} + +TEST(MustacheInterpolation, DottedNamesBasicInterpolation) { + Value D = Object{{"person", Object{{"name", "Joe"; + auto T = Template::createTemplate( + "{{person.name}} == {{#person}}{{name}}{{/person}}"); + auto Out = T.get().render(D); + EXPECT_EQ("Joe == Joe", Out); +} + +TEST(MustacheInterpolation, DottedNamesArbitraryDepth) { + Value D = Object{ + {"a", + Object{{"b", + Object{{"c", + Object{{"d", + Object{{"e", Object{{"name", "Phil"; + auto T = Template::createTemplate("{{a.b.c.d.e.name}} == Phil"); + auto Out = T.get().render(D); + EXPECT_EQ("Phil == Phil", Out); ilovepi wrote: I don't think you need the `== Phil` bits, do you? It seems redundant, since you just want it to match, right? https://github.com/llvm/llvm-project/pull/105893 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][HLSL] Update DXIL/SPIRV hybird CodeGen tests to use temp var (PR #105930)
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/105930 >From 452073564bd2e5c43b7a485db2fdf1652aa3da1f Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sat, 24 Aug 2024 10:08:23 +0200 Subject: [PATCH] [clang][HLSL] Update DXIL/SPIRV hybird CodeGen tests to use temp var Update all hybird DXIL/SPIRV codegen tests to use temp variable representing interchange target --- .../builtins/RWBuffer-constructor.hlsl| 10 +- clang/test/CodeGenHLSL/builtins/all.hlsl | 134 ++ clang/test/CodeGenHLSL/builtins/any.hlsl | 134 ++ clang/test/CodeGenHLSL/builtins/frac.hlsl | 38 ++--- clang/test/CodeGenHLSL/builtins/lerp.hlsl | 56 +++- clang/test/CodeGenHLSL/builtins/mad.hlsl | 16 +-- .../test/CodeGenHLSL/builtins/normalize.hlsl | 39 ++--- clang/test/CodeGenHLSL/builtins/rsqrt.hlsl| 38 ++--- .../semantics/DispatchThreadID.hlsl | 10 +- 9 files changed, 173 insertions(+), 302 deletions(-) diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl index e51eac7f57c2d3..e3fa0d2c3083fd 100644 --- a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl @@ -1,12 +1,12 @@ -// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-SPIRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=DXCHECK + +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=SPVCHECK RWBuffer Buf; // CHECK: define linkonce_odr noundef ptr @"??0?$RWBuffer@M@hlsl@@QAA@XZ" // CHECK-NEXT: entry: -// CHECK: %[[HandleRes:[0-9]+]] = call ptr @llvm.dx.create.handle(i8 1) +// DXCHECK: %[[HandleRes:[0-9]+]] = call ptr @llvm.dx.create.handle(i8 1) +// SPVCHECK: %[[HandleRes:[0-9]+]] = call ptr @llvm.spv.create.handle(i8 1) // CHECK: store ptr %[[HandleRes]], ptr %h, align 4 - -// CHECK-SPIRV: %[[HandleRes:[0-9]+]] = call ptr @llvm.spv.create.handle(i8 1) -// CHECK-SPIRV: store ptr %[[HandleRes]], ptr %h, align 8 diff --git a/clang/test/CodeGenHLSL/builtins/all.hlsl b/clang/test/CodeGenHLSL/builtins/all.hlsl index b48daa287480ff..f431aa8eb692dd 100644 --- a/clang/test/CodeGenHLSL/builtins/all.hlsl +++ b/clang/test/CodeGenHLSL/builtins/all.hlsl @@ -16,262 +16,220 @@ #ifdef __HLSL_ENABLE_16_BIT // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.i16 +// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF:dx]].all.i16 +// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF:spv]].all.i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t(int16_t p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v2i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v2i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v2i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t2(int16_t2 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v3i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v3i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v3i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t3(int16_t3 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v4i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v4i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v4i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_int16_t4(int16_t4 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_uint16_t(uint16_t p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all = call i1 @llvm.dx.all.v2i16 -// SPIR_NATIVE_HALF: %hlsl.all = call i1 @llvm.spv.all.v2i16 +// NATIVE_HALF: %hlsl.all = call i1 @llvm.[[ICF]].all.v2i16 // NATIVE_HALF: ret i1 %hlsl.all bool test_all_uint16_t2(uint16_t2 p0) { return all(p0); } // DXIL_NATIVE_HALF: define noundef i1 @ // SPIR_NATIVE_HALF: define spir_func noundef i1 @ -// DXIL_NATIVE_HALF: %hlsl.all
[clang] [clang][AArch64] Add SME2.1 feature macros (PR #105657)
https://github.com/sdesmalen-arm milestoned https://github.com/llvm/llvm-project/pull/105657 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add tests for CWG issues about friend declaration matching (PR #106117)
cor3ntin wrote: I think both CWG1900 and CW1477 can be marked as implemented with such a test ```cpp namespace N { struct A { friend int f(); }; } int N::f() { return 0; } int N::g() { return 0; } // expected-error@-1 {{out-of-line definition of 'g' does not match any declaration in namespace 'N'}}``` Resolved by https://eel.is/c++draft/dcl.meaning#general-3.4.sentence-2 added by p1787r6 https://github.com/llvm/llvm-project/pull/106117 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add tests for CWG issues about friend declaration matching (PR #106117)
@@ -568,6 +568,80 @@ namespace cwg137 { // cwg137: yes const volatile int *cvqcv = static_cast(cvp); } +namespace cwg138 { // cwg138: partial +namespace example1 { +void foo(); // #cwg138-ex1-foo +namespace A { + using example1::foo; // #cwg138-ex1-using + class X { +static const int i = 10; +// This friend declaration is using neither qualified-id nor template-id, +// so name 'foo' is not looked up, which means the using-declaration has no effect. +// Target scope of this declaration is A, so this is grating friendship to +// (hypothetical) A::foo instead of 'example1::foo' using declaration refers to. +// A::foo corresponds to example1::foo named by the using declaration, +// and since A::foo is a different entity, they potentially conflict. +// FIXME: This is ill-formed, but not for the reason diagnostic says. +friend void foo(); +// expected-error@-1 {{cannot befriend target of using declaration}} +// expected-note@#cwg138-ex1-foo {{target of using declaration}} +// expected-note@#cwg138-ex1-using {{using declaration}} cor3ntin wrote: Do you want to try to fix this one? https://github.com/llvm/llvm-project/pull/106117 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add tests for CWG issues about friend declaration matching (PR #106117)
@@ -1369,6 +1369,75 @@ namespace cwg385 { // cwg385: 2.8 // expected-note@#cwg385-n {{member is declared here}} } +namespace cwg386 { // cwg386: no +namespace example1 { +namespace N1 { +// Binds name 'f' in N1. Target scope is N1. +template void f( T* x ) { + // ... other stuff ... + delete x; +} +} + +namespace N2 { +// Bind name 'f' in N2. When a single search find this declaration, +// it's replaced with N1::f declaration. +using N1::f; + +// `f` is not a qualified-id, so its target scope is N2. +// `f` is a template-id, so 'f' undergoes (unqualified) lookup. +// Search performed by unqualified lookup finds N1::f via using-declaration, +// but this result is not considered, because it's not nominable in N2, +// which is because its target scope is N1. +// So unqualified lookup doesn't find anything, making this declaration ill-formed. +template<> void f( int* ); +// expected-error@-1 {{no function template matches function template specialization 'f'}} + +class Test { + ~Test() { } + // `f<>` is a template-id and not a template declaration, + // so its terminal name 'f' undergoes (unqualified) lookup. + // Search in N2 performed by unqualified lookup finds + // (single) N1::f declaration via using-declaration. + // N1::f is replaced with N1::f<> specialization after deduction, + // and this is the result of the unqualified lookup. + // This friend declaration correspond to the result of the lookup. + // All lookup results target the same scope, which is N1, + // so target scope of this friend declaration is also N1. + // FIXME: This is well-formed. + friend void f<>( Test* x ); + // expected-error@-1 {{no function template matches function template specialization 'f'}} cor3ntin wrote: Interestingly, it's confused by the namespaces - or more likely, the using declarations https://compiler-explorer.com/z/oP6Er4e4j https://github.com/llvm/llvm-project/pull/106117 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Use the correct lookup context when building overloaded 'operator->' in the current instantiation (PR #104458)
cor3ntin wrote: I think there won't be a rc4 so it's actually probably too late (@tobias) - but presumably there will be a `19.0.2` version a couple of weeks after release. So ~2 or 3 weeks? https://github.com/llvm/llvm-project/pull/104458 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AArch64] Add SME2.1 feature macros (PR #105657)
sdesmalen-arm wrote: /cherry-pick 2617023923175b0fd2a8cb94ad677c061c01627f https://github.com/llvm/llvm-project/pull/105657 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AArch64] Add SME2.1 feature macros (PR #105657)
llvmbot wrote: /pull-request llvm/llvm-project#106135 https://github.com/llvm/llvm-project/pull/105657 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [docs] Document the missing Apple availability platforms (PR #104653)
@@ -1637,31 +1637,42 @@ specifies availability for the current target platform, the availability attributes are ignored. Supported platforms are: ``ios`` +``ios_app_extension`` ian-twilightcoder wrote: I actually feel like these don't need descriptions and we don't need to explain how client code sets its deployment target. I think less is more and let's just list the allowed platforms? https://github.com/llvm/llvm-project/pull/104653 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][test] Rewrote test using $() to work with lit internal shell syntax (PR #105902)
https://github.com/connieyzhu edited https://github.com/llvm/llvm-project/pull/105902 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c821cc3 - [Clang] Correctly finds subexpressions of immediate invocations (#106055)
Author: cor3ntin Date: 2024-08-26T22:55:32+02:00 New Revision: c821cc3f8824e29ba1861fb1de43e90543928498 URL: https://github.com/llvm/llvm-project/commit/c821cc3f8824e29ba1861fb1de43e90543928498 DIFF: https://github.com/llvm/llvm-project/commit/c821cc3f8824e29ba1861fb1de43e90543928498.diff LOG: [Clang] Correctly finds subexpressions of immediate invocations (#106055) We were not correctly ignoring implicit casts. Fixes #105558 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaExpr.cpp clang/test/AST/ByteCode/new-delete.cpp clang/test/SemaCXX/cxx2a-consteval.cpp Removed: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 0a31953ab87005..2c29d49ba20f03 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -317,7 +317,7 @@ Bug Fixes to C++ Support - Clang now rebuilds the template parameters of out-of-line declarations and specializations in the context of the current instantiation in all cases. - Fix evaluation of the index of dependent pack indexing expressions/types specifiers (#GH105900) - +- Correctly handle subexpressions of an immediate invocation in the presence of implicit casts. (#GH105558) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ea57316ad8014e..95f53dfefbcc52 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -17463,11 +17463,22 @@ static void RemoveNestedImmediateInvocation( ExprResult TransformInitializer(Expr *Init, bool NotCopyInit) { if (!Init) return Init; + + // We cannot use IgnoreImpCasts because we need to preserve + // full expressions. + while (true) { +if (auto *ICE = dyn_cast(Init)) + Init = ICE->getSubExpr(); +else if (auto *ICE = dyn_cast(Init)) + Init = ICE->getSubExpr(); +else + break; + } /// ConstantExpr are the first layer of implicit node to be removed so if /// Init isn't a ConstantExpr, no ConstantExpr will be skipped. - if (auto *CE = dyn_cast(Init)) -if (CE->isImmediateInvocation()) - RemoveImmediateInvocation(CE); + if (auto *CE = dyn_cast(Init); + CE && CE->isImmediateInvocation()) +RemoveImmediateInvocation(CE); return Base::TransformInitializer(Init, NotCopyInit); } ExprResult TransformDeclRefExpr(DeclRefExpr *E) { diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp index a7be4102fd0a05..d733e3182fd59c 100644 --- a/clang/test/AST/ByteCode/new-delete.cpp +++ b/clang/test/AST/ByteCode/new-delete.cpp @@ -404,7 +404,7 @@ constexpr typename std::remove_reference::type&& move(T &&t) noexcept { namespace cxx2a { struct A { - int* p = new int(42); // both-note 7{{heap allocation performed here}} + int* p = new int(42); // both-note 3{{heap allocation performed here}} consteval int ret_i() const { return p ? *p : 0; } consteval A ret_a() const { return A{}; } constexpr ~A() { delete p; } @@ -433,9 +433,7 @@ void test() { { A k = to_lvalue_ref(A()); } // both-error {{'cxx2a::to_lvalue_ref' is not a constant expression}} \ // both-note {{reference to temporary is not a constant expression}} \ // both-note {{temporary created here}} - { A k = to_lvalue_ref(A().ret_a()); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \ -// both-note {{heap-allocated object is not a constant expression}} \ -// both-error {{'cxx2a::to_lvalue_ref' is not a constant expression}} \ + { A k = to_lvalue_ref(A().ret_a()); } // both-error {{'cxx2a::to_lvalue_ref' is not a constant expression}} \ // both-note {{reference to temporary is not a constant expression}} \ // both-note {{temporary created here}} { int k = A().ret_a().ret_i(); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \ @@ -445,19 +443,15 @@ void test() { { int k = const_a_ref(a); } { int k = rvalue_ref(A()); } { int k = rvalue_ref(std::move(a)); } - { int k = const_a_ref(A().ret_a()); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \ -// both-note {{is not a constant expression}} - { int k = const_a_ref(to_lvalue_ref(A().ret_a())); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \ - // both-note {{is not a constant expression}} + { int k = const_a_ref(A().ret_a()); } + { int k = const_a_ref(to_lvalue_ref(A().ret_a())); } { int k = const_a_ref(to_lvalue_ref(std::move(a))); } { int
[clang] [Clang] Correctly finds subexpressions of immediate invocations (PR #106055)
https://github.com/cor3ntin closed https://github.com/llvm/llvm-project/pull/106055 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Correctly finds subexpressions of immediate invocations (PR #106055)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `openmp-offload-amdgpu-runtime` running on `omp-vega20-0` while building `clang` at step 6 "test-openmp". Full details are available at: https://lab.llvm.org/buildbot/#/builders/30/builds/4816 Here is the relevant piece of the build log for the reference ``` Step 6 (test-openmp) failure: test (failure) TEST 'libomp :: tasking/issue-94260-2.c' FAILED Exit Code: -11 Command Output (stdout): -- # RUN: at line 1 /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/clang -fopenmp -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/openmp/runtime/test -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -fno-omit-frame-pointer -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/openmp/runtime/test/ompt /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/openmp/runtime/test/tasking/issue-94260-2.c -o /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/test/tasking/Output/issue-94260-2.c.tmp -lm -latomic && /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/test/tasking/Output/issue-94260-2.c.tmp # executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/clang -fopenmp -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/openmp/runtime/test -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -fno-omit-frame-pointer -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/openmp/runtime/test/ompt /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/openmp/runtime/test/tasking/issue-94260-2.c -o /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/test/tasking/Output/issue-94260-2.c.tmp -lm -latomic # note: command had no output on stdout or stderr # executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/test/tasking/Output/issue-94260-2.c.tmp # note: command had no output on stdout or stderr # error: command failed with exit status: -11 -- ``` https://github.com/llvm/llvm-project/pull/106055 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] restrict use of attribute names reserved by the C++ standard (PR #106036)
@@ -177,6 +177,26 @@ static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, return false; } +static bool isReservedAttrName(Preprocessor &PP, IdentifierInfo *II) { Sirraide wrote: > The > [Attr.td](https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/Attr.td) > file contain some details about attributes. I'm uncertain whether this file > is sufficient for our case or if we need to define a new one... >From what I can tell, you’ll have to extend ClangAttrEmitter and introduce a >new flag in `Attr.td` that is set for every standard C++ attribute (e.g. >`CXX11NoReturn`, but not `C11NoReturn` or `NoReturn`). https://github.com/llvm/llvm-project/pull/106036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [docs] Document the missing Apple availability platforms (PR #104653)
https://github.com/ian-twilightcoder updated https://github.com/llvm/llvm-project/pull/104653 >From e908672f2f9c3a8995dcc7c50fe1fb72fdd467e9 Mon Sep 17 00:00:00 2001 From: Ian Anderson Date: Fri, 16 Aug 2024 17:32:29 -0700 Subject: [PATCH] [docs] Document the missing availability platforms and environments Update the availability attribute documentation to include all of the missing platforms, and add in the environments. --- clang/include/clang/Basic/AttrDocs.td | 80 +-- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index df36a2163b9f0b..dbb6033aafd22e 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -1636,41 +1636,61 @@ the implicitly inferred availability attributes. If no availability attribute specifies availability for the current target platform, the availability attributes are ignored. Supported platforms are: -``ios`` - Apple's iOS operating system. The minimum deployment target is specified - as part of the ``-target *arch*-apple-ios*version*`` command line argument. - Alternatively, it can be specified by the ``-mtargetos=ios*version*`` - command-line argument. +``iOS`` +``macOS`` +``tvOS`` +``watchOS`` +``iOSApplicationExtension`` +``macOSApplicationExtension`` +``tvOSApplicationExtension`` +``watchOSApplicationExtension`` +``macCatalyst`` +``macCatalystApplicationExtension`` +``visionOS`` +``visionOSApplicationExtension`` +``driverkit`` +``swift`` +``android`` +``fuchsia`` +``ohos`` +``zos`` +``ShaderModel`` -``macos`` - Apple's macOS operating system. The minimum deployment target is specified - as part of the ``-target *arch*-apple-macos*version*`` command line argument. - Alternatively, it can be specified by the ``-mtargetos=macos*version*`` - command-line argument. ``macosx`` is supported for - backward-compatibility reasons, but it is deprecated. +Some platforms have alias names: +``ios`` +``macos`` +``macosx (deprecated)`` ``tvos`` - Apple's tvOS operating system. The minimum deployment target is specified - as part of the ``-target *arch*-apple-tvos*version*`` command line argument. - Alternatively, it can be specified by the ``-mtargetos=tvos*version*`` - command-line argument. - ``watchos`` - Apple's watchOS operating system. The minimum deployment target is specified - as part of the ``-target *arch*-apple-watchos*version*`` command line argument. - Alternatively, it can be specified by the ``-mtargetos=watchos*version*`` - command-line argument. - +``ios_app_extension`` +``macos_app_extension`` +``macosx_app_extension (deprecated)`` +``tvos_app_extension`` +``watchos_app_extension`` +``maccatalyst`` +``maccatalyst_app_extension`` ``visionos`` - Apple's visionOS operating system. The minimum deployment target is specified - as part of the ``-target *arch*-apple-visionos*version*`` command line argument. - Alternatively, it can be specified by the ``-mtargetos=visionos*version*`` - command-line argument. - -``driverkit`` - Apple's DriverKit userspace kernel extensions. The minimum deployment target - is specified as part of the ``-target *arch*-apple-driverkit*version*`` - command line argument. +``visionos_app_extension`` +``shadermodel`` + +Supported environment names: + +``pixel`` +``vertex`` +``geometry`` +``hull`` +``domain`` +``compute`` +``raygeneration`` +``intersection`` +``anyhit`` +``closesthit`` +``miss`` +``callable`` +``mesh`` +``amplification`` +``library`` A declaration can typically be used even when deploying back to a platform version prior to when the declaration was introduced. When this happens, the ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] restrict use of attribute names reserved by the C++ standard (PR #106036)
@@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx11 -pedantic -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx14 -pedantic -std=c++14 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -pedantic -std=c++17 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx20 -pedantic -std=c++20 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx23 -pedantic -std=c++23 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx26 -pedantic -std=c++26 %s + +#define noreturn 1 // cxx11-warning {{keyword is hidden by macro definition}} +#undef noreturn + +#define carries_dependency 1 // cxx11-warning {{keyword is hidden by macro definition}} +#undef carries_dependency + +#define deprecated 1 // cxx14-warning {{keyword is hidden by macro definition}} +#undef deprecated + +#define fallthrough 1// cxx17-warning {{keyword is hidden by macro definition}} +#undef fallthrough + +#define maybe_unused 1 // cxx17-warning {{keyword is hidden by macro definition}} +#undef maybe_unused + +#define nodiscard 1 // cxx17-warning {{keyword is hidden by macro definition}} +#undef nodiscard + +#define no_unique_address 1 // cxx20-warning {{keyword is hidden by macro definition}} +#undef no_unique_address + +#define assume 1 // cxx23-warning {{keyword is hidden by macro definition}} +#undef assume + +#define indeterminate 1 // cxx26-warning {{keyword is hidden by macro definition}} +#undef indeterminate Sirraide wrote: Test cases for some of the others defined as function-like macros would be nice too, which we should diagnose (except for `likely` and `unlikely` ofc). https://github.com/llvm/llvm-project/pull/106036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [docs] Document the missing Apple availability platforms (PR #104653)
https://github.com/ian-twilightcoder edited https://github.com/llvm/llvm-project/pull/104653 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [docs] Document the missing availability platforms and environments (PR #104653)
https://github.com/ian-twilightcoder edited https://github.com/llvm/llvm-project/pull/104653 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Fix diagnostic for function overloading in extern "C" (PR #106033)
https://github.com/Sirraide approved this pull request. LGTM Thanks for the patch! I’ll merge once CI is done with this. https://github.com/llvm/llvm-project/pull/106033 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add tests for CWG issues about friend declaration matching (PR #106117)
https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/106117 >From 65307bd2f5f8ca5c6aaa24335c77a63280d668e3 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Mon, 26 Aug 2024 20:45:31 +0300 Subject: [PATCH 1/2] [clang] Add tests for CWG issues about friend declaration matching --- clang/test/CXX/drs/cwg14xx.cpp | 19 + clang/test/CXX/drs/cwg1xx.cpp | 74 ++ clang/test/CXX/drs/cwg3xx.cpp | 69 +++ 3 files changed, 162 insertions(+) diff --git a/clang/test/CXX/drs/cwg14xx.cpp b/clang/test/CXX/drs/cwg14xx.cpp index a23ac744436331..1240c416451b8f 100644 --- a/clang/test/CXX/drs/cwg14xx.cpp +++ b/clang/test/CXX/drs/cwg14xx.cpp @@ -603,6 +603,25 @@ namespace cwg1467 { // cwg1467: 3.7 c++11 #endif } // cwg1467 +namespace cwg1477 { // cwg1477: 2.7 +namespace N { +struct A { + // Name "f" is not bound in N, + // so single searches of 'f' in N won't find it, + // but the targets scope of this declaration is N, + // making it nominable in N. + friend int f(); +}; +} +// Corresponds to the friend declaration, +// because it's nominable in N, +// and binds name 'f' in N. +int N::f() { return 0; } +// Name 'f' is bound in N, +// so the search performed by qualified lookup finds it. +int i = N::f(); +} // namespace cwg1477 + namespace cwg1479 { // cwg1479: 3.1 #if __cplusplus >= 201103L int operator"" _a(const char*, std::size_t = 0); diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp index e71ea9278f..d6ee0844458b1d 100644 --- a/clang/test/CXX/drs/cwg1xx.cpp +++ b/clang/test/CXX/drs/cwg1xx.cpp @@ -568,6 +568,80 @@ namespace cwg137 { // cwg137: yes const volatile int *cvqcv = static_cast(cvp); } +namespace cwg138 { // cwg138: partial +namespace example1 { +void foo(); // #cwg138-ex1-foo +namespace A { + using example1::foo; // #cwg138-ex1-using + class X { +static const int i = 10; +// This friend declaration is using neither qualified-id nor template-id, +// so name 'foo' is not looked up, which means the using-declaration has no effect. +// Target scope of this declaration is A, so this is grating friendship to +// (hypothetical) A::foo instead of 'example1::foo' using declaration refers to. +// A::foo corresponds to example1::foo named by the using declaration, +// and since A::foo is a different entity, they potentially conflict. +// FIXME: This is ill-formed, but not for the reason diagnostic says. +friend void foo(); +// expected-error@-1 {{cannot befriend target of using declaration}} +// expected-note@#cwg138-ex1-foo {{target of using declaration}} +// expected-note@#cwg138-ex1-using {{using declaration}} + }; +} +} // namespace example1 + +namespace example2 { +void f(); +void g(); +class B { + void g(); +}; +class A : public B { + static const int i = 10; + void f(); + // Both friend declaration are not using qualified-ids or template-ids, + // so 'f' and 'g' are not looked up, which means that presence of A::f + // and base B have no effect. + // Both target scope of namespace 'example2', and grant friendship to + // example2::f and example2::g respectively. + friend void f(); + friend void g(); +}; +void f() { + int i2 = A::i; +} +void g() { + int i3 = A::i; +} +} // namespace example2 + +namespace example3 { +struct Base { +private: + static const int i = 10; // #cwg138-ex3-Base-i + +public: + struct Data; + // Elaborated type specifier is not the sole constituent of declaration, + // so 'Data' undergoes unqualified type-only lookup, which finds Base::Data. + friend class Data; + + struct Data { +void f() { + int i2 = Base::i; +} + }; +}; +struct Data { + void f() { +int i2 = Base::i; +// expected-error@-1 {{'i' is a private member of 'cwg138::example3::Base'}} +// expected-note@#cwg138-ex3-Base-i {{declared private here}} + } +}; +} // namespace example3 +} // namespace cwg138 + namespace cwg139 { // cwg139: yes namespace example1 { typedef int f; // #cwg139-typedef-f diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp index a10ed95941ba4a..44bf974ef66649 100644 --- a/clang/test/CXX/drs/cwg3xx.cpp +++ b/clang/test/CXX/drs/cwg3xx.cpp @@ -1369,6 +1369,75 @@ namespace cwg385 { // cwg385: 2.8 // expected-note@#cwg385-n {{member is declared here}} } +namespace cwg386 { // cwg386: no +namespace example1 { +namespace N1 { +// Binds name 'f' in N1. Target scope is N1. +template void f( T* x ) { + // ... other stuff ... + delete x; +} +} + +namespace N2 { +// Bind name 'f' in N2. When a single search find this declaration, +// it's replaced with N1::f declaration. +using N1::f; + +// `f` is not a qualified-id, so its target scope is N2. +// `f` is a template-id, so 'f' undergoes (unqualified) lookup. +// Search performed by unqualified lookup finds N1::f via using-declaration, +// but this result is not considered
[clang] [clang] Add tests for CWG issues about friend declaration matching (PR #106117)
https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/106117 >From 65307bd2f5f8ca5c6aaa24335c77a63280d668e3 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Mon, 26 Aug 2024 20:45:31 +0300 Subject: [PATCH 1/3] [clang] Add tests for CWG issues about friend declaration matching --- clang/test/CXX/drs/cwg14xx.cpp | 19 + clang/test/CXX/drs/cwg1xx.cpp | 74 ++ clang/test/CXX/drs/cwg3xx.cpp | 69 +++ 3 files changed, 162 insertions(+) diff --git a/clang/test/CXX/drs/cwg14xx.cpp b/clang/test/CXX/drs/cwg14xx.cpp index a23ac744436331..1240c416451b8f 100644 --- a/clang/test/CXX/drs/cwg14xx.cpp +++ b/clang/test/CXX/drs/cwg14xx.cpp @@ -603,6 +603,25 @@ namespace cwg1467 { // cwg1467: 3.7 c++11 #endif } // cwg1467 +namespace cwg1477 { // cwg1477: 2.7 +namespace N { +struct A { + // Name "f" is not bound in N, + // so single searches of 'f' in N won't find it, + // but the targets scope of this declaration is N, + // making it nominable in N. + friend int f(); +}; +} +// Corresponds to the friend declaration, +// because it's nominable in N, +// and binds name 'f' in N. +int N::f() { return 0; } +// Name 'f' is bound in N, +// so the search performed by qualified lookup finds it. +int i = N::f(); +} // namespace cwg1477 + namespace cwg1479 { // cwg1479: 3.1 #if __cplusplus >= 201103L int operator"" _a(const char*, std::size_t = 0); diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp index e71ea9278f..d6ee0844458b1d 100644 --- a/clang/test/CXX/drs/cwg1xx.cpp +++ b/clang/test/CXX/drs/cwg1xx.cpp @@ -568,6 +568,80 @@ namespace cwg137 { // cwg137: yes const volatile int *cvqcv = static_cast(cvp); } +namespace cwg138 { // cwg138: partial +namespace example1 { +void foo(); // #cwg138-ex1-foo +namespace A { + using example1::foo; // #cwg138-ex1-using + class X { +static const int i = 10; +// This friend declaration is using neither qualified-id nor template-id, +// so name 'foo' is not looked up, which means the using-declaration has no effect. +// Target scope of this declaration is A, so this is grating friendship to +// (hypothetical) A::foo instead of 'example1::foo' using declaration refers to. +// A::foo corresponds to example1::foo named by the using declaration, +// and since A::foo is a different entity, they potentially conflict. +// FIXME: This is ill-formed, but not for the reason diagnostic says. +friend void foo(); +// expected-error@-1 {{cannot befriend target of using declaration}} +// expected-note@#cwg138-ex1-foo {{target of using declaration}} +// expected-note@#cwg138-ex1-using {{using declaration}} + }; +} +} // namespace example1 + +namespace example2 { +void f(); +void g(); +class B { + void g(); +}; +class A : public B { + static const int i = 10; + void f(); + // Both friend declaration are not using qualified-ids or template-ids, + // so 'f' and 'g' are not looked up, which means that presence of A::f + // and base B have no effect. + // Both target scope of namespace 'example2', and grant friendship to + // example2::f and example2::g respectively. + friend void f(); + friend void g(); +}; +void f() { + int i2 = A::i; +} +void g() { + int i3 = A::i; +} +} // namespace example2 + +namespace example3 { +struct Base { +private: + static const int i = 10; // #cwg138-ex3-Base-i + +public: + struct Data; + // Elaborated type specifier is not the sole constituent of declaration, + // so 'Data' undergoes unqualified type-only lookup, which finds Base::Data. + friend class Data; + + struct Data { +void f() { + int i2 = Base::i; +} + }; +}; +struct Data { + void f() { +int i2 = Base::i; +// expected-error@-1 {{'i' is a private member of 'cwg138::example3::Base'}} +// expected-note@#cwg138-ex3-Base-i {{declared private here}} + } +}; +} // namespace example3 +} // namespace cwg138 + namespace cwg139 { // cwg139: yes namespace example1 { typedef int f; // #cwg139-typedef-f diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp index a10ed95941ba4a..44bf974ef66649 100644 --- a/clang/test/CXX/drs/cwg3xx.cpp +++ b/clang/test/CXX/drs/cwg3xx.cpp @@ -1369,6 +1369,75 @@ namespace cwg385 { // cwg385: 2.8 // expected-note@#cwg385-n {{member is declared here}} } +namespace cwg386 { // cwg386: no +namespace example1 { +namespace N1 { +// Binds name 'f' in N1. Target scope is N1. +template void f( T* x ) { + // ... other stuff ... + delete x; +} +} + +namespace N2 { +// Bind name 'f' in N2. When a single search find this declaration, +// it's replaced with N1::f declaration. +using N1::f; + +// `f` is not a qualified-id, so its target scope is N2. +// `f` is a template-id, so 'f' undergoes (unqualified) lookup. +// Search performed by unqualified lookup finds N1::f via using-declaration, +// but this result is not considered
[clang-tools-extra] [clang-tidy] Use upper case letters for bool conversion suffix (PR #104882)
Da-Viper wrote: > @Da-Viper I believe there's some merge conflicts to fix before being able to > merge :) rebased https://github.com/llvm/llvm-project/pull/104882 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add new option: WrapNamespaceBodyWithNewlines (PR #106145)
https://github.com/dmasloff created https://github.com/llvm/llvm-project/pull/106145 I would like to suggest a new clang-format option for llvm-project - WrapNamespaceBodyWithNewlines. I think it can be added to upstream since it is used by many popular public repositories, for example, [ytsaurus](https://github.com/ytsaurus/ytsaurus/). You can look through their style guide at this page: https://github.com/ytsaurus/ytsaurus/blob/main/yt/styleguide/cpp.md#namespaces As you can see from the name of the option it wraps the body of namespace with additional newlines turning this code: ``` namespace N { int function(); } ``` into that: ``` namespace N { int function(); } ``` Looking forward to your advices and recommendations >From 84ba9930e4650319265b2fabd2715268a91de614 Mon Sep 17 00:00:00 2001 From: dmasloff Date: Mon, 26 Aug 2024 22:11:05 +0300 Subject: [PATCH] [clang-format] Add new option: WrapNamespaceBodyWithNewlines --- clang/docs/ClangFormatStyleOptions.rst | 17 + clang/include/clang/Format/Format.h | 18 - clang/lib/Format/Format.cpp | 3 + clang/lib/Format/UnwrappedLineFormatter.cpp | 30 + clang/unittests/Format/FormatTest.cpp | 73 + 5 files changed, 140 insertions(+), 1 deletion(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index a427d7cd40fcdd..140787ad9776d9 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -6652,6 +6652,23 @@ the configuration (without a prefix: ``Auto``). For example: BOOST_PP_STRINGIZE +.. _WrapNamespaceBodyWithNewlines: + +**WrapNamespaceBodyWithNewlines** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ ` + Insert a newline at the begging and at the end of namespace definition + + .. code-block:: c++ + +false: vs. true: + +namespace a { namespace a { +namespace b { namespace b { + function(); +} function(); +} + } + } + .. END_FORMAT_STYLE_OPTIONS Adding additional style options diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index d8b62c7652a0f6..eb8f198cc8a919 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -5057,6 +5057,21 @@ struct FormatStyle { /// \version 11 std::vector WhitespaceSensitiveMacros; + /// Insert a newline at the begging and at the end of namespace definition + /// \code + /// false: vs. true: + /// + /// namespace a { namespace a { + /// namespace b { namespace b { + /// function(); + /// } function(); + /// } + /// } + /// } + /// \endcode + /// \version 19 + bool WrapNamespaceBodyWithNewlines; + bool operator==(const FormatStyle &R) const { return AccessModifierOffset == R.AccessModifierOffset && AlignAfterOpenBracket == R.AlignAfterOpenBracket && @@ -5234,7 +5249,8 @@ struct FormatStyle { TypenameMacros == R.TypenameMacros && UseTab == R.UseTab && VerilogBreakBetweenInstancePorts == R.VerilogBreakBetweenInstancePorts && - WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros; + WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros && + WrapNamespaceBodyWithNewlines == R.WrapNamespaceBodyWithNewlines; } std::optional GetLanguageStyle(LanguageKind Language) const; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index d2463b892fbb96..65d7737b397212 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1154,6 +1154,8 @@ template <> struct MappingTraits { Style.VerilogBreakBetweenInstancePorts); IO.mapOptional("WhitespaceSensitiveMacros", Style.WhitespaceSensitiveMacros); +IO.mapOptional("WrapNamespaceBodyWithNewlines", + Style.WrapNamespaceBodyWithNewlines); // If AlwaysBreakAfterDefinitionReturnType was specified but // BreakAfterReturnType was not, initialize the latter from the former for @@ -1623,6 +1625,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.WhitespaceSensitiveMacros.push_back("NS_SWIFT_NAME"); LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE"); LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE"); + LLVMStyle.WrapNamespaceBodyWithNewlines = false; LLVMStyle.PenaltyBreakAssignment = prec::Assignment; LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19; diff --git a/clan