@@ -57,6 +57,29 @@ CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
5757 return CD;
5858 return nullptr ;
5959}
60+
61+ ParameterABI
62+ convertParamModifierToParamABI (HLSLParamModifierAttr::Spelling Modifier) {
63+ assert (Modifier != HLSLParamModifierAttr::Spelling::Keyword_in &&
64+ " HLSL 'in' parameters modifier cannot be converted to ParameterABI" );
65+ switch (Modifier) {
66+ case HLSLParamModifierAttr::Spelling::Keyword_out:
67+ return ParameterABI::HLSLOut;
68+ case HLSLParamModifierAttr::Spelling::Keyword_inout:
69+ return ParameterABI::HLSLInOut;
70+ default :
71+ llvm_unreachable (" Invalid HLSL parameter modifier" );
72+ }
73+ }
74+
75+ QualType getInoutParameterType (ASTContext &AST, QualType Ty) {
76+ assert (!Ty->isReferenceType () &&
77+ " Pointer and reference types cannot be inout or out parameters" );
78+ Ty = AST.getLValueReferenceType (Ty);
79+ Ty.addRestrict ();
80+ return Ty;
81+ }
82+
6083} // namespace
6184
6285// Builder for template arguments of builtin types. Used internally
@@ -430,19 +453,36 @@ BuiltinTypeMethodBuilder::addParam(StringRef Name, QualType Ty,
430453void BuiltinTypeMethodBuilder::createDecl () {
431454 assert (Method == nullptr && " Method or constructor is already created" );
432455
433- // create method or constructor type
456+ // create function prototype
434457 ASTContext &AST = DeclBuilder.SemaRef .getASTContext ();
435458 SmallVector<QualType> ParamTypes;
436- for (Param &MP : Params)
459+ SmallVector<FunctionType::ExtParameterInfo> ParamExtInfos (Params.size ());
460+ uint32_t ArgIndex = 0 ;
461+
462+ // Create function prototype.
463+ bool UseParamExtInfo = false ;
464+ for (Param &MP : Params) {
465+ if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
466+ UseParamExtInfo = true ;
467+ FunctionType::ExtParameterInfo &PI = ParamExtInfos[ArgIndex];
468+ ParamExtInfos[ArgIndex] =
469+ PI.withABI (convertParamModifierToParamABI (MP.Modifier ));
470+ if (!MP.Ty ->isDependentType ())
471+ MP.Ty = getInoutParameterType (AST, MP.Ty );
472+ }
437473 ParamTypes.emplace_back (MP.Ty );
474+ ++ArgIndex;
475+ }
438476
439477 FunctionProtoType::ExtProtoInfo ExtInfo;
478+ if (UseParamExtInfo)
479+ ExtInfo.ExtParameterInfos = ParamExtInfos.data ();
440480 if (IsConst)
441481 ExtInfo.TypeQuals .addConst ();
442482
443483 QualType FuncTy = AST.getFunctionType (ReturnTy, ParamTypes, ExtInfo);
444484
445- // create method or constructor decl
485+ // Create method or constructor declaration.
446486 auto *TSInfo = AST.getTrivialTypeSourceInfo (FuncTy, SourceLocation ());
447487 DeclarationNameInfo NameInfo = DeclarationNameInfo (Name, SourceLocation ());
448488 if (IsCtor)
@@ -455,7 +495,7 @@ void BuiltinTypeMethodBuilder::createDecl() {
455495 AST, DeclBuilder.Record , SourceLocation (), NameInfo, FuncTy, TSInfo, SC,
456496 false , false , ConstexprSpecKind::Unspecified, SourceLocation ());
457497
458- // create params & set them to the function prototype
498+ // Create params & set them to the method/constructor and function prototype.
459499 SmallVector<ParmVarDecl *> ParmDecls;
460500 unsigned CurScopeDepth = DeclBuilder.SemaRef .getCurScope ()->getDepth ();
461501 auto FnProtoLoc =
@@ -1258,5 +1298,37 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() {
12581298 .finalize ();
12591299}
12601300
1301+ BuiltinTypeDeclBuilder &
1302+ BuiltinTypeDeclBuilder::addGetDimensionsMethodForBuffer () {
1303+ using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1304+ ASTContext &AST = SemaRef.getASTContext ();
1305+ QualType UIntTy = AST.UnsignedIntTy ;
1306+
1307+ QualType HandleTy = getResourceHandleField ()->getType ();
1308+ auto *AttrResTy = cast<HLSLAttributedResourceType>(HandleTy.getTypePtr ());
1309+
1310+ // Structured buffers except {RW}ByteAddressBuffer have overload
1311+ // GetDimensions(out uint numStructs, out uint stride).
1312+ if (AttrResTy->getAttrs ().RawBuffer &&
1313+ AttrResTy->getContainedType () != AST.Char8Ty ) {
1314+ return BuiltinTypeMethodBuilder (*this , " GetDimensions" , AST.VoidTy )
1315+ .addParam (" numStructs" , UIntTy, HLSLParamModifierAttr::Keyword_out)
1316+ .addParam (" stride" , UIntTy, HLSLParamModifierAttr::Keyword_out)
1317+ .callBuiltin (" __builtin_hlsl_resource_getdimensions_x" , QualType (),
1318+ PH::Handle, PH::_0)
1319+ .callBuiltin (" __builtin_hlsl_resource_getstride" , QualType (),
1320+ PH::Handle, PH::_1)
1321+ .finalize ();
1322+ }
1323+
1324+ // Typed buffers and {RW}ByteAddressBuffer have overload
1325+ // GetDimensions(out uint dim).
1326+ return BuiltinTypeMethodBuilder (*this , " GetDimensions" , AST.VoidTy )
1327+ .addParam (" dim" , UIntTy, HLSLParamModifierAttr::Keyword_out)
1328+ .callBuiltin (" __builtin_hlsl_resource_getdimensions_x" , QualType (),
1329+ PH::Handle, PH::_0)
1330+ .finalize ();
1331+ }
1332+
12611333} // namespace hlsl
12621334} // namespace clang
0 commit comments