Skip to content
Merged
16 changes: 8 additions & 8 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -4943,25 +4943,25 @@ def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
def HLSLResourceUninitializedHandle : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_uninitializedhandle"];
let Attributes = [NoThrow];
let Prototype = "void(...)";
let Prototype = "__hlsl_resource_t(__hlsl_resource_t)";
}

def HLSLResourceHandleFromBinding : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_handlefrombinding"];
let Attributes = [NoThrow];
let Prototype = "void(...)";
let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t, uint32_t, int32_t, uint32_t, char const*)";
}

def HLSLResourceHandleFromImplicitBinding : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_handlefromimplicitbinding"];
let Attributes = [NoThrow];
let Prototype = "void(...)";
let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t, uint32_t, int32_t, uint32_t, char const*)";
}

def HLSLResourceCounterHandleFromImplicitBinding : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_counterhandlefromimplicitbinding"];
let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
let Attributes = [NoThrow];
let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t, uint32_t)";
}

def HLSLResourceNonUniformIndex : LangBuiltin<"HLSL_LANG"> {
Expand All @@ -4973,13 +4973,13 @@ def HLSLResourceNonUniformIndex : LangBuiltin<"HLSL_LANG"> {
def HLSLResourceGetDimensionsX : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_getdimensions_x"];
let Attributes = [NoThrow];
let Prototype = "void(...)";
let Prototype = "void(__hlsl_resource_t, uint32_t&)";
}

def HLSLResourceGetStride : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_getstride"];
let Attributes = [NoThrow];
let Prototype = "void(...)";
let Prototype = "void(__hlsl_resource_t, uint32_t&)";
}

def HLSLAll : LangBuiltin<"HLSL_LANG"> {
Expand Down Expand Up @@ -5207,7 +5207,7 @@ def HLSLRadians : LangBuiltin<"HLSL_LANG"> {
def HLSLBufferUpdateCounter : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_buffer_update_counter"];
let Attributes = [NoThrow];
let Prototype = "uint32_t(...)";
let Prototype = "uint32_t(__hlsl_resource_t, int)";
}

def HLSLSplitDouble: LangBuiltin<"HLSL_LANG"> {
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12615,6 +12615,9 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
case 'm':
Type = Context.MFloat8Ty;
break;
case 'r':
Type = Context.HLSLResourceTy;
break;
}

// If there are modifiers and if we're allowed to parse them, go for it.
Expand Down
57 changes: 6 additions & 51 deletions clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3050,54 +3050,29 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
break;
}
case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
if (SemaRef.checkArgCount(TheCall, 1) ||
CheckResourceHandle(&SemaRef, TheCall, 0))
return true;
assert(TheCall->getNumArgs() == 1 && "expected 1 arg");
// use the type of the handle (arg0) as a return type
QualType ResourceTy = TheCall->getArg(0)->getType();
TheCall->setType(ResourceTy);
break;
}
case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
ASTContext &AST = SemaRef.getASTContext();
if (SemaRef.checkArgCount(TheCall, 6) ||
CheckResourceHandle(&SemaRef, TheCall, 0) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(3), AST.IntTy) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(4), AST.UnsignedIntTy) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(5),
AST.getPointerType(AST.CharTy.withConst())))
return true;
assert(TheCall->getNumArgs() == 6 && "expected 6 args");
// use the type of the handle (arg0) as a return type
QualType ResourceTy = TheCall->getArg(0)->getType();
TheCall->setType(ResourceTy);
break;
}
case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
ASTContext &AST = SemaRef.getASTContext();
if (SemaRef.checkArgCount(TheCall, 6) ||
CheckResourceHandle(&SemaRef, TheCall, 0) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(3), AST.IntTy) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(4), AST.UnsignedIntTy) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(5),
AST.getPointerType(AST.CharTy.withConst())))
return true;
assert(TheCall->getNumArgs() == 6 && "expected 6 args");
// use the type of the handle (arg0) as a return type
QualType ResourceTy = TheCall->getArg(0)->getType();
TheCall->setType(ResourceTy);
break;
}
case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
assert(TheCall->getNumArgs() == 3 && "expected 3 args");
ASTContext &AST = SemaRef.getASTContext();
if (SemaRef.checkArgCount(TheCall, 3) ||
CheckResourceHandle(&SemaRef, TheCall, 0) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy))
return true;

