Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
16 changes: 8 additions & 8 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -4937,25 +4937,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 @@ -4967,13 +4967,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 @@ -5201,7 +5201,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 @@ -3011,54 +3011,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 @@ -3070,24 +3045,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 @@ -3385,14 +3342,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