llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Nathan Gauër (Keenuts) <details> <summary>Changes</summary> This is a re-land of #<!-- -->152537 now that #<!-- -->157841 is merged. --- Patch is 40.11 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/158044.diff 22 Files Affected: - (modified) clang/include/clang/AST/Attr.h (+34) - (modified) clang/include/clang/Basic/Attr.td (+35-31) - (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+4) - (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+2-3) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+5) - (modified) clang/include/clang/Parse/Parser.h (+8) - (modified) clang/include/clang/Sema/SemaHLSL.h (+21-4) - (modified) clang/lib/Basic/Attributes.cpp (+6-1) - (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+53-19) - (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+22-2) - (modified) clang/lib/Parse/ParseHLSL.cpp (+57-10) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+3-15) - (modified) clang/lib/Sema/SemaHLSL.cpp (+80-33) - (added) clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl (+8) - (added) clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl (+9) - (added) clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl (+8) - (modified) clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl (+2-2) - (added) clang/test/CodeGenHLSL/semantics/missing.hlsl (+7) - (modified) clang/test/ParserHLSL/semantic_parsing.hlsl (+35-1) - (added) clang/test/ParserHLSL/semantic_parsing_define.hlsl (+7) - (modified) clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl (+6-6) - (modified) clang/utils/TableGen/ClangAttrEmitter.cpp (+7-1) ``````````diff diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index 994f236337b99..fe388b9fa045e 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -232,6 +232,40 @@ 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; + +protected: + HLSLSemanticAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, + attr::Kind AK, bool IsLateParsed, + bool InheritEvenIfAlreadyPresent, bool SemanticIndexable) + : HLSLAnnotationAttr(Context, CommonInfo, AK, IsLateParsed, + InheritEvenIfAlreadyPresent) { + this->SemanticIndexable = SemanticIndexable; + this->SemanticExplicitIndex = false; + } + +public: + bool isSemanticIndexable() const { return SemanticIndexable; } + + void setSemanticIndex(unsigned SemanticIndex) { + this->SemanticIndex = SemanticIndex; + this->SemanticExplicitIndex = true; + } + + unsigned getSemanticIndex() const { return SemanticIndex; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { + return A->getKind() >= attr::FirstHLSLSemanticAttr && + A->getKind() <= attr::LastHLSLSemanticAttr; + } +}; + /// A parameter attribute which changes the argument-passing ABI rule /// for the parameter. class ParameterABIAttr : public InheritableParamAttr { diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 1e48fa5a390f7..cdaed4a176735 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -779,6 +779,16 @@ class DeclOrStmtAttr : InheritableAttr; /// An attribute class for HLSL Annotations. class HLSLAnnotationAttr : InheritableAttr; +class HLSLSemanticAttr<bit Indexable> : HLSLAnnotationAttr { + bit SemanticIndexable = Indexable; + int SemanticIndex = 0; + bit SemanticExplicitIndex = 0; + + let Spellings = []; + let Subjects = SubjectList<[ParmVar, Field, Function]>; + let LangOpts = [HLSL]; +} + /// 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<TargetSpec target> { @@ -4890,27 +4900,6 @@ def HLSLNumThreads: InheritableAttr { let Documentation = [NumThreadsDocs]; } -def HLSLSV_GroupThreadID: HLSLAnnotationAttr { - let Spellings = [HLSLAnnotation<"sv_groupthreadid">]; - let Subjects = SubjectList<[ParmVar, Field]>; - let LangOpts = [HLSL]; - let Documentation = [HLSLSV_GroupThreadIDDocs]; -} - -def HLSLSV_GroupID: HLSLAnnotationAttr { - let Spellings = [HLSLAnnotation<"sv_groupid">]; - let Subjects = SubjectList<[ParmVar, Field]>; - let LangOpts = [HLSL]; - let Documentation = [HLSLSV_GroupIDDocs]; -} - -def HLSLSV_GroupIndex: HLSLAnnotationAttr { - let Spellings = [HLSLAnnotation<"sv_groupindex">]; - let Subjects = SubjectList<[ParmVar, GlobalVar]>; - let LangOpts = [HLSL]; - let Documentation = [HLSLSV_GroupIndexDocs]; -} - def HLSLVkBinding : InheritableAttr { let Spellings = [CXX11<"vk", "binding">]; let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar], ErrorDiag>; @@ -4969,13 +4958,35 @@ def HLSLResourceBinding: InheritableAttr { }]; } -def HLSLSV_Position : HLSLAnnotationAttr { - let Spellings = [HLSLAnnotation<"sv_position">]; - let Subjects = SubjectList<[ParmVar, Field]>; +def HLSLUnparsedSemantic : HLSLAnnotationAttr { + let Spellings = []; + let Args = [DefaultIntArgument<"Index", 0>, + DefaultBoolArgument<"ExplicitIndex", 0>]; + let Subjects = SubjectList<[ParmVar, Field, Function]>; let LangOpts = [HLSL]; + let Documentation = [InternalOnly]; +} + +def HLSLSV_Position : HLSLSemanticAttr</* Indexable= */ 1> { let Documentation = [HLSLSV_PositionDocs]; } +def HLSLSV_GroupThreadID : HLSLSemanticAttr</* Indexable= */ 0> { + let Documentation = [HLSLSV_GroupThreadIDDocs]; +} + +def HLSLSV_GroupID : HLSLSemanticAttr</* Indexable= */ 0> { + let Documentation = [HLSLSV_GroupIDDocs]; +} + +def HLSLSV_GroupIndex : HLSLSemanticAttr</* Indexable= */ 0> { + let Documentation = [HLSLSV_GroupIndexDocs]; +} + +def HLSLSV_DispatchThreadID : HLSLSemanticAttr</* Indexable= */ 0> { + let Documentation = [HLSLSV_DispatchThreadIDDocs]; +} + def HLSLPackOffset: HLSLAnnotationAttr { let Spellings = [HLSLAnnotation<"packoffset">]; let LangOpts = [HLSL]; @@ -4988,13 +4999,6 @@ def HLSLPackOffset: HLSLAnnotationAttr { }]; } -def HLSLSV_DispatchThreadID: HLSLAnnotationAttr { - let Spellings = [HLSLAnnotation<"sv_dispatchthreadid">]; - let Subjects = SubjectList<[ParmVar, Field]>; - let LangOpts = [HLSL]; - let Documentation = [HLSLSV_DispatchThreadIDDocs]; -} - def HLSLShader : InheritableAttr { let Spellings = [Microsoft<"shader">]; let Subjects = SubjectList<[HLSLEntry]>; diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 15447558cf952..2fd2ae434d7c5 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -400,6 +400,10 @@ def warn_hlsl_langstd_minimal : "recommend using %1 instead">, InGroup<HLSLDXCCompat>; +def err_hlsl_semantic_missing : Error<"semantic annotations must be present " + "for all input and outputs of an entry " + "function or patch constant function">; + // ClangIR frontend errors def err_cir_to_cir_transform_failed : Error< "CIR-to-CIR transformation failed">, DefaultFatal; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index bc7a6e231d93c..968a7c5b0dc8e 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1860,9 +1860,8 @@ def note_max_tokens_total_override : Note<"total token limit set here">; def err_expected_semantic_identifier : Error< "expected HLSL Semantic identifier">; -def err_invalid_declaration_in_hlsl_buffer : Error< - "invalid declaration inside %select{tbuffer|cbuffer}0">; -def err_unknown_hlsl_semantic : Error<"unknown HLSL semantic %0">; +def err_invalid_declaration_in_hlsl_buffer + : Error<"invalid declaration inside %select{tbuffer|cbuffer}0">; def err_hlsl_separate_attr_arg_and_number : Error<"wrong argument format for hlsl attribute, use %0 instead">; def ext_hlsl_access_specifiers : ExtWarn< "access specifiers are a clang HLSL extension">, diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ecdbeb0687cac..b0e669cd3560d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -13121,6 +13121,11 @@ def err_hlsl_duplicate_parameter_modifier : Error<"duplicate parameter modifier def err_hlsl_missing_semantic_annotation : Error< "semantic annotations must be present for all parameters of an entry " "function or patch constant function">; +def err_hlsl_unknown_semantic : Error<"unknown HLSL semantic %0">; +def err_hlsl_semantic_output_not_supported + : Error<"semantic %0 does not support output">; +def err_hlsl_semantic_indexing_not_supported + : Error<"semantic %0 does not allow indexing">; def err_hlsl_init_priority_unsupported : Error< "initializer priorities are not supported in HLSL">; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index a9a87fb586fc2..30edd303e1824 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -5188,6 +5188,14 @@ class Parser : public CodeCompletionHandler { ParseHLSLAnnotations(Attrs, EndLoc); } + struct ParsedSemantic { + StringRef Name = ""; + unsigned Index = 0; + bool Explicit = false; + }; + + ParsedSemantic ParseHLSLSemantic(); + void ParseHLSLAnnotations(ParsedAttributes &Attrs, SourceLocation *EndLoc = nullptr, bool CouldBeBitField = false); diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 4bad26e7a09a7..b5ddca0fe2ca5 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -17,6 +17,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/SemaBase.h" #include "llvm/ADT/SmallVector.h" @@ -129,6 +130,7 @@ class SemaHLSL : public SemaBase { bool ActOnUninitializedVarDecl(VarDecl *D); void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU); void CheckEntryPoint(FunctionDecl *FD); + bool isSemanticValid(FunctionDecl *FD, DeclaratorDecl *D); void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param, const HLSLAnnotationAttr *AnnotationAttr); void DiagnoseAttrStageMismatch( @@ -168,16 +170,31 @@ class SemaHLSL : public SemaBase { void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL); void handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL); void handleVkBindingAttr(Decl *D, const ParsedAttr &AL); - void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL); - void handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL); - void handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL); - void handleSV_PositionAttr(Decl *D, const ParsedAttr &AL); void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL); void handleShaderAttr(Decl *D, const ParsedAttr &AL); void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL); void handleParamModifierAttr(Decl *D, const ParsedAttr &AL); bool handleResourceTypeAttr(QualType T, const ParsedAttr &AL); + template <typename T> + T *createSemanticAttr(const ParsedAttr &AL, + std::optional<unsigned> Location) { + T *Attr = ::new (getASTContext()) T(getASTContext(), AL); + if (Attr->isSemanticIndexable()) + Attr->setSemanticIndex(Location ? *Location : 0); + else if (Location.has_value()) { + Diag(Attr->getLocation(), diag::err_hlsl_semantic_indexing_not_supported) + << Attr->getAttrName()->getName(); + return nullptr; + } + + return Attr; + } + + void diagnoseSystemSemanticAttr(Decl *D, const ParsedAttr &AL, + std::optional<unsigned> Index); + void handleSemanticAttr(Decl *D, const ParsedAttr &AL); + void handleVkExtBuiltinInputAttr(Decl *D, const ParsedAttr &AL); bool CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp index 81b186f844b8a..5878a4e3f83a4 100644 --- a/clang/lib/Basic/Attributes.cpp +++ b/clang/lib/Basic/Attributes.cpp @@ -189,7 +189,12 @@ AttributeCommonInfo::Kind AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name, const IdentifierInfo *ScopeName, Syntax SyntaxUsed) { - return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed); + AttributeCommonInfo::Kind Kind = + ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed); + if (SyntaxUsed == AS_HLSLAnnotation && + Kind == AttributeCommonInfo::Kind::UnknownAttribute) + return AttributeCommonInfo::Kind::AT_HLSLUnparsedSemantic; + return Kind; } AttributeCommonInfo::AttrArgsInfo diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 4c8ece972f754..afee1198e0988 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -23,6 +23,7 @@ #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/Basic/TargetOptions.h" +#include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Frontend/HLSL/RootSignatureMetadata.h" @@ -565,47 +566,78 @@ static llvm::Value *createSPIRVBuiltinLoad(IRBuilder<> &B, llvm::Module &M, return B.CreateLoad(Ty, GV); } -llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B, - const ParmVarDecl &D, - llvm::Type *Ty) { - assert(D.hasAttrs() && "Entry parameter missing annotation attribute!"); - if (D.hasAttr<HLSLSV_GroupIndexAttr>()) { +llvm::Value * +CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, + SemanticInfo &ActiveSemantic) { + if (isa<HLSLSV_GroupIndexAttr>(ActiveSemantic.Semantic)) { llvm::Function *GroupIndex = CGM.getIntrinsic(getFlattenedThreadIdInGroupIntrinsic()); return B.CreateCall(FunctionCallee(GroupIndex)); } - if (D.hasAttr<HLSLSV_DispatchThreadIDAttr>()) { + + if (isa<HLSLSV_DispatchThreadIDAttr>(ActiveSemantic.Semantic)) { llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic(); llvm::Function *ThreadIDIntrinsic = llvm::Intrinsic::isOverloaded(IntrinID) ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty}) : CGM.getIntrinsic(IntrinID); - return buildVectorInput(B, ThreadIDIntrinsic, Ty); + return buildVectorInput(B, ThreadIDIntrinsic, Type); } - if (D.hasAttr<HLSLSV_GroupThreadIDAttr>()) { + + if (isa<HLSLSV_GroupThreadIDAttr>(ActiveSemantic.Semantic)) { llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic(); llvm::Function *GroupThreadIDIntrinsic = llvm::Intrinsic::isOverloaded(IntrinID) ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty}) : CGM.getIntrinsic(IntrinID); - return buildVectorInput(B, GroupThreadIDIntrinsic, Ty); + return buildVectorInput(B, GroupThreadIDIntrinsic, Type); } - if (D.hasAttr<HLSLSV_GroupIDAttr>()) { + + if (isa<HLSLSV_GroupIDAttr>(ActiveSemantic.Semantic)) { llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic(); llvm::Function *GroupIDIntrinsic = llvm::Intrinsic::isOverloaded(IntrinID) ? CGM.getIntrinsic(IntrinID, {CGM.Int32Ty}) : CGM.getIntrinsic(IntrinID); - return buildVectorInput(B, GroupIDIntrinsic, Ty); + return buildVectorInput(B, GroupIDIntrinsic, Type); } - if (D.hasAttr<HLSLSV_PositionAttr>()) { - if (getArch() == llvm::Triple::spirv) - return createSPIRVBuiltinLoad(B, CGM.getModule(), Ty, "sv_position", - /* BuiltIn::Position */ 0); - llvm_unreachable("SV_Position semantic not implemented for this target."); + + if (HLSLSV_PositionAttr *S = + dyn_cast<HLSLSV_PositionAttr>(ActiveSemantic.Semantic)) { + if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel) + return createSPIRVBuiltinLoad(B, CGM.getModule(), Type, + S->getAttrName()->getName(), + /* BuiltIn::FragCoord */ 15); } - assert(false && "Unhandled parameter attribute"); - return nullptr; + + llvm_unreachable("non-handled system semantic. FIXME."); +} + +llvm::Value * +CGHLSLRuntime::handleScalarSemanticLoad(IRBuilder<> &B, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, + SemanticInfo &ActiveSemantic) { + + if (!ActiveSemantic.Semantic) { + ActiveSemantic.Semantic = Decl->getAttr<HLSLSemanticAttr>(); + if (!ActiveSemantic.Semantic) { + CGM.getDiags().Report(Decl->getInnerLocStart(), + diag::err_hlsl_semantic_missing); + return nullptr; + } + ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex(); + } + + return emitSystemSemanticLoad(B, Type, Decl, ActiveSemantic); +} + +llvm::Value * +CGHLSLRuntime::handleSemanticLoad(IRBuilder<> &B, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, + SemanticInfo &ActiveSemantic) { + assert(!Type->isStructTy()); + return handleScalarSemanticLoad(B, Type, Decl, ActiveSemantic); } void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, @@ -650,8 +682,10 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, Args.emplace_back(PoisonValue::get(Param.getType())); continue; } + const ParmVarDecl *PD = FD->getParamDecl(Param.getArgNo() - SRetOffset); - Args.push_back(emitInputSemantic(B, *PD, Param.getType())); + SemanticInfo ActiveSemantic = {nullptr, 0}; + Args.push_back(handleSemanticLoad(B, Param.getType(), PD, ActiveSemantic)); } CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 0948fefe7685e..370f3d5c5d30d 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -21,6 +21,8 @@ #include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsSPIRV.h" +#include "clang/AST/Attr.h" +#include "clang/AST/Decl.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/HLSLRuntime.h" @@ -138,8 +140,26 @@ class CGHLSLRuntime { protected: CodeGenModule &CGM; - llvm::Value *emitInputSemantic(llvm::IRBuilder<> &B, const ParmVarDecl &D, - llvm::Type *Ty); + void collectInputSemantic(llvm::IRBuilder<> &B, const DeclaratorDecl *D, + llvm::Type *Type, + SmallVectorImpl<llvm::Value *> &Inputs); + + struct SemanticInfo { + clang::HLSLSemanticAttr *Semantic; + uint32_t Index; + }; + + llvm::Value *emitSystemSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, + SemanticInfo &ActiveSemantic); + + llvm::Value *handleScalarSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, + SemanticInfo &ActiveSemantic); + + llvm::Value *handleSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, + const clang::DeclaratorDecl *Decl, + SemanticInfo &ActiveSemantic); public: CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {} diff --git a/clang/lib/Parse/ParseHLSL.cpp b/clang/lib/Parse/ParseHLSL.cpp index f243b0cb95eae..51f2aef869649 100644 --- a/clang/lib/Parse/ParseHLSL.cpp +++ b/clang/lib/Parse/ParseHLSL.cpp @@ -118,6 +118,46 @@ static void fixSeparateAttrArgAndNumber(StringRef ArgStr, SourceLocation ArgLoc, Slot = new (Ctx) IdentifierLoc(ArgLoc, PP.getIdentifierInfo(FixedArg)); } +Parser::ParsedSemantic Parser::ParseHLSLSemantic() { + assert(Tok.is(tok::identifier) && "Not a HLSL Annotation"); + + // Semantic pattern: [A-Za-z_]([A-Za-z_0-9]*[A-Za-z_])?[0-9]* + // The first part is the semantic name, the second is the optional + // semantic index. The semantic index is the number at the end of + // the semantic, including leading zeroes. Digits located before + // the last letter are part of the semantic name. + bool Invalid = false; + SmallString<256> Buffer; + Buffer.resize(Tok.getLength() + 1); + StringRef Identifier = PP.getSpelling(Tok, Buffer); + if (Invalid) { + Diag(Tok.getLocation(), diag::err_expected_semantic_identifier); + return {}; + } + + assert(Identifier.size() > 0); + // Determine the start of the semantic index. + unsigned IndexIndex = Identifier.find_last_not_of("0123456789") + 1; + + // ParseHLSLSemantic being called on an indentifier, the first + // character cannot be a digit. This error should be handled by + // the caller. We can assert here. + StringRef SemanticName = Identifier.take_front(IndexIndex); + assert(SemanticName.size() > 0); + + unsigned Index = 0; + bool Explicit = false; + if (IndexIndex != Identifier.size()) { + Explicit = true; + [[maybe_unused]] bool Failure = + Identifier.substr(IndexIndex).getAsInteger(10, Index); + // Given the logi... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/158044 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
