Skip to content

Commit 4d1c3ab

Browse files
committed
rebase
Created using spr 1.3.4
2 parents d426186 + 8fc8a84 commit 4d1c3ab

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+792
-234
lines changed

clang/cmake/caches/Release.cmake

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,4 @@ endif()
143143
set_final_stage_var(CPACK_GENERATOR "TXZ" STRING)
144144
set_final_stage_var(CPACK_ARCHIVE_THREADS "0" STRING)
145145

146-
if(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Darwin")
147-
set_final_stage_var(LLVM_USE_STATIC_ZSTD "ON" BOOL)
148-
endif()
146+
set_final_stage_var(LLVM_USE_STATIC_ZSTD "ON" BOOL)

clang/include/clang/AST/Decl.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5045,15 +5045,26 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext {
50455045
// LayoutStruct - Layout struct for the buffer
50465046
CXXRecordDecl *LayoutStruct;
50475047

5048+
// For default (implicit) constant buffer, an array of references of global
5049+
// decls that belong to the buffer. The decls are already parented by the
5050+
// translation unit context. The array is allocated by the ASTContext
5051+
// allocator in HLSLBufferDecl::CreateDefaultCBuffer.
5052+
ArrayRef<Decl *> DefaultBufferDecls;
5053+
50485054
HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc,
50495055
IdentifierInfo *ID, SourceLocation IDLoc,
50505056
SourceLocation LBrace);
50515057

5058+
void setDefaultBufferDecls(ArrayRef<Decl *> Decls);
5059+
50525060
public:
50535061
static HLSLBufferDecl *Create(ASTContext &C, DeclContext *LexicalParent,
50545062
bool CBuffer, SourceLocation KwLoc,
50555063
IdentifierInfo *ID, SourceLocation IDLoc,
50565064
SourceLocation LBrace);
5065+
static HLSLBufferDecl *
5066+
CreateDefaultCBuffer(ASTContext &C, DeclContext *LexicalParent,
5067+
ArrayRef<Decl *> DefaultCBufferDecls);
50575068
static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
50585069

50595070
SourceRange getSourceRange() const override LLVM_READONLY {
@@ -5079,6 +5090,28 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext {
50795090
return static_cast<HLSLBufferDecl *>(const_cast<DeclContext *>(DC));
50805091
}
50815092

5093+
// Iterator for the buffer decls. For constant buffers explicitly declared
5094+
// with `cbuffer` keyword this will the list of decls parented by this
5095+
// HLSLBufferDecl (equal to `decls()`).
5096+
// For implicit $Globals buffer this will be the list of default buffer
5097+
// declarations stored in DefaultBufferDecls plus the implicit layout
5098+
// struct (the only child of HLSLBufferDecl in this case).
5099+
//
5100+
// The iterator uses llvm::concat_iterator to concatenate the lists
5101+
// `decls()` and `DefaultBufferDecls`. For non-default buffers
5102+
// `DefaultBufferDecls` is always empty.
5103+
using buffer_decl_iterator =
5104+
llvm::concat_iterator<Decl *const, SmallVector<Decl *>::const_iterator,
5105+
decl_iterator>;
5106+
using buffer_decl_range = llvm::iterator_range<buffer_decl_iterator>;
5107+
5108+
buffer_decl_range buffer_decls() const {
5109+
return buffer_decl_range(buffer_decls_begin(), buffer_decls_end());
5110+
}
5111+
buffer_decl_iterator buffer_decls_begin() const;
5112+
buffer_decl_iterator buffer_decls_end() const;
5113+
bool buffer_decls_empty();
5114+
50825115
friend class ASTDeclReader;
50835116
friend class ASTDeclWriter;
50845117
};

clang/include/clang/Sema/SemaHLSL.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,13 @@ class SemaHLSL : public SemaBase {
105105
HLSLParamModifierAttr::Spelling Spelling);
106106
void ActOnTopLevelFunction(FunctionDecl *FD);
107107
void ActOnVariableDeclarator(VarDecl *VD);
108+
void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU);
108109
void CheckEntryPoint(FunctionDecl *FD);
109110
void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
110111
const HLSLAnnotationAttr *AnnotationAttr);
111112
void DiagnoseAttrStageMismatch(
112113
const Attr *A, llvm::Triple::EnvironmentType Stage,
113114
std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages);
114-
void DiagnoseAvailabilityViolations(TranslationUnitDecl *TU);
115115

