aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/Decl.h30
-rw-r--r--clang/include/clang/Sema/SemaHLSL.h7
-rw-r--r--clang/lib/AST/Decl.cpp36
-rw-r--r--clang/lib/CodeGen/CGHLSLRuntime.cpp2
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp5
-rw-r--r--clang/lib/Sema/Sema.cpp3
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp45
-rw-r--r--clang/test/AST/HLSL/default_cbuffer.hlsl50
-rw-r--r--clang/test/CodeGenHLSL/basic_types.hlsl64
-rw-r--r--clang/test/CodeGenHLSL/default_cbuffer.hlsl39
10 files changed, 41 insertions, 240 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 86e6d14..0f96bf0 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -5045,11 +5045,6 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext {
// LayoutStruct - Layout struct for the buffer
CXXRecordDecl *LayoutStruct;
- // For default (implicit) constant buffer, a lisf of references of global
- // decls that belong to the buffer. The decls are already parented by the
- // translation unit context.
- SmallVector<Decl *> DefaultBufferDecls;
-
HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc,
IdentifierInfo *ID, SourceLocation IDLoc,
SourceLocation LBrace);
@@ -5059,8 +5054,6 @@ public:
bool CBuffer, SourceLocation KwLoc,
IdentifierInfo *ID, SourceLocation IDLoc,
SourceLocation LBrace);
- static HLSLBufferDecl *CreateDefaultCBuffer(ASTContext &C,
- DeclContext *LexicalParent);
static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
SourceRange getSourceRange() const override LLVM_READONLY {
@@ -5075,7 +5068,6 @@ public:
bool hasValidPackoffset() const { return HasValidPackoffset; }
const CXXRecordDecl *getLayoutStruct() const { return LayoutStruct; }
void addLayoutStruct(CXXRecordDecl *LS);
- void addDefaultBufferDecl(Decl *D);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -5087,28 +5079,6 @@ public:
return static_cast<HLSLBufferDecl *>(const_cast<DeclContext *>(DC));
}
- // Iterator for the buffer decls. For constant buffers explicitly declared
- // with `cbuffer` keyword this will the list of decls parented by this
- // HLSLBufferDecl (equal to `decls()`).
- // For implicit $Globals buffer this will be the list of default buffer
- // declarations stored in DefaultBufferDecls plus the implicit layout
- // struct (the only child of HLSLBufferDecl in this case).
- //
- // The iterator uses llvm::concat_iterator to concatenate the lists
- // `decls()` and `DefaultBufferDecls`. For non-default buffers
- // `DefaultBufferDecls` is always empty.
- using buffer_decl_iterator =
- llvm::concat_iterator<Decl *const, SmallVector<Decl *>::const_iterator,
- decl_iterator>;
- using buffer_decl_range = llvm::iterator_range<buffer_decl_iterator>;
-
- buffer_decl_range buffer_decls() const {
- return buffer_decl_range(buffer_decls_begin(), buffer_decls_end());
- }
- buffer_decl_iterator buffer_decls_begin() const;
- buffer_decl_iterator buffer_decls_end() const;
- bool buffer_decls_empty();
-
friend class ASTDeclReader;
friend class ASTDeclWriter;
};
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index c4006fd..4f4bbe9 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -105,13 +105,13 @@ public:
HLSLParamModifierAttr::Spelling Spelling);
void ActOnTopLevelFunction(FunctionDecl *FD);
void ActOnVariableDeclarator(VarDecl *VD);
- void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU);
void CheckEntryPoint(FunctionDecl *FD);
void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
const HLSLAnnotationAttr *AnnotationAttr);
void DiagnoseAttrStageMismatch(
const Attr *A, llvm::Triple::EnvironmentType Stage,
std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages);
+ void DiagnoseAvailabilityViolations(TranslationUnitDecl *TU);
QualType handleVectorBinOpConversion(ExprResult &LHS, ExprResult &RHS,
QualType LHSType, QualType RHSType,
@@ -168,16 +168,11 @@ private:
// List of all resource bindings
ResourceBindings Bindings;
- // default constant buffer $Globals
- HLSLBufferDecl *DefaultCBuffer;
-
private:
void collectResourceBindingsOnVarDecl(VarDecl *D);
void collectResourceBindingsOnUserRecordDecl(const VarDecl *VD,
const RecordType *RT);
void processExplicitBindingsOnDecl(VarDecl *D);
-
- void diagnoseAvailabilityViolations(TranslationUnitDecl *TU);
};
} // namespace clang
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 9c0be5c..5a3be16 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -57,7 +57,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -5746,17 +5745,6 @@ HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C,
return Result;
}
-HLSLBufferDecl *
-HLSLBufferDecl::CreateDefaultCBuffer(ASTContext &C,
- DeclContext *LexicalParent) {
- DeclContext *DC = LexicalParent;
- IdentifierInfo *II = &C.Idents.get("$Globals", tok::TokenKind::identifier);
- HLSLBufferDecl *Result = new (C, DC) HLSLBufferDecl(
- DC, true, SourceLocation(), II, SourceLocation(), SourceLocation());
- Result->setImplicit(true);
- return Result;
-}
-
HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C,
GlobalDeclID ID) {
return new (C, ID) HLSLBufferDecl(nullptr, false, SourceLocation(), nullptr,
@@ -5769,30 +5757,6 @@ void HLSLBufferDecl::addLayoutStruct(CXXRecordDecl *LS) {
addDecl(LS);
}
-void HLSLBufferDecl::addDefaultBufferDecl(Decl *D) {
- assert(isImplicit() &&
- "default decls can only be added to the implicit/default constant "
- "buffer $Globals");
- DefaultBufferDecls.push_back(D);
-}
-
-HLSLBufferDecl::buffer_decl_iterator
-HLSLBufferDecl::buffer_decls_begin() const {
- return buffer_decl_iterator(llvm::iterator_range(DefaultBufferDecls.begin(),
- DefaultBufferDecls.end()),
- decl_range(decls_begin(), decls_end()));
-}
-
-HLSLBufferDecl::buffer_decl_iterator HLSLBufferDecl::buffer_decls_end() const {
- return buffer_decl_iterator(
- llvm::iterator_range(DefaultBufferDecls.end(), DefaultBufferDecls.end()),
- decl_range(decls_end(), decls_end()));
-}
-
-bool HLSLBufferDecl::buffer_decls_empty() {
- return DefaultBufferDecls.empty() && decls_empty();
-}
-
//===----------------------------------------------------------------------===//
// ImportDecl Implementation
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index ed6d203..547220f 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -116,7 +116,7 @@ void CGHLSLRuntime::emitBufferGlobalsAndMetadata(const HLSLBufferDecl *BufDecl,
BufGlobals.push_back(ValueAsMetadata::get(BufGV));
const auto *ElemIt = LayoutStruct->element_begin();
- for (Decl *D : BufDecl->buffer_decls()) {
+ for (Decl *D : BufDecl->decls()) {
if (isa<CXXRecordDecl, EmptyDecl>(D))
// Nothing to do for this declaration.
continue;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 1b7d0ac..7924c32 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -5513,11 +5513,6 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
if (getLangOpts().OpenCL && ASTTy->isSamplerT())
return;
- // HLSL default buffer constants will be emitted during HLSLBufferDecl codegen
- if (getLangOpts().HLSL &&
- D->getType().getAddressSpace() == LangAS::hlsl_constant)
- return;
-
// If this is OpenMP device, check if it is legal to emit this global
// normally.
if (LangOpts.OpenMPIsTargetDevice && OpenMPRuntime &&
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index c699e92..145cda6 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1417,7 +1417,8 @@ void Sema::ActOnEndOfTranslationUnit() {
}
if (LangOpts.HLSL)
- HLSL().ActOnEndOfTranslationUnit(getASTContext().getTranslationUnitDecl());
+ HLSL().DiagnoseAvailabilityViolations(
+ getASTContext().getTranslationUnitDecl());
// If there were errors, disable 'unused' warnings since they will mostly be
// noise. Don't warn for a use from a module: either we should warn on all
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index b298423..d26d85d 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -9,7 +9,6 @@
//===----------------------------------------------------------------------===//
#include "clang/Sema/SemaHLSL.h"
-#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Attrs.inc"
@@ -148,7 +147,7 @@ bool ResourceBindings::hasBindingInfoForDecl(const VarDecl *VD) const {
return DeclToBindingListIndex.contains(VD);
}
-SemaHLSL::SemaHLSL(Sema &S) : SemaBase(S), DefaultCBuffer(nullptr) {}
+SemaHLSL::SemaHLSL(Sema &S) : SemaBase(S) {}
Decl *SemaHLSL::ActOnStartBuffer(Scope *BufferScope, bool CBuffer,
SourceLocation KwLoc, IdentifierInfo *Ident,
@@ -226,7 +225,7 @@ static void validatePackoffset(Sema &S, HLSLBufferDecl *BufDecl) {
// or on none.
bool HasPackOffset = false;
bool HasNonPackOffset = false;
- for (auto *Field : BufDecl->buffer_decls()) {
+ for (auto *Field : BufDecl->decls()) {
VarDecl *Var = dyn_cast<VarDecl>(Field);
if (!Var)
continue;
@@ -493,7 +492,7 @@ void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl) {
LS->setImplicit(true);
LS->startDefinition();
- for (Decl *D : BufDecl->buffer_decls()) {
+ for (Decl *D : BufDecl->decls()) {
VarDecl *VD = dyn_cast<VarDecl>(D);
if (!VD || VD->getStorageClass() == SC_Static ||
VD->getType().getAddressSpace() == LangAS::hlsl_groupshared)
@@ -1929,19 +1928,7 @@ void DiagnoseHLSLAvailability::CheckDeclAvailability(NamedDecl *D,
} // namespace
-void SemaHLSL::ActOnEndOfTranslationUnit(TranslationUnitDecl *TU) {
- // process default CBuffer - create buffer layout struct and invoke codegenCGH
- if (DefaultCBuffer) {
- SemaRef.getCurLexicalContext()->addDecl(DefaultCBuffer);
- createHostLayoutStructForBuffer(SemaRef, DefaultCBuffer);
-
- DeclGroupRef DG(DefaultCBuffer);
- SemaRef.Consumer.HandleTopLevelDecl(DG);
- }
- diagnoseAvailabilityViolations(TU);
-}
-
-void SemaHLSL::diagnoseAvailabilityViolations(TranslationUnitDecl *TU) {
+void SemaHLSL::DiagnoseAvailabilityViolations(TranslationUnitDecl *TU) {
// Skip running the diagnostics scan if the diagnostic mode is
// strict (-fhlsl-strict-availability) and the target shader stage is known
// because all relevant diagnostics were already emitted in the
@@ -3004,14 +2991,6 @@ QualType SemaHLSL::getInoutParameterType(QualType Ty) {
return Ty;
}
-static bool IsDefaultBufferConstantDecl(VarDecl *VD) {
- QualType QT = VD->getType();
- return VD->getDeclContext()->isTranslationUnit() &&
- QT.getAddressSpace() == LangAS::Default &&
- VD->getStorageClass() != SC_Static &&
- !isInvalidConstantBufferLeafElementType(QT.getTypePtr());
-}
-
void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
if (VD->hasGlobalStorage()) {
// make sure the declaration has a complete type
@@ -3023,21 +3002,7 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
return;
}
- // Global variables outside a cbuffer block that are not a resource, static,
- // groupshared, or an empty array or struct belong to the default constant
- // buffer $Globals
- if (IsDefaultBufferConstantDecl(VD)) {
- if (DefaultCBuffer == nullptr)
- DefaultCBuffer = HLSLBufferDecl::CreateDefaultCBuffer(
- SemaRef.getASTContext(), SemaRef.getCurLexicalContext());
- // update address space to hlsl_constant
- QualType NewTy = getASTContext().getAddrSpaceQualType(
- VD->getType(), LangAS::hlsl_constant);
- VD->setType(NewTy);
- DefaultCBuffer->addDefaultBufferDecl(VD);
- }
-
- // find all resources bindings on decl
+ // find all resources on decl
if (VD->getType()->isHLSLIntangibleType())
collectResourceBindingsOnVarDecl(VD);
diff --git a/clang/test/AST/HLSL/default_cbuffer.hlsl b/clang/test/AST/HLSL/default_cbuffer.hlsl
deleted file mode 100644
index 9e0fce7..0000000
--- a/clang/test/AST/HLSL/default_cbuffer.hlsl
+++ /dev/null
@@ -1,50 +0,0 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -ast-dump -o - %s | FileCheck %s
-
-struct EmptyStruct {
-};
-
-struct S {
- RWBuffer<float> buf;
- EmptyStruct es;
- float ea[0];
- float b;
-};
-
-// CHECK: VarDecl {{.*}} used a 'hlsl_constant float'
-float a;
-
-// CHECK: VarDecl {{.*}} b 'RWBuffer<float>':'hlsl::RWBuffer<float>'
-RWBuffer<float> b;
-
-// CHECK: VarDecl {{.*}} c 'EmptyStruct'
-EmptyStruct c;
-
-// CHECK: VarDecl {{.*}} d 'float[0]'
-float d[0];
-
-// CHECK: VarDecl {{.*}} e 'RWBuffer<float>[2]'
-RWBuffer<float> e[2];
-
-// CHECK: VarDecl {{.*}} f 'groupshared float'
-groupshared float f;
-
-// CHECK: VarDecl {{.*}} g 'hlsl_constant float'
-float g;
-
-// CHECK: VarDecl {{.*}} h 'hlsl_constant S'
-S h;
-
-// CHECK: HLSLBufferDecl {{.*}} implicit cbuffer $Globals
-// CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_$Globals definition
-// CHECK: PackedAttr
-// CHECK-NEXT: FieldDecl {{.*}} a 'float'
-// CHECK-NEXT: FieldDecl {{.*}} g 'float'
-// CHECK-NEXT: FieldDecl {{.*}} h '__cblayout_S'
-
-// CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_S definition
-// CHECK: PackedAttr {{.*}} Implicit
-// CHECK-NEXT: FieldDecl {{.*}} b 'float'
-
-export float foo() {
- return a;
-}
diff --git a/clang/test/CodeGenHLSL/basic_types.hlsl b/clang/test/CodeGenHLSL/basic_types.hlsl
index 3620426..d987af4 100644
--- a/clang/test/CodeGenHLSL/basic_types.hlsl
+++ b/clang/test/CodeGenHLSL/basic_types.hlsl
@@ -6,38 +6,38 @@
// RUN: -emit-llvm -disable-llvm-passes -o - -DNAMESPACED| FileCheck %s
-// CHECK: @uint16_t_Val = external addrspace(2) global i16, align 2
-// CHECK: @int16_t_Val = external addrspace(2) global i16, align 2
-// CHECK: @uint_Val = external addrspace(2) global i32, align 4
-// CHECK: @uint64_t_Val = external addrspace(2) global i64, align 8
-// CHECK: @int64_t_Val = external addrspace(2) global i64, align 8
-// CHECK: @int16_t2_Val = external addrspace(2) global <2 x i16>, align 4
-// CHECK: @int16_t3_Val = external addrspace(2) global <3 x i16>, align 8
-// CHECK: @int16_t4_Val = external addrspace(2) global <4 x i16>, align 8
-// CHECK: @uint16_t2_Val = external addrspace(2) global <2 x i16>, align 4
-// CHECK: @uint16_t3_Val = external addrspace(2) global <3 x i16>, align 8
-// CHECK: @uint16_t4_Val = external addrspace(2) global <4 x i16>, align 8
-// CHECK: @int2_Val = external addrspace(2) global <2 x i32>, align 8
-// CHECK: @int3_Val = external addrspace(2) global <3 x i32>, align 16
-// CHECK: @int4_Val = external addrspace(2) global <4 x i32>, align 16
-// CHECK: @uint2_Val = external addrspace(2) global <2 x i32>, align 8
-// CHECK: @uint3_Val = external addrspace(2) global <3 x i32>, align 16
-// CHECK: @uint4_Val = external addrspace(2) global <4 x i32>, align 16
-// CHECK: @int64_t2_Val = external addrspace(2) global <2 x i64>, align 16
-// CHECK: @int64_t3_Val = external addrspace(2) global <3 x i64>, align 32
-// CHECK: @int64_t4_Val = external addrspace(2) global <4 x i64>, align 32
-// CHECK: @uint64_t2_Val = external addrspace(2) global <2 x i64>, align 16
-// CHECK: @uint64_t3_Val = external addrspace(2) global <3 x i64>, align 32
-// CHECK: @uint64_t4_Val = external addrspace(2) global <4 x i64>, align 32
-// CHECK: @half2_Val = external addrspace(2) global <2 x half>, align 4
-// CHECK: @half3_Val = external addrspace(2) global <3 x half>, align 8
-// CHECK: @half4_Val = external addrspace(2) global <4 x half>, align 8
-// CHECK: @float2_Val = external addrspace(2) global <2 x float>, align 8
-// CHECK: @float3_Val = external addrspace(2) global <3 x float>, align 16
-// CHECK: @float4_Val = external addrspace(2) global <4 x float>, align 16
-// CHECK: @double2_Val = external addrspace(2) global <2 x double>, align 16
-// CHECK: @double3_Val = external addrspace(2) global <3 x double>, align 32
-// CHECK: @double4_Val = external addrspace(2) global <4 x double>, align 32
+// CHECK: @uint16_t_Val = global i16 0, align 2
+// CHECK: @int16_t_Val = global i16 0, align 2
+// CHECK: @uint_Val = global i32 0, align 4
+// CHECK: @uint64_t_Val = global i64 0, align 8
+// CHECK: @int64_t_Val = global i64 0, align 8
+// CHECK: @int16_t2_Val = global <2 x i16> zeroinitializer, align 4
+// CHECK: @int16_t3_Val = global <3 x i16> zeroinitializer, align 8
+// CHECK: @int16_t4_Val = global <4 x i16> zeroinitializer, align 8
+// CHECK: @uint16_t2_Val = global <2 x i16> zeroinitializer, align 4
+// CHECK: @uint16_t3_Val = global <3 x i16> zeroinitializer, align 8
+// CHECK: @uint16_t4_Val = global <4 x i16> zeroinitializer, align 8
+// CHECK: @int2_Val = global <2 x i32> zeroinitializer, align 8
+// CHECK: @int3_Val = global <3 x i32> zeroinitializer, align 16
+// CHECK: @int4_Val = global <4 x i32> zeroinitializer, align 16
+// CHECK: @uint2_Val = global <2 x i32> zeroinitializer, align 8
+// CHECK: @uint3_Val = global <3 x i32> zeroinitializer, align 16
+// CHECK: @uint4_Val = global <4 x i32> zeroinitializer, align 16
+// CHECK: @int64_t2_Val = global <2 x i64> zeroinitializer, align 16
+// CHECK: @int64_t3_Val = global <3 x i64> zeroinitializer, align 32
+// CHECK: @int64_t4_Val = global <4 x i64> zeroinitializer, align 32
+// CHECK: @uint64_t2_Val = global <2 x i64> zeroinitializer, align 16
+// CHECK: @uint64_t3_Val = global <3 x i64> zeroinitializer, align 32
+// CHECK: @uint64_t4_Val = global <4 x i64> zeroinitializer, align 32
+// CHECK: @half2_Val = global <2 x half> zeroinitializer, align 4
+// CHECK: @half3_Val = global <3 x half> zeroinitializer, align 8
+// CHECK: @half4_Val = global <4 x half> zeroinitializer, align 8
+// CHECK: @float2_Val = global <2 x float> zeroinitializer, align 8
+// CHECK: @float3_Val = global <3 x float> zeroinitializer, align 16
+// CHECK: @float4_Val = global <4 x float> zeroinitializer, align 16
+// CHECK: @double2_Val = global <2 x double> zeroinitializer, align 16
+// CHECK: @double3_Val = global <3 x double> zeroinitializer, align 32
+// CHECK: @double4_Val = global <4 x double> zeroinitializer, align 32
#ifdef NAMESPACED
#define TYPE_DECL(T) hlsl::T T##_Val
diff --git a/clang/test/CodeGenHLSL/default_cbuffer.hlsl b/clang/test/CodeGenHLSL/default_cbuffer.hlsl
deleted file mode 100644
index c5176aa..0000000
--- a/clang/test/CodeGenHLSL/default_cbuffer.hlsl
+++ /dev/null
@@ -1,39 +0,0 @@
-// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute \
-// RUN: -fnative-half-type -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
-
-// CHECK: %"__cblayout_$Globals" = type <{ float, float, target("dx.Layout", %__cblayout_S, 4, 0) }>
-// CHECK: %__cblayout_S = type <{ float }>
-
-// CHECK-DAG: @"$Globals.cb" = external constant target("dx.CBuffer", target("dx.Layout", %"__cblayout_$Globals", 20, 0, 4, 16))
-// CHECK-DAG: @a = external addrspace(2) global float
-// CHECK-DAG: @g = external addrspace(2) global float
-// CHECK-DAG: @h = external addrspace(2) global target("dx.Layout", %__cblayout_S, 4, 0), align 4
-
-struct EmptyStruct {
-};
-
-struct S {
- RWBuffer<float> buf;
- EmptyStruct es;
- float ea[0];
- float b;
-};
-
-float a;
-RWBuffer<float> b;
-EmptyStruct c;
-float d[0];
-RWBuffer<float> e[2];
-groupshared float f;
-float g;
-S h;
-
-RWBuffer<float> Buf;
-
-[numthreads(4,1,1)]
-void main() {
- Buf[0] = a;
-}
-
-// CHECK: !hlsl.cbs = !{![[CB:.*]]}
-// CHECK: ![[CB]] = !{ptr @"$Globals.cb", ptr addrspace(2) @a, ptr addrspace(2) @g, ptr addrspace(2) @h}