[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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)
@@ -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)
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)
@@ -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)
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)
@@ -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)
@@ -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)
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)
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)
@@ -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