116116
QualType handleVectorBinOpConversion(ExprResult &LHS, ExprResult &RHS,
117117
QualType LHSType, QualType RHSType,
@@ -168,11 +168,17 @@ class SemaHLSL : public SemaBase {
168168
// List of all resource bindings
169169
ResourceBindings Bindings;
170170

171+
// Global declaration collected for the $Globals default constant
172+
// buffer which will be created at the end of the translation unit.
173+
llvm::SmallVector<Decl *> DefaultCBufferDecls;
174+
171175
private:
172176
void collectResourceBindingsOnVarDecl(VarDecl *D);
173177
void collectResourceBindingsOnUserRecordDecl(const VarDecl *VD,
174178
const RecordType *RT);
175179
void processExplicitBindingsOnDecl(VarDecl *D);
180+
181+
void diagnoseAvailabilityViolations(TranslationUnitDecl *TU);
176182
};
177183

178184
} // namespace clang

clang/lib/AST/Decl.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include "llvm/ADT/SmallVector.h"
5858
#include "llvm/ADT/StringRef.h"
5959
#include "llvm/ADT/StringSwitch.h"
60+
#include "llvm/ADT/iterator_range.h"
6061
#include "llvm/Support/Casting.h"
6162
#include "llvm/Support/ErrorHandling.h"
6263
#include "llvm/Support/raw_ostream.h"
@@ -5745,6 +5746,18 @@ HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C,
57455746
return Result;
57465747
}
57475748

