30#include "llvm/ADT/SmallVector.h"
32using namespace llvm::hlsl;
40static FunctionDecl *lookupBuiltinFunction(Sema &S, StringRef Name) {
42 S.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
43 DeclarationNameInfo NameInfo =
44 DeclarationNameInfo(DeclarationName(&II), SourceLocation());
48 S.LookupName(R, S.getCurScope());
51 assert(
R.isSingleResult() &&
52 "Since this is a builtin it should always resolve!");
56static QualType lookupBuiltinType(Sema &S, StringRef Name, DeclContext *DC) {
58 S.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
60 S.LookupQualifiedName(
Result, DC);
61 assert(!
Result.empty() &&
"Builtin type not found");
63 S.getASTContext().getTypeDeclType(
Result.getAsSingle<TypeDecl>());
64 S.RequireCompleteType(SourceLocation(), Ty,
65 diag::err_tentative_def_incomplete_type);
69CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
70 assert(ResTy->isRecordType() &&
"not a CXXRecord type");
71 for (
auto *CD : ResTy->getAsCXXRecordDecl()->ctors())
72 if (CD->isCopyConstructor())
78convertParamModifierToParamABI(HLSLParamModifierAttr::Spelling Modifier) {
79 assert(Modifier != HLSLParamModifierAttr::Spelling::Keyword_in &&
80 "HLSL 'in' parameters modifier cannot be converted to ParameterABI");
82 case HLSLParamModifierAttr::Spelling::Keyword_out:
84 case HLSLParamModifierAttr::Spelling::Keyword_inout:
87 llvm_unreachable(
"Invalid HLSL parameter modifier");
91QualType getInoutParameterType(ASTContext &AST, QualType Ty) {
92 assert(!Ty->isReferenceType() &&
93 "Pointer and reference types cannot be inout or out parameters");
148 HLSLParamModifierAttr::Spelling Modifier;
150 HLSLParamModifierAttr::Spelling Modifier)
151 : NameII(NameII), Ty(Ty), Modifier(Modifier) {}
158 LocalVar(StringRef Name,
QualType Ty) : Name(Name), Ty(Ty),
Decl(
nullptr) {}
182 enum class PlaceHolder {
195 Expr *convertPlaceholder(PlaceHolder PH);
196 Expr *convertPlaceholder(LocalVar &Var);
197 Expr *convertPlaceholder(
Expr *E) {
return E; }
205 QualType ReturnTy,
bool IsConst =
false,
207 : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(
nullptr),
208 IsConst(IsConst), IsCtor(IsCtor), SC(SC) {}
211 QualType ReturnTy,
bool IsConst =
false,
221 HLSLParamModifierAttr::Spelling Modifier =
222 HLSLParamModifierAttr::Keyword_in);
225 template <
typename... Ts>
227 QualType ReturnType, Ts &&...ArgSpecs);
228 template <
typename TLHS,
typename TRHS>
231 template <
typename V,
typename S>
234 template <
typename T>
236 template <
typename T>
239 template <
typename ValueT>
242 template <
typename ResourceT,
typename ValueT>
247 template <
typename T>
250 template <
typename ResourceT,
typename ValueT>
265 void ensureCompleteDecl() {
278 assert(!
Builder.Record->isCompleteDefinition() &&
279 "record is already complete");
281 unsigned Position =
static_cast<unsigned>(
Params.size());
285 &AST.
Idents.
get(Name, tok::TokenKind::identifier),
289 if (!DefaultValue.
isNull())
290 Decl->setDefaultArgument(AST,
291 Builder.SemaRef.getTrivialTemplateArgumentLoc(
333 "unexpected concept decl parameter count");
342 Builder.Record->getDeclContext(),
352 T->setDeclContext(DC);
354 QualType ConceptTType = Context.getTypeDeclType(ConceptTTPD);
360 QualType CSETType = Context.getTypeDeclType(T);
368 Context,
Builder.Record->getDeclContext(), Loc, {CSETA});
408 Builder.Template->setImplicit(
true);
409 Builder.Template->setLexicalDeclContext(
Builder.Record->getDeclContext());
420Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) {
421 if (PH == PlaceHolder::Handle)
423 if (PH == PlaceHolder::CounterHandle)
425 if (PH == PlaceHolder::This) {
428 Method->getFunctionObjectParameterType(),
432 if (PH == PlaceHolder::LastStmt) {
433 assert(!StmtsList.empty() &&
"no statements in the list");
434 Stmt *LastStmt = StmtsList.pop_back_val();
435 assert(
isa<ValueStmt>(LastStmt) &&
"last statement does not have a value");
444 ParmVarDecl *ParamDecl = Method->getParamDecl(
static_cast<unsigned>(PH));
446 AST, NestedNameSpecifierLoc(), SourceLocation(), ParamDecl,
false,
447 DeclarationNameInfo(ParamDecl->getDeclName(), SourceLocation()),
448 ParamDecl->getType().getNonReferenceType(),
VK_LValue);
451Expr *BuiltinTypeMethodBuilder::convertPlaceholder(LocalVar &Var) {
452 VarDecl *VD = Var.Decl;
453 assert(VD &&
"local variable is not declared");
455 VD->getASTContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
456 false, DeclarationNameInfo(VD->getDeclName(), SourceLocation()),
460Expr *BuiltinTypeMethodBuilder::convertPlaceholder(QualType Ty) {
461 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
464 return new (AST) CXXScalarValueInitExpr(
472 bool IsConst,
bool IsCtor,
474 : DeclBuilder(DB), ReturnTy(ReturnTy), Method(
nullptr), IsConst(IsConst),
475 IsCtor(IsCtor), SC(SC) {
477 assert((!NameStr.empty() || IsCtor) &&
"method needs a name");
478 assert(((IsCtor && !IsConst) || !IsCtor) &&
"constructor cannot be const");
486 AST.
Idents.
get(NameStr, tok::TokenKind::identifier);
493 HLSLParamModifierAttr::Spelling Modifier) {
494 assert(Method ==
nullptr &&
"Cannot add param, method already created");
495 const IdentifierInfo &II = DeclBuilder.SemaRef.getASTContext().Idents.get(
496 Name, tok::TokenKind::identifier);
497 Params.emplace_back(II, Ty, Modifier);
501 assert(Method ==
nullptr &&
502 "Cannot add template param, method already created");
503 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
504 unsigned Position =
static_cast<unsigned>(TemplateParamDecls.size());
508 &AST.
Idents.
get(Name, tok::TokenKind::identifier),
512 TemplateParamDecls.push_back(
Decl);
517void BuiltinTypeMethodBuilder::createDecl() {
518 assert(
Method ==
nullptr &&
"Method or constructor is already created");
524 uint32_t ArgIndex = 0;
527 bool UseParamExtInfo =
false;
528 for (Param &MP : Params) {
529 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
530 UseParamExtInfo =
true;
532 ParamExtInfos[ArgIndex] =
533 PI.
withABI(convertParamModifierToParamABI(MP.Modifier));
534 if (!MP.Ty->isDependentType())
535 MP.Ty = getInoutParameterType(AST, MP.Ty);
537 ParamTypes.emplace_back(MP.Ty);
541 FunctionProtoType::ExtProtoInfo ExtInfo;
543 ExtInfo.ExtParameterInfos = ParamExtInfos.data();
545 ExtInfo.TypeQuals.addConst();
551 DeclarationNameInfo NameInfo = DeclarationNameInfo(Name, SourceLocation());
554 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo,
555 ExplicitSpecifier(),
false,
true,
false,
559 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo, SC,
566 Method->getTypeSourceInfo()->getTypeLoc().getAs<FunctionProtoTypeLoc>();
567 for (
int I = 0, E = Params.size(); I != E; I++) {
568 Param &MP = Params[I];
570 AST, Method, SourceLocation(), SourceLocation(), &MP.NameII, MP.Ty,
573 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
575 HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
578 Parm->setScopeInfo(CurScopeDepth, I);
579 ParmDecls.push_back(Parm);
580 FnProtoLoc.setParam(I, Parm);
582 Method->setParams({ParmDecls});
586 ensureCompleteDecl();
588 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
590 AST,
SourceLocation(), Method->getFunctionObjectParameterType(),
true);
591 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
598 ensureCompleteDecl();
600 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
602 AST,
SourceLocation(), Method->getFunctionObjectParameterType(),
true);
603 FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
611 ensureCompleteDecl();
613 assert(Var.Decl ==
nullptr &&
"local variable is already declared");
615 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
618 &AST.
Idents.
get(Var.Name, tok::TokenKind::identifier), Var.Ty,
622 StmtsList.push_back(DS);
626template <
typename V,
typename S>
629 assert(ResultTy->
isVectorType() &&
"The result type must be a vector type.");
630 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
631 Expr *VecExpr = convertPlaceholder(Vec);
633 Expr *ScalarExpr = convertPlaceholder(Scalar);
637 LocalVar VecVar(
"vec_tmp", VecTy->desugar());
641 QualType EltTy = VecTy->getElementType();
642 unsigned NumElts = VecTy->getNumElements();
645 for (
unsigned I = 0; I < NumElts; ++I) {
647 convertPlaceholder(VecVar), DeclBuilder.getConstantIntExpr(I), EltTy,
650 Elts.push_back(ScalarExpr);
656 ExprResult Cast = DeclBuilder.SemaRef.BuildCStyleCastExpr(
659 assert(!Cast.isInvalid() &&
"Cast cannot fail!");
660 StmtsList.push_back(Cast.get());
666 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
670 StmtsList.push_back(ThisExpr);
674template <
typename... Ts>
677 QualType ReturnType, Ts &&...ArgSpecs) {
678 ensureCompleteDecl();
680 std::array<
Expr *,
sizeof...(ArgSpecs)> Args{
681 convertPlaceholder(std::forward<Ts>(ArgSpecs))...};
683 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
684 FunctionDecl *FD = lookupBuiltinFunction(DeclBuilder.SemaRef, BuiltinName);
692 assert(!
Call.isInvalid() &&
"Call to builtin cannot fail!");
695 if (!ReturnType.
isNull() &&
697 ExprResult CastResult = DeclBuilder.SemaRef.BuildCStyleCastExpr(
700 assert(!CastResult.isInvalid() &&
"Cast cannot fail!");
701 E = CastResult.get();
704 StmtsList.push_back(E);
708template <
typename TLHS,
typename TRHS>
710 Expr *LHSExpr = convertPlaceholder(LHS);
711 Expr *RHSExpr = convertPlaceholder(RHS);
713 DeclBuilder.SemaRef.getASTContext(), LHSExpr, RHSExpr, BO_Assign,
716 StmtsList.push_back(AssignStmt);
722 Expr *PtrExpr = convertPlaceholder(Ptr);
728 StmtsList.push_back(Deref);
735 ensureCompleteDecl();
737 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
740 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
743 if (ResourceTypeDecl == DeclBuilder.Record)
744 HandleField = DeclBuilder.getResourceHandleField();
747 for (
auto *
Decl : ResourceTypeDecl->lookup(&II)) {
748 if ((HandleField = dyn_cast<FieldDecl>(
Decl)))
751 assert(HandleField &&
"Resource handle field not found");
757 StmtsList.push_back(HandleExpr);
765 ensureCompleteDecl();
766 Expr *
Base = convertPlaceholder(ResourceRecord);
768 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
772 StmtsList.push_back(
Member);
777 FieldDecl *MipsField = DeclBuilder.Fields.lookup(
"mips");
781 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
783 const auto *RT = MipsTy->
castAs<RecordType>();
787 assert(MipsRecord->field_begin() != MipsRecord->field_end() &&
788 "mips_type must have at least one field");
789 assert(std::next(MipsRecord->field_begin()) == MipsRecord->field_end() &&
790 "mips_type must have exactly one field");
791 FieldDecl *MipsHandleField = *MipsRecord->field_begin();
793 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
794 Expr *ResExpr = convertPlaceholder(ResourceRecord);
803 AST, MipsMemberExpr,
false, MipsHandleField, MipsHandleField->
getType(),
807 AST, MipsHandleMemberExpr, HandleMemberExpr, BO_Assign,
811 StmtsList.push_back(AssignStmt);
814template <
typename ValueT>
817 ValueT HandleValue) {
819 DeclBuilder.getResourceHandleField());
824template <
typename ResourceT,
typename ValueT>
827 ResourceT ResourceRecord, ValueT HandleValue) {
829 DeclBuilder.getResourceCounterHandleField());
832template <
typename ResourceT,
typename ValueT>
834 ResourceT ResourceRecord, ValueT HandleValue,
FieldDecl *HandleField) {
835 ensureCompleteDecl();
837 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
840 "Getting the field from the wrong resource type.");
842 Expr *HandleValueExpr = convertPlaceholder(HandleValue);
844 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
849 DeclBuilder.SemaRef.getASTContext(), HandleMemberExpr, HandleValueExpr,
852 StmtsList.push_back(AssignStmt);
859 ensureCompleteDecl();
861 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
863 "Getting the field from the wrong resource type.");
865 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
866 FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
870 StmtsList.push_back(HandleExpr);
876 ensureCompleteDecl();
878 Expr *ReturnValueExpr = convertPlaceholder(ReturnValue);
879 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
889 assert(CD &&
"no copy constructor found");
904 assert(!DeclBuilder.Record->isCompleteDefinition() &&
905 "record is already complete");
907 ensureCompleteDecl();
909 if (!Method->hasBody()) {
910 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
911 assert((ReturnTy == AST.
VoidTy || !StmtsList.empty()) &&
912 "nothing to return from non-void method");
913 if (ReturnTy != AST.
VoidTy) {
914 if (
Expr *LastExpr = dyn_cast<Expr>(StmtsList.back())) {
916 ReturnTy.getNonReferenceType()) &&
917 "Return type of the last statement must match the return type "
920 StmtsList.pop_back();
929 Method->setLexicalDeclContext(DeclBuilder.Record);
930 Method->setAccess(Access);
931 Method->setImplicitlyInline();
932 Method->addAttr(AlwaysInlineAttr::CreateImplicit(
933 AST,
SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
934 Method->addAttr(ConvergentAttr::CreateImplicit(AST));
935 if (!TemplateParamDecls.empty()) {
942 TemplateParams, Method);
944 FuncTemplate->setLexicalDeclContext(DeclBuilder.Record);
945 FuncTemplate->setImplicit(
true);
946 Method->setDescribedFunctionTemplate(FuncTemplate);
947 DeclBuilder.Record->addDecl(FuncTemplate);
949 DeclBuilder.Record->addDecl(Method);
956 : SemaRef(SemaRef), Record(R) {
957 Record->startDefinition();
958 Template = Record->getDescribedClassTemplate();
964 : SemaRef(SemaRef), HLSLNamespace(Namespace) {
970 if (SemaRef.LookupQualifiedName(
Result, HLSLNamespace)) {
973 if (
auto *TD = dyn_cast<ClassTemplateDecl>(
Found)) {
974 PrevDecl = TD->getTemplatedDecl();
977 PrevDecl = dyn_cast<CXXRecordDecl>(
Found);
978 assert(PrevDecl &&
"Unexpected lookup result type.");
983 Template = PrevTemplate;
990 Record->setImplicit(
true);
991 Record->setLexicalDeclContext(HLSLNamespace);
992 Record->setHasExternalLexicalStorage();
996 FinalAttr::CreateImplicit(AST,
SourceRange(), FinalAttr::Keyword_final));
1000 if (HLSLNamespace && !Template && Record->getDeclContext() == HLSLNamespace)
1001 HLSLNamespace->addDecl(Record);
1008 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1009 assert(Record->isBeingDefined() &&
1010 "Definition must be started before adding members!");
1019 Field->setAccess(Access);
1020 Field->setImplicit(
true);
1021 for (
Attr *A : Attrs) {
1026 Record->addDecl(Field);
1027 Fields[Name] = Field;
1033 bool RawBuffer,
bool HasCounter,
1035 QualType ElementTy = getHandleElementType();
1036 addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer, ElementTy,
1039 addCounterHandleMember(RC, IsROV, RawBuffer, ElementTy, Access);
1045 ResourceDimension RD,
1047 addHandleMember(RC, RD, IsROV,
false, getHandleElementType(),
1053 addHandleMember(ResourceClass::Sampler, ResourceDimension::Unknown,
1054 false,
false, getHandleElementType());
1060 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1071CXXRecordDecl *BuiltinTypeDeclBuilder::addPrivateNestedRecord(StringRef Name) {
1072 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1081 Record->addDecl(NestedRecord);
1082 return NestedRecord;
1086 ResourceClass RC, ResourceDimension RD,
bool IsROV,
bool RawBuffer,
1087 QualType ElementTy, AccessSpecifier Access) {
1088 return addResourceMember(
"__handle", RC, RD, IsROV, RawBuffer,
1089 false, ElementTy, Access);
1093 ResourceClass RC,
bool IsROV,
bool RawBuffer, QualType ElementTy,
1095 return addResourceMember(
"__counter_handle", RC, ResourceDimension::Unknown,
1097 true, ElementTy, Access);
1101 StringRef MemberName,
ResourceClass RC, ResourceDimension RD,
bool IsROV,
1102 bool RawBuffer,
bool IsCounter, QualType ElementTy,
1104 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1106 ASTContext &Ctx = SemaRef.getASTContext();
1108 assert(!ElementTy.isNull() &&
1109 "The caller should always pass in the type for the handle.");
1110 TypeSourceInfo *ElementTypeInfo =
1114 QualType AttributedResTy = QualType();
1115 SmallVector<const Attr *> Attrs = {
1116 HLSLResourceClassAttr::CreateImplicit(Ctx, RC),
1117 IsROV ? HLSLROVAttr::CreateImplicit(Ctx) :
nullptr,
1118 RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) :
nullptr,
1119 RD != ResourceDimension::
Unknown
1120 ? HLSLResourceDimensionAttr::CreateImplicit(Ctx, RD)
1123 ? HLSLContainedTypeAttr::CreateImplicit(Ctx, ElementTypeInfo)
1126 Attrs.push_back(HLSLIsCounterAttr::CreateImplicit(Ctx));
1138 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1140 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1141 QualType HandleType = getResourceHandleField()->getType();
1144 .callBuiltin(
"__builtin_hlsl_resource_uninitializedhandle", HandleType,
1146 .assign(PH::Handle, PH::LastStmt)
1153 addCreateFromBindingWithImplicitCounter();
1154 addCreateFromImplicitBindingWithImplicitCounter();
1156 addCreateFromBinding();
1157 addCreateFromImplicitBinding();
1174 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1176 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1180 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1186 .addParam(
"range", AST.
IntTy)
1189 .declareLocalVar(TmpVar)
1190 .accessHandleFieldOnResource(TmpVar)
1191 .callBuiltin(
"__builtin_hlsl_resource_handlefrombinding", HandleType,
1192 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
1193 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1194 .returnValue(TmpVar)
1211 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1213 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1217 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1223 .addParam(
"range", AST.
IntTy)
1226 .declareLocalVar(TmpVar)
1227 .accessHandleFieldOnResource(TmpVar)
1228 .callBuiltin(
"__builtin_hlsl_resource_handlefromimplicitbinding",
1229 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
1231 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1232 .returnValue(TmpVar)
1252BuiltinTypeDeclBuilder::addCreateFromBindingWithImplicitCounter() {
1253 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1255 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1257 QualType HandleType = getResourceHandleField()->
getType();
1258 QualType CounterHandleType = getResourceCounterHandleField()->
getType();
1260 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1263 "__createFromBindingWithImplicitCounter",
1267 .addParam(
"range", AST.
IntTy)
1271 .declareLocalVar(TmpVar)
1272 .accessHandleFieldOnResource(TmpVar)
1273 .callBuiltin(
"__builtin_hlsl_resource_handlefrombinding", HandleType,
1274 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
1275 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1276 .accessHandleFieldOnResource(TmpVar)
1277 .callBuiltin(
"__builtin_hlsl_resource_counterhandlefromimplicitbinding",
1278 CounterHandleType, PH::LastStmt, PH::_5, PH::_1)
1279 .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt)
1280 .returnValue(TmpVar)
1301BuiltinTypeDeclBuilder::addCreateFromImplicitBindingWithImplicitCounter() {
1302 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1304 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1305 ASTContext &AST = SemaRef.getASTContext();
1306 QualType HandleType = getResourceHandleField()->getType();
1307 QualType CounterHandleType = getResourceCounterHandleField()->getType();
1309 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1312 *
this,
"__createFromImplicitBindingWithImplicitCounter",
1316 .addParam(
"range", AST.
IntTy)
1320 .declareLocalVar(TmpVar)
1321 .accessHandleFieldOnResource(TmpVar)
1322 .callBuiltin(
"__builtin_hlsl_resource_handlefromimplicitbinding",
1323 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
1325 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1326 .accessHandleFieldOnResource(TmpVar)
1327 .callBuiltin(
"__builtin_hlsl_resource_counterhandlefromimplicitbinding",
1328 CounterHandleType, PH::LastStmt, PH::_5, PH::_1)
1329 .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt)
1330 .returnValue(TmpVar)
1336 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1343 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1347 MMB.
addParam(
"other", ConstRecordRefType);
1349 for (
auto *Field : Record->fields()) {
1359 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1367 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1370 MMB.
addParam(
"other", ConstRecordRefType);
1372 for (
auto *Field : Record->fields()) {
1382 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1385 uint32_t VecSize = 1;
1386 if (
Dim != ResourceDimension::Unknown)
1397 if (getResourceAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV)
1405 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1418CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsSliceType(ResourceDimension
Dim,
1425 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1430 CXXRecordDecl *MipsSliceRecord = addPrivateNestedRecord(
"mips_slice_type");
1432 MipsSliceBuilder.addFriend(
Record)
1433 .addHandleMember(getResourceAttrs().ResourceClass,
Dim,
1434 getResourceAttrs().IsROV,
false, ReturnType,
1441 FieldDecl *LevelField = MipsSliceBuilder.Fields[
"__level"];
1442 assert(LevelField &&
"Could not find the level field.");
1450 .addParam(
"Coord", IndexTy)
1451 .accessFieldOnResource(PH::This, LevelField)
1452 .concat(PH::_0, PH::LastStmt, CoordLevelTy)
1453 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1457 MipsSliceBuilder.completeDefinition();
1458 return MipsSliceRecord;
1461CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsType(ResourceDimension Dim,
1462 QualType ReturnType) {
1464 QualType IntTy = AST.
IntTy;
1465 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1468 CXXRecordDecl *MipsSliceRecord = addMipsSliceType(Dim, ReturnType);
1473 CXXRecordDecl *MipsRecord = addPrivateNestedRecord(
"mips_type");
1475 MipsBuilder.addFriend(
Record)
1477 getResourceAttrs().IsROV,
false, ReturnType,
1485 DeclarationName SubscriptName =
1489 auto FieldIt = MipsSliceRecord->field_begin();
1490 FieldDecl *MipsSliceHandleField = *FieldIt;
1492 assert(MipsSliceHandleField->getName() ==
"__handle" &&
1493 LevelField->getName() ==
"__level" &&
1494 "Could not find fields on mips_slice_type");
1497 BuiltinTypeMethodBuilder::LocalVar MipsSliceVar(
"slice", MipsSliceTy);
1500 .addParam(
"Level", IntTy)
1501 .declareLocalVar(MipsSliceVar)
1502 .accessHandleFieldOnResource(PH::This)
1503 .setFieldOnResource(MipsSliceVar, PH::LastStmt, MipsSliceHandleField)
1504 .setFieldOnResource(MipsSliceVar, PH::_0, LevelField)
1505 .returnValue(MipsSliceVar)
1508 MipsBuilder.completeDefinition();
1514 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1516 QualType ReturnType = getHandleElementType();
1529 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1535 QualType ReturnType = getHandleElementType();
1537 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1541 .addParam(
"Location", LocationTy)
1542 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1548 .addParam(
"Location", LocationTy)
1549 .addParam(
"Offset", OffsetTy)
1550 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1557 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1561 auto AddLoads = [&](StringRef MethodName,
QualType ReturnType) {
1580 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1584 auto AddStore = [&](StringRef MethodName,
QualType ValueType) {
1602 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1604 QualType ReturnType = getHandleElementType();
1606 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1612 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1616 .addParam(
"Sampler", SamplerStateType)
1617 .addParam(
"Location", Float2Ty)
1618 .accessHandleFieldOnResource(PH::_0)
1619 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1620 PH::LastStmt, PH::_1)
1621 .returnValue(PH::LastStmt)
1626 .addParam(
"Sampler", SamplerStateType)
1627 .addParam(
"Location", Float2Ty)
1628 .addParam(
"Offset", Int2Ty)
1629 .accessHandleFieldOnResource(PH::_0)
1630 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1631 PH::LastStmt, PH::_1, PH::_2)
1632 .returnValue(PH::LastStmt)
1637 .addParam(
"Sampler", SamplerStateType)
1638 .addParam(
"Location", Float2Ty)
1639 .addParam(
"Offset", Int2Ty)
1640 .addParam(
"Clamp", FloatTy)
1641 .accessHandleFieldOnResource(PH::_0)
1642 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1643 PH::LastStmt, PH::_1, PH::_2, PH::_3)
1644 .returnValue(PH::LastStmt)
1650 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1652 QualType ReturnType = getHandleElementType();
1654 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1660 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1664 .addParam(
"Sampler", SamplerStateType)
1665 .addParam(
"Location", Float2Ty)
1666 .addParam(
"Bias", FloatTy)
1667 .accessHandleFieldOnResource(PH::_0)
1668 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
1669 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
1670 .returnValue(PH::LastStmt)
1675 .addParam(
"Sampler", SamplerStateType)
1676 .addParam(
"Location", Float2Ty)
1677 .addParam(
"Bias", FloatTy)
1678 .addParam(
"Offset", Int2Ty)
1679 .accessHandleFieldOnResource(PH::_0)
1680 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
1681 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1682 .returnValue(PH::LastStmt)
1688 .addParam(
"Sampler", SamplerStateType)
1689 .addParam(
"Location", Float2Ty)
1690 .addParam(
"Bias", FloatTy)
1691 .addParam(
"Offset", Int2Ty)
1692 .addParam(
"Clamp", FloatTy)
1693 .accessHandleFieldOnResource(PH::_0)
1694 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
1695 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
1696 .returnValue(PH::LastStmt)
1702 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1704 QualType ReturnType = getHandleElementType();
1706 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1712 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1716 .addParam(
"Sampler", SamplerStateType)
1717 .addParam(
"Location", Float2Ty)
1718 .addParam(
"DDX", Float2Ty)
1719 .addParam(
"DDY", Float2Ty)
1720 .accessHandleFieldOnResource(PH::_0)
1721 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
1722 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1723 .returnValue(PH::LastStmt)
1729 .addParam(
"Sampler", SamplerStateType)
1730 .addParam(
"Location", Float2Ty)
1731 .addParam(
"DDX", Float2Ty)
1732 .addParam(
"DDY", Float2Ty)
1733 .addParam(
"Offset", Int2Ty)
1734 .accessHandleFieldOnResource(PH::_0)
1735 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
1736 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
1737 .returnValue(PH::LastStmt)
1743 .addParam(
"Sampler", SamplerStateType)
1744 .addParam(
"Location", Float2Ty)
1745 .addParam(
"DDX", Float2Ty)
1746 .addParam(
"DDY", Float2Ty)
1747 .addParam(
"Offset", Int2Ty)
1748 .addParam(
"Clamp", FloatTy)
1749 .accessHandleFieldOnResource(PH::_0)
1750 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
1751 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4,
1753 .returnValue(PH::LastStmt)
1759 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1761 QualType ReturnType = getHandleElementType();
1763 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1769 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1773 .addParam(
"Sampler", SamplerStateType)
1774 .addParam(
"Location", Float2Ty)
1775 .addParam(
"LOD", FloatTy)
1776 .accessHandleFieldOnResource(PH::_0)
1777 .callBuiltin(
"__builtin_hlsl_resource_sample_level", ReturnType,
1778 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
1779 .returnValue(PH::LastStmt)
1784 .addParam(
"Sampler", SamplerStateType)
1785 .addParam(
"Location", Float2Ty)
1786 .addParam(
"LOD", FloatTy)
1787 .addParam(
"Offset", Int2Ty)
1788 .accessHandleFieldOnResource(PH::_0)
1789 .callBuiltin(
"__builtin_hlsl_resource_sample_level", ReturnType,
1790 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1791 .returnValue(PH::LastStmt)
1797 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1800 QualType SamplerComparisonStateType = lookupBuiltinType(
1801 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
1807 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1811 .addParam(
"Sampler", SamplerComparisonStateType)
1812 .addParam(
"Location", Float2Ty)
1813 .addParam(
"CompareValue", FloatTy)
1814 .accessHandleFieldOnResource(PH::_0)
1815 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
1816 PH::LastStmt, PH::_1, PH::_2)
1817 .returnValue(PH::LastStmt)
1823 .addParam(
"Sampler", SamplerComparisonStateType)
1824 .addParam(
"Location", Float2Ty)
1825 .addParam(
"CompareValue", FloatTy)
1826 .addParam(
"Offset", Int2Ty)
1827 .accessHandleFieldOnResource(PH::_0)
1828 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
1829 PH::LastStmt, PH::_1, PH::_2, PH::_3)
1830 .returnValue(PH::LastStmt)
1836 .addParam(
"Sampler", SamplerComparisonStateType)
1837 .addParam(
"Location", Float2Ty)
1838 .addParam(
"CompareValue", FloatTy)
1839 .addParam(
"Offset", Int2Ty)
1840 .addParam(
"Clamp", FloatTy)
1841 .accessHandleFieldOnResource(PH::_0)
1842 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
1843 PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
1844 .returnValue(PH::LastStmt)
1850 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1853 QualType SamplerComparisonStateType = lookupBuiltinType(
1854 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
1860 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1865 .addParam(
"Sampler", SamplerComparisonStateType)
1866 .addParam(
"Location", Float2Ty)
1867 .addParam(
"CompareValue", FloatTy)
1868 .accessHandleFieldOnResource(PH::_0)
1869 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
1870 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
1871 .returnValue(PH::LastStmt)
1877 .addParam(
"Sampler", SamplerComparisonStateType)
1878 .addParam(
"Location", Float2Ty)
1879 .addParam(
"CompareValue", FloatTy)
1880 .addParam(
"Offset", Int2Ty)
1881 .accessHandleFieldOnResource(PH::_0)
1882 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
1883 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1884 .returnValue(PH::LastStmt)
1890 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1891 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1895 assert(
Dim != ResourceDimension::Unknown);
1899 QualType Params[] = {UIntTy, FloatTy};
1902 if (
Dim == ResourceDimension::Dim2D) {
1903 StringRef XYName =
"__builtin_hlsl_resource_getdimensions_xy";
1904 StringRef LevelsXYName =
1905 "__builtin_hlsl_resource_getdimensions_levels_xy";
1907 if (OutTy == FloatTy) {
1908 XYName =
"__builtin_hlsl_resource_getdimensions_xy_float";
1909 LevelsXYName =
"__builtin_hlsl_resource_getdimensions_levels_xy_float";
1914 .addParam(
"width", OutTy, HLSLParamModifierAttr::Keyword_out)
1915 .addParam(
"height", OutTy, HLSLParamModifierAttr::Keyword_out)
1916 .callBuiltin(XYName,
QualType(), PH::Handle, PH::_0, PH::_1)
1922 .addParam(
"mipLevel", UIntTy)
1923 .addParam(
"width", OutTy, HLSLParamModifierAttr::Keyword_out)
1924 .addParam(
"height", OutTy, HLSLParamModifierAttr::Keyword_out)
1925 .addParam(
"numberOfLevels", OutTy, HLSLParamModifierAttr::Keyword_out)
1926 .callBuiltin(LevelsXYName,
QualType(), PH::Handle, PH::_0, PH::_1,
1937 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1941 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1945 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1949 .addParam(
"Sampler", SamplerStateType)
1950 .addParam(
"Location", LocationTy)
1951 .accessHandleFieldOnResource(PH::_0)
1952 .callBuiltin(
"__builtin_hlsl_resource_calculate_lod", ReturnType,
1953 PH::Handle, PH::LastStmt, PH::_1)
1959 .addParam(
"Sampler", SamplerStateType)
1960 .addParam(
"Location", LocationTy)
1961 .accessHandleFieldOnResource(PH::_0)
1962 .callBuiltin(
"__builtin_hlsl_resource_calculate_lod_unclamped",
1963 ReturnType, PH::Handle, PH::LastStmt, PH::_1)
1967QualType BuiltinTypeDeclBuilder::getGatherReturnType() {
1969 QualType T = getHandleElementType();
1974 T = VT->getElementType();
1976 T = DT->getElementType();
1983 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1985 QualType ReturnType = getGatherReturnType();
1988 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1994 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1997 struct GatherVariant {
2001 GatherVariant Variants[] = {{
"Gather", 0},
2005 {
"GatherAlpha", 3}};
2007 for (
const auto &
V : Variants) {
2010 .addParam(
"Sampler", SamplerStateType)
2011 .addParam(
"Location", Float2Ty)
2012 .accessHandleFieldOnResource(PH::_0)
2013 .callBuiltin(
"__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
2014 PH::LastStmt, PH::_1,
2015 getConstantUnsignedIntExpr(
V.Component))
2020 .addParam(
"Sampler", SamplerStateType)
2021 .addParam(
"Location", Float2Ty)
2022 .addParam(
"Offset", OffsetTy)
2023 .accessHandleFieldOnResource(PH::_0)
2024 .callBuiltin(
"__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
2025 PH::LastStmt, PH::_1,
2026 getConstantUnsignedIntExpr(
V.Component), PH::_2)
2035 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2039 QualType SamplerComparisonStateType = lookupBuiltinType(
2040 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
2046 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2050 struct GatherVariant {
2054 GatherVariant Variants[] = {{
"GatherCmp", 0},
2055 {
"GatherCmpRed", 0},
2056 {
"GatherCmpGreen", 1},
2057 {
"GatherCmpBlue", 2},
2058 {
"GatherCmpAlpha", 3}};
2060 for (
const auto &
V : Variants) {
2064 .addParam(
"Sampler", SamplerComparisonStateType)
2065 .addParam(
"Location", Float2Ty)
2066 .addParam(
"CompareValue", FloatTy)
2067 .accessHandleFieldOnResource(PH::_0)
2068 .callBuiltin(
"__builtin_hlsl_resource_gather_cmp", ReturnType,
2069 PH::Handle, PH::LastStmt, PH::_1, PH::_2,
2070 getConstantUnsignedIntExpr(
V.Component))
2076 .addParam(
"Sampler", SamplerComparisonStateType)
2077 .addParam(
"Location", Float2Ty)
2078 .addParam(
"CompareValue", FloatTy)
2079 .addParam(
"Offset", Int2Ty)
2080 .accessHandleFieldOnResource(PH::_0)
2081 .callBuiltin(
"__builtin_hlsl_resource_gather_cmp", ReturnType,
2082 PH::Handle, PH::LastStmt, PH::_1, PH::_2,
2083 getConstantUnsignedIntExpr(
V.Component), PH::_3)
2090FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField()
const {
2091 auto I = Fields.find(
"__handle");
2092 assert(I != Fields.end() &&
2093 I->second->getType()->isHLSLAttributedResourceType() &&
2094 "record does not have resource handle field");
2098FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField()
const {
2099 auto I = Fields.find(
"__counter_handle");
2100 if (I == Fields.end() ||
2101 !I->second->getType()->isHLSLAttributedResourceType())
2106QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam() {
2107 assert(
Template &&
"record it not a template");
2108 if (
const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
2109 Template->getTemplateParameters()->getParam(0))) {
2110 return QualType(TTD->getTypeForDecl(), 0);
2115QualType BuiltinTypeDeclBuilder::getHandleElementType() {
2117 return getFirstTemplateTypeParam();
2119 if (
auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
2120 const auto &Args = Spec->getTemplateArgs();
2122 return Args[0].getAsType();
2126 return SemaRef.getASTContext().Char8Ty;
2129HLSLAttributedResourceType::Attributes
2130BuiltinTypeDeclBuilder::getResourceAttrs()
const {
2131 QualType HandleType = getResourceHandleField()->getType();
2136 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2137 assert(Record->isBeingDefined() &&
2138 "Definition must be started before completing it.");
2140 Record->completeDefinition();
2144Expr *BuiltinTypeDeclBuilder::getConstantIntExpr(
int value) {
2151Expr *BuiltinTypeDeclBuilder::getConstantUnsignedIntExpr(
unsigned value) {
2168 if (Record->isCompleteDefinition()) {
2169 assert(Template &&
"existing record it not a template");
2170 assert(Template->getTemplateParameters()->size() == Names.size() &&
2171 "template param count mismatch");
2175 assert((DefaultTypes.empty() || DefaultTypes.size() == Names.size()) &&
2176 "template default argument count mismatch");
2179 for (
unsigned i = 0; i < Names.size(); ++i) {
2181 Builder.addTypeParameter(Names[i], DefaultTy);
2183 return Builder.finalizeTemplateArgs(CD);
2187 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2188 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
2190 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
2191 PH::CounterHandle, getConstantIntExpr(1))
2196 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2197 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
2199 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
2200 PH::CounterHandle, getConstantIntExpr(-1))
2206 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2208 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2209 bool NeedsTypedBuiltin = !ReturnTy.
isNull();
2214 if (!NeedsTypedBuiltin)
2215 ReturnTy = getHandleElementType();
2218 MMB.ReturnTy = ReturnTy;
2222 HLSLParamModifierAttr::Keyword_out);
2224 if (NeedsTypedBuiltin)
2225 MMB.
callBuiltin(
"__builtin_hlsl_resource_load_with_status_typed", ReturnTy,
2226 PH::Handle, PH::_0, PH::_1, ReturnTy);
2228 MMB.
callBuiltin(
"__builtin_hlsl_resource_load_with_status", ReturnTy,
2229 PH::Handle, PH::_0, PH::_1);
2237 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2239 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2240 bool NeedsTypedBuiltin = !ElemTy.
isNull();
2245 if (!NeedsTypedBuiltin)
2246 ElemTy = getHandleElementType();
2255 ReturnTy = AddrSpaceElemTy;
2264 MMB.ReturnTy = ReturnTy;
2268 if (NeedsTypedBuiltin)
2269 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2270 PH::Handle, PH::_0, ElemTy);
2272 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer", ElemPtrTy, PH::Handle,
2281 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2283 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2295 .
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2296 PH::Handle, PH::_0, ValueTy)
2298 .
assign(PH::LastStmt, PH::_1)
2303 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2305 QualType ElemTy = getHandleElementType();
2309 .addParam(
"value", ElemTy)
2310 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
2311 PH::CounterHandle, getConstantIntExpr(1))
2312 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
2315 .dereference(PH::LastStmt)
2316 .assign(PH::LastStmt, PH::_0)
2321 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2323 QualType ElemTy = getHandleElementType();
2327 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
2328 PH::CounterHandle, getConstantIntExpr(-1))
2329 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
2332 .dereference(PH::LastStmt)
2338 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2342 QualType HandleTy = getResourceHandleField()->getType();
2347 if (AttrResTy->getAttrs().RawBuffer &&
2348 AttrResTy->getContainedType() != AST.
Char8Ty) {
2350 .addParam(
"numStructs", UIntTy, HLSLParamModifierAttr::Keyword_out)
2351 .addParam(
"stride", UIntTy, HLSLParamModifierAttr::Keyword_out)
2352 .callBuiltin(
"__builtin_hlsl_resource_getdimensions_x",
QualType(),
2354 .callBuiltin(
"__builtin_hlsl_resource_getstride",
QualType(),
2362 .addParam(
"dim", UIntTy, HLSLParamModifierAttr::Keyword_out)
2363 .callBuiltin(
"__builtin_hlsl_resource_getdimensions_x",
QualType(),
Defines the clang::ASTContext interface.
llvm::dxil::ResourceClass ResourceClass
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
llvm::MachO::Record Record
This file declares semantic analysis for HLSL constructs.
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
DeclarationNameTable DeclarationNames
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
CanQualType UnsignedIntTy
CanQualType getCanonicalTagType(const TagDecl *TD) const
Represents a member of a struct/union/class.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
DeclarationNameTable DeclarationNames
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Attr - This represents one attribute.
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
static CXXConstructExpr * Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor, bool Elidable, ArrayRef< Expr * > Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, bool ZeroInitialization, CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange)
Create a C++ construction expression.
Represents a C++ constructor within a class.
static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited=InheritedConstructor(), const AssociatedConstraint &TrailingRequiresClause={})
Represents a static or instance method of a struct/union/class.
static CXXMethodDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin, bool isInline, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, const AssociatedConstraint &TrailingRequiresClause={})
Represents a C++ struct/union/class.
static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr)
Represents the this expression in C++.
static CXXThisExpr * Create(const ASTContext &Ctx, SourceLocation L, QualType Ty, bool IsImplicit)
QualType withConst() const
Retrieves a version of this type with const applied.
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Declaration of a C++20 concept.
A reference to a concept and its template args, as it appears in the code.
static ConceptReference * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, TemplateDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten)
Represents the specialization of a concept - evaluates to a prvalue of type bool.
static ConceptSpecializationExpr * Create(const ASTContext &C, ConceptReference *ConceptRef, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction)
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
void setAccess(AccessSpecifier AS)
void setImplicit(bool I=true)
void setLexicalDeclContext(DeclContext *DC)
The name of a declaration.
Represents an extended vector type where either the type or size is dependent.
This represents one expression.
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
static FieldDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle)
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
static FriendDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, SourceLocation EllipsisLoc={}, ArrayRef< TemplateParameterList * > FriendTypeTPLists={})
Represents a function declaration or definition.
DeclarationNameInfo getNameInfo() const
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
ExtParameterInfo withABI(ParameterABI kind) const
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
Describes an C or C++ initializer list.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Represents the results of name lookup.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
static MemberExpr * CreateImplicit(const ASTContext &C, Expr *Base, bool IsArrow, ValueDecl *MemberDecl, QualType T, ExprValueKind VK, ExprObjectKind OK)
Create an implicit MemberExpr, with no location, qualifier, template arguments, and so on.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represent a C++ namespace.
A C++ nested-name-specifier augmented with source location information.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
A (possibly-)qualified type.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
unsigned getDepth() const
Returns the depth of this scope. The translation-unit has scope depth 0.
Sema - This implements semantic analysis and AST building for C.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
Scope * getCurScope() const
Retrieve the parser's current scope.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
ASTContext & getASTContext() const
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
Location wrapper for a TemplateArgument.
Represents a template argument.
@ Type
The template argument is a type.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Declaration of a template type parameter.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
A container of type source information.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const T * castAs() const
Member-template castAs<specific type>.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVectorType() const
bool isRecordType() const
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Represents a GCC generic vector type.
BuiltinTypeDeclBuilder & addStoreFunction(DeclarationName &Name, bool IsConst, QualType ValueType)
friend struct BuiltinTypeMethodBuilder
BuiltinTypeDeclBuilder & addDefaultHandleConstructor(AccessSpecifier Access=AccessSpecifier::AS_public)
BuiltinTypeDeclBuilder(Sema &SemaRef, CXXRecordDecl *R)
BuiltinTypeDeclBuilder & addSimpleTemplateParams(ArrayRef< StringRef > Names, ConceptDecl *CD)
BuiltinTypeDeclBuilder & addMemberVariable(StringRef Name, QualType Type, llvm::ArrayRef< Attr * > Attrs, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addConsumeMethod()
BuiltinTypeDeclBuilder & addCopyAssignmentOperator(AccessSpecifier Access=AccessSpecifier::AS_public)
~BuiltinTypeDeclBuilder()
friend struct TemplateParameterListBuilder
BuiltinTypeDeclBuilder & addArraySubscriptOperators(ResourceDimension Dim=ResourceDimension::Unknown)
BuiltinTypeDeclBuilder & addLoadWithStatusFunction(DeclarationName &Name, bool IsConst, QualType ReturnTy=QualType())
BuiltinTypeDeclBuilder & addSampleGradMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addHandleAccessFunction(DeclarationName &Name, bool IsConst, bool IsRef, QualType IndexTy, QualType ElemTy=QualType())
BuiltinTypeDeclBuilder & addGetDimensionsMethodForBuffer()
BuiltinTypeDeclBuilder & addGatherCmpMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addSamplerHandle()
BuiltinTypeDeclBuilder & addSampleBiasMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & completeDefinition()
BuiltinTypeDeclBuilder & addBufferHandles(ResourceClass RC, bool IsROV, bool RawBuffer, bool HasCounter, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addByteAddressBufferStoreMethods()
BuiltinTypeDeclBuilder & addTextureHandle(ResourceClass RC, bool IsROV, ResourceDimension RD, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addCopyConstructor(AccessSpecifier Access=AccessSpecifier::AS_public)
BuiltinTypeDeclBuilder & addAppendMethod()
BuiltinTypeDeclBuilder & addTextureLoadMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addIncrementCounterMethod()
BuiltinTypeDeclBuilder & addSampleLevelMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addMipsMember(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addByteAddressBufferLoadMethods()
BuiltinTypeDeclBuilder & addSampleMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addStaticInitializationFunctions(bool HasCounter)
BuiltinTypeDeclBuilder & addCalculateLodMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addGetDimensionsMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addSampleCmpLevelZeroMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addGatherMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addDecrementCounterMethod()
BuiltinTypeDeclBuilder & addSampleCmpMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addLoadMethods()
uint32_t getResourceDimensions(llvm::dxil::ResourceDimension Dim)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ ICIS_NoInit
No in-class initializer.
@ OK_Ordinary
An ordinary object is located at an address in memory.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
MutableArrayRef< Expr * > MultiExprArg
@ Result
The result type of a method or function.
ParameterABI
Kinds of parameter ABI.
@ Template
We are parsing a template declaration.
bool CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, ArrayRef< const Attr * > AttrList, QualType &ResType, HLSLAttributedResourceLocInfo *LocInfo=nullptr)
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
BuiltinTypeMethodBuilder & concat(V Vec, S Scalar, QualType ResultTy)
BuiltinTypeMethodBuilder & addParam(StringRef Name, QualType Ty, HLSLParamModifierAttr::Spelling Modifier=HLSLParamModifierAttr::Keyword_in)
BuiltinTypeMethodBuilder & accessFieldOnResource(T ResourceRecord, FieldDecl *Field)
Expr * getResourceHandleExpr()
BuiltinTypeDeclBuilder & finalize(AccessSpecifier Access=AccessSpecifier::AS_public)
BuiltinTypeMethodBuilder & callBuiltin(StringRef BuiltinName, QualType ReturnType, Ts &&...ArgSpecs)
BuiltinTypeMethodBuilder & accessHandleFieldOnResource(T ResourceRecord)
Expr * getResourceCounterHandleExpr()
BuiltinTypeMethodBuilder & setHandleFieldOnResource(LocalVar &ResourceRecord, ValueT HandleValue)
BuiltinTypeMethodBuilder & operator=(const BuiltinTypeMethodBuilder &Other)=delete
BuiltinTypeMethodBuilder & returnThis()
BuiltinTypeMethodBuilder & dereference(T Ptr)
~BuiltinTypeMethodBuilder()
BuiltinTypeMethodBuilder & declareLocalVar(LocalVar &Var)
BuiltinTypeMethodBuilder & assign(TLHS LHS, TRHS RHS)
BuiltinTypeMethodBuilder(const BuiltinTypeMethodBuilder &Other)=delete
BuiltinTypeMethodBuilder & accessCounterHandleFieldOnResource(T ResourceRecord)
BuiltinTypeMethodBuilder & setFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue, FieldDecl *HandleField)
BuiltinTypeMethodBuilder & setCounterHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue)
friend BuiltinTypeDeclBuilder
BuiltinTypeMethodBuilder & returnValue(T ReturnValue)
QualType addTemplateTypeParam(StringRef Name)
BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, DeclarationName &Name, QualType ReturnTy, bool IsConst=false, bool IsCtor=false, StorageClass SC=SC_None)
void setMipsHandleField(LocalVar &ResourceRecord)
TemplateParameterListBuilder & addTypeParameter(StringRef Name, QualType DefaultValue=QualType())
BuiltinTypeDeclBuilder & finalizeTemplateArgs(ConceptDecl *CD=nullptr)
llvm::SmallVector< NamedDecl * > Params
~TemplateParameterListBuilder()
TemplateParameterListBuilder(BuiltinTypeDeclBuilder &RB)
ConceptSpecializationExpr * constructConceptSpecializationExpr(Sema &S, ConceptDecl *CD)
BuiltinTypeDeclBuilder & Builder