[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

2025-03-12 Thread Alex Sepkowski via cfe-commits


@@ -89,14 +99,57 @@ llvm::TargetExtType 
*HLSLBufferLayoutBuilder::createLayoutType(
 RecordTypes.pop_back();
 
 for (const auto *FD : RT->getDecl()->fields()) {
-  assert((!Packoffsets || Index < Packoffsets->size()) &&
- "number of elements in layout struct does not "
- "match number of packoffset annotations");
+  unsigned FieldOffset = UINT_MAX;
+  llvm::Type *FieldType = nullptr;
+
+  if (Packoffsets) {
+// have packoffset/register(c#) annotations
+assert(Index < Packoffsets->size() &&
+   "number of elements in layout struct does not match number of "
+   "packoffset annotations");
+int PO = (*Packoffsets)[Index++];
+if (PO != -1) {
+  if (!layoutField(FD, EndOffset, FieldOffset, FieldType, PO))
+return nullptr;
+} else {
+  // No packoffset/register(cX) annotation on this field;
+  // Delay the layout until after all of the other elements
+  // annotated with packoffsets/register(cX) are processed.
+  DelayLayoutFields.emplace_back(FD, LayoutElements.size());
+  // reserve space for this field in the layout vector and elements 
list
+  Layout.push_back(UINT_MAX);
+  LayoutElements.push_back(nullptr);
+  continue;
+}
+  } else {
+if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
+  return nullptr;
+  }
+
+  assert(FieldOffset != UINT_MAX && FieldType != nullptr);
+  Layout.push_back((unsigned)FieldOffset);

alsepkow wrote:

Left over cast from a previous revision? Layout contains unsigned ints.

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


[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

2025-03-12 Thread Alex Sepkowski via cfe-commits


@@ -174,21 +176,45 @@ createBufferHandleType(const HLSLBufferDecl *BufDecl) {
   return cast(QT.getTypePtr());
 }
 
+// Iterates over all declarations in the HLSL buffer and based on the
+// packoffset or register(c#) annotations it fills outs the Layout
+// vector with the user-specified layout offsets.
+// The buffer offsets can be specified 2 ways:
+// 1. declarations in cbuffer {} block can have a packoffset annotation
+//(translates to HLSLPackOffsetAttr)
+// 2. default constant buffer declarations at global scope can have
+//register(c#) annotations (translates to HLSLResourceBindingAttr with
+//RegisterType::C)
+// It is not guaranteed that all declarations in a buffer have an annotation.
+// For those where it is not specified a -1 value is added to the Layout
+// vector. In the final layout these declarations will be placed at the end
+// of the HLSL buffer after all of the elements with specified offset.
 static void fillPackoffsetLayout(const HLSLBufferDecl *BufDecl,
- SmallVector &Layout) {
+ SmallVector &Layout) {
   assert(Layout.empty() && "expected empty vector for layout");
   assert(BufDecl->hasValidPackoffset());
 
-  for (Decl *D : BufDecl->decls()) {
+  for (Decl *D : BufDecl->buffer_decls()) {

alsepkow wrote:

nit: On formatting, it sounds like the llvm repo prefers 'auto *name' for for 
loops? 

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


[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

2025-03-12 Thread Alex Sepkowski via cfe-commits


@@ -174,21 +176,45 @@ createBufferHandleType(const HLSLBufferDecl *BufDecl) {
   return cast(QT.getTypePtr());
 }
 
+// Iterates over all declarations in the HLSL buffer and based on the
+// packoffset or register(c#) annotations it fills outs the Layout

alsepkow wrote:

Found it 🥳
[dx-graphics-hlsl-variable-register](https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-variable-register
 )

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


[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

2025-03-12 Thread Alex Sepkowski via cfe-commits


@@ -174,21 +176,45 @@ createBufferHandleType(const HLSLBufferDecl *BufDecl) {
   return cast(QT.getTypePtr());
 }
 
+// Iterates over all declarations in the HLSL buffer and based on the
+// packoffset or register(c#) annotations it fills outs the Layout
+// vector with the user-specified layout offsets.
+// The buffer offsets can be specified 2 ways:
+// 1. declarations in cbuffer {} block can have a packoffset annotation
+//(translates to HLSLPackOffsetAttr)
+// 2. default constant buffer declarations at global scope can have
+//register(c#) annotations (translates to HLSLResourceBindingAttr with
+//RegisterType::C)
+// It is not guaranteed that all declarations in a buffer have an annotation.
+// For those where it is not specified a -1 value is added to the Layout
+// vector. In the final layout these declarations will be placed at the end
+// of the HLSL buffer after all of the elements with specified offset.
 static void fillPackoffsetLayout(const HLSLBufferDecl *BufDecl,
- SmallVector &Layout) {
+ SmallVector &Layout) {
   assert(Layout.empty() && "expected empty vector for layout");
   assert(BufDecl->hasValidPackoffset());
 
-  for (Decl *D : BufDecl->decls()) {
+  for (Decl *D : BufDecl->buffer_decls()) {
 if (isa(D) || isa(D)) {
   continue;
 }
 VarDecl *VD = dyn_cast(D);
 if (!VD || VD->getType().getAddressSpace() != LangAS::hlsl_constant)
   continue;
-assert(VD->hasAttr() &&
-   "expected packoffset attribute on every declaration");
-size_t Offset = VD->getAttr()->getOffsetInBytes();
+size_t Offset = -1;

alsepkow wrote:

size_t is unsigned. You should use something like SIZE_MAX instead. Or 0?

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


[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

2025-03-12 Thread Alex Sepkowski via cfe-commits


@@ -89,14 +99,57 @@ llvm::TargetExtType 
*HLSLBufferLayoutBuilder::createLayoutType(
 RecordTypes.pop_back();
 
 for (const auto *FD : RT->getDecl()->fields()) {
-  assert((!Packoffsets || Index < Packoffsets->size()) &&
- "number of elements in layout struct does not "
- "match number of packoffset annotations");
+  unsigned FieldOffset = UINT_MAX;
+  llvm::Type *FieldType = nullptr;
+
+  if (Packoffsets) {
+// have packoffset/register(c#) annotations
+assert(Index < Packoffsets->size() &&
+   "number of elements in layout struct does not match number of "
+   "packoffset annotations");
+int PO = (*Packoffsets)[Index++];

alsepkow wrote:

P0 should be a const, I think? I noticed we don't really use that pattern in 
DXC but it looks like it is used here.

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


[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

2025-03-12 Thread Alex Sepkowski via cfe-commits


@@ -89,14 +99,57 @@ llvm::TargetExtType 
*HLSLBufferLayoutBuilder::createLayoutType(
 RecordTypes.pop_back();
 
 for (const auto *FD : RT->getDecl()->fields()) {
-  assert((!Packoffsets || Index < Packoffsets->size()) &&
- "number of elements in layout struct does not "
- "match number of packoffset annotations");
+  unsigned FieldOffset = UINT_MAX;
+  llvm::Type *FieldType = nullptr;
+
+  if (Packoffsets) {
+// have packoffset/register(c#) annotations
+assert(Index < Packoffsets->size() &&
+   "number of elements in layout struct does not match number of "
+   "packoffset annotations");
+int PO = (*Packoffsets)[Index++];
+if (PO != -1) {
+  if (!layoutField(FD, EndOffset, FieldOffset, FieldType, PO))
+return nullptr;
+} else {
+  // No packoffset/register(cX) annotation on this field;
+  // Delay the layout until after all of the other elements
+  // annotated with packoffsets/register(cX) are processed.
+  DelayLayoutFields.emplace_back(FD, LayoutElements.size());
+  // reserve space for this field in the layout vector and elements 
list
+  Layout.push_back(UINT_MAX);
+  LayoutElements.push_back(nullptr);
+  continue;
+}
+  } else {
+if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
+  return nullptr;
+  }
+
+  assert(FieldOffset != UINT_MAX && FieldType != nullptr);
+  Layout.push_back((unsigned)FieldOffset);
+  LayoutElements.push_back(FieldType);
+}
+  }
 
-  if (!layoutField(FD, EndOffset, Layout, LayoutElements,
-   Packoffsets ? (*Packoffsets)[Index] : -1))
+  // process delayed layouts
+  if (!DelayLayoutFields.empty()) {
+for (auto I : DelayLayoutFields) {
+  const FieldDecl *FD = I.first;
+  unsigned IndexInLayoutElements = I.second;

alsepkow wrote:

const?

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


[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

2025-03-12 Thread Alex Sepkowski via cfe-commits


@@ -89,14 +99,57 @@ llvm::TargetExtType 
*HLSLBufferLayoutBuilder::createLayoutType(
 RecordTypes.pop_back();
 
 for (const auto *FD : RT->getDecl()->fields()) {
-  assert((!Packoffsets || Index < Packoffsets->size()) &&
- "number of elements in layout struct does not "
- "match number of packoffset annotations");
+  unsigned FieldOffset = UINT_MAX;
+  llvm::Type *FieldType = nullptr;
+
+  if (Packoffsets) {
+// have packoffset/register(c#) annotations
+assert(Index < Packoffsets->size() &&
+   "number of elements in layout struct does not match number of "
+   "packoffset annotations");
+int PO = (*Packoffsets)[Index++];
+if (PO != -1) {
+  if (!layoutField(FD, EndOffset, FieldOffset, FieldType, PO))
+return nullptr;
+} else {
+  // No packoffset/register(cX) annotation on this field;
+  // Delay the layout until after all of the other elements
+  // annotated with packoffsets/register(cX) are processed.
+  DelayLayoutFields.emplace_back(FD, LayoutElements.size());
+  // reserve space for this field in the layout vector and elements 
list
+  Layout.push_back(UINT_MAX);
+  LayoutElements.push_back(nullptr);
+  continue;
+}
+  } else {
+if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
+  return nullptr;
+  }
+
+  assert(FieldOffset != UINT_MAX && FieldType != nullptr);
+  Layout.push_back((unsigned)FieldOffset);
+  LayoutElements.push_back(FieldType);
+}
+  }
 
-  if (!layoutField(FD, EndOffset, Layout, LayoutElements,
-   Packoffsets ? (*Packoffsets)[Index] : -1))
+  // process delayed layouts
+  if (!DelayLayoutFields.empty()) {
+for (auto I : DelayLayoutFields) {
+  const FieldDecl *FD = I.first;
+  unsigned IndexInLayoutElements = I.second;
+  // the first item in layout vector is size, so we need to offset the 
index
+  // by 1
+  unsigned IndexInLayout = IndexInLayoutElements + 1;
+  assert(Layout[IndexInLayout] == UINT_MAX &&
+ LayoutElements[IndexInLayoutElements] == nullptr);
+
+  unsigned FieldOffset = UINT_MAX;
+  llvm::Type *FieldType = nullptr;
+  if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
 return nullptr;
-  Index++;
+
+  Layout[IndexInLayout] = (unsigned)FieldOffset;

alsepkow wrote:

Cast no longer needed

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


[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

2025-03-12 Thread Alex Sepkowski via cfe-commits


@@ -58,9 +60,15 @@ namespace CodeGen {
 // classes) and calls layoutField to converts each field to its corresponding
 // LLVM type and to calculate its HLSL constant buffer layout. Any embedded
 // structs (or arrays of structs) are converted to target layout types as well.
+//
+// When Packoffsets are specified the elements will be placed based on the
+// user-specified offsets. Not all elements must have a packoffset/register(c#)
+// annotation though. For those that don't, the Packoffsets array will constain

alsepkow wrote:

nit: typo, 'contain'

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


[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

2025-03-12 Thread Alex Sepkowski via cfe-commits


@@ -174,21 +176,45 @@ createBufferHandleType(const HLSLBufferDecl *BufDecl) {
   return cast(QT.getTypePtr());
 }
 
+// Iterates over all declarations in the HLSL buffer and based on the
+// packoffset or register(c#) annotations it fills outs the Layout

alsepkow wrote:

Just curious, what is 'register(c#)' annotation? I didn't get any hits trying 
to search it online or with copilot.

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


[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

2025-03-12 Thread Alex Sepkowski via cfe-commits


@@ -89,14 +99,57 @@ llvm::TargetExtType 
*HLSLBufferLayoutBuilder::createLayoutType(
 RecordTypes.pop_back();
 
 for (const auto *FD : RT->getDecl()->fields()) {
-  assert((!Packoffsets || Index < Packoffsets->size()) &&
- "number of elements in layout struct does not "
- "match number of packoffset annotations");
+  unsigned FieldOffset = UINT_MAX;
+  llvm::Type *FieldType = nullptr;
+
+  if (Packoffsets) {
+// have packoffset/register(c#) annotations
+assert(Index < Packoffsets->size() &&
+   "number of elements in layout struct does not match number of "
+   "packoffset annotations");
+int PO = (*Packoffsets)[Index++];
+if (PO != -1) {
+  if (!layoutField(FD, EndOffset, FieldOffset, FieldType, PO))
+return nullptr;
+} else {
+  // No packoffset/register(cX) annotation on this field;
+  // Delay the layout until after all of the other elements
+  // annotated with packoffsets/register(cX) are processed.
+  DelayLayoutFields.emplace_back(FD, LayoutElements.size());
+  // reserve space for this field in the layout vector and elements 
list
+  Layout.push_back(UINT_MAX);
+  LayoutElements.push_back(nullptr);
+  continue;
+}
+  } else {
+if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
+  return nullptr;
+  }
+
+  assert(FieldOffset != UINT_MAX && FieldType != nullptr);
+  Layout.push_back((unsigned)FieldOffset);
+  LayoutElements.push_back(FieldType);
+}
+  }
 
-  if (!layoutField(FD, EndOffset, Layout, LayoutElements,
-   Packoffsets ? (*Packoffsets)[Index] : -1))
+  // process delayed layouts
+  if (!DelayLayoutFields.empty()) {
+for (auto I : DelayLayoutFields) {
+  const FieldDecl *FD = I.first;
+  unsigned IndexInLayoutElements = I.second;

alsepkow wrote:

a few other variables in this block could also be const.

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


[clang] [HLSL][NFC] Update HLSL AST tests to be more readable (PR #130910)

2025-03-12 Thread Alex Sepkowski via cfe-commits

https://github.com/alsepkow approved this pull request.

LGTM

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


[clang] [llvm] [HLSL][RootSignature] Add parsing for empty RootParams (PR #140147)

2025-05-15 Thread Alex Sepkowski via cfe-commits


@@ -155,6 +163,41 @@ std::optional 
RootSignatureParser::parseRootConstants() {
   return Constants;
 }
 
+std::optional RootSignatureParser::parseRootParam() {
+  assert((CurToken.TokKind == TokenKind::kw_CBV ||
+  CurToken.TokKind == TokenKind::kw_SRV ||
+  CurToken.TokKind == TokenKind::kw_UAV) &&
+ "Expects to only be invoked starting at given keyword");
+
+  TokenKind ParamKind = CurToken.TokKind;
+
+  if (consumeExpectedToken(TokenKind::pu_l_paren, diag::err_expected_after,
+   CurToken.TokKind))
+return std::nullopt;
+
+  RootParam Param;
+  switch (ParamKind) {
+  default:

alsepkow wrote:

nit: Is there a reason the default case comes first? Just looks weird to me. 
Also why do we need to add llvm_unreachable? The llvm coding standards say 
"-Wswitch " should be enabled. Do we disable it for some reason?

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


[clang] [llvm] [NFC][HLSL][RootSignature] Split up `HLSLRootSignatureUtils` (PR #146124)

2025-07-03 Thread Alex Sepkowski via cfe-commits

https://github.com/alsepkow edited 
https://github.com/llvm/llvm-project/pull/146124
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [NFC][HLSL][RootSignature] Split up `HLSLRootSignatureUtils` (PR #146124)

2025-07-03 Thread Alex Sepkowski via cfe-commits


@@ -0,0 +1,56 @@
+//===- RootSignatureMetadata.h - HLSL Root Signature helpers 
--===//
+//
+// 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
+//
+//===--===//
+///
+/// \file This file contains a library for working with HLSL Root Signatures 
and
+/// their metadata representation.
+///
+//===--===//
+
+#ifndef LLVM_FRONTEND_HLSL_ROOTSIGNATUREMETADATA_H
+#define LLVM_FRONTEND_HLSL_ROOTSIGNATUREMETADATA_H
+
+#include "llvm/Frontend/HLSL/HLSLRootSignature.h"
+
+namespace llvm {
+class LLVMContext;
+class MDNode;
+class Metadata;
+
+namespace hlsl {
+namespace rootsig {
+
+class MetadataBuilder {
+public:
+  MetadataBuilder(llvm::LLVMContext &Ctx, ArrayRef Elements)
+  : Ctx(Ctx), Elements(Elements) {}
+
+  /// Iterates through the elements and dispatches onto the correct Build 
method

alsepkow wrote:

minor nit: 'Build*' method would be clearer to me vs 'Build'

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


[clang] [llvm] [NFC][HLSL][RootSignature] Split up `HLSLRootSignatureUtils` (PR #146124)

2025-07-03 Thread Alex Sepkowski via cfe-commits

https://github.com/alsepkow commented:

LGTM outside of a few minor comments you may choose to address or not.

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


[clang] [llvm] [NFC][HLSL][RootSignature] Split up `HLSLRootSignatureUtils` (PR #146124)

2025-07-03 Thread Alex Sepkowski via cfe-commits


@@ -103,7 +51,7 @@ class ResourceRange {
   getOverlapping(const RangeInfo &Info) const;
 
   // Return the mapped RangeInfo at X or nullptr if no mapping exists
-  LLVM_ABI const RangeInfo *lookup(uint32_t X) const;

alsepkow wrote:

LLVM_ABI no longer needed? 

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


[clang] [llvm] [NFC][HLSL][RootSignature] Split up `HLSLRootSignatureUtils` (PR #146124)

2025-07-03 Thread Alex Sepkowski via cfe-commits


@@ -0,0 +1,194 @@
+//===- RootSignatureMetadata.h - HLSL Root Signature helpers 
--===//
+//
+// 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
+//
+//===--===//
+///
+/// \file This file implements a library for working with HLSL Root Signatures
+/// and their metadata representation.
+///
+//===--===//
+
+#include "llvm/Frontend/HLSL/RootSignatureMetadata.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+namespace llvm {
+namespace hlsl {
+namespace rootsig {
+
+static const EnumEntry ResourceClassNames[] = {
+{"CBV", dxil::ResourceClass::CBuffer},
+{"SRV", dxil::ResourceClass::SRV},
+{"UAV", dxil::ResourceClass::UAV},
+{"Sampler", dxil::ResourceClass::Sampler},
+};
+
+static std::optional getResourceName(dxil::ResourceClass Class) {
+  for (const auto &ClassEnum : ResourceClassNames)
+if (ClassEnum.Value == Class)
+  return ClassEnum.Name;
+  return std::nullopt;
+}
+
+namespace {
+
+// We use the OverloadVisit with std::visit to ensure the compiler catches if a
+// new RootElement variant type is added but it's metadata generation isn't
+// handled.
+template  struct OverloadedVisit : Ts... {
+  using Ts::operator()...;
+};
+template  OverloadedVisit(Ts...) -> OverloadedVisit;
+
+} // namespace
+
+MDNode *MetadataBuilder::BuildRootSignature() {
+  const auto Visitor = OverloadedVisit{
+  [this](const dxbc::RootFlags &Flags) -> MDNode * {
+return BuildRootFlags(Flags);
+  },
+  [this](const RootConstants &Constants) -> MDNode * {
+return BuildRootConstants(Constants);
+  },
+  [this](const RootDescriptor &Descriptor) -> MDNode * {
+return BuildRootDescriptor(Descriptor);
+  },
+  [this](const DescriptorTableClause &Clause) -> MDNode * {
+return BuildDescriptorTableClause(Clause);
+  },
+  [this](const DescriptorTable &Table) -> MDNode * {
+return BuildDescriptorTable(Table);
+  },
+  [this](const StaticSampler &Sampler) -> MDNode * {
+return BuildStaticSampler(Sampler);
+  },
+  };
+
+  for (const RootElement &Element : Elements) {
+MDNode *ElementMD = std::visit(Visitor, Element);
+assert(ElementMD != nullptr &&
+   "Root Element must be initialized and validated");
+GeneratedMetadata.push_back(ElementMD);
+  }
+
+  return MDNode::get(Ctx, GeneratedMetadata);
+}
+
+MDNode *MetadataBuilder::BuildRootFlags(const dxbc::RootFlags &Flags) {
+  IRBuilder<> Builder(Ctx);
+  Metadata *Operands[] = {
+  MDString::get(Ctx, "RootFlags"),
+  ConstantAsMetadata::get(Builder.getInt32(llvm::to_underlying(Flags))),
+  };
+  return MDNode::get(Ctx, Operands);
+}
+
+MDNode *MetadataBuilder::BuildRootConstants(const RootConstants &Constants) {
+  IRBuilder<> Builder(Ctx);
+  Metadata *Operands[] = {
+  MDString::get(Ctx, "RootConstants"),
+  ConstantAsMetadata::get(
+  Builder.getInt32(llvm::to_underlying(Constants.Visibility))),
+  ConstantAsMetadata::get(Builder.getInt32(Constants.Reg.Number)),
+  ConstantAsMetadata::get(Builder.getInt32(Constants.Space)),
+  ConstantAsMetadata::get(Builder.getInt32(Constants.Num32BitConstants)),
+  };
+  return MDNode::get(Ctx, Operands);
+}
+
+MDNode *MetadataBuilder::BuildRootDescriptor(const RootDescriptor &Descriptor) 
{
+  IRBuilder<> Builder(Ctx);
+  std::optional ResName = getResourceName(
+  dxil::ResourceClass(llvm::to_underlying(Descriptor.Type)));
+  assert(ResName && "Provided an invalid Resource Class");
+  llvm::SmallString<7> Name({"Root", *ResName});

alsepkow wrote:

Is 7 a sufficient size here? Copilot tells me this class uses that size for its 
default stack allocation size and falls back to the heap if its larger. Do you 
think it would be worth it to just add a bigger buffer to that to avoid future 
issues? 7 seems really small to me.

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


[clang] Address a handful of C4146 compiler warnings where literals can be replaced with std::numeric_limits (PR #147623)

2025-07-09 Thread Alex Sepkowski via cfe-commits

https://github.com/alsepkow updated 
https://github.com/llvm/llvm-project/pull/147623

>From 7e1c62fce3741b8182db2428c29136524b27b98c Mon Sep 17 00:00:00 2001
From: Alex Sepkowski <5620315+alsep...@users.noreply.github.com>
Date: Tue, 8 Jul 2025 16:17:56 -0700
Subject: [PATCH 1/6] Numeric limits in ExprConstant.cpp

---
 clang/lib/AST/ExprConstant.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 60c658a8d8f99..5d399a3c75ca8 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1428,11 +1428,11 @@ namespace {
 }
 bool destroy(bool RunDestructors = true) {
   bool OK = cleanup(Info, RunDestructors, OldStackSize);
-  OldStackSize = -1U;
+  OldStackSize = std::numeric_limits::max();
   return OK;
 }
 ~ScopeRAII() {
-  if (OldStackSize != -1U)
+  if (OldStackSize != std::numeric_limits::max())
 destroy(false);
   // Body moved to a static method to encourage the compiler to inline away
   // instances of this class.

>From 98197ad801b0647e9b755212fe8b6f7648784ac4 Mon Sep 17 00:00:00 2001
From: Alex Sepkowski <5620315+alsep...@users.noreply.github.com>
Date: Tue, 8 Jul 2025 16:44:39 -0700
Subject: [PATCH 2/6] Numeric limits in Format.cpp

---
 clang/lib/Format/Format.cpp | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index f0412cddc6f19..a8c88c6412805 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -22,6 +22,8 @@
 #include "UnwrappedLineFormatter.h"
 #include "UsingDeclarationsSorter.h"
 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
+
+#include 
 #include "llvm/ADT/Sequence.h"
 
 #define DEBUG_TYPE "format-formatter"
@@ -777,7 +779,7 @@ template <> struct 
MappingTraits {
 IO.mapOptional("Maximum", signedMaximum);
 Space.Maximum = static_cast(signedMaximum);
 
-if (Space.Maximum != -1u)
+if (Space.Maximum != std::numeric_limits::max())
   Space.Minimum = std::min(Space.Minimum, Space.Maximum);
   }
 };
@@ -1672,7 +1674,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind 
Language) {
   LLVMStyle.SpacesBeforeTrailingComments = 1;
   LLVMStyle.SpacesInAngles = FormatStyle::SIAS_Never;
   LLVMStyle.SpacesInContainerLiterals = true;
-  LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u};
+  LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, 
/*Maximum=*/std::numeric_limits::max()};
   LLVMStyle.SpacesInParens = FormatStyle::SIPO_Never;
   LLVMStyle.SpacesInSquareBrackets = false;
   LLVMStyle.Standard = FormatStyle::LS_Latest;

>From a07376154afed4967c652469de3a4ec8ba2be980 Mon Sep 17 00:00:00 2001
From: Alex Sepkowski <5620315+alsep...@users.noreply.github.com>
Date: Tue, 8 Jul 2025 16:46:54 -0700
Subject: [PATCH 3/6] Numeric limits in Lexer.cpp

---
 clang/lib/Lex/Lexer.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 78988e928a689..1f695b4a8676c 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -3456,7 +3457,7 @@ std::optional Lexer::tryReadNumericUCN(const 
char *&StartPtr,
 }
 
 unsigned Value = llvm::hexDigitValue(C);
-if (Value == -1U) {
+if (Value == std::numeric_limits::max()) {
   if (!Delimited)
 break;
   if (Diagnose)

>From 2a479e17aced19aecdb9e0e8085857d060b7fbb2 Mon Sep 17 00:00:00 2001
From: Alex Sepkowski <5620315+alsep...@users.noreply.github.com>
Date: Tue, 8 Jul 2025 16:56:16 -0700
Subject: [PATCH 4/6] Numeric limits in SemaExpr.cpp

---
 clang/lib/Sema/SemaExpr.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3c3d29c415249..2c721e9cf1bd7 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/ASTMutationListener.h"
+#include 
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
@@ -1906,7 +1907,7 @@ ExprResult Sema::CreateGenericSelectionExpr(
   }
 
   SmallVector CompatIndices;
-  unsigned DefaultIndex = -1U;
+  unsigned DefaultIndex = std::numeric_limits::max();
   // Look at the canonical type of the controlling expression in case it was a
   // deduced type like __auto_type. However, when issuing diagnostics, use the
   // type the user wrote in source rather than the canonical one.
@@ -1961,7 +1962,7 @@ ExprResult Sema::CreateGenericSelectionExpr(
   // C11 6.5.1.1p2 "If a generic selection has no default generic association,
   // its controlling expression shall have type compatible with exactly one of
   // the types named in its generic association l

[clang] Address a handful of C4146 compiler warnings where literals can be replaced with std::numeric_limits (PR #147623)

2025-07-09 Thread Alex Sepkowski via cfe-commits

https://github.com/alsepkow updated 
https://github.com/llvm/llvm-project/pull/147623

>From 7e1c62fce3741b8182db2428c29136524b27b98c Mon Sep 17 00:00:00 2001
From: Alex Sepkowski <5620315+alsep...@users.noreply.github.com>
Date: Tue, 8 Jul 2025 16:17:56 -0700
Subject: [PATCH 1/7] Numeric limits in ExprConstant.cpp

---
 clang/lib/AST/ExprConstant.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 60c658a8d8f99..5d399a3c75ca8 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1428,11 +1428,11 @@ namespace {
 }
 bool destroy(bool RunDestructors = true) {
   bool OK = cleanup(Info, RunDestructors, OldStackSize);
-  OldStackSize = -1U;
+  OldStackSize = std::numeric_limits::max();
   return OK;
 }
 ~ScopeRAII() {
-  if (OldStackSize != -1U)
+  if (OldStackSize != std::numeric_limits::max())
 destroy(false);
   // Body moved to a static method to encourage the compiler to inline away
   // instances of this class.

>From 98197ad801b0647e9b755212fe8b6f7648784ac4 Mon Sep 17 00:00:00 2001
From: Alex Sepkowski <5620315+alsep...@users.noreply.github.com>
Date: Tue, 8 Jul 2025 16:44:39 -0700
Subject: [PATCH 2/7] Numeric limits in Format.cpp

---
 clang/lib/Format/Format.cpp | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index f0412cddc6f19..a8c88c6412805 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -22,6 +22,8 @@
 #include "UnwrappedLineFormatter.h"
 #include "UsingDeclarationsSorter.h"
 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
+
+#include 
 #include "llvm/ADT/Sequence.h"
 
 #define DEBUG_TYPE "format-formatter"
@@ -777,7 +779,7 @@ template <> struct 
MappingTraits {
 IO.mapOptional("Maximum", signedMaximum);
 Space.Maximum = static_cast(signedMaximum);
 
-if (Space.Maximum != -1u)
+if (Space.Maximum != std::numeric_limits::max())
   Space.Minimum = std::min(Space.Minimum, Space.Maximum);
   }
 };
@@ -1672,7 +1674,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind 
Language) {
   LLVMStyle.SpacesBeforeTrailingComments = 1;
   LLVMStyle.SpacesInAngles = FormatStyle::SIAS_Never;
   LLVMStyle.SpacesInContainerLiterals = true;
-  LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u};
+  LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, 
/*Maximum=*/std::numeric_limits::max()};
   LLVMStyle.SpacesInParens = FormatStyle::SIPO_Never;
   LLVMStyle.SpacesInSquareBrackets = false;
   LLVMStyle.Standard = FormatStyle::LS_Latest;

>From a07376154afed4967c652469de3a4ec8ba2be980 Mon Sep 17 00:00:00 2001
From: Alex Sepkowski <5620315+alsep...@users.noreply.github.com>
Date: Tue, 8 Jul 2025 16:46:54 -0700
Subject: [PATCH 3/7] Numeric limits in Lexer.cpp

---
 clang/lib/Lex/Lexer.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 78988e928a689..1f695b4a8676c 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -3456,7 +3457,7 @@ std::optional Lexer::tryReadNumericUCN(const 
char *&StartPtr,
 }
 
 unsigned Value = llvm::hexDigitValue(C);
-if (Value == -1U) {
+if (Value == std::numeric_limits::max()) {
   if (!Delimited)
 break;
   if (Diagnose)

>From 2a479e17aced19aecdb9e0e8085857d060b7fbb2 Mon Sep 17 00:00:00 2001
From: Alex Sepkowski <5620315+alsep...@users.noreply.github.com>
Date: Tue, 8 Jul 2025 16:56:16 -0700
Subject: [PATCH 4/7] Numeric limits in SemaExpr.cpp

---
 clang/lib/Sema/SemaExpr.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3c3d29c415249..2c721e9cf1bd7 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/ASTMutationListener.h"
+#include 
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
@@ -1906,7 +1907,7 @@ ExprResult Sema::CreateGenericSelectionExpr(
   }
 
   SmallVector CompatIndices;
-  unsigned DefaultIndex = -1U;
+  unsigned DefaultIndex = std::numeric_limits::max();
   // Look at the canonical type of the controlling expression in case it was a
   // deduced type like __auto_type. However, when issuing diagnostics, use the
   // type the user wrote in source rather than the canonical one.
@@ -1961,7 +1962,7 @@ ExprResult Sema::CreateGenericSelectionExpr(
   // C11 6.5.1.1p2 "If a generic selection has no default generic association,
   // its controlling expression shall have type compatible with exactly one of
   // the types named in its generic association l

[clang] Address a handful of C4146 compiler warnings where literals can be replaced with std::numeric_limits (PR #147623)

2025-07-09 Thread Alex Sepkowski via cfe-commits


@@ -777,7 +779,7 @@ template <> struct 
MappingTraits {
 IO.mapOptional("Maximum", signedMaximum);
 Space.Maximum = static_cast(signedMaximum);
 
-if (Space.Maximum != -1u)
+if (Space.Maximum != std::numeric_limits::max())

alsepkow wrote:

On further consideration, I think it would be cleaner to stay consistent with 
using numeric_limits for all of the updates. And given that there are only a 
handful of UINT_MAX cases in this file I've swapped them to use numeric_limits 
for consistency. That would be the preferred choice if this were new code 
anyways.

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