@@ -57,6 +57,28 @@ CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
5757 return CD;
5858 return nullptr ;
5959}
60+
61+ ParameterABI convertParamModifierToParamABI (HLSLParamModifierAttr::Spelling Modifier) {
62+ assert (Modifier != HLSLParamModifierAttr::Spelling::Keyword_in &&
63+ " HLSL 'in' parameters modifier cannot be converted to ParameterABI" );
64+ switch (Modifier) {
65+ case HLSLParamModifierAttr::Spelling::Keyword_out:
66+ return ParameterABI::HLSLOut;
67+ case HLSLParamModifierAttr::Spelling::Keyword_inout:
68+ return ParameterABI::HLSLInOut;
69+ default :
70+ llvm_unreachable (" Invalid HLSL parameter modifier" );
71+ }
72+ }
73+
74+ QualType getInoutParameterType (ASTContext &AST, QualType Ty) {
75+ assert (!Ty->isReferenceType () &&
76+ " Pointer and reference types cannot be inout or out parameters" );
77+ Ty = AST.getLValueReferenceType (Ty);
78+ Ty.addRestrict ();
79+ return Ty;
80+ }
81+
6082} // namespace
6183
6284// Builder for template arguments of builtin types. Used internally
@@ -421,13 +443,31 @@ BuiltinTypeMethodBuilder::addParam(StringRef Name, QualType Ty,
421443void BuiltinTypeMethodBuilder::createDecl () {
422444 assert (Method == nullptr && " Method or constructor is already created" );
423445
424- // create method or constructor type
446+ // create function prototype
425447 ASTContext &AST = DeclBuilder.SemaRef .getASTContext ();
426448 SmallVector<QualType> ParamTypes;
427- for (Param &MP : Params)
428- ParamTypes.emplace_back (MP.Ty );
449+ SmallVector<FunctionType::ExtParameterInfo> ParamExtInfos (Params.size ());
450+ uint32_t ArgIndex = 0 ;
451+ bool IsTemplate = DeclBuilder.Template != nullptr ;
452+ bool UseParamExtInfo = false ;
453+ for (Param &MP : Params) {
454+ QualType Ty = MP.Ty ;
455+ if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
456+ UseParamExtInfo = true ;
457+ ParamExtInfos[ArgIndex].withABI (convertParamModifierToParamABI (MP.Modifier ));
458+ // Only update types on inout and out parameters for non-templated
459+ // methods. Templated types will have their inout/out parameters
460+ // converted to references during template instantiation.
461+ if (!IsTemplate)
462+ Ty = getInoutParameterType (AST, Ty);
463+ }
464+ ParamTypes.emplace_back (Ty);
465+ ++ArgIndex;
466+ }
429467
430468 FunctionProtoType::ExtProtoInfo ExtInfo;
469+ if (UseParamExtInfo)
470+ ExtInfo.ExtParameterInfos = ParamExtInfos.data ();
431471 if (IsConst)
432472 ExtInfo.TypeQuals .addConst ();
433473
@@ -459,8 +499,10 @@ void BuiltinTypeMethodBuilder::createDecl() {
459499 AST.getTrivialTypeSourceInfo (MP.Ty , SourceLocation ()), SC_None,
460500 nullptr );
461501 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
502+ // Parm->setType(getInoutParameterType(AST, Parm->getType()));
462503 auto *Mod =
463504 HLSLParamModifierAttr::Create (AST, SourceRange (), MP.Modifier );
505+ Parm->setType (getInoutParameterType (AST, Parm->getType ()));
464506 Parm->addAttr (Mod);
465507 }
466508 Parm->setScopeInfo (CurScopeDepth, I);
@@ -1127,5 +1169,37 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() {
11271169 .finalize ();
11281170}
11291171
1172+ BuiltinTypeDeclBuilder &
1173+ BuiltinTypeDeclBuilder::addGetDimensionsMethodForBuffer () {
1174+ using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1175+ ASTContext &AST = SemaRef.getASTContext ();
1176+ QualType UIntTy = AST.UnsignedIntTy ;
1177+
1178+ QualType HandleTy = getResourceHandleField ()->getType ();
1179+ auto *AttrResTy = cast<HLSLAttributedResourceType>(HandleTy.getTypePtr ());
1180+
1181+ // Structured buffers except {RW}ByteAddressBuffer have overload
1182+ // GetDimensions(out uint numStructs, out uint stride).
1183+ if (AttrResTy->getAttrs ().RawBuffer &&
1184+ AttrResTy->getContainedType () != AST.Char8Ty ) {
1185+ return BuiltinTypeMethodBuilder (*this , " GetDimensions" , AST.VoidTy )
1186+ .addParam (" numStructs" , UIntTy, HLSLParamModifierAttr::Keyword_out)
1187+ .addParam (" stride" , UIntTy, HLSLParamModifierAttr::Keyword_out)
1188+ .callBuiltin (" __builtin_hlsl_buffer_getdimensions" , QualType (),
1189+ PH::Handle, PH::_0)
1190+ .callBuiltin (" __builtin_hlsl_buffer_getstride" , QualType (), PH::Handle,
1191+ PH::_1)
1192+ .finalize ();
1193+ }
1194+
1195+ // Typed buffers and {RW}ByteAddressBuffer have overload
1196+ // GetDimensions(out uint dim).
1197+ return BuiltinTypeMethodBuilder (*this , " GetDimensions" , AST.VoidTy )
1198+ .addParam (" dim" , UIntTy, HLSLParamModifierAttr::Keyword_out)
1199+ .callBuiltin (" __builtin_hlsl_buffer_getdimensions" , QualType (),
1200+ PH::Handle, PH::_0)
1201+ .finalize ();
1202+ }
1203+
11301204} // namespace hlsl
11311205} // namespace clang
0 commit comments