@@ -57,6 +57,29 @@ CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
57
57
return CD;
58
58
return nullptr ;
59
59
}
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
+
60
83
} // namespace
61
84
62
85
// Builder for template arguments of builtin types. Used internally
@@ -421,13 +444,32 @@ BuiltinTypeMethodBuilder::addParam(StringRef Name, QualType Ty,
421
444
void BuiltinTypeMethodBuilder::createDecl () {
422
445
assert (Method == nullptr && " Method or constructor is already created" );
423
446
424
- // create method or constructor type
447
+ // create function prototype
425
448
ASTContext &AST = DeclBuilder.SemaRef .getASTContext ();
426
449
SmallVector<QualType> ParamTypes;
427
- for (Param &MP : Params)
428
- ParamTypes.emplace_back (MP.Ty );
450
+ SmallVector<FunctionType::ExtParameterInfo> ParamExtInfos (Params.size ());
451
+ uint32_t ArgIndex = 0 ;
452
+ bool IsTemplate = DeclBuilder.Template != nullptr ;
453
+ bool UseParamExtInfo = false ;
454
+ for (Param &MP : Params) {
455
+ QualType Ty = MP.Ty ;
456
+ if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
457
+ UseParamExtInfo = true ;
458
+ ParamExtInfos[ArgIndex].withABI (
459
+ convertParamModifierToParamABI (MP.Modifier ));
460
+ // Only update types on inout and out parameters for non-templated
461
+ // methods. Templated types will have their inout/out parameters
462
+ // converted to references during template instantiation.
463
+ if (!IsTemplate)
464
+ Ty = getInoutParameterType (AST, Ty);
465
+ }
466
+ ParamTypes.emplace_back (Ty);
467
+ ++ArgIndex;
468
+ }
429
469
430
470
FunctionProtoType::ExtProtoInfo ExtInfo;
471
+ if (UseParamExtInfo)
472
+ ExtInfo.ExtParameterInfos = ParamExtInfos.data ();
431
473
if (IsConst)
432
474
ExtInfo.TypeQuals .addConst ();
433
475
@@ -459,6 +501,7 @@ void BuiltinTypeMethodBuilder::createDecl() {
459
501
AST.getTrivialTypeSourceInfo (MP.Ty , SourceLocation ()), SC_None,
460
502
nullptr );
461
503
if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
504
+ Parm->setType (getInoutParameterType (AST, Parm->getType ()));
462
505
auto *Mod =
463
506
HLSLParamModifierAttr::Create (AST, SourceRange (), MP.Modifier );
464
507
Parm->addAttr (Mod);
@@ -1127,5 +1170,37 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() {
1127
1170
.finalize ();
1128
1171
}
1129
1172
1173
+ BuiltinTypeDeclBuilder &
1174
+ BuiltinTypeDeclBuilder::addGetDimensionsMethodForBuffer () {
1175
+ using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1176
+ ASTContext &AST = SemaRef.getASTContext ();
1177
+ QualType UIntTy = AST.UnsignedIntTy ;
1178
+
1179
+ QualType HandleTy = getResourceHandleField ()->getType ();
1180
+ auto *AttrResTy = cast<HLSLAttributedResourceType>(HandleTy.getTypePtr ());
1181
+
1182
+ // Structured buffers except {RW}ByteAddressBuffer have overload
1183
+ // GetDimensions(out uint numStructs, out uint stride).
1184
+ if (AttrResTy->getAttrs ().RawBuffer &&
1185
+ AttrResTy->getContainedType () != AST.Char8Ty ) {
1186
+ return BuiltinTypeMethodBuilder (*this , " GetDimensions" , AST.VoidTy )
1187
+ .addParam (" numStructs" , UIntTy, HLSLParamModifierAttr::Keyword_out)
1188
+ .addParam (" stride" , UIntTy, HLSLParamModifierAttr::Keyword_out)
1189
+ .callBuiltin (" __builtin_hlsl_buffer_getdimensions" , QualType (),
1190
+ PH::Handle, PH::_0)
1191
+ .callBuiltin (" __builtin_hlsl_buffer_getstride" , QualType (), PH::Handle,
1192
+ PH::_1)
1193
+ .finalize ();
1194
+ }
1195
+
1196
+ // Typed buffers and {RW}ByteAddressBuffer have overload
1197
+ // GetDimensions(out uint dim).
1198
+ return BuiltinTypeMethodBuilder (*this , " GetDimensions" , AST.VoidTy )
1199
+ .addParam (" dim" , UIntTy, HLSLParamModifierAttr::Keyword_out)
1200
+ .callBuiltin (" __builtin_hlsl_buffer_getdimensions" , QualType (),
1201
+ PH::Handle, PH::_0)
1202
+ .finalize ();
1203
+ }
1204
+
1130
1205
} // namespace hlsl
1131
1206
} // namespace clang
0 commit comments