QualType MainHandleTy = TheCall->getArg(0)->getType();
auto *MainResType = MainHandleTy->getAs<HLSLAttributedResourceType>();
auto MainAttrs = MainResType->getAttrs();
Expand All @@ -3109,24 +3084,6 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
TheCall->setType(CounterHandleTy);
break;
}
case Builtin::BI__builtin_hlsl_resource_getdimensions_x: {
ASTContext &AST = SemaRef.getASTContext();
if (SemaRef.checkArgCount(TheCall, 2) ||
CheckResourceHandle(&SemaRef, TheCall, 0) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
CheckModifiableLValue(&SemaRef, TheCall, 1))
return true;
break;
}
case Builtin::BI__builtin_hlsl_resource_getstride: {
ASTContext &AST = SemaRef.getASTContext();
if (SemaRef.checkArgCount(TheCall, 2) ||
CheckResourceHandle(&SemaRef, TheCall, 0) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
CheckModifiableLValue(&SemaRef, TheCall, 1))
return true;
break;
}
case Builtin::BI__builtin_hlsl_and:
case Builtin::BI__builtin_hlsl_or: {
if (SemaRef.checkArgCount(TheCall, 2))
Expand Down Expand Up @@ -3424,14 +3381,12 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
break;
}
case Builtin::BI__builtin_hlsl_buffer_update_counter: {
assert(TheCall->getNumArgs() == 2 && "expected 2 args");
auto checkResTy = [](const HLSLAttributedResourceType *ResTy) -> bool {
return !(ResTy->getAttrs().ResourceClass == ResourceClass::UAV &&
ResTy->getAttrs().RawBuffer && ResTy->hasContainedType());
};
if (SemaRef.checkArgCount(TheCall, 2) ||
CheckResourceHandle(&SemaRef, TheCall, 0, checkResTy) ||
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1),
SemaRef.getASTContext().IntTy))
if (CheckResourceHandle(&SemaRef, TheCall, 0, checkResTy))
return true;
Expr *OffsetExpr = TheCall->getArg(1);
std::optional<llvm::APSInt> Offset =
Expand Down
42 changes: 28 additions & 14 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1825,20 +1825,34 @@ TryImplicitConversion(Sema &S, Expr *From, QualType ToType,
return ICS;
}

if (S.getLangOpts().HLSL && ToType->isHLSLAttributedResourceType() &&
FromType->isHLSLAttributedResourceType()) {
auto *ToResType = cast<HLSLAttributedResourceType>(ToType);
auto *FromResType = cast<HLSLAttributedResourceType>(FromType);
if (S.Context.hasSameUnqualifiedType(ToResType->getWrappedType(),
FromResType->getWrappedType()) &&
S.Context.hasSameUnqualifiedType(ToResType->getContainedType(),
FromResType->getContainedType()) &&
ToResType->getAttrs() == FromResType->getAttrs()) {
ICS.setStandard();
ICS.Standard.setAsIdentityConversion();
ICS.Standard.setFromType(FromType);
ICS.Standard.setAllToTypes(ToType);
return ICS;
if (S.getLangOpts().HLSL) {
// Handle conversion of the HLSL resource types.
const Type *FromTy = FromType->getUnqualifiedDesugaredType();
if (FromTy->isHLSLAttributedResourceType()) {
// Attributed resource types can convert to other attributed
// resource types with the same attributes and contained types,
// or to __hlsl_resource_t without any attributes.
bool CanConvert = false;
const Type *ToTy = ToType->getUnqualifiedDesugaredType();
if (ToTy->isHLSLAttributedResourceType()) {
auto *ToResType = cast<HLSLAttributedResourceType>(ToTy);
auto *FromResType = cast<HLSLAttributedResourceType>(FromTy);
if (S.Context.hasSameUnqualifiedType(ToResType->getWrappedType(),
FromResType->getWrappedType()) &&
S.Context.hasSameUnqualifiedType(ToResType->getContainedType(),
FromResType->getContainedType()) &&
ToResType->getAttrs() == FromResType->getAttrs())
CanConvert = true;
} else if (ToTy->isHLSLResourceType()) {
CanConvert = true;
}
if (CanConvert) {
ICS.setStandard();
ICS.Standard.setAsIdentityConversion();
ICS.Standard.setFromType(FromType);
ICS.Standard.setAllToTypes(ToType);
return ICS;
}
}
}

Expand Down
16 changes: 8 additions & 8 deletions clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ RESOURCE Buffer;
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_uninitializedhandle'
// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t (*)(__hlsl_resource_t) noexcept' <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_uninitializedhandle' '__hlsl_resource_t (__hlsl_resource_t) noexcept'
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-NEXT: AlwaysInlineAttr
Expand Down Expand Up @@ -97,8 +97,8 @@ RESOURCE Buffer;
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]'
// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept'
// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t (*)(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char *) noexcept' <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' '__hlsl_resource_t (__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char *) noexcept'
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]'
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int'
Expand Down Expand Up @@ -127,8 +127,8 @@ RESOURCE Buffer;
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]'
// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept'
// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t (*)(__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char *) noexcept' <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' '__hlsl_resource_t (__hlsl_resource_t, unsigned int, unsigned int, int, unsigned int, const char *) noexcept'
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]'
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int'
Expand All @@ -149,8 +149,8 @@ RESOURCE Buffer;
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: CallExpr {{.*}} 'void'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_x' 'void (...) noexcept'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(__hlsl_resource_t, unsigned int &) noexcept' <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_x' 'void (__hlsl_resource_t, unsigned int &) noexcept'
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle {{.*}}
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'dim' 'unsigned int &__restrict'
Expand Down
Loading
Loading