diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index 14d7caa0e16d7..e36184f232f8a 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -233,44 +233,19 @@ class HLSLAnnotationAttr : public InheritableAttr { } }; -class HLSLSemanticAttr : public HLSLAnnotationAttr { - unsigned SemanticIndex = 0; - LLVM_PREFERRED_TYPE(bool) - unsigned SemanticIndexable : 1; - LLVM_PREFERRED_TYPE(bool) - unsigned SemanticExplicitIndex : 1; - - Decl *TargetDecl = nullptr; - +class HLSLSemanticBaseAttr : public HLSLAnnotationAttr { protected: - HLSLSemanticAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, - attr::Kind AK, bool IsLateParsed, - bool InheritEvenIfAlreadyPresent, bool SemanticIndexable) + HLSLSemanticBaseAttr(ASTContext &Context, + const AttributeCommonInfo &CommonInfo, attr::Kind AK, + bool IsLateParsed, bool InheritEvenIfAlreadyPresent) : HLSLAnnotationAttr(Context, CommonInfo, AK, IsLateParsed, - InheritEvenIfAlreadyPresent) { - this->SemanticIndexable = SemanticIndexable; - this->SemanticExplicitIndex = false; - } + InheritEvenIfAlreadyPresent) {} public: - bool isSemanticIndexable() const { return SemanticIndexable; } - - void setSemanticIndex(unsigned SemanticIndex) { - this->SemanticIndex = SemanticIndex; - this->SemanticExplicitIndex = true; - } - - unsigned getSemanticIndex() const { return SemanticIndex; } - - bool isSemanticIndexExplicit() const { return SemanticExplicitIndex; } - - void setTargetDecl(Decl *D) { TargetDecl = D; } - Decl *getTargetDecl() const { return TargetDecl; } - // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { - return A->getKind() >= attr::FirstHLSLSemanticAttr && - A->getKind() <= attr::LastHLSLSemanticAttr; + return A->getKind() >= attr::FirstHLSLSemanticBaseAttr && + A->getKind() <= attr::LastHLSLSemanticBaseAttr; } }; diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 1013bfc575747..9081897bbf147 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -779,18 +779,6 @@ class DeclOrStmtAttr : InheritableAttr; /// An attribute class for HLSL Annotations. class HLSLAnnotationAttr : InheritableAttr; -class HLSLSemanticAttr : HLSLAnnotationAttr { - bit SemanticIndexable = Indexable; - int SemanticIndex = 0; - bit SemanticExplicitIndex = 0; - - let Spellings = []; - let Subjects = SubjectList<[ParmVar, Field, Function]>; - let LangOpts = [HLSL]; - let Args = [DeclArgument, IntArgument<"SemanticIndex">, - BoolArgument<"SemanticExplicitIndex">]; -} - /// A target-specific attribute. This class is meant to be used as a mixin /// with InheritableAttr or Attr depending on the attribute's needs. class TargetSpecificAttr { @@ -5017,28 +5005,30 @@ def HLSLUnparsedSemantic : HLSLAnnotationAttr { let Documentation = [InternalOnly]; } -def HLSLUserSemantic : HLSLSemanticAttr { - let Documentation = [InternalOnly]; -} +class HLSLSemanticBaseAttr : HLSLAnnotationAttr { + int SemanticIndex = 0; -def HLSLSV_Position : HLSLSemanticAttr { - let Documentation = [HLSLSV_PositionDocs]; + let Spellings = []; + let Subjects = SubjectList<[ParmVar, Field, Function]>; + let LangOpts = [HLSL]; } -def HLSLSV_GroupThreadID : HLSLSemanticAttr { - let Documentation = [HLSLSV_GroupThreadIDDocs]; -} +def HLSLParsedSemantic : HLSLSemanticBaseAttr { + let Spellings = []; + let Subjects = SubjectList<[ParmVar, Field, Function]>; + let LangOpts = [HLSL]; + let Documentation = [InternalOnly]; -def HLSLSV_GroupID : HLSLSemanticAttr { - let Documentation = [HLSLSV_GroupIDDocs]; + let Args = [StringArgument<"SemanticName">, IntArgument<"SemanticIndex">]; } -def HLSLSV_GroupIndex : HLSLSemanticAttr { - let Documentation = [HLSLSV_GroupIndexDocs]; -} +def HLSLAppliedSemantic : HLSLSemanticBaseAttr { + let Spellings = []; + let Subjects = SubjectList<[ParmVar, Field, Function]>; + let LangOpts = [HLSL]; + let Documentation = [InternalOnly]; -def HLSLSV_DispatchThreadID : HLSLSemanticAttr { - let Documentation = [HLSLSV_DispatchThreadIDDocs]; + let Args = [StringArgument<"SemanticName">, IntArgument<"SemanticIndex">]; } def HLSLPackOffset: HLSLAnnotationAttr { diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 1be9a96aa44de..e064e69ce6ece 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -8672,38 +8672,6 @@ randomized. }]; } -def HLSLSV_GroupThreadIDDocs : Documentation { - let Category = DocHLSLSemantics; - let Content = [{ -The ``SV_GroupThreadID`` semantic, when applied to an input parameter, specifies which -individual thread within a thread group is executing in. This attribute is -only supported in compute shaders. - -The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupthreadid - }]; -} - -def HLSLSV_GroupIDDocs : Documentation { - let Category = DocHLSLSemantics; - let Content = [{ -The ``SV_GroupID`` semantic, when applied to an input parameter, specifies which -thread group a shader is executing in. This attribute is only supported in compute shaders. - -The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupid - }]; -} - -def HLSLSV_GroupIndexDocs : Documentation { - let Category = DocHLSLSemantics; - let Content = [{ -The ``SV_GroupIndex`` semantic, when applied to an input parameter, specifies a -data binding to map the group index to the specified parameter. This attribute -is only supported in compute shaders. - -The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupindex - }]; -} - def HLSLResourceBindingDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -8750,35 +8718,6 @@ The full documentation is available here: https://learn.microsoft.com/en-us/wind }]; } -def HLSLSV_DispatchThreadIDDocs : Documentation { - let Category = DocHLSLSemantics; - let Content = [{ -The ``SV_DispatchThreadID`` semantic, when applied to an input parameter, -specifies a data binding to map the global thread offset within the Dispatch -call (per dimension of the group) to the specified parameter. -When applied to a field of a struct, the data binding is specified to the field -when the struct is used as a parameter type. -The semantic on the field is ignored when not used as a parameter. -This attribute is only supported in compute shaders. - -The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-dispatchthreadid - }]; -} - -def HLSLSV_PositionDocs : Documentation { - let Category = DocHLSLSemantics; - let Content = [{ -The ``SV_Position`` semantic, when applied to an input parameter in a pixel -shader, contains the location of the pixel center (x, y) in screen space. -This semantic can be applied to the parameter, or a field in a struct used -as an input parameter. -This attribute is supported as an input in pixel, hull, domain and mesh shaders. -This attribute is supported as an output in vertex, geometry and domain shaders. - -The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics - }]; -} - def HLSLGroupSharedAddressSpaceDocs : Documentation { let Category = DocCatVariable; let Content = [{ diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 28b03ac4c4676..86da323892f98 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -178,18 +178,11 @@ class SemaHLSL : public SemaBase { bool handleResourceTypeAttr(QualType T, const ParsedAttr &AL); template - T *createSemanticAttr(const AttributeCommonInfo &ACI, NamedDecl *TargetDecl, + T *createSemanticAttr(const AttributeCommonInfo &ACI, std::optional Location) { - T *Attr = - ::new (getASTContext()) T(getASTContext(), ACI, TargetDecl, - Location.value_or(0), Location.has_value()); - - if (!Attr->isSemanticIndexable() && Location.has_value()) { - Diag(Attr->getLocation(), diag::err_hlsl_semantic_indexing_not_supported) - << Attr->getAttrName()->getName(); - return nullptr; - } - return Attr; + return ::new (getASTContext()) + T(getASTContext(), ACI, ACI.getAttrName()->getName(), + Location.value_or(0)); } void diagnoseSystemSemanticAttr(Decl *D, const ParsedAttr &AL, @@ -247,7 +240,7 @@ class SemaHLSL : public SemaBase { IdentifierInfo *RootSigOverrideIdent = nullptr; struct SemanticInfo { - HLSLSemanticAttr *Semantic; + HLSLParsedSemanticAttr *Semantic; std::optional Index; }; @@ -257,14 +250,14 @@ class SemaHLSL : public SemaBase { const RecordType *RT); void checkSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param, - const HLSLSemanticAttr *SemanticAttr); - HLSLSemanticAttr *createSemantic(const SemanticInfo &Semantic, - DeclaratorDecl *TargetDecl); - bool determineActiveSemanticOnScalar(FunctionDecl *FD, DeclaratorDecl *D, + const HLSLAppliedSemanticAttr *SemanticAttr); + bool determineActiveSemanticOnScalar(FunctionDecl *FD, + DeclaratorDecl *OutputDecl, + DeclaratorDecl *D, SemanticInfo &ActiveSemantic, llvm::StringSet<> &ActiveInputSemantics); - bool determineActiveSemantic(FunctionDecl *FD, DeclaratorDecl *D, - SemanticInfo &ActiveSemantic, + bool determineActiveSemantic(FunctionDecl *FD, DeclaratorDecl *OutputDecl, + DeclaratorDecl *D, SemanticInfo &ActiveSemantic, llvm::StringSet<> &ActiveInputSemantics); void processExplicitBindingsOnDecl(VarDecl *D); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index e392a12044a39..d40ba2539cd00 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -587,7 +587,7 @@ static llvm::Value *createSPIRVLocationLoad(IRBuilder<> &B, llvm::Module &M, llvm::Value * CGHLSLRuntime::emitSPIRVUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, - HLSLSemanticAttr *Semantic, + HLSLAppliedSemanticAttr *Semantic, std::optional Index) { Twine BaseName = Twine(Semantic->getAttrName()->getName()); Twine VariableName = BaseName.concat(Twine(Index.value_or(0))); @@ -605,7 +605,7 @@ CGHLSLRuntime::emitSPIRVUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, llvm::Value * CGHLSLRuntime::emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, - HLSLSemanticAttr *Semantic, + HLSLAppliedSemanticAttr *Semantic, std::optional Index) { Twine BaseName = Twine(Semantic->getAttrName()->getName()); Twine VariableName = BaseName.concat(Twine(Index.value_or(0))); @@ -625,7 +625,7 @@ CGHLSLRuntime::emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, llvm::Value *CGHLSLRuntime::emitUserSemanticLoad( IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, - HLSLSemanticAttr *Semantic, std::optional Index) { + HLSLAppliedSemanticAttr *Semantic, std::optional Index) { if (CGM.getTarget().getTriple().isSPIRV()) return emitSPIRVUserSemanticLoad(B, Type, Semantic, Index); @@ -637,14 +637,16 @@ llvm::Value *CGHLSLRuntime::emitUserSemanticLoad( llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad( IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, - Attr *Semantic, std::optional Index) { - if (isa(Semantic)) { + HLSLSemanticBaseAttr *Semantic, std::optional Index) { + + std::string SemanticName = Semantic->getAttrName()->getName().upper(); + if (SemanticName == "SV_GROUPINDEX") { llvm::Function *GroupIndex = CGM.getIntrinsic(getFlattenedThreadIdInGroupIntrinsic()); return B.CreateCall(FunctionCallee(GroupIndex)); } - if (isa(Semantic)) { + if (SemanticName == "SV_DISPATCHTHREADID") { llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic(); llvm::Function *ThreadIDIntrinsic = llvm::Intrinsic::isOverloaded(IntrinID) @@ -653,7 +655,7 @@ llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad( return buildVectorInput(B, ThreadIDIntrinsic, Type); } - if (isa(Semantic)) { + if (SemanticName == "SV_GROUPTHREADID") { llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic(); llvm::Function *GroupThreadIDIntrinsic = llvm::Intrinsic::isOverloaded(IntrinID) @@ -662,7 +664,7 @@ llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad( return buildVectorInput(B, GroupThreadIDIntrinsic, Type); } - if (isa(Semantic)) { + if (SemanticName == "SV_GROUPID") { llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic(); llvm::Function *GroupIDIntrinsic = llvm::Intrinsic::isOverloaded(IntrinID) @@ -671,44 +673,31 @@ llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad( return buildVectorInput(B, GroupIDIntrinsic, Type); } - if (HLSLSV_PositionAttr *S = dyn_cast(Semantic)) { + if (SemanticName == "SV_POSITION") { if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel) return createSPIRVBuiltinLoad(B, CGM.getModule(), Type, - S->getAttrName()->getName(), + Semantic->getAttrName()->getName(), /* BuiltIn::FragCoord */ 15); } llvm_unreachable("non-handled system semantic. FIXME."); } -llvm::Value * -CGHLSLRuntime::handleScalarSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD, - llvm::Type *Type, - const clang::DeclaratorDecl *Decl) { - - HLSLSemanticAttr *Semantic = nullptr; - for (HLSLSemanticAttr *Item : FD->specific_attrs()) { - if (Item->getTargetDecl() == Decl) { - Semantic = Item; - break; - } - } - // Sema must create one attribute per scalar field. - assert(Semantic); - - std::optional Index = std::nullopt; - if (Semantic->isSemanticIndexExplicit()) - Index = Semantic->getSemanticIndex(); +llvm::Value *CGHLSLRuntime::handleScalarSemanticLoad( + IRBuilder<> &B, const FunctionDecl *FD, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, HLSLAppliedSemanticAttr *Semantic) { - if (isa(Semantic)) - return emitUserSemanticLoad(B, Type, Decl, Semantic, Index); - return emitSystemSemanticLoad(B, Type, Decl, Semantic, Index); + std::optional Index = Semantic->getSemanticIndex(); + if (Semantic->getAttrName()->getName().starts_with_insensitive("SV_")) + return emitSystemSemanticLoad(B, Type, Decl, Semantic, Index); + return emitUserSemanticLoad(B, Type, Decl, Semantic, Index); } -llvm::Value * -CGHLSLRuntime::handleStructSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD, - llvm::Type *Type, - const clang::DeclaratorDecl *Decl) { +llvm::Value *CGHLSLRuntime::handleStructSemanticLoad( + IRBuilder<> &B, const FunctionDecl *FD, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, + specific_attr_iterator &begin, + specific_attr_iterator end) { const llvm::StructType *ST = cast(Type); const clang::RecordDecl *RD = Decl->getType()->getAsRecordDecl(); @@ -718,8 +707,8 @@ CGHLSLRuntime::handleStructSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD, llvm::Value *Aggregate = llvm::PoisonValue::get(Type); auto FieldDecl = RD->field_begin(); for (unsigned I = 0; I < ST->getNumElements(); ++I) { - llvm::Value *ChildValue = - handleSemanticLoad(B, FD, ST->getElementType(I), *FieldDecl); + llvm::Value *ChildValue = handleSemanticLoad(B, FD, ST->getElementType(I), + *FieldDecl, begin, end); assert(ChildValue); Aggregate = B.CreateInsertValue(Aggregate, ChildValue, I); ++FieldDecl; @@ -728,13 +717,18 @@ CGHLSLRuntime::handleStructSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD, return Aggregate; } -llvm::Value * -CGHLSLRuntime::handleSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD, - llvm::Type *Type, - const clang::DeclaratorDecl *Decl) { +llvm::Value *CGHLSLRuntime::handleSemanticLoad( + IRBuilder<> &B, const FunctionDecl *FD, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, + specific_attr_iterator &begin, + specific_attr_iterator end) { + assert(end != begin); if (Type->isStructTy()) - return handleStructSemanticLoad(B, FD, Type, Decl); - return handleScalarSemanticLoad(B, FD, Type, Decl); + return handleStructSemanticLoad(B, FD, Type, Decl, begin, end); + + HLSLAppliedSemanticAttr *Attr = *begin; + ++begin; + return handleScalarSemanticLoad(B, FD, Type, Decl, Attr); } void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, @@ -781,6 +775,8 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, } const ParmVarDecl *PD = FD->getParamDecl(Param.getArgNo() - SRetOffset); + auto AttrBegin = PD->specific_attr_begin(); + auto AttrEnd = PD->specific_attr_end(); llvm::Value *SemanticValue = nullptr; if ([[maybe_unused]] HLSLParamModifierAttr *MA = PD->getAttr()) { @@ -788,7 +784,8 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, } else { llvm::Type *ParamType = Param.hasByValAttr() ? Param.getParamByValType() : Param.getType(); - SemanticValue = handleSemanticLoad(B, FD, ParamType, PD); + SemanticValue = + handleSemanticLoad(B, FD, ParamType, PD, AttrBegin, AttrEnd); if (!SemanticValue) return; if (Param.hasByValAttr()) { diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 9d31714ab8606..1c844f8c218ef 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -146,22 +146,26 @@ class CGHLSLRuntime { llvm::Value *emitSystemSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, - Attr *Semantic, + HLSLSemanticBaseAttr *Semantic, std::optional Index); llvm::Value *handleScalarSemanticLoad(llvm::IRBuilder<> &B, const FunctionDecl *FD, llvm::Type *Type, - const clang::DeclaratorDecl *Decl); + const clang::DeclaratorDecl *Decl, + HLSLAppliedSemanticAttr *Semantic); - llvm::Value *handleStructSemanticLoad(llvm::IRBuilder<> &B, - const FunctionDecl *FD, - llvm::Type *Type, - const clang::DeclaratorDecl *Decl); + llvm::Value *handleStructSemanticLoad( + llvm::IRBuilder<> &B, const FunctionDecl *FD, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, + specific_attr_iterator &begin, + specific_attr_iterator end); - llvm::Value *handleSemanticLoad(llvm::IRBuilder<> &B, const FunctionDecl *FD, - llvm::Type *Type, - const clang::DeclaratorDecl *Decl); + llvm::Value * + handleSemanticLoad(llvm::IRBuilder<> &B, const FunctionDecl *FD, + llvm::Type *Type, const clang::DeclaratorDecl *Decl, + specific_attr_iterator &begin, + specific_attr_iterator end); public: CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {} @@ -205,14 +209,14 @@ class CGHLSLRuntime { HLSLResourceBindingAttr *RBA); llvm::Value *emitSPIRVUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, - HLSLSemanticAttr *Semantic, + HLSLAppliedSemanticAttr *Semantic, std::optional Index); llvm::Value *emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, - HLSLSemanticAttr *Semantic, + HLSLAppliedSemanticAttr *Semantic, std::optional Index); llvm::Value *emitUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, - HLSLSemanticAttr *Semantic, + HLSLAppliedSemanticAttr *Semantic, std::optional Index); llvm::Triple::ArchType getArch(); diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index a06c57b15c585..70673a52bf830 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -771,44 +771,12 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) { } } -HLSLSemanticAttr *SemaHLSL::createSemantic(const SemanticInfo &Info, - DeclaratorDecl *TargetDecl) { - std::string SemanticName = Info.Semantic->getAttrName()->getName().upper(); - - if (dyn_cast(Info.Semantic)) - return createSemanticAttr(*Info.Semantic, TargetDecl, - Info.Index); - - if (SemanticName == "SV_DISPATCHTHREADID") { - return createSemanticAttr( - *Info.Semantic, TargetDecl, Info.Index); - } else if (SemanticName == "SV_GROUPINDEX") { - return createSemanticAttr(*Info.Semantic, TargetDecl, - Info.Index); - } else if (SemanticName == "SV_GROUPTHREADID") { - return createSemanticAttr(*Info.Semantic, - TargetDecl, Info.Index); - } else if (SemanticName == "SV_GROUPID") { - return createSemanticAttr(*Info.Semantic, TargetDecl, - Info.Index); - } else if (SemanticName == "SV_POSITION") { - return createSemanticAttr(*Info.Semantic, TargetDecl, - Info.Index); - } else - Diag(Info.Semantic->getLoc(), diag::err_hlsl_unknown_semantic) - << *Info.Semantic; - - return nullptr; -} - bool SemaHLSL::determineActiveSemanticOnScalar( - FunctionDecl *FD, DeclaratorDecl *D, SemanticInfo &ActiveSemantic, - llvm::StringSet<> &ActiveInputSemantics) { - + FunctionDecl *FD, DeclaratorDecl *OutputDecl, DeclaratorDecl *D, + SemanticInfo &ActiveSemantic, llvm::StringSet<> &ActiveInputSemantics) { if (ActiveSemantic.Semantic == nullptr) { - ActiveSemantic.Semantic = D->getAttr(); - if (ActiveSemantic.Semantic && - ActiveSemantic.Semantic->isSemanticIndexExplicit()) + ActiveSemantic.Semantic = D->getAttr(); + if (ActiveSemantic.Semantic) ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex(); } @@ -817,12 +785,15 @@ bool SemaHLSL::determineActiveSemanticOnScalar( return false; } - auto *A = createSemantic(ActiveSemantic, D); + auto *A = ::new (getASTContext()) + HLSLAppliedSemanticAttr(getASTContext(), *ActiveSemantic.Semantic, + ActiveSemantic.Semantic->getAttrName()->getName(), + ActiveSemantic.Index.value_or(0)); if (!A) return false; checkSemanticAnnotation(FD, D, A); - FD->addAttr(A); + OutputDecl->addAttr(A); unsigned Location = ActiveSemantic.Index.value_or(0); @@ -846,25 +817,25 @@ bool SemaHLSL::determineActiveSemanticOnScalar( } bool SemaHLSL::determineActiveSemantic( - FunctionDecl *FD, DeclaratorDecl *D, SemanticInfo &ActiveSemantic, - llvm::StringSet<> &ActiveInputSemantics) { + FunctionDecl *FD, DeclaratorDecl *OutputDecl, DeclaratorDecl *D, + SemanticInfo &ActiveSemantic, llvm::StringSet<> &ActiveInputSemantics) { if (ActiveSemantic.Semantic == nullptr) { - ActiveSemantic.Semantic = D->getAttr(); - if (ActiveSemantic.Semantic && - ActiveSemantic.Semantic->isSemanticIndexExplicit()) + ActiveSemantic.Semantic = D->getAttr(); + if (ActiveSemantic.Semantic) ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex(); } const Type *T = D->getType()->getUnqualifiedDesugaredType(); const RecordType *RT = dyn_cast(T); if (!RT) - return determineActiveSemanticOnScalar(FD, D, ActiveSemantic, + return determineActiveSemanticOnScalar(FD, OutputDecl, D, ActiveSemantic, ActiveInputSemantics); const RecordDecl *RD = RT->getDecl(); for (FieldDecl *Field : RD->fields()) { SemanticInfo Info = ActiveSemantic; - if (!determineActiveSemantic(FD, Field, Info, ActiveInputSemantics)) { + if (!determineActiveSemantic(FD, OutputDecl, Field, Info, + ActiveInputSemantics)) { Diag(Field->getLocation(), diag::note_hlsl_semantic_used_here) << Field; return false; } @@ -940,10 +911,11 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) { llvm::StringSet<> ActiveInputSemantics; for (ParmVarDecl *Param : FD->parameters()) { SemanticInfo ActiveSemantic; - ActiveSemantic.Semantic = nullptr; - ActiveSemantic.Index = std::nullopt; + ActiveSemantic.Semantic = Param->getAttr(); + if (ActiveSemantic.Semantic) + ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex(); - if (!determineActiveSemantic(FD, Param, ActiveSemantic, + if (!determineActiveSemantic(FD, Param, Param, ActiveSemantic, ActiveInputSemantics)) { Diag(Param->getLocation(), diag::note_previous_decl) << Param; FD->setInvalidDecl(); @@ -952,34 +924,44 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) { // FIXME: Verify return type semantic annotation. } -void SemaHLSL::checkSemanticAnnotation(FunctionDecl *EntryPoint, - const Decl *Param, - const HLSLSemanticAttr *SemanticAttr) { +void SemaHLSL::checkSemanticAnnotation( + FunctionDecl *EntryPoint, const Decl *Param, + const HLSLAppliedSemanticAttr *SemanticAttr) { auto *ShaderAttr = EntryPoint->getAttr(); assert(ShaderAttr && "Entry point has no shader attribute"); llvm::Triple::EnvironmentType ST = ShaderAttr->getType(); - switch (SemanticAttr->getKind()) { - case attr::HLSLSV_DispatchThreadID: - case attr::HLSLSV_GroupIndex: - case attr::HLSLSV_GroupThreadID: - case attr::HLSLSV_GroupID: - if (ST == llvm::Triple::Compute) - return; - DiagnoseAttrStageMismatch(SemanticAttr, ST, {llvm::Triple::Compute}); - break; - case attr::HLSLSV_Position: + auto SemanticName = SemanticAttr->getSemanticName().upper(); + if (SemanticName == "SV_DISPATCHTHREADID" || + SemanticName == "SV_GROUPINDEX" || SemanticName == "SV_GROUPTHREADID" || + SemanticName == "SV_GROUPID") { + + if (ST != llvm::Triple::Compute) + DiagnoseAttrStageMismatch(SemanticAttr, ST, {llvm::Triple::Compute}); + + if (SemanticAttr->getSemanticIndex() != 0) { + Twine PrettyName = + std::string("'") + SemanticAttr->getSemanticName() + "'"; + Diag(SemanticAttr->getLoc(), + diag::err_hlsl_semantic_indexing_not_supported) + << PrettyName.str(); + } + return; + } + + if (SemanticName == "SV_POSITION") { // TODO(#143523): allow use on other shader types & output once the overall // semantic logic is implemented. if (ST == llvm::Triple::Pixel) return; DiagnoseAttrStageMismatch(SemanticAttr, ST, {llvm::Triple::Pixel}); - break; - case attr::HLSLUserSemantic: return; - default: - llvm_unreachable("Unknown SemanticAttr"); } + + // FIXME: catch-all for non-implemented system semantics reaching this + // location. + if (SemanticAttr->getAttrName()->getName().starts_with_insensitive("SV_")) + llvm_unreachable("Unknown SemanticAttr"); } void SemaHLSL::DiagnoseAttrStageMismatch( @@ -1748,41 +1730,56 @@ void SemaHLSL::diagnoseSystemSemanticAttr(Decl *D, const ParsedAttr &AL, } } - Attr *Attribute = nullptr; if (SemanticName == "SV_DISPATCHTHREADID") { diagnoseInputIDType(ValueType, AL); if (IsOutput) Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL; - Attribute = - createSemanticAttr(AL, nullptr, Index); - } else if (SemanticName == "SV_GROUPINDEX") { + if (Index.has_value()) + Diag(AL.getLoc(), diag::err_hlsl_semantic_indexing_not_supported) << AL; + D->addAttr(createSemanticAttr(AL, Index)); + return; + } + + if (SemanticName == "SV_GROUPINDEX") { if (IsOutput) Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL; - Attribute = createSemanticAttr(AL, nullptr, Index); - } else if (SemanticName == "SV_GROUPTHREADID") { + if (Index.has_value()) + Diag(AL.getLoc(), diag::err_hlsl_semantic_indexing_not_supported) << AL; + D->addAttr(createSemanticAttr(AL, Index)); + return; + } + + if (SemanticName == "SV_GROUPTHREADID") { diagnoseInputIDType(ValueType, AL); if (IsOutput) Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL; - Attribute = - createSemanticAttr(AL, nullptr, Index); - } else if (SemanticName == "SV_GROUPID") { + if (Index.has_value()) + Diag(AL.getLoc(), diag::err_hlsl_semantic_indexing_not_supported) << AL; + D->addAttr(createSemanticAttr(AL, Index)); + return; + } + + if (SemanticName == "SV_GROUPID") { diagnoseInputIDType(ValueType, AL); if (IsOutput) Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL; - Attribute = createSemanticAttr(AL, nullptr, Index); - } else if (SemanticName == "SV_POSITION") { + if (Index.has_value()) + Diag(AL.getLoc(), diag::err_hlsl_semantic_indexing_not_supported) << AL; + D->addAttr(createSemanticAttr(AL, Index)); + return; + } + + if (SemanticName == "SV_POSITION") { const auto *VT = ValueType->getAs(); if (!ValueType->hasFloatingRepresentation() || (VT && VT->getNumElements() > 4)) Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_type) << AL << "float/float1/float2/float3/float4"; - Attribute = createSemanticAttr(AL, nullptr, Index); - } else - Diag(AL.getLoc(), diag::err_hlsl_unknown_semantic) << AL; - - if (!Attribute) + D->addAttr(createSemanticAttr(AL, Index)); return; - D->addAttr(Attribute); + } + + Diag(AL.getLoc(), diag::err_hlsl_unknown_semantic) << AL; } void SemaHLSL::handleSemanticAttr(Decl *D, const ParsedAttr &AL) { @@ -1796,7 +1793,7 @@ void SemaHLSL::handleSemanticAttr(Decl *D, const ParsedAttr &AL) { if (AL.getAttrName()->getName().starts_with_insensitive("SV_")) diagnoseSystemSemanticAttr(D, AL, Index); else - D->addAttr(createSemanticAttr(AL, nullptr, Index)); + D->addAttr(createSemanticAttr(AL, Index)); } void SemaHLSL::handlePackOffsetAttr(Decl *D, const ParsedAttr &AL) { diff --git a/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl b/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl index 9ed545762ec94..b41bb0b0e8995 100644 --- a/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl +++ b/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl @@ -4,5 +4,5 @@ [shader("compute")] [numthreads(8,8,1)] void foo(uint Idx : SV_DispatchThreadID1) { - // expected-error@-1 {{semantic SV_DispatchThreadID does not allow indexing}} + // expected-error@-1 {{semantic 'SV_DispatchThreadID' does not allow indexing}} } diff --git a/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl b/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl index 8fa0b07a36027..795e880fba0fd 100644 --- a/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl +++ b/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl @@ -4,6 +4,11 @@ [shader("compute")] [numthreads(8,8,1)] void foo(uint Idx : SV_GroupID1) { - // expected-error@-1 {{semantic SV_GroupID does not allow indexing}} + // expected-error@-1 {{semantic 'SV_GroupID' does not allow indexing}} } +[shader("compute")] +[numthreads(8,8,1)] +void bar(uint Idx : SV_GROUPID1) { + // expected-error@-1 {{semantic 'SV_GROUPID' does not allow indexing}} +} diff --git a/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl b/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl index da72e85d2600e..1fd5ae4ff488e 100644 --- a/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl +++ b/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl @@ -4,5 +4,5 @@ [shader("compute")] [numthreads(8,8,1)] void foo(uint Idx : SV_GroupThreadID1) { - // expected-error@-1 {{semantic SV_GroupThreadID does not allow indexing}} + // expected-error@-1 {{semantic 'SV_GroupThreadID' does not allow indexing}} } diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl index b2cb3dad9f0ce..f57ac607db5bd 100644 --- a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl +++ b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl @@ -13,14 +13,14 @@ struct S0 { // CHECK: define void @main0() // CHECK-DXIL: %A0 = call [2 x <4 x float>] @llvm.dx.load.input.a2v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison) -// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %A0, 0 -// CHECK-DXIL: %A2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison) -// CHECK-DXIL: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %A2, 1 +// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %A0, 0 +// CHECK-DXIL: %A2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison) +// CHECK-DXIL: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %A2, 1 // CHECK-SPIRV: %[[#A0:]] = load [2 x <4 x float>], ptr addrspace(7) @A0, align 16 // CHECK-SPIRV: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[#A0]], 0 -// CHECK-SPIRV: %[[#A2:]] = load <4 x float>, ptr addrspace(7) @A2, align 16 -// CHECK-SPIRV: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %[[#A2]], 1 +// CHECK-SPIRV: %[[#A01:]] = load <4 x float>, ptr addrspace(7) @A2, align 16 +// CHECK-SPIRV: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %[[#A01]], 1 // CHECK: %[[#ARG:]] = alloca %struct.S0, align 16 // CHECK: store %struct.S0 %[[#TMP1]], ptr %[[#ARG]], align 16 diff --git a/clang/test/ParserHLSL/hlsl_annotations_on_struct_members.hlsl b/clang/test/ParserHLSL/hlsl_annotations_on_struct_members.hlsl index 5b228d039345e..a52c01d772a72 100644 --- a/clang/test/ParserHLSL/hlsl_annotations_on_struct_members.hlsl +++ b/clang/test/ParserHLSL/hlsl_annotations_on_struct_members.hlsl @@ -6,7 +6,7 @@ struct Eg9{ // CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} col:8 implicit struct Eg9 // CHECK: FieldDecl 0x{{[0-9a-f]+}} col:16 referenced a 'unsigned int' - // CHECK: -HLSLSV_DispatchThreadIDAttr 0x{{[0-9a-f]+}} + // CHECK: -HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_DispatchThreadID" 0 unsigned int a : SV_DispatchThreadID; }; Eg9 e9; diff --git a/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl b/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl index bcc94f0632d64..91dbf9c74ad60 100644 --- a/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl +++ b/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl @@ -4,16 +4,15 @@ void CSMain(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : SV_GroupID, uint GThreadID : SV_GroupThreadID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain 'void (int, uint, uint, uint)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:17 GI 'int' -// CHECK-NEXT: HLSLSV_GroupIndexAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupIndex" 0 +// CHECK-NEXT: HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupIndex" 0 // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:42 ID 'uint' -// CHECK-NEXT: HLSLSV_DispatchThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_DispatchThreadID" 0 +// CHECK-NEXT: HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} "SV_DispatchThreadID" 0 // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:73 GID 'uint' -// CHECK-NEXT: HLSLSV_GroupIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupID" 0 +// CHECK-NEXT: HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupID" 0 // 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 +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupThreadID" 0 +// CHECK-NEXT: HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupThreadID" 0 } diff --git a/clang/test/SemaHLSL/Semantics/position.ps.hlsl b/clang/test/SemaHLSL/Semantics/position.ps.hlsl index 27a8e4a0e2662..7adf2a51f01c8 100644 --- a/clang/test/SemaHLSL/Semantics/position.ps.hlsl +++ b/clang/test/SemaHLSL/Semantics/position.ps.hlsl @@ -4,7 +4,6 @@ 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' -// 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' 2 SemanticExplicitIndex +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_Position" 2 +// CHECK-NEXT: HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} "SV_Position" 2 } diff --git a/clang/test/SemaHLSL/Semantics/position.ps.struct.hlsl b/clang/test/SemaHLSL/Semantics/position.ps.struct.hlsl index 9f57231bea0c1..3186aadf19946 100644 --- a/clang/test/SemaHLSL/Semantics/position.ps.struct.hlsl +++ b/clang/test/SemaHLSL/Semantics/position.ps.struct.hlsl @@ -3,17 +3,16 @@ struct S { float4 f0 : SV_Position; // CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:10 f0 'float4':'vector' -// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <<>> 0 +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_Position" 0 float4 f1 : SV_Position3; // CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:10 f1 'float4':'vector' -// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <<>> 3 SemanticExplicitIndex +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_Position" 3 }; // FIXME(Keenuts): add mandatory output semantic once those are implemented. 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' 0 -// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> Field 0x{{[0-9a-fA-F]+}} 'f1' 'float4':'vector' 3 SemanticExplicitIndex +// CHECK-NEXT: HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} "SV_Position" 0 +// CHECK-NEXT: HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} "SV_Position" 3 } diff --git a/clang/test/SemaHLSL/Semantics/position.ps.struct.reuse.hlsl b/clang/test/SemaHLSL/Semantics/position.ps.struct.reuse.hlsl new file mode 100644 index 0000000000000..f12ac4df0c450 --- /dev/null +++ b/clang/test/SemaHLSL/Semantics/position.ps.struct.reuse.hlsl @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-pixel -x hlsl -finclude-default-header -o - %s -ast-dump | FileCheck %s + +struct A { + float4 x : A; +// CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:10 x 'float4':'vector' +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "A" 0 +}; + +struct Top { + A f0 : B; +// CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:5 f0 'A' +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "B" 0 + A f1 : C; +// CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:5 f1 'A' +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "C" 0 +}; + + +// FIXME(Keenuts): add mandatory output semantic once those are implemented. +float4 main(Top s : D) { +// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:8 main 'float4 (Top)' +// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:17 s 'Top' +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "D" 0 +// CHECK-NEXT: HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} "D" 0 +// CHECK-NEXT: HLSLAppliedSemanticAttr 0x{{[0-9a-f]+}} "D" 1 +} diff --git a/clang/test/SemaHLSL/Semantics/semantics-valid.hlsl b/clang/test/SemaHLSL/Semantics/semantics-valid.hlsl index 1e6bae4fcbca5..6d1ce27f6741f 100644 --- a/clang/test/SemaHLSL/Semantics/semantics-valid.hlsl +++ b/clang/test/SemaHLSL/Semantics/semantics-valid.hlsl @@ -1,33 +1,34 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -hlsl-entry CSMain -x hlsl -finclude-default-header -ast-dump -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -ast-dump -o - %s | FileCheck %s struct s_fields { float a : semantic_a; float b : semantic_b; -// CHECK: |-CXXRecordDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-3]]:8 struct s_fields definition -// CHECK: | |-FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:9 a 'float' -// CHECK: | | `-HLSLUserSemanticAttr 0x{{[0-9a-fA-F]+}} -// CHECK: | `-FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:9 b 'float' -// CHECK: | `-HLSLUserSemanticAttr 0x{{[0-9a-fA-F]+}} +// CHECK: CXXRecordDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-3]]:8 struct s_fields definition +// CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:9 a 'float' +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "semantic_a" 0 +// CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:9 b 'float' +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "semantic_b" 0 }; float fn_foo1(float a : a, float b : b) : sem_ret { return 1.0f; } -// CHECK: |-FunctionDecl {{.*}} <{{.*}}> col:7 fn_foo1 'float (float, float)' -// CHECK-NEXT: | |-ParmVarDecl {{.*}} <{{.*}}> col:21 a 'float' -// CHECK-NEXT: | | `-HLSLUserSemanticAttr {{.*}} <{{.*}}> -// CHECK-NEXT: | |-ParmVarDecl {{.*}} <{{.*}}> col:34 b 'float' -// CHECK-NEXT: | | `-HLSLUserSemanticAttr {{.*}} <{{.*}}> -// CHECK-NEXT: | |-CompoundStmt {{.*}} <{{.*}}> -// CHECK-NEXT: | | `-ReturnStmt {{.*}} <{{.*}}> -// CHECK-NEXT: | | `-FloatingLiteral {{.*}} <{{.*}}> 'float' 1.000000e+00 -// CHECK-NEXT: | `-HLSLUserSemanticAttr {{.*}} <{{.*}}> +// CHECK: FunctionDecl {{.*}} <{{.*}}> col:7 fn_foo1 'float (float, float)' +// CHECK-NEXT: ParmVarDecl {{.*}} <{{.*}}> col:21 a 'float' +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "a" 0 +// CHECK-NEXT: ParmVarDecl {{.*}} <{{.*}}> col:34 b 'float' +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "b" 0 +// CHECK-NEXT: CompoundStmt {{.*}} <{{.*}}> +// CHECK-NEXT: ReturnStmt {{.*}} <{{.*}}> +// CHECK-NEXT: FloatingLiteral {{.*}} <{{.*}}> 'float' 1.000000e+00 +// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} <{{.*}}> "sem_ret" 0 + float fn_foo2(float a : a, float b : b) : sem_ret : also_ret { return 1.0f; } -// CHECK: `-FunctionDecl {{.*}} <{{.*}}> col:7 fn_foo2 'float (float, float)' -// CHECK-NEXT: |-ParmVarDecl {{.*}} <{{.*}}> col:21 a 'float' -// CHECK-NEXT: | `-HLSLUserSemanticAttr {{.*}} <{{.*}}> -// CHECK-NEXT: |-ParmVarDecl {{.*}} <{{.*}}> col:34 b 'float' -// CHECK-NEXT: | `-HLSLUserSemanticAttr {{.*}} <{{.*}}> -// CHECK-NEXT: |-CompoundStmt {{.*}} <{{.*}}> -// CHECK-NEXT: | `-ReturnStmt {{.*}} <{{.*}}> -// CHECK-NEXT: | `-FloatingLiteral {{.*}} <{{.*}}> 'float' 1.000000e+00 -// CHECK-NEXT: |-HLSLUserSemanticAttr {{.*}} <{{.*}}> -// CHECK-NEXT: `-HLSLUserSemanticAttr {{.*}} <{{.*}}> +// CHECK: FunctionDecl {{.*}} <{{.*}}> col:7 fn_foo2 'float (float, float)' +// CHECK-NEXT: ParmVarDecl {{.*}} <{{.*}}> col:21 a 'float' +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "a" 0 +// CHECK-NEXT: ParmVarDecl {{.*}} <{{.*}}> col:34 b 'float' +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "b" 0 +// CHECK-NEXT: CompoundStmt {{.*}} <{{.*}}> +// CHECK-NEXT: ReturnStmt {{.*}} <{{.*}}> +// CHECK-NEXT: FloatingLiteral {{.*}} <{{.*}}> 'float' 1.000000e+00 +// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} <{{.*}}> "sem_ret" 0 +// CHECK-NEXT: HLSLParsedSemanticAttr {{.*}} <{{.*}}> "also_ret" 0 diff --git a/clang/test/SemaHLSL/Semantics/valid_entry_parameter.hlsl b/clang/test/SemaHLSL/Semantics/valid_entry_parameter.hlsl index a2203692b582b..6bb9ae8dd1bb0 100644 --- a/clang/test/SemaHLSL/Semantics/valid_entry_parameter.hlsl +++ b/clang/test/SemaHLSL/Semantics/valid_entry_parameter.hlsl @@ -4,91 +4,91 @@ void CSMain(uint ID : SV_DispatchThreadID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain 'void (uint)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:18 ID 'uint' -// CHECK-NEXT: HLSLSV_DispatchThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_DispatchThreadID" 0 } [numthreads(8,8,1)] void CSMain1(uint2 ID : SV_DispatchThreadID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain1 'void (uint2)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:20 ID 'uint2' -// CHECK-NEXT: HLSLSV_DispatchThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_DispatchThreadID" 0 } [numthreads(8,8,1)] void CSMain2(uint3 ID : SV_DispatchThreadID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain2 'void (uint3)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:20 ID 'uint3' -// CHECK-NEXT: HLSLSV_DispatchThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_DispatchThreadID" 0 } [numthreads(8,8,1)] void CSMain3(uint3 : SV_DispatchThreadID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain3 'void (uint3)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:20 'uint3' -// CHECK-NEXT: HLSLSV_DispatchThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_DispatchThreadID" 0 } [numthreads(8,8,1)] void CSMain4(uint3 : SV_DispatchThreadId) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain4 'void (uint3)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:20 'uint3' -// CHECK-NEXT: HLSLSV_DispatchThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_DispatchThreadId" 0 } [numthreads(8,8,1)] void CSMain_GID(uint ID : SV_GroupID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain_GID 'void (uint)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:22 ID 'uint' -// CHECK-NEXT: HLSLSV_GroupIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupID" 0 } [numthreads(8,8,1)] void CSMain1_GID(uint2 ID : SV_GroupID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain1_GID 'void (uint2)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:24 ID 'uint2' -// CHECK-NEXT: HLSLSV_GroupIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupID" 0 } [numthreads(8,8,1)] void CSMain2_GID(uint3 ID : SV_GroupID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain2_GID 'void (uint3)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:24 ID 'uint3' -// CHECK-NEXT: HLSLSV_GroupIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupID" 0 } [numthreads(8,8,1)] void CSMain3_GID(uint3 : SV_GroupID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain3_GID 'void (uint3)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:24 'uint3' -// CHECK-NEXT: HLSLSV_GroupIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupID" 0 } [numthreads(8,8,1)] void CSMain4_GID(uint3 : Sv_GroupId) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain4_GID 'void (uint3)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:24 'uint3' -// CHECK-NEXT: HLSLSV_GroupIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "Sv_GroupId" 0 } [numthreads(8,8,1)] void CSMain_GThreadID(uint ID : SV_GroupThreadID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain_GThreadID 'void (uint)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:28 ID 'uint' -// CHECK-NEXT: HLSLSV_GroupThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupThreadID" 0 } [numthreads(8,8,1)] void CSMain1_GThreadID(uint2 ID : SV_GroupThreadID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain1_GThreadID 'void (uint2)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:30 ID 'uint2' -// CHECK-NEXT: HLSLSV_GroupThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupThreadID" 0 } [numthreads(8,8,1)] void CSMain2_GThreadID(uint3 ID : SV_GroupThreadID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain2_GThreadID 'void (uint3)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:30 ID 'uint3' -// CHECK-NEXT: HLSLSV_GroupThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupThreadID" 0 } [numthreads(8,8,1)] void CSMain3_GThreadID(uint3 : SV_GroupThreadID) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain3_GThreadID 'void (uint3)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:30 'uint3' -// CHECK-NEXT: HLSLSV_GroupThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "SV_GroupThreadID" 0 } [numthreads(8,8,1)] void CSMain4_GThreadID(uint3 : sv_GroupThreadid) { // CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain4_GThreadID 'void (uint3)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:30 'uint3' -// CHECK-NEXT: HLSLSV_GroupThreadIDAttr +// CHECK-NEXT: HLSLParsedSemanticAttr 0x{{[0-9a-f]+}} "sv_GroupThreadid" 0 } diff --git a/clang/test/TableGen/HLSLAttribute-errors.td b/clang/test/TableGen/HLSLAttribute-errors.td index fc9473dcc1fb4..6680762cc6e30 100644 --- a/clang/test/TableGen/HLSLAttribute-errors.td +++ b/clang/test/TableGen/HLSLAttribute-errors.td @@ -7,5 +7,5 @@ def HLSLSV_FAKE: HLSLAnnotationAttr { let Spellings = [HLSLAnnotation<"SV_Fake">]; let Subjects = SubjectList<[ParmVar, Field]>; let LangOpts = [HLSL]; - let Documentation = [HLSLSV_GroupThreadIDDocs]; + let Documentation = []; } diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 183952af590e1..e49dcb9b70b0f 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -2725,15 +2725,12 @@ static void emitAttributes(const RecordKeeper &Records, raw_ostream &OS, assert(!Supers.empty() && "Forgot to specify a superclass for the attr"); std::string SuperName; bool Inheritable = false; - bool HLSLSemantic = false; for (const Record *R : reverse(Supers)) { if (R->getName() != "TargetSpecificAttr" && R->getName() != "DeclOrTypeAttr" && SuperName.empty()) SuperName = R->getName().str(); if (R->getName() == "InheritableAttr") Inheritable = true; - if (R->getName() == "HLSLSemanticAttr") - HLSLSemantic = true; } if (Header) @@ -3057,8 +3054,6 @@ static void emitAttributes(const RecordKeeper &Records, raw_ostream &OS, << (R.getValueAsBit("InheritEvenIfAlreadyPresent") ? "true" : "false"); } - if (HLSLSemantic) - OS << ", " << (R.getValueAsBit("SemanticIndexable") ? "true" : "false"); OS << ")\n"; for (auto const &ai : Args) { @@ -3078,17 +3073,6 @@ 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"; - } - for (auto const &ai : Args) { if (!shouldEmitArg(ai)) continue; @@ -3287,7 +3271,7 @@ static const AttrClassDescriptor AttrClassDescriptors[] = { {"INHERITABLE_PARAM_OR_STMT_ATTR", "InheritableParamOrStmtAttr"}, {"PARAMETER_ABI_ATTR", "ParameterABIAttr"}, {"HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"}, - {"HLSL_SEMANTIC_ATTR", "HLSLSemanticAttr"}}; + {"HLSL_SEMANTIC_ATTR", "HLSLSemanticBaseAttr"}}; static void emitDefaultDefine(raw_ostream &OS, StringRef name, const char *superName) {