[HLSL] Entry functions require param annotation

HLSL entry function parameters must have parameter annotations. This
allows appropriate intrinsic values to be populated into parameters
during code generation.

This does not handle entry function return values, which will be
handled in a subsequent commit because we don't currently support any
annotations that are valid for function returns.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D131625
This commit is contained in:
Chris Bieneman 2022-08-24 14:34:46 -05:00
parent 322ea53144
commit bdf1327fea
6 changed files with 39 additions and 2 deletions

View File

@ -190,6 +190,22 @@ public:
}
};
class HLSLAnnotationAttr : public InheritableAttr {
protected:
HLSLAnnotationAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
attr::Kind AK, bool IsLateParsed,
bool InheritEvenIfAlreadyPresent)
: InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
InheritEvenIfAlreadyPresent) {}
public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() >= attr::FirstHLSLAnnotationAttr &&
A->getKind() <= attr::LastHLSLAnnotationAttr;
}
};
/// A parameter attribute which changes the argument-passing ABI rule
/// for the parameter.
class ParameterABIAttr : public InheritableParamAttr {

View File

@ -608,6 +608,9 @@ class DeclOrTypeAttr : InheritableAttr;
/// A attribute is either a declaration attribute or a statement attribute.
class DeclOrStmtAttr : InheritableAttr;
/// An attribute class for HLSL Annotations.
class HLSLAnnotationAttr : InheritableAttr;
/// 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> {
@ -4011,7 +4014,7 @@ def HLSLNumThreads: InheritableAttr {
let Documentation = [NumThreadsDocs];
}
def HLSLSV_GroupIndex: InheritableAttr {
def HLSLSV_GroupIndex: HLSLAnnotationAttr {
let Spellings = [HLSLSemantic<"SV_GroupIndex">];
let Subjects = SubjectList<[ParmVar, GlobalVar]>;
let LangOpts = [HLSL];

View File

@ -11643,6 +11643,9 @@ def err_hlsl_numthreads_argument_oor : Error<"argument '%select{X|Y|Z}0' to numt
def err_hlsl_numthreads_invalid : Error<"total number of threads cannot exceed %0">;
def err_hlsl_missing_numthreads : Error<"missing numthreads attribute for %0 shader entry">;
def err_hlsl_attribute_param_mismatch : Error<"%0 attribute parameters do not match the previous declaration">;
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_pointers_unsupported : Error<
"%select{pointers|references}0 are unsupported in HLSL">;

View File

@ -11894,6 +11894,16 @@ void Sema::CheckHLSLEntryPoint(FunctionDecl *FD) {
}
break;
}
for (const auto *Param : FD->parameters()) {
if (!Param->hasAttr<HLSLAnnotationAttr>()) {
// FIXME: Handle struct parameters where annotations are on struct fields.
Diag(FD->getLocation(), diag::err_hlsl_missing_semantic_annotation);
Diag(Param->getLocation(), diag::note_previous_decl) << Param;
FD->setInvalidDecl();
}
}
// FIXME: Verify return type semantic annotation.
}
bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {

View File

@ -0,0 +1,4 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -hlsl-entry main -verify %s
[numthreads(1,1, 1)]
void main(int GI) { } // expected-error{{semantic annotations must be present for all parameters of an entry function or patch constant function}} expected-note{{'GI' declared here}}

View File

@ -2897,7 +2897,8 @@ static const AttrClassDescriptor AttrClassDescriptors[] = {
{ "INHERITABLE_ATTR", "InheritableAttr" },
{ "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" },
{ "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" },
{ "PARAMETER_ABI_ATTR", "ParameterABIAttr" }
{ "PARAMETER_ABI_ATTR", "ParameterABIAttr" },
{ "HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"}
};
static void emitDefaultDefine(raw_ostream &OS, StringRef name,