[clang] [llvm] [mlir] [MLIR] Add f8E4M3 IEEE 754 type (PR #97118)
@@ -460,10 +460,10 @@ class alignas(void *) Stmt { unsigned : NumExprBits; static_assert( -llvm::APFloat::S_MaxSemantics < 16, -"Too many Semantics enum values to fit in bitfield of size 4"); +llvm::APFloat::S_MaxSemantics < 32, +"Too many Semantics enum values to fit in bitfield of size 5"); LLVM_PREFERRED_TYPE(llvm::APFloat::Semantics) -unsigned Semantics : 4; // Provides semantics for APFloat construction apivovarov wrote: This code is from [PR-97179](https://github.com/llvm/llvm-project/pull/97179). Need to use one additional byte to store new item with id 16 (total 17 items) https://github.com/llvm/llvm-project/pull/97118 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [FMV][AArch64] Do not emit ifunc resolver on use. (PR #97761)
@@ -261,9 +261,9 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // CHECK: attributes #[[ATTR3]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-v9.5a" } // CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm,-v9.5a" } // CHECK: attributes #[[ATTR5:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR6:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+jsconv,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR7:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.5a" } -// CHECK: attributes #[[ATTR8:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-v9.5a" } +// CHECK: attributes #[[ATTR6:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.5a" } +// CHECK: attributes #[[ATTR7:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-v9.5a" } +// CHECK: attributes #[[ATTR8:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+jsconv,+neon,-v9.5a" } labrinea wrote: By the way do you know how to disable the attribute checks? https://github.com/llvm/llvm-project/pull/97761 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [MLIR] Add f8E4M3 IEEE 754 type (PR #97118)
@@ -136,6 +136,7 @@ static constexpr fltSemantics semIEEEquad = {16383, -16382, 113, 128}; static constexpr fltSemantics semFloat8E5M2 = {15, -14, 3, 8}; static constexpr fltSemantics semFloat8E5M2FNUZ = { 15, -15, 3, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero}; +static constexpr fltSemantics semFloat8E4M3 = {7, -6, 4, 8}; apivovarov wrote: Maksim, Adding f8E4M3 IEE754 dtype was split into two PRs: 1. llvm/clang/APFloat changes [PR-97179](https://github.com/llvm/llvm-project/pull/97179) 2. MLIR changes [PR-97118](https://github.com/llvm/llvm-project/pull/97118) (this PR) PR-97118 depends on PR-97179. Currently you see two commits in PR-97118. Once PR-97179 is merged - I'll rebase PR-97118 and it will contain just one commit - just MLIR changes. Can you review just MLIR changes in this PR (PR-97118). All comments for llvm/clang/APFloat should go to [PR-97179](https://github.com/llvm/llvm-project/pull/97179). https://github.com/llvm/llvm-project/pull/97118 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [LoongArch][clang] Add support for option `-msimd=` and macro `__loongarch_simd_width`. (PR #97984)
github-actions[bot] wrote: @ylzsx Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with a build, you may receive a report in an email or a comment on this PR. Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues. How to do this, and the rest of the post-merge process, is covered in detail [here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr). If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of [LLVM development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy). You can fix your changes and open a new PR to merge them again. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! https://github.com/llvm/llvm-project/pull/97984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [LoongArch][clang] Add support for option `-msimd=` and macro `__loongarch_simd_width`. (PR #97984)
https://github.com/SixWeining closed https://github.com/llvm/llvm-project/pull/97984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 626c7ce - [LoongArch][clang] Add support for option `-msimd=` and macro `__loongarch_simd_width`. (#97984)
Author: Zhaoxin Yang Date: 2024-07-09T14:13:19+08:00 New Revision: 626c7ce33f850831949e4e724016ddbff3a34990 URL: https://github.com/llvm/llvm-project/commit/626c7ce33f850831949e4e724016ddbff3a34990 DIFF: https://github.com/llvm/llvm-project/commit/626c7ce33f850831949e4e724016ddbff3a34990.diff LOG: [LoongArch][clang] Add support for option `-msimd=` and macro `__loongarch_simd_width`. (#97984) Added: clang/test/Driver/loongarch-msimd.c Modified: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Driver/Options.td clang/lib/Basic/Targets/LoongArch.cpp clang/lib/Driver/ToolChains/Arch/LoongArch.cpp clang/test/Preprocessor/init-loongarch.c Removed: diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index a62bdc21298ee..243d88d53d664 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -791,6 +791,8 @@ def err_drv_loongarch_wrong_fpu_width : Error< "wrong fpu width; %select{LSX|LASX}0 depends on 64-bit FPU">; def err_drv_loongarch_invalid_simd_option_combination : Error< "invalid option combination; LASX depends on LSX">; +def err_drv_loongarch_invalid_msimd_EQ : Error< + "invalid argument '%0' to -msimd=; must be one of: none, lsx, lasx">; def err_drv_expand_response_file : Error< "failed to expand response file: %0">; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 58ca6f2bea9e4..707ce8ce78d0b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5252,6 +5252,9 @@ def mlasx : Flag<["-"], "mlasx">, Group, HelpText<"Enable Loongson Advanced SIMD Extension (LASX).">; def mno_lasx : Flag<["-"], "mno-lasx">, Group, HelpText<"Disable Loongson Advanced SIMD Extension (LASX).">; +def msimd_EQ : Joined<["-"], "msimd=">, Group, + Flags<[TargetSpecific]>, + HelpText<"Select the SIMD extension(s) to be enabled in LoongArch either 'none', 'lsx', 'lasx'.">; def mnop_mcount : Flag<["-"], "mnop-mcount">, HelpText<"Generate mcount/__fentry__ calls as nops. To activate they need to be patched in.">, Visibility<[ClangOption, CC1Option]>, Group, MarshallingInfoFlag>; diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index 280bd1d8033cc..75f71a337b7a4 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -208,10 +208,14 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, TuneCPU = ArchName; Builder.defineMacro("__loongarch_tune", Twine('"') + TuneCPU + Twine('"')); - if (HasFeatureLSX) + if (HasFeatureLASX) { +Builder.defineMacro("__loongarch_simd_width", "256"); Builder.defineMacro("__loongarch_sx", Twine(1)); - if (HasFeatureLASX) Builder.defineMacro("__loongarch_asx", Twine(1)); + } else if (HasFeatureLSX) { +Builder.defineMacro("__loongarch_simd_width", "128"); +Builder.defineMacro("__loongarch_sx", Twine(1)); + } StringRef ABI = getABI(); if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s") diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp index 9ea4cc3f7cb95..4a2b9efc9ffad 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -206,6 +206,35 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, } else /*-mno-lasx*/ Features.push_back("-lasx"); } + + // Select lsx/lasx feature determined by -msimd=. + // Option -msimd= has lower priority than -m[no-]lsx and -m[no-]lasx. + if (const Arg *A = Args.getLastArg(options::OPT_msimd_EQ)) { +StringRef MSIMD = A->getValue(); +if (MSIMD == "lsx") { + // Option -msimd=lsx depends on 64-bit FPU. + // -m*-float and -mfpu=none/0/32 conflict with -mlsx. + if (llvm::find(Features, "-d") != Features.end()) +D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << /*LSX*/ 0; + // The previous option does not contain feature -lsx. + else if (llvm::find(Features, "-lsx") == Features.end()) +Features.push_back("+lsx"); +} else if (MSIMD == "lasx") { + // Option -msimd=lasx depends on 64-bit FPU and LSX. + // -m*-float and -mfpu=none/0/32 conflict with -mlsx. + if (llvm::find(Features, "-d") != Features.end()) +D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << /*LASX*/ 1; + else if (llvm::find(Features, "-lsx") != Features.end()) +D.Diag(diag::err_drv_loongarch_invalid_simd_option_combination); + // The previous option does not contain feature -lasx. + else if (llvm::find(Features, "-lasx") == Features.end()) { +Features.push_back("+lsx"); +Features.push_back("+lasx"); + } +}
[clang] [llvm] [AArch64] Add -mlr-for-calls-only to replace the now removed -ffixed-x30 flag. (PR #98073)
https://github.com/aemerson updated https://github.com/llvm/llvm-project/pull/98073 >From d7a8f55b0790b15060f73f188ce97c83fe75f62d Mon Sep 17 00:00:00 2001 From: Amara Emerson Date: Mon, 8 Jul 2024 10:09:06 -0700 Subject: [PATCH 1/3] [AArch64] Add -mlr-for-calls-only to replace the now removed -ffixed-x30 flag. This re-introduces the effective behaviour that was reverted in 7ad481e76c9bee5b9895ebfa0fdb52f31cb7de77. This time we're not using the same mechanism, exposing another reservation feature that prevents only regalloc from using the register, but not for other required uses like ABIs. This also fixes a consequent issue with reserving LR, which is that frame lowering was only adding live-in flags for non-reserved regs. This would cause issues later since the outliner needs accurate flags to determine when LR needs to be preserved. rdar://131313095 --- clang/include/clang/Driver/Options.td | 3 + .../clang/Driver/aarch64-mlr-for-calls-only.c | 4 + clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 3 + llvm/lib/Target/AArch64/AArch64Features.td| 4 + .../Target/AArch64/AArch64FrameLowering.cpp | 7 +- .../Target/AArch64/AArch64RegisterInfo.cpp| 3 + llvm/lib/Target/AArch64/AArch64Subtarget.h| 1 + .../CodeGen/AArch64/arm64-platform-reg.ll | 7 +- .../AArch64/lr-reserved-for-ra-live-in.mir| 110 ++ 9 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 clang/include/clang/Driver/aarch64-mlr-for-calls-only.c create mode 100644 llvm/test/CodeGen/AArch64/lr-reserved-for-ra-live-in.mir diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 58ca6f2bea9e4..714d5de76dd99 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4917,6 +4917,9 @@ foreach i = {1-31} in def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group, HelpText<"Reserve the x"#i#" register (AArch64/RISC-V only)">; +def mlr_for_calls_only : Flag<["-"], "mlr-for-calls-only">, Group, + HelpText<"Do not allocate the LR register for general purpose usage, only for calls. (AArch64 only)">; + foreach i = {8-15,18} in def fcall_saved_x#i : Flag<["-"], "fcall-saved-x"#i>, Group, HelpText<"Make the x"#i#" register call-saved (AArch64 only)">; diff --git a/clang/include/clang/Driver/aarch64-mlr-for-calls-only.c b/clang/include/clang/Driver/aarch64-mlr-for-calls-only.c new file mode 100644 index 0..1fe3bdab4f3e4 --- /dev/null +++ b/clang/include/clang/Driver/aarch64-mlr-for-calls-only.c @@ -0,0 +1,4 @@ + +// RUN: %clang --target=aarch64-none-gnu -mlr-for-calls-only -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK < %t %s +// CHECK: "-target-feature" "+reserve-lr-for-ra" diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index ec248b80251ea..5fbf38cdda12b 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -398,6 +398,9 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, if (Args.hasArg(options::OPT_ffixed_x28)) Features.push_back("+reserve-x28"); + if (Args.hasArg(options::OPT_mlr_for_calls_only)) +Features.push_back("+reserve-lr-for-ra"); + if (Args.hasArg(options::OPT_fcall_saved_x8)) Features.push_back("+call-saved-x8"); diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td index 8754ea4974999..50ff25ff1ba0c 100644 --- a/llvm/lib/Target/AArch64/AArch64Features.td +++ b/llvm/lib/Target/AArch64/AArch64Features.td @@ -571,6 +571,10 @@ foreach i = {1-7,9-15,18,20-28} in "Reserve X"#i#", making it unavailable " "as a GPR">; +def FeatureReserveLRForRA : SubtargetFeature<"reserve-lr-for-ra", + "ReserveLRForRA", "true", + "Reserve LR for call use only">; + foreach i = {8-15,18} in def FeatureCallSavedX#i : SubtargetFeature<"call-saved-x"#i, "CustomCallSavedXRegs["#i#"]", "true", "Make X"#i#" callee saved.">; diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 75e89e8222ae9..c760d29e9d138 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -3267,10 +3267,13 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters( InsertSEH(MIB, TII, MachineInstr::FrameSetup); } else { // The code when the pair of ZReg is not present MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc)); - if (!MRI.isReserved(Reg1)) + const AArch64RegisterInfo *RegInfo = + static_cast( + MF.getSubtarget().getRegisterInfo()); + if (!RegInfo->isStrictlyReservedReg(MF, Reg1)) MBB.addLiveIn(
[clang] [Clang] Ensure the method scope at the late parsing of noexcept specifiers (PR #98023)
zyn0217 wrote: Looks like this caused a regression in `std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp`... I will look into that. https://github.com/llvm/llvm-project/pull/98023 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] fix sema init crash for not checking a ExprResult (PR #98102)
https://github.com/yuxuanchen1997 updated https://github.com/llvm/llvm-project/pull/98102 >From 01a5dd6e5bfc612678818035b88f85fda5c039d1 Mon Sep 17 00:00:00 2001 From: Yuxuan Chen Date: Mon, 8 Jul 2024 18:16:17 -0700 Subject: [PATCH] [clang] fix sema init crash for not checking a ExprResult --- clang/lib/Sema/SemaInit.cpp | 4 1 file changed, 4 insertions(+) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 41753a1661ace..a27ed02fc73b8 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -5576,6 +5576,10 @@ static void TryOrBuildParenListInitialization( ExprResult ER; ER = IS.Perform(S, SubEntity, SubKind, Arg ? MultiExprArg(Arg) : std::nullopt); + + if (ER.isInvalid()) +return false; + if (InitExpr) *InitExpr = ER.get(); else ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [X86][MC] Added support for -msse2avx option in llvm-mc (PR #96860)
JaydeepChauhan14 wrote: @MaskRay, @RKSimon, @aengelke, @phoebewang, @KanRobert requesting for review again. https://github.com/llvm/llvm-project/pull/96860 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AArch64] Add -mlr-for-calls-only to replace the now removed -ffixed-x30 flag. (PR #98073)
@@ -3267,10 +3267,13 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters( InsertSEH(MIB, TII, MachineInstr::FrameSetup); } else { // The code when the pair of ZReg is not present MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc)); - if (!MRI.isReserved(Reg1)) + const AArch64RegisterInfo *RegInfo = + static_cast( + MF.getSubtarget().getRegisterInfo()); + if (!RegInfo->isStrictlyReservedReg(MF, Reg1)) aemerson wrote: Maybe not, but I'm not sure what other options we have. It's worked for so far except for this case with the outliner. https://github.com/llvm/llvm-project/pull/98073 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Ensure the method scope at the late parsing of noexcept specifiers (PR #98023)
https://github.com/zyn0217 edited https://github.com/llvm/llvm-project/pull/98023 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Ensure the method scope at the late parsing of noexcept specifiers (PR #98023)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/98023 >From 74d7184777e977ab3e83bfcae7e08e550ef32a39 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Mon, 8 Jul 2024 21:28:30 +0800 Subject: [PATCH 1/2] [Clang] Ensure the method scope at the late parsing of noexcept specifiers --- clang/docs/ReleaseNotes.rst | 2 +- clang/lib/Parse/ParseCXXInlineMethods.cpp | 15 +-- .../expr/expr.prim/expr.prim.general/p3-0x.cpp| 5 +++-- clang/test/CodeGenCXX/mangle-exception-spec.cpp | 11 +++ clang/test/SemaCXX/cxx0x-noexcept-expression.cpp | 8 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 838cb69f647ee..b521de4515e1f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -958,7 +958,7 @@ Bug Fixes to C++ Support - Fixed a type constraint substitution issue involving a generic lambda expression. (#GH93821) - Fix a crash caused by improper use of ``__array_extent``. (#GH80474) - Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), - (#GH88081), (#GH89496), (#GH90669) and (#GH91633). + (#GH88081), (#GH89496), (#GH90669), (#GH91633) and (#GH97453). - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). - Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849) - Fixed a failed assertion when attempting to convert an integer representing the difference diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 943ce0fdde3a3..faab9c6b19caa 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -511,11 +511,13 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { // and the end of the function-definition, member-declarator, or // declarator. CXXMethodDecl *Method; +FunctionDecl *FunctionToPush; if (FunctionTemplateDecl *FunTmpl = dyn_cast(LM.Method)) - Method = dyn_cast(FunTmpl->getTemplatedDecl()); + FunctionToPush = FunTmpl->getTemplatedDecl(); else - Method = dyn_cast(LM.Method); + FunctionToPush = cast(LM.Method); +Method = dyn_cast(FunctionToPush); Sema::CXXThisScopeRAII ThisScope( Actions, Method ? Method->getParent() : nullptr, @@ -529,6 +531,15 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { ExprResult NoexceptExpr; CachedTokens *ExceptionSpecTokens; +// Push a function scope so that tryCaptureVariable() can properly visit +// function scopes involving function parameters that are referenced inside +// the noexcept specifier e.g. through a lambda expression. +// Example: +// struct X { +// void ICE(int val) noexcept(noexcept([val]{})); +// }; +Sema::SynthesizedFunctionScope Scope(Actions, FunctionToPush); + ExceptionSpecificationType EST = tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange, DynamicExceptions, diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp index b59cc175a1976..d50d05d17ab7a 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp @@ -113,8 +113,9 @@ namespace Static { static auto g() -> decltype(this->m); // expected-error{{'this' cannot be used in a static member function declaration}} static int h(); - -static int i() noexcept(noexcept(m + 2)); // expected-error{{'this' cannot be implicitly used in a static member function declaration}} + +// The use of 'm' doesn't constitute an ODR use, so we don't have a reason to reject it. +static int i() noexcept(noexcept(m + 2)); }; auto X1::h() -> decltype(m) { return 0; } // expected-error{{'this' cannot be implicitly used in a static member function declaration}} diff --git a/clang/test/CodeGenCXX/mangle-exception-spec.cpp b/clang/test/CodeGenCXX/mangle-exception-spec.cpp index 15f7a8b6cb504..1bc268e1b6ca4 100644 --- a/clang/test/CodeGenCXX/mangle-exception-spec.cpp +++ b/clang/test/CodeGenCXX/mangle-exception-spec.cpp @@ -47,3 +47,14 @@ template auto i<>(int()) -> int (*)(); // CHECK-CXX11: define {{.*}} @_Z1iIJfEEPDwiDpT_EFivEPS2_( // CHECK-CXX17: define {{.*}} @_Z1iIJfEEPDwiDpT_EFivES3_( template auto i(int()) -> int (*)(); + +template +struct X1 { + T m; + static void j(int (X1::*)() noexcept(noexcept(m + 2))); +}; + +void foo() { + // CHECK-CXX17: call {{.*}} @_ZN2X1IiE1jEMS0_DoFivE( + X1::j(nullptr); +} diff --git a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp index c616a77f36619..53d2
[clang] [Clang] Ensure the method scope at the late parsing of noexcept specifiers (PR #98023)
@@ -113,8 +113,9 @@ namespace Static { static auto g() -> decltype(this->m); // expected-error{{'this' cannot be used in a static member function declaration}} static int h(); - -static int i() noexcept(noexcept(m + 2)); // expected-error{{'this' cannot be implicitly used in a static member function declaration}} + +// The use of 'm' doesn't constitute an ODR use, so we don't have a reason to reject it. +static int i() noexcept(noexcept(m + 2)); zyn0217 wrote: Done. I didn't even know we had relevant wordings about such scenarios until @frederick-vs-ja (thanks!) told me about [[expr.prim.id.general](https://eel.is/c++draft/expr.prim#id.general-4.3)]/4. https://github.com/llvm/llvm-project/pull/98023 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Remove unused RequiredFeatures argument from RVVIntrinsic constructor. NFC (PR #98067)
https://github.com/topperc closed https://github.com/llvm/llvm-project/pull/98067 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 8474194 - [RISCV] Remove unused RequiredFeatures argument from RVVIntrinsic constructor. NFC (#98067)
Author: Craig Topper Date: 2024-07-08T21:48:29-07:00 New Revision: 84741940f2d9cb858ecb29ce5197714a45e7e67a URL: https://github.com/llvm/llvm-project/commit/84741940f2d9cb858ecb29ce5197714a45e7e67a DIFF: https://github.com/llvm/llvm-project/commit/84741940f2d9cb858ecb29ce5197714a45e7e67a.diff LOG: [RISCV] Remove unused RequiredFeatures argument from RVVIntrinsic constructor. NFC (#98067) Looks like the usage was removed by 7a5cb15ea6facd82756adafae76d60f36a0b60fd Added: Modified: clang/include/clang/Support/RISCVVIntrinsicUtils.h clang/lib/Support/RISCVVIntrinsicUtils.cpp clang/utils/TableGen/RISCVVEmitter.cpp Removed: diff --git a/clang/include/clang/Support/RISCVVIntrinsicUtils.h b/clang/include/clang/Support/RISCVVIntrinsicUtils.h index 97493bae5656e..b4ff61784126e 100644 --- a/clang/include/clang/Support/RISCVVIntrinsicUtils.h +++ b/clang/include/clang/Support/RISCVVIntrinsicUtils.h @@ -409,7 +409,6 @@ class RVVIntrinsic { bool HasBuiltinAlias, llvm::StringRef ManualCodegen, const RVVTypes &Types, const std::vector &IntrinsicTypes, - const std::vector &RequiredFeatures, unsigned NF, Policy PolicyAttrs, bool HasFRMRoundModeOp); ~RVVIntrinsic() = default; diff --git a/clang/lib/Support/RISCVVIntrinsicUtils.cpp b/clang/lib/Support/RISCVVIntrinsicUtils.cpp index 7d2a2d7e826f9..e3718130ca06a 100644 --- a/clang/lib/Support/RISCVVIntrinsicUtils.cpp +++ b/clang/lib/Support/RISCVVIntrinsicUtils.cpp @@ -978,8 +978,7 @@ RVVIntrinsic::RVVIntrinsic( bool HasMaskedOffOperand, bool HasVL, PolicyScheme Scheme, bool SupportOverloading, bool HasBuiltinAlias, StringRef ManualCodegen, const RVVTypes &OutInTypes, const std::vector &NewIntrinsicTypes, -const std::vector &RequiredFeatures, unsigned NF, -Policy NewPolicyAttrs, bool HasFRMRoundModeOp) +unsigned NF, Policy NewPolicyAttrs, bool HasFRMRoundModeOp) : IRName(IRName), IsMasked(IsMasked), HasMaskedOffOperand(HasMaskedOffOperand), HasVL(HasVL), Scheme(Scheme), SupportOverloading(SupportOverloading), HasBuiltinAlias(HasBuiltinAlias), diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp index 48cd83cabfc7d..7f3cb70c97d09 100644 --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -576,8 +576,8 @@ void RVVEmitter::createRVVIntrinsics( Name, SuffixStr, OverloadedName, OverloadedSuffixStr, IRName, /*IsMasked=*/false, /*HasMaskedOffOperand=*/false, HasVL, UnMaskedPolicyScheme, SupportOverloading, HasBuiltinAlias, -ManualCodegen, *Types, IntrinsicTypes, RequiredFeatures, NF, -DefaultPolicy, HasFRMRoundModeOp)); +ManualCodegen, *Types, IntrinsicTypes, NF, DefaultPolicy, +HasFRMRoundModeOp)); if (UnMaskedPolicyScheme != PolicyScheme::SchemeNone) for (auto P : SupportedUnMaskedPolicies) { SmallVector PolicyPrototype = @@ -591,8 +591,8 @@ void RVVEmitter::createRVVIntrinsics( Name, SuffixStr, OverloadedName, OverloadedSuffixStr, IRName, /*IsMask=*/false, /*HasMaskedOffOperand=*/false, HasVL, UnMaskedPolicyScheme, SupportOverloading, HasBuiltinAlias, -ManualCodegen, *PolicyTypes, IntrinsicTypes, RequiredFeatures, -NF, P, HasFRMRoundModeOp)); +ManualCodegen, *PolicyTypes, IntrinsicTypes, NF, P, +HasFRMRoundModeOp)); } if (!HasMasked) continue; @@ -603,8 +603,7 @@ void RVVEmitter::createRVVIntrinsics( Name, SuffixStr, OverloadedName, OverloadedSuffixStr, MaskedIRName, /*IsMasked=*/true, HasMaskedOffOperand, HasVL, MaskedPolicyScheme, SupportOverloading, HasBuiltinAlias, ManualCodegen, *MaskTypes, -IntrinsicTypes, RequiredFeatures, NF, DefaultPolicy, -HasFRMRoundModeOp)); +IntrinsicTypes, NF, DefaultPolicy, HasFRMRoundModeOp)); if (MaskedPolicyScheme == PolicyScheme::SchemeNone) continue; for (auto P : SupportedMaskedPolicies) { @@ -618,8 +617,8 @@ void RVVEmitter::createRVVIntrinsics( Name, SuffixStr, OverloadedName, OverloadedSuffixStr, MaskedIRName, /*IsMasked=*/true, HasMaskedOffOperand, HasVL, MaskedPolicyScheme, SupportOverloading, HasBuiltinAlias, - ManualCodegen, *PolicyTypes, IntrinsicTypes, RequiredFeatures, NF, - P, HasFRMRoundModeOp)); + ManualCodegen, *PolicyTypes, IntrinsicTypes, NF, P, + HasFRMRoundModeOp)); } } // End for Log2LMULList } // End for TypeRange ___ cfe-commits mailing list cfe-commits@lists
[clang] Compiler messages on HIP SDK for Windows (PR #97668)
https://github.com/david-salinas updated https://github.com/llvm/llvm-project/pull/97668 >From 970b1e696b77216f326fb7d8dcad5b55a82db489 Mon Sep 17 00:00:00 2001 From: David Salinas Date: Thu, 4 Jul 2024 03:32:13 + Subject: [PATCH] Compiler messages on HIP SDK for Windows When target triple indicates we are on Windows, do not add linux paths to search path in ROCm Installation Detection. Change-Id: I18effb8c20252de3d84ea37ef562124695c5a570 --- clang/lib/Driver/ToolChains/AMDGPU.cpp| 18 ++ clang/lib/Driver/ToolChains/ROCm.h| 5 + clang/test/Driver/rocm-detect-windows.hip | 7 +++ 3 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 clang/test/Driver/rocm-detect-windows.hip diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index 453daed7cc7d5..e05b9202599c7 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -306,14 +306,16 @@ RocmInstallationDetector::getInstallationPathCandidates() { LatestVer = Ver; } } - if (!LatestROCm.empty()) -ROCmSearchDirs.emplace_back(D.SysRoot + "/opt/" + LatestROCm, -/*StrictChecking=*/true); + if (!isWindows()) { +if (!LatestROCm.empty()) + ROCmSearchDirs.emplace_back(D.SysRoot + "/opt/" + LatestROCm, + /*StrictChecking=*/true); - ROCmSearchDirs.emplace_back(D.SysRoot + "/usr/local", - /*StrictChecking=*/true); - ROCmSearchDirs.emplace_back(D.SysRoot + "/usr", - /*StrictChecking=*/true); +ROCmSearchDirs.emplace_back(D.SysRoot + "/usr/local", +/*StrictChecking=*/true); +ROCmSearchDirs.emplace_back(D.SysRoot + "/usr", +/*StrictChecking=*/true); + } DoPrintROCmSearchDirs(); return ROCmSearchDirs; @@ -322,7 +324,7 @@ RocmInstallationDetector::getInstallationPathCandidates() { RocmInstallationDetector::RocmInstallationDetector( const Driver &D, const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args, bool DetectHIPRuntime, bool DetectDeviceLib) -: D(D) { +: D(D), hostTriple(HostTriple) { Verbose = Args.hasArg(options::OPT_v); RocmPathArg = Args.getLastArgValue(clang::driver::options::OPT_rocm_path_EQ); PrintROCmSearchDirs = diff --git a/clang/lib/Driver/ToolChains/ROCm.h b/clang/lib/Driver/ToolChains/ROCm.h index dceb0ab036693..242e84a32e8d0 100644 --- a/clang/lib/Driver/ToolChains/ROCm.h +++ b/clang/lib/Driver/ToolChains/ROCm.h @@ -111,6 +111,8 @@ class RocmInstallationDetector { // Wheter -nogpulib is specified. bool NoBuiltinLibs = false; + llvm::Triple hostTriple; + // Paths SmallString<0> InstallPath; SmallString<0> BinPath; @@ -193,6 +195,9 @@ class RocmInstallationDetector { /// Check whether we detected a valid HIP STDPAR Acceleration library. bool hasHIPStdParLibrary() const { return HasHIPStdParLibrary; } + /// Check whether the target triple is for Windows. + bool isWindows() const { return hostTriple.isOSWindows(); } + /// Print information about the detected ROCm installation. void print(raw_ostream &OS) const; diff --git a/clang/test/Driver/rocm-detect-windows.hip b/clang/test/Driver/rocm-detect-windows.hip new file mode 100644 index 0..7f7c34efb5fd4 --- /dev/null +++ b/clang/test/Driver/rocm-detect-windows.hip @@ -0,0 +1,7 @@ +// UNSUPPORTED: system-linux + +// RUN: %clang -### -nogpulib -nogpuinc \ +// RUN: --print-rocm-search-dirs %s 2>&1 \ +// RUN: | FileCheck %s + +// CHECK-NOT: ROCm installation search path: [[ROCM_PATH:.*/usr$]] ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Compiler messages on HIP SDK for Windows (PR #97668)
https://github.com/david-salinas updated https://github.com/llvm/llvm-project/pull/97668 >From e9722655b4fd32b3128ba10b69b1b498e507d437 Mon Sep 17 00:00:00 2001 From: David Salinas Date: Thu, 4 Jul 2024 03:32:13 + Subject: [PATCH] Compiler messages on HIP SDK for Windows When target triple indicates we are on Windows, do not add linux paths to search path in ROCm Installation Detection. Change-Id: I18effb8c20252de3d84ea37ef562124695c5a570 --- clang/lib/Driver/ToolChains/AMDGPU.cpp| 18 +-- clang/lib/Driver/ToolChains/ROCm.h| 5 + clang/test/Driver/rocm-detect-windows.hip | 167 ++ 3 files changed, 182 insertions(+), 8 deletions(-) create mode 100644 clang/test/Driver/rocm-detect-windows.hip diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index 453daed7cc7d5..e05b9202599c7 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -306,14 +306,16 @@ RocmInstallationDetector::getInstallationPathCandidates() { LatestVer = Ver; } } - if (!LatestROCm.empty()) -ROCmSearchDirs.emplace_back(D.SysRoot + "/opt/" + LatestROCm, -/*StrictChecking=*/true); + if (!isWindows()) { +if (!LatestROCm.empty()) + ROCmSearchDirs.emplace_back(D.SysRoot + "/opt/" + LatestROCm, + /*StrictChecking=*/true); - ROCmSearchDirs.emplace_back(D.SysRoot + "/usr/local", - /*StrictChecking=*/true); - ROCmSearchDirs.emplace_back(D.SysRoot + "/usr", - /*StrictChecking=*/true); +ROCmSearchDirs.emplace_back(D.SysRoot + "/usr/local", +/*StrictChecking=*/true); +ROCmSearchDirs.emplace_back(D.SysRoot + "/usr", +/*StrictChecking=*/true); + } DoPrintROCmSearchDirs(); return ROCmSearchDirs; @@ -322,7 +324,7 @@ RocmInstallationDetector::getInstallationPathCandidates() { RocmInstallationDetector::RocmInstallationDetector( const Driver &D, const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args, bool DetectHIPRuntime, bool DetectDeviceLib) -: D(D) { +: D(D), hostTriple(HostTriple) { Verbose = Args.hasArg(options::OPT_v); RocmPathArg = Args.getLastArgValue(clang::driver::options::OPT_rocm_path_EQ); PrintROCmSearchDirs = diff --git a/clang/lib/Driver/ToolChains/ROCm.h b/clang/lib/Driver/ToolChains/ROCm.h index dceb0ab036693..242e84a32e8d0 100644 --- a/clang/lib/Driver/ToolChains/ROCm.h +++ b/clang/lib/Driver/ToolChains/ROCm.h @@ -111,6 +111,8 @@ class RocmInstallationDetector { // Wheter -nogpulib is specified. bool NoBuiltinLibs = false; + llvm::Triple hostTriple; + // Paths SmallString<0> InstallPath; SmallString<0> BinPath; @@ -193,6 +195,9 @@ class RocmInstallationDetector { /// Check whether we detected a valid HIP STDPAR Acceleration library. bool hasHIPStdParLibrary() const { return HasHIPStdParLibrary; } + /// Check whether the target triple is for Windows. + bool isWindows() const { return hostTriple.isOSWindows(); } + /// Print information about the detected ROCm installation. void print(raw_ostream &OS) const; diff --git a/clang/test/Driver/rocm-detect-windows.hip b/clang/test/Driver/rocm-detect-windows.hip new file mode 100644 index 0..4aafeb97c00b5 --- /dev/null +++ b/clang/test/Driver/rocm-detect-windows.hip @@ -0,0 +1,167 @@ +// UNSUPPORTED: system-windows + +// Make sure the appropriate device specific library is available. + +// We don't include every target in the test directory, so just pick a valid +// target not included in the test. + +// RUN: not %clang -### -v --target=x86_64-linux-gnu --cuda-gpu-arch=gfx902 \ +// RUN: --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=COMMON,GFX902-DEFAULTLIBS %s + +// Should not interpret -nostdlib as disabling offload libraries. +// RUN: not %clang -### -v --target=x86_64-linux-gnu --cuda-gpu-arch=gfx902 -nostdlib \ +// RUN: --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=COMMON,GFX902-DEFAULTLIBS %s + +// RUN: %clang -### -v -target x86_64-linux-gnu --cuda-gpu-arch=gfx902 -nogpulib \ +// RUN: --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=COMMON,NODEFAULTLIBS %s + +// Test environment variable ROCM_PATH. +// RUN: env ROCM_PATH=%S/Inputs/rocm %clang -### --target=x86_64-linux-gnu \ +// RUN: --print-rocm-search-dirs --offload-arch=gfx1010 %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=ROCM-ENV %s + +// Test interaction between environment variables HIP_PATH and ROCM_PATH. +// Device libs are found under ROCM_PATH. HIP include files and HIP runtime library +// are found under HIP_PATH. + +// RUN: rm -rf %t/myhip +// RUN: mkdir -p %t/myhip +// RUN: cp -r %S/Inputs/rocm/bin %t/myhip + +// Test HIP_PATH overrides ROCM_PATH. +// RUN: env ROCM_PATH
[clang] [X86][vectorcall] Do not consume register for indirect return value (PR #97939)
phoebewang wrote: > You can see from this example that when C++ rules force the use of an sret > indirect return, a register is consumed: > https://godbolt.org/z/W3fdn8s5Y Could you explain more about the example? I didn't find where the register consumed. Don't both `copy_trivial` and `copy_nontrivial` use the same `esp + 4` to pass the pointer of sret? https://github.com/llvm/llvm-project/pull/97939 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format][NFC] Annotate function/ctor/dtor declaration l_paren (PR #97938)
https://github.com/owenca edited https://github.com/llvm/llvm-project/pull/97938 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format][NFC] Annotate function decl l_paren (PR #97938)
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/97938 >From eb53318b3c5dec2452c4a0d5aed7944ebdd99380 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sat, 6 Jul 2024 22:21:26 -0700 Subject: [PATCH 1/2] [clang-format][NFC] Annotate function decl l_paren --- clang/lib/Format/FormatToken.h| 1 + clang/lib/Format/TokenAnnotator.cpp | 6 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 18 ++ 3 files changed, 25 insertions(+) diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 4ffd745bf9307..cc45d5a8c5c1e 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -77,6 +77,7 @@ namespace format { TYPE(ForEachMacro) \ TYPE(FunctionAnnotationRParen) \ TYPE(FunctionDeclarationName) \ + TYPE(FunctionDeclarationLParen) \ TYPE(FunctionLBrace) \ TYPE(FunctionLikeOrFreestandingMacro) \ TYPE(FunctionTypeLParen) \ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 0fd0214d16615..d453fd6d4d224 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3864,6 +3864,12 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const { Tok->setFinalizedType(TT_FunctionDeclarationName); LineIsFunctionDeclaration = true; SeenName = true; + if (ClosingParen) { +auto *OpeningParen = ClosingParen->MatchingParen; +assert(OpeningParen); +if (OpeningParen->is(TT_Unknown)) + OpeningParen->setType(TT_FunctionDeclarationLParen); + } break; } } diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 5d83d8a0c4429..d109bf2ba5327 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1037,6 +1037,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) { EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); EXPECT_TRUE(Tokens[9]->ClosesRequiresClause); EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[12], tok::l_paren, TT_FunctionDeclarationLParen); Tokens = annotate("template \n" "requires Bar\n" @@ -1045,6 +1046,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) { EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); EXPECT_TRUE(Tokens[9]->ClosesRequiresClause); EXPECT_TOKEN(Tokens[14], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[15], tok::l_paren, TT_FunctionDeclarationLParen); Tokens = annotate("template \n" "struct S {\n" @@ -1914,15 +1916,18 @@ TEST_F(TokenAnnotatorTest, UnderstandsFunctionDeclarationNames) { auto Tokens = annotate("void f [[noreturn]] ();"); ASSERT_EQ(Tokens.size(), 11u) << Tokens; EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_FunctionDeclarationLParen); Tokens = annotate("void f [[noreturn]] () {}"); ASSERT_EQ(Tokens.size(), 12u) << Tokens; EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_FunctionDeclarationLParen); Tokens = annotate("#define FOO Foo::\n" "FOO Foo();"); ASSERT_EQ(Tokens.size(), 11u) << Tokens; EXPECT_TOKEN(Tokens[6], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_FunctionDeclarationLParen); Tokens = annotate("struct Foo {\n" " Bar (*func)();\n" @@ -1934,16 +1939,19 @@ TEST_F(TokenAnnotatorTest, UnderstandsFunctionDeclarationNames) { Tokens = annotate("void instanceof();"); ASSERT_EQ(Tokens.size(), 6u); EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); Tokens = annotate("int iso_time(time_t);"); ASSERT_EQ(Tokens.size(), 7u) << Tokens; EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); auto Style = getLLVMStyle(); Style.TypeNames.push_back("MyType"); Tokens = annotate("int iso_time(MyType);", Style); ASSERT_EQ(Tokens.size(), 7u) << Tokens; EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); EXPECT_TOKEN(Tokens[3], tok::identifier, TT_TypeName); } @@ -2836,6 +284
[clang] [clang][ARM] Fix warning for using VFP from interrupts. (PR #91870)
chrisnc wrote: Fixed another release notes conflict. Ping @DavidSpickett @ostannard @jthackray. https://github.com/llvm/llvm-project/pull/91870 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ARM] Fix warning for using VFP from interrupts. (PR #91870)
https://github.com/chrisnc updated https://github.com/llvm/llvm-project/pull/91870 >From 947526935e78dfcb40ffde6aeb273c6120884339 Mon Sep 17 00:00:00 2001 From: Chris Copeland Date: Sat, 11 May 2024 00:15:50 -0700 Subject: [PATCH 1/2] [clang][ARM] Fix warning for using VFP from interrupts. This warning has three issues: - The interrupt attribute causes the function to return using an exception return instruction. This warning allows calls from one function with the interrupt attribute to another, and the diagnostic text suggests that not having the attribute on the callee is a problem. Actually making such a call will lead to a double exception return, which is unpredictable according to the ARM architecture manual section B9.1.1, "Restrictions on exception return instructions". Even on machines where an exception return from user/system mode is tolerated, if the callee's interrupt type is anything other than a supervisor call or secure monitor call, it will also return to a different address than a normal function would. For example, returning from an "IRQ" handler will return to lr - 4, which will generally result in calling the same function again. - The interrupt attribute currently does not cause caller-saved VFP registers to be saved and restored if they are used, so putting __attribute__((interrupt)) on a called function doesn't prevent it from clobbering VFP state. - It is part of the -Wextra diagnostic group and can't be individually disabled when using -Wextra, which also means the diagnostic text of this specific warning appears in the documentation of -Wextra. This change addresses all three issues by instead generating a warning for any interrupt handler where the vfp feature is enabled. The warning is also given its own diagnostic group. Closes #34876. --- clang/docs/ReleaseNotes.rst | 10 + .../clang/Basic/DiagnosticSemaKinds.td| 7 +-- clang/lib/Sema/SemaARM.cpp| 5 +++ clang/lib/Sema/SemaExpr.cpp | 14 +- clang/test/Sema/arm-interrupt-attr.c | 45 +++ 5 files changed, 26 insertions(+), 55 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e086b4fa43743..c7fed20e2bd9a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -442,6 +442,9 @@ New Compiler Flags - ``-Wc++2c-compat`` group was added to help migrating existing codebases to upcoming C++26. +- For the ARM target, added ``-Warm-interrupt-vfp-clobber`` that will emit a + diagnostic when an interrupt handler is declared and VFP is enabled. + Deprecated Compiler Flags - @@ -484,6 +487,13 @@ Modified Compiler Flags now include dianostics about C++26 features that are not present in older versions. +- Removed the "arm interrupt calling convention" warning that was included in + ``-Wextra`` without its own flag. This warning suggested adding + ``__attribute__((interrupt))`` to functions that are called from interrupt + handlers to prevent clobbering VFP registers. Following this suggestion leads + to unpredictable behavior by causing multiple exception returns from one + exception. Fixes #GH34876. + Removed Compiler Flags - diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1aba8bc24ba2f..a29287153a604 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -336,9 +336,10 @@ def warn_anyx86_excessive_regsave : Warning< " with attribute 'no_caller_saved_registers'" " or be compiled with '-mgeneral-regs-only'">, InGroup>; -def warn_arm_interrupt_calling_convention : Warning< - "call to function without interrupt attribute could clobber interruptee's VFP registers">, - InGroup; +def warn_arm_interrupt_vfp_clobber : Warning< + "interrupt service routine with vfp enabled may clobber the " + "interruptee's vfp state">, + InGroup>; def warn_interrupt_attribute_invalid : Warning< "%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to " "functions that have %select{no parameters|a 'void' return type}1">, diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp index 370db341e997e..d4668fbdcd2a8 100644 --- a/clang/lib/Sema/SemaARM.cpp +++ b/clang/lib/Sema/SemaARM.cpp @@ -1329,6 +1329,11 @@ void SemaARM::handleInterruptAttr(Decl *D, const ParsedAttr &AL) { return; } + const TargetInfo &TI = getASTContext().getTargetInfo(); + if (TI.hasFeature("vfp")) { +Diag(D->getLocation(), diag::warn_arm_interrupt_vfp_clobber); + } + D->addAttr(::new (getASTContext()) ARMInterruptAttr(getASTContext(), AL, Kind)); } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 852344d895ffd..be579be7bf331 100644 --- a/clang/lib/Sema/Sem
[clang-tools-extra] [clang-doc] fix paths by hard coding path to share (PR #98099)
https://github.com/PeterChou1 closed https://github.com/llvm/llvm-project/pull/98099 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 87d58ab - [clang-doc] fix paths by hard coding path to share (#98099)
Author: PeterChou1 Date: 2024-07-08T23:48:34-04:00 New Revision: 87d58ab22af0627b2c90138713c19b5263b6c132 URL: https://github.com/llvm/llvm-project/commit/87d58ab22af0627b2c90138713c19b5263b6c132 DIFF: https://github.com/llvm/llvm-project/commit/87d58ab22af0627b2c90138713c19b5263b6c132.diff LOG: [clang-doc] fix paths by hard coding path to share (#98099) Added: Modified: clang-tools-extra/clang-doc/tool/CMakeLists.txt Removed: diff --git a/clang-tools-extra/clang-doc/tool/CMakeLists.txt b/clang-tools-extra/clang-doc/tool/CMakeLists.txt index e93a5728d6b6b..601a0460d76b3 100644 --- a/clang-tools-extra/clang-doc/tool/CMakeLists.txt +++ b/clang-tools-extra/clang-doc/tool/CMakeLists.txt @@ -25,7 +25,7 @@ set(assets ) set(asset_dir "${CMAKE_CURRENT_SOURCE_DIR}/../assets") -set(resource_dir "${CMAKE_BINARY_DIR}/share/clang-doc") +set(resource_dir "${LLVM_RUNTIME_OUTPUT_INTDIR}/../share/clang-doc") set(out_files) function(copy_files_to_dst src_dir dst_dir file) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Define ATOMIC_FLAG_INIT correctly for C++. (PR #97534)
chrisnc wrote: ping https://github.com/llvm/llvm-project/pull/97534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix the order of addInstantiatedParameters in LambdaScopeForCallOperatorInstantiationRAII (PR #97215)
https://github.com/mizvekov approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/97215 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Coverage] Suppress covmap and profdata for system headers. (PR #97952)
https://github.com/ornata approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/97952 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Adds a pseudonym to clang"s windows mangler... (PR #97792)
https://github.com/memory-thrasher edited https://github.com/llvm/llvm-project/pull/97792 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Fix Default Asset File locator for clang docs (PR #97505)
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/97505 >From 1c190c9c6b55aec23bab6d7b2a0f489c59285dc7 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Tue, 2 Jul 2024 18:38:24 -0700 Subject: [PATCH 1/9] if debug exists, go up an extra dir --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 6198a6e0cdcc3..b97fa715f9e67 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -167,7 +167,13 @@ llvm::Error getDefaultAssetFiles(const char *Argv0, llvm::SmallString<128> AssetsPath; AssetsPath = llvm::sys::path::parent_path(NativeClangDocPath); - llvm::sys::path::append(AssetsPath, "..", "share", "clang-doc"); + llvm::sys::path::append(AssetsPath, ".."); + llvm::SmallString<128> tempCopyDbg = AssetsPath; + llvm::sys::path::append(tempCopyDbg, "Debug"); + // index.js may be in the debug + if (!llvm::sys::fs::is_directory(tempCopyDbg)) +llvm::sys::path::append(AssetsPath, ".."); + llvm::sys::path::append(AssetsPath, "share", "clang-doc"); llvm::SmallString<128> DefaultStylesheet; llvm::sys::path::native(AssetsPath, DefaultStylesheet); llvm::sys::path::append(DefaultStylesheet, >From 07662a63e1b3ab2886871f3960246be8219c6ecd Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Tue, 2 Jul 2024 18:45:23 -0700 Subject: [PATCH 2/9] cleanup comment --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index b97fa715f9e67..ebd0675cd5501 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -170,7 +170,7 @@ llvm::Error getDefaultAssetFiles(const char *Argv0, llvm::sys::path::append(AssetsPath, ".."); llvm::SmallString<128> tempCopyDbg = AssetsPath; llvm::sys::path::append(tempCopyDbg, "Debug"); - // index.js may be in the debug + // The executable that ran clangDoc may be in the Debug directory. if (!llvm::sys::fs::is_directory(tempCopyDbg)) llvm::sys::path::append(AssetsPath, ".."); llvm::sys::path::append(AssetsPath, "share", "clang-doc"); >From ea1d0ce1c2893297e67eebf0a52885681c6a866d Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 3 Jul 2024 03:12:38 -0700 Subject: [PATCH 3/9] use native to copy path, instead of assignment operator --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index ebd0675cd5501..6ec35acfc2db3 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -168,7 +168,8 @@ llvm::Error getDefaultAssetFiles(const char *Argv0, llvm::SmallString<128> AssetsPath; AssetsPath = llvm::sys::path::parent_path(NativeClangDocPath); llvm::sys::path::append(AssetsPath, ".."); - llvm::SmallString<128> tempCopyDbg = AssetsPath; + llvm::SmallString<128> tempCopyDbg; + llvm::sys::path::native(AssetsPath, tempCopyDbg); llvm::sys::path::append(tempCopyDbg, "Debug"); // The executable that ran clangDoc may be in the Debug directory. if (!llvm::sys::fs::is_directory(tempCopyDbg)) >From b7484828d96d23dd7d2d88ee8d44f5aad6e23140 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Wed, 3 Jul 2024 13:37:17 -0700 Subject: [PATCH 4/9] revert change in .cpp, make attempt at fixing cmake --- clang-tools-extra/clang-doc/tool/CMakeLists.txt | 10 -- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp | 9 + 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/clang-tools-extra/clang-doc/tool/CMakeLists.txt b/clang-tools-extra/clang-doc/tool/CMakeLists.txt index e93a5728d6b6b..31ff0aca72b88 100644 --- a/clang-tools-extra/clang-doc/tool/CMakeLists.txt +++ b/clang-tools-extra/clang-doc/tool/CMakeLists.txt @@ -25,15 +25,16 @@ set(assets ) set(asset_dir "${CMAKE_CURRENT_SOURCE_DIR}/../assets") -set(resource_dir "${CMAKE_BINARY_DIR}/share/clang-doc") set(out_files) function(copy_files_to_dst src_dir dst_dir file) set(src "${src_dir}/${file}") set(dst "${dst_dir}/${file}") + message(here) add_custom_command(OUTPUT ${dst} DEPENDS ${src} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} +message(here2) COMMENT "Copying ${file} to ${dst_dir}" ) list(APPEND out_files ${dst}) @@ -44,7 +45,12 @@ foreach(f ${assets}) install(FILES ${asset_dir}/${f} DESTINATION "${CMAKE_INSTALL_DATADIR}/clang-doc" COMPONENT clang-doc) - copy_files_to_dst(${asset_dir} ${resource_dir} ${f}) + foreach(config ${CMAKE_CONFIGURATION_
[clang] [llvm] [mlir] [MLIR] Add f8E4M3 IEEE 754 type (PR #97118)
@@ -6532,6 +6534,34 @@ TEST(APFloatTest, Float8E5M2ToDouble) { EXPECT_TRUE(std::isnan(QNaN.convertToDouble())); } +TEST(APFloatTest, Float8E4M3ToDouble) { + APFloat One(APFloat::Float8E4M3(), "1.0"); + EXPECT_EQ(1.0, One.convertToDouble()); + APFloat Two(APFloat::Float8E4M3(), "2.0"); + EXPECT_EQ(2.0, Two.convertToDouble()); + APFloat PosLargest = APFloat::getLargest(APFloat::Float8E4M3(), false); + EXPECT_EQ(240.0F, PosLargest.convertToDouble()); + APFloat NegLargest = APFloat::getLargest(APFloat::Float8E4M3(), true); + EXPECT_EQ(-240.0F, NegLargest.convertToDouble()); + APFloat PosSmallest = + APFloat::getSmallestNormalized(APFloat::Float8E4M3(), false); + EXPECT_EQ(0x1.p-6, PosSmallest.convertToDouble()); + APFloat NegSmallest = + APFloat::getSmallestNormalized(APFloat::Float8E4M3(), true); + EXPECT_EQ(-0x1.p-6, NegSmallest.convertToDouble()); makslevental wrote: Sanity check: this test is basically exactly the same as above except with exponent adjusted? https://github.com/llvm/llvm-project/pull/97118 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [MLIR] Add f8E4M3 IEEE 754 type (PR #97118)
@@ -460,10 +460,10 @@ class alignas(void *) Stmt { unsigned : NumExprBits; static_assert( -llvm::APFloat::S_MaxSemantics < 16, -"Too many Semantics enum values to fit in bitfield of size 4"); +llvm::APFloat::S_MaxSemantics < 32, +"Too many Semantics enum values to fit in bitfield of size 5"); LLVM_PREFERRED_TYPE(llvm::APFloat::Semantics) -unsigned Semantics : 4; // Provides semantics for APFloat construction makslevental wrote: Didn't I see this in another PR you sent? If not, is there a way to separate this into PRs for LLVM/Clang and PRs for MLIR? https://github.com/llvm/llvm-project/pull/97118 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [MLIR] Add f8E4M3 IEEE 754 type (PR #97118)
@@ -136,6 +136,7 @@ static constexpr fltSemantics semIEEEquad = {16383, -16382, 113, 128}; static constexpr fltSemantics semFloat8E5M2 = {15, -14, 3, 8}; static constexpr fltSemantics semFloat8E5M2FNUZ = { 15, -15, 3, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero}; +static constexpr fltSemantics semFloat8E4M3 = {7, -6, 4, 8}; makslevental wrote: Just sanity checking: this is ``` maxExponent = 7 minExponent = -6 precision = 4 sizeInBits = 8 ``` ? https://github.com/llvm/llvm-project/pull/97118 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [MLIR] Add f8E4M3 IEEE 754 type (PR #97118)
https://github.com/makslevental commented: Man talk about boiler plate 😄. Anyway this all looks basically fine. Except for the one ask about splitting this up I think I can approve (modulo the tests passing). I'll double check tomorrow on a bigger screen (currently on my laptop) so I can make sure everything lines up with the copy-pasted tests. https://github.com/llvm/llvm-project/pull/97118 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [MLIR] Add f8E4M3 IEEE 754 type (PR #97118)
https://github.com/makslevental edited https://github.com/llvm/llvm-project/pull/97118 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix erroneous `-Wmissing-prototypes` for Win32 entry points (PR #98105)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/98105 >From f9def27dcbfe6ce1a55fd5c41d15d55b05d9a056 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 8 Jul 2024 19:14:11 -0700 Subject: [PATCH 1/4] Fix erroneous `-Wmissing-prototypes` for Win32 entry points --- clang/lib/Sema/SemaDecl.cpp | 3 +++ clang/test/Sema/no-warn-missing-prototype.c | 27 +++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b3bfdacb01790..b4d8d653616b1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15214,6 +15214,9 @@ ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, if (II->isStr("main") || II->isStr("efi_main")) return false; + if (FD->isMSVCRTEntryPoint()) +return false; + // Don't warn about inline functions. if (FD->isInlined()) return false; diff --git a/clang/test/Sema/no-warn-missing-prototype.c b/clang/test/Sema/no-warn-missing-prototype.c index 6059b6aa0f146..577718c928e59 100644 --- a/clang/test/Sema/no-warn-missing-prototype.c +++ b/clang/test/Sema/no-warn-missing-prototype.c @@ -1,10 +1,33 @@ // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c -ffreestanding -verify %s // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c++ -ffreestanding -verify %s +// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s // expected-no-diagnostics int main() { - return 0; +return 0; } int efi_main() { - return 0; +return 0; } + +#ifdef MS +int wmain(int, wchar_t *[], wchar_t *[]) +{ +return 0; +} + +int wWinMain(void*, void*, wchar_t*, int) +{ +return 0; +} + +int WinMain(void*, void*, char*, int) +{ +return 0; +} + +bool DllMain(void*, unsigned, void*) +{ +return true; +} +#endif \ No newline at end of file >From 1143a06a4b4b7f435c19325bd3b2253cde02372c Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 8 Jul 2024 19:19:07 -0700 Subject: [PATCH 2/4] formatting --- clang/test/Sema/no-warn-missing-prototype.c | 26 + 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/clang/test/Sema/no-warn-missing-prototype.c b/clang/test/Sema/no-warn-missing-prototype.c index 577718c928e59..1b6e8f059fc45 100644 --- a/clang/test/Sema/no-warn-missing-prototype.c +++ b/clang/test/Sema/no-warn-missing-prototype.c @@ -3,31 +3,27 @@ // RUN: %clang_cc1 -fms-compatibility -fsyntax-only -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s // expected-no-diagnostics int main() { -return 0; + return 0; } int efi_main() { -return 0; + return 0; } #ifdef MS -int wmain(int, wchar_t *[], wchar_t *[]) -{ -return 0; +int wmain(int, wchar_t *[], wchar_t *[]) { + return 0; } -int wWinMain(void*, void*, wchar_t*, int) -{ -return 0; +int wWinMain(void*, void*, wchar_t*, int) { + return 0; } -int WinMain(void*, void*, char*, int) -{ -return 0; +int WinMain(void*, void*, char*, int) { + return 0; } -bool DllMain(void*, unsigned, void*) -{ -return true; +bool DllMain(void*, unsigned, void* { + return true; } -#endif \ No newline at end of file +#endif >From bc40af777e31df856de3c68fe749311c8011f21f Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 8 Jul 2024 19:26:29 -0700 Subject: [PATCH 3/4] fix unit test --- clang/test/Sema/no-warn-missing-prototype.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Sema/no-warn-missing-prototype.c b/clang/test/Sema/no-warn-missing-prototype.c index 1b6e8f059fc45..17d69ac8913fa 100644 --- a/clang/test/Sema/no-warn-missing-prototype.c +++ b/clang/test/Sema/no-warn-missing-prototype.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c -ffreestanding -verify %s // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c++ -ffreestanding -verify %s -// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s +// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -Wmissing-prototypes -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s // expected-no-diagnostics int main() { return 0; @@ -23,7 +23,7 @@ int WinMain(void*, void*, char*, int) { return 0; } -bool DllMain(void*, unsigned, void* { +bool DllMain(void*, unsigned, void*) { return true; } #endif >From 5ca6a7feeebdf1db1f79353873e946c990ab4494 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 8 Jul 2024 19:34:49 -0700 Subject: [PATCH 4/4] Add Release Note --- clang/docs/ReleaseNotes.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 36cf615a4287c..0f67a4ed4ea96 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -654,6 +654,9 @@ Improvements to Clang's diagnostics - Clang now shows implicit deduction guides when diagn
[clang] Fix erroneous `-Wmissing-prototypes` for Win32 entry points (PR #98105)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/98105 >From f9def27dcbfe6ce1a55fd5c41d15d55b05d9a056 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 8 Jul 2024 19:14:11 -0700 Subject: [PATCH 1/3] Fix erroneous `-Wmissing-prototypes` for Win32 entry points --- clang/lib/Sema/SemaDecl.cpp | 3 +++ clang/test/Sema/no-warn-missing-prototype.c | 27 +++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b3bfdacb01790..b4d8d653616b1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15214,6 +15214,9 @@ ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, if (II->isStr("main") || II->isStr("efi_main")) return false; + if (FD->isMSVCRTEntryPoint()) +return false; + // Don't warn about inline functions. if (FD->isInlined()) return false; diff --git a/clang/test/Sema/no-warn-missing-prototype.c b/clang/test/Sema/no-warn-missing-prototype.c index 6059b6aa0f146..577718c928e59 100644 --- a/clang/test/Sema/no-warn-missing-prototype.c +++ b/clang/test/Sema/no-warn-missing-prototype.c @@ -1,10 +1,33 @@ // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c -ffreestanding -verify %s // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c++ -ffreestanding -verify %s +// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s // expected-no-diagnostics int main() { - return 0; +return 0; } int efi_main() { - return 0; +return 0; } + +#ifdef MS +int wmain(int, wchar_t *[], wchar_t *[]) +{ +return 0; +} + +int wWinMain(void*, void*, wchar_t*, int) +{ +return 0; +} + +int WinMain(void*, void*, char*, int) +{ +return 0; +} + +bool DllMain(void*, unsigned, void*) +{ +return true; +} +#endif \ No newline at end of file >From 1143a06a4b4b7f435c19325bd3b2253cde02372c Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 8 Jul 2024 19:19:07 -0700 Subject: [PATCH 2/3] formatting --- clang/test/Sema/no-warn-missing-prototype.c | 26 + 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/clang/test/Sema/no-warn-missing-prototype.c b/clang/test/Sema/no-warn-missing-prototype.c index 577718c928e59..1b6e8f059fc45 100644 --- a/clang/test/Sema/no-warn-missing-prototype.c +++ b/clang/test/Sema/no-warn-missing-prototype.c @@ -3,31 +3,27 @@ // RUN: %clang_cc1 -fms-compatibility -fsyntax-only -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s // expected-no-diagnostics int main() { -return 0; + return 0; } int efi_main() { -return 0; + return 0; } #ifdef MS -int wmain(int, wchar_t *[], wchar_t *[]) -{ -return 0; +int wmain(int, wchar_t *[], wchar_t *[]) { + return 0; } -int wWinMain(void*, void*, wchar_t*, int) -{ -return 0; +int wWinMain(void*, void*, wchar_t*, int) { + return 0; } -int WinMain(void*, void*, char*, int) -{ -return 0; +int WinMain(void*, void*, char*, int) { + return 0; } -bool DllMain(void*, unsigned, void*) -{ -return true; +bool DllMain(void*, unsigned, void* { + return true; } -#endif \ No newline at end of file +#endif >From bc40af777e31df856de3c68fe749311c8011f21f Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 8 Jul 2024 19:26:29 -0700 Subject: [PATCH 3/3] fix unit test --- clang/test/Sema/no-warn-missing-prototype.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Sema/no-warn-missing-prototype.c b/clang/test/Sema/no-warn-missing-prototype.c index 1b6e8f059fc45..17d69ac8913fa 100644 --- a/clang/test/Sema/no-warn-missing-prototype.c +++ b/clang/test/Sema/no-warn-missing-prototype.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c -ffreestanding -verify %s // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c++ -ffreestanding -verify %s -// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s +// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -Wmissing-prototypes -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s // expected-no-diagnostics int main() { return 0; @@ -23,7 +23,7 @@ int WinMain(void*, void*, char*, int) { return 0; } -bool DllMain(void*, unsigned, void* { +bool DllMain(void*, unsigned, void*) { return true; } #endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix erroneous `-Wmissing-prototypes` for Win32 entry points (PR #98105)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Max Winkler (MaxEW707) Changes Fixes https://github.com/llvm/llvm-project/issues/94366. --- Full diff: https://github.com/llvm/llvm-project/pull/98105.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaDecl.cpp (+3) - (modified) clang/test/Sema/no-warn-missing-prototype.c (+19) ``diff diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b3bfdacb01790..b4d8d653616b1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15214,6 +15214,9 @@ ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, if (II->isStr("main") || II->isStr("efi_main")) return false; + if (FD->isMSVCRTEntryPoint()) +return false; + // Don't warn about inline functions. if (FD->isInlined()) return false; diff --git a/clang/test/Sema/no-warn-missing-prototype.c b/clang/test/Sema/no-warn-missing-prototype.c index 6059b6aa0f146..1b6e8f059fc45 100644 --- a/clang/test/Sema/no-warn-missing-prototype.c +++ b/clang/test/Sema/no-warn-missing-prototype.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c -ffreestanding -verify %s // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c++ -ffreestanding -verify %s +// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s // expected-no-diagnostics int main() { return 0; @@ -8,3 +9,21 @@ int main() { int efi_main() { return 0; } + +#ifdef MS +int wmain(int, wchar_t *[], wchar_t *[]) { + return 0; +} + +int wWinMain(void*, void*, wchar_t*, int) { + return 0; +} + +int WinMain(void*, void*, char*, int) { + return 0; +} + +bool DllMain(void*, unsigned, void* { + return true; +} +#endif `` https://github.com/llvm/llvm-project/pull/98105 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix erroneous `-Wmissing-prototypes` for Win32 entry points (PR #98105)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/98105 Fixes https://github.com/llvm/llvm-project/issues/94366. >From f9def27dcbfe6ce1a55fd5c41d15d55b05d9a056 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 8 Jul 2024 19:14:11 -0700 Subject: [PATCH 1/2] Fix erroneous `-Wmissing-prototypes` for Win32 entry points --- clang/lib/Sema/SemaDecl.cpp | 3 +++ clang/test/Sema/no-warn-missing-prototype.c | 27 +++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b3bfdacb01790..b4d8d653616b1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15214,6 +15214,9 @@ ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, if (II->isStr("main") || II->isStr("efi_main")) return false; + if (FD->isMSVCRTEntryPoint()) +return false; + // Don't warn about inline functions. if (FD->isInlined()) return false; diff --git a/clang/test/Sema/no-warn-missing-prototype.c b/clang/test/Sema/no-warn-missing-prototype.c index 6059b6aa0f146..577718c928e59 100644 --- a/clang/test/Sema/no-warn-missing-prototype.c +++ b/clang/test/Sema/no-warn-missing-prototype.c @@ -1,10 +1,33 @@ // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c -ffreestanding -verify %s // RUN: %clang_cc1 -fsyntax-only -Wmissing-prototypes -x c++ -ffreestanding -verify %s +// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s // expected-no-diagnostics int main() { - return 0; +return 0; } int efi_main() { - return 0; +return 0; } + +#ifdef MS +int wmain(int, wchar_t *[], wchar_t *[]) +{ +return 0; +} + +int wWinMain(void*, void*, wchar_t*, int) +{ +return 0; +} + +int WinMain(void*, void*, char*, int) +{ +return 0; +} + +bool DllMain(void*, unsigned, void*) +{ +return true; +} +#endif \ No newline at end of file >From 1143a06a4b4b7f435c19325bd3b2253cde02372c Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 8 Jul 2024 19:19:07 -0700 Subject: [PATCH 2/2] formatting --- clang/test/Sema/no-warn-missing-prototype.c | 26 + 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/clang/test/Sema/no-warn-missing-prototype.c b/clang/test/Sema/no-warn-missing-prototype.c index 577718c928e59..1b6e8f059fc45 100644 --- a/clang/test/Sema/no-warn-missing-prototype.c +++ b/clang/test/Sema/no-warn-missing-prototype.c @@ -3,31 +3,27 @@ // RUN: %clang_cc1 -fms-compatibility -fsyntax-only -x c++ -ffreestanding -triple=x86_64-pc-win32 -verify -DMS %s // expected-no-diagnostics int main() { -return 0; + return 0; } int efi_main() { -return 0; + return 0; } #ifdef MS -int wmain(int, wchar_t *[], wchar_t *[]) -{ -return 0; +int wmain(int, wchar_t *[], wchar_t *[]) { + return 0; } -int wWinMain(void*, void*, wchar_t*, int) -{ -return 0; +int wWinMain(void*, void*, wchar_t*, int) { + return 0; } -int WinMain(void*, void*, char*, int) -{ -return 0; +int WinMain(void*, void*, char*, int) { + return 0; } -bool DllMain(void*, unsigned, void*) -{ -return true; +bool DllMain(void*, unsigned, void* { + return true; } -#endif \ No newline at end of file +#endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -470,13 +892,15 @@ void SemaHLSL::handleResourceBindingAttr(Decl *D, const ParsedAttr &AL) { // Validate. if (!Slot.empty()) { switch (Slot[0]) { +case 't': case 'u': case 'b': case 's': -case 't': +case 'c': +case 'i': break; default: - Diag(ArgLoc, diag::err_hlsl_unsupported_register_type) + Diag(ArgLoc, diag::err_hlsl_unsupported_register_type_and_resource_type) bob80905 wrote: Test added in resource_binding_attr_error.hlsl https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Support --sysroot= for ${arch}-windows-msvc targets (PR #96417)
https://github.com/trcrsired updated https://github.com/llvm/llvm-project/pull/96417 >From 1458330d0f32c530ac15793cdc03439975d79928 Mon Sep 17 00:00:00 2001 From: trcrsired Date: Sun, 23 Jun 2024 00:07:19 -0400 Subject: [PATCH] Support --sysroot= for ${arch}-windows-msvc targets I think it is possible to use the same rule for msvc targets with --target= and --sysroot= See Repository: https://github.com/trcrsired/windows-msvc-sysroot Add sysroot support for msvc MSVC.cpp needs getDriver before using D add stl in parser for -stdlib= Add Vcruntime to runtime list and unwind list MSVC add default runtime lib type and default unwind lib type add a msvc sysroot test use %S instead of /foo Fix test for msvc-sysroot Also add a pesudo implementation for WebAssembly and maybe Microsoft STL could be ported to more targets in the future Fix the toggle of wasm that prevents -stdlib=stl passed into Avoid clang-formatting in MSVC.cpp Add some comments to ToolChain avoid indent the if block Add back space before winsysroot line use instead of arch in the comment remove FIXME for libc++ since we have added the logic here Remove MSVC.h formatting Remove default cases in WebAssembly add back the empty line before the Sysroot line fix msvc-sysroot typo for libc++ loongarch Fix : missing in CST_Stl case --- clang/include/clang/Driver/ToolChain.h | 11 +- clang/lib/Driver/ToolChain.cpp | 10 ++ clang/lib/Driver/ToolChains/MSVC.cpp| 128 +++- clang/lib/Driver/ToolChains/MSVC.h | 15 +++ clang/lib/Driver/ToolChains/WebAssembly.cpp | 25 clang/lib/Driver/ToolChains/WebAssembly.h | 2 + clang/test/Driver/msvc-sysroot.cpp | 81 + clang/test/Driver/wasm-toolchain.cpp| 12 ++ 8 files changed, 279 insertions(+), 5 deletions(-) create mode 100644 clang/test/Driver/msvc-sysroot.cpp diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index ece1384d5d3c0..a7483a89d9ff1 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -94,19 +94,22 @@ class ToolChain { using path_list = SmallVector; enum CXXStdlibType { -CST_Libcxx, -CST_Libstdcxx +CST_Libcxx, // LLVM libc++ +CST_Libstdcxx, // GNU libstdc++ +CST_Stl, // MSVC STL }; enum RuntimeLibType { RLT_CompilerRT, -RLT_Libgcc +RLT_Libgcc, +RLT_Vcruntime }; enum UnwindLibType { UNW_None, UNW_CompilerRT, -UNW_Libgcc +UNW_Libgcc, +UNW_Vcruntime }; enum class UnwindTableLevel { diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 977e08390800d..ed4a73c80c0b7 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1097,6 +1097,8 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( runtimeLibType = ToolChain::RLT_CompilerRT; else if (LibName == "libgcc") runtimeLibType = ToolChain::RLT_Libgcc; + else if (LibName == "vcruntime") +runtimeLibType = ToolChain::RLT_Vcruntime; else if (LibName == "platform") runtimeLibType = GetDefaultRuntimeLibType(); else { @@ -1135,6 +1137,8 @@ ToolChain::UnwindLibType ToolChain::GetUnwindLibType( unwindLibType = ToolChain::UNW_CompilerRT; } else if (LibName == "libgcc") unwindLibType = ToolChain::UNW_Libgcc; + else if (LibName == "vcruntime") +unwindLibType = ToolChain::UNW_Vcruntime; else { if (A) getDriver().Diag(diag::err_drv_invalid_unwindlib_name) @@ -1158,6 +1162,8 @@ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ cxxStdlibType = ToolChain::CST_Libcxx; else if (LibName == "libstdc++") cxxStdlibType = ToolChain::CST_Libstdcxx; + else if (LibName == "stl") +cxxStdlibType = ToolChain::CST_Stl; else if (LibName == "platform") cxxStdlibType = GetDefaultCXXStdlibType(); else { @@ -1296,6 +1302,10 @@ void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args, case ToolChain::CST_Libstdcxx: CmdArgs.push_back("-lstdc++"); break; + + case ToolChain::CST_Stl: +// MSVC STL does not need to add -l +break; } } diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index ca266e3e1d1d3..ad89003ed1c33 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -90,6 +90,16 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-defaultlib:oldnames"); } + auto SysRoot = TC.getDriver().SysRoot; + if (!SysRoot.empty()) { +// If we have --sysroot, then we ignore all other setings +// libpath is $SYSROOT/lib and $SYSROOT/lib/${ARCH}-unknown-windows-msvc +const std::string MultiarchTriple = +TC.getMultiarchTriple(TC.getDriver(), TC.getTriple(), SysRoot); +std::string SysRootLib = "-libpath:" + SysRoot + "/lib"; +CmdArgs.pu
[clang] [llvm] [AsmPrinter] Don't check for inlineasm dialect on non-X86 platforms (PR #98097)
https://github.com/dtellenbach edited https://github.com/llvm/llvm-project/pull/98097 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AsmPrinter] Don't check for inlineasm dialect on non-X86 platforms (PR #98097)
@@ -0,0 +1,23 @@ +// REQUIRES: aarch64-registered-target dtellenbach wrote: Yep, seems like I accidentally added a new folder. Targets other than AArch64 and Arm use a subfolder but still rely on `REQUIRES`. AArch64 just dumps everything into the top-level test folder and thus have to rely on `REQUIRES`. I now move the test up to `test/CodeGen` and stick with `REQUIRES`. Should be reworked but not in this patch. https://github.com/llvm/llvm-project/pull/98097 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AsmPrinter] Don't check for inlineasm dialect on non-X86 platforms (PR #98097)
https://github.com/dtellenbach updated https://github.com/llvm/llvm-project/pull/98097 >From 46e32d1156e38653c79682600fbf63d964277dba Mon Sep 17 00:00:00 2001 From: David Tellenbach Date: Mon, 8 Jul 2024 16:04:18 -0700 Subject: [PATCH 1/2] [AsmPrinter] Don't check for inlineasm dialect on non-X86 platforms AArch64 uses MCAsmInfo::AssemblerDialect to control the style of emitted Neon assembly. E.g. Apple platforms use AsmWriterVariantTy::Apple by default which collides with InlineAsm::AD_Intel (both value 1). Checking for inlineasm dialects on non-X86 platforms can thus lead to problems. --- clang/test/CodeGen/AArch64/inline-asm-ios.c | 23 +++ .../AsmPrinter/AsmPrinterInlineAsm.cpp| 14 +++ 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGen/AArch64/inline-asm-ios.c diff --git a/clang/test/CodeGen/AArch64/inline-asm-ios.c b/clang/test/CodeGen/AArch64/inline-asm-ios.c new file mode 100644 index 0..5e7328a15f69d --- /dev/null +++ b/clang/test/CodeGen/AArch64/inline-asm-ios.c @@ -0,0 +1,23 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple arm64-apple-ios -S -o - %s | FileCheck %s + +// CHECK: _restartable_function: +// CHECK-NEXT: ldr x11, [x0] +// CHECK-NEXT: add x11, x11, #1 +// CHECK-NEXT: str x11, [x0] +// CHECK-NEXT: Ltmp0: +// CHECK-NEXT: b Ltmp0 +// CHECK-NEXT: LExit_restartable_function: +// CHECK-NEXT: ret +asm(".align 4\n" +".text\n" +".private_extern _restartable_function\n" +"_restartable_function:\n" +"ldrx11, [x0]\n" +"addx11, x11, #1\n" +"strx11, [x0]\n" +"1:\n" +"b 1b\n" +"LExit_restartable_function:\n" +"ret\n" +); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index 5a7013c964cb4..6fe8d0e0af995 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -113,12 +113,16 @@ void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI, if (!TAP) report_fatal_error("Inline asm not supported by this streamer because" " we don't have an asm parser for this target\n"); - Parser->setAssemblerDialect(Dialect); + + // Respect inlineasm dialect on X86 targets only + if (TM.getTargetTriple().isX86()) { +Parser->setAssemblerDialect(Dialect); +// Enable lexing Masm binary and hex integer literals in intel inline +// assembly. +if (Dialect == InlineAsm::AD_Intel) + Parser->getLexer().setLexMasmIntegers(true); + } Parser->setTargetParser(*TAP); - // Enable lexing Masm binary and hex integer literals in intel inline - // assembly. - if (Dialect == InlineAsm::AD_Intel) -Parser->getLexer().setLexMasmIntegers(true); emitInlineAsmStart(); // Don't implicitly switch to the text section before the asm. >From ca81fa117841a551702d678a6402a3bd98e85f2b Mon Sep 17 00:00:00 2001 From: David Tellenbach Date: Mon, 8 Jul 2024 18:38:32 -0700 Subject: [PATCH 2/2] Move test up into clang/test/CodeGen instead of target specific folder --- .../CodeGen/{AArch64/inline-asm-ios.c => aarch64-inlineasm-ios.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clang/test/CodeGen/{AArch64/inline-asm-ios.c => aarch64-inlineasm-ios.c} (100%) diff --git a/clang/test/CodeGen/AArch64/inline-asm-ios.c b/clang/test/CodeGen/aarch64-inlineasm-ios.c similarity index 100% rename from clang/test/CodeGen/AArch64/inline-asm-ios.c rename to clang/test/CodeGen/aarch64-inlineasm-ios.c ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] fix sema init crash for not checking a ExprResult (PR #98102)
@@ -5576,6 +5576,10 @@ static void TryOrBuildParenListInitialization( ExprResult ER; ER = IS.Perform(S, SubEntity, SubKind, Arg ? MultiExprArg(Arg) : std::nullopt); + + if (ER.IsInvalid()) +return false; + if (InitExpr) *InitExpr = ER.get(); yuxuanchen1997 wrote: ER.get() is null if we don't apply this fix. https://github.com/llvm/llvm-project/pull/98102 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] fix sema init crash for not checking a ExprResult (PR #98102)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Yuxuan Chen (yuxuanchen1997) Changes We ran into a FE crash and root caused to `ER.get()` on line 5584 here being nullptr. I think this is a result of not checking if ER here is invalid. We have been using automated reduction tools (like CReduce) for a while and it is not performing well and would like to ask upstream opinions on whether this condition here is handled correctly. Preferably with help to write a small, well contained crash-on-valid test case. I do have a crash-on-invalid test [here](https://gist.github.com/yuxuanchen1997/2bbfc1b9d78fe43ed8784a5db11eac98), would really appreciate any pointers. --- Full diff: https://github.com/llvm/llvm-project/pull/98102.diff 1 Files Affected: - (modified) clang/lib/Sema/SemaInit.cpp (+4) ``diff diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 41753a1661ace..80286302e9b9d 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -5576,6 +5576,10 @@ static void TryOrBuildParenListInitialization( ExprResult ER; ER = IS.Perform(S, SubEntity, SubKind, Arg ? MultiExprArg(Arg) : std::nullopt); + + if (ER.IsInvalid()) +return false; + if (InitExpr) *InitExpr = ER.get(); else `` https://github.com/llvm/llvm-project/pull/98102 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] fix sema init crash for not checking a ExprResult (PR #98102)
https://github.com/yuxuanchen1997 created https://github.com/llvm/llvm-project/pull/98102 We ran into a FE crash and root caused to `ER.get()` on line 5584 here being nullptr. I think this is a result of not checking if ER here is invalid. We have been using automated reduction tools (like CReduce) for a while and it is not performing well and would like to ask upstream opinions on whether this condition here is handled correctly. Preferably with help to write a small, well contained crash-on-valid test case. I do have a crash-on-invalid test [here](https://gist.github.com/yuxuanchen1997/2bbfc1b9d78fe43ed8784a5db11eac98), would really appreciate any pointers. >From 82e3cb025e8eafdae5f7ee42fc9d14235d5b Mon Sep 17 00:00:00 2001 From: Yuxuan Chen Date: Mon, 8 Jul 2024 18:16:17 -0700 Subject: [PATCH] [clang] fix sema init crash for not checking a ExprResult --- clang/lib/Sema/SemaInit.cpp | 4 1 file changed, 4 insertions(+) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 41753a1661ace..80286302e9b9d 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -5576,6 +5576,10 @@ static void TryOrBuildParenListInitialization( ExprResult ER; ER = IS.Perform(S, SubEntity, SubKind, Arg ? MultiExprArg(Arg) : std::nullopt); + + if (ER.IsInvalid()) +return false; + if (InitExpr) *InitExpr = ER.get(); else ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -470,13 +892,15 @@ void SemaHLSL::handleResourceBindingAttr(Decl *D, const ParsedAttr &AL) { // Validate. if (!Slot.empty()) { switch (Slot[0]) { +case 't': case 'u': case 'b': case 's': -case 't': +case 'c': +case 'i': break; default: - Diag(ArgLoc, diag::err_hlsl_unsupported_register_type) + Diag(ArgLoc, diag::err_hlsl_unsupported_register_type_and_resource_type) damyanp wrote: Is there a test for this? https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Handle empty structs/unions passing in C++ (PR #97315)
topperc wrote: > Could someone please merge this change? I do not have permissions to do so. Done https://github.com/llvm/llvm-project/pull/97315 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Handle empty structs/unions passing in C++ (PR #97315)
https://github.com/topperc closed https://github.com/llvm/llvm-project/pull/97315 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d65f423 - [RISCV] Handle empty structs/unions passing in C++ (#97315)
Author: Sudharsan Veeravalli Date: 2024-07-08T18:17:51-07:00 New Revision: d65f4232026a6c0fcd2431e1d28a7ad49127f6e5 URL: https://github.com/llvm/llvm-project/commit/d65f4232026a6c0fcd2431e1d28a7ad49127f6e5 DIFF: https://github.com/llvm/llvm-project/commit/d65f4232026a6c0fcd2431e1d28a7ad49127f6e5.diff LOG: [RISCV] Handle empty structs/unions passing in C++ (#97315) According to RISC-V integer calling convention empty structs or union arguments or return values are ignored by C compilers which support them as a non-standard extension. This is not the case for C++, which requires them to be sized types. Fixes #97285 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/CodeGen/Targets/RISCV.cpp clang/test/CodeGen/RISCV/abi-empty-structs.c Removed: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 838cb69f647ee..e086b4fa43743 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1084,6 +1084,7 @@ RISC-V Support - ``__attribute__((rvv_vector_bits(N)))`` is now supported for RVV vbool*_t types. - Profile names in ``-march`` option are now supported. +- Passing empty structs/unions as arguments in C++ is now handled correctly. The behavior is similar to GCC's. CUDA/HIP Language Changes ^ diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index a4c5ec315b8df..f2add9351c03c 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -361,12 +361,13 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, CGCXXABI::RAA_DirectInMemory); } - // Ignore empty structs/unions. - if (isEmptyRecord(getContext(), Ty, true)) -return ABIArgInfo::getIgnore(); - uint64_t Size = getContext().getTypeSize(Ty); + // Ignore empty structs/unions whose size is zero. According to the calling + // convention empty structs/unions are required to be sized types in C++. + if (isEmptyRecord(getContext(), Ty, true) && Size == 0) +return ABIArgInfo::getIgnore(); + // Pass floating point values via FPRs if possible. if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() && FLen >= Size && ArgFPRsLeft) { diff --git a/clang/test/CodeGen/RISCV/abi-empty-structs.c b/clang/test/CodeGen/RISCV/abi-empty-structs.c index c48a2891627d4..5157165787fcb 100644 --- a/clang/test/CodeGen/RISCV/abi-empty-structs.c +++ b/clang/test/CodeGen/RISCV/abi-empty-structs.c @@ -167,6 +167,61 @@ struct s9 { // void test_s9(struct s9 a) {} +struct s10 { }; +// CHECK-C-LABEL: define dso_local void @test_s10 +// CHECK-C-SAME: () #[[ATTR0]] { +// CHECK-C: entry: +// +// CHECK32-CXX-LABEL: define dso_local i32 @_Z8test_s103s10 +// CHECK32-CXX-SAME: (i32 [[A_COERCE:%.*]]) #[[ATTR0]] { +// CHECK32-CXX: entry: +// +// CHECK64-CXX-LABEL: define dso_local i64 @_Z8test_s103s10 +// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] { +// CHECK64-CXX: entry: +// +struct s10 test_s10(struct s10 a) { + return a; +} + +struct s11 { int : 0; }; +// CHECK-C-LABEL: define dso_local void @test_s11 +// CHECK-C-SAME: () #[[ATTR0]] { +// CHECK-C: entry: +// +// CHECK32-CXX-LABEL: define dso_local i32 @_Z8test_s113s11 +// CHECK32-CXX-SAME: (i32 [[A_COERCE:%.*]]) #[[ATTR0]] { +// CHECK32-CXX: entry: +// +// CHECK64-CXX-LABEL: define dso_local i64 @_Z8test_s113s11 +// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] { +// CHECK64-CXX: entry: +// +struct s11 test_s11(struct s11 a) { + return a; +} + +struct s12 {int x[0];}; +// CHECK32-C-LABEL: define dso_local i32 @test_s12 +// CHECK32-C-SAME: (i32 noundef [[I1:%.*]], i32 noundef [[I2:%.*]]) #[[ATTR0]] { +// CHECK32-C: entry: +// +// CHECK64-C-LABEL: define dso_local signext i32 @test_s12 +// CHECK64-C-SAME: (i32 noundef signext [[I1:%.*]], i32 noundef signext [[I2:%.*]]) #[[ATTR0]] { +// CHECK64-C: entry: +// +// CHECK32-CXX-LABEL: define dso_local noundef i32 @_Z8test_s12i3s12i +// CHECK32-CXX-SAME: (i32 noundef [[I1:%.*]], i32 noundef [[I2:%.*]]) #[[ATTR0]] { +// CHECK32-CXX: entry: +// +// CHECK64-CXX-LABEL: define dso_local noundef signext i32 @_Z8test_s12i3s12i +// CHECK64-CXX-SAME: (i32 noundef signext [[I1:%.*]], i32 noundef signext [[I2:%.*]]) #[[ATTR0]] { +// CHECK64-CXX: entry: +// +int test_s12(int32_t i1, struct s12 a, int32_t i2) { + return i2; +} + NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: // CHECK32-C: {{.*}} // CHECK64-C: {{.*}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
https://github.com/bob80905 edited https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// TODO: Implement "Buffer" +struct Eg1 { + float f; + // Buffer Buf; + RWBuffer RWBuf; + }; +Eg1 e1 : /* register(t0) :*/ register(u0); +// Valid: f is skipped, Buf is bound to t0, RWBuf is bound to u0 + + +struct Eg2 { + float f; + // Buffer Buf; + RWBuffer RWBuf; + RWBuffer RWBuf2; + }; +Eg2 e2 : /* register(t0) :*/ register(u0); +// Valid: f is skipped, Buf is bound to t0, RWBuf is bound to u0. +// RWBuf2 gets automatically assigned to u1 even though there is no explicit binding for u1. + +/* +struct Eg3 { + float f; + // Buffer Buf; + }; +Eg3 e3 : register(t0) : register(u0); +// Valid: Buf gets bound to t0. Buf will also be bound to u0. +*/ + +struct Eg4 { + struct Bar { +RWBuffer a; +}; +Bar b; +}; +Eg4 e4 : register(u0); +// Valid: Bar, the struct within Eg4, has a valid resource that can be bound to t0. + +/* Light up this test when SamplerState is implemented +struct Eg5 { + SamplerState s[3]; +}; + +Eg5 e5 : register(s5); +// Valid: the first sampler state object within Eg5's s is bound to slot 5 +*/ + +struct Eg6 { + float f; +}; +// expected-warning@+1{{variable of type 'Eg6' bound to register type 't' does not contain a matching 'srv' resource}} +Eg6 e6 : register(t0); + +struct Eg7 { + struct Bar { +float f; + }; + Bar b; +}; +// expected-warning@+1{{variable of type 'Eg7' bound to register type 't' does not contain a matching 'srv' resource}} +Eg7 e7 : register(t0); + +struct Eg8 { + RWBuffer a; +}; +// expected-warning@+1{{register 'c' used on type with no contents to allocate in a constant buffer}} +Eg8 e8 : register(c0); + + +struct Eg9{ + // expected-error@+1{{'register' attribute only applies to cbuffer/tbuffer and external global variables}} + RWBuffer a : register(u9); +}; + +Eg9 e9; + + +/* Light up this test when Texture2D is implemented +template +struct Eg10 { +R b; +}; +// expecting warning: {{variable of type 'Eg10' bound to register type 'u' does not contain a matching 'uav' resource}} +Eg10 e10 : register(u0); + +// invalid because after template expansion, there are no valid resources inside Eg10 to bind as a UAV. +*/ + +struct Eg11{ + RWBuffer a; + RWBuffer b; +}; + +// expected-error@+1{{conflicting register annotations: multiple register numbers detected for register type 'u'}} +Eg11 e11 : register(u9) : register(u10); bob80905 wrote: This isn't a conflict in DXC, and no errors are reported: https://godbolt.org/z/1dGTcdrW4 I think it's worth adding to the test, but I don't think we should expect any errors from it, since the variable is being bound to 2 different logical registers at the same virtual register number. Also there's this quote according to the docs on the register keyword: > register(t3, space0) will never conflict with register(t3, space1), nor with > any array in another space that might include t3. Which can be found here: https://learn.microsoft.com/en-us/windows/win32/direct3d12/resource-binding-in-hlsl https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Handle empty structs/unions passing in C++ (PR #97315)
svs-quic wrote: Could someone please merge this change? I do not have permissions to do so. https://github.com/llvm/llvm-project/pull/97315 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
https://github.com/llvm-beanz edited https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +453,409 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct RegisterBindingFlags { + bool Resource = false; + bool Udt = false; + bool Other = false; + bool Basic = false; + + bool Srv = false; + bool Uav = false; + bool Cbv = false; + bool Sampler = false; + + bool ContainsNumeric = false; + bool DefaultGlobals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { llvm-beanz wrote: Take a pass over the parameter names and local variables you’re adding. They should match the style guide: https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +453,409 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct RegisterBindingFlags { + bool Resource = false; + bool Udt = false; + bool Other = false; + bool Basic = false; + + bool Srv = false; + bool Uav = false; + bool Cbv = false; + bool Sampler = false; + + bool ContainsNumeric = false; + bool DefaultGlobals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *VD) { + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + return TheRecordDecl; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *VD, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (VD) { +const CXXRecordDecl *TheRecordDecl = getRecordDeclFromVarDecl(VD); +if (!TheRecordDecl) + return nullptr; +const auto *Attr = TheRecordDecl->getAttr(); +return Attr; + } else if (CBufferOrTBuffer) { +const auto *Attr = CBufferOrTBuffer->getAttr(); +return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType T, RegisterBindingFlags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.ContainsNumeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { +RecordDecl *SubRD = RT->getDecl(); +if (auto TDecl = dyn_cast(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.Srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.Uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.Cbv = true; +break; + } + case llvm::hlsl::ResourceClass::Sampler: { +r.Sampler = true; +break; + } + } +} + +else if (SubRD->isCompleteDefinition()) { + for (auto Field : SubRD->fields()) { +QualType T = Field->getType(); +traverseType(T, r); + } +} + } +} + +void setResourceClassFlagsFromRecordDecl(RegisterBindingFlags &r, + const RecordDecl *RD) { + if (!RD) +return; + + if (RD->isCompleteDefinition()) { +for (auto Field : RD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); +} + } +} + +RegisterBindingFlags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { + RegisterBindingFlags r; + if (!isDeclaredWithinCOrTBuffer(D)) { +// make sure the type is a basic / numeric type +if (VarDecl *v = dyn_cast(D)) { + QualType t = v->getType(); + // a numeric variable will inevitably end up in $Globals buffer + if (t->isIntegralType(S.getASTContext()) || t->isFloatingType()) +r.DefaultGlobals = true; +} + } + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(D); + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *VD = dyn_cast(D); + + if (CBufferOrTBuffer) { +r.Resource = true; +if (CBufferOrTBuffer->isCBuffer()) + r.Cbv = true; +else + r.Srv = true; + } else if (VD) { +const HLSLResourceAttr *res_attr = +getHLSLResourceAttrFromEitherDecl(VD, CBufferOrTBuffer); +if (res_attr) { + llvm::hlsl::ResourceClass DeclResourceClass = + res_attr->getResourceClass(); + r.Resource = true; + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.Srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.Uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.Cbv = true; +break; + } + case llvm::hlsl::ResourceClass::Sampler: { +r.Sampler = true; +break; + } + } +} else { + if (VD->getType()->isBuil
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +453,409 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct RegisterBindingFlags { + bool Resource = false; + bool Udt = false; + bool Other = false; + bool Basic = false; + + bool Srv = false; + bool Uav = false; + bool Cbv = false; + bool Sampler = false; + + bool ContainsNumeric = false; + bool DefaultGlobals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *VD) { + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + return TheRecordDecl; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *VD, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (VD) { +const CXXRecordDecl *TheRecordDecl = getRecordDeclFromVarDecl(VD); +if (!TheRecordDecl) + return nullptr; +const auto *Attr = TheRecordDecl->getAttr(); +return Attr; + } else if (CBufferOrTBuffer) { +const auto *Attr = CBufferOrTBuffer->getAttr(); +return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType T, RegisterBindingFlags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.ContainsNumeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { llvm-beanz wrote: nit: Don’t use `else` after a return (see: https://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return) This functions nesting also gets pretty deep, you could use an early return to flatten it (see: https://llvm.org/docs/CodingStandards.html#use-early-exits-and-continue-to-simplify-code). https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +453,409 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct RegisterBindingFlags { + bool Resource = false; + bool Udt = false; + bool Other = false; + bool Basic = false; + + bool Srv = false; + bool Uav = false; + bool Cbv = false; + bool Sampler = false; + + bool ContainsNumeric = false; + bool DefaultGlobals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { llvm-beanz wrote: What are the cases where we need to traverse up more than one level here? https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +453,409 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct RegisterBindingFlags { + bool Resource = false; + bool Udt = false; + bool Other = false; + bool Basic = false; + + bool Srv = false; + bool Uav = false; + bool Cbv = false; + bool Sampler = false; + + bool ContainsNumeric = false; + bool DefaultGlobals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *VD) { + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + return TheRecordDecl; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *VD, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (VD) { +const CXXRecordDecl *TheRecordDecl = getRecordDeclFromVarDecl(VD); +if (!TheRecordDecl) + return nullptr; +const auto *Attr = TheRecordDecl->getAttr(); +return Attr; + } else if (CBufferOrTBuffer) { +const auto *Attr = CBufferOrTBuffer->getAttr(); +return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType T, RegisterBindingFlags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.ContainsNumeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { +RecordDecl *SubRD = RT->getDecl(); +if (auto TDecl = dyn_cast(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { llvm-beanz wrote: nit: the braces on these case labels add a lot of extra braces, but the scoping isn’t particularly useful. https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -490,34 +490,36 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() { } /// Set up common members and attributes for buffer types -static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, - ResourceClass RC, ResourceKind RK, - bool IsROV) { +static BuiltinTypeDeclBuilder setupBufferHandle(CXXRecordDecl *Decl, Sema &S, +ResourceClass RC) { llvm-beanz wrote: Am I correct in reading this that you’re moving the attribute from the `onCompletion` handler to the forward declaration so that the type is always attributed? https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +453,409 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct RegisterBindingFlags { + bool Resource = false; + bool Udt = false; + bool Other = false; + bool Basic = false; + + bool Srv = false; + bool Uav = false; + bool Cbv = false; + bool Sampler = false; + + bool ContainsNumeric = false; + bool DefaultGlobals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *VD) { + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } llvm-beanz wrote: nit: Avoid braces on simple single-line expressions (see: https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements). nit: Use auto for cases where the type is obvious (see: https://llvm.org/docs/CodingStandards.html#use-auto-type-deduction-to-make-code-more-readable). ```suggestion if (const auto *BTy = dyn_cast(Ty)) return nullptr; ``` https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +453,409 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct RegisterBindingFlags { + bool Resource = false; + bool Udt = false; + bool Other = false; + bool Basic = false; + + bool Srv = false; + bool Uav = false; + bool Cbv = false; llvm-beanz wrote: UDT, SRV, UAV, and CBV are all initialisms, it probably makes the most sense to fully capitalize them. https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +453,409 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct RegisterBindingFlags { + bool Resource = false; + bool Udt = false; + bool Other = false; + bool Basic = false; + + bool Srv = false; + bool Uav = false; + bool Cbv = false; + bool Sampler = false; + + bool ContainsNumeric = false; + bool DefaultGlobals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *VD) { + const Type *Ty = VD->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); llvm-beanz wrote: A condition body should never just be an assert or unreachable. ```suggestion assert(Ty && "Resource class must have an element type."); ``` https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -38,6 +38,22 @@ Decl *SemaHLSL::ActOnStartBuffer(Scope *BufferScope, bool CBuffer, HLSLBufferDecl *Result = HLSLBufferDecl::Create( getASTContext(), LexicalParent, CBuffer, KwLoc, Ident, IdentLoc, LBrace); + HLSLResourceAttr *NewAttr; + if (CBuffer) { +NewAttr = HLSLResourceAttr::CreateImplicit( +getASTContext(), llvm::hlsl::ResourceClass::CBuffer, +llvm::hlsl::ResourceKind::CBuffer, +/*IsROV=*/false); + } + // tbuffer case + else { +NewAttr = HLSLResourceAttr::CreateImplicit( +getASTContext(), llvm::hlsl::ResourceClass::SRV, +llvm::hlsl::ResourceKind::TBuffer, +/*IsROV=*/false); + } + Result->addAttr(NewAttr); llvm-beanz wrote: ```suggestion auto RC = CBuffer ? llvm::hlsl::ResourceClass::CBuffer : llvm::hlsl::ResourceClass::SRV; auto RK = CBuffer ? llvm::hlsl::ResourceKind::CBuffer : llvm::hlsl::ResourceKind::TBuffer D->addAttr(HLSLResourceAttr::CreateImplicit(getASTContext(),RC, RK, /*IsROV=*/false)); ``` nit: the formatting for this is off, but I think this is a simpler way to write it. https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
https://github.com/llvm-beanz commented: I’ll give this a deeper read tomorrow, but I’ve left some comments mostly on coding convention and style issues. https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +460,406 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct register_binding_flags { + bool resource = false; + bool udt = false; + bool other = false; + bool basic = false; + + bool srv = false; + bool uav = false; + bool cbv = false; + bool sampler = false; + + bool contains_numeric = false; + bool default_globals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *SamplerUAVOrSRV) { + const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + return TheRecordDecl; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *SamplerUAVOrSRV, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (SamplerUAVOrSRV) { +const CXXRecordDecl *TheRecordDecl = +getRecordDeclFromVarDecl(SamplerUAVOrSRV); +if (!TheRecordDecl) + return nullptr; +const auto *Attr = TheRecordDecl->getAttr(); +return Attr; + } else if (CBufferOrTBuffer) { +const auto *Attr = CBufferOrTBuffer->getAttr(); +return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType T, register_binding_flags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.contains_numeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { +RecordDecl *SubRD = RT->getDecl(); +if (auto TDecl = dyn_cast(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::ResourceClass::Sampler: { +r.sampler = true; +break; + } + } +} + +else if (SubRD->isCompleteDefinition()) { + for (auto Field : SubRD->fields()) { +QualType T = Field->getType(); +traverseType(T, r); + } +} + } +} + +void setResourceClassFlagsFromRecordDecl(register_binding_flags &r, + const RecordDecl *RD) { + if (!RD) +return; + + if (RD->isCompleteDefinition()) { +for (auto Field : RD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); +} + } +} + +register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { + register_binding_flags r; + if (!isDeclaredWithinCOrTBuffer(D)) { +// make sure the type is a basic / numeric type +if (VarDecl *v = dyn_cast(D)) { + QualType t = v->getType(); + // a numeric variable will inevitably end up in $Globals buffer + if (t->isIntegralType(S.getASTContext()) || t->isFloatingType()) +r.default_globals = true; +} + } + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(D); + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast(D); + + if (CBufferOrTBuffer) { +r.resource = true; +if (CBufferOrTBuffer->isCBuffer()) + r.cbv = true; +else + r.srv = true; + } else if (SamplerUAVOrSRV) { +const HLSLResourceAttr *res_attr = +getHLSLResourceAttrFromEitherDecl(SamplerUAVOrSRV, CBufferOrTBuffer); +if (res_attr) { + llvm::hlsl::ResourceClass DeclResourceClass = + res_attr->getResourceClass(); + r.resource = true; + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::Resour
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +460,406 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct register_binding_flags { + bool resource = false; + bool udt = false; + bool other = false; + bool basic = false; + + bool srv = false; + bool uav = false; + bool cbv = false; + bool sampler = false; + + bool contains_numeric = false; + bool default_globals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *SamplerUAVOrSRV) { + const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + return TheRecordDecl; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *SamplerUAVOrSRV, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (SamplerUAVOrSRV) { +const CXXRecordDecl *TheRecordDecl = +getRecordDeclFromVarDecl(SamplerUAVOrSRV); +if (!TheRecordDecl) + return nullptr; +const auto *Attr = TheRecordDecl->getAttr(); +return Attr; + } else if (CBufferOrTBuffer) { +const auto *Attr = CBufferOrTBuffer->getAttr(); +return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType T, register_binding_flags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.contains_numeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { +RecordDecl *SubRD = RT->getDecl(); +if (auto TDecl = dyn_cast(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::ResourceClass::Sampler: { +r.sampler = true; +break; + } + } +} + +else if (SubRD->isCompleteDefinition()) { + for (auto Field : SubRD->fields()) { +QualType T = Field->getType(); +traverseType(T, r); + } +} + } +} + +void setResourceClassFlagsFromRecordDecl(register_binding_flags &r, + const RecordDecl *RD) { + if (!RD) +return; + + if (RD->isCompleteDefinition()) { +for (auto Field : RD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); +} + } +} + +register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { + register_binding_flags r; + if (!isDeclaredWithinCOrTBuffer(D)) { +// make sure the type is a basic / numeric type +if (VarDecl *v = dyn_cast(D)) { + QualType t = v->getType(); + // a numeric variable will inevitably end up in $Globals buffer + if (t->isIntegralType(S.getASTContext()) || t->isFloatingType()) +r.default_globals = true; +} + } + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(D); + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast(D); + + if (CBufferOrTBuffer) { +r.resource = true; +if (CBufferOrTBuffer->isCBuffer()) + r.cbv = true; +else + r.srv = true; + } else if (SamplerUAVOrSRV) { +const HLSLResourceAttr *res_attr = +getHLSLResourceAttrFromEitherDecl(SamplerUAVOrSRV, CBufferOrTBuffer); +if (res_attr) { + llvm::hlsl::ResourceClass DeclResourceClass = + res_attr->getResourceClass(); + r.resource = true; + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::Resour
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +460,406 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct register_binding_flags { + bool resource = false; + bool udt = false; + bool other = false; + bool basic = false; + + bool srv = false; + bool uav = false; + bool cbv = false; + bool sampler = false; + + bool contains_numeric = false; + bool default_globals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *SamplerUAVOrSRV) { + const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + return TheRecordDecl; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *SamplerUAVOrSRV, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (SamplerUAVOrSRV) { +const CXXRecordDecl *TheRecordDecl = +getRecordDeclFromVarDecl(SamplerUAVOrSRV); +if (!TheRecordDecl) + return nullptr; +const auto *Attr = TheRecordDecl->getAttr(); +return Attr; + } else if (CBufferOrTBuffer) { +const auto *Attr = CBufferOrTBuffer->getAttr(); +return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType T, register_binding_flags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.contains_numeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { +RecordDecl *SubRD = RT->getDecl(); +if (auto TDecl = dyn_cast(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::ResourceClass::Sampler: { +r.sampler = true; +break; + } + } +} + +else if (SubRD->isCompleteDefinition()) { + for (auto Field : SubRD->fields()) { +QualType T = Field->getType(); +traverseType(T, r); + } +} + } +} + +void setResourceClassFlagsFromRecordDecl(register_binding_flags &r, + const RecordDecl *RD) { + if (!RD) +return; + + if (RD->isCompleteDefinition()) { +for (auto Field : RD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); +} + } +} + +register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { + register_binding_flags r; + if (!isDeclaredWithinCOrTBuffer(D)) { +// make sure the type is a basic / numeric type +if (VarDecl *v = dyn_cast(D)) { + QualType t = v->getType(); + // a numeric variable will inevitably end up in $Globals buffer + if (t->isIntegralType(S.getASTContext()) || t->isFloatingType()) +r.default_globals = true; +} + } + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(D); + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast(D); + + if (CBufferOrTBuffer) { +r.resource = true; +if (CBufferOrTBuffer->isCBuffer()) + r.cbv = true; +else + r.srv = true; + } else if (SamplerUAVOrSRV) { +const HLSLResourceAttr *res_attr = +getHLSLResourceAttrFromEitherDecl(SamplerUAVOrSRV, CBufferOrTBuffer); +if (res_attr) { + llvm::hlsl::ResourceClass DeclResourceClass = + res_attr->getResourceClass(); + r.resource = true; + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::Resour
[clang-tools-extra] Fix Default Asset File locator for clang docs (PR #97505)
@@ -25,12 +25,14 @@ set(assets ) set(asset_dir "${CMAKE_CURRENT_SOURCE_DIR}/../assets") -set(resource_dir "${CMAKE_BINARY_DIR}/share/clang-doc") set(out_files) function(copy_files_to_dst src_dir dst_dir file) set(src "${src_dir}/${file}") set(dst "${dst_dir}/${file}") + if (NOT EXISTS ${dst_dir}) +file(MAKE_DIRECTORY ${dst_dir}) + endif() bogner wrote: I don't believe this is necessary - copy_if_different will do the right thing. https://github.com/llvm/llvm-project/pull/97505 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Fix Default Asset File locator for clang docs (PR #97505)
https://github.com/bogner approved this pull request. It's kind of unfortunate how this works dependency-wise - we end up creating "Debug/share/clang-doc/${f}" even when we only build "Release" and vice-versa, as the "copy-clang-doc-assets" explicitly depends on each version of this file. Also the actual install copies the file directly from the source directory, so if we did end up actually configuring these files per config for some reason there's some potential for confusion. However, the cmake-fu to do this any better is beyond me, and the current state is that we actually have broken bots because of this, so I think the solution here is Good Enough to get in and get the bots unblocked. https://github.com/llvm/llvm-project/pull/97505 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Fix Default Asset File locator for clang docs (PR #97505)
https://github.com/bogner edited https://github.com/llvm/llvm-project/pull/97505 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// TODO: Implement "Buffer" +struct Eg1 { + float f; + // Buffer Buf; damyanp wrote: It's a shame that there's no way to spell HLSLResource :( https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +460,406 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct register_binding_flags { + bool resource = false; + bool udt = false; + bool other = false; + bool basic = false; + + bool srv = false; + bool uav = false; + bool cbv = false; + bool sampler = false; + + bool contains_numeric = false; + bool default_globals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *SamplerUAVOrSRV) { + const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + return TheRecordDecl; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *SamplerUAVOrSRV, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (SamplerUAVOrSRV) { +const CXXRecordDecl *TheRecordDecl = +getRecordDeclFromVarDecl(SamplerUAVOrSRV); +if (!TheRecordDecl) + return nullptr; +const auto *Attr = TheRecordDecl->getAttr(); +return Attr; + } else if (CBufferOrTBuffer) { +const auto *Attr = CBufferOrTBuffer->getAttr(); +return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType T, register_binding_flags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.contains_numeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { +RecordDecl *SubRD = RT->getDecl(); +if (auto TDecl = dyn_cast(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::ResourceClass::Sampler: { +r.sampler = true; +break; + } + } +} + +else if (SubRD->isCompleteDefinition()) { + for (auto Field : SubRD->fields()) { +QualType T = Field->getType(); +traverseType(T, r); + } +} + } +} + +void setResourceClassFlagsFromRecordDecl(register_binding_flags &r, + const RecordDecl *RD) { + if (!RD) +return; + + if (RD->isCompleteDefinition()) { +for (auto Field : RD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); +} + } +} + +register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { + register_binding_flags r; + if (!isDeclaredWithinCOrTBuffer(D)) { +// make sure the type is a basic / numeric type +if (VarDecl *v = dyn_cast(D)) { + QualType t = v->getType(); + // a numeric variable will inevitably end up in $Globals buffer + if (t->isIntegralType(S.getASTContext()) || t->isFloatingType()) +r.default_globals = true; +} + } + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(D); + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast(D); + + if (CBufferOrTBuffer) { +r.resource = true; +if (CBufferOrTBuffer->isCBuffer()) + r.cbv = true; +else + r.srv = true; + } else if (SamplerUAVOrSRV) { +const HLSLResourceAttr *res_attr = +getHLSLResourceAttrFromEitherDecl(SamplerUAVOrSRV, CBufferOrTBuffer); +if (res_attr) { + llvm::hlsl::ResourceClass DeclResourceClass = + res_attr->getResourceClass(); + r.resource = true; + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::Resour
[clang] Adds an arbitrary pseudonym to clang"s windows mangler... (PR #97792)
memory-thrasher wrote: > I think this NTTP mangling code needs some significant updates, refactoring, > and an increase in test coverage. I see > [cd93532](https://github.com/llvm/llvm-project/commit/cd93532dfc455255cb2fa553090d14aaa52b106b) > landed last May, probably when I was offline for a while. Oh for sure. There are 5 other cases in template argument values alone that are still broken, I just made their error messages slightly clearer, at least as to which case is happening. I fixed one specific case I was hitting for my own sake, and am trying to share it but I have little interest in trying to fix the others (for free). https://github.com/llvm/llvm-project/pull/97792 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// TODO: Implement "Buffer" +struct Eg1 { + float f; + // Buffer Buf; + RWBuffer RWBuf; + }; +Eg1 e1 : /* register(t0) :*/ register(u0); +// Valid: f is skipped, Buf is bound to t0, RWBuf is bound to u0 + + +struct Eg2 { + float f; + // Buffer Buf; + RWBuffer RWBuf; + RWBuffer RWBuf2; + }; +Eg2 e2 : /* register(t0) :*/ register(u0); +// Valid: f is skipped, Buf is bound to t0, RWBuf is bound to u0. +// RWBuf2 gets automatically assigned to u1 even though there is no explicit binding for u1. + +/* +struct Eg3 { + float f; + // Buffer Buf; + }; +Eg3 e3 : register(t0) : register(u0); +// Valid: Buf gets bound to t0. Buf will also be bound to u0. +*/ + +struct Eg4 { + struct Bar { +RWBuffer a; +}; +Bar b; +}; +Eg4 e4 : register(u0); +// Valid: Bar, the struct within Eg4, has a valid resource that can be bound to t0. + +/* Light up this test when SamplerState is implemented +struct Eg5 { + SamplerState s[3]; +}; + +Eg5 e5 : register(s5); +// Valid: the first sampler state object within Eg5's s is bound to slot 5 +*/ + +struct Eg6 { + float f; +}; +// expected-warning@+1{{variable of type 'Eg6' bound to register type 't' does not contain a matching 'srv' resource}} +Eg6 e6 : register(t0); + +struct Eg7 { + struct Bar { +float f; + }; + Bar b; +}; +// expected-warning@+1{{variable of type 'Eg7' bound to register type 't' does not contain a matching 'srv' resource}} +Eg7 e7 : register(t0); + +struct Eg8 { + RWBuffer a; +}; +// expected-warning@+1{{register 'c' used on type with no contents to allocate in a constant buffer}} +Eg8 e8 : register(c0); + + +struct Eg9{ + // expected-error@+1{{'register' attribute only applies to cbuffer/tbuffer and external global variables}} + RWBuffer a : register(u9); +}; + +Eg9 e9; + + +/* Light up this test when Texture2D is implemented +template +struct Eg10 { +R b; +}; +// expecting warning: {{variable of type 'Eg10' bound to register type 'u' does not contain a matching 'uav' resource}} +Eg10 e10 : register(u0); + +// invalid because after template expansion, there are no valid resources inside Eg10 to bind as a UAV. +*/ + +struct Eg11{ + RWBuffer a; + RWBuffer b; +}; + +// expected-error@+1{{conflicting register annotations: multiple register numbers detected for register type 'u'}} +Eg11 e11 : register(u9) : register(u10); damyanp wrote: eg11a is also binding conflicting registers and so should generate the error. https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// TODO: Implement "Buffer" +struct Eg1 { + float f; + // Buffer Buf; bob80905 wrote: No, it isn't possible, because the tests in udt depend on both the declaration of the variable and the definition of the variable type. Even when adding the availability attribute, the `Texture2D` token just isn't parseable. https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement function pointer type discrimination (PR #96992)
@@ -3140,6 +3140,269 @@ ASTContext::getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD) { return llvm::getPointerAuthStableSipHash(Str); } +/// Encode a function type for use in the discriminator of a function pointer +/// type. We can't use the itanium scheme for this since C has quite permissive +/// rules for type compatibility that we need to be compatible with. +/// +/// Formally, this function associates every function pointer type T with an +/// encoded string E(T). Let the equivalence relation T1 ~ T2 be defined as +/// E(T1) == E(T2). E(T) is part of the ABI of values of type T. C type +/// compatibility requires equivalent treatment under the ABI, so +/// CCompatible(T1, T2) must imply E(T1) == E(T2), that is, CCompatible must be +/// a subset of ~. Crucially, however, it must be a proper subset because +/// CCompatible is not an equivalence relation: for example, int[] is compatible +/// with both int[1] and int[2], but the latter are not compatible with each +/// other. Therefore this encoding function must be careful to only distinguish +/// types if there is no third type with which they are both required to be +/// compatible. +static void encodeTypeForFunctionPointerAuth(ASTContext &Ctx, raw_ostream &OS, + QualType QT) { + // FIXME: Consider address space qualifiers. + const Type *T = QT.getCanonicalType().getTypePtr(); + + // FIXME: Consider using the C++ type mangling when we encounter a construct + // that is incompatible with C. + + switch (T->getTypeClass()) { + case Type::Atomic: +return encodeTypeForFunctionPointerAuth( +Ctx, OS, cast(T)->getValueType()); + + case Type::LValueReference: +OS << "R"; +encodeTypeForFunctionPointerAuth(Ctx, OS, + cast(T)->getPointeeType()); +return; + case Type::RValueReference: +OS << "O"; +encodeTypeForFunctionPointerAuth(Ctx, OS, + cast(T)->getPointeeType()); +return; + + case Type::Pointer: +// C11 6.7.6.1p2: +// For two pointer types to be compatible, both shall be identically +// qualified and both shall be pointers to compatible types. +// FIXME: we should also consider pointee types. +OS << "P"; +return; + + case Type::ObjCObjectPointer: + case Type::BlockPointer: +OS << "P"; +return; + + case Type::Complex: +OS << "C"; +return encodeTypeForFunctionPointerAuth( +Ctx, OS, cast(T)->getElementType()); + + case Type::VariableArray: + case Type::ConstantArray: + case Type::IncompleteArray: + case Type::ArrayParameter: +// C11 6.7.6.2p6: +// For two array types to be compatible, both shall have compatible +// element types, and if both size specifiers are present, and are integer +// constant expressions, then both size specifiers shall have the same +// constant value [...] +// +// So since ElemType[N] has to be compatible ElemType[], we can't encode the +// width of the array. +OS << "A"; +return encodeTypeForFunctionPointerAuth( +Ctx, OS, cast(T)->getElementType()); + + case Type::ObjCInterface: + case Type::ObjCObject: +OS << ""; +return; + + case Type::Enum: +// C11 6.7.2.2p4: +// Each enumerated type shall be compatible with char, a signed integer +// type, or an unsigned integer type. +// +// So we have to treat enum types as integers. +OS << "i"; +return; + + case Type::FunctionNoProto: + case Type::FunctionProto: { +// C11 6.7.6.3p15: +// For two function types to be compatible, both shall specify compatible +// return types. Moreover, the parameter type lists, if both are present, +// shall agree in the number of parameters and in the use of the ellipsis +// terminator; corresponding parameters shall have compatible types. +// +// That paragraph goes on to describe how unprototyped functions are to be +// handled, which we ignore here. Unprototyped function pointers are hashed +// as though they were prototyped nullary functions since thats probably +// what the user meant. This behavior is non-conforming. +// FIXME: If we add a "custom discriminator" function type attribute we +// should encode functions as their discriminators. +OS << "F"; +auto *FuncType = cast(T); +encodeTypeForFunctionPointerAuth(Ctx, OS, FuncType->getReturnType()); +if (auto *FPT = dyn_cast(FuncType)) { + for (QualType Param : FPT->param_types()) { +Param = Ctx.getSignatureParameterType(Param); +encodeTypeForFunctionPointerAuth(Ctx, OS, Param); + } + if (FPT->isVariadic()) +OS << "z"; +} +OS << "E"; +return; + } + + case Type::MemberPointer: { +OS << "M"; +auto *MPT = T->getAs(); +encodeTypeForFunctionPointerAuth(Ctx, OS, QualType(MPT->getClass(), 0)); +encodeTypeForFunctionP
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// TODO: Implement "Buffer" +struct Eg1 { + float f; + // Buffer Buf; damyanp wrote: I guess we don't have the ability to create resource types using just the attributes that we can use in the tests, like how Helena did for the availability diagnostics? https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] let UseAfterMoveFinder::find() return an optional (PR #98100)
https://github.com/tchaikov updated https://github.com/llvm/llvm-project/pull/98100 >From 1a2d88917db32253514fc7a533f5cb39d465a9c7 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 9 Jul 2024 07:58:23 +0800 Subject: [PATCH] [clang-tidy] let UseAfterMoveFinder::find() return an optional before this change, we use an output parameter so `UseAfterMoveFinder::find()` can return the found `UseAfterMove`, and addition to it, `UseAfterMoveFinder::find()` return a bool, so we can tell if a use-after-free is identified. this arrangement could be confusing when one needs to understand when the each member variable of the returned `UseAfterMove` instance is initialized. in this change, we return an `std::optional` instead of a bool, so that it's more obvious on when/where the returned `UseAfterMove` is initialized. this change is a cleanup. so it does not change the behavior of this check. Signed-off-by: Kefu Chai --- .../clang-tidy/bugprone/UseAfterMoveCheck.cpp | 56 ++- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index c90c92b5f660a..8f4b5e8092dda 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -54,13 +54,13 @@ class UseAfterMoveFinder { // occurs after 'MovingCall' (the expression that performs the move). If a // use-after-move is found, writes information about it to 'TheUseAfterMove'. // Returns whether a use-after-move was found. - bool find(Stmt *CodeBlock, const Expr *MovingCall, -const DeclRefExpr *MovedVariable, UseAfterMove *TheUseAfterMove); + std::optional find(Stmt *CodeBlock, const Expr *MovingCall, + const DeclRefExpr *MovedVariable); private: - bool findInternal(const CFGBlock *Block, const Expr *MovingCall, -const ValueDecl *MovedVariable, -UseAfterMove *TheUseAfterMove); + std::optional findInternal(const CFGBlock *Block, + const Expr *MovingCall, + const ValueDecl *MovedVariable); void getUsesAndReinits(const CFGBlock *Block, const ValueDecl *MovedVariable, llvm::SmallVectorImpl *Uses, llvm::SmallPtrSetImpl *Reinits); @@ -95,9 +95,9 @@ static StatementMatcher inDecltypeOrTemplateArg() { UseAfterMoveFinder::UseAfterMoveFinder(ASTContext *TheContext) : Context(TheContext) {} -bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, - const DeclRefExpr *MovedVariable, - UseAfterMove *TheUseAfterMove) { +std::optional +UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, + const DeclRefExpr *MovedVariable) { // Generate the CFG manually instead of through an AnalysisDeclContext because // it seems the latter can't be used to generate a CFG for the body of a // lambda. @@ -111,7 +111,7 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, std::unique_ptr TheCFG = CFG::buildCFG(nullptr, CodeBlock, Context, Options); if (!TheCFG) -return false; +return std::nullopt; Sequence = std::make_unique(TheCFG.get(), CodeBlock, Context); BlockMap = std::make_unique(TheCFG.get(), Context); @@ -125,10 +125,10 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, MoveBlock = &TheCFG->getEntry(); } - bool Found = findInternal(MoveBlock, MovingCall, MovedVariable->getDecl(), -TheUseAfterMove); + auto TheUseAfterMove = + findInternal(MoveBlock, MovingCall, MovedVariable->getDecl()); - if (Found) { + if (TheUseAfterMove) { if (const CFGBlock *UseBlock = BlockMap->blockContainingStmt(TheUseAfterMove->DeclRef)) { // Does the use happen in a later loop iteration than the move? @@ -142,15 +142,14 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, : CFA.isReachable(UseBlock, MoveBlock); } } - return Found; + return TheUseAfterMove; } -bool UseAfterMoveFinder::findInternal(const CFGBlock *Block, - const Expr *MovingCall, - const ValueDecl *MovedVariable, - UseAfterMove *TheUseAfterMove) { +std::optional +UseAfterMoveFinder::findInternal(const CFGBlock *Block, const Expr *MovingCall, + const ValueDecl *MovedVariable) { if (Visited.count(Block)) -return false; +return std::nullopt; // Mark the block as visited (except if this is the block containing the // std::move() and it's being visited the first time). @@ -189,17 +188,18 @@ bool Us
[clang-tools-extra] [clang-doc] fix paths by hard coding path to share (PR #98099)
https://github.com/PeterChou1 edited https://github.com/llvm/llvm-project/pull/98099 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] let UseAfterMoveFinder::find() return an optional (PR #98100)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 46a2abb91cb6cfac9b807ae2055cc5f1743405e4 3537fe828bac5678970e106ac89306e465446163 -- clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp `` View the diff from clang-format here. ``diff diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index a740b602af..8f4b5e8092 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -58,7 +58,8 @@ public: const DeclRefExpr *MovedVariable); private: - std::optional findInternal(const CFGBlock *Block, const Expr *MovingCall, + std::optional findInternal(const CFGBlock *Block, + const Expr *MovingCall, const ValueDecl *MovedVariable); void getUsesAndReinits(const CFGBlock *Block, const ValueDecl *MovedVariable, llvm::SmallVectorImpl *Uses, @@ -94,8 +95,9 @@ static StatementMatcher inDecltypeOrTemplateArg() { UseAfterMoveFinder::UseAfterMoveFinder(ASTContext *TheContext) : Context(TheContext) {} -std::optional UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, - const DeclRefExpr *MovedVariable) { +std::optional +UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, + const DeclRefExpr *MovedVariable) { // Generate the CFG manually instead of through an AnalysisDeclContext because // it seems the latter can't be used to generate a CFG for the body of a // lambda. @@ -123,7 +125,8 @@ std::optional UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr MoveBlock = &TheCFG->getEntry(); } - auto TheUseAfterMove = findInternal(MoveBlock, MovingCall, MovedVariable->getDecl()); + auto TheUseAfterMove = + findInternal(MoveBlock, MovingCall, MovedVariable->getDecl()); if (TheUseAfterMove) { if (const CFGBlock *UseBlock = @@ -142,9 +145,9 @@ std::optional UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr return TheUseAfterMove; } -std::optional UseAfterMoveFinder::findInternal(const CFGBlock *Block, - const Expr *MovingCall, - const ValueDecl *MovedVariable) { +std::optional +UseAfterMoveFinder::findInternal(const CFGBlock *Block, const Expr *MovingCall, + const ValueDecl *MovedVariable) { if (Visited.count(Block)) return std::nullopt; `` https://github.com/llvm/llvm-project/pull/98100 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// TODO: Implement "Buffer" +struct Eg1 { + float f; + // Buffer Buf; + RWBuffer RWBuf; + }; +Eg1 e1 : /* register(t0) :*/ register(u0); +// Valid: f is skipped, Buf is bound to t0, RWBuf is bound to u0 + + +struct Eg2 { + float f; + // Buffer Buf; + RWBuffer RWBuf; + RWBuffer RWBuf2; + }; +Eg2 e2 : /* register(t0) :*/ register(u0); +// Valid: f is skipped, Buf is bound to t0, RWBuf is bound to u0. +// RWBuf2 gets automatically assigned to u1 even though there is no explicit binding for u1. + +/* +struct Eg3 { + float f; + // Buffer Buf; + }; +Eg3 e3 : register(t0) : register(u0); +// Valid: Buf gets bound to t0. Buf will also be bound to u0. +*/ + +struct Eg4 { + struct Bar { +RWBuffer a; +}; +Bar b; +}; +Eg4 e4 : register(u0); +// Valid: Bar, the struct within Eg4, has a valid resource that can be bound to t0. + +/* Light up this test when SamplerState is implemented +struct Eg5 { + SamplerState s[3]; +}; + +Eg5 e5 : register(s5); +// Valid: the first sampler state object within Eg5's s is bound to slot 5 +*/ + +struct Eg6 { + float f; +}; +// expected-warning@+1{{variable of type 'Eg6' bound to register type 't' does not contain a matching 'srv' resource}} +Eg6 e6 : register(t0); + +struct Eg7 { + struct Bar { +float f; + }; + Bar b; +}; +// expected-warning@+1{{variable of type 'Eg7' bound to register type 't' does not contain a matching 'srv' resource}} +Eg7 e7 : register(t0); + +struct Eg8 { + RWBuffer a; +}; +// expected-warning@+1{{register 'c' used on type with no contents to allocate in a constant buffer}} +Eg8 e8 : register(c0); + + +struct Eg9{ + // expected-error@+1{{'register' attribute only applies to cbuffer/tbuffer and external global variables}} + RWBuffer a : register(u9); +}; + +Eg9 e9; + + +/* Light up this test when Texture2D is implemented +template +struct Eg10 { +R b; +}; +// expecting warning: {{variable of type 'Eg10' bound to register type 'u' does not contain a matching 'uav' resource}} +Eg10 e10 : register(u0); + +// invalid because after template expansion, there are no valid resources inside Eg10 to bind as a UAV. +*/ + +struct Eg11{ + RWBuffer a; + RWBuffer b; +}; + +// expected-error@+1{{conflicting register annotations: multiple register numbers detected for register type 'u'}} +Eg11 e11 : register(u9) : register(u10); damyanp wrote: With the expected error? https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] let UseAfterMoveFinder::find() return an optional (PR #98100)
llvmbot wrote: @llvm/pr-subscribers-clang-tidy @llvm/pr-subscribers-clang-tools-extra Author: Kefu Chai (tchaikov) Changes before this change, we use an output parameter so `UseAfterMoveFinder::find()` can return the found `UseAfterMove`, and addition to it, `UseAfterMoveFinder::find()` return a bool, so we can tell if a use-after-free is identified. this arrangement could be confusing when one needs to understand when the each member variable of the returned `UseAfterMove` instance is initialized. in this change, we return an `std::optional` instead of a bool, so that it's more obvious on when/where the returned `UseAfterMove` is initialized. this change is a cleanup. so it does not change the behavior of this check. --- Full diff: https://github.com/llvm/llvm-project/pull/98100.diff 1 Files Affected: - (modified) clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp (+26-27) ``diff diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index c90c92b5f660a..a740b602af12b 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -54,13 +54,12 @@ class UseAfterMoveFinder { // occurs after 'MovingCall' (the expression that performs the move). If a // use-after-move is found, writes information about it to 'TheUseAfterMove'. // Returns whether a use-after-move was found. - bool find(Stmt *CodeBlock, const Expr *MovingCall, -const DeclRefExpr *MovedVariable, UseAfterMove *TheUseAfterMove); + std::optional find(Stmt *CodeBlock, const Expr *MovingCall, + const DeclRefExpr *MovedVariable); private: - bool findInternal(const CFGBlock *Block, const Expr *MovingCall, -const ValueDecl *MovedVariable, -UseAfterMove *TheUseAfterMove); + std::optional findInternal(const CFGBlock *Block, const Expr *MovingCall, + const ValueDecl *MovedVariable); void getUsesAndReinits(const CFGBlock *Block, const ValueDecl *MovedVariable, llvm::SmallVectorImpl *Uses, llvm::SmallPtrSetImpl *Reinits); @@ -95,9 +94,8 @@ static StatementMatcher inDecltypeOrTemplateArg() { UseAfterMoveFinder::UseAfterMoveFinder(ASTContext *TheContext) : Context(TheContext) {} -bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, - const DeclRefExpr *MovedVariable, - UseAfterMove *TheUseAfterMove) { +std::optional UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, + const DeclRefExpr *MovedVariable) { // Generate the CFG manually instead of through an AnalysisDeclContext because // it seems the latter can't be used to generate a CFG for the body of a // lambda. @@ -111,7 +109,7 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, std::unique_ptr TheCFG = CFG::buildCFG(nullptr, CodeBlock, Context, Options); if (!TheCFG) -return false; +return std::nullopt; Sequence = std::make_unique(TheCFG.get(), CodeBlock, Context); BlockMap = std::make_unique(TheCFG.get(), Context); @@ -125,10 +123,9 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, MoveBlock = &TheCFG->getEntry(); } - bool Found = findInternal(MoveBlock, MovingCall, MovedVariable->getDecl(), -TheUseAfterMove); + auto TheUseAfterMove = findInternal(MoveBlock, MovingCall, MovedVariable->getDecl()); - if (Found) { + if (TheUseAfterMove) { if (const CFGBlock *UseBlock = BlockMap->blockContainingStmt(TheUseAfterMove->DeclRef)) { // Does the use happen in a later loop iteration than the move? @@ -142,15 +139,14 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, : CFA.isReachable(UseBlock, MoveBlock); } } - return Found; + return TheUseAfterMove; } -bool UseAfterMoveFinder::findInternal(const CFGBlock *Block, - const Expr *MovingCall, - const ValueDecl *MovedVariable, - UseAfterMove *TheUseAfterMove) { +std::optional UseAfterMoveFinder::findInternal(const CFGBlock *Block, + const Expr *MovingCall, + const ValueDecl *MovedVariable) { if (Visited.count(Block)) -return false; +return std::nullopt; // Mark the block as visited (except if this is the block containing the // std::move() and it's being visited the first time). @@ -189,17 +185,18 @@ bool UseAfterMoveFinder::findInternal(const
[clang-tools-extra] [clang-tidy] In C++17, callee is guaranteed to be sequenced before arguments. (PR #93623)
@@ -175,6 +218,10 @@ bool UseAfterMoveFinder::findInternal(const CFGBlock *Block, MovingCall != nullptr && Sequence->potentiallyAfter(MovingCall, Use); +// We default to false here and change this to true if required in +// find(). +TheUseAfterMove->UseHappensInLaterLoopIteration = false; + tchaikov wrote: > for better readability. but the `optional<>` refactor is still a > nice-to-have, IMHO. created #98100 https://github.com/llvm/llvm-project/pull/93623 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] let UseAfterMoveFinder::find() return an optional (PR #98100)
https://github.com/tchaikov created https://github.com/llvm/llvm-project/pull/98100 before this change, we use an output parameter so `UseAfterMoveFinder::find()` can return the found `UseAfterMove`, and addition to it, `UseAfterMoveFinder::find()` return a bool, so we can tell if a use-after-free is identified. this arrangement could be confusing when one needs to understand when the each member variable of the returned `UseAfterMove` instance is initialized. in this change, we return an `std::optional` instead of a bool, so that it's more obvious on when/where the returned `UseAfterMove` is initialized. this change is a cleanup. so it does not change the behavior of this check. >From 3537fe828bac5678970e106ac89306e465446163 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 9 Jul 2024 07:58:23 +0800 Subject: [PATCH] [clang-tidy] let UseAfterMoveFinder::find() return an optional before this change, we use an output parameter so `UseAfterMoveFinder::find()` can return the found `UseAfterMove`, and addition to it, `UseAfterMoveFinder::find()` return a bool, so we can tell if a use-after-free is identified. this arrangement could be confusing when one needs to understand when the each member variable of the returned `UseAfterMove` instance is initialized. in this change, we return an `std::optional` instead of a bool, so that it's more obvious on when/where the returned `UseAfterMove` is initialized. this change is a cleanup. so it does not change the behavior of this check. Signed-off-by: Kefu Chai --- .../clang-tidy/bugprone/UseAfterMoveCheck.cpp | 53 +-- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index c90c92b5f660a..a740b602af12b 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -54,13 +54,12 @@ class UseAfterMoveFinder { // occurs after 'MovingCall' (the expression that performs the move). If a // use-after-move is found, writes information about it to 'TheUseAfterMove'. // Returns whether a use-after-move was found. - bool find(Stmt *CodeBlock, const Expr *MovingCall, -const DeclRefExpr *MovedVariable, UseAfterMove *TheUseAfterMove); + std::optional find(Stmt *CodeBlock, const Expr *MovingCall, + const DeclRefExpr *MovedVariable); private: - bool findInternal(const CFGBlock *Block, const Expr *MovingCall, -const ValueDecl *MovedVariable, -UseAfterMove *TheUseAfterMove); + std::optional findInternal(const CFGBlock *Block, const Expr *MovingCall, + const ValueDecl *MovedVariable); void getUsesAndReinits(const CFGBlock *Block, const ValueDecl *MovedVariable, llvm::SmallVectorImpl *Uses, llvm::SmallPtrSetImpl *Reinits); @@ -95,9 +94,8 @@ static StatementMatcher inDecltypeOrTemplateArg() { UseAfterMoveFinder::UseAfterMoveFinder(ASTContext *TheContext) : Context(TheContext) {} -bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, - const DeclRefExpr *MovedVariable, - UseAfterMove *TheUseAfterMove) { +std::optional UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, + const DeclRefExpr *MovedVariable) { // Generate the CFG manually instead of through an AnalysisDeclContext because // it seems the latter can't be used to generate a CFG for the body of a // lambda. @@ -111,7 +109,7 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, std::unique_ptr TheCFG = CFG::buildCFG(nullptr, CodeBlock, Context, Options); if (!TheCFG) -return false; +return std::nullopt; Sequence = std::make_unique(TheCFG.get(), CodeBlock, Context); BlockMap = std::make_unique(TheCFG.get(), Context); @@ -125,10 +123,9 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, MoveBlock = &TheCFG->getEntry(); } - bool Found = findInternal(MoveBlock, MovingCall, MovedVariable->getDecl(), -TheUseAfterMove); + auto TheUseAfterMove = findInternal(MoveBlock, MovingCall, MovedVariable->getDecl()); - if (Found) { + if (TheUseAfterMove) { if (const CFGBlock *UseBlock = BlockMap->blockContainingStmt(TheUseAfterMove->DeclRef)) { // Does the use happen in a later loop iteration than the move? @@ -142,15 +139,14 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, : CFA.isReachable(UseBlock, MoveBlock); } } - return Found; + return TheUseAfterMove; } -bool UseAfterMoveFinder::findInternal(const CFGBlock *Block, -
[clang] [llvm] [RISCV] Remove experimental for bf16 extensions (PR #97996)
https://github.com/topperc approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/97996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +460,406 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct register_binding_flags { + bool resource = false; + bool udt = false; + bool other = false; + bool basic = false; + + bool srv = false; + bool uav = false; + bool cbv = false; + bool sampler = false; + + bool contains_numeric = false; + bool default_globals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *SamplerUAVOrSRV) { + const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + return TheRecordDecl; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *SamplerUAVOrSRV, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (SamplerUAVOrSRV) { +const CXXRecordDecl *TheRecordDecl = +getRecordDeclFromVarDecl(SamplerUAVOrSRV); +if (!TheRecordDecl) + return nullptr; +const auto *Attr = TheRecordDecl->getAttr(); +return Attr; + } else if (CBufferOrTBuffer) { +const auto *Attr = CBufferOrTBuffer->getAttr(); +return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType T, register_binding_flags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.contains_numeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { +RecordDecl *SubRD = RT->getDecl(); +if (auto TDecl = dyn_cast(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::ResourceClass::Sampler: { +r.sampler = true; +break; + } + } +} + +else if (SubRD->isCompleteDefinition()) { + for (auto Field : SubRD->fields()) { +QualType T = Field->getType(); +traverseType(T, r); + } +} + } +} + +void setResourceClassFlagsFromRecordDecl(register_binding_flags &r, + const RecordDecl *RD) { + if (!RD) +return; + + if (RD->isCompleteDefinition()) { +for (auto Field : RD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); +} + } +} + +register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { + register_binding_flags r; + if (!isDeclaredWithinCOrTBuffer(D)) { +// make sure the type is a basic / numeric type +if (VarDecl *v = dyn_cast(D)) { + QualType t = v->getType(); + // a numeric variable will inevitably end up in $Globals buffer + if (t->isIntegralType(S.getASTContext()) || t->isFloatingType()) +r.default_globals = true; +} + } + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(D); + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast(D); + + if (CBufferOrTBuffer) { +r.resource = true; +if (CBufferOrTBuffer->isCBuffer()) + r.cbv = true; +else + r.srv = true; + } else if (SamplerUAVOrSRV) { +const HLSLResourceAttr *res_attr = +getHLSLResourceAttrFromEitherDecl(SamplerUAVOrSRV, CBufferOrTBuffer); +if (res_attr) { + llvm::hlsl::ResourceClass DeclResourceClass = + res_attr->getResourceClass(); + r.resource = true; + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::Resour
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// TODO: Implement "Buffer" +struct Eg1 { + float f; + // Buffer Buf; + RWBuffer RWBuf; + }; +Eg1 e1 : /* register(t0) :*/ register(u0); +// Valid: f is skipped, Buf is bound to t0, RWBuf is bound to u0 + + +struct Eg2 { + float f; + // Buffer Buf; + RWBuffer RWBuf; + RWBuffer RWBuf2; + }; +Eg2 e2 : /* register(t0) :*/ register(u0); +// Valid: f is skipped, Buf is bound to t0, RWBuf is bound to u0. +// RWBuf2 gets automatically assigned to u1 even though there is no explicit binding for u1. + +/* +struct Eg3 { + float f; + // Buffer Buf; + }; +Eg3 e3 : register(t0) : register(u0); +// Valid: Buf gets bound to t0. Buf will also be bound to u0. +*/ + +struct Eg4 { + struct Bar { +RWBuffer a; +}; +Bar b; +}; +Eg4 e4 : register(u0); +// Valid: Bar, the struct within Eg4, has a valid resource that can be bound to t0. + +/* Light up this test when SamplerState is implemented +struct Eg5 { + SamplerState s[3]; +}; + +Eg5 e5 : register(s5); +// Valid: the first sampler state object within Eg5's s is bound to slot 5 +*/ + +struct Eg6 { + float f; +}; +// expected-warning@+1{{variable of type 'Eg6' bound to register type 't' does not contain a matching 'srv' resource}} +Eg6 e6 : register(t0); + +struct Eg7 { + struct Bar { +float f; + }; + Bar b; +}; +// expected-warning@+1{{variable of type 'Eg7' bound to register type 't' does not contain a matching 'srv' resource}} +Eg7 e7 : register(t0); + +struct Eg8 { + RWBuffer a; +}; +// expected-warning@+1{{register 'c' used on type with no contents to allocate in a constant buffer}} +Eg8 e8 : register(c0); + + +struct Eg9{ + // expected-error@+1{{'register' attribute only applies to cbuffer/tbuffer and external global variables}} + RWBuffer a : register(u9); +}; + +Eg9 e9; + + +/* Light up this test when Texture2D is implemented +template +struct Eg10 { +R b; +}; +// expecting warning: {{variable of type 'Eg10' bound to register type 'u' does not contain a matching 'uav' resource}} +Eg10 e10 : register(u0); + +// invalid because after template expansion, there are no valid resources inside Eg10 to bind as a UAV. +*/ + +struct Eg11{ + RWBuffer a; + RWBuffer b; +}; + +// expected-error@+1{{conflicting register annotations: multiple register numbers detected for register type 'u'}} +Eg11 e11 : register(u9) : register(u10); bob80905 wrote: no issue, this passes. https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify + +// TODO: Implement "Buffer" +struct Eg1 { + float f; + // Buffer Buf; bob80905 wrote: Yes, it is intentional. The commented-out examples cannot be run in any valuable sense, without some prerequisite implementation of types that are not yet implemented. For example, after `Buffer` is implemented, or after `Texture2D` is implemented, we can better test the diagnostic infrastructure. We don't have any resources that can bind to the `t` register type yet, so tests are necessarily quite limited. https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] fix paths by hard coding path to share (PR #98099)
https://github.com/ilovepi approved this pull request. LGTM, modulo my comments on the commit message and title, and premerge checks passing. https://github.com/llvm/llvm-project/pull/98099 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] fix paths by hard coding path to share (PR #98099)
ilovepi wrote: I'd rephrase your commit message and title in the following way. ``` [clang-doc][cmake] Fix asset directory location for other generator types This patch fixes how clang-doc copies asset files for the build to match the install location for all CMake generator types. The previous version of this patch did not account for standalone builds of clang that may use older LLVM installs, ane which do not have the `LLVM_SHARE_OUTPUT_INTDIR` defined. Instead, we create an equivalent path using `LLVM_RUNTIME_OUTPUT_INTDIR`. Fixes #97507 ``` You may want to adjust the line length to match 80 columns, since I just eyeballed it. https://github.com/llvm/llvm-project/pull/98099 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +460,406 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct register_binding_flags { + bool resource = false; + bool udt = false; + bool other = false; + bool basic = false; + + bool srv = false; + bool uav = false; + bool cbv = false; + bool sampler = false; + + bool contains_numeric = false; + bool default_globals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *SamplerUAVOrSRV) { + const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + return TheRecordDecl; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *SamplerUAVOrSRV, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (SamplerUAVOrSRV) { +const CXXRecordDecl *TheRecordDecl = +getRecordDeclFromVarDecl(SamplerUAVOrSRV); +if (!TheRecordDecl) + return nullptr; +const auto *Attr = TheRecordDecl->getAttr(); +return Attr; + } else if (CBufferOrTBuffer) { +const auto *Attr = CBufferOrTBuffer->getAttr(); +return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType T, register_binding_flags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.contains_numeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { +RecordDecl *SubRD = RT->getDecl(); +if (auto TDecl = dyn_cast(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::ResourceClass::Sampler: { +r.sampler = true; +break; + } + } +} + +else if (SubRD->isCompleteDefinition()) { + for (auto Field : SubRD->fields()) { +QualType T = Field->getType(); +traverseType(T, r); + } +} + } +} + +void setResourceClassFlagsFromRecordDecl(register_binding_flags &r, + const RecordDecl *RD) { + if (!RD) +return; + + if (RD->isCompleteDefinition()) { +for (auto Field : RD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); +} + } +} + +register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { + register_binding_flags r; + if (!isDeclaredWithinCOrTBuffer(D)) { +// make sure the type is a basic / numeric type +if (VarDecl *v = dyn_cast(D)) { + QualType t = v->getType(); + // a numeric variable will inevitably end up in $Globals buffer + if (t->isIntegralType(S.getASTContext()) || t->isFloatingType()) +r.default_globals = true; +} + } + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(D); + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast(D); + + if (CBufferOrTBuffer) { +r.resource = true; +if (CBufferOrTBuffer->isCBuffer()) + r.cbv = true; +else + r.srv = true; + } else if (SamplerUAVOrSRV) { +const HLSLResourceAttr *res_attr = +getHLSLResourceAttrFromEitherDecl(SamplerUAVOrSRV, CBufferOrTBuffer); +if (res_attr) { + llvm::hlsl::ResourceClass DeclResourceClass = + res_attr->getResourceClass(); + r.resource = true; + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::Resour
[clang] [llvm] [X86] Support branch hint (PR #97721)
@@ -1815,12 +1822,12 @@ def : ProcModel<"pantherlake", AlderlakePModel, def : ProcModel<"clearwaterforest", AlderlakePModel, ProcessorFeatures.CWFFeatures, ProcessorFeatures.ADLTuning>; def : ProcModel<"graniterapids", SapphireRapidsModel, -ProcessorFeatures.GNRFeatures, ProcessorFeatures.SPRTuning>; +ProcessorFeatures.GNRFeatures, ProcessorFeatures.GNRTuning>; def : ProcModel<"emeraldrapids", SapphireRapidsModel, -ProcessorFeatures.SPRFeatures, ProcessorFeatures.SPRTuning>; +ProcessorFeatures.SPRFeatures, ProcessorFeatures.GNRTuning>; MattPD wrote: Isn't Emerald Rapids based on Raptor Lake microarchitecture (and not Redwood Cove)? If so, wouldn't branch hints be unsupported for this subtarget? https://github.com/llvm/llvm-project/pull/97721 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +460,406 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct register_binding_flags { + bool resource = false; + bool udt = false; + bool other = false; + bool basic = false; + + bool srv = false; + bool uav = false; + bool cbv = false; + bool sampler = false; + + bool contains_numeric = false; + bool default_globals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *SamplerUAVOrSRV) { + const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + return TheRecordDecl; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *SamplerUAVOrSRV, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (SamplerUAVOrSRV) { +const CXXRecordDecl *TheRecordDecl = +getRecordDeclFromVarDecl(SamplerUAVOrSRV); +if (!TheRecordDecl) + return nullptr; +const auto *Attr = TheRecordDecl->getAttr(); +return Attr; + } else if (CBufferOrTBuffer) { +const auto *Attr = CBufferOrTBuffer->getAttr(); +return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType T, register_binding_flags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.contains_numeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { +RecordDecl *SubRD = RT->getDecl(); +if (auto TDecl = dyn_cast(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::ResourceClass::Sampler: { +r.sampler = true; +break; + } + } +} + +else if (SubRD->isCompleteDefinition()) { + for (auto Field : SubRD->fields()) { +QualType T = Field->getType(); +traverseType(T, r); + } +} + } +} + +void setResourceClassFlagsFromRecordDecl(register_binding_flags &r, + const RecordDecl *RD) { + if (!RD) +return; + + if (RD->isCompleteDefinition()) { +for (auto Field : RD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); +} + } +} + +register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { + register_binding_flags r; + if (!isDeclaredWithinCOrTBuffer(D)) { +// make sure the type is a basic / numeric type +if (VarDecl *v = dyn_cast(D)) { + QualType t = v->getType(); + // a numeric variable will inevitably end up in $Globals buffer + if (t->isIntegralType(S.getASTContext()) || t->isFloatingType()) +r.default_globals = true; +} + } + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast(D); + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast(D); + + if (CBufferOrTBuffer) { +r.resource = true; +if (CBufferOrTBuffer->isCBuffer()) + r.cbv = true; +else + r.srv = true; + } else if (SamplerUAVOrSRV) { +const HLSLResourceAttr *res_attr = +getHLSLResourceAttrFromEitherDecl(SamplerUAVOrSRV, CBufferOrTBuffer); +if (res_attr) { + llvm::hlsl::ResourceClass DeclResourceClass = + res_attr->getResourceClass(); + r.resource = true; + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::Resour
[clang] [llvm] [AsmPrinter] Don't check for inlineasm dialect on non-X86 platforms (PR #98097)
@@ -0,0 +1,23 @@ +// REQUIRES: aarch64-registered-target jroelofs wrote: Is this a new folder? There should be a `lit.local.cfg` in there that takes care of this: ``` if "AArch64" not in config.root.targets: config.unsupported = True ``` If not, please add one. https://github.com/llvm/llvm-project/pull/98097 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] fix paths by hard coding path to share (PR #98099)
llvmbot wrote: @llvm/pr-subscribers-clang-tools-extra Author: None (PeterChou1) Changes Fixes https://github.com/llvm/llvm-project/issues/97507 The previous patch I put up broke clang's standalone build, this patch is a hack workaround so that the clang-docs tests can pass regression test without breaking visual studio build and other standalone clang builds --- Full diff: https://github.com/llvm/llvm-project/pull/98099.diff 1 Files Affected: - (modified) clang-tools-extra/clang-doc/tool/CMakeLists.txt (+1-1) ``diff diff --git a/clang-tools-extra/clang-doc/tool/CMakeLists.txt b/clang-tools-extra/clang-doc/tool/CMakeLists.txt index e93a5728d6b6b..601a0460d76b3 100644 --- a/clang-tools-extra/clang-doc/tool/CMakeLists.txt +++ b/clang-tools-extra/clang-doc/tool/CMakeLists.txt @@ -25,7 +25,7 @@ set(assets ) set(asset_dir "${CMAKE_CURRENT_SOURCE_DIR}/../assets") -set(resource_dir "${CMAKE_BINARY_DIR}/share/clang-doc") +set(resource_dir "${LLVM_RUNTIME_OUTPUT_INTDIR}/../share/clang-doc") set(out_files) function(copy_files_to_dst src_dir dst_dir file) `` https://github.com/llvm/llvm-project/pull/98099 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] fix paths by hard coding path to share (PR #98099)
https://github.com/PeterChou1 created https://github.com/llvm/llvm-project/pull/98099 Fixes https://github.com/llvm/llvm-project/issues/97507 The previous patch I put up broke clang's standalone build, this patch is a hack workaround so that the clang-docs tests can pass regression test without breaking visual studio build and other standalone clang builds >From 6e0cbfa80e3a4b36d04903a17e1493eb45a50893 Mon Sep 17 00:00:00 2001 From: PeterChou1 Date: Mon, 8 Jul 2024 19:31:16 -0400 Subject: [PATCH] [clang-doc] fix paths by hard coding path to share --- clang-tools-extra/clang-doc/tool/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-doc/tool/CMakeLists.txt b/clang-tools-extra/clang-doc/tool/CMakeLists.txt index e93a5728d6b6b..601a0460d76b3 100644 --- a/clang-tools-extra/clang-doc/tool/CMakeLists.txt +++ b/clang-tools-extra/clang-doc/tool/CMakeLists.txt @@ -25,7 +25,7 @@ set(assets ) set(asset_dir "${CMAKE_CURRENT_SOURCE_DIR}/../assets") -set(resource_dir "${CMAKE_BINARY_DIR}/share/clang-doc") +set(resource_dir "${LLVM_RUNTIME_OUTPUT_INTDIR}/../share/clang-doc") set(out_files) function(copy_files_to_dst src_dir dst_dir file) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Implement resource binding type prefix mismatch flag setting logic (PR #97103)
@@ -437,7 +460,206 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +struct register_binding_flags { + bool resource = false; + bool udt = false; + bool other = false; + bool basic = false; + + bool srv = false; + bool uav = false; + bool cbv = false; + bool sampler = false; + + bool contains_numeric = false; + bool default_globals = false; +}; + +bool isDeclaredWithinCOrTBuffer(const Decl *decl) { + if (!decl) +return false; + + // Traverse up the parent contexts + const DeclContext *context = decl->getDeclContext(); + while (context) { +if (isa(context)) { + return true; +} +context = context->getParent(); + } + + return false; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromVarDecl(VarDecl *SamplerUAVOrSRV) { + const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); + if (!Ty) +llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast(Ty)) { +/* QualType QT = SamplerUAVOrSRV->getType(); +PrintingPolicy PP = S.getPrintingPolicy(); +std::string typestr = QualType::getAsString(QT.split(), PP); + +S.Diag(ArgLoc, diag::err_hlsl_unsupported_register_resource_type) +<< typestr; +return; */ +return nullptr; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) +llvm_unreachable("Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast(TheRecordDecl)) +TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + return Attr; +} + +void traverseType(QualType T, register_binding_flags &r) { + if (T->isIntegralOrEnumerationType() || T->isFloatingType()) { +r.contains_numeric = true; +return; + } else if (const RecordType *RT = T->getAs()) { +RecordDecl *SubRD = RT->getDecl(); +if (auto TDecl = dyn_cast(SubRD)) { + auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr(); + llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass(); + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { +r.srv = true; +break; + } + case llvm::hlsl::ResourceClass::UAV: { +r.uav = true; +break; + } + case llvm::hlsl::ResourceClass::CBuffer: { +r.cbv = true; +break; + } + case llvm::hlsl::ResourceClass::Sampler: { +r.sampler = true; +break; + } + } +} + +else if (SubRD->isCompleteDefinition()) { + for (auto Field : SubRD->fields()) { +QualType T = Field->getType(); +traverseType(T, r); + } +} + } +} + +void setResourceClassFlagsFromRecordDecl(register_binding_flags &r, + const RecordDecl *RD) { + if (!RD) +return; + + if (RD->isCompleteDefinition()) { +for (auto Field : RD->fields()) { + QualType T = Field->getType(); + traverseType(T, r); +} + } +} + +register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) { bob80905 wrote: This will now be used to emit the diagnostics that are tested for in the `resource_binding_attr_error*` tests https://github.com/llvm/llvm-project/pull/97103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc][nfc] Avoid constructing SmallString in ToString method (PR #96921)
https://github.com/ilovepi closed https://github.com/llvm/llvm-project/pull/96921 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits