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");
104void addDerivativeAvailabilityAttrs(ASTContext &AST, FunctionDecl *FD) {
105 struct DerivativeShaderStage {
106 StringRef Environment;
107 VersionTuple Introduced;
109 const DerivativeShaderStage Stages[] = {
110 {
"pixel", VersionTuple(6, 0)},
111 {
"compute", VersionTuple(6, 6)},
112 {
"mesh", VersionTuple(6, 6)},
113 {
"amplification", VersionTuple(6, 6)},
116 const IdentifierInfo *Platform = &AST.
Idents.get(
"shadermodel");
117 for (
const DerivativeShaderStage &Stage : Stages)
118 FD->addAttr(AvailabilityAttr::CreateImplicit(
119 AST, Platform, Stage.Introduced, VersionTuple(),
120 VersionTuple(),
false,
"",
122 &AST.
Idents.get(Stage.Environment),
nullptr));
174 HLSLParamModifierAttr::Spelling Modifier;
176 HLSLParamModifierAttr::Spelling Modifier)
177 : NameII(NameII), Ty(Ty), Modifier(Modifier) {}
184 LocalVar(StringRef Name,
QualType Ty) : Name(Name), Ty(Ty),
Decl(
nullptr) {}
208 enum class PlaceHolder {
221 Expr *convertPlaceholder(PlaceHolder PH);
222 Expr *convertPlaceholder(LocalVar &Var);
223 Expr *convertPlaceholder(
Expr *E) {
return E; }
231 QualType ReturnTy,
bool IsConst =
false,
233 : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(
nullptr),
234 IsConst(IsConst), IsCtor(IsCtor), SC(SC) {}
237 QualType ReturnTy,
bool IsConst =
false,
247 HLSLParamModifierAttr::Spelling Modifier =
248 HLSLParamModifierAttr::Keyword_in);
251 template <
typename... Ts>
253 QualType ReturnType, Ts &&...ArgSpecs);
254 template <
typename TLHS,
typename TRHS>
257 template <
typename V,
typename S>
260 template <
typename T>
262 template <
typename T>
265 template <
typename ValueT>
268 template <
typename ResourceT,
typename ValueT>
273 template <
typename T>
276 template <
typename ResourceT,
typename ValueT>
291 void ensureCompleteDecl() {
304 assert(!
Builder.Record->isCompleteDefinition() &&
305 "record is already complete");
307 unsigned Position =
static_cast<unsigned>(
Params.size());
311 &AST.
Idents.
get(Name, tok::TokenKind::identifier),
315 if (!DefaultValue.
isNull())
316 Decl->setDefaultArgument(AST,
317 Builder.SemaRef.getTrivialTemplateArgumentLoc(
359 "unexpected concept decl parameter count");
368 Builder.Record->getDeclContext(),
378 T->setDeclContext(DC);
380 QualType ConceptTType = Context.getTypeDeclType(ConceptTTPD);
386 QualType CSETType = Context.getTypeDeclType(
T);
394 Context,
Builder.Record->getDeclContext(), Loc, {CSETA});
434 Builder.Template->setImplicit(
true);
435 Builder.Template->setLexicalDeclContext(
Builder.Record->getDeclContext());
446Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) {
447 if (PH == PlaceHolder::Handle)
449 if (PH == PlaceHolder::CounterHandle)
451 if (PH == PlaceHolder::This) {
454 Method->getFunctionObjectParameterType(),
458 if (PH == PlaceHolder::LastStmt) {
459 assert(!StmtsList.empty() &&
"no statements in the list");
460 Stmt *LastStmt = StmtsList.pop_back_val();
461 assert(
isa<ValueStmt>(LastStmt) &&
"last statement does not have a value");
470 ParmVarDecl *ParamDecl = Method->getParamDecl(
static_cast<unsigned>(PH));
472 AST, NestedNameSpecifierLoc(), SourceLocation(), ParamDecl,
false,
473 DeclarationNameInfo(ParamDecl->getDeclName(), SourceLocation()),
474 ParamDecl->getType().getNonReferenceType(),
VK_LValue);
477Expr *BuiltinTypeMethodBuilder::convertPlaceholder(LocalVar &Var) {
478 VarDecl *VD = Var.Decl;
479 assert(VD &&
"local variable is not declared");
481 VD->getASTContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
482 false, DeclarationNameInfo(VD->getDeclName(), SourceLocation()),
486Expr *BuiltinTypeMethodBuilder::convertPlaceholder(QualType Ty) {
487 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
490 return new (AST) CXXScalarValueInitExpr(
498 bool IsConst,
bool IsCtor,
500 : DeclBuilder(DB), ReturnTy(ReturnTy), Method(
nullptr), IsConst(IsConst),
501 IsCtor(IsCtor), SC(SC) {
503 assert((!NameStr.empty() || IsCtor) &&
"method needs a name");
504 assert(((IsCtor && !IsConst) || !IsCtor) &&
"constructor cannot be const");
512 AST.
Idents.
get(NameStr, tok::TokenKind::identifier);
519 HLSLParamModifierAttr::Spelling Modifier) {
520 assert(Method ==
nullptr &&
"Cannot add param, method already created");
521 const IdentifierInfo &II = DeclBuilder.SemaRef.getASTContext().Idents.get(
522 Name, tok::TokenKind::identifier);
523 Params.emplace_back(II, Ty, Modifier);
527 assert(Method ==
nullptr &&
528 "Cannot add template param, method already created");
529 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
530 unsigned Position =
static_cast<unsigned>(TemplateParamDecls.size());
534 &AST.
Idents.
get(Name, tok::TokenKind::identifier),
538 TemplateParamDecls.push_back(
Decl);
543void BuiltinTypeMethodBuilder::createDecl() {
544 assert(
Method ==
nullptr &&
"Method or constructor is already created");
550 uint32_t ArgIndex = 0;
553 bool UseParamExtInfo =
false;
554 for (Param &MP : Params) {
555 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
556 UseParamExtInfo =
true;
558 ParamExtInfos[ArgIndex] =
559 PI.
withABI(convertParamModifierToParamABI(MP.Modifier));
560 if (!MP.Ty->isDependentType())
561 MP.Ty = getInoutParameterType(AST, MP.Ty);
563 ParamTypes.emplace_back(MP.Ty);
567 FunctionProtoType::ExtProtoInfo ExtInfo;
569 ExtInfo.ExtParameterInfos = ParamExtInfos.data();
571 ExtInfo.TypeQuals.addConst();
577 DeclarationNameInfo NameInfo = DeclarationNameInfo(Name, SourceLocation());
580 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo,
581 ExplicitSpecifier(),
false,
true,
false,
585 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo,
586 false,
true, ExplicitSpecifier(),
590 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo, SC,
597 Method->getTypeSourceInfo()->getTypeLoc().getAs<FunctionProtoTypeLoc>();
598 for (
int I = 0, E = Params.size(); I != E; I++) {
599 Param &MP = Params[I];
601 AST, Method, SourceLocation(), SourceLocation(), &MP.NameII, MP.Ty,
604 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
606 HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
609 Parm->setScopeInfo(CurScopeDepth, I);
610 ParmDecls.push_back(Parm);
611 FnProtoLoc.setParam(I, Parm);
613 Method->setParams({ParmDecls});
617 ensureCompleteDecl();
619 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
621 AST,
SourceLocation(), Method->getFunctionObjectParameterType(),
true);
622 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
629 ensureCompleteDecl();
631 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
633 AST,
SourceLocation(), Method->getFunctionObjectParameterType(),
true);
634 FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
642 ensureCompleteDecl();
644 assert(Var.Decl ==
nullptr &&
"local variable is already declared");
646 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
649 &AST.
Idents.
get(Var.Name, tok::TokenKind::identifier), Var.Ty,
653 StmtsList.push_back(DS);
657template <
typename V,
typename S>
660 assert(ResultTy->
isVectorType() &&
"The result type must be a vector type.");
661 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
662 Expr *VecExpr = convertPlaceholder(Vec);
664 Expr *ScalarExpr = convertPlaceholder(Scalar);
668 LocalVar VecVar(
"vec_tmp", VecTy->desugar());
672 QualType EltTy = VecTy->getElementType();
673 unsigned NumElts = VecTy->getNumElements();
676 for (
unsigned I = 0; I < NumElts; ++I) {
678 convertPlaceholder(VecVar), DeclBuilder.getConstantIntExpr(I), EltTy,
681 Elts.push_back(ScalarExpr);
687 ExprResult Cast = DeclBuilder.SemaRef.BuildCStyleCastExpr(
690 assert(!Cast.isInvalid() &&
"Cast cannot fail!");
691 StmtsList.push_back(Cast.get());
697 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
701 StmtsList.push_back(ThisExpr);
705template <
typename... Ts>
708 QualType ReturnType, Ts &&...ArgSpecs) {
709 ensureCompleteDecl();
711 std::array<
Expr *,
sizeof...(ArgSpecs)> Args{
712 convertPlaceholder(std::forward<Ts>(ArgSpecs))...};
714 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
715 FunctionDecl *FD = lookupBuiltinFunction(DeclBuilder.SemaRef, BuiltinName);
723 assert(!
Call.isInvalid() &&
"Call to builtin cannot fail!");
726 if (!ReturnType.
isNull() &&
728 ExprResult CastResult = DeclBuilder.SemaRef.BuildCStyleCastExpr(
731 assert(!CastResult.isInvalid() &&
"Cast cannot fail!");
732 E = CastResult.get();
735 StmtsList.push_back(E);
739template <
typename TLHS,
typename TRHS>
741 Expr *LHSExpr = convertPlaceholder(LHS);
742 Expr *RHSExpr = convertPlaceholder(RHS);
744 DeclBuilder.SemaRef.getASTContext(), LHSExpr, RHSExpr, BO_Assign,
747 StmtsList.push_back(AssignStmt);
753 Expr *PtrExpr = convertPlaceholder(Ptr);
759 StmtsList.push_back(Deref);
766 ensureCompleteDecl();
768 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
771 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
774 if (ResourceTypeDecl == DeclBuilder.Record)
775 HandleField = DeclBuilder.getResourceHandleField();
778 for (
auto *
Decl : ResourceTypeDecl->lookup(&II)) {
779 if ((HandleField = dyn_cast<FieldDecl>(
Decl)))
782 assert(HandleField &&
"Resource handle field not found");
788 StmtsList.push_back(HandleExpr);
796 ensureCompleteDecl();
797 Expr *
Base = convertPlaceholder(ResourceRecord);
799 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
803 StmtsList.push_back(
Member);
808 FieldDecl *MipsField = DeclBuilder.Fields.lookup(
"mips");
812 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
814 const auto *RT = MipsTy->
castAs<RecordType>();
818 assert(MipsRecord->field_begin() != MipsRecord->field_end() &&
819 "mips_type must have at least one field");
820 assert(std::next(MipsRecord->field_begin()) == MipsRecord->field_end() &&
821 "mips_type must have exactly one field");
822 FieldDecl *MipsHandleField = *MipsRecord->field_begin();
824 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
825 Expr *ResExpr = convertPlaceholder(ResourceRecord);
834 AST, MipsMemberExpr,
false, MipsHandleField, MipsHandleField->
getType(),
838 AST, MipsHandleMemberExpr, HandleMemberExpr, BO_Assign,
842 StmtsList.push_back(AssignStmt);
845template <
typename ValueT>
848 ValueT HandleValue) {
850 DeclBuilder.getResourceHandleField());
855template <
typename ResourceT,
typename ValueT>
858 ResourceT ResourceRecord, ValueT HandleValue) {
860 DeclBuilder.getResourceCounterHandleField());
863template <
typename ResourceT,
typename ValueT>
865 ResourceT ResourceRecord, ValueT HandleValue,
FieldDecl *HandleField) {
866 ensureCompleteDecl();
868 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
871 "Getting the field from the wrong resource type.");
873 Expr *HandleValueExpr = convertPlaceholder(HandleValue);
875 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
880 DeclBuilder.SemaRef.getASTContext(), HandleMemberExpr, HandleValueExpr,
883 StmtsList.push_back(AssignStmt);
890 ensureCompleteDecl();
892 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
894 "Getting the field from the wrong resource type.");
896 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
897 FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
901 StmtsList.push_back(HandleExpr);
907 ensureCompleteDecl();
909 Expr *ReturnValueExpr = convertPlaceholder(ReturnValue);
910 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
913 if (Ty->
isRecordType() && !Method->getReturnType()->isReferenceType()) {
920 assert(CD &&
"no copy constructor found");
935 assert(!DeclBuilder.Record->isCompleteDefinition() &&
936 "record is already complete");
938 ensureCompleteDecl();
940 if (!Method->hasBody()) {
941 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
942 assert((ReturnTy == AST.
VoidTy || !StmtsList.empty()) &&
943 "nothing to return from non-void method");
944 if (ReturnTy != AST.
VoidTy) {
945 if (
Expr *LastExpr = dyn_cast<Expr>(StmtsList.back())) {
947 ReturnTy.getNonReferenceType()) &&
948 "Return type of the last statement must match the return type "
951 StmtsList.pop_back();
960 Method->setLexicalDeclContext(DeclBuilder.Record);
961 Method->setAccess(Access);
962 Method->setImplicitlyInline();
963 Method->addAttr(AlwaysInlineAttr::CreateImplicit(
964 AST,
SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
965 Method->addAttr(ConvergentAttr::CreateImplicit(AST));
966 if (!TemplateParamDecls.empty()) {
973 TemplateParams, Method);
975 FuncTemplate->setLexicalDeclContext(DeclBuilder.Record);
976 FuncTemplate->setImplicit(
true);
977 Method->setDescribedFunctionTemplate(FuncTemplate);
978 DeclBuilder.Record->addDecl(FuncTemplate);
980 DeclBuilder.Record->addDecl(Method);
987 : SemaRef(SemaRef), Record(R) {
988 Record->startDefinition();
989 Template = Record->getDescribedClassTemplate();
995 : SemaRef(SemaRef), HLSLNamespace(Namespace) {
1001 if (SemaRef.LookupQualifiedName(
Result, HLSLNamespace)) {
1004 if (
auto *TD = dyn_cast<ClassTemplateDecl>(
Found)) {
1005 PrevDecl = TD->getTemplatedDecl();
1008 PrevDecl = dyn_cast<CXXRecordDecl>(
Found);
1009 assert(PrevDecl &&
"Unexpected lookup result type.");
1014 Template = PrevTemplate;
1021 Record->setImplicit(
true);
1022 Record->setLexicalDeclContext(HLSLNamespace);
1023 Record->setHasExternalLexicalStorage();
1027 FinalAttr::CreateImplicit(AST,
SourceRange(), FinalAttr::Keyword_final));
1031 if (HLSLNamespace && !Template && Record->getDeclContext() == HLSLNamespace)
1032 HLSLNamespace->addDecl(Record);
1039 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1040 assert(Record->isBeingDefined() &&
1041 "Definition must be started before adding members!");
1050 Field->setAccess(Access);
1051 Field->setImplicit(
true);
1052 for (
Attr *A : Attrs) {
1057 Record->addDecl(Field);
1058 Fields[Name] = Field;
1064 bool RawBuffer,
bool HasCounter,
1066 QualType ElementTy = getHandleElementType();
1067 addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer,
1068 false, ElementTy, Access);
1070 addCounterHandleMember(RC, IsROV, RawBuffer, ElementTy, Access);
1076 bool IsArray, ResourceDimension RD,
1078 addHandleMember(RC, RD, IsROV,
false, IsArray,
1079 getHandleElementType(), Access);
1084 addHandleMember(ResourceClass::Sampler, ResourceDimension::Unknown,
1085 false,
false,
false,
1086 getHandleElementType());
1092 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1094 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1096 QualType ElemTy = getHandleElementType();
1106 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
1108 .dereference(PH::LastStmt)
1114 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1125CXXRecordDecl *BuiltinTypeDeclBuilder::addPrivateNestedRecord(StringRef Name) {
1126 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1135 Record->addDecl(NestedRecord);
1136 return NestedRecord;
1140 ResourceClass RC, ResourceDimension RD,
bool IsROV,
bool RawBuffer,
1141 bool IsArray, QualType ElementTy, AccessSpecifier Access) {
1142 return addResourceMember(
"__handle", RC, RD, IsROV, RawBuffer,
1143 false, IsArray, ElementTy, Access);
1147 ResourceClass RC,
bool IsROV,
bool RawBuffer, QualType ElementTy,
1149 return addResourceMember(
"__counter_handle", RC, ResourceDimension::Unknown,
1150 IsROV, RawBuffer,
true,
1151 false, ElementTy, Access);
1155 StringRef MemberName,
ResourceClass RC, ResourceDimension RD,
bool IsROV,
1156 bool RawBuffer,
bool IsCounter,
bool IsArray, QualType ElementTy,
1158 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1160 ASTContext &Ctx = SemaRef.getASTContext();
1162 assert(!ElementTy.isNull() &&
1163 "The caller should always pass in the type for the handle.");
1164 TypeSourceInfo *ElementTypeInfo =
1168 QualType AttributedResTy = QualType();
1169 SmallVector<const Attr *> Attrs = {
1170 HLSLResourceClassAttr::CreateImplicit(Ctx, RC),
1171 IsROV ? HLSLIsROVAttr::CreateImplicit(Ctx) :
nullptr,
1172 RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) :
nullptr,
1173 RD != ResourceDimension::
Unknown
1174 ? HLSLResourceDimensionAttr::CreateImplicit(Ctx, RD)
1177 ? HLSLContainedTypeAttr::CreateImplicit(Ctx, ElementTypeInfo)
1180 Attrs.push_back(HLSLIsCounterAttr::CreateImplicit(Ctx));
1182 Attrs.push_back(HLSLIsArrayAttr::CreateImplicit(Ctx));
1194 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1196 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1197 QualType HandleType = getResourceHandleField()->getType();
1200 .callBuiltin(
"__builtin_hlsl_resource_uninitializedhandle", HandleType,
1202 .assign(PH::Handle, PH::LastStmt)
1209 addCreateFromBindingWithImplicitCounter();
1210 addCreateFromImplicitBindingWithImplicitCounter();
1212 addCreateFromBinding();
1213 addCreateFromImplicitBinding();
1230 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1232 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1236 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1242 .addParam(
"range", AST.
IntTy)
1245 .declareLocalVar(TmpVar)
1246 .accessHandleFieldOnResource(TmpVar)
1247 .callBuiltin(
"__builtin_hlsl_resource_handlefrombinding", HandleType,
1248 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
1249 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1250 .returnValue(TmpVar)
1267 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1269 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1273 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1279 .addParam(
"range", AST.
IntTy)
1282 .declareLocalVar(TmpVar)
1283 .accessHandleFieldOnResource(TmpVar)
1284 .callBuiltin(
"__builtin_hlsl_resource_handlefromimplicitbinding",
1285 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
1287 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1288 .returnValue(TmpVar)
1308BuiltinTypeDeclBuilder::addCreateFromBindingWithImplicitCounter() {
1309 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1311 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1313 QualType HandleType = getResourceHandleField()->
getType();
1314 QualType CounterHandleType = getResourceCounterHandleField()->
getType();
1316 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1319 "__createFromBindingWithImplicitCounter",
1323 .addParam(
"range", AST.
IntTy)
1327 .declareLocalVar(TmpVar)
1328 .accessHandleFieldOnResource(TmpVar)
1329 .callBuiltin(
"__builtin_hlsl_resource_handlefrombinding", HandleType,
1330 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
1331 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1332 .accessHandleFieldOnResource(TmpVar)
1333 .callBuiltin(
"__builtin_hlsl_resource_counterhandlefromimplicitbinding",
1334 CounterHandleType, PH::LastStmt, PH::_5, PH::_1)
1335 .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt)
1336 .returnValue(TmpVar)
1357BuiltinTypeDeclBuilder::addCreateFromImplicitBindingWithImplicitCounter() {
1358 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1360 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1361 ASTContext &AST = SemaRef.getASTContext();
1362 QualType HandleType = getResourceHandleField()->getType();
1363 QualType CounterHandleType = getResourceCounterHandleField()->getType();
1365 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1368 *
this,
"__createFromImplicitBindingWithImplicitCounter",
1372 .addParam(
"range", AST.
IntTy)
1376 .declareLocalVar(TmpVar)
1377 .accessHandleFieldOnResource(TmpVar)
1378 .callBuiltin(
"__builtin_hlsl_resource_handlefromimplicitbinding",
1379 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
1381 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1382 .accessHandleFieldOnResource(TmpVar)
1383 .callBuiltin(
"__builtin_hlsl_resource_counterhandlefromimplicitbinding",
1384 CounterHandleType, PH::LastStmt, PH::_5, PH::_1)
1385 .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt)
1386 .returnValue(TmpVar)
1392 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1399 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1403 MMB.
addParam(
"other", ConstRecordRefType);
1405 for (
auto *Field : Record->fields()) {
1415 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1423 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1426 MMB.
addParam(
"other", ConstRecordRefType);
1428 for (
auto *Field : Record->fields()) {
1439 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1442 uint32_t VecSize = 1;
1443 if (
Dim != ResourceDimension::Unknown)
1454 getResourceAttrs().ResourceClass !=
1455 llvm::dxil::ResourceClass::UAV,
1462 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1476CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsSliceType(ResourceDimension
Dim,
1484 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1489 CXXRecordDecl *MipsSliceRecord = addPrivateNestedRecord(
"mips_slice_type");
1491 MipsSliceBuilder.addFriend(
Record)
1492 .addHandleMember(getResourceAttrs().ResourceClass,
Dim,
1493 getResourceAttrs().IsROV,
false,
1494 getResourceAttrs().IsArray, ReturnType,
1501 FieldDecl *LevelField = MipsSliceBuilder.Fields[
"__level"];
1502 assert(LevelField &&
"Could not find the level field.");
1510 .addParam(
"Coord", IndexTy)
1511 .accessFieldOnResource(PH::This, LevelField)
1512 .concat(PH::_0, PH::LastStmt, CoordLevelTy)
1513 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1517 MipsSliceBuilder.completeDefinition();
1518 return MipsSliceRecord;
1521CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsType(ResourceDimension Dim,
1522 QualType ReturnType) {
1524 QualType IntTy = AST.
IntTy;
1525 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1528 CXXRecordDecl *MipsSliceRecord = addMipsSliceType(Dim, ReturnType);
1533 CXXRecordDecl *MipsRecord = addPrivateNestedRecord(
"mips_type");
1535 MipsBuilder.addFriend(
Record)
1537 getResourceAttrs().IsROV,
false,
1538 getResourceAttrs().IsArray, ReturnType,
1546 DeclarationName SubscriptName =
1550 auto FieldIt = MipsSliceRecord->field_begin();
1551 FieldDecl *MipsSliceHandleField = *FieldIt;
1553 assert(MipsSliceHandleField->getName() ==
"__handle" &&
1554 LevelField->getName() ==
"__level" &&
1555 "Could not find fields on mips_slice_type");
1558 BuiltinTypeMethodBuilder::LocalVar MipsSliceVar(
"slice", MipsSliceTy);
1561 .addParam(
"Level", IntTy)
1562 .declareLocalVar(MipsSliceVar)
1563 .accessHandleFieldOnResource(PH::This)
1564 .setFieldOnResource(MipsSliceVar, PH::LastStmt, MipsSliceHandleField)
1565 .setFieldOnResource(MipsSliceVar, PH::_0, LevelField)
1566 .returnValue(MipsSliceVar)
1569 MipsBuilder.completeDefinition();
1575 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1577 QualType ReturnType = getHandleElementType();
1591 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1594 uint32_t CoordSize = OffsetSize + (IsArray ? 2 : 1);
1598 QualType ReturnType = getHandleElementType();
1600 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1604 .addParam(
"Location", LocationTy)
1605 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1611 .addParam(
"Location", LocationTy)
1612 .addParam(
"Offset", OffsetTy)
1613 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1620 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1624 auto AddLoads = [&](StringRef MethodName,
QualType ReturnType) {
1644 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1648 auto AddStore = [&](StringRef MethodName,
QualType ValueType) {
1666 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1672 "__builtin_hlsl_interlocked_add");
1674 "__builtin_hlsl_interlocked_or");
1676 "__builtin_hlsl_interlocked_xor");
1680 bool HasInt64AtomicSupport =
1681 TT.getArch() != llvm::Triple::dxil ||
1683 if (HasInt64AtomicSupport) {
1687 "__builtin_hlsl_interlocked_add");
1689 "__builtin_hlsl_interlocked_or");
1692 "__builtin_hlsl_interlocked_xor");
1699BuiltinTypeDeclBuilder::addDerivativeAvailability(StringRef MethodName) {
1703 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
1704 D = FTD->getTemplatedDecl();
1705 if (
auto *MD = dyn_cast<CXXMethodDecl>(D))
1706 addDerivativeAvailabilityAttrs(AST, MD);
1713 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1715 QualType ReturnType = getHandleElementType();
1717 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1719 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
1724 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1728 .addParam(
"Sampler", SamplerStateType)
1729 .addParam(
"Location", CoordTy)
1730 .accessHandleFieldOnResource(PH::_0)
1731 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1732 PH::LastStmt, PH::_1)
1733 .returnValue(PH::LastStmt)
1738 .addParam(
"Sampler", SamplerStateType)
1739 .addParam(
"Location", CoordTy)
1740 .addParam(
"Offset", OffsetTy)
1741 .accessHandleFieldOnResource(PH::_0)
1742 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1743 PH::LastStmt, PH::_1, PH::_2)
1744 .returnValue(PH::LastStmt)
1749 .addParam(
"Sampler", SamplerStateType)
1750 .addParam(
"Location", CoordTy)
1751 .addParam(
"Offset", OffsetTy)
1752 .addParam(
"Clamp", FloatTy)
1753 .accessHandleFieldOnResource(PH::_0)
1754 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1755 PH::LastStmt, PH::_1, PH::_2, PH::_3)
1756 .returnValue(PH::LastStmt)
1760 return addDerivativeAvailability(
"Sample");
1766 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1768 QualType ReturnType = getHandleElementType();
1770 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1772 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
1777 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1781 .addParam(
"Sampler", SamplerStateType)
1782 .addParam(
"Location", CoordTy)
1783 .addParam(
"Bias", FloatTy)
1784 .accessHandleFieldOnResource(PH::_0)
1785 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
1786 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
1787 .returnValue(PH::LastStmt)
1792 .addParam(
"Sampler", SamplerStateType)
1793 .addParam(
"Location", CoordTy)
1794 .addParam(
"Bias", FloatTy)
1795 .addParam(
"Offset", OffsetTy)
1796 .accessHandleFieldOnResource(PH::_0)
1797 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
1798 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1799 .returnValue(PH::LastStmt)
1805 .addParam(
"Sampler", SamplerStateType)
1806 .addParam(
"Location", CoordTy)
1807 .addParam(
"Bias", FloatTy)
1808 .addParam(
"Offset", OffsetTy)
1809 .addParam(
"Clamp", FloatTy)
1810 .accessHandleFieldOnResource(PH::_0)
1811 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
1812 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
1813 .returnValue(PH::LastStmt)
1817 return addDerivativeAvailability(
"SampleBias");
1823 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1825 QualType ReturnType = getHandleElementType();
1827 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1829 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
1835 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1839 .addParam(
"Sampler", SamplerStateType)
1840 .addParam(
"Location", CoordTy)
1841 .addParam(
"DDX", OffsetFloatTy)
1842 .addParam(
"DDY", OffsetFloatTy)
1843 .accessHandleFieldOnResource(PH::_0)
1844 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
1845 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1846 .returnValue(PH::LastStmt)
1852 .addParam(
"Sampler", SamplerStateType)
1853 .addParam(
"Location", CoordTy)
1854 .addParam(
"DDX", OffsetFloatTy)
1855 .addParam(
"DDY", OffsetFloatTy)
1856 .addParam(
"Offset", OffsetTy)
1857 .accessHandleFieldOnResource(PH::_0)
1858 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
1859 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
1860 .returnValue(PH::LastStmt)
1866 .addParam(
"Sampler", SamplerStateType)
1867 .addParam(
"Location", CoordTy)
1868 .addParam(
"DDX", OffsetFloatTy)
1869 .addParam(
"DDY", OffsetFloatTy)
1870 .addParam(
"Offset", OffsetTy)
1871 .addParam(
"Clamp", FloatTy)
1872 .accessHandleFieldOnResource(PH::_0)
1873 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
1874 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4,
1876 .returnValue(PH::LastStmt)
1883 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1885 QualType ReturnType = getHandleElementType();
1887 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1889 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
1894 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1898 .addParam(
"Sampler", SamplerStateType)
1899 .addParam(
"Location", CoordTy)
1900 .addParam(
"LOD", FloatTy)
1901 .accessHandleFieldOnResource(PH::_0)
1902 .callBuiltin(
"__builtin_hlsl_resource_sample_level", ReturnType,
1903 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
1904 .returnValue(PH::LastStmt)
1909 .addParam(
"Sampler", SamplerStateType)
1910 .addParam(
"Location", CoordTy)
1911 .addParam(
"LOD", FloatTy)
1912 .addParam(
"Offset", OffsetTy)
1913 .accessHandleFieldOnResource(PH::_0)
1914 .callBuiltin(
"__builtin_hlsl_resource_sample_level", ReturnType,
1915 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1916 .returnValue(PH::LastStmt)
1923 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1926 QualType SamplerComparisonStateType = lookupBuiltinType(
1927 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
1929 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
1934 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1938 .addParam(
"Sampler", SamplerComparisonStateType)
1939 .addParam(
"Location", CoordTy)
1940 .addParam(
"CompareValue", FloatTy)
1941 .accessHandleFieldOnResource(PH::_0)
1942 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
1943 PH::LastStmt, PH::_1, PH::_2)
1944 .returnValue(PH::LastStmt)
1950 .addParam(
"Sampler", SamplerComparisonStateType)
1951 .addParam(
"Location", CoordTy)
1952 .addParam(
"CompareValue", FloatTy)
1953 .addParam(
"Offset", OffsetTy)
1954 .accessHandleFieldOnResource(PH::_0)
1955 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
1956 PH::LastStmt, PH::_1, PH::_2, PH::_3)
1957 .returnValue(PH::LastStmt)
1963 .addParam(
"Sampler", SamplerComparisonStateType)
1964 .addParam(
"Location", CoordTy)
1965 .addParam(
"CompareValue", FloatTy)
1966 .addParam(
"Offset", OffsetTy)
1967 .addParam(
"Clamp", FloatTy)
1968 .accessHandleFieldOnResource(PH::_0)
1969 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
1970 PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
1971 .returnValue(PH::LastStmt)
1975 return addDerivativeAvailability(
"SampleCmp");
1981 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1984 QualType SamplerComparisonStateType = lookupBuiltinType(
1985 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
1987 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
1992 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1997 .addParam(
"Sampler", SamplerComparisonStateType)
1998 .addParam(
"Location", CoordTy)
1999 .addParam(
"CompareValue", FloatTy)
2000 .accessHandleFieldOnResource(PH::_0)
2001 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
2002 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
2003 .returnValue(PH::LastStmt)
2009 .addParam(
"Sampler", SamplerComparisonStateType)
2010 .addParam(
"Location", CoordTy)
2011 .addParam(
"CompareValue", FloatTy)
2012 .addParam(
"Offset", OffsetTy)
2013 .accessHandleFieldOnResource(PH::_0)
2014 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
2015 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2016 .returnValue(PH::LastStmt)
2022 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2023 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2027 assert(
Dim != ResourceDimension::Unknown);
2031 QualType Params[] = {UIntTy, FloatTy};
2034 if (
Dim == ResourceDimension::Dim2D) {
2035 StringRef XYName =
"__builtin_hlsl_resource_getdimensions_xy";
2036 StringRef LevelsXYName =
2037 "__builtin_hlsl_resource_getdimensions_levels_xy";
2039 if (OutTy == FloatTy) {
2040 XYName =
"__builtin_hlsl_resource_getdimensions_xy_float";
2041 LevelsXYName =
"__builtin_hlsl_resource_getdimensions_levels_xy_float";
2046 .addParam(
"width", OutTy, HLSLParamModifierAttr::Keyword_out)
2047 .addParam(
"height", OutTy, HLSLParamModifierAttr::Keyword_out)
2048 .callBuiltin(XYName,
QualType(), PH::Handle, PH::_0, PH::_1)
2054 .addParam(
"mipLevel", UIntTy)
2055 .addParam(
"width", OutTy, HLSLParamModifierAttr::Keyword_out)
2056 .addParam(
"height", OutTy, HLSLParamModifierAttr::Keyword_out)
2057 .addParam(
"numberOfLevels", OutTy, HLSLParamModifierAttr::Keyword_out)
2058 .callBuiltin(LevelsXYName,
QualType(), PH::Handle, PH::_0, PH::_1,
2069 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2073 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2077 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2081 .addParam(
"Sampler", SamplerStateType)
2082 .addParam(
"Location", LocationTy)
2083 .accessHandleFieldOnResource(PH::_0)
2084 .callBuiltin(
"__builtin_hlsl_resource_calculate_lod", ReturnType,
2085 PH::Handle, PH::LastStmt, PH::_1)
2090 .addParam(
"Sampler", SamplerStateType)
2091 .addParam(
"Location", LocationTy)
2092 .accessHandleFieldOnResource(PH::_0)
2093 .callBuiltin(
"__builtin_hlsl_resource_calculate_lod_unclamped",
2094 ReturnType, PH::Handle, PH::LastStmt, PH::_1)
2098 addDerivativeAvailability(
"CalculateLevelOfDetail");
2099 return addDerivativeAvailability(
"CalculateLevelOfDetailUnclamped");
2102QualType BuiltinTypeDeclBuilder::getGatherReturnType() {
2109 T = VT->getElementType();
2111 T = DT->getElementType();
2118 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2120 QualType ReturnType = getGatherReturnType();
2123 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2125 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2130 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2133 struct GatherVariant {
2137 GatherVariant Variants[] = {{
"Gather", 0},
2141 {
"GatherAlpha", 3}};
2143 for (
const auto &
V : Variants) {
2146 .addParam(
"Sampler", SamplerStateType)
2147 .addParam(
"Location", CoordTy)
2148 .accessHandleFieldOnResource(PH::_0)
2149 .callBuiltin(
"__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
2150 PH::LastStmt, PH::_1,
2151 getConstantUnsignedIntExpr(
V.Component))
2156 .addParam(
"Sampler", SamplerStateType)
2157 .addParam(
"Location", CoordTy)
2158 .addParam(
"Offset", OffsetTy)
2159 .accessHandleFieldOnResource(PH::_0)
2160 .callBuiltin(
"__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
2161 PH::LastStmt, PH::_1,
2162 getConstantUnsignedIntExpr(
V.Component), PH::_2)
2172 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2176 QualType SamplerComparisonStateType = lookupBuiltinType(
2177 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
2179 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2184 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2188 struct GatherVariant {
2192 GatherVariant Variants[] = {{
"GatherCmp", 0},
2193 {
"GatherCmpRed", 0},
2194 {
"GatherCmpGreen", 1},
2195 {
"GatherCmpBlue", 2},
2196 {
"GatherCmpAlpha", 3}};
2198 for (
const auto &
V : Variants) {
2202 .addParam(
"Sampler", SamplerComparisonStateType)
2203 .addParam(
"Location", CoordTy)
2204 .addParam(
"CompareValue", FloatTy)
2205 .accessHandleFieldOnResource(PH::_0)
2206 .callBuiltin(
"__builtin_hlsl_resource_gather_cmp", ReturnType,
2207 PH::Handle, PH::LastStmt, PH::_1, PH::_2,
2208 getConstantUnsignedIntExpr(
V.Component))
2214 .addParam(
"Sampler", SamplerComparisonStateType)
2215 .addParam(
"Location", CoordTy)
2216 .addParam(
"CompareValue", FloatTy)
2217 .addParam(
"Offset", OffsetTy)
2218 .accessHandleFieldOnResource(PH::_0)
2219 .callBuiltin(
"__builtin_hlsl_resource_gather_cmp", ReturnType,
2220 PH::Handle, PH::LastStmt, PH::_1, PH::_2,
2221 getConstantUnsignedIntExpr(
V.Component), PH::_3)
2228FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField()
const {
2229 auto I = Fields.find(
"__handle");
2230 assert(I != Fields.end() &&
2231 I->second->getType()->isHLSLAttributedResourceType() &&
2232 "record does not have resource handle field");
2236FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField()
const {
2237 auto I = Fields.find(
"__counter_handle");
2238 if (I == Fields.end() ||
2239 !I->second->getType()->isHLSLAttributedResourceType())
2244QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam() {
2245 assert(
Template &&
"record it not a template");
2246 if (
const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
2247 Template->getTemplateParameters()->getParam(0))) {
2248 return QualType(TTD->getTypeForDecl(), 0);
2253QualType BuiltinTypeDeclBuilder::getHandleElementType() {
2255 return getFirstTemplateTypeParam();
2257 if (
auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
2258 const auto &Args = Spec->getTemplateArgs();
2260 return Args[0].getAsType();
2264 return SemaRef.getASTContext().Char8Ty;
2267HLSLAttributedResourceType::Attributes
2268BuiltinTypeDeclBuilder::getResourceAttrs()
const {
2269 QualType HandleType = getResourceHandleField()->getType();
2274 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2275 assert(Record->isBeingDefined() &&
2276 "Definition must be started before completing it.");
2278 Record->completeDefinition();
2279 Record->setIsHLSLBuiltinRecord(
true);
2283Expr *BuiltinTypeDeclBuilder::getConstantIntExpr(
int value) {
2290Expr *BuiltinTypeDeclBuilder::getConstantUnsignedIntExpr(
unsigned value) {
2307 if (Record->isCompleteDefinition()) {
2308 assert(Template &&
"existing record it not a template");
2309 assert(Template->getTemplateParameters()->size() == Names.size() &&
2310 "template param count mismatch");
2314 assert((DefaultTypes.empty() || DefaultTypes.size() == Names.size()) &&
2315 "template default argument count mismatch");
2318 for (
unsigned i = 0; i < Names.size(); ++i) {
2320 Builder.addTypeParameter(Names[i], DefaultTy);
2322 return Builder.finalizeTemplateArgs(CD);
2326 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2327 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
2329 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
2330 PH::CounterHandle, getConstantIntExpr(1))
2335 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2336 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
2338 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
2339 PH::CounterHandle, getConstantIntExpr(-1))
2346 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2348 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2349 bool NeedsTypedBuiltin = !ReturnTy.
isNull();
2355 if (!NeedsTypedBuiltin)
2356 ReturnTy = getHandleElementType();
2359 MMB.ReturnTy = ReturnTy;
2363 HLSLParamModifierAttr::Keyword_out);
2365 if (NeedsTypedBuiltin)
2366 MMB.
callBuiltin(
"__builtin_hlsl_resource_load_with_status_typed", ReturnTy,
2367 PH::Handle, PH::_0, PH::_1, ReturnTy);
2369 MMB.
callBuiltin(
"__builtin_hlsl_resource_load_with_status", ReturnTy,
2370 PH::Handle, PH::_0, PH::_1);
2378 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2380 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2381 bool NeedsTypedBuiltin = !ElemTy.
isNull();
2387 if (!NeedsTypedBuiltin)
2388 ElemTy = getHandleElementType();
2397 ReturnTy = AddrSpaceElemTy;
2402 assert(!IsConstReturn &&
"There shouldn't be any resource methods with a "
2403 "const ref return value");
2406 MMB.ReturnTy = ReturnTy;
2410 if (NeedsTypedBuiltin)
2411 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2412 PH::Handle, PH::_0, ElemTy);
2414 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer", ElemPtrTy, PH::Handle,
2423 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2425 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2437 .
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2438 PH::Handle, PH::_0, ValueTy)
2440 .
assign(PH::LastStmt, PH::_1)
2446 StringRef MethodName,
QualType ValueTy, StringRef BuiltinName) {
2447 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2449 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2459 auto BuildOverload = [&](
bool WithOriginalValue) {
2462 if (WithOriginalValue)
2463 MMB.
addParam(
"OriginalValue", ValueTy,
2464 HLSLParamModifierAttr::Keyword_out);
2465 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2466 PH::Handle, PH::_0, ValueTy)
2468 if (WithOriginalValue)
2475 BuildOverload(
false);
2476 BuildOverload(
true);
2481 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2483 QualType ElemTy = getHandleElementType();
2487 .addParam(
"value", ElemTy)
2488 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
2489 PH::CounterHandle, getConstantIntExpr(1))
2490 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
2493 .dereference(PH::LastStmt)
2494 .assign(PH::LastStmt, PH::_0)
2499 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2501 QualType ElemTy = getHandleElementType();
2505 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
2506 PH::CounterHandle, getConstantIntExpr(-1))
2507 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
2510 .dereference(PH::LastStmt)
2516 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2520 QualType HandleTy = getResourceHandleField()->getType();
2525 if (AttrResTy->getAttrs().RawBuffer &&
2526 AttrResTy->getContainedType() != AST.
Char8Ty) {
2528 .addParam(
"numStructs", UIntTy, HLSLParamModifierAttr::Keyword_out)
2529 .addParam(
"stride", UIntTy, HLSLParamModifierAttr::Keyword_out)
2530 .callBuiltin(
"__builtin_hlsl_resource_getdimensions_x",
QualType(),
2532 .callBuiltin(
"__builtin_hlsl_resource_getstride",
QualType(),
2540 .addParam(
"dim", UIntTy, HLSLParamModifierAttr::Keyword_out)
2541 .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 ...
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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.
CanQualType UnsignedLongTy
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.
const TargetInfo & getTargetInfo() const
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={})
static CXXConversionDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, 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.
@ CXXConversionFunctionName
NameKind getNameKind() const
Determine what kind of name this is.
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={})
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.
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
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
@ AP_Explicit
The availability attribute was specified explicitly next to the declaration.
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.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
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, int D, int 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 & addMemberVariable(StringRef Name, QualType Type, llvm::ArrayRef< Attr * > Attrs, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addHandleAccessFunction(DeclarationName &Name, bool IsConstReturn, bool IsRef, QualType IndexTy, QualType ElemTy=QualType())
BuiltinTypeDeclBuilder & addConsumeMethod()
BuiltinTypeDeclBuilder & addSampleGradMethods(ResourceDimension Dim, bool IsArray=false)
BuiltinTypeDeclBuilder & addCopyAssignmentOperator(AccessSpecifier Access=AccessSpecifier::AS_public)
~BuiltinTypeDeclBuilder()
BuiltinTypeDeclBuilder & addGatherCmpMethods(ResourceDimension Dim, bool IsArray=false)
friend struct TemplateParameterListBuilder
BuiltinTypeDeclBuilder & addGetDimensionsMethodForBuffer()
BuiltinTypeDeclBuilder & addConstantBufferConversionToType()
BuiltinTypeDeclBuilder & addSamplerHandle()
BuiltinTypeDeclBuilder & addTextureLoadMethods(ResourceDimension Dim, bool IsArray=false)
BuiltinTypeDeclBuilder & completeDefinition()
BuiltinTypeDeclBuilder & addByteAddressBufferInterlockedMethod(StringRef MethodName, QualType ValueTy, StringRef BuiltinName)
BuiltinTypeDeclBuilder & addSampleBiasMethods(ResourceDimension Dim, bool IsArray=false)
BuiltinTypeDeclBuilder & addBufferHandles(ResourceClass RC, bool IsROV, bool RawBuffer, bool HasCounter, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addByteAddressBufferStoreMethods()
BuiltinTypeDeclBuilder & addSampleMethods(ResourceDimension Dim, bool IsArray=false)
BuiltinTypeDeclBuilder & addArraySubscriptOperators(ResourceDimension Dim=ResourceDimension::Unknown, bool IsArray=false)
BuiltinTypeDeclBuilder & addSampleLevelMethods(ResourceDimension Dim, bool IsArray=false)
BuiltinTypeDeclBuilder & addCopyConstructor(AccessSpecifier Access=AccessSpecifier::AS_public)
BuiltinTypeDeclBuilder & addAppendMethod()
BuiltinTypeDeclBuilder & addTextureHandle(ResourceClass RC, bool IsROV, bool IsArray, ResourceDimension RD, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addLoadWithStatusFunction(DeclarationName &Name, QualType ReturnTy=QualType())
BuiltinTypeDeclBuilder & addIncrementCounterMethod()
BuiltinTypeDeclBuilder & addSampleCmpMethods(ResourceDimension Dim, bool IsArray=false)
BuiltinTypeDeclBuilder & addMipsMember(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addByteAddressBufferLoadMethods()
BuiltinTypeDeclBuilder & addStaticInitializationFunctions(bool HasCounter)
BuiltinTypeDeclBuilder & addGatherMethods(ResourceDimension Dim, bool IsArray=false)
BuiltinTypeDeclBuilder & addCalculateLodMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addGetDimensionsMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addByteAddressBufferInterlockedMethods()
BuiltinTypeDeclBuilder & addSimpleTemplateParams(ArrayRef< StringRef > Names, ConceptDecl *CD=nullptr)
BuiltinTypeDeclBuilder & addDecrementCounterMethod()
BuiltinTypeDeclBuilder & addLoadMethods()
BuiltinTypeDeclBuilder & addSampleCmpLevelZeroMethods(ResourceDimension Dim, bool IsArray=false)
uint32_t getResourceDimensions(llvm::dxil::ResourceDimension Dim)
Top level wrappers for InstallAPI frontend operations.
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.
const FunctionProtoType * T
@ 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