[llvm-branch-commits] [clang] release/20.x: [Clang][AST] Fix HandleLValueBase to deal with references (#140105) (PR #140246)

2025-05-16 Thread A. Jiang via llvm-branch-commits

https://github.com/frederick-vs-ja created 
https://github.com/llvm/llvm-project/pull/140246

Since P2280R4 Unknown references and pointers was implemented, HandleLValueBase 
now has to deal with referneces:

D.MostDerivedType->getAsCXXRecordDecl()

will return a nullptr if D.MostDerivedType is a ReferenceType. The fix is to 
use getNonReferenceType() to obtain the Pointee Type if we have a reference.

(cherry picked from commit 136f2ba2a7bca015ef831c91fb0db5e5e31b7632)

>From 6ae8c79ed2c7d1deeb686f1d6e1c48b633e86c61 Mon Sep 17 00:00:00 2001
From: Shafik Yaghmour 
Date: Thu, 15 May 2025 16:04:37 -0700
Subject: [PATCH] [Clang][AST] Fix HandleLValueBase to deal with references
 (#140105)

Since P2280R4 Unknown references and pointers was implemented,
HandleLValueBase now has to deal with referneces:

D.MostDerivedType->getAsCXXRecordDecl()

will return a nullptr if D.MostDerivedType is a ReferenceType. The fix
is to use getNonReferenceType() to obtain the Pointee Type if we have a
reference.

Fixes: https://github.com/llvm/llvm-project/issues/139452
(cherry picked from commit 136f2ba2a7bca015ef831c91fb0db5e5e31b7632)

# Conflicts:
#   clang/docs/ReleaseNotes.rst
---
 clang/docs/ReleaseNotes.rst   |  2 ++
 clang/lib/AST/ExprConstant.cpp|  6 +-
 .../SemaCXX/constant-expression-p2280r4.cpp   | 21 +++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 47ef2f80ac3f2..2f43dc4021fd8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -909,6 +909,8 @@ Bug Fixes in This Version
   being deleted has a potentially throwing destructor (#GH118660).
 - Clang now outputs correct values when #embed data contains bytes with 
negative
   signed char values (#GH102798).
+- Fix crash due to unknown references and pointer implementation and handling 
of
+  base classes. (GH139452)
 
 Bug Fixes to Compiler Builtins
 ^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 23602362eaa79..e0746f4532245 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3311,7 +3311,11 @@ static bool HandleLValueBase(EvalInfo &Info, const Expr 
*E, LValue &Obj,
 return false;
 
   // Extract most-derived object and corresponding type.
-  DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
+  // FIXME: After implementing P2280R4 it became possible to get references
+  // here. We do MostDerivedType->getAsCXXRecordDecl() in several other
+  // locations and if we see crashes in those locations in the future
+  // it may make more sense to move this fix into Lvalue::set.
+  DerivedDecl = D.MostDerivedType.getNonReferenceType()->getAsCXXRecordDecl();
   if (!CastToDerivedClass(Info, E, Obj, DerivedDecl, D.MostDerivedPathLength))
 return false;
 
diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp 
b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
index 6c9a87267109c..87beeb4d3dc84 100644
--- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp
+++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
@@ -179,3 +179,24 @@ namespace extern_reference_used_as_unknown {
   int y;
   constinit int& g = (x,y); // expected-warning {{left operand of comma 
operator has no effect}}
 }
+
+namespace GH139452 {
+struct Dummy {
+  explicit operator bool() const noexcept { return true; }
+};
+
+struct Base { int error; };
+struct Derived : virtual Base { };
+
+template 
+constexpr R get_value() {
+const auto& derived_val = Derived{};
+if (derived_val.error != 0)
+/* nothing */;
+return R{};
+}
+
+int f() {
+return !get_value(); // contextually convert the function call 
result to bool
+}
+}

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] release/20.x: [Clang][AST] Fix HandleLValueBase to deal with references (#140105) (PR #140246)

2025-05-16 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: A. Jiang (frederick-vs-ja)


Changes

Since P2280R4 Unknown references and pointers was implemented, HandleLValueBase 
now has to deal with referneces:

D.MostDerivedType->getAsCXXRecordDecl()

will return a nullptr if D.MostDerivedType is a ReferenceType. The fix is to 
use getNonReferenceType() to obtain the Pointee Type if we have a reference.

(cherry picked from commit 136f2ba2a7bca015ef831c91fb0db5e5e31b7632)

---
Full diff: https://github.com/llvm/llvm-project/pull/140246.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+2) 
- (modified) clang/lib/AST/ExprConstant.cpp (+5-1) 
- (modified) clang/test/SemaCXX/constant-expression-p2280r4.cpp (+21) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 47ef2f80ac3f2..2f43dc4021fd8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -909,6 +909,8 @@ Bug Fixes in This Version
   being deleted has a potentially throwing destructor (#GH118660).
 - Clang now outputs correct values when #embed data contains bytes with 
negative
   signed char values (#GH102798).
+- Fix crash due to unknown references and pointer implementation and handling 
of
+  base classes. (GH139452)
 
 Bug Fixes to Compiler Builtins
 ^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 23602362eaa79..e0746f4532245 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3311,7 +3311,11 @@ static bool HandleLValueBase(EvalInfo &Info, const Expr 
*E, LValue &Obj,
 return false;
 
   // Extract most-derived object and corresponding type.
-  DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
+  // FIXME: After implementing P2280R4 it became possible to get references
+  // here. We do MostDerivedType->getAsCXXRecordDecl() in several other
+  // locations and if we see crashes in those locations in the future
+  // it may make more sense to move this fix into Lvalue::set.
+  DerivedDecl = D.MostDerivedType.getNonReferenceType()->getAsCXXRecordDecl();
   if (!CastToDerivedClass(Info, E, Obj, DerivedDecl, D.MostDerivedPathLength))
 return false;
 
diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp 
b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
index 6c9a87267109c..87beeb4d3dc84 100644
--- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp
+++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
@@ -179,3 +179,24 @@ namespace extern_reference_used_as_unknown {
   int y;
   constinit int& g = (x,y); // expected-warning {{left operand of comma 
operator has no effect}}
 }
+
+namespace GH139452 {
+struct Dummy {
+  explicit operator bool() const noexcept { return true; }
+};
+
+struct Base { int error; };
+struct Derived : virtual Base { };
+
+template 
+constexpr R get_value() {
+const auto& derived_val = Derived{};
+if (derived_val.error != 0)
+/* nothing */;
+return R{};
+}
+
+int f() {
+return !get_value(); // contextually convert the function call 
result to bool
+}
+}

``




https://github.com/llvm/llvm-project/pull/140246
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] Enable fexec-charset option (PR #138895)

2025-05-16 Thread Abhina Sree via llvm-branch-commits


@@ -0,0 +1,36 @@
+//===--- clang/Lex/LiteralConverter.h - Translator for Literals -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LEX_LITERALCONVERTER_H
+#define LLVM_CLANG_LEX_LITERALCONVERTER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CharSet.h"
+
+enum ConversionAction { NoConversion, ToSystemCharset, ToExecCharset };
+
+class LiteralConverter {
+  llvm::StringRef InternalCharset;
+  llvm::StringRef SystemCharset;
+  llvm::StringRef ExecCharset;
+  llvm::StringMap CharsetConverters;

abhina-sree wrote:

That makes sense, sure I will do the single converter for now, thanks!

https://github.com/llvm/llvm-project/pull/138895
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [lld] release/20.x: [LLD][COFF] Allow -arm64xsameaddress in ARM64EC directives (#139631) (PR #140051)

2025-05-16 Thread via llvm-branch-commits

github-actions[bot] wrote:

@cjacek (or anyone else). If you would like to add a note about this fix in the 
release notes (completely optional). Please reply to this comment with a one or 
two sentence description of the fix.  When you are done, please add the 
release:note label to this PR. 

https://github.com/llvm/llvm-project/pull/140051
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [lld] release/20.x: [LLD][COFF] Allow -arm64xsameaddress in ARM64EC directives (#139631) (PR #140051)

2025-05-16 Thread Tom Stellard via llvm-branch-commits

https://github.com/tstellar closed 
https://github.com/llvm/llvm-project/pull/140051
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [NFC] Run code formatter on Diagnostic.h/cpp ProfileList.cpp SpecialCaseList.cpp (PR #140295)

2025-05-16 Thread Qinkun Bao via llvm-branch-commits

https://github.com/qinkunbao closed 
https://github.com/llvm/llvm-project/pull/140295
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] CodeGen: Fix implementation of __builtin_trivially_relocate. (PR #140312)

2025-05-16 Thread Eli Friedman via llvm-branch-commits


@@ -4425,6 +4425,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 Address Dest = EmitPointerWithAlignment(E->getArg(0));
 Address Src = EmitPointerWithAlignment(E->getArg(1));
 Value *SizeVal = EmitScalarExpr(E->getArg(2));
+if (BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_trivially_relocate)
+  SizeVal = Builder.CreateMul(

efriedma-quic wrote:

Should this multiply trigger some sort of ubsan check if it overflows?

https://github.com/llvm/llvm-project/pull/140312
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: [LoongArch] Fix fp_to_uint/fp_to_sint conversion errors for lasx (#137129) (PR #139851)

2025-05-16 Thread via llvm-branch-commits

github-actions[bot] wrote:

@tangaac (or anyone else). If you would like to add a note about this fix in 
the release notes (completely optional). Please reply to this comment with a 
one or two sentence description of the fix.  When you are done, please add the 
release:note label to this PR. 

https://github.com/llvm/llvm-project/pull/139851
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] 85e06a7 - [LoongArch] Fix fp_to_uint/fp_to_sint conversion errors for lasx (#137129)

2025-05-16 Thread Tom Stellard via llvm-branch-commits

Author: tangaac
Date: 2025-05-16T16:43:08-07:00
New Revision: 85e06a7614831577a632905c7e3a4f6501fcabd3

URL: 
https://github.com/llvm/llvm-project/commit/85e06a7614831577a632905c7e3a4f6501fcabd3
DIFF: 
https://github.com/llvm/llvm-project/commit/85e06a7614831577a632905c7e3a4f6501fcabd3.diff

LOG: [LoongArch] Fix fp_to_uint/fp_to_sint conversion errors for lasx (#137129)

Prvious `fp_to_uint/fp_to_sint` patterns for `v4f64 -> v4i32` are wrong.
Conversion error was triggered after pr
https://github.com/llvm/llvm-project/pull/126456.

(cherry picked from commit b5c7724f82b6afe98761d0a1c5b6ee7cd2330ada)

Added: 


Modified: 
llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll
llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll

Removed: 




diff  --git a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td 
b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
index 7022fddf34100..9b515a2721d7f 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
@@ -1792,24 +1792,24 @@ def : Pat<(v4f32 (uint_to_fp v4i64:$vj)),
 // XVFTINTRZ_{W_S/L_D}
 def : Pat<(v8i32 (fp_to_sint v8f32:$vj)), (XVFTINTRZ_W_S v8f32:$vj)>;
 def : Pat<(v4i64 (fp_to_sint v4f64:$vj)), (XVFTINTRZ_L_D v4f64:$vj)>;
-def : Pat<(v4i64 (fp_to_sint v4f32:$vj)),
-  (VEXT2XV_D_W (SUBREG_TO_REG (i64 0), (VFTINTRZ_W_S v4f32:$vj),
-  sub_128))>;
-def : Pat<(v4i32 (fp_to_sint (v4f64 LASX256:$vj))),
-  (EXTRACT_SUBREG (XVFTINTRZ_W_S (XVFCVT_S_D (XVPERMI_D v4f64:$vj, 
238),
- v4f64:$vj)),
-  sub_128)>;
+def : Pat<(v4i64(fp_to_sint v4f32:$vj)), (VEXT2XV_D_W(SUBREG_TO_REG(i64 0),
+ (VFTINTRZ_W_S v4f32:$vj),
+ sub_128))>;
+def : Pat<(v4i32(fp_to_sint v4f64:$vj)),
+  (EXTRACT_SUBREG(XVPICKEV_W(XVPERMI_D(XVFTINTRZ_L_D v4f64:$vj), 238),
+   (XVFTINTRZ_L_D v4f64:$vj)),
+  sub_128)>;
 
 // XVFTINTRZ_{W_SU/L_DU}
 def : Pat<(v8i32 (fp_to_uint v8f32:$vj)), (XVFTINTRZ_WU_S v8f32:$vj)>;
 def : Pat<(v4i64 (fp_to_uint v4f64:$vj)), (XVFTINTRZ_LU_D v4f64:$vj)>;
-def : Pat<(v4i64 (fp_to_uint v4f32:$vj)),
-  (VEXT2XV_DU_WU (SUBREG_TO_REG (i64 0), (VFTINTRZ_WU_S v4f32:$vj),
-sub_128))>;
-def : Pat<(v4i32 (fp_to_uint (v4f64 LASX256:$vj))),
-  (EXTRACT_SUBREG (XVFTINTRZ_W_S (XVFCVT_S_D (XVPERMI_D v4f64:$vj, 
238),
- v4f64:$vj)),
-  sub_128)>;
+def : Pat<(v4i64(fp_to_uint v4f32:$vj)), (VEXT2XV_DU_WU(SUBREG_TO_REG(i64 0),
+ (VFTINTRZ_WU_S v4f32:$vj),
+ sub_128))>;
+def : Pat<(v4i32(fp_to_uint v4f64:$vj)),
+  (EXTRACT_SUBREG(XVPICKEV_W(XVPERMI_D(XVFTINTRZ_LU_D v4f64:$vj), 238),
+   (XVFTINTRZ_LU_D v4f64:$vj)),
+  sub_128)>;
 
 // XVPERMI_Q
 foreach vt = [v32i8, v16i16, v8i32, v4i64, v8f32, v4f64] in

diff  --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll 
b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll
index 0d9f57b57ffae..ed333c303879c 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll
@@ -31,9 +31,9 @@ define void @fptosi_v4f64_v4i32(ptr %res, ptr %in){
 ; CHECK-LABEL: fptosi_v4f64_v4i32:
 ; CHECK:   # %bb.0:
 ; CHECK-NEXT:xvld $xr0, $a1, 0
+; CHECK-NEXT:xvftintrz.l.d $xr0, $xr0
 ; CHECK-NEXT:xvpermi.d $xr1, $xr0, 238
-; CHECK-NEXT:xvfcvt.s.d $xr0, $xr1, $xr0
-; CHECK-NEXT:xvftintrz.w.s $xr0, $xr0
+; CHECK-NEXT:xvpickev.w $xr0, $xr1, $xr0
 ; CHECK-NEXT:vst $vr0, $a0, 0
 ; CHECK-NEXT:ret
   %v0 = load <4 x double>, ptr %in

diff  --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll 
b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll
index 27d70f33cd34e..9c499ba71d646 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll
@@ -31,9 +31,9 @@ define void @fptoui_v4f64_v4i32(ptr %res, ptr %in){
 ; CHECK-LABEL: fptoui_v4f64_v4i32:
 ; CHECK:   # %bb.0:
 ; CHECK-NEXT:xvld $xr0, $a1, 0
+; CHECK-NEXT:xvftintrz.lu.d $xr0, $xr0
 ; CHECK-NEXT:xvpermi.d $xr1, $xr0, 238
-; CHECK-NEXT:xvfcvt.s.d $xr0, $xr1, $xr0
-; CHECK-NEXT:xvftintrz.w.s $xr0, $xr0
+; CHECK-NEXT:xvpickev.w $xr0, $xr1, $xr0
 ; CHECK-NEXT:vst $vr0, $a0, 0
 ; CHECK-NEXT:ret
   %v0 = load <4 x double>, ptr %in



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org

[llvm-branch-commits] [llvm] release/20.x: [LoongArch] Fix fp_to_uint/fp_to_sint conversion errors for lasx (#137129) (PR #139851)

2025-05-16 Thread Tom Stellard via llvm-branch-commits

https://github.com/tstellar closed 
https://github.com/llvm/llvm-project/pull/139851
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: [LoongArch] Fix fp_to_uint/fp_to_sint conversion errors for lasx (#137129) (PR #139851)

2025-05-16 Thread via llvm-branch-commits

https://github.com/llvmbot updated 
https://github.com/llvm/llvm-project/pull/139851

>From 85e06a7614831577a632905c7e3a4f6501fcabd3 Mon Sep 17 00:00:00 2001
From: tangaac 
Date: Wed, 7 May 2025 09:29:35 +0800
Subject: [PATCH] [LoongArch] Fix fp_to_uint/fp_to_sint conversion errors for
 lasx (#137129)

Prvious `fp_to_uint/fp_to_sint` patterns for `v4f64 -> v4i32` are wrong.
Conversion error was triggered after pr
https://github.com/llvm/llvm-project/pull/126456.

(cherry picked from commit b5c7724f82b6afe98761d0a1c5b6ee7cd2330ada)
---
 .../LoongArch/LoongArchLASXInstrInfo.td   | 28 +--
 .../LoongArch/lasx/ir-instruction/fptosi.ll   |  4 +--
 .../LoongArch/lasx/ir-instruction/fptoui.ll   |  4 +--
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td 
b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
index 7022fddf34100..9b515a2721d7f 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
@@ -1792,24 +1792,24 @@ def : Pat<(v4f32 (uint_to_fp v4i64:$vj)),
 // XVFTINTRZ_{W_S/L_D}
 def : Pat<(v8i32 (fp_to_sint v8f32:$vj)), (XVFTINTRZ_W_S v8f32:$vj)>;
 def : Pat<(v4i64 (fp_to_sint v4f64:$vj)), (XVFTINTRZ_L_D v4f64:$vj)>;
-def : Pat<(v4i64 (fp_to_sint v4f32:$vj)),
-  (VEXT2XV_D_W (SUBREG_TO_REG (i64 0), (VFTINTRZ_W_S v4f32:$vj),
-  sub_128))>;
-def : Pat<(v4i32 (fp_to_sint (v4f64 LASX256:$vj))),
-  (EXTRACT_SUBREG (XVFTINTRZ_W_S (XVFCVT_S_D (XVPERMI_D v4f64:$vj, 
238),
- v4f64:$vj)),
-  sub_128)>;
+def : Pat<(v4i64(fp_to_sint v4f32:$vj)), (VEXT2XV_D_W(SUBREG_TO_REG(i64 0),
+ (VFTINTRZ_W_S v4f32:$vj),
+ sub_128))>;
+def : Pat<(v4i32(fp_to_sint v4f64:$vj)),
+  (EXTRACT_SUBREG(XVPICKEV_W(XVPERMI_D(XVFTINTRZ_L_D v4f64:$vj), 238),
+   (XVFTINTRZ_L_D v4f64:$vj)),
+  sub_128)>;
 
 // XVFTINTRZ_{W_SU/L_DU}
 def : Pat<(v8i32 (fp_to_uint v8f32:$vj)), (XVFTINTRZ_WU_S v8f32:$vj)>;
 def : Pat<(v4i64 (fp_to_uint v4f64:$vj)), (XVFTINTRZ_LU_D v4f64:$vj)>;
-def : Pat<(v4i64 (fp_to_uint v4f32:$vj)),
-  (VEXT2XV_DU_WU (SUBREG_TO_REG (i64 0), (VFTINTRZ_WU_S v4f32:$vj),
-sub_128))>;
-def : Pat<(v4i32 (fp_to_uint (v4f64 LASX256:$vj))),
-  (EXTRACT_SUBREG (XVFTINTRZ_W_S (XVFCVT_S_D (XVPERMI_D v4f64:$vj, 
238),
- v4f64:$vj)),
-  sub_128)>;
+def : Pat<(v4i64(fp_to_uint v4f32:$vj)), (VEXT2XV_DU_WU(SUBREG_TO_REG(i64 0),
+ (VFTINTRZ_WU_S v4f32:$vj),
+ sub_128))>;
+def : Pat<(v4i32(fp_to_uint v4f64:$vj)),
+  (EXTRACT_SUBREG(XVPICKEV_W(XVPERMI_D(XVFTINTRZ_LU_D v4f64:$vj), 238),
+   (XVFTINTRZ_LU_D v4f64:$vj)),
+  sub_128)>;
 
 // XVPERMI_Q
 foreach vt = [v32i8, v16i16, v8i32, v4i64, v8f32, v4f64] in
diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll 
b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll
index 0d9f57b57ffae..ed333c303879c 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll
@@ -31,9 +31,9 @@ define void @fptosi_v4f64_v4i32(ptr %res, ptr %in){
 ; CHECK-LABEL: fptosi_v4f64_v4i32:
 ; CHECK:   # %bb.0:
 ; CHECK-NEXT:xvld $xr0, $a1, 0
+; CHECK-NEXT:xvftintrz.l.d $xr0, $xr0
 ; CHECK-NEXT:xvpermi.d $xr1, $xr0, 238
-; CHECK-NEXT:xvfcvt.s.d $xr0, $xr1, $xr0
-; CHECK-NEXT:xvftintrz.w.s $xr0, $xr0
+; CHECK-NEXT:xvpickev.w $xr0, $xr1, $xr0
 ; CHECK-NEXT:vst $vr0, $a0, 0
 ; CHECK-NEXT:ret
   %v0 = load <4 x double>, ptr %in
diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll 
b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll
index 27d70f33cd34e..9c499ba71d646 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll
@@ -31,9 +31,9 @@ define void @fptoui_v4f64_v4i32(ptr %res, ptr %in){
 ; CHECK-LABEL: fptoui_v4f64_v4i32:
 ; CHECK:   # %bb.0:
 ; CHECK-NEXT:xvld $xr0, $a1, 0
+; CHECK-NEXT:xvftintrz.lu.d $xr0, $xr0
 ; CHECK-NEXT:xvpermi.d $xr1, $xr0, 238
-; CHECK-NEXT:xvfcvt.s.d $xr0, $xr1, $xr0
-; CHECK-NEXT:xvftintrz.w.s $xr0, $xr0
+; CHECK-NEXT:xvpickev.w $xr0, $xr1, $xr0
 ; CHECK-NEXT:vst $vr0, $a0, 0
 ; CHECK-NEXT:ret
   %v0 = load <4 x double>, ptr %in

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update serializer for improved template handling (PR #138065)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138065

>From 9c19df29900c95a1b19508a6e99fb76f7bab3cc0 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Tue, 29 Apr 2025 18:31:54 -0700
Subject: [PATCH] [clang-doc] Update serializer for improved template handling

This patch updates Serialize.cpp to serialize more data about C++
templates, which are supported by the new mustache HTML template.
Split from #133161.

Co-authored-by: Peter Chou 
---
 clang-tools-extra/clang-doc/Representation.h |   3 +
 clang-tools-extra/clang-doc/Serialize.cpp| 214 ++-
 2 files changed, 209 insertions(+), 8 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index a2e01719eb59e..1673be496b7b2 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -363,6 +363,9 @@ struct FunctionInfo : public SymbolInfo {
   // specializations.
   SmallString<16> FullName;
 
+  // Function Prototype
+  SmallString<256> Prototype;
+
   // When present, this function is a template or specialization.
   std::optional Template;
 };
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 18db427b5239e..b7c0d95c3be39 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -8,10 +8,10 @@
 
 #include "Serialize.h"
 #include "BitcodeWriter.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Comment.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/Lexer.h"
-#include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/SHA1.h"
 
@@ -35,6 +35,180 @@ static void populateMemberTypeInfo(RecordInfo &I, 
AccessSpecifier &Access,
const DeclaratorDecl *D,
bool IsStatic = false);
 
+static void getTemplateParameters(const TemplateParameterList *TemplateParams,
+  llvm::raw_ostream &Stream) {
+  Stream << "template <";
+
+  for (unsigned i = 0; i < TemplateParams->size(); ++i) {
+if (i > 0)
+  Stream << ", ";
+
+const NamedDecl *Param = TemplateParams->getParam(i);
+if (const auto *TTP = llvm::dyn_cast(Param)) {
+  if (TTP->wasDeclaredWithTypename())
+Stream << "typename";
+  else
+Stream << "class";
+  if (TTP->isParameterPack())
+Stream << "...";
+  Stream << " " << TTP->getNameAsString();
+} else if (const auto *NTTP =
+   llvm::dyn_cast(Param)) {
+  NTTP->getType().print(Stream, NTTP->getASTContext().getPrintingPolicy());
+  if (NTTP->isParameterPack())
+Stream << "...";
+  Stream << " " << NTTP->getNameAsString();
+} else if (const auto *TTPD =
+   llvm::dyn_cast(Param)) {
+  Stream << "template <";
+  getTemplateParameters(TTPD->getTemplateParameters(), Stream);
+  Stream << "> class " << TTPD->getNameAsString();
+}
+  }
+
+  Stream << "> ";
+}
+
+// Extract the full function prototype from a FunctionDecl including
+// Full Decl
+static llvm::SmallString<256>
+getFunctionPrototype(const FunctionDecl *FuncDecl) {
+  llvm::SmallString<256> Result;
+  llvm::raw_svector_ostream Stream(Result);
+  const ASTContext &Ctx = FuncDecl->getASTContext();
+  const auto *Method = llvm::dyn_cast(FuncDecl);
+  // If it's a templated function, handle the template parameters
+  if (const auto *TmplDecl = FuncDecl->getDescribedTemplate())
+getTemplateParameters(TmplDecl->getTemplateParameters(), Stream);
+
+  // If it's a virtual method
+  if (Method && Method->isVirtual())
+Stream << "virtual ";
+
+  // Print return type
+  FuncDecl->getReturnType().print(Stream, Ctx.getPrintingPolicy());
+
+  // Print function name
+  Stream << " " << FuncDecl->getNameAsString() << "(";
+
+  // Print parameter list with types, names, and default values
+  for (unsigned I = 0; I < FuncDecl->getNumParams(); ++I) {
+if (I > 0)
+  Stream << ", ";
+const ParmVarDecl *ParamDecl = FuncDecl->getParamDecl(I);
+QualType ParamType = ParamDecl->getType();
+ParamType.print(Stream, Ctx.getPrintingPolicy());
+
+// Print parameter name if it has one
+if (!ParamDecl->getName().empty())
+  Stream << " " << ParamDecl->getNameAsString();
+
+// Print default argument if it exists
+if (ParamDecl->hasDefaultArg()) {
+  const Expr *DefaultArg = ParamDecl->getDefaultArg();
+  if (DefaultArg) {
+Stream << " = ";
+DefaultArg->printPretty(Stream, nullptr, Ctx.getPrintingPolicy());
+  }
+}
+  }
+
+  // If it is a variadic function, add '...'
+  if (FuncDecl->isVariadic()) {
+if (FuncDecl->getNumParams() > 0)
+  Stream << ", ";
+Stream << "...";
+  }
+
+  Stream << ")";
+
+  // If it's a const method, add 'const' qualifier
+  if (Method) {
+if (Method->size_overridden_methods())
+   

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Extract Info into JSON values (PR #138063)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138063

>From c7f6fb81bf5bbf16d76d1ea541fb5719da529220 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:11:39 -0700
Subject: [PATCH] [clang-doc] Extract Info into JSON values

Split from #133161. This patch provides the implementation of a number
of extractValue overloads used with the different types of Info.

The new helper functions extract the relevant information from the
different *Infos and inserts them into the correct fields of the JSON
values that will be used with the specific Mustache templates, which
will land separately.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   | 249 ++
 1 file changed, 249 insertions(+)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 4a971f315efc7..801f54670fb89 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -162,15 +162,264 @@ Error MustacheHTMLGenerator::generateDocs(
   return Error::success();
 }
 
+static json::Value
+extractValue(const Location &L,
+ std::optional RepositoryUrl = std::nullopt) {
+  Object Obj = Object();
+  // Should there be Start/End line numbers?
+  Obj.insert({"LineNumber", L.StartLineNumber});
+  Obj.insert({"Filename", L.Filename});
+
+  if (!L.IsFileInRootDir || !RepositoryUrl)
+return Obj;
+  SmallString<128> FileURL(*RepositoryUrl);
+  sys::path::append(FileURL, sys::path::Style::posix, L.Filename);
+  FileURL += "#" + std::to_string(L.StartLineNumber);
+  Obj.insert({"FileURL", FileURL});
+
+  return Obj;
+}
+
+static json::Value extractValue(const Reference &I,
+StringRef CurrentDirectory) {
+  SmallString<64> Path = I.getRelativeFilePath(CurrentDirectory);
+  sys::path::append(Path, I.getFileBaseName() + ".html");
+  sys::path::native(Path, sys::path::Style::posix);
+  Object Obj = Object();
+  Obj.insert({"Link", Path});
+  Obj.insert({"Name", I.Name});
+  Obj.insert({"QualName", I.QualName});
+  Obj.insert({"ID", toHex(toStringRef(I.USR))});
+  return Obj;
+}
+
+static json::Value extractValue(const TypedefInfo &I) {
+  // Not Supported
+  return nullptr;
+}
+
+static json::Value extractValue(const CommentInfo &I) {
+  assert((I.Kind == "BlockCommandComment" || I.Kind == "FullComment" ||
+  I.Kind == "ParagraphComment" || I.Kind == "TextComment") &&
+ "Unknown Comment type in CommentInfo.");
+
+  Object Obj = Object();
+  json::Value Child = Object();
+
+  // TextComment has no children, so return it.
+  if (I.Kind == "TextComment") {
+Obj.insert({"TextComment", I.Text});
+return Obj;
+  }
+
+  // BlockCommandComment needs to generate a Command key.
+  if (I.Kind == "BlockCommandComment")
+Child.getAsObject()->insert({"Command", I.Name});
+
+  // Use the same handling for everything else.
+  // Only valid for:
+  //  - BlockCommandComment
+  //  - FullComment
+  //  - ParagraphComment
+  json::Value ChildArr = Array();
+  auto &CARef = *ChildArr.getAsArray();
+  CARef.reserve(I.Children.size());
+  for (const auto &C : I.Children)
+CARef.emplace_back(extractValue(*C));
+  Child.getAsObject()->insert({"Children", ChildArr});
+  Obj.insert({I.Kind, Child});
+
+  return Obj;
+}
+
+static void maybeInsertLocation(std::optional Loc,
+const ClangDocContext &CDCtx, Object &Obj) {
+  if (!Loc)
+return;
+  Location L = *Loc;
+  Obj.insert({"Location", extractValue(L, CDCtx.RepositoryUrl)});
+}
+
+static void extractDescriptionFromInfo(ArrayRef Descriptions,
+   json::Object &EnumValObj) {
+  if (Descriptions.empty())
+return;
+  json::Value ArrDesc = Array();
+  json::Array &ADescRef = *ArrDesc.getAsArray();
+  for (const CommentInfo &Child : Descriptions)
+ADescRef.emplace_back(extractValue(Child));
+  EnumValObj.insert({"EnumValueComments", ArrDesc});
+}
+
+static json::Value extractValue(const FunctionInfo &I, StringRef ParentInfoDir,
+const ClangDocContext &CDCtx) {
+  Object Obj = Object();
+  Obj.insert({"Name", I.Name});
+  Obj.insert({"ID", toHex(toStringRef(I.USR))});
+  Obj.insert({"Access", getAccessSpelling(I.Access).str()});
+  Obj.insert({"ReturnType", extractValue(I.ReturnType.Type, ParentInfoDir)});
+
+  json::Value ParamArr = Array();
+  for (const auto Val : enumerate(I.Params)) {
+json::Value V = Object();
+auto &VRef = *V.getAsObject();
+VRef.insert({"Name", Val.value().Name});
+VRef.insert({"Type", Val.value().Type.Name});
+VRef.insert({"End", Val.index() + 1 == I.Params.size()});
+ParamArr.getAsArray()->emplace_back(V);
+  }
+  Obj.insert({"Params", ParamArr});
+
+  maybeInsertLocation(I.DefLoc, CDCtx, Obj);
+  return Obj;
+}
+
+static json::Value extractValue(const EnumInfo &I,
+

[llvm-branch-commits] [lld] e3d2c00 - [LLD][COFF] Allow -arm64xsameaddress in ARM64EC directives (#139631)

2025-05-16 Thread Tom Stellard via llvm-branch-commits

Author: Jacek Caban
Date: 2025-05-16T16:47:32-07:00
New Revision: e3d2c00ccee45e882233fce230c42b23423a8ef7

URL: 
https://github.com/llvm/llvm-project/commit/e3d2c00ccee45e882233fce230c42b23423a8ef7
DIFF: 
https://github.com/llvm/llvm-project/commit/e3d2c00ccee45e882233fce230c42b23423a8ef7.diff

LOG: [LLD][COFF] Allow -arm64xsameaddress in ARM64EC directives (#139631)

Make it a no-op for now, which is sufficient for non-hybrid images.

Fixes #131712.

(cherry picked from commit d5da557782dd47395fb41e03d7663df6319d7ea6)

Added: 
lld/test/COFF/arm64x-sameaddress.test

Modified: 
lld/COFF/Driver.cpp
lld/COFF/Options.td

Removed: 




diff  --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index f50ca529df4d7..a669b7e9296f6 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -492,6 +492,12 @@ void LinkerDriver::parseDirectives(InputFile *file) {
 case OPT_alternatename:
   parseAlternateName(arg->getValue());
   break;
+case OPT_arm64xsameaddress:
+  if (!file->symtab.isEC())
+Warn(ctx) << arg->getSpelling()
+  << " is not allowed in non-ARM64EC files (" << toString(file)
+  << ")";
+  break;
 case OPT_defaultlib:
   if (std::optional path = findLibIfNew(arg->getValue()))
 enqueuePath(*path, false, false);

diff  --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index b6fd3d0daaef9..ea2e7ded38043 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -355,3 +355,4 @@ def tlbid : P_priv<"tlbid">;
 def tlbout : P_priv<"tlbout">;
 def verbose_all : P_priv<"verbose">;
 def guardsym : P_priv<"guardsym">;
+def arm64xsameaddress : P_priv<"arm64xsameaddress">;

diff  --git a/lld/test/COFF/arm64x-sameaddress.test 
b/lld/test/COFF/arm64x-sameaddress.test
new file mode 100644
index 0..c69be9d268c3b
--- /dev/null
+++ b/lld/test/COFF/arm64x-sameaddress.test
@@ -0,0 +1,56 @@
+REQUIRES: aarch64
+RUN: split-file %s %t.dir && cd %t.dir
+
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows func-arm64ec.s -o 
func-arm64ec.obj
+RUN: llvm-mc -filetype=obj -triple=aarch64-windows func-arm64.s -o 
func-arm64.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows drectve.s -o drectve.obj
+RUN: llvm-mc -filetype=obj -triple=aarch64-windows drectve.s -o 
drectve-arm64.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows 
%S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
+RUN: llvm-mc -filetype=obj -triple=aarch64-windows 
%S/Inputs/loadconfig-arm64.s -o loadconfig-arm64.obj
+
+RUN: lld-link -machine:arm64x -dll -noentry -out:out.dll loadconfig-arm64.obj 
loadconfig-arm64ec.obj \
+RUN:  func-arm64.obj func-arm64ec.obj drectve.obj
+
+RUN: lld-link -machine:arm64x -dll -noentry -out:out-cmd.dll 
loadconfig-arm64.obj loadconfig-arm64ec.obj \
+RUN:  func-arm64.obj func-arm64ec.obj -arm64xsameaddress:func
+
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out-ec.dll 
loadconfig-arm64ec.obj func-arm64ec.obj drectve.obj
+
+RUN: lld-link -machine:arm64x -dll -noentry -out:out-warn.dll 
loadconfig-arm64.obj loadconfig-arm64ec.obj \
+RUN:  func-arm64.obj func-arm64ec.obj drectve-arm64.obj 2>&1 | 
FileCheck --check-prefix=WARN %s
+WARN: lld-link: warning: -arm64xsameaddress: is not allowed in non-ARM64EC 
files (drectve-arm64.obj)
+
+#--- func-arm64.s
+.section .text,"xr",discard,func
+.globl func
+func:
+mov x0, #1
+ret
+
+#--- func-arm64ec.s
+.section .text,"xr",discard,"#func"
+.globl "#func"
+"#func":
+mov x0, #2
+ret
+
+.weak_anti_dep func
+.set func,"#func"
+
+.section .wowthk,"xr",discard,entry_thunk
+.globl entry_thunk
+entry_thunk:
+mov x0, #3
+ret
+
+.section .test,"dr"
+.rva func
+
+   .section .hybmp$x,"yi"
+   .symidx "#func"
+   .symidx entry_thunk
+   .word 1
+
+#--- drectve.s
+.section .drectve, "yn"
+.ascii " -arm64xsameaddress:func"



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] release/20.x: [Clang][AST] Fix HandleLValueBase to deal with references (#140105) (PR #140246)

2025-05-16 Thread Tom Stellard via llvm-branch-commits

https://github.com/tstellar updated 
https://github.com/llvm/llvm-project/pull/140246

>From 5befd1fb3c97a5c880da4c1e3ae4c8cf7b614425 Mon Sep 17 00:00:00 2001
From: Shafik Yaghmour 
Date: Thu, 15 May 2025 16:04:37 -0700
Subject: [PATCH] [Clang][AST] Fix HandleLValueBase to deal with references
 (#140105)

Since P2280R4 Unknown references and pointers was implemented,
HandleLValueBase now has to deal with referneces:

D.MostDerivedType->getAsCXXRecordDecl()

will return a nullptr if D.MostDerivedType is a ReferenceType. The fix
is to use getNonReferenceType() to obtain the Pointee Type if we have a
reference.

Fixes: https://github.com/llvm/llvm-project/issues/139452
(cherry picked from commit 136f2ba2a7bca015ef831c91fb0db5e5e31b7632)

# Conflicts:
#   clang/docs/ReleaseNotes.rst
---
 clang/docs/ReleaseNotes.rst   |  2 ++
 clang/lib/AST/ExprConstant.cpp|  6 +-
 .../SemaCXX/constant-expression-p2280r4.cpp   | 21 +++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 47ef2f80ac3f2..2f43dc4021fd8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -909,6 +909,8 @@ Bug Fixes in This Version
   being deleted has a potentially throwing destructor (#GH118660).
 - Clang now outputs correct values when #embed data contains bytes with 
negative
   signed char values (#GH102798).
+- Fix crash due to unknown references and pointer implementation and handling 
of
+  base classes. (GH139452)
 
 Bug Fixes to Compiler Builtins
 ^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 23602362eaa79..e0746f4532245 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3311,7 +3311,11 @@ static bool HandleLValueBase(EvalInfo &Info, const Expr 
*E, LValue &Obj,
 return false;
 
   // Extract most-derived object and corresponding type.
-  DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
+  // FIXME: After implementing P2280R4 it became possible to get references
+  // here. We do MostDerivedType->getAsCXXRecordDecl() in several other
+  // locations and if we see crashes in those locations in the future
+  // it may make more sense to move this fix into Lvalue::set.
+  DerivedDecl = D.MostDerivedType.getNonReferenceType()->getAsCXXRecordDecl();
   if (!CastToDerivedClass(Info, E, Obj, DerivedDecl, D.MostDerivedPathLength))
 return false;
 
diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp 
b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
index 6c9a87267109c..87beeb4d3dc84 100644
--- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp
+++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
@@ -179,3 +179,24 @@ namespace extern_reference_used_as_unknown {
   int y;
   constinit int& g = (x,y); // expected-warning {{left operand of comma 
operator has no effect}}
 }
+
+namespace GH139452 {
+struct Dummy {
+  explicit operator bool() const noexcept { return true; }
+};
+
+struct Base { int error; };
+struct Derived : virtual Base { };
+
+template 
+constexpr R get_value() {
+const auto& derived_val = Derived{};
+if (derived_val.error != 0)
+/* nothing */;
+return R{};
+}
+
+int f() {
+return !get_value(); // contextually convert the function call 
result to bool
+}
+}

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] 5befd1f - [Clang][AST] Fix HandleLValueBase to deal with references (#140105)

2025-05-16 Thread Tom Stellard via llvm-branch-commits

Author: Shafik Yaghmour
Date: 2025-05-16T16:54:12-07:00
New Revision: 5befd1fb3c97a5c880da4c1e3ae4c8cf7b614425

URL: 
https://github.com/llvm/llvm-project/commit/5befd1fb3c97a5c880da4c1e3ae4c8cf7b614425
DIFF: 
https://github.com/llvm/llvm-project/commit/5befd1fb3c97a5c880da4c1e3ae4c8cf7b614425.diff

LOG: [Clang][AST] Fix HandleLValueBase to deal with references (#140105)

Since P2280R4 Unknown references and pointers was implemented,
HandleLValueBase now has to deal with referneces:

D.MostDerivedType->getAsCXXRecordDecl()

will return a nullptr if D.MostDerivedType is a ReferenceType. The fix
is to use getNonReferenceType() to obtain the Pointee Type if we have a
reference.

Fixes: https://github.com/llvm/llvm-project/issues/139452
(cherry picked from commit 136f2ba2a7bca015ef831c91fb0db5e5e31b7632)

# Conflicts:
#   clang/docs/ReleaseNotes.rst

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/constant-expression-p2280r4.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 47ef2f80ac3f2..2f43dc4021fd8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -909,6 +909,8 @@ Bug Fixes in This Version
   being deleted has a potentially throwing destructor (#GH118660).
 - Clang now outputs correct values when #embed data contains bytes with 
negative
   signed char values (#GH102798).
+- Fix crash due to unknown references and pointer implementation and handling 
of
+  base classes. (GH139452)
 
 Bug Fixes to Compiler Builtins
 ^^

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 23602362eaa79..e0746f4532245 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3311,7 +3311,11 @@ static bool HandleLValueBase(EvalInfo &Info, const Expr 
*E, LValue &Obj,
 return false;
 
   // Extract most-derived object and corresponding type.
-  DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
+  // FIXME: After implementing P2280R4 it became possible to get references
+  // here. We do MostDerivedType->getAsCXXRecordDecl() in several other
+  // locations and if we see crashes in those locations in the future
+  // it may make more sense to move this fix into Lvalue::set.
+  DerivedDecl = D.MostDerivedType.getNonReferenceType()->getAsCXXRecordDecl();
   if (!CastToDerivedClass(Info, E, Obj, DerivedDecl, D.MostDerivedPathLength))
 return false;
 

diff  --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp 
b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
index 6c9a87267109c..87beeb4d3dc84 100644
--- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp
+++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
@@ -179,3 +179,24 @@ namespace extern_reference_used_as_unknown {
   int y;
   constinit int& g = (x,y); // expected-warning {{left operand of comma 
operator has no effect}}
 }
+
+namespace GH139452 {
+struct Dummy {
+  explicit operator bool() const noexcept { return true; }
+};
+
+struct Base { int error; };
+struct Derived : virtual Base { };
+
+template 
+constexpr R get_value() {
+const auto& derived_val = Derived{};
+if (derived_val.error != 0)
+/* nothing */;
+return R{};
+}
+
+int f() {
+return !get_value(); // contextually convert the function call 
result to bool
+}
+}



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] release/20.x: [Clang][AST] Fix HandleLValueBase to deal with references (#140105) (PR #140246)

2025-05-16 Thread Tom Stellard via llvm-branch-commits

https://github.com/tstellar closed 
https://github.com/llvm/llvm-project/pull/140246
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] release/20.x: [Clang][AST] Fix HandleLValueBase to deal with references (#140105) (PR #140246)

2025-05-16 Thread via llvm-branch-commits

github-actions[bot] wrote:

@frederick-vs-ja (or anyone else). If you would like to add a note about this 
fix in the release notes (completely optional). Please reply to this comment 
with a one or two sentence description of the fix.  When you are done, please 
add the release:note label to this PR. 

https://github.com/llvm/llvm-project/pull/140246
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update serializer for improved template handling (PR #138065)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138065

>From 9c19df29900c95a1b19508a6e99fb76f7bab3cc0 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Tue, 29 Apr 2025 18:31:54 -0700
Subject: [PATCH] [clang-doc] Update serializer for improved template handling

This patch updates Serialize.cpp to serialize more data about C++
templates, which are supported by the new mustache HTML template.
Split from #133161.

Co-authored-by: Peter Chou 
---
 clang-tools-extra/clang-doc/Representation.h |   3 +
 clang-tools-extra/clang-doc/Serialize.cpp| 214 ++-
 2 files changed, 209 insertions(+), 8 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index a2e01719eb59e..1673be496b7b2 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -363,6 +363,9 @@ struct FunctionInfo : public SymbolInfo {
   // specializations.
   SmallString<16> FullName;
 
+  // Function Prototype
+  SmallString<256> Prototype;
+
   // When present, this function is a template or specialization.
   std::optional Template;
 };
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 18db427b5239e..b7c0d95c3be39 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -8,10 +8,10 @@
 
 #include "Serialize.h"
 #include "BitcodeWriter.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Comment.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/Lexer.h"
-#include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/SHA1.h"
 
@@ -35,6 +35,180 @@ static void populateMemberTypeInfo(RecordInfo &I, 
AccessSpecifier &Access,
const DeclaratorDecl *D,
bool IsStatic = false);
 
+static void getTemplateParameters(const TemplateParameterList *TemplateParams,
+  llvm::raw_ostream &Stream) {
+  Stream << "template <";
+
+  for (unsigned i = 0; i < TemplateParams->size(); ++i) {
+if (i > 0)
+  Stream << ", ";
+
+const NamedDecl *Param = TemplateParams->getParam(i);
+if (const auto *TTP = llvm::dyn_cast(Param)) {
+  if (TTP->wasDeclaredWithTypename())
+Stream << "typename";
+  else
+Stream << "class";
+  if (TTP->isParameterPack())
+Stream << "...";
+  Stream << " " << TTP->getNameAsString();
+} else if (const auto *NTTP =
+   llvm::dyn_cast(Param)) {
+  NTTP->getType().print(Stream, NTTP->getASTContext().getPrintingPolicy());
+  if (NTTP->isParameterPack())
+Stream << "...";
+  Stream << " " << NTTP->getNameAsString();
+} else if (const auto *TTPD =
+   llvm::dyn_cast(Param)) {
+  Stream << "template <";
+  getTemplateParameters(TTPD->getTemplateParameters(), Stream);
+  Stream << "> class " << TTPD->getNameAsString();
+}
+  }
+
+  Stream << "> ";
+}
+
+// Extract the full function prototype from a FunctionDecl including
+// Full Decl
+static llvm::SmallString<256>
+getFunctionPrototype(const FunctionDecl *FuncDecl) {
+  llvm::SmallString<256> Result;
+  llvm::raw_svector_ostream Stream(Result);
+  const ASTContext &Ctx = FuncDecl->getASTContext();
+  const auto *Method = llvm::dyn_cast(FuncDecl);
+  // If it's a templated function, handle the template parameters
+  if (const auto *TmplDecl = FuncDecl->getDescribedTemplate())
+getTemplateParameters(TmplDecl->getTemplateParameters(), Stream);
+
+  // If it's a virtual method
+  if (Method && Method->isVirtual())
+Stream << "virtual ";
+
+  // Print return type
+  FuncDecl->getReturnType().print(Stream, Ctx.getPrintingPolicy());
+
+  // Print function name
+  Stream << " " << FuncDecl->getNameAsString() << "(";
+
+  // Print parameter list with types, names, and default values
+  for (unsigned I = 0; I < FuncDecl->getNumParams(); ++I) {
+if (I > 0)
+  Stream << ", ";
+const ParmVarDecl *ParamDecl = FuncDecl->getParamDecl(I);
+QualType ParamType = ParamDecl->getType();
+ParamType.print(Stream, Ctx.getPrintingPolicy());
+
+// Print parameter name if it has one
+if (!ParamDecl->getName().empty())
+  Stream << " " << ParamDecl->getNameAsString();
+
+// Print default argument if it exists
+if (ParamDecl->hasDefaultArg()) {
+  const Expr *DefaultArg = ParamDecl->getDefaultArg();
+  if (DefaultArg) {
+Stream << " = ";
+DefaultArg->printPretty(Stream, nullptr, Ctx.getPrintingPolicy());
+  }
+}
+  }
+
+  // If it is a variadic function, add '...'
+  if (FuncDecl->isVariadic()) {
+if (FuncDecl->getNumParams() > 0)
+  Stream << ", ";
+Stream << "...";
+  }
+
+  Stream << ")";
+
+  // If it's a const method, add 'const' qualifier
+  if (Method) {
+if (Method->size_overridden_methods())
+   

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138062

>From fb0db52bfd5f3e32ddb176b97d984ccb15de7154 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:10:20 -0700
Subject: [PATCH] [clang-doc] Add helpers for Template config

This patch adds or fills in some helper functions related to template
setup when initializing the mustache backend. It was split from #133161.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   | 45 ++
 .../clang-doc/support/CMakeLists.txt  |  4 +-
 clang-tools-extra/clang-doc/support/Utils.cpp | 61 +++
 clang-tools-extra/clang-doc/support/Utils.h   | 26 
 .../unittests/clang-doc/CMakeLists.txt| 12 
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 11 +++-
 .../unittests/clang-doc/config.h.cmake|  6 ++
 7 files changed, 162 insertions(+), 3 deletions(-)
 create mode 100644 clang-tools-extra/clang-doc/support/Utils.cpp
 create mode 100644 clang-tools-extra/clang-doc/support/Utils.h
 create mode 100644 clang-tools-extra/unittests/clang-doc/config.h.cmake

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 366deb55b77b9..4a971f315efc7 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Mustache.h"
+#include "llvm/Support/Path.h"
 
 using namespace llvm;
 using namespace llvm::json;
@@ -74,7 +75,51 @@ static std::unique_ptr 
NamespaceTemplate = nullptr;
 
 static std::unique_ptr RecordTemplate = nullptr;
 
+static Error
+setupTemplate(std::unique_ptr &Template,
+  StringRef TemplatePath,
+  std::vector> Partials) {
+  auto T = MustacheTemplateFile::createMustacheFile(TemplatePath);
+  if (Error Err = T.takeError())
+return Err;
+  Template = std::move(T.get());
+  for (const auto [Name, FileName] : Partials) {
+if (auto Err = Template->registerPartialFile(Name, FileName))
+  return Err;
+  }
+  return Error::success();
+}
+
 static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) {
+  // Template files need to use the native path when they're opened,
+  // but have to be used in Posix style when used in HTML.
+  auto ConvertToNative = [](std::string &&Path) -> std::string {
+SmallString<128> PathBuff(Path);
+llvm::sys::path::native(PathBuff);
+return PathBuff.str().str();
+  };
+
+  std::string NamespaceFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("namespace-template"));
+  std::string ClassFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("class-template"));
+  std::string CommentFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("comments-template"));
+  std::string FunctionFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("function-template"));
+  std::string EnumFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("enum-template"));
+  std::vector> Partials = {
+  {"Comments", CommentFilePath},
+  {"FunctionPartial", FunctionFilePath},
+  {"EnumPartial", EnumFilePath}};
+
+  if (Error Err = setupTemplate(NamespaceTemplate, NamespaceFilePath, 
Partials))
+return Err;
+
+  if (Error Err = setupTemplate(RecordTemplate, ClassFilePath, Partials))
+return Err;
+
   return Error::success();
 }
 
diff --git a/clang-tools-extra/clang-doc/support/CMakeLists.txt 
b/clang-tools-extra/clang-doc/support/CMakeLists.txt
index a4f7993d5c9d8..f470a613b95d9 100644
--- a/clang-tools-extra/clang-doc/support/CMakeLists.txt
+++ b/clang-tools-extra/clang-doc/support/CMakeLists.txt
@@ -6,4 +6,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_clang_library(clangDocSupport STATIC
   File.cpp
-  )
\ No newline at end of file
+  Utils.cpp
+  )
+
diff --git a/clang-tools-extra/clang-doc/support/Utils.cpp 
b/clang-tools-extra/clang-doc/support/Utils.cpp
new file mode 100644
index 0..f1d193379afa6
--- /dev/null
+++ b/clang-tools-extra/clang-doc/support/Utils.cpp
@@ -0,0 +1,61 @@
+//===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "Utils.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+using namespace llvm;
+
+SmallString<128> appendPathNative(StringRef Base, StringRef Path) {
+  SmallString<128> Default;
+  sys::path::native(Base, Default);
+  sys::path::append(Default, Path);
+  return Default;
+}
+
+SmallString<128> appendPathPo

[llvm-branch-commits] [clang] [Clang][Backport] Demote mixed enumeration arithmetic error to a warning (#131811) (PR #139396)

2025-05-16 Thread Tom Stellard via llvm-branch-commits


@@ -7567,9 +7567,13 @@ def warn_arith_conv_mixed_enum_types_cxx20 : Warning<
   "%sub{select_arith_conv_kind}0 "
   "different enumeration types%diff{ ($ and $)|}1,2 is deprecated">,
   InGroup;
-def err_conv_mixed_enum_types_cxx26 : Error<
+
+def err_conv_mixed_enum_types: Error <
   "invalid %sub{select_arith_conv_kind}0 "
   "different enumeration types%diff{ ($ and $)|}1,2">;
+def warn_conv_mixed_enum_types_cxx26 : Warning <
+  err_conv_mixed_enum_types.Summary>,
+  InGroup, DefaultError;

tstellar wrote:

The issue is that TableGen sorts the enums alphabetically, so adding a new 
value will change the name->integer mapping for approximately half of the enum. 
 Maybe ABI break is the wrong term here, but it means than an app built against 
20.1.4, for example will stop working if 20.1.4 libraries are replaced by 
20.1.5 libraries, which is something we want to avoid even if it's not 
technically an ABI break.

https://github.com/llvm/llvm-project/pull/139396
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Fix test pfalse-v4i1.ll added in #138712 to require asserts. (PR #139822)

2025-05-16 Thread Tom Stellard via llvm-branch-commits

https://github.com/tstellar updated 
https://github.com/llvm/llvm-project/pull/139822

>From ff2e8f93f6090965e82d799af43f6dfef52baa66 Mon Sep 17 00:00:00 2001
From: Douglas Yung 
Date: Wed, 7 May 2025 06:13:07 +
Subject: [PATCH] Fix test pfalse-v4i1.ll added in #138712 to require asserts.

Should fix build bot failure: 
https://lab.llvm.org/buildbot/#/builders/202/builds/1102

(cherry picked from commit 194a4a333a95f9e001d2c8abe82c3d4cf8894acf)
---
 llvm/test/CodeGen/Hexagon/isel/pfalse-v4i1.ll | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/test/CodeGen/Hexagon/isel/pfalse-v4i1.ll 
b/llvm/test/CodeGen/Hexagon/isel/pfalse-v4i1.ll
index c0904b8b4fdd6..2c26bb1e310ea 100644
--- a/llvm/test/CodeGen/Hexagon/isel/pfalse-v4i1.ll
+++ b/llvm/test/CodeGen/Hexagon/isel/pfalse-v4i1.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -march=hexagon -debug-only=isel 2>&1 < %s - | FileCheck %s
+; REQUIRES: asserts
 
 ; CHECK: [[R0:%[0-9]+]]:intregs = A2_tfrsi 0
 ; CHECK-NEXT: predregs = C2_tfrrp killed [[R0]]:intregs

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] [clang-doc] Implement setupTemplateValue for HTMLMustacheGenerator (PR #138064)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138064

>From fa0b1fbf9af85f5c8f55957c46eb42c878f28a2a Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:13:46 -0700
Subject: [PATCH] [clang-doc] Implement setupTemplateValue for
 HTMLMustacheGenerator

This patch implements the business logic for setupTemplateValue, which
was split from #133161. The implementation configures the relative path
relationships between the various HTML components, and prepares them
prior to their use in the generator.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   |  27 +-
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 416 +-
 2 files changed, 434 insertions(+), 9 deletions(-)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 801f54670fb89..46e3e331db03d 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -391,7 +391,7 @@ static json::Value extractValue(const RecordInfo &I,
 
   maybeInsertLocation(I.DefLoc, CDCtx, RecordValue);
 
-  StringRef BasePath = I.getRelativeFilePath("");
+  SmallString<64> BasePath = I.getRelativeFilePath("");
   extractScopeChildren(I.Children, RecordValue, BasePath, CDCtx);
   json::Value PublicMembers = Array();
   json::Array &PubMemberRef = *PublicMembers.getAsArray();
@@ -425,8 +425,28 @@ static json::Value extractValue(const RecordInfo &I,
 
 static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V,
 Info *I) {
-  return createStringError(inconvertibleErrorCode(),
-   "setupTemplateValue is unimplemented");
+  V.getAsObject()->insert({"ProjectName", CDCtx.ProjectName});
+  json::Value StylesheetArr = Array();
+  auto InfoPath = I->getRelativeFilePath("");
+  SmallString<128> RelativePath = computeRelativePath("", InfoPath);
+  sys::path::native(RelativePath, sys::path::Style::posix);
+  for (const auto &FilePath : CDCtx.UserStylesheets) {
+SmallString<128> StylesheetPath = RelativePath;
+sys::path::append(StylesheetPath, sys::path::Style::posix,
+  sys::path::filename(FilePath));
+StylesheetArr.getAsArray()->emplace_back(StylesheetPath);
+  }
+  V.getAsObject()->insert({"Stylesheets", StylesheetArr});
+
+  json::Value ScriptArr = Array();
+  for (auto Script : CDCtx.JsScripts) {
+SmallString<128> JsPath = RelativePath;
+sys::path::append(JsPath, sys::path::Style::posix,
+  sys::path::filename(Script));
+ScriptArr.getAsArray()->emplace_back(JsPath);
+  }
+  V.getAsObject()->insert({"Scripts", ScriptArr});
+  return Error::success();
 }
 
 Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
@@ -437,6 +457,7 @@ Error MustacheHTMLGenerator::generateDocForInfo(Info *I, 
raw_ostream &OS,
 extractValue(*static_cast(I), CDCtx);
 if (auto Err = setupTemplateValue(CDCtx, V, I))
   return Err;
+assert(NamespaceTemplate && "NamespaceTemplate is nullptr.");
 NamespaceTemplate->render(V, OS);
 break;
   }
diff --git 
a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
index 4d1af9d387092..681964969ec01 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
@@ -20,10 +20,10 @@
 
 using namespace llvm;
 using namespace testing;
+using namespace clang;
 using namespace clang::doc;
 
-static const std::string ClangDocVersion =
-clang::getClangToolFullVersion("clang-doc");
+static const std::string ClangDocVersion = 
getClangToolFullVersion("clang-doc");
 
 static std::unique_ptr getHTMLMustacheGenerator() {
   auto G = findGeneratorByName("mustache");
@@ -114,12 +114,416 @@ TEST(HTMLMustacheGeneratorTest, generateDocsForInfo) {
   I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
   "Namespace::ChildStruct", "Namespace");
   I.Children.Functions.emplace_back();
-  I.Children.Functions.back().Access = clang::AccessSpecifier::AS_none;
+  I.Children.Functions.back().Access = AccessSpecifier::AS_none;
   I.Children.Functions.back().Name = "OneFunction";
   I.Children.Enums.emplace_back();
 
-  EXPECT_THAT_ERROR(G->generateDocForInfo(&I, Actual, CDCtx), Failed());
+  unittest::TempDir RootTestDirectory("generateDocForInfoTest",
+  /*Unique=*/true);
+  CDCtx.OutDirectory = RootTestDirectory.path();
+
+  getMustacheHtmlFiles(CLANG_DOC_TEST_ASSET_DIR, CDCtx);
+
+  // FIXME: This is a terrible hack, since we can't initialize the templates
+  // directly. We'll need to update the interfaces so that we can call
+  // SetupTemplateFiles() from outsize of HTMLMustacheGenerator.cpp
+  EXPECT_THAT_ERROR(

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Track if a type is a template or builtin (PR #138067)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138067

>From c3bb0ce348a640bf2d3dfc8f47ae9eb68780959f Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 14:20:40 -0700
Subject: [PATCH] [clang-doc] Track if a type is a template or builtin

Originally part of #133161. This patch adds preliminary tracking
for of TypeInfo, by tracking if the type is a builtin or template.

The new functionality is not yet exercised.

Co-authored-by: Peter Chou 
---
 clang-tools-extra/clang-doc/Representation.h |  3 +++
 clang-tools-extra/clang-doc/Serialize.cpp| 17 -
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index 1673be496b7b2..a3a6217f76bbd 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -164,6 +164,9 @@ struct TypeInfo {
   bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
 
   Reference Type; // Referenced type in this info.
+
+  bool IsTemplate = false;
+  bool IsBuiltIn = false;
 };
 
 // Represents one template parameter.
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index b7c0d95c3be39..241a3de081d9a 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -416,9 +416,12 @@ static RecordDecl *getRecordDeclForType(const QualType &T) 
{
 static TypeInfo getTypeInfoForType(const QualType &T,
const PrintingPolicy &Policy) {
   const TagDecl *TD = getTagDeclForType(T);
-  if (!TD)
-return TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
-
+  if (!TD) {
+TypeInfo TI = TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
+TI.IsBuiltIn = T->isBuiltinType();
+TI.IsTemplate = T->isTemplateTypeParmType();
+return TI;
+  }
   InfoType IT;
   if (isa(TD)) {
 IT = InfoType::IT_enum;
@@ -427,8 +430,12 @@ static TypeInfo getTypeInfoForType(const QualType &T,
   } else {
 IT = InfoType::IT_default;
   }
-  return TypeInfo(Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
-T.getAsString(Policy), getInfoRelativePath(TD)));
+  Reference R = Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
+  T.getAsString(Policy), getInfoRelativePath(TD));
+  TypeInfo TI = TypeInfo(R);
+  TI.IsBuiltIn = T->isBuiltinType();
+  TI.IsTemplate = T->isTemplateTypeParmType();
+  return TI;
 }
 
 static bool isPublic(const clang::AccessSpecifier AS,

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update clang-doc tool to enable mustache templates (PR #138066)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138066

>From 5ab40f8e1c32da2597385c905b8f852fce5fc878 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Tue, 29 Apr 2025 18:08:03 -0700
Subject: [PATCH] [clang-doc] Update clang-doc tool to enable mustache
 templates

This patch adds a command line option and enables the Mustache template
HTML backend. This allows users to use the new, more flexible templates
over the old and cumbersome HTML output. Split from #133161.

Co-authored-by: Peter Chou 
---
 .../clang-doc/tool/ClangDocMain.cpp   |  80 +--
 .../clang-doc/basic-project.mustache.test | 481 ++
 2 files changed, 531 insertions(+), 30 deletions(-)
 create mode 100644 clang-tools-extra/test/clang-doc/basic-project.mustache.test

diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp 
b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 8e8f7053a8f87..41fbe87a713d9 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -18,20 +18,14 @@
 
//===--===//
 
 #include "BitcodeReader.h"
-#include "BitcodeWriter.h"
 #include "ClangDoc.h"
 #include "Generators.h"
 #include "Representation.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/Decl.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "support/Utils.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
-#include "clang/Driver/Options.h"
-#include "clang/Frontend/FrontendActions.h"
 #include "clang/Tooling/AllTUsExecution.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Execution.h"
-#include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
@@ -110,22 +104,19 @@ static llvm::cl::opt 
RepositoryCodeLinePrefix(
 llvm::cl::desc("Prefix of line code for repository."),
 llvm::cl::cat(ClangDocCategory));
 
-enum OutputFormatTy {
-  md,
-  yaml,
-  html,
-};
-
-static llvm::cl::opt
-FormatEnum("format", llvm::cl::desc("Format for outputted docs."),
-   llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
-   "Documentation in YAML format."),
-clEnumValN(OutputFormatTy::md, "md",
-   "Documentation in MD format."),
-clEnumValN(OutputFormatTy::html, "html",
-   "Documentation in HTML format.")),
-   llvm::cl::init(OutputFormatTy::yaml),
-   llvm::cl::cat(ClangDocCategory));
+enum OutputFormatTy { md, yaml, html, mustache };
+
+static llvm::cl::opt FormatEnum(
+"format", llvm::cl::desc("Format for outputted docs."),
+llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
+"Documentation in YAML format."),
+ clEnumValN(OutputFormatTy::md, "md",
+"Documentation in MD format."),
+ clEnumValN(OutputFormatTy::html, "html",
+"Documentation in HTML format."),
+ clEnumValN(OutputFormatTy::mustache, "mustache",
+"Documentation in mustache HTML format")),
+llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory));
 
 static std::string getFormatString() {
   switch (FormatEnum) {
@@ -135,6 +126,8 @@ static std::string getFormatString() {
 return "md";
   case OutputFormatTy::html:
 return "html";
+  case OutputFormatTy::mustache:
+return "mustache";
   }
   llvm_unreachable("Unknown OutputFormatTy");
 }
@@ -178,13 +171,9 @@ static 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::SmallString<128> DefaultStylesheet;
-  llvm::sys::path::native(AssetsPath, DefaultStylesheet);
-  llvm::sys::path::append(DefaultStylesheet,
-  "clang-doc-default-stylesheet.css");
-  llvm::SmallString<128> IndexJS;
-  llvm::sys::path::native(AssetsPath, IndexJS);
-  llvm::sys::path::append(IndexJS, "index.js");
+  llvm::SmallString<128> DefaultStylesheet =
+  appendPathNative(AssetsPath, "clang-doc-default-stylesheet.css");
+  llvm::SmallString<128> IndexJS = appendPathNative(AssetsPath, "index.js");
 
   if (!llvm::sys::fs::is_regular_file(IndexJS))
 return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -215,6 +204,30 @@ static llvm::Error getHtmlAssetFiles(const char *Argv0,
   return getDefaultAssetFiles(Argv0, CDCtx);
 }
 
+static llvm::Error getMustacheHtmlFiles(const char *Argv0,
+clang::doc::ClangDocContext &CDCtx) {
+  bool IsDir = llvm::sys::fs::is_direct

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138062

>From fb0db52bfd5f3e32ddb176b97d984ccb15de7154 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:10:20 -0700
Subject: [PATCH] [clang-doc] Add helpers for Template config

This patch adds or fills in some helper functions related to template
setup when initializing the mustache backend. It was split from #133161.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   | 45 ++
 .../clang-doc/support/CMakeLists.txt  |  4 +-
 clang-tools-extra/clang-doc/support/Utils.cpp | 61 +++
 clang-tools-extra/clang-doc/support/Utils.h   | 26 
 .../unittests/clang-doc/CMakeLists.txt| 12 
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 11 +++-
 .../unittests/clang-doc/config.h.cmake|  6 ++
 7 files changed, 162 insertions(+), 3 deletions(-)
 create mode 100644 clang-tools-extra/clang-doc/support/Utils.cpp
 create mode 100644 clang-tools-extra/clang-doc/support/Utils.h
 create mode 100644 clang-tools-extra/unittests/clang-doc/config.h.cmake

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 366deb55b77b9..4a971f315efc7 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Mustache.h"
+#include "llvm/Support/Path.h"
 
 using namespace llvm;
 using namespace llvm::json;
@@ -74,7 +75,51 @@ static std::unique_ptr 
NamespaceTemplate = nullptr;
 
 static std::unique_ptr RecordTemplate = nullptr;
 
+static Error
+setupTemplate(std::unique_ptr &Template,
+  StringRef TemplatePath,
+  std::vector> Partials) {
+  auto T = MustacheTemplateFile::createMustacheFile(TemplatePath);
+  if (Error Err = T.takeError())
+return Err;
+  Template = std::move(T.get());
+  for (const auto [Name, FileName] : Partials) {
+if (auto Err = Template->registerPartialFile(Name, FileName))
+  return Err;
+  }
+  return Error::success();
+}
+
 static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) {
+  // Template files need to use the native path when they're opened,
+  // but have to be used in Posix style when used in HTML.
+  auto ConvertToNative = [](std::string &&Path) -> std::string {
+SmallString<128> PathBuff(Path);
+llvm::sys::path::native(PathBuff);
+return PathBuff.str().str();
+  };
+
+  std::string NamespaceFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("namespace-template"));
+  std::string ClassFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("class-template"));
+  std::string CommentFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("comments-template"));
+  std::string FunctionFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("function-template"));
+  std::string EnumFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("enum-template"));
+  std::vector> Partials = {
+  {"Comments", CommentFilePath},
+  {"FunctionPartial", FunctionFilePath},
+  {"EnumPartial", EnumFilePath}};
+
+  if (Error Err = setupTemplate(NamespaceTemplate, NamespaceFilePath, 
Partials))
+return Err;
+
+  if (Error Err = setupTemplate(RecordTemplate, ClassFilePath, Partials))
+return Err;
+
   return Error::success();
 }
 
diff --git a/clang-tools-extra/clang-doc/support/CMakeLists.txt 
b/clang-tools-extra/clang-doc/support/CMakeLists.txt
index a4f7993d5c9d8..f470a613b95d9 100644
--- a/clang-tools-extra/clang-doc/support/CMakeLists.txt
+++ b/clang-tools-extra/clang-doc/support/CMakeLists.txt
@@ -6,4 +6,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_clang_library(clangDocSupport STATIC
   File.cpp
-  )
\ No newline at end of file
+  Utils.cpp
+  )
+
diff --git a/clang-tools-extra/clang-doc/support/Utils.cpp 
b/clang-tools-extra/clang-doc/support/Utils.cpp
new file mode 100644
index 0..f1d193379afa6
--- /dev/null
+++ b/clang-tools-extra/clang-doc/support/Utils.cpp
@@ -0,0 +1,61 @@
+//===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "Utils.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+using namespace llvm;
+
+SmallString<128> appendPathNative(StringRef Base, StringRef Path) {
+  SmallString<128> Default;
+  sys::path::native(Base, Default);
+  sys::path::append(Default, Path);
+  return Default;
+}
+
+SmallString<128> appendPathPo

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Implement setupTemplateValue for HTMLMustacheGenerator (PR #138064)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138064

>From fa0b1fbf9af85f5c8f55957c46eb42c878f28a2a Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:13:46 -0700
Subject: [PATCH] [clang-doc] Implement setupTemplateValue for
 HTMLMustacheGenerator

This patch implements the business logic for setupTemplateValue, which
was split from #133161. The implementation configures the relative path
relationships between the various HTML components, and prepares them
prior to their use in the generator.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   |  27 +-
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 416 +-
 2 files changed, 434 insertions(+), 9 deletions(-)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 801f54670fb89..46e3e331db03d 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -391,7 +391,7 @@ static json::Value extractValue(const RecordInfo &I,
 
   maybeInsertLocation(I.DefLoc, CDCtx, RecordValue);
 
-  StringRef BasePath = I.getRelativeFilePath("");
+  SmallString<64> BasePath = I.getRelativeFilePath("");
   extractScopeChildren(I.Children, RecordValue, BasePath, CDCtx);
   json::Value PublicMembers = Array();
   json::Array &PubMemberRef = *PublicMembers.getAsArray();
@@ -425,8 +425,28 @@ static json::Value extractValue(const RecordInfo &I,
 
 static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V,
 Info *I) {
-  return createStringError(inconvertibleErrorCode(),
-   "setupTemplateValue is unimplemented");
+  V.getAsObject()->insert({"ProjectName", CDCtx.ProjectName});
+  json::Value StylesheetArr = Array();
+  auto InfoPath = I->getRelativeFilePath("");
+  SmallString<128> RelativePath = computeRelativePath("", InfoPath);
+  sys::path::native(RelativePath, sys::path::Style::posix);
+  for (const auto &FilePath : CDCtx.UserStylesheets) {
+SmallString<128> StylesheetPath = RelativePath;
+sys::path::append(StylesheetPath, sys::path::Style::posix,
+  sys::path::filename(FilePath));
+StylesheetArr.getAsArray()->emplace_back(StylesheetPath);
+  }
+  V.getAsObject()->insert({"Stylesheets", StylesheetArr});
+
+  json::Value ScriptArr = Array();
+  for (auto Script : CDCtx.JsScripts) {
+SmallString<128> JsPath = RelativePath;
+sys::path::append(JsPath, sys::path::Style::posix,
+  sys::path::filename(Script));
+ScriptArr.getAsArray()->emplace_back(JsPath);
+  }
+  V.getAsObject()->insert({"Scripts", ScriptArr});
+  return Error::success();
 }
 
 Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
@@ -437,6 +457,7 @@ Error MustacheHTMLGenerator::generateDocForInfo(Info *I, 
raw_ostream &OS,
 extractValue(*static_cast(I), CDCtx);
 if (auto Err = setupTemplateValue(CDCtx, V, I))
   return Err;
+assert(NamespaceTemplate && "NamespaceTemplate is nullptr.");
 NamespaceTemplate->render(V, OS);
 break;
   }
diff --git 
a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
index 4d1af9d387092..681964969ec01 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
@@ -20,10 +20,10 @@
 
 using namespace llvm;
 using namespace testing;
+using namespace clang;
 using namespace clang::doc;
 
-static const std::string ClangDocVersion =
-clang::getClangToolFullVersion("clang-doc");
+static const std::string ClangDocVersion = 
getClangToolFullVersion("clang-doc");
 
 static std::unique_ptr getHTMLMustacheGenerator() {
   auto G = findGeneratorByName("mustache");
@@ -114,12 +114,416 @@ TEST(HTMLMustacheGeneratorTest, generateDocsForInfo) {
   I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
   "Namespace::ChildStruct", "Namespace");
   I.Children.Functions.emplace_back();
-  I.Children.Functions.back().Access = clang::AccessSpecifier::AS_none;
+  I.Children.Functions.back().Access = AccessSpecifier::AS_none;
   I.Children.Functions.back().Name = "OneFunction";
   I.Children.Enums.emplace_back();
 
-  EXPECT_THAT_ERROR(G->generateDocForInfo(&I, Actual, CDCtx), Failed());
+  unittest::TempDir RootTestDirectory("generateDocForInfoTest",
+  /*Unique=*/true);
+  CDCtx.OutDirectory = RootTestDirectory.path();
+
+  getMustacheHtmlFiles(CLANG_DOC_TEST_ASSET_DIR, CDCtx);
+
+  // FIXME: This is a terrible hack, since we can't initialize the templates
+  // directly. We'll need to update the interfaces so that we can call
+  // SetupTemplateFiles() from outsize of HTMLMustacheGenerator.cpp
+  EXPECT_THAT_ERROR(

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Track if a type is a template or builtin (PR #138067)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138067

>From c3bb0ce348a640bf2d3dfc8f47ae9eb68780959f Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 14:20:40 -0700
Subject: [PATCH] [clang-doc] Track if a type is a template or builtin

Originally part of #133161. This patch adds preliminary tracking
for of TypeInfo, by tracking if the type is a builtin or template.

The new functionality is not yet exercised.

Co-authored-by: Peter Chou 
---
 clang-tools-extra/clang-doc/Representation.h |  3 +++
 clang-tools-extra/clang-doc/Serialize.cpp| 17 -
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index 1673be496b7b2..a3a6217f76bbd 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -164,6 +164,9 @@ struct TypeInfo {
   bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
 
   Reference Type; // Referenced type in this info.
+
+  bool IsTemplate = false;
+  bool IsBuiltIn = false;
 };
 
 // Represents one template parameter.
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index b7c0d95c3be39..241a3de081d9a 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -416,9 +416,12 @@ static RecordDecl *getRecordDeclForType(const QualType &T) 
{
 static TypeInfo getTypeInfoForType(const QualType &T,
const PrintingPolicy &Policy) {
   const TagDecl *TD = getTagDeclForType(T);
-  if (!TD)
-return TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
-
+  if (!TD) {
+TypeInfo TI = TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
+TI.IsBuiltIn = T->isBuiltinType();
+TI.IsTemplate = T->isTemplateTypeParmType();
+return TI;
+  }
   InfoType IT;
   if (isa(TD)) {
 IT = InfoType::IT_enum;
@@ -427,8 +430,12 @@ static TypeInfo getTypeInfoForType(const QualType &T,
   } else {
 IT = InfoType::IT_default;
   }
-  return TypeInfo(Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
-T.getAsString(Policy), getInfoRelativePath(TD)));
+  Reference R = Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
+  T.getAsString(Policy), getInfoRelativePath(TD));
+  TypeInfo TI = TypeInfo(R);
+  TI.IsBuiltIn = T->isBuiltinType();
+  TI.IsTemplate = T->isTemplateTypeParmType();
+  return TI;
 }
 
 static bool isPublic(const clang::AccessSpecifier AS,

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] [clang-doc] Extract Info into JSON values (PR #138063)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138063

>From c7f6fb81bf5bbf16d76d1ea541fb5719da529220 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:11:39 -0700
Subject: [PATCH] [clang-doc] Extract Info into JSON values

Split from #133161. This patch provides the implementation of a number
of extractValue overloads used with the different types of Info.

The new helper functions extract the relevant information from the
different *Infos and inserts them into the correct fields of the JSON
values that will be used with the specific Mustache templates, which
will land separately.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   | 249 ++
 1 file changed, 249 insertions(+)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 4a971f315efc7..801f54670fb89 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -162,15 +162,264 @@ Error MustacheHTMLGenerator::generateDocs(
   return Error::success();
 }
 
+static json::Value
+extractValue(const Location &L,
+ std::optional RepositoryUrl = std::nullopt) {
+  Object Obj = Object();
+  // Should there be Start/End line numbers?
+  Obj.insert({"LineNumber", L.StartLineNumber});
+  Obj.insert({"Filename", L.Filename});
+
+  if (!L.IsFileInRootDir || !RepositoryUrl)
+return Obj;
+  SmallString<128> FileURL(*RepositoryUrl);
+  sys::path::append(FileURL, sys::path::Style::posix, L.Filename);
+  FileURL += "#" + std::to_string(L.StartLineNumber);
+  Obj.insert({"FileURL", FileURL});
+
+  return Obj;
+}
+
+static json::Value extractValue(const Reference &I,
+StringRef CurrentDirectory) {
+  SmallString<64> Path = I.getRelativeFilePath(CurrentDirectory);
+  sys::path::append(Path, I.getFileBaseName() + ".html");
+  sys::path::native(Path, sys::path::Style::posix);
+  Object Obj = Object();
+  Obj.insert({"Link", Path});
+  Obj.insert({"Name", I.Name});
+  Obj.insert({"QualName", I.QualName});
+  Obj.insert({"ID", toHex(toStringRef(I.USR))});
+  return Obj;
+}
+
+static json::Value extractValue(const TypedefInfo &I) {
+  // Not Supported
+  return nullptr;
+}
+
+static json::Value extractValue(const CommentInfo &I) {
+  assert((I.Kind == "BlockCommandComment" || I.Kind == "FullComment" ||
+  I.Kind == "ParagraphComment" || I.Kind == "TextComment") &&
+ "Unknown Comment type in CommentInfo.");
+
+  Object Obj = Object();
+  json::Value Child = Object();
+
+  // TextComment has no children, so return it.
+  if (I.Kind == "TextComment") {
+Obj.insert({"TextComment", I.Text});
+return Obj;
+  }
+
+  // BlockCommandComment needs to generate a Command key.
+  if (I.Kind == "BlockCommandComment")
+Child.getAsObject()->insert({"Command", I.Name});
+
+  // Use the same handling for everything else.
+  // Only valid for:
+  //  - BlockCommandComment
+  //  - FullComment
+  //  - ParagraphComment
+  json::Value ChildArr = Array();
+  auto &CARef = *ChildArr.getAsArray();
+  CARef.reserve(I.Children.size());
+  for (const auto &C : I.Children)
+CARef.emplace_back(extractValue(*C));
+  Child.getAsObject()->insert({"Children", ChildArr});
+  Obj.insert({I.Kind, Child});
+
+  return Obj;
+}
+
+static void maybeInsertLocation(std::optional Loc,
+const ClangDocContext &CDCtx, Object &Obj) {
+  if (!Loc)
+return;
+  Location L = *Loc;
+  Obj.insert({"Location", extractValue(L, CDCtx.RepositoryUrl)});
+}
+
+static void extractDescriptionFromInfo(ArrayRef Descriptions,
+   json::Object &EnumValObj) {
+  if (Descriptions.empty())
+return;
+  json::Value ArrDesc = Array();
+  json::Array &ADescRef = *ArrDesc.getAsArray();
+  for (const CommentInfo &Child : Descriptions)
+ADescRef.emplace_back(extractValue(Child));
+  EnumValObj.insert({"EnumValueComments", ArrDesc});
+}
+
+static json::Value extractValue(const FunctionInfo &I, StringRef ParentInfoDir,
+const ClangDocContext &CDCtx) {
+  Object Obj = Object();
+  Obj.insert({"Name", I.Name});
+  Obj.insert({"ID", toHex(toStringRef(I.USR))});
+  Obj.insert({"Access", getAccessSpelling(I.Access).str()});
+  Obj.insert({"ReturnType", extractValue(I.ReturnType.Type, ParentInfoDir)});
+
+  json::Value ParamArr = Array();
+  for (const auto Val : enumerate(I.Params)) {
+json::Value V = Object();
+auto &VRef = *V.getAsObject();
+VRef.insert({"Name", Val.value().Name});
+VRef.insert({"Type", Val.value().Type.Name});
+VRef.insert({"End", Val.index() + 1 == I.Params.size()});
+ParamArr.getAsArray()->emplace_back(V);
+  }
+  Obj.insert({"Params", ParamArr});
+
+  maybeInsertLocation(I.DefLoc, CDCtx, Obj);
+  return Obj;
+}
+
+static json::Value extractValue(const EnumInfo &I,
+

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update clang-doc tool to enable mustache templates (PR #138066)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138066

>From 5ab40f8e1c32da2597385c905b8f852fce5fc878 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Tue, 29 Apr 2025 18:08:03 -0700
Subject: [PATCH] [clang-doc] Update clang-doc tool to enable mustache
 templates

This patch adds a command line option and enables the Mustache template
HTML backend. This allows users to use the new, more flexible templates
over the old and cumbersome HTML output. Split from #133161.

Co-authored-by: Peter Chou 
---
 .../clang-doc/tool/ClangDocMain.cpp   |  80 +--
 .../clang-doc/basic-project.mustache.test | 481 ++
 2 files changed, 531 insertions(+), 30 deletions(-)
 create mode 100644 clang-tools-extra/test/clang-doc/basic-project.mustache.test

diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp 
b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 8e8f7053a8f87..41fbe87a713d9 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -18,20 +18,14 @@
 
//===--===//
 
 #include "BitcodeReader.h"
-#include "BitcodeWriter.h"
 #include "ClangDoc.h"
 #include "Generators.h"
 #include "Representation.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/Decl.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "support/Utils.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
-#include "clang/Driver/Options.h"
-#include "clang/Frontend/FrontendActions.h"
 #include "clang/Tooling/AllTUsExecution.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Execution.h"
-#include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
@@ -110,22 +104,19 @@ static llvm::cl::opt 
RepositoryCodeLinePrefix(
 llvm::cl::desc("Prefix of line code for repository."),
 llvm::cl::cat(ClangDocCategory));
 
-enum OutputFormatTy {
-  md,
-  yaml,
-  html,
-};
-
-static llvm::cl::opt
-FormatEnum("format", llvm::cl::desc("Format for outputted docs."),
-   llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
-   "Documentation in YAML format."),
-clEnumValN(OutputFormatTy::md, "md",
-   "Documentation in MD format."),
-clEnumValN(OutputFormatTy::html, "html",
-   "Documentation in HTML format.")),
-   llvm::cl::init(OutputFormatTy::yaml),
-   llvm::cl::cat(ClangDocCategory));
+enum OutputFormatTy { md, yaml, html, mustache };
+
+static llvm::cl::opt FormatEnum(
+"format", llvm::cl::desc("Format for outputted docs."),
+llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
+"Documentation in YAML format."),
+ clEnumValN(OutputFormatTy::md, "md",
+"Documentation in MD format."),
+ clEnumValN(OutputFormatTy::html, "html",
+"Documentation in HTML format."),
+ clEnumValN(OutputFormatTy::mustache, "mustache",
+"Documentation in mustache HTML format")),
+llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory));
 
 static std::string getFormatString() {
   switch (FormatEnum) {
@@ -135,6 +126,8 @@ static std::string getFormatString() {
 return "md";
   case OutputFormatTy::html:
 return "html";
+  case OutputFormatTy::mustache:
+return "mustache";
   }
   llvm_unreachable("Unknown OutputFormatTy");
 }
@@ -178,13 +171,9 @@ static 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::SmallString<128> DefaultStylesheet;
-  llvm::sys::path::native(AssetsPath, DefaultStylesheet);
-  llvm::sys::path::append(DefaultStylesheet,
-  "clang-doc-default-stylesheet.css");
-  llvm::SmallString<128> IndexJS;
-  llvm::sys::path::native(AssetsPath, IndexJS);
-  llvm::sys::path::append(IndexJS, "index.js");
+  llvm::SmallString<128> DefaultStylesheet =
+  appendPathNative(AssetsPath, "clang-doc-default-stylesheet.css");
+  llvm::SmallString<128> IndexJS = appendPathNative(AssetsPath, "index.js");
 
   if (!llvm::sys::fs::is_regular_file(IndexJS))
 return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -215,6 +204,30 @@ static llvm::Error getHtmlAssetFiles(const char *Argv0,
   return getDefaultAssetFiles(Argv0, CDCtx);
 }
 
+static llvm::Error getMustacheHtmlFiles(const char *Argv0,
+clang::doc::ClangDocContext &CDCtx) {
+  bool IsDir = llvm::sys::fs::is_direct

[llvm-branch-commits] [llvm] Fix test pfalse-v4i1.ll added in #138712 to require asserts. (PR #139822)

2025-05-16 Thread Tom Stellard via llvm-branch-commits

https://github.com/tstellar closed 
https://github.com/llvm/llvm-project/pull/139822
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] ff2e8f9 - Fix test pfalse-v4i1.ll added in #138712 to require asserts.

2025-05-16 Thread Tom Stellard via llvm-branch-commits

Author: Douglas Yung
Date: 2025-05-16T16:35:56-07:00
New Revision: ff2e8f93f6090965e82d799af43f6dfef52baa66

URL: 
https://github.com/llvm/llvm-project/commit/ff2e8f93f6090965e82d799af43f6dfef52baa66
DIFF: 
https://github.com/llvm/llvm-project/commit/ff2e8f93f6090965e82d799af43f6dfef52baa66.diff

LOG: Fix test pfalse-v4i1.ll added in #138712 to require asserts.

Should fix build bot failure: 
https://lab.llvm.org/buildbot/#/builders/202/builds/1102

(cherry picked from commit 194a4a333a95f9e001d2c8abe82c3d4cf8894acf)

Added: 


Modified: 
llvm/test/CodeGen/Hexagon/isel/pfalse-v4i1.ll

Removed: 




diff  --git a/llvm/test/CodeGen/Hexagon/isel/pfalse-v4i1.ll 
b/llvm/test/CodeGen/Hexagon/isel/pfalse-v4i1.ll
index c0904b8b4fdd6..2c26bb1e310ea 100644
--- a/llvm/test/CodeGen/Hexagon/isel/pfalse-v4i1.ll
+++ b/llvm/test/CodeGen/Hexagon/isel/pfalse-v4i1.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -march=hexagon -debug-only=isel 2>&1 < %s - | FileCheck %s
+; REQUIRES: asserts
 
 ; CHECK: [[R0:%[0-9]+]]:intregs = A2_tfrsi 0
 ; CHECK-NEXT: predregs = C2_tfrrp killed [[R0]]:intregs



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Fix test pfalse-v4i1.ll added in #138712 to require asserts. (PR #139822)

2025-05-16 Thread via llvm-branch-commits

github-actions[bot] wrote:

@dyung (or anyone else). If you would like to add a note about this fix in the 
release notes (completely optional). Please reply to this comment with a one or 
two sentence description of the fix.  When you are done, please add the 
release:note label to this PR. 

https://github.com/llvm/llvm-project/pull/139822
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [lld] release/20.x: [LLD][COFF] Allow -arm64xsameaddress in ARM64EC directives (#139631) (PR #140051)

2025-05-16 Thread via llvm-branch-commits

https://github.com/llvmbot updated 
https://github.com/llvm/llvm-project/pull/140051

>From e3d2c00ccee45e882233fce230c42b23423a8ef7 Mon Sep 17 00:00:00 2001
From: Jacek Caban 
Date: Thu, 15 May 2025 03:28:18 -0700
Subject: [PATCH] [LLD][COFF] Allow -arm64xsameaddress in ARM64EC directives
 (#139631)

Make it a no-op for now, which is sufficient for non-hybrid images.

Fixes #131712.

(cherry picked from commit d5da557782dd47395fb41e03d7663df6319d7ea6)
---
 lld/COFF/Driver.cpp   |  6 +++
 lld/COFF/Options.td   |  1 +
 lld/test/COFF/arm64x-sameaddress.test | 56 +++
 3 files changed, 63 insertions(+)
 create mode 100644 lld/test/COFF/arm64x-sameaddress.test

diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index f50ca529df4d7..a669b7e9296f6 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -492,6 +492,12 @@ void LinkerDriver::parseDirectives(InputFile *file) {
 case OPT_alternatename:
   parseAlternateName(arg->getValue());
   break;
+case OPT_arm64xsameaddress:
+  if (!file->symtab.isEC())
+Warn(ctx) << arg->getSpelling()
+  << " is not allowed in non-ARM64EC files (" << toString(file)
+  << ")";
+  break;
 case OPT_defaultlib:
   if (std::optional path = findLibIfNew(arg->getValue()))
 enqueuePath(*path, false, false);
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index b6fd3d0daaef9..ea2e7ded38043 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -355,3 +355,4 @@ def tlbid : P_priv<"tlbid">;
 def tlbout : P_priv<"tlbout">;
 def verbose_all : P_priv<"verbose">;
 def guardsym : P_priv<"guardsym">;
+def arm64xsameaddress : P_priv<"arm64xsameaddress">;
diff --git a/lld/test/COFF/arm64x-sameaddress.test 
b/lld/test/COFF/arm64x-sameaddress.test
new file mode 100644
index 0..c69be9d268c3b
--- /dev/null
+++ b/lld/test/COFF/arm64x-sameaddress.test
@@ -0,0 +1,56 @@
+REQUIRES: aarch64
+RUN: split-file %s %t.dir && cd %t.dir
+
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows func-arm64ec.s -o 
func-arm64ec.obj
+RUN: llvm-mc -filetype=obj -triple=aarch64-windows func-arm64.s -o 
func-arm64.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows drectve.s -o drectve.obj
+RUN: llvm-mc -filetype=obj -triple=aarch64-windows drectve.s -o 
drectve-arm64.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows 
%S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
+RUN: llvm-mc -filetype=obj -triple=aarch64-windows 
%S/Inputs/loadconfig-arm64.s -o loadconfig-arm64.obj
+
+RUN: lld-link -machine:arm64x -dll -noentry -out:out.dll loadconfig-arm64.obj 
loadconfig-arm64ec.obj \
+RUN:  func-arm64.obj func-arm64ec.obj drectve.obj
+
+RUN: lld-link -machine:arm64x -dll -noentry -out:out-cmd.dll 
loadconfig-arm64.obj loadconfig-arm64ec.obj \
+RUN:  func-arm64.obj func-arm64ec.obj -arm64xsameaddress:func
+
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out-ec.dll 
loadconfig-arm64ec.obj func-arm64ec.obj drectve.obj
+
+RUN: lld-link -machine:arm64x -dll -noentry -out:out-warn.dll 
loadconfig-arm64.obj loadconfig-arm64ec.obj \
+RUN:  func-arm64.obj func-arm64ec.obj drectve-arm64.obj 2>&1 | 
FileCheck --check-prefix=WARN %s
+WARN: lld-link: warning: -arm64xsameaddress: is not allowed in non-ARM64EC 
files (drectve-arm64.obj)
+
+#--- func-arm64.s
+.section .text,"xr",discard,func
+.globl func
+func:
+mov x0, #1
+ret
+
+#--- func-arm64ec.s
+.section .text,"xr",discard,"#func"
+.globl "#func"
+"#func":
+mov x0, #2
+ret
+
+.weak_anti_dep func
+.set func,"#func"
+
+.section .wowthk,"xr",discard,entry_thunk
+.globl entry_thunk
+entry_thunk:
+mov x0, #3
+ret
+
+.section .test,"dr"
+.rva func
+
+   .section .hybmp$x,"yi"
+   .symidx "#func"
+   .symidx entry_thunk
+   .word 1
+
+#--- drectve.s
+.section .drectve, "yn"
+.ascii " -arm64xsameaddress:func"

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] [clang-doc] Implement setupTemplateValue for HTMLMustacheGenerator (PR #138064)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138064

>From ef64af73fabaacd884c66c47b6791063e41a430b Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:13:46 -0700
Subject: [PATCH] [clang-doc] Implement setupTemplateValue for
 HTMLMustacheGenerator

This patch implements the business logic for setupTemplateValue, which
was split from #133161. The implementation configures the relative path
relationships between the various HTML components, and prepares them
prior to their use in the generator.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   |  27 +-
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 416 +-
 2 files changed, 434 insertions(+), 9 deletions(-)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 682c4b59fc741..aa5b40e3efc61 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -391,7 +391,7 @@ static json::Value extractValue(const RecordInfo &I,
 
   maybeInsertLocation(I.DefLoc, CDCtx, RecordValue);
 
-  StringRef BasePath = I.getRelativeFilePath("");
+  SmallString<64> BasePath = I.getRelativeFilePath("");
   extractScopeChildren(I.Children, RecordValue, BasePath, CDCtx);
   json::Value PublicMembers = Array();
   json::Array &PubMemberRef = *PublicMembers.getAsArray();
@@ -425,8 +425,28 @@ static json::Value extractValue(const RecordInfo &I,
 
 static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V,
 Info *I) {
-  return createStringError(inconvertibleErrorCode(),
-   "setupTemplateValue is unimplemented");
+  V.getAsObject()->insert({"ProjectName", CDCtx.ProjectName});
+  json::Value StylesheetArr = Array();
+  auto InfoPath = I->getRelativeFilePath("");
+  SmallString<128> RelativePath = computeRelativePath("", InfoPath);
+  sys::path::native(RelativePath, sys::path::Style::posix);
+  for (const auto &FilePath : CDCtx.UserStylesheets) {
+SmallString<128> StylesheetPath = RelativePath;
+sys::path::append(StylesheetPath, sys::path::Style::posix,
+  sys::path::filename(FilePath));
+StylesheetArr.getAsArray()->emplace_back(StylesheetPath);
+  }
+  V.getAsObject()->insert({"Stylesheets", StylesheetArr});
+
+  json::Value ScriptArr = Array();
+  for (auto Script : CDCtx.JsScripts) {
+SmallString<128> JsPath = RelativePath;
+sys::path::append(JsPath, sys::path::Style::posix,
+  sys::path::filename(Script));
+ScriptArr.getAsArray()->emplace_back(JsPath);
+  }
+  V.getAsObject()->insert({"Scripts", ScriptArr});
+  return Error::success();
 }
 
 Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
@@ -437,6 +457,7 @@ Error MustacheHTMLGenerator::generateDocForInfo(Info *I, 
raw_ostream &OS,
 extractValue(*static_cast(I), CDCtx);
 if (auto Err = setupTemplateValue(CDCtx, V, I))
   return Err;
+assert(NamespaceTemplate && "NamespaceTemplate is nullptr.");
 NamespaceTemplate->render(V, OS);
 break;
   }
diff --git 
a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
index 70491f0754b3d..9a6969f789a65 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
@@ -20,10 +20,10 @@
 
 using namespace llvm;
 using namespace testing;
+using namespace clang;
 using namespace clang::doc;
 
-static const std::string ClangDocVersion =
-clang::getClangToolFullVersion("clang-doc");
+static const std::string ClangDocVersion = 
getClangToolFullVersion("clang-doc");
 
 static std::unique_ptr getHTMLMustacheGenerator() {
   auto G = findGeneratorByName("mustache");
@@ -114,12 +114,416 @@ TEST(HTMLMustacheGeneratorTest, generateDocsForInfo) {
   I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
   "Namespace::ChildStruct", "Namespace");
   I.Children.Functions.emplace_back();
-  I.Children.Functions.back().Access = clang::AccessSpecifier::AS_none;
+  I.Children.Functions.back().Access = AccessSpecifier::AS_none;
   I.Children.Functions.back().Name = "OneFunction";
   I.Children.Enums.emplace_back();
 
-  EXPECT_THAT_ERROR(G->generateDocForInfo(&I, Actual, CDCtx), Failed());
+  unittest::TempDir RootTestDirectory("generateDocForInfoTest",
+  /*Unique=*/true);
+  CDCtx.OutDirectory = RootTestDirectory.path();
+
+  getMustacheHtmlFiles(CLANG_DOC_TEST_ASSET_DIR, CDCtx);
+
+  // FIXME: This is a terrible hack, since we can't initialize the templates
+  // directly. We'll need to update the interfaces so that we can call
+  // SetupTemplateFiles() from outsize of HTMLMustacheGenerator.cpp
+  EXPECT_THAT_ERROR(

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Extract Info into JSON values (PR #138063)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138063

>From fa76fb7a912325452126192240f6fc728b21db40 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:11:39 -0700
Subject: [PATCH] [clang-doc] Extract Info into JSON values

Split from #133161. This patch provides the implementation of a number
of extractValue overloads used with the different types of Info.

The new helper functions extract the relevant information from the
different *Infos and inserts them into the correct fields of the JSON
values that will be used with the specific Mustache templates, which
will land separately.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   | 249 ++
 1 file changed, 249 insertions(+)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index f7e53fc64196a..682c4b59fc741 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -162,15 +162,264 @@ Error MustacheHTMLGenerator::generateDocs(
   return Error::success();
 }
 
+static json::Value
+extractValue(const Location &L,
+ std::optional RepositoryUrl = std::nullopt) {
+  Object Obj = Object();
+  // Should there be Start/End line numbers?
+  Obj.insert({"LineNumber", L.StartLineNumber});
+  Obj.insert({"Filename", L.Filename});
+
+  if (!L.IsFileInRootDir || !RepositoryUrl)
+return Obj;
+  SmallString<128> FileURL(*RepositoryUrl);
+  sys::path::append(FileURL, sys::path::Style::posix, L.Filename);
+  FileURL += "#" + std::to_string(L.StartLineNumber);
+  Obj.insert({"FileURL", FileURL});
+
+  return Obj;
+}
+
+static json::Value extractValue(const Reference &I,
+StringRef CurrentDirectory) {
+  SmallString<64> Path = I.getRelativeFilePath(CurrentDirectory);
+  sys::path::append(Path, I.getFileBaseName() + ".html");
+  sys::path::native(Path, sys::path::Style::posix);
+  Object Obj = Object();
+  Obj.insert({"Link", Path});
+  Obj.insert({"Name", I.Name});
+  Obj.insert({"QualName", I.QualName});
+  Obj.insert({"ID", toHex(toStringRef(I.USR))});
+  return Obj;
+}
+
+static json::Value extractValue(const TypedefInfo &I) {
+  // Not Supported
+  return nullptr;
+}
+
+static json::Value extractValue(const CommentInfo &I) {
+  assert((I.Kind == "BlockCommandComment" || I.Kind == "FullComment" ||
+  I.Kind == "ParagraphComment" || I.Kind == "TextComment") &&
+ "Unknown Comment type in CommentInfo.");
+
+  Object Obj = Object();
+  json::Value Child = Object();
+
+  // TextComment has no children, so return it.
+  if (I.Kind == "TextComment") {
+Obj.insert({"TextComment", I.Text});
+return Obj;
+  }
+
+  // BlockCommandComment needs to generate a Command key.
+  if (I.Kind == "BlockCommandComment")
+Child.getAsObject()->insert({"Command", I.Name});
+
+  // Use the same handling for everything else.
+  // Only valid for:
+  //  - BlockCommandComment
+  //  - FullComment
+  //  - ParagraphComment
+  json::Value ChildArr = Array();
+  auto &CARef = *ChildArr.getAsArray();
+  CARef.reserve(I.Children.size());
+  for (const auto &C : I.Children)
+CARef.emplace_back(extractValue(*C));
+  Child.getAsObject()->insert({"Children", ChildArr});
+  Obj.insert({I.Kind, Child});
+
+  return Obj;
+}
+
+static void maybeInsertLocation(std::optional Loc,
+const ClangDocContext &CDCtx, Object &Obj) {
+  if (!Loc)
+return;
+  Location L = *Loc;
+  Obj.insert({"Location", extractValue(L, CDCtx.RepositoryUrl)});
+}
+
+static void extractDescriptionFromInfo(ArrayRef Descriptions,
+   json::Object &EnumValObj) {
+  if (Descriptions.empty())
+return;
+  json::Value ArrDesc = Array();
+  json::Array &ADescRef = *ArrDesc.getAsArray();
+  for (const CommentInfo &Child : Descriptions)
+ADescRef.emplace_back(extractValue(Child));
+  EnumValObj.insert({"EnumValueComments", ArrDesc});
+}
+
+static json::Value extractValue(const FunctionInfo &I, StringRef ParentInfoDir,
+const ClangDocContext &CDCtx) {
+  Object Obj = Object();
+  Obj.insert({"Name", I.Name});
+  Obj.insert({"ID", toHex(toStringRef(I.USR))});
+  Obj.insert({"Access", getAccessSpelling(I.Access).str()});
+  Obj.insert({"ReturnType", extractValue(I.ReturnType.Type, ParentInfoDir)});
+
+  json::Value ParamArr = Array();
+  for (const auto Val : enumerate(I.Params)) {
+json::Value V = Object();
+auto &VRef = *V.getAsObject();
+VRef.insert({"Name", Val.value().Name});
+VRef.insert({"Type", Val.value().Type.Name});
+VRef.insert({"End", Val.index() + 1 == I.Params.size()});
+ParamArr.getAsArray()->emplace_back(V);
+  }
+  Obj.insert({"Params", ParamArr});
+
+  maybeInsertLocation(I.DefLoc, CDCtx, Obj);
+  return Obj;
+}
+
+static json::Value extractValue(const EnumInfo &I,
+

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update serializer for improved template handling (PR #138065)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138065

>From 3e47a53b5bdf484069427e574e84d3a2d0459092 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Tue, 29 Apr 2025 18:31:54 -0700
Subject: [PATCH] [clang-doc] Update serializer for improved template handling

This patch updates Serialize.cpp to serialize more data about C++
templates, which are supported by the new mustache HTML template.
Split from #133161.

Co-authored-by: Peter Chou 
---
 clang-tools-extra/clang-doc/Representation.h |   3 +
 clang-tools-extra/clang-doc/Serialize.cpp| 203 ++-
 2 files changed, 198 insertions(+), 8 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index a2e01719eb59e..1673be496b7b2 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -363,6 +363,9 @@ struct FunctionInfo : public SymbolInfo {
   // specializations.
   SmallString<16> FullName;
 
+  // Function Prototype
+  SmallString<256> Prototype;
+
   // When present, this function is a template or specialization.
   std::optional Template;
 };
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 18db427b5239e..0a59724a0d75a 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -8,10 +8,10 @@
 
 #include "Serialize.h"
 #include "BitcodeWriter.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Comment.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/Lexer.h"
-#include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/SHA1.h"
 
@@ -35,6 +35,169 @@ static void populateMemberTypeInfo(RecordInfo &I, 
AccessSpecifier &Access,
const DeclaratorDecl *D,
bool IsStatic = false);
 
+static void getTemplateParameters(const TemplateParameterList *TemplateParams,
+  llvm::raw_ostream &Stream) {
+  Stream << "template <";
+
+  for (unsigned i = 0; i < TemplateParams->size(); ++i) {
+if (i > 0)
+  Stream << ", ";
+
+const NamedDecl *Param = TemplateParams->getParam(i);
+if (const auto *TTP = llvm::dyn_cast(Param)) {
+  if (TTP->wasDeclaredWithTypename())
+Stream << "typename";
+  else
+Stream << "class";
+  if (TTP->isParameterPack())
+Stream << "...";
+  Stream << " " << TTP->getNameAsString();
+} else if (const auto *NTTP =
+   llvm::dyn_cast(Param)) {
+  NTTP->getType().print(Stream, NTTP->getASTContext().getPrintingPolicy());
+  if (NTTP->isParameterPack())
+Stream << "...";
+  Stream << " " << NTTP->getNameAsString();
+} else if (const auto *TTPD =
+   llvm::dyn_cast(Param)) {
+  Stream << "template <";
+  getTemplateParameters(TTPD->getTemplateParameters(), Stream);
+  Stream << "> class " << TTPD->getNameAsString();
+}
+  }
+
+  Stream << "> ";
+}
+
+// Extract the full function prototype from a FunctionDecl including
+// Full Decl
+static llvm::SmallString<256>
+getFunctionPrototype(const FunctionDecl *FuncDecl) {
+  llvm::SmallString<256> Result;
+  llvm::raw_svector_ostream Stream(Result);
+  const ASTContext &Ctx = FuncDecl->getASTContext();
+  const auto *Method = llvm::dyn_cast(FuncDecl);
+  // If it's a templated function, handle the template parameters
+  if (const auto *TmplDecl = FuncDecl->getDescribedTemplate())
+getTemplateParameters(TmplDecl->getTemplateParameters(), Stream);
+
+  // If it's a virtual method
+  if (Method && Method->isVirtual())
+Stream << "virtual ";
+
+  // Print return type
+  FuncDecl->getReturnType().print(Stream, Ctx.getPrintingPolicy());
+
+  // Print function name
+  Stream << " " << FuncDecl->getNameAsString() << "(";
+
+  // Print parameter list with types, names, and default values
+  for (unsigned I = 0; I < FuncDecl->getNumParams(); ++I) {
+if (I > 0)
+  Stream << ", ";
+const ParmVarDecl *ParamDecl = FuncDecl->getParamDecl(I);
+QualType ParamType = ParamDecl->getType();
+ParamType.print(Stream, Ctx.getPrintingPolicy());
+
+// Print parameter name if it has one
+if (!ParamDecl->getName().empty())
+  Stream << " " << ParamDecl->getNameAsString();
+
+// Print default argument if it exists
+if (ParamDecl->hasDefaultArg()) {
+  const Expr *DefaultArg = ParamDecl->getDefaultArg();
+  if (DefaultArg) {
+Stream << " = ";
+DefaultArg->printPretty(Stream, nullptr, Ctx.getPrintingPolicy());
+  }
+}
+  }
+
+  // If it is a variadic function, add '...'
+  if (FuncDecl->isVariadic()) {
+if (FuncDecl->getNumParams() > 0)
+  Stream << ", ";
+Stream << "...";
+  }
+
+  Stream << ")";
+
+  // If it's a const method, add 'const' qualifier
+  if (Method) {
+if (Method->size_overridden_methods())
+   

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138062

>From e918ff19e30f0584aeac3281b41bd70710f8f2ef Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:10:20 -0700
Subject: [PATCH] [clang-doc] Add helpers for Template config

This patch adds or fills in some helper functions related to template
setup when initializing the mustache backend. It was split from #133161.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   | 45 ++
 .../clang-doc/support/CMakeLists.txt  |  4 +-
 clang-tools-extra/clang-doc/support/Utils.cpp | 61 +++
 clang-tools-extra/clang-doc/support/Utils.h   | 26 
 .../unittests/clang-doc/CMakeLists.txt| 12 
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 11 +++-
 .../unittests/clang-doc/config.h.cmake|  6 ++
 7 files changed, 162 insertions(+), 3 deletions(-)
 create mode 100644 clang-tools-extra/clang-doc/support/Utils.cpp
 create mode 100644 clang-tools-extra/clang-doc/support/Utils.h
 create mode 100644 clang-tools-extra/unittests/clang-doc/config.h.cmake

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 366deb55b77b9..f7e53fc64196a 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Mustache.h"
+#include "llvm/Support/Path.h"
 
 using namespace llvm;
 using namespace llvm::json;
@@ -74,7 +75,51 @@ static std::unique_ptr 
NamespaceTemplate = nullptr;
 
 static std::unique_ptr RecordTemplate = nullptr;
 
+static Error
+setupTemplate(std::unique_ptr &Template,
+  StringRef TemplatePath,
+  std::vector> Partials) {
+  auto T = MustacheTemplateFile::createMustacheFile(TemplatePath);
+  if (Error Err = T.takeError())
+return Err;
+  Template = std::move(T.get());
+  for (const auto [Name, FileName] : Partials) {
+if (auto Err = Template->registerPartialFile(Name, FileName))
+  return Err;
+  }
+  return Error::success();
+}
+
 static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) {
+  // Template files need to use the native path when they're opened,
+  // but have to be used in Posix style when used in HTML.
+  auto ConvertToNative = [](std::string &&Path) -> std::string {
+SmallString<128> PathBuf(Path);
+llvm::sys::path::native(PathBuf);
+return PathBuf.str().str();
+  };
+
+  std::string NamespaceFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("namespace-template"));
+  std::string ClassFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("class-template"));
+  std::string CommentFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("comments-template"));
+  std::string FunctionFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("function-template"));
+  std::string EnumFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("enum-template"));
+  std::vector> Partials = {
+  {"Comments", CommentFilePath},
+  {"FunctionPartial", FunctionFilePath},
+  {"EnumPartial", EnumFilePath}};
+
+  if (Error Err = setupTemplate(NamespaceTemplate, NamespaceFilePath, 
Partials))
+return Err;
+
+  if (Error Err = setupTemplate(RecordTemplate, ClassFilePath, Partials))
+return Err;
+
   return Error::success();
 }
 
diff --git a/clang-tools-extra/clang-doc/support/CMakeLists.txt 
b/clang-tools-extra/clang-doc/support/CMakeLists.txt
index a4f7993d5c9d8..f470a613b95d9 100644
--- a/clang-tools-extra/clang-doc/support/CMakeLists.txt
+++ b/clang-tools-extra/clang-doc/support/CMakeLists.txt
@@ -6,4 +6,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_clang_library(clangDocSupport STATIC
   File.cpp
-  )
\ No newline at end of file
+  Utils.cpp
+  )
+
diff --git a/clang-tools-extra/clang-doc/support/Utils.cpp 
b/clang-tools-extra/clang-doc/support/Utils.cpp
new file mode 100644
index 0..f1d193379afa6
--- /dev/null
+++ b/clang-tools-extra/clang-doc/support/Utils.cpp
@@ -0,0 +1,61 @@
+//===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "Utils.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+using namespace llvm;
+
+SmallString<128> appendPathNative(StringRef Base, StringRef Path) {
+  SmallString<128> Default;
+  sys::path::native(Base, Default);
+  sys::path::append(Default, Path);
+  return Default;
+}
+
+SmallString<128> appendPathPosix

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Extract Info into JSON values (PR #138063)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138063

>From fa76fb7a912325452126192240f6fc728b21db40 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:11:39 -0700
Subject: [PATCH] [clang-doc] Extract Info into JSON values

Split from #133161. This patch provides the implementation of a number
of extractValue overloads used with the different types of Info.

The new helper functions extract the relevant information from the
different *Infos and inserts them into the correct fields of the JSON
values that will be used with the specific Mustache templates, which
will land separately.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   | 249 ++
 1 file changed, 249 insertions(+)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index f7e53fc64196a..682c4b59fc741 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -162,15 +162,264 @@ Error MustacheHTMLGenerator::generateDocs(
   return Error::success();
 }
 
+static json::Value
+extractValue(const Location &L,
+ std::optional RepositoryUrl = std::nullopt) {
+  Object Obj = Object();
+  // Should there be Start/End line numbers?
+  Obj.insert({"LineNumber", L.StartLineNumber});
+  Obj.insert({"Filename", L.Filename});
+
+  if (!L.IsFileInRootDir || !RepositoryUrl)
+return Obj;
+  SmallString<128> FileURL(*RepositoryUrl);
+  sys::path::append(FileURL, sys::path::Style::posix, L.Filename);
+  FileURL += "#" + std::to_string(L.StartLineNumber);
+  Obj.insert({"FileURL", FileURL});
+
+  return Obj;
+}
+
+static json::Value extractValue(const Reference &I,
+StringRef CurrentDirectory) {
+  SmallString<64> Path = I.getRelativeFilePath(CurrentDirectory);
+  sys::path::append(Path, I.getFileBaseName() + ".html");
+  sys::path::native(Path, sys::path::Style::posix);
+  Object Obj = Object();
+  Obj.insert({"Link", Path});
+  Obj.insert({"Name", I.Name});
+  Obj.insert({"QualName", I.QualName});
+  Obj.insert({"ID", toHex(toStringRef(I.USR))});
+  return Obj;
+}
+
+static json::Value extractValue(const TypedefInfo &I) {
+  // Not Supported
+  return nullptr;
+}
+
+static json::Value extractValue(const CommentInfo &I) {
+  assert((I.Kind == "BlockCommandComment" || I.Kind == "FullComment" ||
+  I.Kind == "ParagraphComment" || I.Kind == "TextComment") &&
+ "Unknown Comment type in CommentInfo.");
+
+  Object Obj = Object();
+  json::Value Child = Object();
+
+  // TextComment has no children, so return it.
+  if (I.Kind == "TextComment") {
+Obj.insert({"TextComment", I.Text});
+return Obj;
+  }
+
+  // BlockCommandComment needs to generate a Command key.
+  if (I.Kind == "BlockCommandComment")
+Child.getAsObject()->insert({"Command", I.Name});
+
+  // Use the same handling for everything else.
+  // Only valid for:
+  //  - BlockCommandComment
+  //  - FullComment
+  //  - ParagraphComment
+  json::Value ChildArr = Array();
+  auto &CARef = *ChildArr.getAsArray();
+  CARef.reserve(I.Children.size());
+  for (const auto &C : I.Children)
+CARef.emplace_back(extractValue(*C));
+  Child.getAsObject()->insert({"Children", ChildArr});
+  Obj.insert({I.Kind, Child});
+
+  return Obj;
+}
+
+static void maybeInsertLocation(std::optional Loc,
+const ClangDocContext &CDCtx, Object &Obj) {
+  if (!Loc)
+return;
+  Location L = *Loc;
+  Obj.insert({"Location", extractValue(L, CDCtx.RepositoryUrl)});
+}
+
+static void extractDescriptionFromInfo(ArrayRef Descriptions,
+   json::Object &EnumValObj) {
+  if (Descriptions.empty())
+return;
+  json::Value ArrDesc = Array();
+  json::Array &ADescRef = *ArrDesc.getAsArray();
+  for (const CommentInfo &Child : Descriptions)
+ADescRef.emplace_back(extractValue(Child));
+  EnumValObj.insert({"EnumValueComments", ArrDesc});
+}
+
+static json::Value extractValue(const FunctionInfo &I, StringRef ParentInfoDir,
+const ClangDocContext &CDCtx) {
+  Object Obj = Object();
+  Obj.insert({"Name", I.Name});
+  Obj.insert({"ID", toHex(toStringRef(I.USR))});
+  Obj.insert({"Access", getAccessSpelling(I.Access).str()});
+  Obj.insert({"ReturnType", extractValue(I.ReturnType.Type, ParentInfoDir)});
+
+  json::Value ParamArr = Array();
+  for (const auto Val : enumerate(I.Params)) {
+json::Value V = Object();
+auto &VRef = *V.getAsObject();
+VRef.insert({"Name", Val.value().Name});
+VRef.insert({"Type", Val.value().Type.Name});
+VRef.insert({"End", Val.index() + 1 == I.Params.size()});
+ParamArr.getAsArray()->emplace_back(V);
+  }
+  Obj.insert({"Params", ParamArr});
+
+  maybeInsertLocation(I.DefLoc, CDCtx, Obj);
+  return Obj;
+}
+
+static json::Value extractValue(const EnumInfo &I,
+

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Track if a type is a template or builtin (PR #138067)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138067

>From 1a0c8b969bf020e608d721a93aff8921e3c8aa55 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 14:20:40 -0700
Subject: [PATCH] [clang-doc] Track if a type is a template or builtin

Originally part of #133161. This patch adds preliminary tracking
for of TypeInfo, by tracking if the type is a builtin or template.

The new functionality is not yet exercised.

Co-authored-by: Peter Chou 
---
 clang-tools-extra/clang-doc/Representation.h |  3 +++
 clang-tools-extra/clang-doc/Serialize.cpp| 17 -
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index 1673be496b7b2..a3a6217f76bbd 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -164,6 +164,9 @@ struct TypeInfo {
   bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
 
   Reference Type; // Referenced type in this info.
+
+  bool IsTemplate = false;
+  bool IsBuiltIn = false;
 };
 
 // Represents one template parameter.
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 0a59724a0d75a..9b2fa36194b63 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -405,9 +405,12 @@ static RecordDecl *getRecordDeclForType(const QualType &T) 
{
 static TypeInfo getTypeInfoForType(const QualType &T,
const PrintingPolicy &Policy) {
   const TagDecl *TD = getTagDeclForType(T);
-  if (!TD)
-return TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
-
+  if (!TD) {
+TypeInfo TI = TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
+TI.IsBuiltIn = T->isBuiltinType();
+TI.IsTemplate = T->isTemplateTypeParmType();
+return TI;
+  }
   InfoType IT;
   if (isa(TD)) {
 IT = InfoType::IT_enum;
@@ -416,8 +419,12 @@ static TypeInfo getTypeInfoForType(const QualType &T,
   } else {
 IT = InfoType::IT_default;
   }
-  return TypeInfo(Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
-T.getAsString(Policy), getInfoRelativePath(TD)));
+  Reference R = Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
+  T.getAsString(Policy), getInfoRelativePath(TD));
+  TypeInfo TI = TypeInfo(R);
+  TI.IsBuiltIn = T->isBuiltinType();
+  TI.IsTemplate = T->isTemplateTypeParmType();
+  return TI;
 }
 
 static bool isPublic(const clang::AccessSpecifier AS,

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [BOLT] Support pre-aggregated basic sample profile (PR #140196)

2025-05-16 Thread Amir Ayupov via llvm-branch-commits

https://github.com/aaupov edited 
https://github.com/llvm/llvm-project/pull/140196
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] [clang-doc] Track if a type is a template or builtin (PR #138067)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138067

>From 1a0c8b969bf020e608d721a93aff8921e3c8aa55 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 14:20:40 -0700
Subject: [PATCH] [clang-doc] Track if a type is a template or builtin

Originally part of #133161. This patch adds preliminary tracking
for of TypeInfo, by tracking if the type is a builtin or template.

The new functionality is not yet exercised.

Co-authored-by: Peter Chou 
---
 clang-tools-extra/clang-doc/Representation.h |  3 +++
 clang-tools-extra/clang-doc/Serialize.cpp| 17 -
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index 1673be496b7b2..a3a6217f76bbd 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -164,6 +164,9 @@ struct TypeInfo {
   bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
 
   Reference Type; // Referenced type in this info.
+
+  bool IsTemplate = false;
+  bool IsBuiltIn = false;
 };
 
 // Represents one template parameter.
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 0a59724a0d75a..9b2fa36194b63 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -405,9 +405,12 @@ static RecordDecl *getRecordDeclForType(const QualType &T) 
{
 static TypeInfo getTypeInfoForType(const QualType &T,
const PrintingPolicy &Policy) {
   const TagDecl *TD = getTagDeclForType(T);
-  if (!TD)
-return TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
-
+  if (!TD) {
+TypeInfo TI = TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
+TI.IsBuiltIn = T->isBuiltinType();
+TI.IsTemplate = T->isTemplateTypeParmType();
+return TI;
+  }
   InfoType IT;
   if (isa(TD)) {
 IT = InfoType::IT_enum;
@@ -416,8 +419,12 @@ static TypeInfo getTypeInfoForType(const QualType &T,
   } else {
 IT = InfoType::IT_default;
   }
-  return TypeInfo(Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
-T.getAsString(Policy), getInfoRelativePath(TD)));
+  Reference R = Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
+  T.getAsString(Policy), getInfoRelativePath(TD));
+  TypeInfo TI = TypeInfo(R);
+  TI.IsBuiltIn = T->isBuiltinType();
+  TI.IsTemplate = T->isTemplateTypeParmType();
+  return TI;
 }
 
 static bool isPublic(const clang::AccessSpecifier AS,

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [BOLT] Support pre-aggregated basic sample profile (PR #140196)

2025-05-16 Thread Amir Ayupov via llvm-branch-commits

https://github.com/aaupov updated 
https://github.com/llvm/llvm-project/pull/140196


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [BOLT] Support pre-aggregated basic sample profile (PR #140196)

2025-05-16 Thread Amir Ayupov via llvm-branch-commits

https://github.com/aaupov updated 
https://github.com/llvm/llvm-project/pull/140196


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update clang-doc tool to enable mustache templates (PR #138066)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138066

>From 434ddecc69663e244988cc4fe836f5262c86c3f7 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Tue, 29 Apr 2025 18:08:03 -0700
Subject: [PATCH] [clang-doc] Update clang-doc tool to enable mustache
 templates

This patch adds a command line option and enables the Mustache template
HTML backend. This allows users to use the new, more flexible templates
over the old and cumbersome HTML output. Split from #133161.

Co-authored-by: Peter Chou 
---
 .../clang-doc/tool/ClangDocMain.cpp   |  80 +--
 .../clang-doc/basic-project.mustache.test | 481 ++
 2 files changed, 531 insertions(+), 30 deletions(-)
 create mode 100644 clang-tools-extra/test/clang-doc/basic-project.mustache.test

diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp 
b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 8e8f7053a8f87..41fbe87a713d9 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -18,20 +18,14 @@
 
//===--===//
 
 #include "BitcodeReader.h"
-#include "BitcodeWriter.h"
 #include "ClangDoc.h"
 #include "Generators.h"
 #include "Representation.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/Decl.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "support/Utils.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
-#include "clang/Driver/Options.h"
-#include "clang/Frontend/FrontendActions.h"
 #include "clang/Tooling/AllTUsExecution.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Execution.h"
-#include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
@@ -110,22 +104,19 @@ static llvm::cl::opt 
RepositoryCodeLinePrefix(
 llvm::cl::desc("Prefix of line code for repository."),
 llvm::cl::cat(ClangDocCategory));
 
-enum OutputFormatTy {
-  md,
-  yaml,
-  html,
-};
-
-static llvm::cl::opt
-FormatEnum("format", llvm::cl::desc("Format for outputted docs."),
-   llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
-   "Documentation in YAML format."),
-clEnumValN(OutputFormatTy::md, "md",
-   "Documentation in MD format."),
-clEnumValN(OutputFormatTy::html, "html",
-   "Documentation in HTML format.")),
-   llvm::cl::init(OutputFormatTy::yaml),
-   llvm::cl::cat(ClangDocCategory));
+enum OutputFormatTy { md, yaml, html, mustache };
+
+static llvm::cl::opt FormatEnum(
+"format", llvm::cl::desc("Format for outputted docs."),
+llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
+"Documentation in YAML format."),
+ clEnumValN(OutputFormatTy::md, "md",
+"Documentation in MD format."),
+ clEnumValN(OutputFormatTy::html, "html",
+"Documentation in HTML format."),
+ clEnumValN(OutputFormatTy::mustache, "mustache",
+"Documentation in mustache HTML format")),
+llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory));
 
 static std::string getFormatString() {
   switch (FormatEnum) {
@@ -135,6 +126,8 @@ static std::string getFormatString() {
 return "md";
   case OutputFormatTy::html:
 return "html";
+  case OutputFormatTy::mustache:
+return "mustache";
   }
   llvm_unreachable("Unknown OutputFormatTy");
 }
@@ -178,13 +171,9 @@ static 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::SmallString<128> DefaultStylesheet;
-  llvm::sys::path::native(AssetsPath, DefaultStylesheet);
-  llvm::sys::path::append(DefaultStylesheet,
-  "clang-doc-default-stylesheet.css");
-  llvm::SmallString<128> IndexJS;
-  llvm::sys::path::native(AssetsPath, IndexJS);
-  llvm::sys::path::append(IndexJS, "index.js");
+  llvm::SmallString<128> DefaultStylesheet =
+  appendPathNative(AssetsPath, "clang-doc-default-stylesheet.css");
+  llvm::SmallString<128> IndexJS = appendPathNative(AssetsPath, "index.js");
 
   if (!llvm::sys::fs::is_regular_file(IndexJS))
 return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -215,6 +204,30 @@ static llvm::Error getHtmlAssetFiles(const char *Argv0,
   return getDefaultAssetFiles(Argv0, CDCtx);
 }
 
+static llvm::Error getMustacheHtmlFiles(const char *Argv0,
+clang::doc::ClangDocContext &CDCtx) {
+  bool IsDir = llvm::sys::fs::is_direct

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138062

>From e918ff19e30f0584aeac3281b41bd70710f8f2ef Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:10:20 -0700
Subject: [PATCH] [clang-doc] Add helpers for Template config

This patch adds or fills in some helper functions related to template
setup when initializing the mustache backend. It was split from #133161.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   | 45 ++
 .../clang-doc/support/CMakeLists.txt  |  4 +-
 clang-tools-extra/clang-doc/support/Utils.cpp | 61 +++
 clang-tools-extra/clang-doc/support/Utils.h   | 26 
 .../unittests/clang-doc/CMakeLists.txt| 12 
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 11 +++-
 .../unittests/clang-doc/config.h.cmake|  6 ++
 7 files changed, 162 insertions(+), 3 deletions(-)
 create mode 100644 clang-tools-extra/clang-doc/support/Utils.cpp
 create mode 100644 clang-tools-extra/clang-doc/support/Utils.h
 create mode 100644 clang-tools-extra/unittests/clang-doc/config.h.cmake

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 366deb55b77b9..f7e53fc64196a 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Mustache.h"
+#include "llvm/Support/Path.h"
 
 using namespace llvm;
 using namespace llvm::json;
@@ -74,7 +75,51 @@ static std::unique_ptr 
NamespaceTemplate = nullptr;
 
 static std::unique_ptr RecordTemplate = nullptr;
 
+static Error
+setupTemplate(std::unique_ptr &Template,
+  StringRef TemplatePath,
+  std::vector> Partials) {
+  auto T = MustacheTemplateFile::createMustacheFile(TemplatePath);
+  if (Error Err = T.takeError())
+return Err;
+  Template = std::move(T.get());
+  for (const auto [Name, FileName] : Partials) {
+if (auto Err = Template->registerPartialFile(Name, FileName))
+  return Err;
+  }
+  return Error::success();
+}
+
 static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) {
+  // Template files need to use the native path when they're opened,
+  // but have to be used in Posix style when used in HTML.
+  auto ConvertToNative = [](std::string &&Path) -> std::string {
+SmallString<128> PathBuf(Path);
+llvm::sys::path::native(PathBuf);
+return PathBuf.str().str();
+  };
+
+  std::string NamespaceFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("namespace-template"));
+  std::string ClassFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("class-template"));
+  std::string CommentFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("comments-template"));
+  std::string FunctionFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("function-template"));
+  std::string EnumFilePath =
+  ConvertToNative(CDCtx.MustacheTemplates.lookup("enum-template"));
+  std::vector> Partials = {
+  {"Comments", CommentFilePath},
+  {"FunctionPartial", FunctionFilePath},
+  {"EnumPartial", EnumFilePath}};
+
+  if (Error Err = setupTemplate(NamespaceTemplate, NamespaceFilePath, 
Partials))
+return Err;
+
+  if (Error Err = setupTemplate(RecordTemplate, ClassFilePath, Partials))
+return Err;
+
   return Error::success();
 }
 
diff --git a/clang-tools-extra/clang-doc/support/CMakeLists.txt 
b/clang-tools-extra/clang-doc/support/CMakeLists.txt
index a4f7993d5c9d8..f470a613b95d9 100644
--- a/clang-tools-extra/clang-doc/support/CMakeLists.txt
+++ b/clang-tools-extra/clang-doc/support/CMakeLists.txt
@@ -6,4 +6,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_clang_library(clangDocSupport STATIC
   File.cpp
-  )
\ No newline at end of file
+  Utils.cpp
+  )
+
diff --git a/clang-tools-extra/clang-doc/support/Utils.cpp 
b/clang-tools-extra/clang-doc/support/Utils.cpp
new file mode 100644
index 0..f1d193379afa6
--- /dev/null
+++ b/clang-tools-extra/clang-doc/support/Utils.cpp
@@ -0,0 +1,61 @@
+//===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "Utils.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+using namespace llvm;
+
+SmallString<128> appendPathNative(StringRef Base, StringRef Path) {
+  SmallString<128> Default;
+  sys::path::native(Base, Default);
+  sys::path::append(Default, Path);
+  return Default;
+}
+
+SmallString<128> appendPathPosix

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update serializer for improved template handling (PR #138065)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138065

>From 3e47a53b5bdf484069427e574e84d3a2d0459092 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Tue, 29 Apr 2025 18:31:54 -0700
Subject: [PATCH] [clang-doc] Update serializer for improved template handling

This patch updates Serialize.cpp to serialize more data about C++
templates, which are supported by the new mustache HTML template.
Split from #133161.

Co-authored-by: Peter Chou 
---
 clang-tools-extra/clang-doc/Representation.h |   3 +
 clang-tools-extra/clang-doc/Serialize.cpp| 203 ++-
 2 files changed, 198 insertions(+), 8 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index a2e01719eb59e..1673be496b7b2 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -363,6 +363,9 @@ struct FunctionInfo : public SymbolInfo {
   // specializations.
   SmallString<16> FullName;
 
+  // Function Prototype
+  SmallString<256> Prototype;
+
   // When present, this function is a template or specialization.
   std::optional Template;
 };
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 18db427b5239e..0a59724a0d75a 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -8,10 +8,10 @@
 
 #include "Serialize.h"
 #include "BitcodeWriter.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Comment.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/Lexer.h"
-#include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/SHA1.h"
 
@@ -35,6 +35,169 @@ static void populateMemberTypeInfo(RecordInfo &I, 
AccessSpecifier &Access,
const DeclaratorDecl *D,
bool IsStatic = false);
 
+static void getTemplateParameters(const TemplateParameterList *TemplateParams,
+  llvm::raw_ostream &Stream) {
+  Stream << "template <";
+
+  for (unsigned i = 0; i < TemplateParams->size(); ++i) {
+if (i > 0)
+  Stream << ", ";
+
+const NamedDecl *Param = TemplateParams->getParam(i);
+if (const auto *TTP = llvm::dyn_cast(Param)) {
+  if (TTP->wasDeclaredWithTypename())
+Stream << "typename";
+  else
+Stream << "class";
+  if (TTP->isParameterPack())
+Stream << "...";
+  Stream << " " << TTP->getNameAsString();
+} else if (const auto *NTTP =
+   llvm::dyn_cast(Param)) {
+  NTTP->getType().print(Stream, NTTP->getASTContext().getPrintingPolicy());
+  if (NTTP->isParameterPack())
+Stream << "...";
+  Stream << " " << NTTP->getNameAsString();
+} else if (const auto *TTPD =
+   llvm::dyn_cast(Param)) {
+  Stream << "template <";
+  getTemplateParameters(TTPD->getTemplateParameters(), Stream);
+  Stream << "> class " << TTPD->getNameAsString();
+}
+  }
+
+  Stream << "> ";
+}
+
+// Extract the full function prototype from a FunctionDecl including
+// Full Decl
+static llvm::SmallString<256>
+getFunctionPrototype(const FunctionDecl *FuncDecl) {
+  llvm::SmallString<256> Result;
+  llvm::raw_svector_ostream Stream(Result);
+  const ASTContext &Ctx = FuncDecl->getASTContext();
+  const auto *Method = llvm::dyn_cast(FuncDecl);
+  // If it's a templated function, handle the template parameters
+  if (const auto *TmplDecl = FuncDecl->getDescribedTemplate())
+getTemplateParameters(TmplDecl->getTemplateParameters(), Stream);
+
+  // If it's a virtual method
+  if (Method && Method->isVirtual())
+Stream << "virtual ";
+
+  // Print return type
+  FuncDecl->getReturnType().print(Stream, Ctx.getPrintingPolicy());
+
+  // Print function name
+  Stream << " " << FuncDecl->getNameAsString() << "(";
+
+  // Print parameter list with types, names, and default values
+  for (unsigned I = 0; I < FuncDecl->getNumParams(); ++I) {
+if (I > 0)
+  Stream << ", ";
+const ParmVarDecl *ParamDecl = FuncDecl->getParamDecl(I);
+QualType ParamType = ParamDecl->getType();
+ParamType.print(Stream, Ctx.getPrintingPolicy());
+
+// Print parameter name if it has one
+if (!ParamDecl->getName().empty())
+  Stream << " " << ParamDecl->getNameAsString();
+
+// Print default argument if it exists
+if (ParamDecl->hasDefaultArg()) {
+  const Expr *DefaultArg = ParamDecl->getDefaultArg();
+  if (DefaultArg) {
+Stream << " = ";
+DefaultArg->printPretty(Stream, nullptr, Ctx.getPrintingPolicy());
+  }
+}
+  }
+
+  // If it is a variadic function, add '...'
+  if (FuncDecl->isVariadic()) {
+if (FuncDecl->getNumParams() > 0)
+  Stream << ", ";
+Stream << "...";
+  }
+
+  Stream << ")";
+
+  // If it's a const method, add 'const' qualifier
+  if (Method) {
+if (Method->size_overridden_methods())
+   

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update serializer for improved template handling (PR #138065)

2025-05-16 Thread Paul Kirth via llvm-branch-commits


@@ -710,11 +897,12 @@ emitInfo(const RecordDecl *D, const FullComment *FC, 
Location Loc,
 
 // What this is a specialization of.
 auto SpecOf = CTSD->getSpecializedTemplateOrPartial();
-if (auto *CTD = dyn_cast(SpecOf))
-  Specialization.SpecializationOf = getUSRForDecl(CTD);
-else if (auto *CTPSD =
- dyn_cast(SpecOf))
-  Specialization.SpecializationOf = getUSRForDecl(CTPSD);
+if (auto *SpecPtr = dyn_cast(SpecOf)) {
+  Specialization.SpecializationOf = getUSRForDecl(SpecPtr);
+} else if (auto *SpecPtr =
+   dyn_cast(SpecOf)) 
{
+  Specialization.SpecializationOf = getUSRForDecl(SpecPtr);
+}

ilovepi wrote:

I'll mark this done, since clang-format w/ `RemoveBracesLLVM: true` fixed up 
this and other patches in the stack.

https://github.com/llvm/llvm-project/pull/138065
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update clang-doc tool to enable mustache templates (PR #138066)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138066

>From 434ddecc69663e244988cc4fe836f5262c86c3f7 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Tue, 29 Apr 2025 18:08:03 -0700
Subject: [PATCH] [clang-doc] Update clang-doc tool to enable mustache
 templates

This patch adds a command line option and enables the Mustache template
HTML backend. This allows users to use the new, more flexible templates
over the old and cumbersome HTML output. Split from #133161.

Co-authored-by: Peter Chou 
---
 .../clang-doc/tool/ClangDocMain.cpp   |  80 +--
 .../clang-doc/basic-project.mustache.test | 481 ++
 2 files changed, 531 insertions(+), 30 deletions(-)
 create mode 100644 clang-tools-extra/test/clang-doc/basic-project.mustache.test

diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp 
b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 8e8f7053a8f87..41fbe87a713d9 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -18,20 +18,14 @@
 
//===--===//
 
 #include "BitcodeReader.h"
-#include "BitcodeWriter.h"
 #include "ClangDoc.h"
 #include "Generators.h"
 #include "Representation.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/Decl.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "support/Utils.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
-#include "clang/Driver/Options.h"
-#include "clang/Frontend/FrontendActions.h"
 #include "clang/Tooling/AllTUsExecution.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Execution.h"
-#include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
@@ -110,22 +104,19 @@ static llvm::cl::opt 
RepositoryCodeLinePrefix(
 llvm::cl::desc("Prefix of line code for repository."),
 llvm::cl::cat(ClangDocCategory));
 
-enum OutputFormatTy {
-  md,
-  yaml,
-  html,
-};
-
-static llvm::cl::opt
-FormatEnum("format", llvm::cl::desc("Format for outputted docs."),
-   llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
-   "Documentation in YAML format."),
-clEnumValN(OutputFormatTy::md, "md",
-   "Documentation in MD format."),
-clEnumValN(OutputFormatTy::html, "html",
-   "Documentation in HTML format.")),
-   llvm::cl::init(OutputFormatTy::yaml),
-   llvm::cl::cat(ClangDocCategory));
+enum OutputFormatTy { md, yaml, html, mustache };
+
+static llvm::cl::opt FormatEnum(
+"format", llvm::cl::desc("Format for outputted docs."),
+llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
+"Documentation in YAML format."),
+ clEnumValN(OutputFormatTy::md, "md",
+"Documentation in MD format."),
+ clEnumValN(OutputFormatTy::html, "html",
+"Documentation in HTML format."),
+ clEnumValN(OutputFormatTy::mustache, "mustache",
+"Documentation in mustache HTML format")),
+llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory));
 
 static std::string getFormatString() {
   switch (FormatEnum) {
@@ -135,6 +126,8 @@ static std::string getFormatString() {
 return "md";
   case OutputFormatTy::html:
 return "html";
+  case OutputFormatTy::mustache:
+return "mustache";
   }
   llvm_unreachable("Unknown OutputFormatTy");
 }
@@ -178,13 +171,9 @@ static 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::SmallString<128> DefaultStylesheet;
-  llvm::sys::path::native(AssetsPath, DefaultStylesheet);
-  llvm::sys::path::append(DefaultStylesheet,
-  "clang-doc-default-stylesheet.css");
-  llvm::SmallString<128> IndexJS;
-  llvm::sys::path::native(AssetsPath, IndexJS);
-  llvm::sys::path::append(IndexJS, "index.js");
+  llvm::SmallString<128> DefaultStylesheet =
+  appendPathNative(AssetsPath, "clang-doc-default-stylesheet.css");
+  llvm::SmallString<128> IndexJS = appendPathNative(AssetsPath, "index.js");
 
   if (!llvm::sys::fs::is_regular_file(IndexJS))
 return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -215,6 +204,30 @@ static llvm::Error getHtmlAssetFiles(const char *Argv0,
   return getDefaultAssetFiles(Argv0, CDCtx);
 }
 
+static llvm::Error getMustacheHtmlFiles(const char *Argv0,
+clang::doc::ClangDocContext &CDCtx) {
+  bool IsDir = llvm::sys::fs::is_direct

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Implement setupTemplateValue for HTMLMustacheGenerator (PR #138064)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138064

>From 6e5e44847161247fb4e31cf44fe31f9acd038c39 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:13:46 -0700
Subject: [PATCH] [clang-doc] Implement setupTemplateValue for
 HTMLMustacheGenerator

This patch implements the business logic for setupTemplateValue, which
was split from #133161. The implementation configures the relative path
relationships between the various HTML components, and prepares them
prior to their use in the generator.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   |  27 +-
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 416 +-
 2 files changed, 434 insertions(+), 9 deletions(-)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 682c4b59fc741..aa5b40e3efc61 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -391,7 +391,7 @@ static json::Value extractValue(const RecordInfo &I,
 
   maybeInsertLocation(I.DefLoc, CDCtx, RecordValue);
 
-  StringRef BasePath = I.getRelativeFilePath("");
+  SmallString<64> BasePath = I.getRelativeFilePath("");
   extractScopeChildren(I.Children, RecordValue, BasePath, CDCtx);
   json::Value PublicMembers = Array();
   json::Array &PubMemberRef = *PublicMembers.getAsArray();
@@ -425,8 +425,28 @@ static json::Value extractValue(const RecordInfo &I,
 
 static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V,
 Info *I) {
-  return createStringError(inconvertibleErrorCode(),
-   "setupTemplateValue is unimplemented");
+  V.getAsObject()->insert({"ProjectName", CDCtx.ProjectName});
+  json::Value StylesheetArr = Array();
+  auto InfoPath = I->getRelativeFilePath("");
+  SmallString<128> RelativePath = computeRelativePath("", InfoPath);
+  sys::path::native(RelativePath, sys::path::Style::posix);
+  for (const auto &FilePath : CDCtx.UserStylesheets) {
+SmallString<128> StylesheetPath = RelativePath;
+sys::path::append(StylesheetPath, sys::path::Style::posix,
+  sys::path::filename(FilePath));
+StylesheetArr.getAsArray()->emplace_back(StylesheetPath);
+  }
+  V.getAsObject()->insert({"Stylesheets", StylesheetArr});
+
+  json::Value ScriptArr = Array();
+  for (auto Script : CDCtx.JsScripts) {
+SmallString<128> JsPath = RelativePath;
+sys::path::append(JsPath, sys::path::Style::posix,
+  sys::path::filename(Script));
+ScriptArr.getAsArray()->emplace_back(JsPath);
+  }
+  V.getAsObject()->insert({"Scripts", ScriptArr});
+  return Error::success();
 }
 
 Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
@@ -437,6 +457,7 @@ Error MustacheHTMLGenerator::generateDocForInfo(Info *I, 
raw_ostream &OS,
 extractValue(*static_cast(I), CDCtx);
 if (auto Err = setupTemplateValue(CDCtx, V, I))
   return Err;
+assert(NamespaceTemplate && "NamespaceTemplate is nullptr.");
 NamespaceTemplate->render(V, OS);
 break;
   }
diff --git 
a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
index 70491f0754b3d..9a6969f789a65 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
@@ -20,10 +20,10 @@
 
 using namespace llvm;
 using namespace testing;
+using namespace clang;
 using namespace clang::doc;
 
-static const std::string ClangDocVersion =
-clang::getClangToolFullVersion("clang-doc");
+static const std::string ClangDocVersion = 
getClangToolFullVersion("clang-doc");
 
 static std::unique_ptr getHTMLMustacheGenerator() {
   auto G = findGeneratorByName("mustache");
@@ -114,12 +114,416 @@ TEST(HTMLMustacheGeneratorTest, generateDocsForInfo) {
   I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
   "Namespace::ChildStruct", "Namespace");
   I.Children.Functions.emplace_back();
-  I.Children.Functions.back().Access = clang::AccessSpecifier::AS_none;
+  I.Children.Functions.back().Access = AccessSpecifier::AS_none;
   I.Children.Functions.back().Name = "OneFunction";
   I.Children.Enums.emplace_back();
 
-  EXPECT_THAT_ERROR(G->generateDocForInfo(&I, Actual, CDCtx), Failed());
+  unittest::TempDir RootTestDirectory("generateDocForInfoTest",
+  /*Unique=*/true);
+  CDCtx.OutDirectory = RootTestDirectory.path();
+
+  getMustacheHtmlFiles(CLANG_DOC_TEST_ASSET_DIR, CDCtx);
+
+  // FIXME: This is a terrible hack, since we can't initialize the templates
+  // directly. We'll need to update the interfaces so that we can call
+  // SetupTemplateFiles() from outsize of HTMLMustacheGenerator.cpp
+  EXPECT_THAT_ERROR(

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update serializer for improved template handling (PR #138065)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138065

>From f3de7b414feb181314b4d562a6d8f58460583b05 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Tue, 29 Apr 2025 18:31:54 -0700
Subject: [PATCH] [clang-doc] Update serializer for improved template handling

This patch updates Serialize.cpp to serialize more data about C++
templates, which are supported by the new mustache HTML template.
Split from #133161.

Co-authored-by: Peter Chou 
---
 clang-tools-extra/clang-doc/Representation.h |   3 +
 clang-tools-extra/clang-doc/Serialize.cpp| 203 ++-
 2 files changed, 198 insertions(+), 8 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index a2e01719eb59e..1673be496b7b2 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -363,6 +363,9 @@ struct FunctionInfo : public SymbolInfo {
   // specializations.
   SmallString<16> FullName;
 
+  // Function Prototype
+  SmallString<256> Prototype;
+
   // When present, this function is a template or specialization.
   std::optional Template;
 };
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 18db427b5239e..0a59724a0d75a 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -8,10 +8,10 @@
 
 #include "Serialize.h"
 #include "BitcodeWriter.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Comment.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/Lexer.h"
-#include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/SHA1.h"
 
@@ -35,6 +35,169 @@ static void populateMemberTypeInfo(RecordInfo &I, 
AccessSpecifier &Access,
const DeclaratorDecl *D,
bool IsStatic = false);
 
+static void getTemplateParameters(const TemplateParameterList *TemplateParams,
+  llvm::raw_ostream &Stream) {
+  Stream << "template <";
+
+  for (unsigned i = 0; i < TemplateParams->size(); ++i) {
+if (i > 0)
+  Stream << ", ";
+
+const NamedDecl *Param = TemplateParams->getParam(i);
+if (const auto *TTP = llvm::dyn_cast(Param)) {
+  if (TTP->wasDeclaredWithTypename())
+Stream << "typename";
+  else
+Stream << "class";
+  if (TTP->isParameterPack())
+Stream << "...";
+  Stream << " " << TTP->getNameAsString();
+} else if (const auto *NTTP =
+   llvm::dyn_cast(Param)) {
+  NTTP->getType().print(Stream, NTTP->getASTContext().getPrintingPolicy());
+  if (NTTP->isParameterPack())
+Stream << "...";
+  Stream << " " << NTTP->getNameAsString();
+} else if (const auto *TTPD =
+   llvm::dyn_cast(Param)) {
+  Stream << "template <";
+  getTemplateParameters(TTPD->getTemplateParameters(), Stream);
+  Stream << "> class " << TTPD->getNameAsString();
+}
+  }
+
+  Stream << "> ";
+}
+
+// Extract the full function prototype from a FunctionDecl including
+// Full Decl
+static llvm::SmallString<256>
+getFunctionPrototype(const FunctionDecl *FuncDecl) {
+  llvm::SmallString<256> Result;
+  llvm::raw_svector_ostream Stream(Result);
+  const ASTContext &Ctx = FuncDecl->getASTContext();
+  const auto *Method = llvm::dyn_cast(FuncDecl);
+  // If it's a templated function, handle the template parameters
+  if (const auto *TmplDecl = FuncDecl->getDescribedTemplate())
+getTemplateParameters(TmplDecl->getTemplateParameters(), Stream);
+
+  // If it's a virtual method
+  if (Method && Method->isVirtual())
+Stream << "virtual ";
+
+  // Print return type
+  FuncDecl->getReturnType().print(Stream, Ctx.getPrintingPolicy());
+
+  // Print function name
+  Stream << " " << FuncDecl->getNameAsString() << "(";
+
+  // Print parameter list with types, names, and default values
+  for (unsigned I = 0; I < FuncDecl->getNumParams(); ++I) {
+if (I > 0)
+  Stream << ", ";
+const ParmVarDecl *ParamDecl = FuncDecl->getParamDecl(I);
+QualType ParamType = ParamDecl->getType();
+ParamType.print(Stream, Ctx.getPrintingPolicy());
+
+// Print parameter name if it has one
+if (!ParamDecl->getName().empty())
+  Stream << " " << ParamDecl->getNameAsString();
+
+// Print default argument if it exists
+if (ParamDecl->hasDefaultArg()) {
+  const Expr *DefaultArg = ParamDecl->getDefaultArg();
+  if (DefaultArg) {
+Stream << " = ";
+DefaultArg->printPretty(Stream, nullptr, Ctx.getPrintingPolicy());
+  }
+}
+  }
+
+  // If it is a variadic function, add '...'
+  if (FuncDecl->isVariadic()) {
+if (FuncDecl->getNumParams() > 0)
+  Stream << ", ";
+Stream << "...";
+  }
+
+  Stream << ")";
+
+  // If it's a const method, add 'const' qualifier
+  if (Method) {
+if (Method->size_overridden_methods())
+   

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Extract Info into JSON values (PR #138063)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138063

>From d0754f4d2ac9dddece8d2acd83efc42f1298d14d Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:11:39 -0700
Subject: [PATCH] [clang-doc] Extract Info into JSON values

Split from #133161. This patch provides the implementation of a number
of extractValue overloads used with the different types of Info.

The new helper functions extract the relevant information from the
different *Infos and inserts them into the correct fields of the JSON
values that will be used with the specific Mustache templates, which
will land separately.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   | 249 ++
 1 file changed, 249 insertions(+)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index f7e53fc64196a..682c4b59fc741 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -162,15 +162,264 @@ Error MustacheHTMLGenerator::generateDocs(
   return Error::success();
 }
 
+static json::Value
+extractValue(const Location &L,
+ std::optional RepositoryUrl = std::nullopt) {
+  Object Obj = Object();
+  // Should there be Start/End line numbers?
+  Obj.insert({"LineNumber", L.StartLineNumber});
+  Obj.insert({"Filename", L.Filename});
+
+  if (!L.IsFileInRootDir || !RepositoryUrl)
+return Obj;
+  SmallString<128> FileURL(*RepositoryUrl);
+  sys::path::append(FileURL, sys::path::Style::posix, L.Filename);
+  FileURL += "#" + std::to_string(L.StartLineNumber);
+  Obj.insert({"FileURL", FileURL});
+
+  return Obj;
+}
+
+static json::Value extractValue(const Reference &I,
+StringRef CurrentDirectory) {
+  SmallString<64> Path = I.getRelativeFilePath(CurrentDirectory);
+  sys::path::append(Path, I.getFileBaseName() + ".html");
+  sys::path::native(Path, sys::path::Style::posix);
+  Object Obj = Object();
+  Obj.insert({"Link", Path});
+  Obj.insert({"Name", I.Name});
+  Obj.insert({"QualName", I.QualName});
+  Obj.insert({"ID", toHex(toStringRef(I.USR))});
+  return Obj;
+}
+
+static json::Value extractValue(const TypedefInfo &I) {
+  // Not Supported
+  return nullptr;
+}
+
+static json::Value extractValue(const CommentInfo &I) {
+  assert((I.Kind == "BlockCommandComment" || I.Kind == "FullComment" ||
+  I.Kind == "ParagraphComment" || I.Kind == "TextComment") &&
+ "Unknown Comment type in CommentInfo.");
+
+  Object Obj = Object();
+  json::Value Child = Object();
+
+  // TextComment has no children, so return it.
+  if (I.Kind == "TextComment") {
+Obj.insert({"TextComment", I.Text});
+return Obj;
+  }
+
+  // BlockCommandComment needs to generate a Command key.
+  if (I.Kind == "BlockCommandComment")
+Child.getAsObject()->insert({"Command", I.Name});
+
+  // Use the same handling for everything else.
+  // Only valid for:
+  //  - BlockCommandComment
+  //  - FullComment
+  //  - ParagraphComment
+  json::Value ChildArr = Array();
+  auto &CARef = *ChildArr.getAsArray();
+  CARef.reserve(I.Children.size());
+  for (const auto &C : I.Children)
+CARef.emplace_back(extractValue(*C));
+  Child.getAsObject()->insert({"Children", ChildArr});
+  Obj.insert({I.Kind, Child});
+
+  return Obj;
+}
+
+static void maybeInsertLocation(std::optional Loc,
+const ClangDocContext &CDCtx, Object &Obj) {
+  if (!Loc)
+return;
+  Location L = *Loc;
+  Obj.insert({"Location", extractValue(L, CDCtx.RepositoryUrl)});
+}
+
+static void extractDescriptionFromInfo(ArrayRef Descriptions,
+   json::Object &EnumValObj) {
+  if (Descriptions.empty())
+return;
+  json::Value ArrDesc = Array();
+  json::Array &ADescRef = *ArrDesc.getAsArray();
+  for (const CommentInfo &Child : Descriptions)
+ADescRef.emplace_back(extractValue(Child));
+  EnumValObj.insert({"EnumValueComments", ArrDesc});
+}
+
+static json::Value extractValue(const FunctionInfo &I, StringRef ParentInfoDir,
+const ClangDocContext &CDCtx) {
+  Object Obj = Object();
+  Obj.insert({"Name", I.Name});
+  Obj.insert({"ID", toHex(toStringRef(I.USR))});
+  Obj.insert({"Access", getAccessSpelling(I.Access).str()});
+  Obj.insert({"ReturnType", extractValue(I.ReturnType.Type, ParentInfoDir)});
+
+  json::Value ParamArr = Array();
+  for (const auto Val : enumerate(I.Params)) {
+json::Value V = Object();
+auto &VRef = *V.getAsObject();
+VRef.insert({"Name", Val.value().Name});
+VRef.insert({"Type", Val.value().Type.Name});
+VRef.insert({"End", Val.index() + 1 == I.Params.size()});
+ParamArr.getAsArray()->emplace_back(V);
+  }
+  Obj.insert({"Params", ParamArr});
+
+  maybeInsertLocation(I.DefLoc, CDCtx, Obj);
+  return Obj;
+}
+
+static json::Value extractValue(const EnumInfo &I,
+

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Track if a type is a template or builtin (PR #138067)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138067

>From 429d1eafeabd30797ffd8cf97ace060785182528 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 14:20:40 -0700
Subject: [PATCH] [clang-doc] Track if a type is a template or builtin

Originally part of #133161. This patch adds preliminary tracking
for of TypeInfo, by tracking if the type is a builtin or template.

The new functionality is not yet exercised.

Co-authored-by: Peter Chou 
---
 clang-tools-extra/clang-doc/Representation.h |  3 +++
 clang-tools-extra/clang-doc/Serialize.cpp| 17 -
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index 1673be496b7b2..a3a6217f76bbd 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -164,6 +164,9 @@ struct TypeInfo {
   bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
 
   Reference Type; // Referenced type in this info.
+
+  bool IsTemplate = false;
+  bool IsBuiltIn = false;
 };
 
 // Represents one template parameter.
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 0a59724a0d75a..9b2fa36194b63 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -405,9 +405,12 @@ static RecordDecl *getRecordDeclForType(const QualType &T) 
{
 static TypeInfo getTypeInfoForType(const QualType &T,
const PrintingPolicy &Policy) {
   const TagDecl *TD = getTagDeclForType(T);
-  if (!TD)
-return TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
-
+  if (!TD) {
+TypeInfo TI = TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
+TI.IsBuiltIn = T->isBuiltinType();
+TI.IsTemplate = T->isTemplateTypeParmType();
+return TI;
+  }
   InfoType IT;
   if (isa(TD)) {
 IT = InfoType::IT_enum;
@@ -416,8 +419,12 @@ static TypeInfo getTypeInfoForType(const QualType &T,
   } else {
 IT = InfoType::IT_default;
   }
-  return TypeInfo(Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
-T.getAsString(Policy), getInfoRelativePath(TD)));
+  Reference R = Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
+  T.getAsString(Policy), getInfoRelativePath(TD));
+  TypeInfo TI = TypeInfo(R);
+  TI.IsBuiltIn = T->isBuiltinType();
+  TI.IsTemplate = T->isTemplateTypeParmType();
+  return TI;
 }
 
 static bool isPublic(const clang::AccessSpecifier AS,

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] [clang-doc] Implement setupTemplateValue for HTMLMustacheGenerator (PR #138064)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138064

>From ef64af73fabaacd884c66c47b6791063e41a430b Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Wed, 30 Apr 2025 08:13:46 -0700
Subject: [PATCH] [clang-doc] Implement setupTemplateValue for
 HTMLMustacheGenerator

This patch implements the business logic for setupTemplateValue, which
was split from #133161. The implementation configures the relative path
relationships between the various HTML components, and prepares them
prior to their use in the generator.

Co-authored-by: Peter Chou 
---
 .../clang-doc/HTMLMustacheGenerator.cpp   |  27 +-
 .../clang-doc/HTMLMustacheGeneratorTest.cpp   | 416 +-
 2 files changed, 434 insertions(+), 9 deletions(-)

diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 682c4b59fc741..aa5b40e3efc61 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -391,7 +391,7 @@ static json::Value extractValue(const RecordInfo &I,
 
   maybeInsertLocation(I.DefLoc, CDCtx, RecordValue);
 
-  StringRef BasePath = I.getRelativeFilePath("");
+  SmallString<64> BasePath = I.getRelativeFilePath("");
   extractScopeChildren(I.Children, RecordValue, BasePath, CDCtx);
   json::Value PublicMembers = Array();
   json::Array &PubMemberRef = *PublicMembers.getAsArray();
@@ -425,8 +425,28 @@ static json::Value extractValue(const RecordInfo &I,
 
 static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V,
 Info *I) {
-  return createStringError(inconvertibleErrorCode(),
-   "setupTemplateValue is unimplemented");
+  V.getAsObject()->insert({"ProjectName", CDCtx.ProjectName});
+  json::Value StylesheetArr = Array();
+  auto InfoPath = I->getRelativeFilePath("");
+  SmallString<128> RelativePath = computeRelativePath("", InfoPath);
+  sys::path::native(RelativePath, sys::path::Style::posix);
+  for (const auto &FilePath : CDCtx.UserStylesheets) {
+SmallString<128> StylesheetPath = RelativePath;
+sys::path::append(StylesheetPath, sys::path::Style::posix,
+  sys::path::filename(FilePath));
+StylesheetArr.getAsArray()->emplace_back(StylesheetPath);
+  }
+  V.getAsObject()->insert({"Stylesheets", StylesheetArr});
+
+  json::Value ScriptArr = Array();
+  for (auto Script : CDCtx.JsScripts) {
+SmallString<128> JsPath = RelativePath;
+sys::path::append(JsPath, sys::path::Style::posix,
+  sys::path::filename(Script));
+ScriptArr.getAsArray()->emplace_back(JsPath);
+  }
+  V.getAsObject()->insert({"Scripts", ScriptArr});
+  return Error::success();
 }
 
 Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
@@ -437,6 +457,7 @@ Error MustacheHTMLGenerator::generateDocForInfo(Info *I, 
raw_ostream &OS,
 extractValue(*static_cast(I), CDCtx);
 if (auto Err = setupTemplateValue(CDCtx, V, I))
   return Err;
+assert(NamespaceTemplate && "NamespaceTemplate is nullptr.");
 NamespaceTemplate->render(V, OS);
 break;
   }
diff --git 
a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
index 70491f0754b3d..9a6969f789a65 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp
@@ -20,10 +20,10 @@
 
 using namespace llvm;
 using namespace testing;
+using namespace clang;
 using namespace clang::doc;
 
-static const std::string ClangDocVersion =
-clang::getClangToolFullVersion("clang-doc");
+static const std::string ClangDocVersion = 
getClangToolFullVersion("clang-doc");
 
 static std::unique_ptr getHTMLMustacheGenerator() {
   auto G = findGeneratorByName("mustache");
@@ -114,12 +114,416 @@ TEST(HTMLMustacheGeneratorTest, generateDocsForInfo) {
   I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
   "Namespace::ChildStruct", "Namespace");
   I.Children.Functions.emplace_back();
-  I.Children.Functions.back().Access = clang::AccessSpecifier::AS_none;
+  I.Children.Functions.back().Access = AccessSpecifier::AS_none;
   I.Children.Functions.back().Name = "OneFunction";
   I.Children.Enums.emplace_back();
 
-  EXPECT_THAT_ERROR(G->generateDocForInfo(&I, Actual, CDCtx), Failed());
+  unittest::TempDir RootTestDirectory("generateDocForInfoTest",
+  /*Unique=*/true);
+  CDCtx.OutDirectory = RootTestDirectory.path();
+
+  getMustacheHtmlFiles(CLANG_DOC_TEST_ASSET_DIR, CDCtx);
+
+  // FIXME: This is a terrible hack, since we can't initialize the templates
+  // directly. We'll need to update the interfaces so that we can call
+  // SetupTemplateFiles() from outsize of HTMLMustacheGenerator.cpp
+  EXPECT_THAT_ERROR(

[llvm-branch-commits] [clang-tools-extra] [clang-doc] Update clang-doc tool to enable mustache templates (PR #138066)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/138066

>From d82998111fa1b72c91f36f9a40d510f7ca295691 Mon Sep 17 00:00:00 2001
From: Paul Kirth 
Date: Tue, 29 Apr 2025 18:08:03 -0700
Subject: [PATCH] [clang-doc] Update clang-doc tool to enable mustache
 templates

This patch adds a command line option and enables the Mustache template
HTML backend. This allows users to use the new, more flexible templates
over the old and cumbersome HTML output. Split from #133161.

Co-authored-by: Peter Chou 
---
 .../clang-doc/tool/ClangDocMain.cpp   |  80 +--
 .../clang-doc/basic-project.mustache.test | 481 ++
 2 files changed, 531 insertions(+), 30 deletions(-)
 create mode 100644 clang-tools-extra/test/clang-doc/basic-project.mustache.test

diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp 
b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 8e8f7053a8f87..41fbe87a713d9 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -18,20 +18,14 @@
 
//===--===//
 
 #include "BitcodeReader.h"
-#include "BitcodeWriter.h"
 #include "ClangDoc.h"
 #include "Generators.h"
 #include "Representation.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/Decl.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "support/Utils.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
-#include "clang/Driver/Options.h"
-#include "clang/Frontend/FrontendActions.h"
 #include "clang/Tooling/AllTUsExecution.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Execution.h"
-#include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
@@ -110,22 +104,19 @@ static llvm::cl::opt 
RepositoryCodeLinePrefix(
 llvm::cl::desc("Prefix of line code for repository."),
 llvm::cl::cat(ClangDocCategory));
 
-enum OutputFormatTy {
-  md,
-  yaml,
-  html,
-};
-
-static llvm::cl::opt
-FormatEnum("format", llvm::cl::desc("Format for outputted docs."),
-   llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
-   "Documentation in YAML format."),
-clEnumValN(OutputFormatTy::md, "md",
-   "Documentation in MD format."),
-clEnumValN(OutputFormatTy::html, "html",
-   "Documentation in HTML format.")),
-   llvm::cl::init(OutputFormatTy::yaml),
-   llvm::cl::cat(ClangDocCategory));
+enum OutputFormatTy { md, yaml, html, mustache };
+
+static llvm::cl::opt FormatEnum(
+"format", llvm::cl::desc("Format for outputted docs."),
+llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
+"Documentation in YAML format."),
+ clEnumValN(OutputFormatTy::md, "md",
+"Documentation in MD format."),
+ clEnumValN(OutputFormatTy::html, "html",
+"Documentation in HTML format."),
+ clEnumValN(OutputFormatTy::mustache, "mustache",
+"Documentation in mustache HTML format")),
+llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory));
 
 static std::string getFormatString() {
   switch (FormatEnum) {
@@ -135,6 +126,8 @@ static std::string getFormatString() {
 return "md";
   case OutputFormatTy::html:
 return "html";
+  case OutputFormatTy::mustache:
+return "mustache";
   }
   llvm_unreachable("Unknown OutputFormatTy");
 }
@@ -178,13 +171,9 @@ static 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::SmallString<128> DefaultStylesheet;
-  llvm::sys::path::native(AssetsPath, DefaultStylesheet);
-  llvm::sys::path::append(DefaultStylesheet,
-  "clang-doc-default-stylesheet.css");
-  llvm::SmallString<128> IndexJS;
-  llvm::sys::path::native(AssetsPath, IndexJS);
-  llvm::sys::path::append(IndexJS, "index.js");
+  llvm::SmallString<128> DefaultStylesheet =
+  appendPathNative(AssetsPath, "clang-doc-default-stylesheet.css");
+  llvm::SmallString<128> IndexJS = appendPathNative(AssetsPath, "index.js");
 
   if (!llvm::sys::fs::is_regular_file(IndexJS))
 return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -215,6 +204,30 @@ static llvm::Error getHtmlAssetFiles(const char *Argv0,
   return getDefaultAssetFiles(Argv0, CDCtx);
 }
 
+static llvm::Error getMustacheHtmlFiles(const char *Argv0,
+clang::doc::ClangDocContext &CDCtx) {
+  bool IsDir = llvm::sys::fs::is_direct

[llvm-branch-commits] CodeGen: Fix implementation of __builtin_trivially_relocate. (PR #140312)

2025-05-16 Thread Peter Collingbourne via llvm-branch-commits


@@ -4425,6 +4425,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 Address Dest = EmitPointerWithAlignment(E->getArg(0));
 Address Src = EmitPointerWithAlignment(E->getArg(1));
 Value *SizeVal = EmitScalarExpr(E->getArg(2));
+if (BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_trivially_relocate)
+  SizeVal = Builder.CreateMul(

pcc wrote:

I think an overflow here can only result from a call to 
`std::trivially_relocate(first, last, result)` with `first > last`. I feel like 
it would probably be better to report the error at the caller so that we can 
provide a better error message.

https://github.com/llvm/llvm-project/pull/140312
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: refactor issue reporting (PR #135662)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/135662

>From 7f4379ffa6bc0e30e3ea7354b7bf2a2c17e954e0 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Mon, 14 Apr 2025 15:08:54 +0300
Subject: [PATCH 1/5] [BOLT] Gadget scanner: refactor issue reporting

Remove `getAffectedRegisters` and `setOverwritingInstrs` methods from
the base `Report` class. Instead, make `Report` always represent the
brief version of the report. When an issue is detected on the first run
of the analysis, return an optional request for extra details to attach
to the report on the second run.
---
 bolt/include/bolt/Passes/PAuthGadgetScanner.h | 102 ++---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 200 ++
 .../AArch64/gs-pauth-debug-output.s   |   8 +-
 3 files changed, 187 insertions(+), 123 deletions(-)

diff --git a/bolt/include/bolt/Passes/PAuthGadgetScanner.h 
b/bolt/include/bolt/Passes/PAuthGadgetScanner.h
index ccfe632889c7a..1cd3f3f6d3233 100644
--- a/bolt/include/bolt/Passes/PAuthGadgetScanner.h
+++ b/bolt/include/bolt/Passes/PAuthGadgetScanner.h
@@ -217,11 +217,6 @@ struct Report {
   virtual void generateReport(raw_ostream &OS,
   const BinaryContext &BC) const = 0;
 
-  // The two methods below are called by Analysis::computeDetailedInfo when
-  // iterating over the reports.
-  virtual ArrayRef getAffectedRegisters() const { return {}; }
-  virtual void setOverwritingInstrs(ArrayRef Instrs) {}
-
   void printBasicInfo(raw_ostream &OS, const BinaryContext &BC,
   StringRef IssueKind) const;
 };
@@ -229,27 +224,11 @@ struct Report {
 struct GadgetReport : public Report {
   // The particular kind of gadget that is detected.
   const GadgetKind &Kind;
-  // The set of registers related to this gadget report (possibly empty).
-  SmallVector AffectedRegisters;
-  // The instructions that clobber the affected registers.
-  // There is no one-to-one correspondence with AffectedRegisters: for example,
-  // the same register can be overwritten by different instructions in 
different
-  // preceding basic blocks.
-  SmallVector OverwritingInstrs;
-
-  GadgetReport(const GadgetKind &Kind, MCInstReference Location,
-   MCPhysReg AffectedRegister)
-  : Report(Location), Kind(Kind), AffectedRegisters({AffectedRegister}) {}
-
-  void generateReport(raw_ostream &OS, const BinaryContext &BC) const override;
 
-  ArrayRef getAffectedRegisters() const override {
-return AffectedRegisters;
-  }
+  GadgetReport(const GadgetKind &Kind, MCInstReference Location)
+  : Report(Location), Kind(Kind) {}
 
-  void setOverwritingInstrs(ArrayRef Instrs) override {
-OverwritingInstrs.assign(Instrs.begin(), Instrs.end());
-  }
+  void generateReport(raw_ostream &OS, const BinaryContext &BC) const override;
 };
 
 /// Report with a free-form message attached.
@@ -261,8 +240,75 @@ struct GenericReport : public Report {
   const BinaryContext &BC) const override;
 };
 
+/// An information about an issue collected on the slower, detailed,
+/// run of an analysis.
+class ExtraInfo {
+public:
+  virtual void print(raw_ostream &OS, const MCInstReference Location) const = 
0;
+
+  virtual ~ExtraInfo() {}
+};
+
+class ClobberingInfo : public ExtraInfo {
+  SmallVector ClobberingInstrs;
+
+public:
+  ClobberingInfo(const ArrayRef Instrs)
+  : ClobberingInstrs(Instrs) {}
+
+  void print(raw_ostream &OS, const MCInstReference Location) const override;
+};
+
+/// A brief version of a report that can be further augmented with the details.
+///
+/// It is common for a particular type of gadget detector to be tied to some
+/// specific kind of analysis. If an issue is returned by that detector, it may
+/// be further augmented with the detailed info in an analysis-specific way,
+/// or just be left as-is (f.e. if a free-form warning was reported).
+template  struct BriefReport {
+  BriefReport(std::shared_ptr Issue,
+  const std::optional RequestedDetails)
+  : Issue(Issue), RequestedDetails(RequestedDetails) {}
+
+  std::shared_ptr Issue;
+  std::optional RequestedDetails;
+};
+
+/// A detailed version of a report.
+struct DetailedReport {
+  DetailedReport(std::shared_ptr Issue,
+ std::shared_ptr Details)
+  : Issue(Issue), Details(Details) {}
+
+  std::shared_ptr Issue;
+  std::shared_ptr Details;
+};
+
 struct FunctionAnalysisResult {
-  std::vector> Diagnostics;
+  std::vector Diagnostics;
+};
+
+/// A helper class storing per-function context to be instantiated by Analysis.
+class FunctionAnalysis {
+  BinaryContext &BC;
+  BinaryFunction &BF;
+  MCPlusBuilder::AllocatorIdTy AllocatorId;
+  FunctionAnalysisResult Result;
+
+  bool PacRetGadgetsOnly;
+
+  void findUnsafeUses(SmallVector> &Reports);
+  void augmentUnsafeUseReports(const ArrayRef> Reports);
+
+public:
+  FunctionAnalysis(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy 
AllocatorId,
+ 

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: clarify MCPlusBuilder callbacks interface (PR #136147)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/136147

>From c4d109a5689b1f490865f29ebe1a3cfe9bc47584 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Thu, 17 Apr 2025 15:40:05 +0300
Subject: [PATCH 1/2] [BOLT] Gadget scanner: clarify MCPlusBuilder callbacks
 interface

Clarify the semantics of `getAuthenticatedReg` and remove a redundant
`isAuthenticationOfReg` method, as combined auth+something instructions
(such as `retaa` on AArch64) should be handled carefully, especially
when searching for authentication oracles: usually, such instructions
cannot be authentication oracles and only some of them actually write
an authenticated pointer to a register (such as "ldra x0, [x1]!").

Use `std::optional` returned type instead of plain MCPhysReg
and returning `getNoRegister()` as a "not applicable" indication.

Document a few existing methods, add information about preconditions.
---
 bolt/include/bolt/Core/MCPlusBuilder.h| 61 ++-
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 64 +---
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   | 76 ---
 .../AArch64/gs-pauth-debug-output.s   |  3 -
 .../AArch64/gs-pauth-signing-oracles.s| 20 +
 5 files changed, 130 insertions(+), 94 deletions(-)

diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index 132d58f3f9f79..83ad70ea97076 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -562,30 +562,50 @@ class MCPlusBuilder {
 return {};
   }
 
-  virtual ErrorOr getAuthenticatedReg(const MCInst &Inst) const {
-llvm_unreachable("not implemented");
-return getNoRegister();
-  }
-
-  virtual bool isAuthenticationOfReg(const MCInst &Inst,
- MCPhysReg AuthenticatedReg) const {
+  /// Returns the register where an authenticated pointer is written to by 
Inst,
+  /// or std::nullopt if not authenticating any register.
+  ///
+  /// Sets IsChecked if the instruction always checks authenticated pointer,
+  /// i.e. it either returns a successfully authenticated pointer or terminates
+  /// the program abnormally (such as "ldra x0, [x1]!" on AArch64, which 
crashes
+  /// on authentication failure even if FEAT_FPAC is not implemented).
+  virtual std::optional
+  getWrittenAuthenticatedReg(const MCInst &Inst, bool &IsChecked) const {
 llvm_unreachable("not implemented");
-return false;
+return std::nullopt;
   }
 
-  virtual MCPhysReg getSignedReg(const MCInst &Inst) const {
+  /// Returns the register signed by Inst, or std::nullopt if not signing any
+  /// register.
+  ///
+  /// The returned register is assumed to be both input and output operand,
+  /// as it is done on AArch64.
+  virtual std::optional getSignedReg(const MCInst &Inst) const {
 llvm_unreachable("not implemented");
-return getNoRegister();
+return std::nullopt;
   }
 
-  virtual ErrorOr getRegUsedAsRetDest(const MCInst &Inst) const {
+  /// Returns the register used as a return address. Returns std::nullopt if
+  /// not applicable, such as reading the return address from a system register
+  /// or from the stack.
+  ///
+  /// Sets IsAuthenticatedInternally if the instruction accepts a signed
+  /// pointer as its operand and authenticates it internally.
+  ///
+  /// Should only be called when isReturn(Inst) is true.
+  virtual std::optional
+  getRegUsedAsRetDest(const MCInst &Inst,
+  bool &IsAuthenticatedInternally) const {
 llvm_unreachable("not implemented");
-return getNoRegister();
+return std::nullopt;
   }
 
   /// Returns the register used as the destination of an indirect branch or 
call
   /// instruction. Sets IsAuthenticatedInternally if the instruction accepts
   /// a signed pointer as its operand and authenticates it internally.
+  ///
+  /// Should only be called if isIndirectCall(Inst) or isIndirectBranch(Inst)
+  /// returns true.
   virtual MCPhysReg
   getRegUsedAsIndirectBranchDest(const MCInst &Inst,
  bool &IsAuthenticatedInternally) const {
@@ -602,14 +622,14 @@ class MCPlusBuilder {
   ///controlled, under the Pointer Authentication threat model.
   ///
   /// If the instruction does not write to any register satisfying the above
-  /// two conditions, NoRegister is returned.
+  /// two conditions, std::nullopt is returned.
   ///
   /// The Pointer Authentication threat model assumes an attacker is able to
   /// modify any writable memory, but not executable code (due to W^X).
-  virtual MCPhysReg
+  virtual std::optional
   getMaterializedAddressRegForPtrAuth(const MCInst &Inst) const {
 llvm_unreachable("not implemented");
-return getNoRegister();
+return std::nullopt;
   }
 
   /// Analyzes if this instruction can safely perform address arithmetics
@@ -622,10 +642,13 @@ class MCPlusBuilder {
   /// controlled, provided InReg and exe

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: detect untrusted LR before tail call (PR #137224)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/137224

>From 7ed0a41d2162a97103cfa7c3eed10543cacc89df Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 22 Apr 2025 21:43:14 +0300
Subject: [PATCH 1/2] [BOLT] Gadget scanner: detect untrusted LR before tail
 call

Implement the detection of tail calls performed with untrusted link
register, which violates the assumption made on entry to every function.

Unlike other pauth gadgets, this one involves some amount of guessing
which branch instructions should be checked as tail calls.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp|  94 ++-
 .../AArch64/gs-pacret-autiasp.s   |  31 +-
 .../AArch64/gs-pauth-debug-output.s   |  30 +-
 .../AArch64/gs-pauth-tail-calls.s | 597 ++
 4 files changed, 706 insertions(+), 46 deletions(-)
 create mode 100644 bolt/test/binary-analysis/AArch64/gs-pauth-tail-calls.s

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 7a5d47a3ff812..dfb71575b2b39 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -701,8 +701,9 @@ class DataflowSrcSafetyAnalysis
 //
 // Then, a function can be split into a number of disjoint contiguous sequences
 // of instructions without labels in between. These sequences can be processed
-// the same way basic blocks are processed by data-flow analysis, assuming
-// pessimistically that all registers are unsafe at the start of each sequence.
+// the same way basic blocks are processed by data-flow analysis, with the same
+// pessimistic estimation of the initial state at the start of each sequence
+// (except the first instruction of the function).
 class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis {
   BinaryFunction &BF;
   MCPlusBuilder::AllocatorIdTy AllocId;
@@ -713,12 +714,6 @@ class CFGUnawareSrcSafetyAnalysis : public 
SrcSafetyAnalysis {
   BC.MIB->removeAnnotation(I.second, StateAnnotationIndex);
   }
 
-  /// Creates a state with all registers marked unsafe (not to be confused
-  /// with empty state).
-  SrcState createUnsafeState() const {
-return SrcState(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
-  }
-
 public:
   CFGUnawareSrcSafetyAnalysis(BinaryFunction &BF,
   MCPlusBuilder::AllocatorIdTy AllocId,
@@ -729,6 +724,7 @@ class CFGUnawareSrcSafetyAnalysis : public 
SrcSafetyAnalysis {
   }
 
   void run() override {
+const SrcState DefaultState = computePessimisticState(BF);
 SrcState S = createEntryState();
 for (auto &I : BF.instrs()) {
   MCInst &Inst = I.second;
@@ -743,7 +739,7 @@ class CFGUnawareSrcSafetyAnalysis : public 
SrcSafetyAnalysis {
 LLVM_DEBUG({
   traceInst(BC, "Due to label, resetting the state before", Inst);
 });
-S = createUnsafeState();
+S = DefaultState;
   }
 
   // Check if we need to remove an old annotation (this is the case if
@@ -1288,6 +1284,83 @@ shouldReportReturnGadget(const BinaryContext &BC, const 
MCInstReference &Inst,
   return make_gadget_report(RetKind, Inst, *RetReg);
 }
 
+/// While BOLT already marks some of the branch instructions as tail calls,
+/// this function tries to improve the coverage by including less obvious cases
+/// when it is possible to do without introducing too many false positives.
+static bool shouldAnalyzeTailCallInst(const BinaryContext &BC,
+  const BinaryFunction &BF,
+  const MCInstReference &Inst) {
+  // Some BC.MIB->isXYZ(Inst) methods simply delegate to MCInstrDesc::isXYZ()
+  // (such as isBranch at the time of writing this comment), some don't (such
+  // as isCall). For that reason, call MCInstrDesc's methods explicitly when
+  // it is important.
+  const MCInstrDesc &Desc =
+  BC.MII->get(static_cast(Inst).getOpcode());
+  // Tail call should be a branch (but not necessarily an indirect one).
+  if (!Desc.isBranch())
+return false;
+
+  // Always analyze the branches already marked as tail calls by BOLT.
+  if (BC.MIB->isTailCall(Inst))
+return true;
+
+  // Try to also check the branches marked as "UNKNOWN CONTROL FLOW" - the
+  // below is a simplified condition from BinaryContext::printInstruction.
+  bool IsUnknownControlFlow =
+  BC.MIB->isIndirectBranch(Inst) && !BC.MIB->getJumpTable(Inst);
+
+  if (BF.hasCFG() && IsUnknownControlFlow)
+return true;
+
+  return false;
+}
+
+static std::optional>
+shouldReportUnsafeTailCall(const BinaryContext &BC, const BinaryFunction &BF,
+   const MCInstReference &Inst, const SrcState &S) {
+  static const GadgetKind UntrustedLRKind(
+  "untrusted link register found before tail call");
+
+  if (!shouldAnalyzeTailCallInst(BC, BF, Inst))
+return std::nullopt;
+
+  // Not only the set of registers returned by getTrustedLiveInRegs() can be
+  /

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: use more appropriate types (NFC) (PR #135661)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/135661

>From 66d205120b50240725ea2d99c8172a962513b800 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Mon, 14 Apr 2025 14:35:56 +0300
Subject: [PATCH 1/2] [BOLT] Gadget scanner: use more appropriate types (NFC)

* use more flexible `const ArrayRef` and `StringRef` types instead of
  `const std::vector &` and `const std::string &`, correspondingly,
  for function arguments
* return plain `const SrcState &` instead of `ErrorOr`
  from `SrcSafetyAnalysis::getStateBefore`, as absent state is not
  handled gracefully by any caller
---
 bolt/include/bolt/Passes/PAuthGadgetScanner.h |  8 +---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 39 ---
 2 files changed, 19 insertions(+), 28 deletions(-)

diff --git a/bolt/include/bolt/Passes/PAuthGadgetScanner.h 
b/bolt/include/bolt/Passes/PAuthGadgetScanner.h
index 75a8d26c64537..451299327e3b2 100644
--- a/bolt/include/bolt/Passes/PAuthGadgetScanner.h
+++ b/bolt/include/bolt/Passes/PAuthGadgetScanner.h
@@ -12,7 +12,6 @@
 #include "bolt/Core/BinaryContext.h"
 #include "bolt/Core/BinaryFunction.h"
 #include "bolt/Passes/BinaryPasses.h"
-#include "llvm/ADT/SmallSet.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 
@@ -197,9 +196,6 @@ raw_ostream &operator<<(raw_ostream &OS, const 
MCInstReference &);
 
 namespace PAuthGadgetScanner {
 
-class SrcSafetyAnalysis;
-struct SrcState;
-
 /// Description of a gadget kind that can be detected. Intended to be
 /// statically allocated to be attached to reports by reference.
 class GadgetKind {
@@ -208,7 +204,7 @@ class GadgetKind {
 public:
   GadgetKind(const char *Description) : Description(Description) {}
 
-  const StringRef getDescription() const { return Description; }
+  StringRef getDescription() const { return Description; }
 };
 
 /// Base report located at some instruction, without any additional 
information.
@@ -259,7 +255,7 @@ struct GadgetReport : public Report {
 /// Report with a free-form message attached.
 struct GenericReport : public Report {
   std::string Text;
-  GenericReport(MCInstReference Location, const std::string &Text)
+  GenericReport(MCInstReference Location, StringRef Text)
   : Report(Location), Text(Text) {}
   virtual void generateReport(raw_ostream &OS,
   const BinaryContext &BC) const override;
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 12eb9c66130b9..3d723456b6ffd 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -91,14 +91,14 @@ class TrackedRegisters {
   const std::vector Registers;
   std::vector RegToIndexMapping;
 
-  static size_t getMappingSize(const std::vector &RegsToTrack) {
+  static size_t getMappingSize(const ArrayRef RegsToTrack) {
 if (RegsToTrack.empty())
   return 0;
 return 1 + *llvm::max_element(RegsToTrack);
   }
 
 public:
-  TrackedRegisters(const std::vector &RegsToTrack)
+  TrackedRegisters(const ArrayRef RegsToTrack)
   : Registers(RegsToTrack),
 RegToIndexMapping(getMappingSize(RegsToTrack), NoIndex) {
 for (unsigned I = 0; I < RegsToTrack.size(); ++I)
@@ -234,7 +234,7 @@ struct SrcState {
 
 static void printLastInsts(
 raw_ostream &OS,
-const std::vector> &LastInstWritingReg) {
+const ArrayRef> LastInstWritingReg) {
   OS << "Insts: ";
   for (unsigned I = 0; I < LastInstWritingReg.size(); ++I) {
 auto &Set = LastInstWritingReg[I];
@@ -295,7 +295,7 @@ void SrcStatePrinter::print(raw_ostream &OS, const SrcState 
&S) const {
 class SrcSafetyAnalysis {
 public:
   SrcSafetyAnalysis(BinaryFunction &BF,
-const std::vector &RegsToTrackInstsFor)
+const ArrayRef RegsToTrackInstsFor)
   : BC(BF.getBinaryContext()), NumRegs(BC.MRI->getNumRegs()),
 RegsToTrackInstsFor(RegsToTrackInstsFor) {}
 
@@ -303,11 +303,10 @@ class SrcSafetyAnalysis {
 
   static std::shared_ptr
   create(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId,
- const std::vector &RegsToTrackInstsFor);
+ const ArrayRef RegsToTrackInstsFor);
 
   virtual void run() = 0;
-  virtual ErrorOr
-  getStateBefore(const MCInst &Inst) const = 0;
+  virtual const SrcState &getStateBefore(const MCInst &Inst) const = 0;
 
 protected:
   BinaryContext &BC;
@@ -347,7 +346,7 @@ class SrcSafetyAnalysis {
   }
 
   BitVector getClobberedRegs(const MCInst &Point) const {
-BitVector Clobbered(NumRegs, false);
+BitVector Clobbered(NumRegs);
 // Assume a call can clobber all registers, including callee-saved
 // registers. There's a good chance that callee-saved registers will be
 // saved on the stack at some point during execution of the callee.
@@ -409,8 +408,7 @@ class SrcSafetyAnalysis {
   // FirstCheckerInst should belong to the same basic block (see the
   // assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
  

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: prevent false positives due to jump tables (PR #138884)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138884

>From be7f0d86c0c879bd9ab8fa6faf34a0be2c548de9 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 6 May 2025 11:31:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: prevent false positives due to jump
 tables

As part of PAuth hardening, AArch64 LLVM backend can use a special
BR_JumpTable pseudo (enabled by -faarch64-jump-table-hardening
Clang option) which is expanded in the AsmPrinter into a contiguous
sequence without unsafe instructions in the middle.

This commit adds another target-specific callback to MCPlusBuilder
to make it possible to inhibit false positives for known-safe jump
table dispatch sequences. Without special handling, the branch
instruction is likely to be reported as a non-protected call (as its
destination is not produced by an auth instruction, PC-relative address
materialization, etc.) and possibly as a tail call being performed with
unsafe link register (as the detection whether the branch instruction
is a tail call is an heuristic).

For now, only the specific instruction sequence used by the AArch64
LLVM backend is matched.
---
 bolt/include/bolt/Core/MCInstUtils.h  |   9 +
 bolt/include/bolt/Core/MCPlusBuilder.h|  14 +
 bolt/lib/Core/MCInstUtils.cpp |  20 +
 bolt/lib/Passes/PAuthGadgetScanner.cpp|  10 +
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   |  73 ++
 .../AArch64/gs-pauth-jump-table.s | 703 ++
 6 files changed, 829 insertions(+)
 create mode 100644 bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
index 50b7d56470c99..33d36cccbcfff 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -154,6 +154,15 @@ class MCInstReference {
 return nullptr;
   }
 
+  /// Returns the only preceding instruction, or std::nullopt if multiple or no
+  /// predecessors are possible.
+  ///
+  /// If CFG information is available, basic block boundary can be crossed,
+  /// provided there is exactly one predecessor. If CFG is not available, the
+  /// preceding instruction in the offset order is returned, unless this is the
+  /// first instruction of the function.
+  std::optional getSinglePredecessor();
+
   raw_ostream &print(raw_ostream &OS) const;
 };
 
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index 87de6754017db..eb93d7de7fee9 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -14,6 +14,7 @@
 #ifndef BOLT_CORE_MCPLUSBUILDER_H
 #define BOLT_CORE_MCPLUSBUILDER_H
 
+#include "bolt/Core/MCInstUtils.h"
 #include "bolt/Core/MCPlus.h"
 #include "bolt/Core/Relocation.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -699,6 +700,19 @@ class MCPlusBuilder {
 return std::nullopt;
   }
 
+  /// Tests if BranchInst corresponds to an instruction sequence which is known
+  /// to be a safe dispatch via jump table.
+  ///
+  /// The target can decide which instruction sequences to consider "safe" from
+  /// the Pointer Authentication point of view, such as any jump table dispatch
+  /// sequence without function calls inside, any sequence which is contiguous,
+  /// or only some specific well-known sequences.
+  virtual bool
+  isSafeJumpTableBranchForPtrAuth(MCInstReference BranchInst) const {
+llvm_unreachable("not implemented");
+return false;
+  }
+
   virtual bool isTerminator(const MCInst &Inst) const;
 
   virtual bool isNoop(const MCInst &Inst) const {
diff --git a/bolt/lib/Core/MCInstUtils.cpp b/bolt/lib/Core/MCInstUtils.cpp
index 40f6edd59135c..b7c6d898988af 100644
--- a/bolt/lib/Core/MCInstUtils.cpp
+++ b/bolt/lib/Core/MCInstUtils.cpp
@@ -55,3 +55,23 @@ raw_ostream &MCInstReference::print(raw_ostream &OS) const {
   OS << ">";
   return OS;
 }
+
+std::optional MCInstReference::getSinglePredecessor() {
+  if (const RefInBB *Ref = tryGetRefInBB()) {
+if (Ref->It != Ref->BB->begin())
+  return MCInstReference(Ref->BB, &*std::prev(Ref->It));
+
+if (Ref->BB->pred_size() != 1)
+  return std::nullopt;
+
+BinaryBasicBlock *PredBB = *Ref->BB->pred_begin();
+assert(!PredBB->empty() && "Empty basic blocks are not supported yet");
+return MCInstReference(PredBB, &*PredBB->rbegin());
+  }
+
+  const RefInBF &Ref = getRefInBF();
+  if (Ref.It == Ref.BF->instrs().begin())
+return std::nullopt;
+
+  return MCInstReference(Ref.BF, std::prev(Ref.It));
+}
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 5e08ae3fbf767..bda971bcd9343 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1328,6 +1328,11 @@ shouldReportUnsafeTailCall(const BinaryContext &BC, 
const BinaryFunction &BF,
 return std::nullopt;
   }
 
+  if (BC.MIB->isSafeJumpTableBranchForPtrAuth(Inst)) {
+LL

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: improve handling of unreachable basic blocks (PR #136183)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/136183

>From 756d695aeb6bcec050dee61b1368ca407d55d306 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Thu, 17 Apr 2025 20:51:16 +0300
Subject: [PATCH 1/3] [BOLT] Gadget scanner: improve handling of unreachable
 basic blocks

Instead of refusing to analyze an instruction completely, when it is
unreachable according to the CFG reconstructed by BOLT, pessimistically
assume all registers to be unsafe at the start of basic blocks without
any predecessors. Nevertheless, unreachable basic blocks found in
optimized code likely means imprecise CFG reconstruction, thus report a
warning once per basic block without predecessors.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 46 ++-
 .../AArch64/gs-pacret-autiasp.s   |  7 ++-
 .../binary-analysis/AArch64/gs-pauth-calls.s  | 57 +++
 3 files changed, 95 insertions(+), 15 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index cd7c077a6412e..3cee579ef2a15 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -343,6 +343,12 @@ class SrcSafetyAnalysis {
 return S;
   }
 
+  /// Creates a state with all registers marked unsafe (not to be confused
+  /// with empty state).
+  SrcState createUnsafeState() const {
+return SrcState(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
+  }
+
   BitVector getClobberedRegs(const MCInst &Point) const {
 BitVector Clobbered(NumRegs);
 // Assume a call can clobber all registers, including callee-saved
@@ -585,6 +591,13 @@ class DataflowSrcSafetyAnalysis
 if (BB.isEntryPoint())
   return createEntryState();
 
+// If a basic block without any predecessors is found in an optimized code,
+// this likely means that some CFG edges were not detected. Pessimistically
+// assume all registers to be unsafe before this basic block and warn about
+// this fact in FunctionAnalysis::findUnsafeUses().
+if (BB.pred_empty())
+  return createUnsafeState();
+
 return SrcState();
   }
 
@@ -658,12 +671,6 @@ class CFGUnawareSrcSafetyAnalysis : public 
SrcSafetyAnalysis {
   BC.MIB->removeAnnotation(I.second, StateAnnotationIndex);
   }
 
-  /// Creates a state with all registers marked unsafe (not to be confused
-  /// with empty state).
-  SrcState createUnsafeState() const {
-return SrcState(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
-  }
-
 public:
   CFGUnawareSrcSafetyAnalysis(BinaryFunction &BF,
   MCPlusBuilder::AllocatorIdTy AllocId,
@@ -1342,19 +1349,30 @@ void FunctionAnalysisContext::findUnsafeUses(
 BF.dump();
   });
 
+  if (BF.hasCFG()) {
+// Warn on basic blocks being unreachable according to BOLT, as this
+// likely means CFG is imprecise.
+for (BinaryBasicBlock &BB : BF) {
+  if (!BB.pred_empty() || BB.isEntryPoint())
+continue;
+  // Arbitrarily attach the report to the first instruction of BB.
+  MCInst *InstToReport = BB.getFirstNonPseudoInstr();
+  if (!InstToReport)
+continue; // BB has no real instructions
+
+  Reports.push_back(
+  make_generic_report(MCInstReference::get(InstToReport, BF),
+  "Warning: no predecessor basic blocks detected "
+  "(possibly incomplete CFG)"));
+}
+  }
+
   iterateOverInstrs(BF, [&](MCInstReference Inst) {
 if (BC.MIB->isCFI(Inst))
   return;
 
 const SrcState &S = Analysis->getStateBefore(Inst);
-
-// If non-empty state was never propagated from the entry basic block
-// to Inst, assume it to be unreachable and report a warning.
-if (S.empty()) {
-  Reports.push_back(
-  make_generic_report(Inst, "Warning: unreachable instruction found"));
-  return;
-}
+assert(!S.empty() && "Instruction has no associated state");
 
 if (auto Report = shouldReportReturnGadget(BC, Inst, S))
   Reports.push_back(*Report);
diff --git a/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s 
b/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s
index 284f0bea607a5..6559ba336e8de 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s
@@ -215,12 +215,17 @@ f_callclobbered_calleesaved:
 .globl  f_unreachable_instruction
 .type   f_unreachable_instruction,@function
 f_unreachable_instruction:
-// CHECK-LABEL: GS-PAUTH: Warning: unreachable instruction found in function 
f_unreachable_instruction, basic block {{[0-9a-zA-Z.]+}}, at address
+// CHECK-LABEL: GS-PAUTH: Warning: no predecessor basic blocks detected 
(possibly incomplete CFG) in function f_unreachable_instruction, basic block 
{{[0-9a-zA-Z.]+}}, at address
 // CHECK-NEXT:The instruction is {{[0-9a-f]+}}:   add x0, x1, 
x2
 // CHECK-NOT:   instructi

[llvm-branch-commits] [clang] release/20.x: [Clang][AST] Fix HandleLValueBase to deal with references (#140105) (PR #140246)

2025-05-16 Thread Eli Friedman via llvm-branch-commits

https://github.com/efriedma-quic approved this pull request.

LGTM; seems like a conservative fix for the crash, should be safe for the 
branch.

https://github.com/llvm/llvm-project/pull/140246
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add parsing of remaining enums to StaticSampler (PR #140305)

2025-05-16 Thread Finn Plummer via llvm-branch-commits

https://github.com/inbelic created 
https://github.com/llvm/llvm-project/pull/140305

 - defines in-memory reprsentation of `comparisonFunc` and `borderColor`
 - defines parsing of the `ComparisonFunc` and `StaticBorderColor` enum
 - integrates parsing of these number parameters with their respective 
`parseComparisonFunc` and `parseStaticBorderColor`
 - adds basic unit tests to demonstrate setting functionality

Part 6 of https://github.com/llvm/llvm-project/issues/126574

>From e3e711f09017205bca27e38046365ceaa9bdc4cd Mon Sep 17 00:00:00 2001
From: Finn Plummer 
Date: Fri, 16 May 2025 19:53:17 +
Subject: [PATCH 1/4] pre-req: add keywords

---
 .../clang/Lex/HLSLRootSignatureTokenKinds.def | 27 +++
 .../Lex/LexHLSLRootSignatureTest.cpp  | 19 -
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def 
b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index 9515bc7d847fa..19f182d3df2c6 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -59,6 +59,12 @@
 #ifndef TEXTURE_ADDRESS_MODE_ENUM
 #define TEXTURE_ADDRESS_MODE_ENUM(NAME, LIT) ENUM(NAME, LIT)
 #endif
+#ifndef COMPARISON_FUNC_ENUM
+#define COMPARISON_FUNC_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
+#ifndef STATIC_BORDER_COLOR_ENUM
+#define STATIC_BORDER_COLOR_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
 
 // General Tokens:
 TOK(invalid, "invalid identifier")
@@ -113,6 +119,8 @@ KEYWORD(addressV)
 KEYWORD(addressW)
 KEYWORD(mipLODBias)
 KEYWORD(maxAnisotropy)
+KEYWORD(comparisonFunc)
+KEYWORD(borderColor)
 KEYWORD(minLOD)
 KEYWORD(maxLOD)
 
@@ -203,6 +211,25 @@ TEXTURE_ADDRESS_MODE_ENUM(Clamp, "TEXTURE_ADDRESS_CLAMP")
 TEXTURE_ADDRESS_MODE_ENUM(Border, "TEXTURE_ADDRESS_BORDER")
 TEXTURE_ADDRESS_MODE_ENUM(MirrorOnce, "TEXTURE_ADDRESS_MIRRORONCE")
 
+// Comparison Func Enums:
+COMPARISON_FUNC_ENUM(Never, "COMPARISON_NEVER")
+COMPARISON_FUNC_ENUM(Less, "COMPARISON_LESS")
+COMPARISON_FUNC_ENUM(Equal, "COMPARISON_EQUAL")
+COMPARISON_FUNC_ENUM(LessEqual, "COMPARISON_LESS_EQUAL")
+COMPARISON_FUNC_ENUM(Greater, "COMPARISON_GREATER")
+COMPARISON_FUNC_ENUM(NotEqual, "COMPARISON_NOT_EQUAL")
+COMPARISON_FUNC_ENUM(GreaterEqual, "COMPARISON_GREATER_EQUAL")
+COMPARISON_FUNC_ENUM(Always, "COMPARISON_ALWAYS")
+
+// Static Border Color Enums:
+STATIC_BORDER_COLOR_ENUM(TransparentBlack, 
"STATIC_BORDER_COLOR_TRANSPARENT_BLACK")
+STATIC_BORDER_COLOR_ENUM(OpaqueBlack, "STATIC_BORDER_COLOR_OPAQUE_BLACK")
+STATIC_BORDER_COLOR_ENUM(OpaqueWhite, "STATIC_BORDER_COLOR_OPAQUE_WHITE")
+STATIC_BORDER_COLOR_ENUM(OpaqueBlackUint, 
"STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT")
+STATIC_BORDER_COLOR_ENUM(OpaqueWhiteUint, 
"STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT")
+
+#undef STATIC_BORDER_COLOR_ENUM
+#undef COMPARISON_FUNC_ENUM
 #undef TEXTURE_ADDRESS_MODE_ENUM
 #undef FILTER_ENUM
 #undef SHADER_VISIBILITY_ENUM
diff --git a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp 
b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
index 39872ea6b0a3e..3fbade375cb58 100644
--- a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
@@ -137,7 +137,9 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
 numDescriptors offset
 
 filter addressU addressV addressW
-mipLODBias maxAnisotropy minLOD maxLOD
+mipLODBias maxAnisotropy
+comparisonFunc borderColor
+minLOD maxLOD
 
 unbounded
 DESCRIPTOR_RANGE_OFFSET_APPEND
@@ -212,6 +214,21 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
 TEXTURE_ADDRESS_CLAMP
 TEXTURE_ADDRESS_BORDER
 TEXTURE_ADDRESS_MIRRORONCE
+
+comparison_never
+comparison_less
+comparison_equal
+comparison_less_equal
+comparison_greater
+comparison_not_equal
+comparison_greater_equal
+comparison_always
+
+STATIC_BORDER_COLOR_TRANSPARENT_BLACK
+STATIC_BORDER_COLOR_OPAQUE_BLACK
+STATIC_BORDER_COLOR_OPAQUE_WHITE
+STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT
+STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT
   )cc";
   auto TokLoc = SourceLocation();
   hlsl::RootSignatureLexer Lexer(Source, TokLoc);

>From 60127c8be3502c45fba3e1e0295ddb4febe2b988 Mon Sep 17 00:00:00 2001
From: Finn Plummer 
Date: Fri, 16 May 2025 20:00:32 +
Subject: [PATCH 2/4] add parsing of comparisonfunc

---
 .../clang/Parse/ParseHLSLRootSignature.h  |  2 +
 clang/lib/Parse/ParseHLSLRootSignature.cpp| 47 +++
 .../Parse/ParseHLSLRootSignatureTest.cpp  |  6 ++-
 .../llvm/Frontend/HLSL/HLSLRootSignature.h| 12 +
 4 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index c31b80ad696c3..64d59d91a0883 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -117,6 +117,7 @@ class RootSig

[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add parsing of remaining enums to StaticSampler (PR #140305)

2025-05-16 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Finn Plummer (inbelic)


Changes

 - defines in-memory reprsentation of `comparisonFunc` and `borderColor`
 - defines parsing of the `ComparisonFunc` and `StaticBorderColor` enum
 - integrates parsing of these number parameters with their respective 
`parseComparisonFunc` and `parseStaticBorderColor`
 - adds basic unit tests to demonstrate setting functionality

Part 6 of https://github.com/llvm/llvm-project/issues/126574

---
Full diff: https://github.com/llvm/llvm-project/pull/140305.diff


6 Files Affected:

- (modified) clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def (+27) 
- (modified) clang/include/clang/Parse/ParseHLSLRootSignature.h (+5) 
- (modified) clang/lib/Parse/ParseHLSLRootSignature.cpp (+92) 
- (modified) clang/unittests/Lex/LexHLSLRootSignatureTest.cpp (+18-1) 
- (modified) clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp (+11-1) 
- (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h (+21) 


``diff
diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def 
b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index 9515bc7d847fa..19f182d3df2c6 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -59,6 +59,12 @@
 #ifndef TEXTURE_ADDRESS_MODE_ENUM
 #define TEXTURE_ADDRESS_MODE_ENUM(NAME, LIT) ENUM(NAME, LIT)
 #endif
+#ifndef COMPARISON_FUNC_ENUM
+#define COMPARISON_FUNC_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
+#ifndef STATIC_BORDER_COLOR_ENUM
+#define STATIC_BORDER_COLOR_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
 
 // General Tokens:
 TOK(invalid, "invalid identifier")
@@ -113,6 +119,8 @@ KEYWORD(addressV)
 KEYWORD(addressW)
 KEYWORD(mipLODBias)
 KEYWORD(maxAnisotropy)
+KEYWORD(comparisonFunc)
+KEYWORD(borderColor)
 KEYWORD(minLOD)
 KEYWORD(maxLOD)
 
@@ -203,6 +211,25 @@ TEXTURE_ADDRESS_MODE_ENUM(Clamp, "TEXTURE_ADDRESS_CLAMP")
 TEXTURE_ADDRESS_MODE_ENUM(Border, "TEXTURE_ADDRESS_BORDER")
 TEXTURE_ADDRESS_MODE_ENUM(MirrorOnce, "TEXTURE_ADDRESS_MIRRORONCE")
 
+// Comparison Func Enums:
+COMPARISON_FUNC_ENUM(Never, "COMPARISON_NEVER")
+COMPARISON_FUNC_ENUM(Less, "COMPARISON_LESS")
+COMPARISON_FUNC_ENUM(Equal, "COMPARISON_EQUAL")
+COMPARISON_FUNC_ENUM(LessEqual, "COMPARISON_LESS_EQUAL")
+COMPARISON_FUNC_ENUM(Greater, "COMPARISON_GREATER")
+COMPARISON_FUNC_ENUM(NotEqual, "COMPARISON_NOT_EQUAL")
+COMPARISON_FUNC_ENUM(GreaterEqual, "COMPARISON_GREATER_EQUAL")
+COMPARISON_FUNC_ENUM(Always, "COMPARISON_ALWAYS")
+
+// Static Border Color Enums:
+STATIC_BORDER_COLOR_ENUM(TransparentBlack, 
"STATIC_BORDER_COLOR_TRANSPARENT_BLACK")
+STATIC_BORDER_COLOR_ENUM(OpaqueBlack, "STATIC_BORDER_COLOR_OPAQUE_BLACK")
+STATIC_BORDER_COLOR_ENUM(OpaqueWhite, "STATIC_BORDER_COLOR_OPAQUE_WHITE")
+STATIC_BORDER_COLOR_ENUM(OpaqueBlackUint, 
"STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT")
+STATIC_BORDER_COLOR_ENUM(OpaqueWhiteUint, 
"STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT")
+
+#undef STATIC_BORDER_COLOR_ENUM
+#undef COMPARISON_FUNC_ENUM
 #undef TEXTURE_ADDRESS_MODE_ENUM
 #undef FILTER_ENUM
 #undef SHADER_VISIBILITY_ENUM
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index c31b80ad696c3..21df9d0da4a53 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -117,6 +117,8 @@ class RootSignatureParser {
 std::optional AddressW;
 std::optional MipLODBias;
 std::optional MaxAnisotropy;
+std::optional ComparisonFunc;
+std::optional BorderColor;
 std::optional MinLOD;
 std::optional MaxLOD;
   };
@@ -132,6 +134,9 @@ class RootSignatureParser {
   std::optional parseFilter();
   std::optional
   parseTextureAddressMode();
+  std::optional parseComparisonFunc();
+  std::optional
+  parseStaticBorderColor();
   std::optional
   parseRootDescriptorFlags();
   std::optional
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index f77e2d4ce6981..07bd10d00dfad 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -399,6 +399,12 @@ std::optional 
RootSignatureParser::parseStaticSampler() {
   if (Params->MaxAnisotropy.has_value())
 Sampler.MaxAnisotropy = Params->MaxAnisotropy.value();
 
+  if (Params->ComparisonFunc.has_value())
+Sampler.ComparisonFunc = Params->ComparisonFunc.value();
+
+  if (Params->BorderColor.has_value())
+Sampler.BorderColor = Params->BorderColor.value();
+
   if (Params->MinLOD.has_value())
 Sampler.MinLOD = Params->MinLOD.value();
 
@@ -793,6 +799,40 @@ RootSignatureParser::parseStaticSamplerParams() {
   Params.MaxAnisotropy = MaxAnisotropy;
 }
 
+// `comparisonFunc` `=` COMPARISON_FUNC
+if (tryConsumeExpectedToken(TokenKind::kw_comparisonFunc)) {
+  if (Params.ComparisonFunc.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::e

[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add space, visibility enums to StaticSampler (PR #140306)

2025-05-16 Thread Finn Plummer via llvm-branch-commits

https://github.com/inbelic created 
https://github.com/llvm/llvm-project/pull/140306

 - adds the `space` and `visibility` parameters to StaticSampler
 - adds basic unit tests to demonstrate setting functionality

Part 7 and Resolves https://github.com/llvm/llvm-project/issues/126574

>From 28c7adf10177f20fa2ac58f315ce5d9f806189bd Mon Sep 17 00:00:00 2001
From: Finn Plummer 
Date: Fri, 16 May 2025 20:33:09 +
Subject: [PATCH] [HLSL][RootSignature] Add space, visibility enums to
 StaticSampler

---
 .../clang/Parse/ParseHLSLRootSignature.h  |  2 +
 clang/lib/Parse/ParseHLSLRootSignature.cpp| 40 +++
 .../Parse/ParseHLSLRootSignatureTest.cpp  |  9 -
 .../llvm/Frontend/HLSL/HLSLRootSignature.h|  2 +
 4 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 21df9d0da4a53..34d59d7fb66f4 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -121,6 +121,8 @@ class RootSignatureParser {
 std::optional BorderColor;
 std::optional MinLOD;
 std::optional MaxLOD;
+std::optional Space;
+std::optional Visibility;
   };
   std::optional parseStaticSamplerParams();
 
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 07bd10d00dfad..2b2d03f1f7091 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -411,6 +411,12 @@ std::optional 
RootSignatureParser::parseStaticSampler() {
   if (Params->MaxLOD.has_value())
 Sampler.MaxLOD = Params->MaxLOD.value();
 
+  if (Params->Space.has_value())
+Sampler.Space= Params->Space.value();
+
+  if (Params->Visibility.has_value())
+Sampler.Visibility= Params->Visibility.value();
+
   if (consumeExpectedToken(TokenKind::pu_r_paren,
diag::err_hlsl_unexpected_end_of_params,
/*param of=*/TokenKind::kw_StaticSampler))
@@ -866,6 +872,40 @@ RootSignatureParser::parseStaticSamplerParams() {
 return std::nullopt;
   Params.MaxLOD = MaxLOD;
 }
+
+// `space` `=` POS_INT
+if (tryConsumeExpectedToken(TokenKind::kw_space)) {
+  if (Params.Space.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto Space = parseUIntParam();
+  if (!Space.has_value())
+return std::nullopt;
+  Params.Space = Space;
+}
+
+// `visibility` `=` SHADER_VISIBILITY
+if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
+  if (Params.Visibility.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto Visibility = parseShaderVisibility();
+  if (!Visibility.has_value())
+return std::nullopt;
+  Params.Visibility = Visibility;
+}
   } while (tryConsumeExpectedToken(TokenKind::pu_comma));
 
   return Params;
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 6343d9feb4411..10621a0feed28 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -226,7 +226,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) 
{
 TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
   const llvm::StringLiteral Source = R"cc(
 StaticSampler(s0),
-StaticSampler(s0, maxAnisotropy = 3,
+StaticSampler(s0, maxAnisotropy = 3, space = 4,
+  visibility = SHADER_VISIBILITY_DOMAIN,
   minLOD = 4.2f, mipLODBias = 0.23e+3,
   addressW = TEXTURE_ADDRESS_CLAMP,
   addressV = TEXTURE_ADDRESS_BORDER,
@@ -269,6 +270,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 StaticBorderColor::OpaqueWhite);
   ASSERT_EQ(std::get(Elem).MinLOD, 0.f);
   ASSERT_EQ(std::get(Elem).MaxLOD, 3.402823466e+38f);
+  ASSERT_EQ(std::get(Elem).Space, 0u);
+  ASSERT_EQ(std::get(Elem).Visibility,
+ShaderVisibility::All);
 
   // Check values can be set as expected
   Elem = Elements[1];
@@ -288,6 +292,9 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 StaticBorderColor::OpaqueBlackUint);
   ASSERT_EQ(std::get(Elem).MinLOD, 4.2f);
   ASSERT_EQ(std::get(Elem).MaxLOD, 9000.f);
+  ASSERT_EQ(std::get(Elem).Space, 4u);
+  ASSERT_EQ(std::get(Elem).Visibility,
+ShaderVisibility::Domain);
 
   ASSERT_TRUE(Consumer->isSatisfied());
 }
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h 
b

[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add space, visibility enums to StaticSampler (PR #140306)

2025-05-16 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-hlsl

Author: Finn Plummer (inbelic)


Changes

 - adds the `space` and `visibility` parameters to StaticSampler
 - adds basic unit tests to demonstrate setting functionality

Part 7 and Resolves https://github.com/llvm/llvm-project/issues/126574

---
Full diff: https://github.com/llvm/llvm-project/pull/140306.diff


4 Files Affected:

- (modified) clang/include/clang/Parse/ParseHLSLRootSignature.h (+2) 
- (modified) clang/lib/Parse/ParseHLSLRootSignature.cpp (+40) 
- (modified) clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp (+6-1) 
- (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h (+2) 


``diff
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 21df9d0da4a53..34d59d7fb66f4 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -121,6 +121,8 @@ class RootSignatureParser {
 std::optional BorderColor;
 std::optional MinLOD;
 std::optional MaxLOD;
+std::optional Space;
+std::optional Visibility;
   };
   std::optional parseStaticSamplerParams();
 
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 07bd10d00dfad..bd0f9abb5ff1b 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -411,6 +411,12 @@ std::optional 
RootSignatureParser::parseStaticSampler() {
   if (Params->MaxLOD.has_value())
 Sampler.MaxLOD = Params->MaxLOD.value();
 
+  if (Params->Space.has_value())
+Sampler.Space = Params->Space.value();
+
+  if (Params->Visibility.has_value())
+Sampler.Visibility = Params->Visibility.value();
+
   if (consumeExpectedToken(TokenKind::pu_r_paren,
diag::err_hlsl_unexpected_end_of_params,
/*param of=*/TokenKind::kw_StaticSampler))
@@ -866,6 +872,40 @@ RootSignatureParser::parseStaticSamplerParams() {
 return std::nullopt;
   Params.MaxLOD = MaxLOD;
 }
+
+// `space` `=` POS_INT
+if (tryConsumeExpectedToken(TokenKind::kw_space)) {
+  if (Params.Space.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto Space = parseUIntParam();
+  if (!Space.has_value())
+return std::nullopt;
+  Params.Space = Space;
+}
+
+// `visibility` `=` SHADER_VISIBILITY
+if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
+  if (Params.Visibility.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto Visibility = parseShaderVisibility();
+  if (!Visibility.has_value())
+return std::nullopt;
+  Params.Visibility = Visibility;
+}
   } while (tryConsumeExpectedToken(TokenKind::pu_comma));
 
   return Params;
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 6343d9feb4411..3eede0dbed61b 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -226,7 +226,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) 
{
 TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
   const llvm::StringLiteral Source = R"cc(
 StaticSampler(s0),
-StaticSampler(s0, maxAnisotropy = 3,
+StaticSampler(s0, maxAnisotropy = 3, space = 4,
+  visibility = SHADER_VISIBILITY_DOMAIN,
   minLOD = 4.2f, mipLODBias = 0.23e+3,
   addressW = TEXTURE_ADDRESS_CLAMP,
   addressV = TEXTURE_ADDRESS_BORDER,
@@ -269,6 +270,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 StaticBorderColor::OpaqueWhite);
   ASSERT_EQ(std::get(Elem).MinLOD, 0.f);
   ASSERT_EQ(std::get(Elem).MaxLOD, 3.402823466e+38f);
+  ASSERT_EQ(std::get(Elem).Space, 0u);
+  ASSERT_EQ(std::get(Elem).Visibility, ShaderVisibility::All);
 
   // Check values can be set as expected
   Elem = Elements[1];
@@ -288,6 +291,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 StaticBorderColor::OpaqueBlackUint);
   ASSERT_EQ(std::get(Elem).MinLOD, 4.2f);
   ASSERT_EQ(std::get(Elem).MaxLOD, 9000.f);
+  ASSERT_EQ(std::get(Elem).Space, 4u);
+  ASSERT_EQ(std::get(Elem).Visibility, 
ShaderVisibility::Domain);
 
   ASSERT_TRUE(Consumer->isSatisfied());
 }
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h 
b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 025e96ec93c2a..ee65722e68556 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSign

[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add space, visibility enums to StaticSampler (PR #140306)

2025-05-16 Thread Finn Plummer via llvm-branch-commits

https://github.com/inbelic updated 
https://github.com/llvm/llvm-project/pull/140306

>From da757494d005288becdf39f738f3bdcf792dd093 Mon Sep 17 00:00:00 2001
From: Finn Plummer 
Date: Fri, 16 May 2025 20:33:09 +
Subject: [PATCH] [HLSL][RootSignature] Add space, visibility enums to
 StaticSampler

---
 .../clang/Parse/ParseHLSLRootSignature.h  |  2 +
 clang/lib/Parse/ParseHLSLRootSignature.cpp| 40 +++
 .../Parse/ParseHLSLRootSignatureTest.cpp  |  7 +++-
 .../llvm/Frontend/HLSL/HLSLRootSignature.h|  2 +
 4 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 21df9d0da4a53..34d59d7fb66f4 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -121,6 +121,8 @@ class RootSignatureParser {
 std::optional BorderColor;
 std::optional MinLOD;
 std::optional MaxLOD;
+std::optional Space;
+std::optional Visibility;
   };
   std::optional parseStaticSamplerParams();
 
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 07bd10d00dfad..bd0f9abb5ff1b 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -411,6 +411,12 @@ std::optional 
RootSignatureParser::parseStaticSampler() {
   if (Params->MaxLOD.has_value())
 Sampler.MaxLOD = Params->MaxLOD.value();
 
+  if (Params->Space.has_value())
+Sampler.Space = Params->Space.value();
+
+  if (Params->Visibility.has_value())
+Sampler.Visibility = Params->Visibility.value();
+
   if (consumeExpectedToken(TokenKind::pu_r_paren,
diag::err_hlsl_unexpected_end_of_params,
/*param of=*/TokenKind::kw_StaticSampler))
@@ -866,6 +872,40 @@ RootSignatureParser::parseStaticSamplerParams() {
 return std::nullopt;
   Params.MaxLOD = MaxLOD;
 }
+
+// `space` `=` POS_INT
+if (tryConsumeExpectedToken(TokenKind::kw_space)) {
+  if (Params.Space.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto Space = parseUIntParam();
+  if (!Space.has_value())
+return std::nullopt;
+  Params.Space = Space;
+}
+
+// `visibility` `=` SHADER_VISIBILITY
+if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
+  if (Params.Visibility.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto Visibility = parseShaderVisibility();
+  if (!Visibility.has_value())
+return std::nullopt;
+  Params.Visibility = Visibility;
+}
   } while (tryConsumeExpectedToken(TokenKind::pu_comma));
 
   return Params;
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 6343d9feb4411..3eede0dbed61b 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -226,7 +226,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) 
{
 TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
   const llvm::StringLiteral Source = R"cc(
 StaticSampler(s0),
-StaticSampler(s0, maxAnisotropy = 3,
+StaticSampler(s0, maxAnisotropy = 3, space = 4,
+  visibility = SHADER_VISIBILITY_DOMAIN,
   minLOD = 4.2f, mipLODBias = 0.23e+3,
   addressW = TEXTURE_ADDRESS_CLAMP,
   addressV = TEXTURE_ADDRESS_BORDER,
@@ -269,6 +270,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 StaticBorderColor::OpaqueWhite);
   ASSERT_EQ(std::get(Elem).MinLOD, 0.f);
   ASSERT_EQ(std::get(Elem).MaxLOD, 3.402823466e+38f);
+  ASSERT_EQ(std::get(Elem).Space, 0u);
+  ASSERT_EQ(std::get(Elem).Visibility, ShaderVisibility::All);
 
   // Check values can be set as expected
   Elem = Elements[1];
@@ -288,6 +291,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 StaticBorderColor::OpaqueBlackUint);
   ASSERT_EQ(std::get(Elem).MinLOD, 4.2f);
   ASSERT_EQ(std::get(Elem).MaxLOD, 9000.f);
+  ASSERT_EQ(std::get(Elem).Space, 4u);
+  ASSERT_EQ(std::get(Elem).Visibility, 
ShaderVisibility::Domain);
 
   ASSERT_TRUE(Consumer->isSatisfied());
 }
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h 
b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 025e96ec93c2a..ee65722e68556 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -236,6 +23

[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add space, visibility enums to StaticSampler (PR #140306)

2025-05-16 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Finn Plummer (inbelic)


Changes

 - adds the `space` and `visibility` parameters to StaticSampler
 - adds basic unit tests to demonstrate setting functionality

Part 7 and Resolves https://github.com/llvm/llvm-project/issues/126574

---
Full diff: https://github.com/llvm/llvm-project/pull/140306.diff


4 Files Affected:

- (modified) clang/include/clang/Parse/ParseHLSLRootSignature.h (+2) 
- (modified) clang/lib/Parse/ParseHLSLRootSignature.cpp (+40) 
- (modified) clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp (+6-1) 
- (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h (+2) 


``diff
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 21df9d0da4a53..34d59d7fb66f4 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -121,6 +121,8 @@ class RootSignatureParser {
 std::optional BorderColor;
 std::optional MinLOD;
 std::optional MaxLOD;
+std::optional Space;
+std::optional Visibility;
   };
   std::optional parseStaticSamplerParams();
 
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 07bd10d00dfad..bd0f9abb5ff1b 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -411,6 +411,12 @@ std::optional 
RootSignatureParser::parseStaticSampler() {
   if (Params->MaxLOD.has_value())
 Sampler.MaxLOD = Params->MaxLOD.value();
 
+  if (Params->Space.has_value())
+Sampler.Space = Params->Space.value();
+
+  if (Params->Visibility.has_value())
+Sampler.Visibility = Params->Visibility.value();
+
   if (consumeExpectedToken(TokenKind::pu_r_paren,
diag::err_hlsl_unexpected_end_of_params,
/*param of=*/TokenKind::kw_StaticSampler))
@@ -866,6 +872,40 @@ RootSignatureParser::parseStaticSamplerParams() {
 return std::nullopt;
   Params.MaxLOD = MaxLOD;
 }
+
+// `space` `=` POS_INT
+if (tryConsumeExpectedToken(TokenKind::kw_space)) {
+  if (Params.Space.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto Space = parseUIntParam();
+  if (!Space.has_value())
+return std::nullopt;
+  Params.Space = Space;
+}
+
+// `visibility` `=` SHADER_VISIBILITY
+if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
+  if (Params.Visibility.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto Visibility = parseShaderVisibility();
+  if (!Visibility.has_value())
+return std::nullopt;
+  Params.Visibility = Visibility;
+}
   } while (tryConsumeExpectedToken(TokenKind::pu_comma));
 
   return Params;
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 6343d9feb4411..3eede0dbed61b 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -226,7 +226,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) 
{
 TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
   const llvm::StringLiteral Source = R"cc(
 StaticSampler(s0),
-StaticSampler(s0, maxAnisotropy = 3,
+StaticSampler(s0, maxAnisotropy = 3, space = 4,
+  visibility = SHADER_VISIBILITY_DOMAIN,
   minLOD = 4.2f, mipLODBias = 0.23e+3,
   addressW = TEXTURE_ADDRESS_CLAMP,
   addressV = TEXTURE_ADDRESS_BORDER,
@@ -269,6 +270,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 StaticBorderColor::OpaqueWhite);
   ASSERT_EQ(std::get(Elem).MinLOD, 0.f);
   ASSERT_EQ(std::get(Elem).MaxLOD, 3.402823466e+38f);
+  ASSERT_EQ(std::get(Elem).Space, 0u);
+  ASSERT_EQ(std::get(Elem).Visibility, ShaderVisibility::All);
 
   // Check values can be set as expected
   Elem = Elements[1];
@@ -288,6 +291,8 @@ TEST_F(ParseHLSLRootSignatureTest, 
ValidParseStaticSamplerTest) {
 StaticBorderColor::OpaqueBlackUint);
   ASSERT_EQ(std::get(Elem).MinLOD, 4.2f);
   ASSERT_EQ(std::get(Elem).MaxLOD, 9000.f);
+  ASSERT_EQ(std::get(Elem).Space, 4u);
+  ASSERT_EQ(std::get(Elem).Visibility, 
ShaderVisibility::Domain);
 
   ASSERT_TRUE(Consumer->isSatisfied());
 }
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h 
b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 025e96ec93c2a..ee65722e68556 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSig

[llvm-branch-commits] CodeGen: Fix implementation of __builtin_trivially_relocate. (PR #140312)

2025-05-16 Thread Peter Collingbourne via llvm-branch-commits

https://github.com/pcc created https://github.com/llvm/llvm-project/pull/140312

The builtin is documented to copy `count` elements, but the implementation
copies `count` bytes. Fix that.



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] CodeGen: Fix implementation of __builtin_trivially_relocate. (PR #140312)

2025-05-16 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Peter Collingbourne (pcc)


Changes

The builtin is documented to copy `count` elements, but the implementation
copies `count` bytes. Fix that.


---
Full diff: https://github.com/llvm/llvm-project/pull/140312.diff


2 Files Affected:

- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+8) 
- (modified) clang/test/CodeGenCXX/cxx2c-trivially-relocatable.cpp (+1-1) 


``diff
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 48cfbda12b2ac..0cfb88a9d9789 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4425,6 +4425,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 Address Dest = EmitPointerWithAlignment(E->getArg(0));
 Address Src = EmitPointerWithAlignment(E->getArg(1));
 Value *SizeVal = EmitScalarExpr(E->getArg(2));
+if (BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_trivially_relocate)
+  SizeVal = Builder.CreateMul(
+  SizeVal,
+  ConstantInt::get(
+  SizeVal->getType(),
+  getContext()
+  
.getTypeSizeInChars(E->getArg(0)->getType()->getPointeeType())
+  .getQuantity()));
 EmitArgCheck(TCK_Store, Dest, E->getArg(0), 0);
 EmitArgCheck(TCK_Load, Src, E->getArg(1), 1);
 Builder.CreateMemMove(Dest, Src, SizeVal, false);
diff --git a/clang/test/CodeGenCXX/cxx2c-trivially-relocatable.cpp 
b/clang/test/CodeGenCXX/cxx2c-trivially-relocatable.cpp
index 17144cffb6476..63f3ba8e74ed5 100644
--- a/clang/test/CodeGenCXX/cxx2c-trivially-relocatable.cpp
+++ b/clang/test/CodeGenCXX/cxx2c-trivially-relocatable.cpp
@@ -8,7 +8,7 @@ struct S trivially_relocatable_if_eligible {
 };
 
 // CHECK: @_Z4testP1SS0_
-// CHECK: call void @llvm.memmove.p0.p0.i64
+// CHECK: call void @llvm.memmove.p0.p0.i64({{.*}}, i64 8
 // CHECK-NOT: __builtin
 // CHECK: ret
 void test(S* source, S* dest) {

``




https://github.com/llvm/llvm-project/pull/140312
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [llvm][EmbedBitcodePass] Prevent modifying the module with ThinLTO (PR #139999)

2025-05-16 Thread Paul Kirth via llvm-branch-commits

ilovepi wrote:

The test suite seems just as happy with the FatLTO fix as it does with ThinLTO 
on the release branch. I see the same three tests failing, and the reported 
test case passes as well.

For completeness these are the failing tests. This was consistent w/ FatLTO + 
ThinLTO, and ThinLTO alone on built from releases/20.x with the call to 
CloneModule().
 
```
 test-suite :: MultiSource/UnitTests/Float/rounding/rounding.test
  test-suite :: 
SingleSource/Regression/C/gcc-c-torture/execute/GCC-C-execute-pr17377.test
  test-suite :: SingleSource/UnitTests/Float/classify.test
```

https://github.com/llvm/llvm-project/pull/13
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] Add pointer field protection feature. (PR #133538)

2025-05-16 Thread Oliver Hunt via llvm-branch-commits

ojhunt wrote:

@pcc and I have been discussing this.

* The perf issues I was concerned about were predicated on access to a pointer 
loaded from a field continuing to be checked after the original field load, 
this is not the case (and in hindsight doing so would imply passing the pointer 
as a parameter to a function would maintain the tag and require the target 
knowing about it). 
* I have a better understanding of why the offset behavior is required - it is 
easier for me to reason about when considering reference parameters as those 
are much more ubiquitous and invisible to the user, so requiring annotations or 
breaking up such calls isn't really an option. I still don't like the current 
approach but I have yet to think of anything that would be better :-/
* For the POD ABI fixups I realized what I really want is just to have the 
codegen separated out - if it turns out there are cases where the codegen size 
is excessive I'm sure we could add a heuristic for outlining it if needed, but 
I think the real issue for me now was actually just that the fixup codegen was 
inline.

https://github.com/llvm/llvm-project/pull/133538
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [NFC] Run code formatter on Diagnostic.h/cpp ProfileList.cpp SpecialCaseList.cpp (PR #140295)

2025-05-16 Thread Qinkun Bao via llvm-branch-commits

https://github.com/qinkunbao updated 
https://github.com/llvm/llvm-project/pull/140295


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [NFC] Run code formatter on Diagnostic.h/cpp ProfileList.cpp SpecialCaseList.cpp (PR #140295)

2025-05-16 Thread Qinkun Bao via llvm-branch-commits

https://github.com/qinkunbao updated 
https://github.com/llvm/llvm-project/pull/140295


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: detect authentication oracles (PR #135663)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/135663

>From d8ecbc2ea167b48dc3e4fff067047941cfda6d2e Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Sat, 5 Apr 2025 14:54:01 +0300
Subject: [PATCH 1/5] [BOLT] Gadget scanner: detect authentication oracles

Implement the detection of authentication instructions whose results can
be inspected by an attacker to know whether authentication succeeded.

As the properties of output registers of authentication instructions are
inspected, add a second set of analysis-related classes to iterate over
the instructions in reverse order.
---
 bolt/include/bolt/Passes/PAuthGadgetScanner.h |  12 +
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 543 +
 .../AArch64/gs-pauth-authentication-oracles.s | 723 ++
 .../AArch64/gs-pauth-debug-output.s   |  78 ++
 4 files changed, 1356 insertions(+)
 create mode 100644 
bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s

diff --git a/bolt/include/bolt/Passes/PAuthGadgetScanner.h 
b/bolt/include/bolt/Passes/PAuthGadgetScanner.h
index 98a49df862ebd..a3b39fcd5dc02 100644
--- a/bolt/include/bolt/Passes/PAuthGadgetScanner.h
+++ b/bolt/include/bolt/Passes/PAuthGadgetScanner.h
@@ -284,6 +284,15 @@ class ClobberingInfo : public ExtraInfo {
   void print(raw_ostream &OS, const MCInstReference Location) const override;
 };
 
+class LeakageInfo : public ExtraInfo {
+  SmallVector LeakingInstrs;
+
+public:
+  LeakageInfo(const ArrayRef Instrs) : LeakingInstrs(Instrs) 
{}
+
+  void print(raw_ostream &OS, const MCInstReference Location) const override;
+};
+
 /// A brief version of a report that can be further augmented with the details.
 ///
 /// A half-baked report produced on the first run of the analysis. An extra,
@@ -324,6 +333,9 @@ class FunctionAnalysisContext {
   void findUnsafeUses(SmallVector> &Reports);
   void augmentUnsafeUseReports(ArrayRef> Reports);
 
+  void findUnsafeDefs(SmallVector> &Reports);
+  void augmentUnsafeDefReports(ArrayRef> Reports);
+
   /// Process the reports which do not have to be augmented, and remove them
   /// from Reports.
   void handleSimpleReports(SmallVector> &Reports);
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 24ad4844ffb7d..1dd2e3824e385 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -717,6 +717,459 @@ SrcSafetyAnalysis::create(BinaryFunction &BF,
RegsToTrackInstsFor);
 }
 
+/// A state representing which registers are safe to be used as the destination
+/// operand of an authentication instruction.
+///
+/// Similar to SrcState, it is the analysis that should take register aliasing
+/// into account.
+///
+/// Depending on the implementation, it may be possible that an authentication
+/// instruction returns an invalid pointer on failure instead of terminating
+/// the program immediately (assuming the program will crash as soon as that
+/// pointer is dereferenced). To prevent brute-forcing the correct signature,
+/// it should be impossible for an attacker to test if a pointer is correctly
+/// signed - either the program should be terminated on authentication failure
+/// or it should be impossible to tell whether authentication succeeded or not.
+///
+/// For that reason, a restricted set of operations is allowed on any register
+/// containing a value derived from the result of an authentication instruction
+/// until that register is either wiped or checked not to contain a result of a
+/// failed authentication.
+///
+/// Specifically, the safety property for a register is computed by iterating
+/// the instructions in backward order: the source register Xn of an 
instruction
+/// Inst is safe if at least one of the following is true:
+/// * Inst checks if Xn contains the result of a successful authentication and
+///   terminates the program on failure. Note that Inst can either naturally
+///   dereference Xn (load, branch, return, etc. instructions) or be the first
+///   instruction of an explicit checking sequence.
+/// * Inst performs safe address arithmetic AND both source and result
+///   registers, as well as any temporary registers, must be safe after
+///   execution of Inst (temporaries are not used on AArch64 and thus not
+///   currently supported/allowed).
+///   See MCPlusBuilder::analyzeAddressArithmeticsForPtrAuth for the details.
+/// * Inst fully overwrites Xn with an unrelated value.
+struct DstState {
+  /// The set of registers whose values cannot be inspected by an attacker in
+  /// a way usable as an authentication oracle. The results of authentication
+  /// instructions should be written to such registers.
+  BitVector CannotEscapeUnchecked;
+
+  std::vector> FirstInstLeakingReg;
+
+  /// Construct an empty state.
+  DstState() {}
+
+  DstState(unsigned NumRegs, unsigned NumRegsToTrack)
+  : Cannot

[llvm-branch-commits] [llvm] [BOLT] Factor out MCInstReference from gadget scanner (NFC) (PR #138655)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138655

>From 386e51d530a03e33daf370c5d0ef00bc830209cc Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Mon, 28 Apr 2025 18:35:48 +0300
Subject: [PATCH] [BOLT] Factor out MCInstReference from gadget scanner (NFC)

Move MCInstReference representing a constant reference to an instruction
inside a parent entity - either inside a basic block (which has a
reference to its parent function) or directly to the function (when CFG
information is not available).
---
 bolt/include/bolt/Core/MCInstUtils.h  | 168 +
 bolt/include/bolt/Passes/PAuthGadgetScanner.h | 178 +-
 bolt/lib/Core/CMakeLists.txt  |   1 +
 bolt/lib/Core/MCInstUtils.cpp |  57 ++
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 102 +-
 5 files changed, 269 insertions(+), 237 deletions(-)
 create mode 100644 bolt/include/bolt/Core/MCInstUtils.h
 create mode 100644 bolt/lib/Core/MCInstUtils.cpp

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
new file mode 100644
index 0..69bf5e6159b74
--- /dev/null
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -0,0 +1,168 @@
+//===- bolt/Core/MCInstUtils.h --*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef BOLT_CORE_MCINSTUTILS_H
+#define BOLT_CORE_MCINSTUTILS_H
+
+#include "bolt/Core/BinaryBasicBlock.h"
+
+#include 
+#include 
+#include 
+
+namespace llvm {
+namespace bolt {
+
+class BinaryFunction;
+
+/// MCInstReference represents a reference to a constant MCInst as stored 
either
+/// in a BinaryFunction (i.e. before a CFG is created), or in a 
BinaryBasicBlock
+/// (after a CFG is created).
+class MCInstReference {
+  using nocfg_const_iterator = std::map::const_iterator;
+
+  // Two cases are possible:
+  // * functions with CFG reconstructed - a function stores a collection of
+  //   basic blocks, each basic block stores a contiguous vector of MCInst
+  // * functions without CFG - there are no basic blocks created,
+  //   the instructions are directly stored in std::map in BinaryFunction
+  //
+  // In both cases, the direct parent of MCInst is stored together with an
+  // iterator pointing to the instruction.
+
+  // Helper struct: CFG is available, the direct parent is a basic block,
+  // iterator's type is `MCInst *`.
+  struct RefInBB {
+RefInBB(const BinaryBasicBlock *BB, const MCInst *Inst)
+: BB(BB), It(Inst) {}
+RefInBB(const RefInBB &Other) = default;
+RefInBB &operator=(const RefInBB &Other) = default;
+
+const BinaryBasicBlock *BB;
+BinaryBasicBlock::const_iterator It;
+
+bool operator<(const RefInBB &Other) const {
+  return std::tie(BB, It) < std::tie(Other.BB, Other.It);
+}
+
+bool operator==(const RefInBB &Other) const {
+  return BB == Other.BB && It == Other.It;
+}
+  };
+
+  // Helper struct: CFG is *not* available, the direct parent is a function,
+  // iterator's type is std::map::iterator (the mapped value
+  // is an instruction's offset).
+  struct RefInBF {
+RefInBF(const BinaryFunction *BF, nocfg_const_iterator It)
+: BF(BF), It(It) {}
+RefInBF(const RefInBF &Other) = default;
+RefInBF &operator=(const RefInBF &Other) = default;
+
+const BinaryFunction *BF;
+nocfg_const_iterator It;
+
+bool operator<(const RefInBF &Other) const {
+  return std::tie(BF, It->first) < std::tie(Other.BF, Other.It->first);
+}
+
+bool operator==(const RefInBF &Other) const {
+  return BF == Other.BF && It->first == Other.It->first;
+}
+  };
+
+  std::variant Reference;
+
+  // Utility methods to be used like this:
+  //
+  // if (auto *Ref = tryGetRefInBB())
+  //   return Ref->doSomething(...);
+  // return getRefInBF().doSomethingElse(...);
+  const RefInBB *tryGetRefInBB() const {
+assert(std::get_if(&Reference) ||
+   std::get_if(&Reference));
+return std::get_if(&Reference);
+  }
+  const RefInBF &getRefInBF() const {
+assert(std::get_if(&Reference));
+return *std::get_if(&Reference);
+  }
+
+public:
+  /// Constructs an empty reference.
+  MCInstReference() : Reference(RefInBB(nullptr, nullptr)) {}
+  /// Constructs a reference to the instruction inside the basic block.
+  MCInstReference(const BinaryBasicBlock *BB, const MCInst *Inst)
+  : Reference(RefInBB(BB, Inst)) {
+assert(BB && Inst && "Neither BB nor Inst should be nullptr");
+  }
+  /// Constructs a reference to the instruction inside the basic block.
+  MCInstReference(const BinaryBasicBlock *BB, unsigned Index)
+  : Reference(RefInBB(BB, &BB->getInstructionAtIndex(I

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: account for BRK when searching for auth oracles (PR #137975)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/137975

>From d2a78c24a5f0a2936b40cdea975165e0f3820e31 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Wed, 30 Apr 2025 16:08:10 +0300
Subject: [PATCH] [BOLT] Gadget scanner: account for BRK when searching for
 auth oracles

An authenticated pointer can be explicitly checked by the compiler via a
sequence of instructions that executes BRK on failure. It is important
to recognize such BRK instruction as checking every register (as it is
expected to immediately trigger an abnormal program termination) to
prevent false positive reports about authentication oracles:

autia   x2, x3
autia   x0, x1
; neither x0 nor x2 are checked at this point
eor x16, x0, x0, lsl #1
tbz x16, #62, on_success ; marks x0 as checked
; end of BB: for x2 to be checked here, it must be checked in both
; successor basic blocks
  on_failure:
brk 0xc470
  on_success:
; x2 is checked
ldr x1, [x2] ; marks x2 as checked
---
 bolt/include/bolt/Core/MCPlusBuilder.h| 14 ++
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 13 +-
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   | 24 --
 .../AArch64/gs-pauth-address-checks.s | 44 +--
 .../AArch64/gs-pauth-authentication-oracles.s |  9 ++--
 .../AArch64/gs-pauth-signing-oracles.s|  6 +--
 6 files changed, 75 insertions(+), 35 deletions(-)

diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index 6d3aa4f5f0feb..87de6754017db 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -706,6 +706,20 @@ class MCPlusBuilder {
 return false;
   }
 
+  /// Returns true if Inst is a trap instruction.
+  ///
+  /// Tests if Inst is an instruction that immediately causes an abnormal
+  /// program termination, for example when a security violation is detected
+  /// by a compiler-inserted check.
+  ///
+  /// @note An implementation of this method should likely return false for
+  /// calls to library functions like abort(), as it is possible that the
+  /// execution state is partially attacker-controlled at this point.
+  virtual bool isTrap(const MCInst &Inst) const {
+llvm_unreachable("not implemented");
+return false;
+  }
+
   virtual bool isBreakpoint(const MCInst &Inst) const {
 llvm_unreachable("not implemented");
 return false;
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index dfb71575b2b39..835ee26aaf08a 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1028,6 +1028,15 @@ class DstSafetyAnalysis {
   dbgs() << ")\n";
 });
 
+// If this instruction terminates the program immediately, no
+// authentication oracles are possible past this point.
+if (BC.MIB->isTrap(Point)) {
+  LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+  DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
+  Next.CannotEscapeUnchecked.set();
+  return Next;
+}
+
 // If this instruction is reachable by the analysis, a non-empty state will
 // be propagated to it sooner or later. Until then, skip computeNext().
 if (Cur.empty()) {
@@ -1133,8 +1142,8 @@ class DataflowDstSafetyAnalysis
 //
 // A basic block without any successors, on the other hand, can be
 // pessimistically initialized to everything-is-unsafe: this will naturally
-// handle both return and tail call instructions and is harmless for
-// internal indirect branch instructions (such as computed gotos).
+// handle return, trap and tail call instructions. At the same time, it is
+// harmless for internal indirect branch instructions, like computed gotos.
 if (BB.succ_empty())
   return createUnsafeState();
 
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp 
b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index f3c29e6ee43b9..4d11c5b206eab 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -386,10 +386,9 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
 // the list of successors of this basic block as appropriate.
 
 // Any of the above code sequences assume the fall-through basic block
-// is a dead-end BRK instruction (any immediate operand is accepted).
+// is a dead-end trap instruction.
 const BinaryBasicBlock *BreakBB = BB.getFallthrough();
-if (!BreakBB || BreakBB->empty() ||
-BreakBB->front().getOpcode() != AArch64::BRK)
+if (!BreakBB || BreakBB->empty() || !isTrap(BreakBB->front()))
   return std::nullopt;
 
 // Iterate over the instructions of BB in reverse order, matching opcodes
@@ -1745,6 +1744,25 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
 Inst.addOperand(MCOperand::createImm(0));
   }
 

[llvm-branch-commits] [llvm] [IR] Introduce the `ptrtoaddr` instruction (PR #139357)

2025-05-16 Thread Alexander Richardson via llvm-branch-commits


@@ -4904,13 +4907,43 @@ class PtrToIntInst : public CastInst {
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static bool classof(const Instruction *I) {
-return I->getOpcode() == PtrToInt;
+return I->getOpcode() == PtrToInt || I->getOpcode() == PtrToAddr;
+  }
+  static bool classof(const Value *V) {
+return isa(V) && classof(cast(V));
+  }
+};
+
+/// This class represents a cast from a pointer to an address (non-capturing
+/// ptrtoint). Inherits from PtrToIntInst since it is a less restrictive 
version
+/// of ptrtoint, so treating it as ptrtoint is conservatively correct.
+class PtrToAddrInst : public PtrToIntInst {

arichardson wrote:

Fixed now.

https://github.com/llvm/llvm-project/pull/139357
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [IR] Introduce the `ptrtoaddr` instruction (PR #139357)

2025-05-16 Thread Alexander Richardson via llvm-branch-commits

https://github.com/arichardson updated 
https://github.com/llvm/llvm-project/pull/139357

>From 25dc175562349410f161ef0e80246301d9a7ba79 Mon Sep 17 00:00:00 2001
From: Alex Richardson 
Date: Fri, 9 May 2025 22:43:37 -0700
Subject: [PATCH] fix docs build

Created using spr 1.3.6-beta.1
---
 llvm/docs/LangRef.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 2d18d0d97aaee..38be6918ff73c 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -12435,7 +12435,7 @@ Example:
 .. _i_ptrtoaddr:
 
 '``ptrtoaddr .. to``' Instruction
-
+^
 
 Syntax:
 """

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [IR] Introduce the `ptrtoaddr` instruction (PR #139357)

2025-05-16 Thread Alexander Richardson via llvm-branch-commits

https://github.com/arichardson updated 
https://github.com/llvm/llvm-project/pull/139357

>From 25dc175562349410f161ef0e80246301d9a7ba79 Mon Sep 17 00:00:00 2001
From: Alex Richardson 
Date: Fri, 9 May 2025 22:43:37 -0700
Subject: [PATCH] fix docs build

Created using spr 1.3.6-beta.1
---
 llvm/docs/LangRef.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 2d18d0d97aaee..38be6918ff73c 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -12435,7 +12435,7 @@ Example:
 .. _i_ptrtoaddr:
 
 '``ptrtoaddr .. to``' Instruction
-
+^
 
 Syntax:
 """

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: account for BRK when searching for auth oracles (PR #137975)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/137975

>From d2a78c24a5f0a2936b40cdea975165e0f3820e31 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Wed, 30 Apr 2025 16:08:10 +0300
Subject: [PATCH] [BOLT] Gadget scanner: account for BRK when searching for
 auth oracles

An authenticated pointer can be explicitly checked by the compiler via a
sequence of instructions that executes BRK on failure. It is important
to recognize such BRK instruction as checking every register (as it is
expected to immediately trigger an abnormal program termination) to
prevent false positive reports about authentication oracles:

autia   x2, x3
autia   x0, x1
; neither x0 nor x2 are checked at this point
eor x16, x0, x0, lsl #1
tbz x16, #62, on_success ; marks x0 as checked
; end of BB: for x2 to be checked here, it must be checked in both
; successor basic blocks
  on_failure:
brk 0xc470
  on_success:
; x2 is checked
ldr x1, [x2] ; marks x2 as checked
---
 bolt/include/bolt/Core/MCPlusBuilder.h| 14 ++
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 13 +-
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   | 24 --
 .../AArch64/gs-pauth-address-checks.s | 44 +--
 .../AArch64/gs-pauth-authentication-oracles.s |  9 ++--
 .../AArch64/gs-pauth-signing-oracles.s|  6 +--
 6 files changed, 75 insertions(+), 35 deletions(-)

diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index 6d3aa4f5f0feb..87de6754017db 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -706,6 +706,20 @@ class MCPlusBuilder {
 return false;
   }
 
+  /// Returns true if Inst is a trap instruction.
+  ///
+  /// Tests if Inst is an instruction that immediately causes an abnormal
+  /// program termination, for example when a security violation is detected
+  /// by a compiler-inserted check.
+  ///
+  /// @note An implementation of this method should likely return false for
+  /// calls to library functions like abort(), as it is possible that the
+  /// execution state is partially attacker-controlled at this point.
+  virtual bool isTrap(const MCInst &Inst) const {
+llvm_unreachable("not implemented");
+return false;
+  }
+
   virtual bool isBreakpoint(const MCInst &Inst) const {
 llvm_unreachable("not implemented");
 return false;
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index dfb71575b2b39..835ee26aaf08a 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1028,6 +1028,15 @@ class DstSafetyAnalysis {
   dbgs() << ")\n";
 });
 
+// If this instruction terminates the program immediately, no
+// authentication oracles are possible past this point.
+if (BC.MIB->isTrap(Point)) {
+  LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+  DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
+  Next.CannotEscapeUnchecked.set();
+  return Next;
+}
+
 // If this instruction is reachable by the analysis, a non-empty state will
 // be propagated to it sooner or later. Until then, skip computeNext().
 if (Cur.empty()) {
@@ -1133,8 +1142,8 @@ class DataflowDstSafetyAnalysis
 //
 // A basic block without any successors, on the other hand, can be
 // pessimistically initialized to everything-is-unsafe: this will naturally
-// handle both return and tail call instructions and is harmless for
-// internal indirect branch instructions (such as computed gotos).
+// handle return, trap and tail call instructions. At the same time, it is
+// harmless for internal indirect branch instructions, like computed gotos.
 if (BB.succ_empty())
   return createUnsafeState();
 
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp 
b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index f3c29e6ee43b9..4d11c5b206eab 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -386,10 +386,9 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
 // the list of successors of this basic block as appropriate.
 
 // Any of the above code sequences assume the fall-through basic block
-// is a dead-end BRK instruction (any immediate operand is accepted).
+// is a dead-end trap instruction.
 const BinaryBasicBlock *BreakBB = BB.getFallthrough();
-if (!BreakBB || BreakBB->empty() ||
-BreakBB->front().getOpcode() != AArch64::BRK)
+if (!BreakBB || BreakBB->empty() || !isTrap(BreakBB->front()))
   return std::nullopt;
 
 // Iterate over the instructions of BB in reverse order, matching opcodes
@@ -1745,6 +1744,25 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
 Inst.addOperand(MCOperand::createImm(0));
   }
 

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: use more appropriate types (NFC) (PR #135661)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/135661

>From 66d205120b50240725ea2d99c8172a962513b800 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Mon, 14 Apr 2025 14:35:56 +0300
Subject: [PATCH 1/2] [BOLT] Gadget scanner: use more appropriate types (NFC)

* use more flexible `const ArrayRef` and `StringRef` types instead of
  `const std::vector &` and `const std::string &`, correspondingly,
  for function arguments
* return plain `const SrcState &` instead of `ErrorOr`
  from `SrcSafetyAnalysis::getStateBefore`, as absent state is not
  handled gracefully by any caller
---
 bolt/include/bolt/Passes/PAuthGadgetScanner.h |  8 +---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 39 ---
 2 files changed, 19 insertions(+), 28 deletions(-)

diff --git a/bolt/include/bolt/Passes/PAuthGadgetScanner.h 
b/bolt/include/bolt/Passes/PAuthGadgetScanner.h
index 75a8d26c64537..451299327e3b2 100644
--- a/bolt/include/bolt/Passes/PAuthGadgetScanner.h
+++ b/bolt/include/bolt/Passes/PAuthGadgetScanner.h
@@ -12,7 +12,6 @@
 #include "bolt/Core/BinaryContext.h"
 #include "bolt/Core/BinaryFunction.h"
 #include "bolt/Passes/BinaryPasses.h"
-#include "llvm/ADT/SmallSet.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 
@@ -197,9 +196,6 @@ raw_ostream &operator<<(raw_ostream &OS, const 
MCInstReference &);
 
 namespace PAuthGadgetScanner {
 
-class SrcSafetyAnalysis;
-struct SrcState;
-
 /// Description of a gadget kind that can be detected. Intended to be
 /// statically allocated to be attached to reports by reference.
 class GadgetKind {
@@ -208,7 +204,7 @@ class GadgetKind {
 public:
   GadgetKind(const char *Description) : Description(Description) {}
 
-  const StringRef getDescription() const { return Description; }
+  StringRef getDescription() const { return Description; }
 };
 
 /// Base report located at some instruction, without any additional 
information.
@@ -259,7 +255,7 @@ struct GadgetReport : public Report {
 /// Report with a free-form message attached.
 struct GenericReport : public Report {
   std::string Text;
-  GenericReport(MCInstReference Location, const std::string &Text)
+  GenericReport(MCInstReference Location, StringRef Text)
   : Report(Location), Text(Text) {}
   virtual void generateReport(raw_ostream &OS,
   const BinaryContext &BC) const override;
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 12eb9c66130b9..3d723456b6ffd 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -91,14 +91,14 @@ class TrackedRegisters {
   const std::vector Registers;
   std::vector RegToIndexMapping;
 
-  static size_t getMappingSize(const std::vector &RegsToTrack) {
+  static size_t getMappingSize(const ArrayRef RegsToTrack) {
 if (RegsToTrack.empty())
   return 0;
 return 1 + *llvm::max_element(RegsToTrack);
   }
 
 public:
-  TrackedRegisters(const std::vector &RegsToTrack)
+  TrackedRegisters(const ArrayRef RegsToTrack)
   : Registers(RegsToTrack),
 RegToIndexMapping(getMappingSize(RegsToTrack), NoIndex) {
 for (unsigned I = 0; I < RegsToTrack.size(); ++I)
@@ -234,7 +234,7 @@ struct SrcState {
 
 static void printLastInsts(
 raw_ostream &OS,
-const std::vector> &LastInstWritingReg) {
+const ArrayRef> LastInstWritingReg) {
   OS << "Insts: ";
   for (unsigned I = 0; I < LastInstWritingReg.size(); ++I) {
 auto &Set = LastInstWritingReg[I];
@@ -295,7 +295,7 @@ void SrcStatePrinter::print(raw_ostream &OS, const SrcState 
&S) const {
 class SrcSafetyAnalysis {
 public:
   SrcSafetyAnalysis(BinaryFunction &BF,
-const std::vector &RegsToTrackInstsFor)
+const ArrayRef RegsToTrackInstsFor)
   : BC(BF.getBinaryContext()), NumRegs(BC.MRI->getNumRegs()),
 RegsToTrackInstsFor(RegsToTrackInstsFor) {}
 
@@ -303,11 +303,10 @@ class SrcSafetyAnalysis {
 
   static std::shared_ptr
   create(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId,
- const std::vector &RegsToTrackInstsFor);
+ const ArrayRef RegsToTrackInstsFor);
 
   virtual void run() = 0;
-  virtual ErrorOr
-  getStateBefore(const MCInst &Inst) const = 0;
+  virtual const SrcState &getStateBefore(const MCInst &Inst) const = 0;
 
 protected:
   BinaryContext &BC;
@@ -347,7 +346,7 @@ class SrcSafetyAnalysis {
   }
 
   BitVector getClobberedRegs(const MCInst &Point) const {
-BitVector Clobbered(NumRegs, false);
+BitVector Clobbered(NumRegs);
 // Assume a call can clobber all registers, including callee-saved
 // registers. There's a good chance that callee-saved registers will be
 // saved on the stack at some point during execution of the callee.
@@ -409,8 +408,7 @@ class SrcSafetyAnalysis {
   // FirstCheckerInst should belong to the same basic block (see the
   // assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
  

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: do not crash on debug-printing CFI instructions (PR #136151)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/136151

>From e192166130e87b449735686d788377140899a2b5 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 15 Apr 2025 21:47:18 +0300
Subject: [PATCH] [BOLT] Gadget scanner: do not crash on debug-printing CFI
 instructions

Some instruction-printing code used under LLVM_DEBUG does not handle CFI
instructions well. While CFI instructions seem to be harmless for the
correctness of the analysis results, they do not convey any useful
information to the analysis either, so skip them early.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 16 ++
 .../AArch64/gs-pauth-debug-output.s   | 32 +++
 2 files changed, 48 insertions(+)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index c18829bc313a8..cd7c077a6412e 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -431,6 +431,9 @@ class SrcSafetyAnalysis {
   }
 
   SrcState computeNext(const MCInst &Point, const SrcState &Cur) {
+if (BC.MIB->isCFI(Point))
+  return Cur;
+
 SrcStatePrinter P(BC);
 LLVM_DEBUG({
   dbgs() << "  SrcSafetyAnalysis::ComputeNext(";
@@ -674,6 +677,8 @@ class CFGUnawareSrcSafetyAnalysis : public 
SrcSafetyAnalysis {
 SrcState S = createEntryState();
 for (auto &I : BF.instrs()) {
   MCInst &Inst = I.second;
+  if (BC.MIB->isCFI(Inst))
+continue;
 
   // If there is a label before this instruction, it is possible that it
   // can be jumped-to, thus conservatively resetting S. As an exception,
@@ -959,6 +964,9 @@ class DstSafetyAnalysis {
   }
 
   DstState computeNext(const MCInst &Point, const DstState &Cur) {
+if (BC.MIB->isCFI(Point))
+  return Cur;
+
 DstStatePrinter P(BC);
 LLVM_DEBUG({
   dbgs() << "  DstSafetyAnalysis::ComputeNext(";
@@ -1135,6 +1143,8 @@ class CFGUnawareDstSafetyAnalysis : public 
DstSafetyAnalysis {
 DstState S = createUnsafeState();
 for (auto &I : llvm::reverse(BF.instrs())) {
   MCInst &Inst = I.second;
+  if (BC.MIB->isCFI(Inst))
+continue;
 
   // If Inst can change the control flow, we cannot be sure that the next
   // instruction (to be executed in analyzed program) is the one processed
@@ -1333,6 +1343,9 @@ void FunctionAnalysisContext::findUnsafeUses(
   });
 
   iterateOverInstrs(BF, [&](MCInstReference Inst) {
+if (BC.MIB->isCFI(Inst))
+  return;
+
 const SrcState &S = Analysis->getStateBefore(Inst);
 
 // If non-empty state was never propagated from the entry basic block
@@ -1396,6 +1409,9 @@ void FunctionAnalysisContext::findUnsafeDefs(
   });
 
   iterateOverInstrs(BF, [&](MCInstReference Inst) {
+if (BC.MIB->isCFI(Inst))
+  return;
+
 const DstState &S = Analysis->getStateAfter(Inst);
 
 if (auto Report = shouldReportAuthOracle(BC, Inst, S))
diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s 
b/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s
index 61aa84377b88e..5aec945621987 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s
@@ -329,6 +329,38 @@ auth_oracle:
 // PAUTH-EMPTY:
 // PAUTH-NEXT:   Attaching leakage info to: :  autia   x0, x1 
# DataflowDstSafetyAnalysis: dst-state
 
+// Gadget scanner should not crash on CFI instructions, including when 
debug-printing them.
+// Note that the particular debug output is not checked, but BOLT should be
+// compiled with assertions enabled to support -debug-only argument.
+
+.globl  cfi_inst_df
+.type   cfi_inst_df,@function
+cfi_inst_df:
+.cfi_startproc
+sub sp, sp, #16
+.cfi_def_cfa_offset 16
+add sp, sp, #16
+.cfi_def_cfa_offset 0
+ret
+.size   cfi_inst_df, .-cfi_inst_df
+.cfi_endproc
+
+.globl  cfi_inst_nocfg
+.type   cfi_inst_nocfg,@function
+cfi_inst_nocfg:
+.cfi_startproc
+sub sp, sp, #16
+.cfi_def_cfa_offset 16
+
+adr x0, 1f
+br  x0
+1:
+add sp, sp, #16
+.cfi_def_cfa_offset 0
+ret
+.size   cfi_inst_nocfg, .-cfi_inst_nocfg
+.cfi_endproc
+
 // CHECK-LABEL:Analyzing function main, AllocatorId = 1
 .globl  main
 .type   main,@function

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: optionally assume auth traps on failure (PR #139778)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/139778

>From 1d09633453e148be111d29792ab80a4057c5c196 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 13 May 2025 19:50:41 +0300
Subject: [PATCH] [BOLT] Gadget scanner: optionally assume auth traps on
 failure

On AArch64 it is possible for an auth instruction to either return an
invalid address value on failure (without FEAT_FPAC) or generate an
error (with FEAT_FPAC). It thus may be possible to never emit explicit
pointer checks, if the target CPU is known to support FEAT_FPAC.

This commit implements an --auth-traps-on-failure command line option,
which essentially makes "safe-to-dereference" and "trusted" register
properties identical and disables scanning for authentication oracles
completely.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 112 +++
 .../binary-analysis/AArch64/cmdline-args.test |   1 +
 .../AArch64/gs-pauth-authentication-oracles.s |   6 +-
 .../binary-analysis/AArch64/gs-pauth-calls.s  |   5 +-
 .../AArch64/gs-pauth-debug-output.s   | 177 ++---
 .../AArch64/gs-pauth-jump-table.s |   6 +-
 .../AArch64/gs-pauth-signing-oracles.s|  54 ++---
 .../AArch64/gs-pauth-tail-calls.s | 184 +-
 8 files changed, 318 insertions(+), 227 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index bda971bcd9343..cfe86d32df798 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -14,6 +14,7 @@
 #include "bolt/Passes/PAuthGadgetScanner.h"
 #include "bolt/Core/ParallelUtilities.h"
 #include "bolt/Passes/DataflowAnalysis.h"
+#include "bolt/Utils/CommandLineOpts.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/MC/MCInst.h"
@@ -26,6 +27,11 @@ namespace llvm {
 namespace bolt {
 namespace PAuthGadgetScanner {
 
+static cl::opt AuthTrapsOnFailure(
+"auth-traps-on-failure",
+cl::desc("Assume authentication instructions always trap on failure"),
+cl::cat(opts::BinaryAnalysisCategory));
+
 [[maybe_unused]] static void traceInst(const BinaryContext &BC, StringRef 
Label,
const MCInst &MI) {
   dbgs() << "  " << Label << ": ";
@@ -365,6 +371,34 @@ class SrcSafetyAnalysis {
 return Clobbered;
   }
 
+  std::optional getRegMadeTrustedByChecking(const MCInst &Inst,
+   SrcState Cur) const {
+// This functions cannot return multiple registers. This is never the case
+// on AArch64.
+std::optional RegCheckedByInst =
+BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/false);
+if (RegCheckedByInst && Cur.SafeToDerefRegs[*RegCheckedByInst])
+  return *RegCheckedByInst;
+
+auto It = CheckerSequenceInfo.find(&Inst);
+if (It == CheckerSequenceInfo.end())
+  return std::nullopt;
+
+MCPhysReg RegCheckedBySequence = It->second.first;
+const MCInst *FirstCheckerInst = It->second.second;
+
+// FirstCheckerInst should belong to the same basic block (see the
+// assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
+// deterministically processed a few steps before this instruction.
+const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst);
+
+// The sequence checks the register, but it should be authenticated before.
+if (!StateBeforeChecker.SafeToDerefRegs[RegCheckedBySequence])
+  return std::nullopt;
+
+return RegCheckedBySequence;
+  }
+
   // Returns all registers that can be treated as if they are written by an
   // authentication instruction.
   SmallVector getRegsMadeSafeToDeref(const MCInst &Point,
@@ -387,18 +421,38 @@ class SrcSafetyAnalysis {
 Regs.push_back(DstAndSrc->first);
 }
 
+// Make sure explicit checker sequence keeps register safe-to-dereference
+// when the register would be clobbered according to the regular rules:
+//
+//; LR is safe to dereference here
+//mov   x16, x30  ; start of the sequence, LR is s-t-d right before
+//xpaclri ; clobbers LR, LR is not safe anymore
+//cmp   x30, x16
+//b.eq  1f; end of the sequence: LR is marked as trusted
+//brk   0x1234
+//  1:
+//; at this point LR would be marked as trusted,
+//; but not safe-to-dereference
+//
+// or even just
+//
+//; X1 is safe to dereference here
+//ldr x0, [x1, #8]!
+//; X1 is trusted here, but it was clobbered due to address write-back
+if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur))
+  Regs.push_back(*CheckedReg);
+
 return Regs;
   }
 
   // Returns all registers made trusted by this instruction.
   SmallVector getRegsMadeTrusted(const MCInst &Point,
 const SrcState &Cur) const {
+assert(!AuthTrapsOnFailure &&

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: prevent false positives due to jump tables (PR #138884)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138884

>From be7f0d86c0c879bd9ab8fa6faf34a0be2c548de9 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 6 May 2025 11:31:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: prevent false positives due to jump
 tables

As part of PAuth hardening, AArch64 LLVM backend can use a special
BR_JumpTable pseudo (enabled by -faarch64-jump-table-hardening
Clang option) which is expanded in the AsmPrinter into a contiguous
sequence without unsafe instructions in the middle.

This commit adds another target-specific callback to MCPlusBuilder
to make it possible to inhibit false positives for known-safe jump
table dispatch sequences. Without special handling, the branch
instruction is likely to be reported as a non-protected call (as its
destination is not produced by an auth instruction, PC-relative address
materialization, etc.) and possibly as a tail call being performed with
unsafe link register (as the detection whether the branch instruction
is a tail call is an heuristic).

For now, only the specific instruction sequence used by the AArch64
LLVM backend is matched.
---
 bolt/include/bolt/Core/MCInstUtils.h  |   9 +
 bolt/include/bolt/Core/MCPlusBuilder.h|  14 +
 bolt/lib/Core/MCInstUtils.cpp |  20 +
 bolt/lib/Passes/PAuthGadgetScanner.cpp|  10 +
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   |  73 ++
 .../AArch64/gs-pauth-jump-table.s | 703 ++
 6 files changed, 829 insertions(+)
 create mode 100644 bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
index 50b7d56470c99..33d36cccbcfff 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -154,6 +154,15 @@ class MCInstReference {
 return nullptr;
   }
 
+  /// Returns the only preceding instruction, or std::nullopt if multiple or no
+  /// predecessors are possible.
+  ///
+  /// If CFG information is available, basic block boundary can be crossed,
+  /// provided there is exactly one predecessor. If CFG is not available, the
+  /// preceding instruction in the offset order is returned, unless this is the
+  /// first instruction of the function.
+  std::optional getSinglePredecessor();
+
   raw_ostream &print(raw_ostream &OS) const;
 };
 
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index 87de6754017db..eb93d7de7fee9 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -14,6 +14,7 @@
 #ifndef BOLT_CORE_MCPLUSBUILDER_H
 #define BOLT_CORE_MCPLUSBUILDER_H
 
+#include "bolt/Core/MCInstUtils.h"
 #include "bolt/Core/MCPlus.h"
 #include "bolt/Core/Relocation.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -699,6 +700,19 @@ class MCPlusBuilder {
 return std::nullopt;
   }
 
+  /// Tests if BranchInst corresponds to an instruction sequence which is known
+  /// to be a safe dispatch via jump table.
+  ///
+  /// The target can decide which instruction sequences to consider "safe" from
+  /// the Pointer Authentication point of view, such as any jump table dispatch
+  /// sequence without function calls inside, any sequence which is contiguous,
+  /// or only some specific well-known sequences.
+  virtual bool
+  isSafeJumpTableBranchForPtrAuth(MCInstReference BranchInst) const {
+llvm_unreachable("not implemented");
+return false;
+  }
+
   virtual bool isTerminator(const MCInst &Inst) const;
 
   virtual bool isNoop(const MCInst &Inst) const {
diff --git a/bolt/lib/Core/MCInstUtils.cpp b/bolt/lib/Core/MCInstUtils.cpp
index 40f6edd59135c..b7c6d898988af 100644
--- a/bolt/lib/Core/MCInstUtils.cpp
+++ b/bolt/lib/Core/MCInstUtils.cpp
@@ -55,3 +55,23 @@ raw_ostream &MCInstReference::print(raw_ostream &OS) const {
   OS << ">";
   return OS;
 }
+
+std::optional MCInstReference::getSinglePredecessor() {
+  if (const RefInBB *Ref = tryGetRefInBB()) {
+if (Ref->It != Ref->BB->begin())
+  return MCInstReference(Ref->BB, &*std::prev(Ref->It));
+
+if (Ref->BB->pred_size() != 1)
+  return std::nullopt;
+
+BinaryBasicBlock *PredBB = *Ref->BB->pred_begin();
+assert(!PredBB->empty() && "Empty basic blocks are not supported yet");
+return MCInstReference(PredBB, &*PredBB->rbegin());
+  }
+
+  const RefInBF &Ref = getRefInBF();
+  if (Ref.It == Ref.BF->instrs().begin())
+return std::nullopt;
+
+  return MCInstReference(Ref.BF, std::prev(Ref.It));
+}
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 5e08ae3fbf767..bda971bcd9343 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1328,6 +1328,11 @@ shouldReportUnsafeTailCall(const BinaryContext &BC, 
const BinaryFunction &BF,
 return std::nullopt;
   }
 
+  if (BC.MIB->isSafeJumpTableBranchForPtrAuth(Inst)) {
+LL

[llvm-branch-commits] [llvm] [BOLT] Introduce helpers to match `MCInst`s one at a time (NFC) (PR #138883)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138883

>From f19a1b7e84d42b77e89b43669a1b9ce368075608 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Wed, 7 May 2025 16:42:00 +0300
Subject: [PATCH] [BOLT] Introduce helpers to match `MCInst`s one at a time
 (NFC)

Introduce matchInst helper function to capture and/or match the operands
of MCInst. Unlike the existing `MCPlusBuilder::MCInstMatcher` machinery,
matchInst is intended for the use cases when precise control over the
instruction order is required. For example, when validating PtrAuth
hardening, all registers are usually considered unsafe after a function
call, even though callee-saved registers should preserve their old
values *under normal operation*.
---
 bolt/include/bolt/Core/MCInstUtils.h  | 128 ++
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   |  90 +---
 2 files changed, 162 insertions(+), 56 deletions(-)

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
index 69bf5e6159b74..50b7d56470c99 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -162,6 +162,134 @@ static inline raw_ostream &operator<<(raw_ostream &OS,
   return Ref.print(OS);
 }
 
+/// Instruction-matching helpers operating on a single instruction at a time.
+///
+/// Unlike MCPlusBuilder::MCInstMatcher, this matchInst() function focuses on
+/// the cases where a precise control over the instruction order is important:
+///
+/// // Bring the short names into the local scope:
+/// using namespace MCInstMatcher;
+/// // Declare the registers to capture:
+/// Reg Xn, Xm;
+/// // Capture the 0th and 1st operands, match the 2nd operand against the
+/// // just captured Xm register, match the 3rd operand against literal 0:
+/// if (!matchInst(MaybeAdd, AArch64::ADDXrs, Xm, Xn, Xm, Imm(0))
+///   return AArch64::NoRegister;
+/// // Match the 0th operand against Xm:
+/// if (!matchInst(MaybeBr, AArch64::BR, Xm))
+///   return AArch64::NoRegister;
+/// // Return the matched register:
+/// return Xm.get();
+namespace MCInstMatcher {
+
+// The base class to match an operand of type T.
+//
+// The subclasses of OpMatcher are intended to be allocated on the stack and
+// to only be used by passing them to matchInst() and by calling their get()
+// function, thus the peculiar `mutable` specifiers: to make the calling code
+// compact and readable, the templated matchInst() function has to accept both
+// long-lived Imm/Reg wrappers declared as local variables (intended to capture
+// the first operand's value and match the subsequent operands, whether inside
+// a single instruction or across multiple instructions), as well as temporary
+// wrappers around literal values to match, f.e. Imm(42) or Reg(AArch64::XZR).
+template  class OpMatcher {
+  mutable std::optional Value;
+  mutable std::optional SavedValue;
+
+  // Remember/restore the last Value - to be called by matchInst.
+  void remember() const { SavedValue = Value; }
+  void restore() const { Value = SavedValue; }
+
+  template 
+  friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
+
+protected:
+  OpMatcher(std::optional ValueToMatch) : Value(ValueToMatch) {}
+
+  bool matchValue(T OpValue) const {
+// Check that OpValue does not contradict the existing Value.
+bool MatchResult = !Value || *Value == OpValue;
+// If MatchResult is false, all matchers will be reset before returning 
from
+// matchInst, including this one, thus no need to assign conditionally.
+Value = OpValue;
+
+return MatchResult;
+  }
+
+public:
+  /// Returns the captured value.
+  T get() const {
+assert(Value.has_value());
+return *Value;
+  }
+};
+
+class Reg : public OpMatcher {
+  bool matches(const MCOperand &Op) const {
+if (!Op.isReg())
+  return false;
+
+return matchValue(Op.getReg());
+  }
+
+  template 
+  friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
+
+public:
+  Reg(std::optional RegToMatch = std::nullopt)
+  : OpMatcher(RegToMatch) {}
+};
+
+class Imm : public OpMatcher {
+  bool matches(const MCOperand &Op) const {
+if (!Op.isImm())
+  return false;
+
+return matchValue(Op.getImm());
+  }
+
+  template 
+  friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
+
+public:
+  Imm(std::optional ImmToMatch = std::nullopt)
+  : OpMatcher(ImmToMatch) {}
+};
+
+/// Tries to match Inst and updates Ops on success.
+///
+/// If Inst has the specified Opcode and its operand list prefix matches Ops,
+/// this function returns true and updates Ops, otherwise false is returned and
+/// values of Ops are kept as before matchInst was called.
+///
+/// Please note that while Ops are technically passed by a const reference to
+/// make invocations like `matchInst(MI, Opcode, Imm(42))` possible, all their
+/// fields are marked mut

[llvm-branch-commits] [llvm] [IR] Introduce the `ptrtoaddr` instruction (PR #139357)

2025-05-16 Thread Alexander Richardson via llvm-branch-commits

arichardson wrote:

Should I clang-format the other files that use manual alignment to ensure that 
future additions don't fail the clang-format checker?

https://github.com/llvm/llvm-project/pull/139357
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [WIP] Introduce a G_PTRTOADDR GIsel node (PR #140300)

2025-05-16 Thread Alexander Richardson via llvm-branch-commits

https://github.com/arichardson created 
https://github.com/llvm/llvm-project/pull/140300

None


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: optionally assume auth traps on failure (PR #139778)

2025-05-16 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/139778

>From 1d09633453e148be111d29792ab80a4057c5c196 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 13 May 2025 19:50:41 +0300
Subject: [PATCH] [BOLT] Gadget scanner: optionally assume auth traps on
 failure

On AArch64 it is possible for an auth instruction to either return an
invalid address value on failure (without FEAT_FPAC) or generate an
error (with FEAT_FPAC). It thus may be possible to never emit explicit
pointer checks, if the target CPU is known to support FEAT_FPAC.

This commit implements an --auth-traps-on-failure command line option,
which essentially makes "safe-to-dereference" and "trusted" register
properties identical and disables scanning for authentication oracles
completely.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 112 +++
 .../binary-analysis/AArch64/cmdline-args.test |   1 +
 .../AArch64/gs-pauth-authentication-oracles.s |   6 +-
 .../binary-analysis/AArch64/gs-pauth-calls.s  |   5 +-
 .../AArch64/gs-pauth-debug-output.s   | 177 ++---
 .../AArch64/gs-pauth-jump-table.s |   6 +-
 .../AArch64/gs-pauth-signing-oracles.s|  54 ++---
 .../AArch64/gs-pauth-tail-calls.s | 184 +-
 8 files changed, 318 insertions(+), 227 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index bda971bcd9343..cfe86d32df798 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -14,6 +14,7 @@
 #include "bolt/Passes/PAuthGadgetScanner.h"
 #include "bolt/Core/ParallelUtilities.h"
 #include "bolt/Passes/DataflowAnalysis.h"
+#include "bolt/Utils/CommandLineOpts.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/MC/MCInst.h"
@@ -26,6 +27,11 @@ namespace llvm {
 namespace bolt {
 namespace PAuthGadgetScanner {
 
+static cl::opt AuthTrapsOnFailure(
+"auth-traps-on-failure",
+cl::desc("Assume authentication instructions always trap on failure"),
+cl::cat(opts::BinaryAnalysisCategory));
+
 [[maybe_unused]] static void traceInst(const BinaryContext &BC, StringRef 
Label,
const MCInst &MI) {
   dbgs() << "  " << Label << ": ";
@@ -365,6 +371,34 @@ class SrcSafetyAnalysis {
 return Clobbered;
   }
 
+  std::optional getRegMadeTrustedByChecking(const MCInst &Inst,
+   SrcState Cur) const {
+// This functions cannot return multiple registers. This is never the case
+// on AArch64.
+std::optional RegCheckedByInst =
+BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/false);
+if (RegCheckedByInst && Cur.SafeToDerefRegs[*RegCheckedByInst])
+  return *RegCheckedByInst;
+
+auto It = CheckerSequenceInfo.find(&Inst);
+if (It == CheckerSequenceInfo.end())
+  return std::nullopt;
+
+MCPhysReg RegCheckedBySequence = It->second.first;
+const MCInst *FirstCheckerInst = It->second.second;
+
+// FirstCheckerInst should belong to the same basic block (see the
+// assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
+// deterministically processed a few steps before this instruction.
+const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst);
+
+// The sequence checks the register, but it should be authenticated before.
+if (!StateBeforeChecker.SafeToDerefRegs[RegCheckedBySequence])
+  return std::nullopt;
+
+return RegCheckedBySequence;
+  }
+
   // Returns all registers that can be treated as if they are written by an
   // authentication instruction.
   SmallVector getRegsMadeSafeToDeref(const MCInst &Point,
@@ -387,18 +421,38 @@ class SrcSafetyAnalysis {
 Regs.push_back(DstAndSrc->first);
 }
 
+// Make sure explicit checker sequence keeps register safe-to-dereference
+// when the register would be clobbered according to the regular rules:
+//
+//; LR is safe to dereference here
+//mov   x16, x30  ; start of the sequence, LR is s-t-d right before
+//xpaclri ; clobbers LR, LR is not safe anymore
+//cmp   x30, x16
+//b.eq  1f; end of the sequence: LR is marked as trusted
+//brk   0x1234
+//  1:
+//; at this point LR would be marked as trusted,
+//; but not safe-to-dereference
+//
+// or even just
+//
+//; X1 is safe to dereference here
+//ldr x0, [x1, #8]!
+//; X1 is trusted here, but it was clobbered due to address write-back
+if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur))
+  Regs.push_back(*CheckedReg);
+
 return Regs;
   }
 
   // Returns all registers made trusted by this instruction.
   SmallVector getRegsMadeTrusted(const MCInst &Point,
 const SrcState &Cur) const {
+assert(!AuthTrapsOnFailure &&

[llvm-branch-commits] [AMDGPU] Set AS8 address width to 48 bits (PR #139419)

2025-05-16 Thread Alexander Richardson via llvm-branch-commits

arichardson wrote:

Is there anything else that needs to be changed on this PR?

https://github.com/llvm/llvm-project/pull/139419
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] [HLSL][RootSiganture] Add parsing of new number params in StaticSampler (PR #140291)

2025-05-16 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Finn Plummer (inbelic)


Changes

 - defines in-memory reprsentation of `maxAnisotropy`, `minLOD` and `maxLOD`
 - integrates parsing of these number parameters with their respective, 
`parseUInt` and `parseFloat` respectively
 - adds basic unit tests to demonstrate setting functionality

Part 3 of https://github.com/llvm/llvm-project/issues/126574

---
Full diff: https://github.com/llvm/llvm-project/pull/140291.diff


6 Files Affected:

- (modified) clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def (+3) 
- (modified) clang/include/clang/Parse/ParseHLSLRootSignature.h (+3) 
- (modified) clang/lib/Parse/ParseHLSLRootSignature.cpp (+60) 
- (modified) clang/unittests/Lex/LexHLSLRootSignatureTest.cpp (+1-1) 
- (modified) clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp (+20-2) 
- (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h (+3) 


``diff
diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def 
b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index 5d16eaa5b72f6..7ca131349fed4 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -102,6 +102,9 @@ KEYWORD(offset)
 
 // StaticSampler Keywords:
 KEYWORD(mipLODBias)
+KEYWORD(maxAnisotropy)
+KEYWORD(minLOD)
+KEYWORD(maxLOD)
 
 // Unbounded Enum:
 UNBOUNDED_ENUM(unbounded, "unbounded")
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index c12b022a030ef..e62d5de948a44 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -112,6 +112,9 @@ class RootSignatureParser {
   struct ParsedStaticSamplerParams {
 std::optional Reg;
 std::optional MipLODBias;
+std::optional MaxAnisotropy;
+std::optional MinLOD;
+std::optional MaxLOD;
   };
   std::optional parseStaticSamplerParams();
 
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index db2e922160062..04fe8d00f25cd 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -384,6 +384,15 @@ std::optional 
RootSignatureParser::parseStaticSampler() {
   if (Params->MipLODBias.has_value())
 Sampler.MipLODBias = Params->MipLODBias.value();
 
+  if (Params->MaxAnisotropy.has_value())
+Sampler.MaxAnisotropy = Params->MaxAnisotropy.value();
+
+  if (Params->MinLOD.has_value())
+Sampler.MinLOD = Params->MinLOD.value();
+
+  if (Params->MaxLOD.has_value())
+Sampler.MaxLOD = Params->MaxLOD.value();
+
   if (consumeExpectedToken(TokenKind::pu_r_paren,
diag::err_hlsl_unexpected_end_of_params,
/*param of=*/TokenKind::kw_StaticSampler))
@@ -686,6 +695,57 @@ RootSignatureParser::parseStaticSamplerParams() {
 return std::nullopt;
   Params.MipLODBias = (float)*MipLODBias;
 }
+
+// `maxAnisotropy` `=` POS_INT
+if (tryConsumeExpectedToken(TokenKind::kw_maxAnisotropy)) {
+  if (Params.MaxAnisotropy.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto MaxAnisotropy = parseUIntParam();
+  if (!MaxAnisotropy.has_value())
+return std::nullopt;
+  Params.MaxAnisotropy = MaxAnisotropy;
+}
+
+// `minLOD` `=` NUMBER
+if (tryConsumeExpectedToken(TokenKind::kw_minLOD)) {
+  if (Params.MinLOD.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto MinLOD = parseFloatParam();
+  if (!MinLOD.has_value())
+return std::nullopt;
+  Params.MinLOD = MinLOD;
+}
+
+// `maxLOD` `=` NUMBER
+if (tryConsumeExpectedToken(TokenKind::kw_maxLOD)) {
+  if (Params.MaxLOD.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto MaxLOD = parseFloatParam();
+  if (!MaxLOD.has_value())
+return std::nullopt;
+  Params.MaxLOD = MaxLOD;
+}
   } while (tryConsumeExpectedToken(TokenKind::pu_comma));
 
   return Params;
diff --git a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp 
b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
index b610b8f10f8da..575a97e75a05d 100644
--- a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
@@ -136,7 +136,7 @@ TEST_F(LexHLSLRootSignature

[llvm-branch-commits] [clang] [llvm] [HLSL][RootSiganture] Add parsing of new number params in StaticSampler (PR #140291)

2025-05-16 Thread Finn Plummer via llvm-branch-commits

https://github.com/inbelic created 
https://github.com/llvm/llvm-project/pull/140291

 - defines in-memory reprsentation of `maxAnisotropy`, `minLOD` and `maxLOD`
 - integrates parsing of these number parameters with their respective, 
`parseUInt` and `parseFloat` respectively
 - adds basic unit tests to demonstrate setting functionality

Part 3 of https://github.com/llvm/llvm-project/issues/126574



  



Rate limit · GitHub


  body {
background-color: #f6f8fa;
color: #24292e;
font-family: -apple-system,BlinkMacSystemFont,Segoe 
UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
font-size: 14px;
line-height: 1.5;
margin: 0;
  }

  .container { margin: 50px auto; max-width: 600px; text-align: center; 
padding: 0 24px; }

  a { color: #0366d6; text-decoration: none; }
  a:hover { text-decoration: underline; }

  h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; 
text-shadow: 0 1px 0 #fff; }
  p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; }

  ul { list-style: none; margin: 25px 0; padding: 0; }
  li { display: table-cell; font-weight: bold; width: 1%; }

  .logo { display: inline-block; margin-top: 35px; }
  .logo-img-2x { display: none; }
  @media
  only screen and (-webkit-min-device-pixel-ratio: 2),
  only screen and (   min--moz-device-pixel-ratio: 2),
  only screen and ( -o-min-device-pixel-ratio: 2/1),
  only screen and (min-device-pixel-ratio: 2),
  only screen and (min-resolution: 192dpi),
  only screen and (min-resolution: 2dppx) {
.logo-img-1x { display: none; }
.logo-img-2x { display: inline-block; }
  }

  #suggestions {
margin-top: 35px;
color: #ccc;
  }
  #suggestions a {
color: #66;
font-weight: 200;
font-size: 14px;
margin: 0 10px;
  }


  
  



  Whoa there!
  You have exceeded a secondary rate limit.
Please wait a few minutes before you try again;
in some cases this may take up to an hour.
  
  
https://support.github.com/contact";>Contact Support —
https://githubstatus.com";>GitHub Status —
https://twitter.com/githubstatus";>@githubstatus
  

  

  

  

  

  


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] [HLSL][RootSiganture] Add parsing of address params in StaticSampler (PR #140293)

2025-05-16 Thread Finn Plummer via llvm-branch-commits

https://github.com/inbelic created 
https://github.com/llvm/llvm-project/pull/140293

 - defines in-memory reprsentation of `address[U|V|W]`
 - defines parsing of the `TextureAddressMode` enum
 - integrates parsing of these number parameters with their respective, 
`parseTextureAddressMode`
 - adds basic unit tests to demonstrate setting functionality

Part 4 of https://github.com/llvm/llvm-project/issues/126574



  



Rate limit · GitHub


  body {
background-color: #f6f8fa;
color: #24292e;
font-family: -apple-system,BlinkMacSystemFont,Segoe 
UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
font-size: 14px;
line-height: 1.5;
margin: 0;
  }

  .container { margin: 50px auto; max-width: 600px; text-align: center; 
padding: 0 24px; }

  a { color: #0366d6; text-decoration: none; }
  a:hover { text-decoration: underline; }

  h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; 
text-shadow: 0 1px 0 #fff; }
  p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; }

  ul { list-style: none; margin: 25px 0; padding: 0; }
  li { display: table-cell; font-weight: bold; width: 1%; }

  .logo { display: inline-block; margin-top: 35px; }
  .logo-img-2x { display: none; }
  @media
  only screen and (-webkit-min-device-pixel-ratio: 2),
  only screen and (   min--moz-device-pixel-ratio: 2),
  only screen and ( -o-min-device-pixel-ratio: 2/1),
  only screen and (min-device-pixel-ratio: 2),
  only screen and (min-resolution: 192dpi),
  only screen and (min-resolution: 2dppx) {
.logo-img-1x { display: none; }
.logo-img-2x { display: inline-block; }
  }

  #suggestions {
margin-top: 35px;
color: #ccc;
  }
  #suggestions a {
color: #66;
font-weight: 200;
font-size: 14px;
margin: 0 10px;
  }


  
  



  Whoa there!
  You have exceeded a secondary rate limit.
Please wait a few minutes before you try again;
in some cases this may take up to an hour.
  
  
https://support.github.com/contact";>Contact Support —
https://githubstatus.com";>GitHub Status —
https://twitter.com/githubstatus";>@githubstatus
  

  

  

  

  

  


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] [HLSL][RootSiganture] Add parsing of address params in StaticSampler (PR #140293)

2025-05-16 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Finn Plummer (inbelic)


Changes

 - defines in-memory reprsentation of `address[U|V|W]`
 - defines parsing of the `TextureAddressMode` enum
 - integrates parsing of these number parameters with their respective, 
`parseTextureAddressMode`
 - adds basic unit tests to demonstrate setting functionality

Part 4 of https://github.com/llvm/llvm-project/issues/126574

---
Full diff: https://github.com/llvm/llvm-project/pull/140293.diff


6 Files Affected:

- (modified) clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def (+14) 
- (modified) clang/include/clang/Parse/ParseHLSLRootSignature.h (+5) 
- (modified) clang/lib/Parse/ParseHLSLRootSignature.cpp (+86) 
- (modified) clang/unittests/Lex/LexHLSLRootSignatureTest.cpp (+8-1) 
- (modified) clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp (+9-1) 
- (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h (+11) 


``diff
diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def 
b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index 7ca131349fed4..9b47ec57f541b 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -53,6 +53,9 @@
 #ifndef SHADER_VISIBILITY_ENUM
 #define SHADER_VISIBILITY_ENUM(NAME, LIT) ENUM(NAME, LIT)
 #endif
+#ifndef TEXTURE_ADDRESS_MODE_ENUM
+#define TEXTURE_ADDRESS_MODE_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
 
 // General Tokens:
 TOK(invalid, "invalid identifier")
@@ -102,6 +105,9 @@ KEYWORD(offset)
 
 // StaticSampler Keywords:
 KEYWORD(mipLODBias)
+KEYWORD(addressU)
+KEYWORD(addressV)
+KEYWORD(addressW)
 KEYWORD(maxAnisotropy)
 KEYWORD(minLOD)
 KEYWORD(maxLOD)
@@ -148,6 +154,14 @@ SHADER_VISIBILITY_ENUM(Pixel, "SHADER_VISIBILITY_PIXEL")
 SHADER_VISIBILITY_ENUM(Amplification, "SHADER_VISIBILITY_AMPLIFICATION")
 SHADER_VISIBILITY_ENUM(Mesh, "SHADER_VISIBILITY_MESH")
 
+// Texture Address Mode Enums:
+TEXTURE_ADDRESS_MODE_ENUM(Wrap, "TEXTURE_ADDRESS_WRAP")
+TEXTURE_ADDRESS_MODE_ENUM(Mirror, "TEXTURE_ADDRESS_MIRROR")
+TEXTURE_ADDRESS_MODE_ENUM(Clamp, "TEXTURE_ADDRESS_CLAMP")
+TEXTURE_ADDRESS_MODE_ENUM(Border, "TEXTURE_ADDRESS_BORDER")
+TEXTURE_ADDRESS_MODE_ENUM(MirrorOnce, "TEXTURE_ADDRESS_MIRRORONCE")
+
+#undef TEXTURE_ADDRESS_MODE_ENUM
 #undef SHADER_VISIBILITY_ENUM
 #undef DESCRIPTOR_RANGE_FLAG_ENUM
 #undef DESCRIPTOR_RANGE_FLAG_ENUM_OFF
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index e62d5de948a44..9fb542ac7f163 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -112,6 +112,9 @@ class RootSignatureParser {
   struct ParsedStaticSamplerParams {
 std::optional Reg;
 std::optional MipLODBias;
+std::optional AddressU;
+std::optional AddressV;
+std::optional AddressW;
 std::optional MaxAnisotropy;
 std::optional MinLOD;
 std::optional MaxLOD;
@@ -125,6 +128,8 @@ class RootSignatureParser {
 
   /// Parsing methods of various enums
   std::optional parseShaderVisibility();
+  std::optional
+  parseTextureAddressMode();
   std::optional
   parseRootDescriptorFlags();
   std::optional
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 04fe8d00f25cd..0268426133e5f 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -381,6 +381,15 @@ std::optional 
RootSignatureParser::parseStaticSampler() {
   Sampler.Reg = Params->Reg.value();
 
   // Fill in optional values
+  if (Params->AddressU.has_value())
+Sampler.AddressU = Params->AddressU.value();
+
+  if (Params->AddressV.has_value())
+Sampler.AddressV = Params->AddressV.value();
+
+  if (Params->AddressW.has_value())
+Sampler.AddressW = Params->AddressW.value();
+
   if (Params->MipLODBias.has_value())
 Sampler.MipLODBias = Params->MipLODBias.value();
 
@@ -679,6 +688,57 @@ RootSignatureParser::parseStaticSamplerParams() {
   Params.Reg = Reg;
 }
 
+// `addressU` `=` TEXTURE_ADDRESS
+if (tryConsumeExpectedToken(TokenKind::kw_addressU)) {
+  if (Params.AddressU.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equal))
+return std::nullopt;
+
+  auto AddressU = parseTextureAddressMode();
+  if (!AddressU.has_value())
+return std::nullopt;
+  Params.AddressU = AddressU;
+}
+
+// `addressV` `=` TEXTURE_ADDRESS
+if (tryConsumeExpectedToken(TokenKind::kw_addressV)) {
+  if (Params.AddressV.has_value()) {
+getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+<< CurToken.TokKind;
+return std::nullopt;
+  }
+
+  if (consumeExpectedToken(TokenKind::pu_equ

[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add parsing of filter enum for StaticSampler (PR #140294)

2025-05-16 Thread Finn Plummer via llvm-branch-commits

https://github.com/inbelic created 
https://github.com/llvm/llvm-project/pull/140294

 - defines in-memory reprsentation of `filter`
 - defines parsing of the `Filter` enum
 - integrates parsing of these number parameters with their respective, 
`parseFilter`
 - adds basic unit tests to demonstrate setting functionality

Part 5 of https://github.com/llvm/llvm-project/issues/126574



  



Rate limit · GitHub


  body {
background-color: #f6f8fa;
color: #24292e;
font-family: -apple-system,BlinkMacSystemFont,Segoe 
UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
font-size: 14px;
line-height: 1.5;
margin: 0;
  }

  .container { margin: 50px auto; max-width: 600px; text-align: center; 
padding: 0 24px; }

  a { color: #0366d6; text-decoration: none; }
  a:hover { text-decoration: underline; }

  h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; 
text-shadow: 0 1px 0 #fff; }
  p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; }

  ul { list-style: none; margin: 25px 0; padding: 0; }
  li { display: table-cell; font-weight: bold; width: 1%; }

  .logo { display: inline-block; margin-top: 35px; }
  .logo-img-2x { display: none; }
  @media
  only screen and (-webkit-min-device-pixel-ratio: 2),
  only screen and (   min--moz-device-pixel-ratio: 2),
  only screen and ( -o-min-device-pixel-ratio: 2/1),
  only screen and (min-device-pixel-ratio: 2),
  only screen and (min-resolution: 192dpi),
  only screen and (min-resolution: 2dppx) {
.logo-img-1x { display: none; }
.logo-img-2x { display: inline-block; }
  }

  #suggestions {
margin-top: 35px;
color: #ccc;
  }
  #suggestions a {
color: #66;
font-weight: 200;
font-size: 14px;
margin: 0 10px;
  }


  
  



  Whoa there!
  You have exceeded a secondary rate limit.
Please wait a few minutes before you try again;
in some cases this may take up to an hour.
  
  
https://support.github.com/contact";>Contact Support —
https://githubstatus.com";>GitHub Status —
https://twitter.com/githubstatus";>@githubstatus
  

  

  

  

  

  


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add parsing of filter enum for StaticSampler (PR #140294)

2025-05-16 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-hlsl

Author: Finn Plummer (inbelic)


Changes

 - defines in-memory reprsentation of `filter`
 - defines parsing of the `Filter` enum
 - integrates parsing of these number parameters with their respective, 
`parseFilter`
 - adds basic unit tests to demonstrate setting functionality

Part 5 of https://github.com/llvm/llvm-project/issues/126574

---
Full diff: https://github.com/llvm/llvm-project/pull/140294.diff


6 Files Affected:

- (modified) clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def (+44-1) 
- (modified) clang/include/clang/Parse/ParseHLSLRootSignature.h (+3-1) 
- (modified) clang/lib/Parse/ParseHLSLRootSignature.cpp (+45) 
- (modified) clang/unittests/Lex/LexHLSLRootSignatureTest.cpp (+39-2) 
- (modified) clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp (+4) 
- (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h (+40) 


``diff
diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def 
b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index 9b47ec57f541b..9515bc7d847fa 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -53,6 +53,9 @@
 #ifndef SHADER_VISIBILITY_ENUM
 #define SHADER_VISIBILITY_ENUM(NAME, LIT) ENUM(NAME, LIT)
 #endif
+#ifndef FILTER_ENUM
+#define FILTER_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
 #ifndef TEXTURE_ADDRESS_MODE_ENUM
 #define TEXTURE_ADDRESS_MODE_ENUM(NAME, LIT) ENUM(NAME, LIT)
 #endif
@@ -104,10 +107,11 @@ KEYWORD(numDescriptors)
 KEYWORD(offset)
 
 // StaticSampler Keywords:
-KEYWORD(mipLODBias)
+KEYWORD(filter)
 KEYWORD(addressU)
 KEYWORD(addressV)
 KEYWORD(addressW)
+KEYWORD(mipLODBias)
 KEYWORD(maxAnisotropy)
 KEYWORD(minLOD)
 KEYWORD(maxLOD)
@@ -154,6 +158,44 @@ SHADER_VISIBILITY_ENUM(Pixel, "SHADER_VISIBILITY_PIXEL")
 SHADER_VISIBILITY_ENUM(Amplification, "SHADER_VISIBILITY_AMPLIFICATION")
 SHADER_VISIBILITY_ENUM(Mesh, "SHADER_VISIBILITY_MESH")
 
+// Filter Enums:
+FILTER_ENUM(MinMagMipPoint, "FILTER_MIN_MAG_MIP_POINT")
+FILTER_ENUM(MinMagPointMipLinear, "FILTER_MIN_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MinPointMagLinearMipPoint, "FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MinPointMagMipLinear, "FILTER_MIN_POINT_MAG_MIP_LINEAR")
+FILTER_ENUM(MinLinearMagMipPoint, "FILTER_MIN_LINEAR_MAG_MIP_POINT")
+FILTER_ENUM(MinLinearMagPointMipLinear, 
"FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MinMagLinearMipPoint, "FILTER_MIN_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MinMagMipLinear, "FILTER_MIN_MAG_MIP_LINEAR")
+FILTER_ENUM(Anisotropic, "FILTER_ANISOTROPIC")
+FILTER_ENUM(ComparisonMinMagMipPoint, "FILTER_COMPARISON_MIN_MAG_MIP_POINT")
+FILTER_ENUM(ComparisonMinMagPointMipLinear, 
"FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(ComparisonMinPointMagLinearMipPoint, 
"FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(ComparisonMinPointMagMipLinear, 
"FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR")
+FILTER_ENUM(ComparisonMinLinearMagMipPoint, 
"FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT")
+FILTER_ENUM(ComparisonMinLinearMagPointMipLinear, 
"FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(ComparisonMinMagLinearMipPoint, 
"FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(ComparisonMinMagMipLinear, "FILTER_COMPARISON_MIN_MAG_MIP_LINEAR")
+FILTER_ENUM(ComparisonAnisotropic, "FILTER_COMPARISON_ANISOTROPIC")
+FILTER_ENUM(MinimumMinMagMipPoint, "FILTER_MINIMUM_MIN_MAG_MIP_POINT")
+FILTER_ENUM(MinimumMinMagPointMipLinear, 
"FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MinimumMinPointMagLinearMipPoint, 
"FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MinimumMinPointMagMipLinear, 
"FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR")
+FILTER_ENUM(MinimumMinLinearMagMipPoint, 
"FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT")
+FILTER_ENUM(MinimumMinLinearMagPointMipLinear, 
"FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MinimumMinMagLinearMipPoint, 
"FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MinimumMinMagMipLinear, "FILTER_MINIMUM_MIN_MAG_MIP_LINEAR")
+FILTER_ENUM(MinimumAnisotropic, "FILTER_MINIMUM_ANISOTROPIC")
+FILTER_ENUM(MaximumMinMagMipPoint, "FILTER_MAXIMUM_MIN_MAG_MIP_POINT")
+FILTER_ENUM(MaximumMinMagPointMipLinear, 
"FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MaximumMinPointMagLinearMipPoint, 
"FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MaximumMinPointMagMipLinear, 
"FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR")
+FILTER_ENUM(MaximumMinLinearMagMipPoint, 
"FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT")
+FILTER_ENUM(MaximumMinLinearMagPointMipLinear, 
"FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MaximumMinMagLinearMipPoint, 
"FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MaximumMinMagMipLinear, "FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR")
+FILTER_ENUM(MaximumAnisotropic, "FILTER_MAXIMUM_ANISOTROPIC")
+
 // Texture Address Mode Enums:
 TEXTURE_ADDRESS_MODE_ENUM(Wrap, "TEXTURE_AD

[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add parsing of filter enum for StaticSampler (PR #140294)

2025-05-16 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Finn Plummer (inbelic)


Changes

 - defines in-memory reprsentation of `filter`
 - defines parsing of the `Filter` enum
 - integrates parsing of these number parameters with their respective, 
`parseFilter`
 - adds basic unit tests to demonstrate setting functionality

Part 5 of https://github.com/llvm/llvm-project/issues/126574

---
Full diff: https://github.com/llvm/llvm-project/pull/140294.diff


6 Files Affected:

- (modified) clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def (+44-1) 
- (modified) clang/include/clang/Parse/ParseHLSLRootSignature.h (+3-1) 
- (modified) clang/lib/Parse/ParseHLSLRootSignature.cpp (+45) 
- (modified) clang/unittests/Lex/LexHLSLRootSignatureTest.cpp (+39-2) 
- (modified) clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp (+4) 
- (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h (+40) 


``diff
diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def 
b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index 9b47ec57f541b..9515bc7d847fa 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -53,6 +53,9 @@
 #ifndef SHADER_VISIBILITY_ENUM
 #define SHADER_VISIBILITY_ENUM(NAME, LIT) ENUM(NAME, LIT)
 #endif
+#ifndef FILTER_ENUM
+#define FILTER_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
 #ifndef TEXTURE_ADDRESS_MODE_ENUM
 #define TEXTURE_ADDRESS_MODE_ENUM(NAME, LIT) ENUM(NAME, LIT)
 #endif
@@ -104,10 +107,11 @@ KEYWORD(numDescriptors)
 KEYWORD(offset)
 
 // StaticSampler Keywords:
-KEYWORD(mipLODBias)
+KEYWORD(filter)
 KEYWORD(addressU)
 KEYWORD(addressV)
 KEYWORD(addressW)
+KEYWORD(mipLODBias)
 KEYWORD(maxAnisotropy)
 KEYWORD(minLOD)
 KEYWORD(maxLOD)
@@ -154,6 +158,44 @@ SHADER_VISIBILITY_ENUM(Pixel, "SHADER_VISIBILITY_PIXEL")
 SHADER_VISIBILITY_ENUM(Amplification, "SHADER_VISIBILITY_AMPLIFICATION")
 SHADER_VISIBILITY_ENUM(Mesh, "SHADER_VISIBILITY_MESH")
 
+// Filter Enums:
+FILTER_ENUM(MinMagMipPoint, "FILTER_MIN_MAG_MIP_POINT")
+FILTER_ENUM(MinMagPointMipLinear, "FILTER_MIN_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MinPointMagLinearMipPoint, "FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MinPointMagMipLinear, "FILTER_MIN_POINT_MAG_MIP_LINEAR")
+FILTER_ENUM(MinLinearMagMipPoint, "FILTER_MIN_LINEAR_MAG_MIP_POINT")
+FILTER_ENUM(MinLinearMagPointMipLinear, 
"FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MinMagLinearMipPoint, "FILTER_MIN_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MinMagMipLinear, "FILTER_MIN_MAG_MIP_LINEAR")
+FILTER_ENUM(Anisotropic, "FILTER_ANISOTROPIC")
+FILTER_ENUM(ComparisonMinMagMipPoint, "FILTER_COMPARISON_MIN_MAG_MIP_POINT")
+FILTER_ENUM(ComparisonMinMagPointMipLinear, 
"FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(ComparisonMinPointMagLinearMipPoint, 
"FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(ComparisonMinPointMagMipLinear, 
"FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR")
+FILTER_ENUM(ComparisonMinLinearMagMipPoint, 
"FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT")
+FILTER_ENUM(ComparisonMinLinearMagPointMipLinear, 
"FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(ComparisonMinMagLinearMipPoint, 
"FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(ComparisonMinMagMipLinear, "FILTER_COMPARISON_MIN_MAG_MIP_LINEAR")
+FILTER_ENUM(ComparisonAnisotropic, "FILTER_COMPARISON_ANISOTROPIC")
+FILTER_ENUM(MinimumMinMagMipPoint, "FILTER_MINIMUM_MIN_MAG_MIP_POINT")
+FILTER_ENUM(MinimumMinMagPointMipLinear, 
"FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MinimumMinPointMagLinearMipPoint, 
"FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MinimumMinPointMagMipLinear, 
"FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR")
+FILTER_ENUM(MinimumMinLinearMagMipPoint, 
"FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT")
+FILTER_ENUM(MinimumMinLinearMagPointMipLinear, 
"FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MinimumMinMagLinearMipPoint, 
"FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MinimumMinMagMipLinear, "FILTER_MINIMUM_MIN_MAG_MIP_LINEAR")
+FILTER_ENUM(MinimumAnisotropic, "FILTER_MINIMUM_ANISOTROPIC")
+FILTER_ENUM(MaximumMinMagMipPoint, "FILTER_MAXIMUM_MIN_MAG_MIP_POINT")
+FILTER_ENUM(MaximumMinMagPointMipLinear, 
"FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MaximumMinPointMagLinearMipPoint, 
"FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MaximumMinPointMagMipLinear, 
"FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR")
+FILTER_ENUM(MaximumMinLinearMagMipPoint, 
"FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT")
+FILTER_ENUM(MaximumMinLinearMagPointMipLinear, 
"FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR")
+FILTER_ENUM(MaximumMinMagLinearMipPoint, 
"FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT")
+FILTER_ENUM(MaximumMinMagMipLinear, "FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR")
+FILTER_ENUM(MaximumAnisotropic, "FILTER_MAXIMUM_ANISOTROPIC")
+
 // Texture Address Mode Enums:
 TEXTURE_ADDRESS_MODE_ENUM(Wrap, "TEXTURE_A

[llvm-branch-commits] [NFC] Run code formatter on Diagnostic.h/cpp ProfileList.cpp SpecialCaseList.cpp (PR #140295)

2025-05-16 Thread via llvm-branch-commits

llvmbot wrote:



@llvm/pr-subscribers-llvm-support

@llvm/pr-subscribers-clang

Author: Qinkun Bao (qinkunbao)


Changes



---

Patch is 24.81 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/140295.diff


4 Files Affected:

- (modified) clang/include/clang/Basic/Diagnostic.h (+29-37) 
- (modified) clang/lib/Basic/Diagnostic.cpp (+78-70) 
- (modified) clang/lib/Basic/ProfileList.cpp (+2-3) 
- (modified) llvm/lib/Support/SpecialCaseList.cpp (+4-2) 


``diff
diff --git a/clang/include/clang/Basic/Diagnostic.h 
b/clang/include/clang/Basic/Diagnostic.h
index 0ba4edcc5d54c..49ef22d4e4eb6 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -92,18 +92,15 @@ class FixItHint {
   /// modification is known.
   FixItHint() = default;
 
-  bool isNull() const {
-return !RemoveRange.isValid();
-  }
+  bool isNull() const { return !RemoveRange.isValid(); }
 
   /// Create a code modification hint that inserts the given
   /// code string at a specific location.
-  static FixItHint CreateInsertion(SourceLocation InsertionLoc,
-   StringRef Code,
+  static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code,
bool BeforePreviousInsertions = false) {
 FixItHint Hint;
 Hint.RemoveRange =
-  CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
+CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
 Hint.CodeToInsert = std::string(Code);
 Hint.BeforePreviousInsertions = BeforePreviousInsertions;
 return Hint;
@@ -111,12 +108,13 @@ class FixItHint {
 
   /// Create a code modification hint that inserts the given
   /// code from \p FromRange at a specific location.
-  static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
-CharSourceRange FromRange,
-bool BeforePreviousInsertions = false) 
{
+  static FixItHint
+  CreateInsertionFromRange(SourceLocation InsertionLoc,
+   CharSourceRange FromRange,
+   bool BeforePreviousInsertions = false) {
 FixItHint Hint;
 Hint.RemoveRange =
-  CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
+CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
 Hint.InsertFromRange = FromRange;
 Hint.BeforePreviousInsertions = BeforePreviousInsertions;
 return Hint;
@@ -143,8 +141,7 @@ class FixItHint {
 return Hint;
   }
 
-  static FixItHint CreateReplacement(SourceRange RemoveRange,
- StringRef Code) {
+  static FixItHint CreateReplacement(SourceRange RemoveRange, StringRef Code) {
 return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), 
Code);
   }
 };
@@ -553,13 +550,11 @@ class DiagnosticsEngine : public 
RefCountedBase {
   /// avoid redundancy across arguments.
   ///
   /// This is a hack to avoid a layering violation between libbasic and 
libsema.
-  using ArgToStringFnTy = void (*)(
-  ArgumentKind Kind, intptr_t Val,
-  StringRef Modifier, StringRef Argument,
-  ArrayRef PrevArgs,
-  SmallVectorImpl &Output,
-  void *Cookie,
-  ArrayRef QualTypeVals);
+  using ArgToStringFnTy = void (*)(ArgumentKind Kind, intptr_t Val,
+   StringRef Modifier, StringRef Argument,
+   ArrayRef PrevArgs,
+   SmallVectorImpl &Output, void *Cookie,
+   ArrayRef QualTypeVals);
 
   void *ArgToStringCookie = nullptr;
   ArgToStringFnTy ArgToStringFn;
@@ -656,9 +651,7 @@ class DiagnosticsEngine : public 
RefCountedBase {
 
   /// Retrieve the maximum number of template instantiation
   /// notes to emit along with a given diagnostic.
-  unsigned getTemplateBacktraceLimit() const {
-return TemplateBacktraceLimit;
-  }
+  unsigned getTemplateBacktraceLimit() const { return TemplateBacktraceLimit; }
 
   /// Specify the maximum number of constexpr evaluation
   /// notes to emit along with a given diagnostic.
@@ -744,9 +737,7 @@ class DiagnosticsEngine : public 
RefCountedBase {
   /// fails.
   ///
   /// By default, we show all candidates.
-  void setShowOverloads(OverloadsShown Val) {
-ShowOverloads = Val;
-  }
+  void setShowOverloads(OverloadsShown Val) { ShowOverloads = Val; }
   OverloadsShown getShowOverloads() const { return ShowOverloads; }
 
   /// When a call or operator fails, print out up to this many candidate
@@ -885,9 +876,7 @@ class DiagnosticsEngine : public 
RefCountedBase {
   unsigned getNumErrors() const { return NumErrors; }
   unsigned getNumWarnings() const { return NumWarnings; }
 
-  void setNumWarnings(unsigned NumWarnings) {
-this->NumWarnings = NumWarnings;
-  }
+  void setNumWarnings(unsigned NumWarnings) { this->NumWarnings = NumWarnings; 
}
 
   /

[llvm-branch-commits] [NFC] Run code formatter on Diagnostic.h/cpp ProfileList.cpp SpecialCaseList.cpp (PR #140295)

2025-05-16 Thread Qinkun Bao via llvm-branch-commits

https://github.com/qinkunbao created 
https://github.com/llvm/llvm-project/pull/140295

None



  



Rate limit · GitHub


  body {
background-color: #f6f8fa;
color: #24292e;
font-family: -apple-system,BlinkMacSystemFont,Segoe 
UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
font-size: 14px;
line-height: 1.5;
margin: 0;
  }

  .container { margin: 50px auto; max-width: 600px; text-align: center; 
padding: 0 24px; }

  a { color: #0366d6; text-decoration: none; }
  a:hover { text-decoration: underline; }

  h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; 
text-shadow: 0 1px 0 #fff; }
  p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; }

  ul { list-style: none; margin: 25px 0; padding: 0; }
  li { display: table-cell; font-weight: bold; width: 1%; }

  .logo { display: inline-block; margin-top: 35px; }
  .logo-img-2x { display: none; }
  @media
  only screen and (-webkit-min-device-pixel-ratio: 2),
  only screen and (   min--moz-device-pixel-ratio: 2),
  only screen and ( -o-min-device-pixel-ratio: 2/1),
  only screen and (min-device-pixel-ratio: 2),
  only screen and (min-resolution: 192dpi),
  only screen and (min-resolution: 2dppx) {
.logo-img-1x { display: none; }
.logo-img-2x { display: inline-block; }
  }

  #suggestions {
margin-top: 35px;
color: #ccc;
  }
  #suggestions a {
color: #66;
font-weight: 200;
font-size: 14px;
margin: 0 10px;
  }


  
  



  Whoa there!
  You have exceeded a secondary rate limit.
Please wait a few minutes before you try again;
in some cases this may take up to an hour.
  
  
https://support.github.com/contact";>Contact Support —
https://githubstatus.com";>GitHub Status —
https://twitter.com/githubstatus";>@githubstatus
  

  

  

  

  

  


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


  1   2   >