5749+
HLSLBufferDecl *
5750+
HLSLBufferDecl::CreateDefaultCBuffer(ASTContext &C, DeclContext *LexicalParent,
5751+
ArrayRef<Decl *> DefaultCBufferDecls) {
5752+
DeclContext *DC = LexicalParent;
5753+
IdentifierInfo *II = &C.Idents.get("$Globals", tok::TokenKind::identifier);
5754+
HLSLBufferDecl *Result = new (C, DC) HLSLBufferDecl(
5755+
DC, true, SourceLocation(), II, SourceLocation(), SourceLocation());
5756+
Result->setImplicit(true);
5757+
Result->setDefaultBufferDecls(DefaultCBufferDecls);
5758+
return Result;
5759+
}
5760+
57485761
HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C,
57495762
GlobalDeclID ID) {
57505763
return new (C, ID) HLSLBufferDecl(nullptr, false, SourceLocation(), nullptr,
@@ -5757,6 +5770,36 @@ void HLSLBufferDecl::addLayoutStruct(CXXRecordDecl *LS) {
57575770
addDecl(LS);
57585771
}
57595772

5773+
void HLSLBufferDecl::setDefaultBufferDecls(ArrayRef<Decl *> Decls) {
5774+
assert(!Decls.empty());
5775+
assert(DefaultBufferDecls.empty() && "default decls are already set");
5776+
assert(isImplicit() &&
5777+
"default decls can only be added to the implicit/default constant "
5778+
"buffer $Globals");
5779+
5780+
// allocate array for default decls with ASTContext allocator
5781+
Decl **DeclsArray = new (getASTContext()) Decl *[Decls.size()];
5782+
std::copy(Decls.begin(), Decls.end(), DeclsArray);
5783+
DefaultBufferDecls = ArrayRef<Decl *>(DeclsArray, Decls.size());
5784+
}
5785+
5786+
HLSLBufferDecl::buffer_decl_iterator
5787+
HLSLBufferDecl::buffer_decls_begin() const {
5788+
return buffer_decl_iterator(llvm::iterator_range(DefaultBufferDecls.begin(),
5789+
DefaultBufferDecls.end()),
5790+
decl_range(decls_begin(), decls_end()));
5791+
}
5792+
5793+
HLSLBufferDecl::buffer_decl_iterator HLSLBufferDecl::buffer_decls_end() const {
5794+
return buffer_decl_iterator(
5795+
llvm::iterator_range(DefaultBufferDecls.end(), DefaultBufferDecls.end()),
5796+
decl_range(decls_end(), decls_end()));
5797+
}
5798+
5799+
bool HLSLBufferDecl::buffer_decls_empty() {
5800+
return DefaultBufferDecls.empty() && decls_empty();
5801+
}
5802+
57605803
//===----------------------------------------------------------------------===//
57615804
// ImportDecl Implementation
57625805
//===----------------------------------------------------------------------===//

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ void CGHLSLRuntime::emitBufferGlobalsAndMetadata(const HLSLBufferDecl *BufDecl,
116116
BufGlobals.push_back(ValueAsMetadata::get(BufGV));
117117

118118
const auto *ElemIt = LayoutStruct->element_begin();
119-
for (Decl *D : BufDecl->decls()) {
119+
for (Decl *D : BufDecl->buffer_decls()) {
120120
if (isa<CXXRecordDecl, EmptyDecl>(D))
121121
// Nothing to do for this declaration.
122122
continue;

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5513,6 +5513,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
55135513
if (getLangOpts().OpenCL && ASTTy->isSamplerT())
55145514
return;
55155515

5516+
// HLSL default buffer constants will be emitted during HLSLBufferDecl codegen
5517+
if (getLangOpts().HLSL &&
5518+
D->getType().getAddressSpace() == LangAS::hlsl_constant)
5519+
return;
5520+
55165521
// If this is OpenMP device, check if it is legal to emit this global
55175522
// normally.
55185523
if (LangOpts.OpenMPIsTargetDevice && OpenMPRuntime &&

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6202,6 +6202,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
62026202
TT_ClassHeadName, tok::kw_operator)) {
62036203
return true;
62046204
}
6205+
if (Right.isAttribute())
6206+
return true;
62056207
if (Left.is(TT_PointerOrReference))
62066208
return false;
62076209
if (Right.isTrailingComment()) {
@@ -6346,9 +6348,6 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
63466348
tok::less, tok::coloncolon);
63476349
}
63486350

6349-
if (Right.isAttribute())
6350-
return true;
6351-
63526351
if (Right.is(tok::l_square) && Right.is(TT_AttributeSquare))
63536352
return Left.isNot(TT_AttributeSquare);
63546353

clang/lib/Sema/Sema.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,8 +1417,7 @@ void Sema::ActOnEndOfTranslationUnit() {
14171417
}
14181418

14191419
if (LangOpts.HLSL)
1420-
HLSL().DiagnoseAvailabilityViolations(
1421-
getASTContext().getTranslationUnitDecl());
1420+
HLSL().ActOnEndOfTranslationUnit(getASTContext().getTranslationUnitDecl());
14221421

14231422
// If there were errors, disable 'unused' warnings since they will mostly be
14241423
// noise. Don't warn for a use from a module: either we should warn on all

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//===----------------------------------------------------------------------===//
1010

1111
#include "clang/Sema/SemaHLSL.h"
12+
#include "clang/AST/ASTConsumer.h"
1213
#include "clang/AST/ASTContext.h"
1314
#include "clang/AST/Attr.h"
1415
#include "clang/AST/Attrs.inc"
@@ -172,6 +173,23 @@ Decl *SemaHLSL::ActOnStartBuffer(Scope *BufferScope, bool CBuffer,
172173
return Result;
173174
}
174175

176+
static unsigned calculateLegacyCbufferFieldAlign(const ASTContext &Context,
177+
QualType T) {
178+
// Arrays and Structs are always aligned to new buffer rows
179+
if (T->isArrayType() || T->isStructureType())
180+
return 16;
181+
182+
// Vectors are aligned to the type they contain
183+
if (const VectorType *VT = T->getAs<VectorType>())
184+
return calculateLegacyCbufferFieldAlign(Context, VT->getElementType());
185+
186+
assert(Context.getTypeSize(T) <= 64 &&
187+
"Scalar bit widths larger than 64 not supported");
188+
189+
// Scalar types are aligned to their byte width
190+
return Context.getTypeSize(T) / 8;
191+
}
192+
175193
// Calculate the size of a legacy cbuffer type in bytes based on
176194
// https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-packing-rules
177195
static unsigned calculateLegacyCbufferSize(const ASTContext &Context,
@@ -183,11 +201,15 @@ static unsigned calculateLegacyCbufferSize(const ASTContext &Context,
183201
for (const FieldDecl *Field : RD->fields()) {
184202
QualType Ty = Field->getType();
185203
unsigned FieldSize = calculateLegacyCbufferSize(Context, Ty);
186-
// FIXME: This is not the correct alignment, it does not work for 16-bit
187-
// types. See llvm/llvm-project#119641.
188-
unsigned FieldAlign = 4;
189-
if (Ty->isAggregateType())
204+
unsigned FieldAlign = calculateLegacyCbufferFieldAlign(Context, Ty);
205+
206+
// If the field crosses the row boundary after alignment it drops to the
207+
// next row
208+
unsigned AlignSize = llvm::alignTo(Size, FieldAlign);
209+
if ((AlignSize % CBufferAlign) + FieldSize > CBufferAlign) {
190210
FieldAlign = CBufferAlign;
211+
}
212+
191213
Size = llvm::alignTo(Size, FieldAlign);
192214
Size += FieldSize;
193215
}
@@ -225,7 +247,7 @@ static void validatePackoffset(Sema &S, HLSLBufferDecl *BufDecl) {
225247
// or on none.
226248
bool HasPackOffset = false;
227249
bool HasNonPackOffset = false;
228-
for (auto *Field : BufDecl->decls()) {
250+
for (auto *Field : BufDecl->buffer_decls()) {
229251
VarDecl *Var = dyn_cast<VarDecl>(Field);
230252
if (!Var)
231253
continue;
@@ -492,7 +514,7 @@ void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl) {
492514
LS->setImplicit(true);
493515
LS->startDefinition();
494516

495-
for (Decl *D : BufDecl->decls()) {
517+
for (Decl *D : BufDecl->buffer_decls()) {
496518
VarDecl *VD = dyn_cast<VarDecl>(D);
497519
if (!VD || VD->getStorageClass() == SC_Static ||
498520
VD->getType().getAddressSpace() == LangAS::hlsl_groupshared)
@@ -1928,7 +1950,22 @@ void DiagnoseHLSLAvailability::CheckDeclAvailability(NamedDecl *D,
19281950

19291951
} // namespace
19301952

1931-
void SemaHLSL::DiagnoseAvailabilityViolations(TranslationUnitDecl *TU) {
1953+
void SemaHLSL::ActOnEndOfTranslationUnit(TranslationUnitDecl *TU) {
1954+
// process default CBuffer - create buffer layout struct and invoke codegenCGH
1955+
if (!DefaultCBufferDecls.empty()) {
1956+
HLSLBufferDecl *DefaultCBuffer = HLSLBufferDecl::CreateDefaultCBuffer(
1957+
SemaRef.getASTContext(), SemaRef.getCurLexicalContext(),
1958+
DefaultCBufferDecls);
1959+
SemaRef.getCurLexicalContext()->addDecl(DefaultCBuffer);
1960+
createHostLayoutStructForBuffer(SemaRef, DefaultCBuffer);
1961+
1962+
DeclGroupRef DG(DefaultCBuffer);
1963+
SemaRef.Consumer.HandleTopLevelDecl(DG);
1964+
}
1965+
diagnoseAvailabilityViolations(TU);
1966+
}
1967+
1968+
void SemaHLSL::diagnoseAvailabilityViolations(TranslationUnitDecl *TU) {
19321969
// Skip running the diagnostics scan if the diagnostic mode is
19331970
// strict (-fhlsl-strict-availability) and the target shader stage is known
19341971
// because all relevant diagnostics were already emitted in the
@@ -2991,6 +3028,14 @@ QualType SemaHLSL::getInoutParameterType(QualType Ty) {
29913028
return Ty;
29923029
}
29933030

3031+
static bool IsDefaultBufferConstantDecl(VarDecl *VD) {
3032+
QualType QT = VD->getType();
3033+
return VD->getDeclContext()->isTranslationUnit() &&
3034+
QT.getAddressSpace() == LangAS::Default &&
3035+
VD->getStorageClass() != SC_Static &&
3036+
!isInvalidConstantBufferLeafElementType(QT.getTypePtr());
3037+
}
3038+
29943039
void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
29953040
if (VD->hasGlobalStorage()) {
29963041
// make sure the declaration has a complete type
@@ -3002,7 +3047,18 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
30023047
return;
30033048
}
30043049

3005-
// find all resources on decl
3050+
// Global variables outside a cbuffer block that are not a resource, static,
3051+
// groupshared, or an empty array or struct belong to the default constant
3052+
// buffer $Globals (to be created at the end of the translation unit).
3053+
if (IsDefaultBufferConstantDecl(VD)) {
3054+
// update address space to hlsl_constant
3055+
QualType NewTy = getASTContext().getAddrSpaceQualType(
3056+
VD->getType(), LangAS::hlsl_constant);
3057+
VD->setType(NewTy);
3058+
DefaultCBufferDecls.push_back(VD);
3059+
}
3060+
3061+
// find all resources bindings on decl
30063062
if (VD->getType()->isHLSLIntangibleType())
30073063
collectResourceBindingsOnVarDecl(VD);
30083064

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -ast-dump -o - %s | FileCheck %s
2+
3+
struct EmptyStruct {
4+
};
5+
6+
struct S {
7+
RWBuffer<float> buf;
8+
EmptyStruct es;
9+
float ea[0];
10+
float b;
11+
};
12+
13+
// CHECK: VarDecl {{.*}} used a 'hlsl_constant float'
14+
float a;
15+
16+
// CHECK: VarDecl {{.*}} b 'RWBuffer<float>':'hlsl::RWBuffer<float>'
17+
RWBuffer<float> b;
18+
19+
// CHECK: VarDecl {{.*}} c 'EmptyStruct'
20+
EmptyStruct c;
21+
22+
// CHECK: VarDecl {{.*}} d 'float[0]'
23+
float d[0];
24+
25+
// CHECK: VarDecl {{.*}} e 'RWBuffer<float>[2]'
26+
RWBuffer<float> e[2];
27+
28+
// CHECK: VarDecl {{.*}} f 'groupshared float'
29+
groupshared float f;
30+
31+
// CHECK: VarDecl {{.*}} g 'hlsl_constant float'
32+
float g;
33+
34+
// CHECK: VarDecl {{.*}} h 'hlsl_constant S'
35+
S h;
36+
37+
// CHECK: HLSLBufferDecl {{.*}} implicit cbuffer $Globals
38+
// CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_$Globals definition
39+
// CHECK: PackedAttr
40+
// CHECK-NEXT: FieldDecl {{.*}} a 'float'
41+
// CHECK-NEXT: FieldDecl {{.*}} g 'float'
42+
// CHECK-NEXT: FieldDecl {{.*}} h '__cblayout_S'
43+
44+
// CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_S definition
45+
// CHECK: PackedAttr {{.*}} Implicit
46+
// CHECK-NEXT: FieldDecl {{.*}} b 'float'
47+
48+
export float foo() {
49+
return a;
50+
}

0 commit comments

Comments
 (0)