Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,8 @@ class HLSLSemanticAttr<bit Indexable> : HLSLAnnotationAttr {
let Spellings = [];
let Subjects = SubjectList<[ParmVar, Field, Function]>;
let LangOpts = [HLSL];
let Args = [DeclArgument<Named, "Target">, IntArgument<"SemanticIndex">,
BoolArgument<"SemanticExplicitIndex">];
}

/// A target-specific attribute. This class is meant to be used as a mixin
Expand Down
14 changes: 6 additions & 8 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,17 @@ class SemaHLSL : public SemaBase {
bool handleResourceTypeAttr(QualType T, const ParsedAttr &AL);

template <typename T>
T *createSemanticAttr(const AttributeCommonInfo &ACI, Decl *TargetDecl,
T *createSemanticAttr(const AttributeCommonInfo &ACI, NamedDecl *TargetDecl,
std::optional<unsigned> Location) {
T *Attr = ::new (getASTContext()) T(getASTContext(), ACI);
T *Attr =
::new (getASTContext()) T(getASTContext(), ACI, TargetDecl,
Location.value_or(0), Location.has_value());

if (Attr->isSemanticIndexable())
Attr->setSemanticIndex(Location ? *Location : 0);
else if (Location.has_value()) {
if (!Attr->isSemanticIndexable() && Location.has_value()) {
Diag(Attr->getLocation(), diag::err_hlsl_semantic_indexing_not_supported)
<< Attr->getAttrName()->getName();
return nullptr;
}

Attr->setTargetDecl(TargetDecl);
return Attr;
}

Expand Down Expand Up @@ -258,7 +256,7 @@ class SemaHLSL : public SemaBase {
void checkSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
const HLSLSemanticAttr *SemanticAttr);
HLSLSemanticAttr *createSemantic(const SemanticInfo &Semantic,
Decl *TargetDecl);
DeclaratorDecl *TargetDecl);
bool determineActiveSemanticOnScalar(FunctionDecl *FD, DeclaratorDecl *D,
SemanticInfo &ActiveSemantic);
bool determineActiveSemantic(FunctionDecl *FD, DeclaratorDecl *D,
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) {
}

HLSLSemanticAttr *SemaHLSL::createSemantic(const SemanticInfo &Info,
Decl *TargetDecl) {
DeclaratorDecl *TargetDecl) {
std::string SemanticName = Info.Semantic->getAttrName()->getName().upper();

if (SemanticName == "SV_DISPATCHTHREADID") {
Expand Down
5 changes: 5 additions & 0 deletions clang/test/SemaHLSL/Semantics/entry_parameter.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ void CSMain(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : SV
// CHECK-NEXT: HLSLSV_GroupIDAttr
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:96 GThreadID 'uint'
// CHECK-NEXT: HLSLSV_GroupThreadIDAttr

// CHECK: HLSLSV_GroupIndexAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> ParmVar 0x{{[0-9a-fA-F]+}} 'GI' 'int' 0
// CHECK-NEXT: HLSLSV_DispatchThreadIDAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> ParmVar 0x{{[0-9a-fA-F]+}} 'ID' 'uint':'unsigned int' 0
// CHECK-NEXT: HLSLSV_GroupIDAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> ParmVar 0x{{[0-9a-fA-F]+}} 'GID' 'uint':'unsigned int' 0
// CHECK-NEXT: HLSLSV_GroupThreadIDAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> ParmVar 0x{{[0-9a-fA-F]+}} 'GThreadID' 'uint':'unsigned int' 0
}
4 changes: 3 additions & 1 deletion clang/test/SemaHLSL/Semantics/position.ps.hlsl
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-pixel -x hlsl -finclude-default-header -o - %s -ast-dump | FileCheck %s

float4 main(float4 a : SV_Position) {
float4 main(float4 a : SV_Position2) {
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:8 main 'float4 (float4)'
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:20 a 'float4':'vector<float, 4>'
// CHECK-NEXT: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <{{.*}}>

// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> ParmVar 0x{{[0-9a-fA-F]+}} 'a' 'float4':'vector<float, 4>' 2 SemanticExplicitIndex
}
18 changes: 18 additions & 0 deletions clang/test/SemaHLSL/Semantics/position.ps.struct.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-pixel -x hlsl -finclude-default-header -o - %s -ast-dump | FileCheck %s

struct S {
float4 f0 : SV_Position;
// CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:10 f0 'float4':'vector<float, 4>'
// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <col:15> <<<NULL>>> 0
float4 f1 : SV_Position3;
// CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:10 f1 'float4':'vector<float, 4>'
// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <col:15> <<<NULL>>> 3 SemanticExplicitIndex
};

float4 main(S s) {
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:8 main 'float4 (S)'
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:15 s 'S'

// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> Field 0x{{[0-9a-fA-F]+}} 'f0' 'float4':'vector<float, 4>' 0
// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> Field 0x{{[0-9a-fA-F]+}} 'f1' 'float4':'vector<float, 4>' 3 SemanticExplicitIndex
}
11 changes: 11 additions & 0 deletions clang/utils/TableGen/ClangAttrEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3078,6 +3078,17 @@ static void emitAttributes(const RecordKeeper &Records, raw_ostream &OS,

OS << " {\n";

// The generator puts the arguments for each attribute in the child class,
// even if those are set in the inherited attribute class (in the TD
// file). This means I cannot access those from the parent class, and have
// to do this weirdness. Maybe the generator should be changed to
// arguments are put in the class they are declared in inside the TD file?
if (HLSLSemantic) {
OS << " if (SemanticExplicitIndex)\n";
OS << " setSemanticIndex(SemanticIndex);\n";
OS << " setTargetDecl(Target);\n";
}

Comment on lines +3081 to +3091
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Someone with more knowledge will have to comment on the best way to do this.

for (auto const &ai : Args) {
if (!shouldEmitArg(ai))
continue;
Expand Down