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 NamespaceDecl *lookupBuiltinNamespace(Sema &S, StringRef Name,
59 S.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
61 S.LookupQualifiedName(
Result, DC);
62 assert(!
Result.empty() &&
"Builtin namespace not found");
63 return Result.getAsSingle<NamespaceDecl>();
66static QualType lookupBuiltinType(Sema &S, StringRef Name, DeclContext *DC) {
68 S.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
70 S.LookupQualifiedName(
Result, DC);
71 assert(!
Result.empty() &&
"Builtin type not found");
73 S.getASTContext().getTypeDeclType(
Result.getAsSingle<TypeDecl>());
74 S.RequireCompleteType(SourceLocation(), Ty,
75 diag::err_tentative_def_incomplete_type);
79CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
80 assert(ResTy->isRecordType() &&
"not a CXXRecord type");
81 for (
auto *CD : ResTy->getAsCXXRecordDecl()->ctors())
82 if (CD->isCopyConstructor())
88convertParamModifierToParamABI(HLSLParamModifierAttr::Spelling Modifier) {
89 assert(Modifier != HLSLParamModifierAttr::Spelling::Keyword_in &&
90 "HLSL 'in' parameters modifier cannot be converted to ParameterABI");
92 case HLSLParamModifierAttr::Spelling::Keyword_out:
94 case HLSLParamModifierAttr::Spelling::Keyword_inout:
97 llvm_unreachable(
"Invalid HLSL parameter modifier");
103 assert(NumElements > 0 &&
"Cannot create a zero-element type");
107QualType getInoutParameterType(ASTContext &AST, QualType Ty) {
108 assert(!Ty->isReferenceType() &&
109 "Pointer and reference types cannot be inout or out parameters");
120void addDerivativeAvailabilityAttrs(ASTContext &AST, FunctionDecl *FD) {
121 struct DerivativeShaderStage {
122 StringRef Environment;
123 VersionTuple Introduced;
125 const DerivativeShaderStage Stages[] = {
126 {
"pixel", VersionTuple(6, 0)},
127 {
"compute", VersionTuple(6, 6)},
128 {
"mesh", VersionTuple(6, 6)},
129 {
"amplification", VersionTuple(6, 6)},
132 const IdentifierInfo *Platform = &AST.
Idents.get(
"shadermodel");
133 for (
const DerivativeShaderStage &Stage : Stages)
134 FD->addAttr(AvailabilityAttr::CreateImplicit(
135 AST, Platform, Stage.Introduced, VersionTuple(),
136 VersionTuple(),
false,
"",
138 &AST.
Idents.get(Stage.Environment),
nullptr));
157 Expr *DefaultValue =
nullptr);
194 HLSLParamModifierAttr::Spelling Modifier;
196 HLSLParamModifierAttr::Spelling Modifier)
197 : NameII(NameII), Ty(Ty), Modifier(Modifier) {}
204 LocalVar(StringRef Name,
QualType Ty) : Name(Name), Ty(Ty),
Decl(
nullptr) {}
228 enum class PlaceHolder {
241 Expr *convertPlaceholder(PlaceHolder PH);
242 Expr *convertPlaceholder(LocalVar &Var);
243 Expr *convertPlaceholder(
Expr *E) {
return E; }
251 QualType ReturnTy,
bool IsConst =
false,
253 : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(
nullptr),
254 IsConst(IsConst), IsCtor(IsCtor), SC(SC) {}
257 QualType ReturnTy,
bool IsConst =
false,
267 HLSLParamModifierAttr::Spelling Modifier =
268 HLSLParamModifierAttr::Keyword_in);
271 template <
typename... Ts>
273 QualType ReturnType, Ts &&...ArgSpecs);
274 template <
typename TLHS,
typename TRHS>
277 template <
typename V,
typename S>
280 template <
typename T>
282 template <
typename T>
285 template <
typename ValueT>
288 template <
typename ResourceT,
typename ValueT>
293 template <
typename T>
296 template <
typename ResourceT,
typename ValueT>
314 void ensureCompleteDecl() {
329 assert(!
Builder.Record->isCompleteDefinition() &&
330 "record is already complete");
332 unsigned Position =
static_cast<unsigned>(
Params.size());
336 &AST.
Idents.
get(Name, tok::TokenKind::identifier),
340 if (!DefaultValue.
isNull())
341 Decl->setDefaultArgument(AST,
342 Builder.SemaRef.getTrivialTemplateArgumentLoc(
351 Expr *DefaultValue) {
352 assert(!
Builder.Record->isCompleteDefinition() &&
353 "record is already complete");
355 unsigned Position =
static_cast<unsigned>(
Params.size());
359 &AST.
Idents.
get(Name, tok::TokenKind::identifier), Ty,
362 Decl->setDefaultArgument(
363 AST,
Builder.SemaRef.getTrivialTemplateArgumentLoc(
406 "unexpected concept decl parameter count");
415 Builder.Record->getDeclContext(),
425 T->setDeclContext(DC);
427 QualType ConceptTType = Context.getTypeDeclType(ConceptTTPD);
433 QualType CSETType = Context.getTypeDeclType(
T);
441 Context,
Builder.Record->getDeclContext(), Loc, {CSETA});
481 Builder.Template->setImplicit(
true);
482 Builder.Template->setLexicalDeclContext(
Builder.Record->getDeclContext());
493Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) {
494 if (PH == PlaceHolder::Handle)
496 if (PH == PlaceHolder::CounterHandle)
498 if (PH == PlaceHolder::This)
501 if (PH == PlaceHolder::LastStmt) {
502 assert(!StmtsList.empty() &&
"no statements in the list");
503 Stmt *LastStmt = StmtsList.pop_back_val();
504 assert(
isa<ValueStmt>(LastStmt) &&
"last statement does not have a value");
519Expr *BuiltinTypeMethodBuilder::convertPlaceholder(LocalVar &Var) {
520 VarDecl *VD = Var.Decl;
521 assert(VD &&
"local variable is not declared");
523 VD->getASTContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
524 false, DeclarationNameInfo(VD->getDeclName(), SourceLocation()),
528Expr *BuiltinTypeMethodBuilder::convertPlaceholder(QualType Ty) {
529 ASTContext &AST = getASTContext();
532 return new (AST) CXXScalarValueInitExpr(
540 bool IsConst,
bool IsCtor,
542 : DeclBuilder(DB), ReturnTy(ReturnTy), Method(
nullptr), IsConst(IsConst),
543 IsCtor(IsCtor), SC(SC) {
545 assert((!NameStr.empty() || IsCtor) &&
"method needs a name");
546 assert(((IsCtor && !IsConst) || !IsCtor) &&
"constructor cannot be const");
554 AST.
Idents.
get(NameStr, tok::TokenKind::identifier);
561 HLSLParamModifierAttr::Spelling Modifier) {
562 assert(Method ==
nullptr &&
"Cannot add param, method already created");
564 getASTContext().Idents.get(Name, tok::TokenKind::identifier);
565 Params.emplace_back(II, Ty, Modifier);
569 assert(Method ==
nullptr &&
570 "Cannot add template param, method already created");
572 unsigned Position =
static_cast<unsigned>(TemplateParamDecls.size());
576 &AST.
Idents.
get(Name, tok::TokenKind::identifier),
580 TemplateParamDecls.push_back(
Decl);
585void BuiltinTypeMethodBuilder::createDecl() {
586 assert(
Method ==
nullptr &&
"Method or constructor is already created");
592 uint32_t ArgIndex = 0;
595 bool UseParamExtInfo =
false;
596 for (Param &MP : Params) {
597 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
598 UseParamExtInfo =
true;
600 ParamExtInfos[ArgIndex] =
601 PI.
withABI(convertParamModifierToParamABI(MP.Modifier));
602 if (!MP.Ty->isDependentType())
603 MP.Ty = getInoutParameterType(AST, MP.Ty);
605 ParamTypes.emplace_back(MP.Ty);
609 FunctionProtoType::ExtProtoInfo ExtInfo;
611 ExtInfo.ExtParameterInfos = ParamExtInfos.data();
613 ExtInfo.TypeQuals.addConst();
619 DeclarationNameInfo NameInfo = DeclarationNameInfo(Name, SourceLocation());
622 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo,
623 ExplicitSpecifier(),
false,
true,
false,
627 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo,
628 false,
true, ExplicitSpecifier(),
632 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo, SC,
639 Method->getTypeSourceInfo()->getTypeLoc().getAs<FunctionProtoTypeLoc>();
640 for (
int I = 0, E = Params.size(); I != E; I++) {
641 Param &MP = Params[I];
643 AST, Method, SourceLocation(), SourceLocation(), &MP.NameII, MP.Ty,
646 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
648 HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
651 Parm->setScopeInfo(CurScopeDepth, I);
652 ParmDecls.push_back(Parm);
653 FnProtoLoc.setParam(I, Parm);
655 Method->setParams({ParmDecls});
659 ensureCompleteDecl();
660 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
665 ensureCompleteDecl();
666 FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
673 ensureCompleteDecl();
674 Expr *BaseExpr = convertPlaceholder(
Base);
682 Method->getFunctionObjectParameterType(),
true);
688 ensureCompleteDecl();
690 assert(Var.Decl ==
nullptr &&
"local variable is already declared");
695 &AST.
Idents.
get(Var.Name, tok::TokenKind::identifier), Var.Ty,
699 StmtsList.push_back(DS);
703template <
typename V,
typename S>
706 assert(ResultTy->
isVectorType() &&
"The result type must be a vector type.");
707 Expr *VecExpr = convertPlaceholder(Vec);
708 Expr *ScalarExpr = convertPlaceholder(Scalar);
715 LocalVar VecVar(
"vec_tmp", VecTy->desugar());
719 QualType EltTy = VecTy->getElementType();
720 unsigned NumElts = VecTy->getNumElements();
722 for (
unsigned I = 0; I < NumElts; ++I) {
724 convertPlaceholder(VecVar), DeclBuilder.getConstantIntExpr(I), EltTy,
728 Elts.push_back(VecExpr);
730 Elts.push_back(ScalarExpr);
732 "The result type must have one element per concatenated value.");
738 ExprResult Cast = DeclBuilder.SemaRef.BuildCStyleCastExpr(
741 assert(!Cast.isInvalid() &&
"Cast cannot fail!");
742 StmtsList.push_back(Cast.get());
752template <
typename... Ts>
755 QualType ReturnType, Ts &&...ArgSpecs) {
756 ensureCompleteDecl();
758 std::array<
Expr *,
sizeof...(ArgSpecs)> Args{
759 convertPlaceholder(std::forward<Ts>(ArgSpecs))...};
762 FunctionDecl *FD = lookupBuiltinFunction(DeclBuilder.SemaRef, BuiltinName);
770 assert(!
Call.isInvalid() &&
"Call to builtin cannot fail!");
773 if (!ReturnType.
isNull() &&
775 ExprResult CastResult = DeclBuilder.SemaRef.BuildCStyleCastExpr(
778 assert(!CastResult.isInvalid() &&
"Cast cannot fail!");
779 E = CastResult.get();
782 StmtsList.push_back(E);
786template <
typename TLHS,
typename TRHS>
788 Expr *LHSExpr = convertPlaceholder(LHS);
789 Expr *RHSExpr = convertPlaceholder(RHS);
791 getASTContext(), LHSExpr, RHSExpr, BO_Assign, LHSExpr->
getType(),
794 StmtsList.push_back(AssignStmt);
800 Expr *PtrExpr = convertPlaceholder(Ptr);
805 StmtsList.push_back(Deref);
812 ensureCompleteDecl();
814 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
820 if (ResourceTypeDecl == DeclBuilder.Record)
821 HandleField = DeclBuilder.getResourceHandleField();
824 for (
auto *
Decl : ResourceTypeDecl->lookup(&II)) {
825 if ((HandleField = dyn_cast<FieldDecl>(
Decl)))
828 assert(HandleField &&
"Resource handle field not found");
834 StmtsList.push_back(HandleExpr);
842 ensureCompleteDecl();
844 StmtsList.push_back(
Member);
849 FieldDecl *MipsField = DeclBuilder.Fields.lookup(
"mips");
854 const auto *RT = MipsTy->
castAs<RecordType>();
858 assert(MipsRecord->field_begin() != MipsRecord->field_end() &&
859 "mips_type must have at least one field");
860 assert(std::next(MipsRecord->field_begin()) == MipsRecord->field_end() &&
861 "mips_type must have exactly one field");
862 FieldDecl *MipsHandleField = *MipsRecord->field_begin();
864 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
865 Expr *ResExpr = convertPlaceholder(ResourceRecord);
873 getASTContext(), MipsHandleMemberExpr, HandleMemberExpr, BO_Assign,
877 StmtsList.push_back(AssignStmt);
880template <
typename ValueT>
883 ValueT HandleValue) {
885 DeclBuilder.getResourceHandleField());
890template <
typename ResourceT,
typename ValueT>
893 ResourceT ResourceRecord, ValueT HandleValue) {
895 DeclBuilder.getResourceCounterHandleField());
898template <
typename ResourceT,
typename ValueT>
900 ResourceT ResourceRecord, ValueT HandleValue,
FieldDecl *HandleField) {
901 ensureCompleteDecl();
903 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
906 "Getting the field from the wrong resource type.");
908 Expr *HandleValueExpr = convertPlaceholder(HandleValue);
912 getASTContext(), HandleMemberExpr, HandleValueExpr, BO_Assign,
915 StmtsList.push_back(AssignStmt);
922 ensureCompleteDecl();
924 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
926 "Getting the field from the wrong resource type.");
928 FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
930 StmtsList.push_back(HandleExpr);
936 ensureCompleteDecl();
938 Expr *ReturnValueExpr = convertPlaceholder(ReturnValue);
942 if (Ty->
isRecordType() && !Method->getReturnType()->isReferenceType()) {
949 assert(CD &&
"no copy constructor found");
964 assert(!DeclBuilder.Record->isCompleteDefinition() &&
965 "record is already complete");
967 ensureCompleteDecl();
969 if (!Method->hasBody()) {
971 assert((ReturnTy == AST.
VoidTy || !StmtsList.empty()) &&
972 "nothing to return from non-void method");
973 if (ReturnTy != AST.
VoidTy) {
974 if (
Expr *LastExpr = dyn_cast<Expr>(StmtsList.back())) {
976 ReturnTy.getNonReferenceType()) &&
977 "Return type of the last statement must match the return type "
980 StmtsList.pop_back();
989 Method->setLexicalDeclContext(DeclBuilder.Record);
990 Method->setAccess(Access);
991 Method->setImplicitlyInline();
992 Method->addAttr(AlwaysInlineAttr::CreateImplicit(
993 AST,
SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
994 Method->addAttr(ConvergentAttr::CreateImplicit(AST));
995 if (!TemplateParamDecls.empty()) {
1002 TemplateParams, Method);
1004 FuncTemplate->setLexicalDeclContext(DeclBuilder.Record);
1005 FuncTemplate->setImplicit(
true);
1006 Method->setDescribedFunctionTemplate(FuncTemplate);
1007 DeclBuilder.Record->addDecl(FuncTemplate);
1009 DeclBuilder.Record->addDecl(Method);
1016 : SemaRef(SemaRef), Record(R) {
1017 Record->startDefinition();
1018 Template = Record->getDescribedClassTemplate();
1024 : SemaRef(SemaRef), HLSLNamespace(Namespace) {
1030 if (SemaRef.LookupQualifiedName(
Result, HLSLNamespace)) {
1033 if (
auto *TD = dyn_cast<ClassTemplateDecl>(
Found)) {
1034 PrevDecl = TD->getTemplatedDecl();
1037 PrevDecl = dyn_cast<CXXRecordDecl>(
Found);
1038 assert(PrevDecl &&
"Unexpected lookup result type.");
1043 Template = PrevTemplate;
1050 Record->setImplicit(
true);
1051 Record->setLexicalDeclContext(HLSLNamespace);
1052 Record->setHasExternalLexicalStorage();
1056 FinalAttr::CreateImplicit(AST,
SourceRange(), FinalAttr::Keyword_final));
1060 if (HLSLNamespace && !Template && Record->getDeclContext() == HLSLNamespace)
1061 HLSLNamespace->addDecl(Record);
1068 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1069 assert(Record->isBeingDefined() &&
1070 "Definition must be started before adding members!");
1079 Field->setAccess(Access);
1080 Field->setImplicit(
true);
1081 for (
Attr *A : Attrs) {
1086 Record->addDecl(Field);
1087 Fields[Name] = Field;
1093 bool RawBuffer,
bool HasCounter,
1095 QualType ElementTy = getHandleElementType();
1096 addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer,
1097 false, ElementTy, Access);
1099 addCounterHandleMember(RC, IsROV, RawBuffer, ElementTy, Access);
1104 ResourceClass RC,
bool IsROV,
bool IsArray, ResourceDimension RD,
1106 addResourceMember(
"__handle", RC, RD, IsROV,
false,
1107 false, IsArray, getHandleElementType(),
1108 SampleCountExpr, Access);
1113 addHandleMember(ResourceClass::Sampler, ResourceDimension::Unknown,
1114 false,
false,
false,
1115 getHandleElementType());
1121 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1123 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1125 QualType ElemTy = getHandleElementType();
1135 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
1137 .dereference(PH::LastStmt)
1143 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1154CXXRecordDecl *BuiltinTypeDeclBuilder::addPrivateNestedRecord(StringRef Name) {
1155 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1164 Record->addDecl(NestedRecord);
1165 return NestedRecord;
1169 ResourceClass RC, ResourceDimension RD,
bool IsROV,
bool RawBuffer,
1170 bool IsArray, QualType ElementTy, AccessSpecifier Access) {
1171 return addResourceMember(
"__handle", RC, RD, IsROV, RawBuffer,
1172 false, IsArray, ElementTy,
1177 ResourceClass RC,
bool IsROV,
bool RawBuffer, QualType ElementTy,
1179 return addResourceMember(
"__counter_handle", RC, ResourceDimension::Unknown,
1180 IsROV, RawBuffer,
true,
1186 StringRef MemberName,
ResourceClass RC, ResourceDimension RD,
bool IsROV,
1187 bool RawBuffer,
bool IsCounter,
bool IsArray, QualType ElementTy,
1189 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1191 ASTContext &AST = SemaRef.getASTContext();
1193 assert(!ElementTy.isNull() &&
1194 "The caller should always pass in the type for the handle.");
1195 TypeSourceInfo *ElementTypeInfo =
1199 QualType AttributedResTy = QualType();
1200 SmallVector<const Attr *> Attrs = {
1201 HLSLResourceClassAttr::CreateImplicit(AST, RC),
1202 IsROV ? HLSLIsROVAttr::CreateImplicit(AST) :
nullptr,
1203 RawBuffer ? HLSLRawBufferAttr::CreateImplicit(AST) :
nullptr,
1204 RD != ResourceDimension::
Unknown
1205 ? HLSLResourceDimensionAttr::CreateImplicit(AST, RD)
1208 ? HLSLContainedTypeAttr::CreateImplicit(AST, ElementTypeInfo)
1211 Attrs.push_back(HLSLIsCounterAttr::CreateImplicit(AST));
1213 Attrs.push_back(HLSLIsArrayAttr::CreateImplicit(AST));
1214 if (SampleCountExpr)
1215 Attrs.push_back(HLSLIsMultiSampledAttr::CreateImplicit(AST));
1218 AttributedResTy,
nullptr,
1228 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1230 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1231 QualType HandleType = getResourceHandleField()->getType();
1234 .callBuiltin(
"__builtin_hlsl_resource_uninitializedhandle", HandleType,
1236 .assign(PH::Handle, PH::LastStmt)
1246 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1248 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1251 QualType HandleType = getResourceHandleField()->getType();
1254 lookupBuiltinNamespace(SemaRef,
"__detail", Record->getDeclContext());
1256 lookupBuiltinType(SemaRef,
"heap_resource_info", HLSLDetailNS);
1261 "Index field not as expected");
1264 MB.addParam(
"HeapResInfo", HeapResInfoType)
1265 .callBuiltin(
"__builtin_hlsl_resource_handlefromheap", HandleType,
1266 PH::Handle, MB.createMemberExpr(PH::_0, IndexField))
1267 .assign(PH::Handle, PH::LastStmt);
1270 QualType CounterHandleType = getResourceCounterHandleField()->getType();
1271 MB.callBuiltin(
"__builtin_hlsl_resource_counterhandlefromheap",
1272 CounterHandleType, PH::Handle)
1273 .assign(PH::CounterHandle, PH::LastStmt);
1276 return MB.finalize();
1285 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1287 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1290 QualType HandleType = getResourceHandleField()->getType();
1293 lookupBuiltinNamespace(SemaRef,
"__detail", Record->getDeclContext());
1295 lookupBuiltinType(SemaRef,
"heap_sampler_info", HLSLDetailNS);
1300 "Index field not as expected");
1303 MB.addParam(
"HeapResInfo", HeapResInfoType);
1304 MB.callBuiltin(
"__builtin_hlsl_resource_handlefromheap", HandleType,
1305 PH::Handle, MB.createMemberExpr(PH::_0, IndexField))
1306 .assign(PH::Handle, PH::LastStmt);
1308 return MB.finalize();
1314 addCreateFromBindingWithImplicitCounter();
1315 addCreateFromImplicitBindingWithImplicitCounter();
1317 addCreateFromBinding();
1318 addCreateFromImplicitBinding();
1335 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1337 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1341 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1347 .addParam(
"range", AST.
IntTy)
1350 .declareLocalVar(TmpVar)
1351 .accessHandleFieldOnResource(TmpVar)
1352 .callBuiltin(
"__builtin_hlsl_resource_handlefrombinding", HandleType,
1353 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
1354 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1355 .returnValue(TmpVar)
1372 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1374 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1378 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1384 .addParam(
"range", AST.
IntTy)
1387 .declareLocalVar(TmpVar)
1388 .accessHandleFieldOnResource(TmpVar)
1389 .callBuiltin(
"__builtin_hlsl_resource_handlefromimplicitbinding",
1390 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
1392 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1393 .returnValue(TmpVar)
1413BuiltinTypeDeclBuilder::addCreateFromBindingWithImplicitCounter() {
1414 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1416 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1418 QualType HandleType = getResourceHandleField()->
getType();
1419 QualType CounterHandleType = getResourceCounterHandleField()->
getType();
1421 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1424 "__createFromBindingWithImplicitCounter",
1428 .addParam(
"range", AST.
IntTy)
1432 .declareLocalVar(TmpVar)
1433 .accessHandleFieldOnResource(TmpVar)
1434 .callBuiltin(
"__builtin_hlsl_resource_handlefrombinding", HandleType,
1435 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
1436 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1437 .accessHandleFieldOnResource(TmpVar)
1438 .callBuiltin(
"__builtin_hlsl_resource_counterhandlefromimplicitbinding",
1439 CounterHandleType, PH::LastStmt, PH::_5, PH::_1)
1440 .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt)
1441 .returnValue(TmpVar)
1462BuiltinTypeDeclBuilder::addCreateFromImplicitBindingWithImplicitCounter() {
1463 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1465 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1466 ASTContext &AST = SemaRef.getASTContext();
1467 QualType HandleType = getResourceHandleField()->getType();
1468 QualType CounterHandleType = getResourceCounterHandleField()->getType();
1470 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1473 *
this,
"__createFromImplicitBindingWithImplicitCounter",
1477 .addParam(
"range", AST.
IntTy)
1481 .declareLocalVar(TmpVar)
1482 .accessHandleFieldOnResource(TmpVar)
1483 .callBuiltin(
"__builtin_hlsl_resource_handlefromimplicitbinding",
1484 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
1486 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1487 .accessHandleFieldOnResource(TmpVar)
1488 .callBuiltin(
"__builtin_hlsl_resource_counterhandlefromimplicitbinding",
1489 CounterHandleType, PH::LastStmt, PH::_5, PH::_1)
1490 .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt)
1491 .returnValue(TmpVar)
1497 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1504 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1508 MMB.
addParam(
"other", ConstRecordRefType);
1510 for (
auto *Field : Record->fields()) {
1520 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1528 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1531 MMB.
addParam(
"other", ConstRecordRefType);
1533 for (
auto *Field : Record->fields()) {
1544 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1547 uint32_t VecSize = 1;
1548 if (
Dim != ResourceDimension::Unknown)
1557 getResourceAttrs().ResourceClass !=
1558 llvm::dxil::ResourceClass::UAV,
1565 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1579CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsSliceType(ResourceDimension
Dim,
1587 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1592 CXXRecordDecl *MipsSliceRecord = addPrivateNestedRecord(
"mips_slice_type");
1594 MipsSliceBuilder.addFriend(
Record)
1595 .addHandleMember(getResourceAttrs().ResourceClass,
Dim,
1596 getResourceAttrs().IsROV,
false,
1597 getResourceAttrs().IsArray, ReturnType,
1604 FieldDecl *LevelField = MipsSliceBuilder.Fields[
"__level"];
1605 assert(LevelField &&
"Could not find the level field.");
1613 .addParam(
"Coord", IndexTy)
1614 .accessFieldOnResource(PH::This, LevelField)
1615 .concat(PH::_0, PH::LastStmt, CoordLevelTy)
1616 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1620 MipsSliceBuilder.completeDefinition();
1621 return MipsSliceRecord;
1624CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsType(ResourceDimension Dim,
1625 QualType ReturnType) {
1627 QualType IntTy = AST.
IntTy;
1628 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1631 CXXRecordDecl *MipsSliceRecord = addMipsSliceType(Dim, ReturnType);
1636 CXXRecordDecl *MipsRecord = addPrivateNestedRecord(
"mips_type");
1638 MipsBuilder.addFriend(
Record)
1640 getResourceAttrs().IsROV,
false,
1641 getResourceAttrs().IsArray, ReturnType,
1649 DeclarationName SubscriptName =
1653 auto FieldIt = MipsSliceRecord->field_begin();
1654 FieldDecl *MipsSliceHandleField = *FieldIt;
1656 assert(MipsSliceHandleField->getName() ==
"__handle" &&
1657 LevelField->getName() ==
"__level" &&
1658 "Could not find fields on mips_slice_type");
1661 BuiltinTypeMethodBuilder::LocalVar MipsSliceVar(
"slice", MipsSliceTy);
1664 .addParam(
"Level", IntTy)
1665 .declareLocalVar(MipsSliceVar)
1666 .accessHandleFieldOnResource(PH::This)
1667 .setFieldOnResource(MipsSliceVar, PH::LastStmt, MipsSliceHandleField)
1668 .setFieldOnResource(MipsSliceVar, PH::_0, LevelField)
1669 .returnValue(MipsSliceVar)
1672 MipsBuilder.completeDefinition();
1678 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1680 QualType ReturnType = getHandleElementType();
1694 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1697 uint32_t CoordSize = OffsetSize + (IsArray ? 2 : 1);
1701 QualType ReturnType = getHandleElementType();
1703 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1707 .addParam(
"Location", LocationTy)
1708 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1714 .addParam(
"Location", LocationTy)
1715 .addParam(
"Offset", OffsetTy)
1716 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1726 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1732 QualType ReturnType = getHandleElementType();
1734 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1738 .addParam(
"Location", LocationTy)
1739 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1749 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1753 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
1757 QualType ReturnType = getHandleElementType();
1759 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1763 .addParam(
"Location", LocationTy)
1764 .addParam(
"SampleIndex", IntTy)
1765 .callBuiltin(
"__builtin_hlsl_resource_load_ms", ReturnType, PH::Handle,
1771 .addParam(
"Location", LocationTy)
1772 .addParam(
"SampleIndex", IntTy)
1773 .addParam(
"Offset", OffsetTy)
1774 .callBuiltin(
"__builtin_hlsl_resource_load_ms", ReturnType, PH::Handle,
1775 PH::_0, PH::_1, PH::_2)
1783 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1787 auto AddLoads = [&](StringRef MethodName,
QualType ReturnType,
1788 bool TransposeResult =
false) {
1811 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1815 auto AddStore = [&](StringRef MethodName,
QualType ValueType,
1816 bool TransposeArg =
false) {
1836 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1843 "__builtin_hlsl_interlocked_add");
1845 "__builtin_hlsl_interlocked_and");
1848 "__builtin_hlsl_interlocked_exchange",
true);
1850 "__builtin_hlsl_interlocked_exchange",
1853 "__builtin_hlsl_interlocked_max");
1855 "__builtin_hlsl_interlocked_max");
1857 "__builtin_hlsl_interlocked_min");
1859 "__builtin_hlsl_interlocked_min");
1861 "__builtin_hlsl_interlocked_or");
1863 "__builtin_hlsl_interlocked_xor");
1867 bool HasInt64AtomicSupport =
1868 TT.getArch() != llvm::Triple::dxil ||
1870 if (HasInt64AtomicSupport) {
1874 "__builtin_hlsl_interlocked_add");
1877 "__builtin_hlsl_interlocked_and");
1880 "__builtin_hlsl_interlocked_exchange",
true);
1882 "__builtin_hlsl_interlocked_max");
1885 "__builtin_hlsl_interlocked_max");
1887 "__builtin_hlsl_interlocked_min");
1890 "__builtin_hlsl_interlocked_min");
1892 "__builtin_hlsl_interlocked_or");
1895 "__builtin_hlsl_interlocked_xor");
1902BuiltinTypeDeclBuilder::addDerivativeAvailability(StringRef MethodName) {
1906 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
1907 D = FTD->getTemplatedDecl();
1908 if (
auto *MD = dyn_cast<CXXMethodDecl>(D))
1909 addDerivativeAvailabilityAttrs(AST, MD);
1916 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1918 QualType ReturnType = getHandleElementType();
1920 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1922 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
1927 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1931 .addParam(
"Sampler", SamplerStateType)
1932 .addParam(
"Location", CoordTy)
1933 .accessHandleFieldOnResource(PH::_0)
1934 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1935 PH::LastStmt, PH::_1)
1936 .returnValue(PH::LastStmt)
1943 .addParam(
"Sampler", SamplerStateType)
1944 .addParam(
"Location", CoordTy)
1945 .addParam(
"Clamp", FloatTy)
1946 .accessHandleFieldOnResource(PH::_0)
1947 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1948 PH::LastStmt, PH::_1, PH::_2)
1949 .returnValue(PH::LastStmt)
1953 return addDerivativeAvailability(
"Sample");
1958 .addParam(
"Sampler", SamplerStateType)
1959 .addParam(
"Location", CoordTy)
1960 .addParam(
"Offset", OffsetTy)
1961 .accessHandleFieldOnResource(PH::_0)
1962 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1963 PH::LastStmt, PH::_1, PH::_2)
1964 .returnValue(PH::LastStmt)
1969 .addParam(
"Sampler", SamplerStateType)
1970 .addParam(
"Location", CoordTy)
1971 .addParam(
"Offset", OffsetTy)
1972 .addParam(
"Clamp", FloatTy)
1973 .accessHandleFieldOnResource(PH::_0)
1974 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1975 PH::LastStmt, PH::_1, PH::_2, PH::_3)
1976 .returnValue(PH::LastStmt)
1980 return addDerivativeAvailability(
"Sample");
1986 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1988 QualType ReturnType = getHandleElementType();
1990 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1992 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
1997 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2001 .addParam(
"Sampler", SamplerStateType)
2002 .addParam(
"Location", CoordTy)
2003 .addParam(
"Bias", FloatTy)
2004 .accessHandleFieldOnResource(PH::_0)
2005 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
2006 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
2007 .returnValue(PH::LastStmt)
2014 .addParam(
"Sampler", SamplerStateType)
2015 .addParam(
"Location", CoordTy)
2016 .addParam(
"Bias", FloatTy)
2017 .addParam(
"Clamp", FloatTy)
2018 .accessHandleFieldOnResource(PH::_0)
2019 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
2020 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2021 .returnValue(PH::LastStmt)
2025 return addDerivativeAvailability(
"SampleBias");
2030 .addParam(
"Sampler", SamplerStateType)
2031 .addParam(
"Location", CoordTy)
2032 .addParam(
"Bias", FloatTy)
2033 .addParam(
"Offset", OffsetTy)
2034 .accessHandleFieldOnResource(PH::_0)
2035 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
2036 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2037 .returnValue(PH::LastStmt)
2043 .addParam(
"Sampler", SamplerStateType)
2044 .addParam(
"Location", CoordTy)
2045 .addParam(
"Bias", FloatTy)
2046 .addParam(
"Offset", OffsetTy)
2047 .addParam(
"Clamp", FloatTy)
2048 .accessHandleFieldOnResource(PH::_0)
2049 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
2050 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
2051 .returnValue(PH::LastStmt)
2055 return addDerivativeAvailability(
"SampleBias");
2061 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2063 QualType ReturnType = getHandleElementType();
2065 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2067 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2073 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2077 .addParam(
"Sampler", SamplerStateType)
2078 .addParam(
"Location", CoordTy)
2079 .addParam(
"DDX", OffsetFloatTy)
2080 .addParam(
"DDY", OffsetFloatTy)
2081 .accessHandleFieldOnResource(PH::_0)
2082 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
2083 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2084 .returnValue(PH::LastStmt)
2092 .addParam(
"Sampler", SamplerStateType)
2093 .addParam(
"Location", CoordTy)
2094 .addParam(
"DDX", OffsetFloatTy)
2095 .addParam(
"DDY", OffsetFloatTy)
2096 .addParam(
"Clamp", FloatTy)
2097 .accessHandleFieldOnResource(PH::_0)
2098 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
2099 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
2100 .returnValue(PH::LastStmt)
2108 .addParam(
"Sampler", SamplerStateType)
2109 .addParam(
"Location", CoordTy)
2110 .addParam(
"DDX", OffsetFloatTy)
2111 .addParam(
"DDY", OffsetFloatTy)
2112 .addParam(
"Offset", OffsetTy)
2113 .accessHandleFieldOnResource(PH::_0)
2114 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
2115 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
2116 .returnValue(PH::LastStmt)
2122 .addParam(
"Sampler", SamplerStateType)
2123 .addParam(
"Location", CoordTy)
2124 .addParam(
"DDX", OffsetFloatTy)
2125 .addParam(
"DDY", OffsetFloatTy)
2126 .addParam(
"Offset", OffsetTy)
2127 .addParam(
"Clamp", FloatTy)
2128 .accessHandleFieldOnResource(PH::_0)
2129 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
2130 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4,
2132 .returnValue(PH::LastStmt)
2141 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2143 QualType ReturnType = getHandleElementType();
2145 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2147 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2152 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2156 .addParam(
"Sampler", SamplerStateType)
2157 .addParam(
"Location", CoordTy)
2158 .addParam(
"LOD", FloatTy)
2159 .accessHandleFieldOnResource(PH::_0)
2160 .callBuiltin(
"__builtin_hlsl_resource_sample_level", ReturnType,
2161 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
2162 .returnValue(PH::LastStmt)
2171 .addParam(
"Sampler", SamplerStateType)
2172 .addParam(
"Location", CoordTy)
2173 .addParam(
"LOD", FloatTy)
2174 .addParam(
"Offset", OffsetTy)
2175 .accessHandleFieldOnResource(PH::_0)
2176 .callBuiltin(
"__builtin_hlsl_resource_sample_level", ReturnType,
2177 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2178 .returnValue(PH::LastStmt)
2187 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2190 QualType SamplerComparisonStateType = lookupBuiltinType(
2191 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
2193 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2198 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2202 .addParam(
"Sampler", SamplerComparisonStateType)
2203 .addParam(
"Location", CoordTy)
2204 .addParam(
"CompareValue", FloatTy)
2205 .accessHandleFieldOnResource(PH::_0)
2206 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
2207 PH::LastStmt, PH::_1, PH::_2)
2208 .returnValue(PH::LastStmt)
2216 .addParam(
"Sampler", SamplerComparisonStateType)
2217 .addParam(
"Location", CoordTy)
2218 .addParam(
"CompareValue", FloatTy)
2219 .addParam(
"Clamp", FloatTy)
2220 .accessHandleFieldOnResource(PH::_0)
2221 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType,
2222 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2223 .returnValue(PH::LastStmt)
2227 return addDerivativeAvailability(
"SampleCmp");
2233 .addParam(
"Sampler", SamplerComparisonStateType)
2234 .addParam(
"Location", CoordTy)
2235 .addParam(
"CompareValue", FloatTy)
2236 .addParam(
"Offset", OffsetTy)
2237 .accessHandleFieldOnResource(PH::_0)
2238 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
2239 PH::LastStmt, PH::_1, PH::_2, PH::_3)
2240 .returnValue(PH::LastStmt)
2246 .addParam(
"Sampler", SamplerComparisonStateType)
2247 .addParam(
"Location", CoordTy)
2248 .addParam(
"CompareValue", FloatTy)
2249 .addParam(
"Offset", OffsetTy)
2250 .addParam(
"Clamp", FloatTy)
2251 .accessHandleFieldOnResource(PH::_0)
2252 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
2253 PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
2254 .returnValue(PH::LastStmt)
2258 return addDerivativeAvailability(
"SampleCmp");
2264 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2267 QualType SamplerComparisonStateType = lookupBuiltinType(
2268 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
2270 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2275 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2280 .addParam(
"Sampler", SamplerComparisonStateType)
2281 .addParam(
"Location", CoordTy)
2282 .addParam(
"CompareValue", FloatTy)
2283 .accessHandleFieldOnResource(PH::_0)
2284 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
2285 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
2286 .returnValue(PH::LastStmt)
2296 .addParam(
"Sampler", SamplerComparisonStateType)
2297 .addParam(
"Location", CoordTy)
2298 .addParam(
"CompareValue", FloatTy)
2299 .addParam(
"Offset", OffsetTy)
2300 .accessHandleFieldOnResource(PH::_0)
2301 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
2302 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2303 .returnValue(PH::LastStmt)
2311 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2312 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2316 assert(
Dim != ResourceDimension::Unknown);
2320 QualType Params[] = {UIntTy, FloatTy};
2323 if (
Dim == ResourceDimension::Dim2D) {
2324 StringRef XYName =
"__builtin_hlsl_resource_getdimensions_xy";
2325 StringRef LevelsXYName =
2326 "__builtin_hlsl_resource_getdimensions_levels_xy";
2328 if (OutTy == FloatTy) {
2329 XYName =
"__builtin_hlsl_resource_getdimensions_xy_float";
2330 LevelsXYName =
"__builtin_hlsl_resource_getdimensions_levels_xy_float";
2335 .addParam(
"width", OutTy, HLSLParamModifierAttr::Keyword_out)
2336 .addParam(
"height", OutTy, HLSLParamModifierAttr::Keyword_out)
2337 .callBuiltin(XYName,
QualType(), PH::Handle, PH::_0, PH::_1)
2343 .addParam(
"mipLevel", UIntTy)
2344 .addParam(
"width", OutTy, HLSLParamModifierAttr::Keyword_out)
2345 .addParam(
"height", OutTy, HLSLParamModifierAttr::Keyword_out)
2346 .addParam(
"numberOfLevels", OutTy, HLSLParamModifierAttr::Keyword_out)
2347 .callBuiltin(LevelsXYName,
QualType(), PH::Handle, PH::_0, PH::_1,
2358 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2362 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2366 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2370 .addParam(
"Sampler", SamplerStateType)
2371 .addParam(
"Location", LocationTy)
2372 .accessHandleFieldOnResource(PH::_0)
2373 .callBuiltin(
"__builtin_hlsl_resource_calculate_lod", ReturnType,
2374 PH::Handle, PH::LastStmt, PH::_1)
2379 .addParam(
"Sampler", SamplerStateType)
2380 .addParam(
"Location", LocationTy)
2381 .accessHandleFieldOnResource(PH::_0)
2382 .callBuiltin(
"__builtin_hlsl_resource_calculate_lod_unclamped",
2383 ReturnType, PH::Handle, PH::LastStmt, PH::_1)
2387 addDerivativeAvailability(
"CalculateLevelOfDetail");
2388 return addDerivativeAvailability(
"CalculateLevelOfDetailUnclamped");
2391QualType BuiltinTypeDeclBuilder::getGatherReturnType() {
2398 T = VT->getElementType();
2400 T = DT->getElementType();
2407 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2409 QualType ReturnType = getGatherReturnType();
2412 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2414 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2419 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2422 struct GatherVariant {
2426 GatherVariant Variants[] = {{
"Gather", 0},
2430 {
"GatherAlpha", 3}};
2432 for (
const auto &
V : Variants) {
2435 .addParam(
"Sampler", SamplerStateType)
2436 .addParam(
"Location", CoordTy)
2437 .accessHandleFieldOnResource(PH::_0)
2438 .callBuiltin(
"__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
2439 PH::LastStmt, PH::_1,
2440 getConstantUnsignedIntExpr(
V.Component))
2449 .addParam(
"Sampler", SamplerStateType)
2450 .addParam(
"Location", CoordTy)
2451 .addParam(
"Offset", OffsetTy)
2452 .accessHandleFieldOnResource(PH::_0)
2453 .callBuiltin(
"__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
2454 PH::LastStmt, PH::_1,
2455 getConstantUnsignedIntExpr(
V.Component), PH::_2)
2465 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2469 QualType SamplerComparisonStateType = lookupBuiltinType(
2470 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
2472 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2477 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2481 struct GatherVariant {
2485 GatherVariant Variants[] = {{
"GatherCmp", 0},
2486 {
"GatherCmpRed", 0},
2487 {
"GatherCmpGreen", 1},
2488 {
"GatherCmpBlue", 2},
2489 {
"GatherCmpAlpha", 3}};
2491 for (
const auto &
V : Variants) {
2495 .addParam(
"Sampler", SamplerComparisonStateType)
2496 .addParam(
"Location", CoordTy)
2497 .addParam(
"CompareValue", FloatTy)
2498 .accessHandleFieldOnResource(PH::_0)
2499 .callBuiltin(
"__builtin_hlsl_resource_gather_cmp", ReturnType,
2500 PH::Handle, PH::LastStmt, PH::_1, PH::_2,
2501 getConstantUnsignedIntExpr(
V.Component))
2511 .addParam(
"Sampler", SamplerComparisonStateType)
2512 .addParam(
"Location", CoordTy)
2513 .addParam(
"CompareValue", FloatTy)
2514 .addParam(
"Offset", OffsetTy)
2515 .accessHandleFieldOnResource(PH::_0)
2516 .callBuiltin(
"__builtin_hlsl_resource_gather_cmp", ReturnType,
2517 PH::Handle, PH::LastStmt, PH::_1, PH::_2,
2518 getConstantUnsignedIntExpr(
V.Component), PH::_3)
2525FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField()
const {
2526 auto I = Fields.find(
"__handle");
2527 assert(I != Fields.end() &&
2528 I->second->getType()->isHLSLAttributedResourceType() &&
2529 "record does not have resource handle field");
2533FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField()
const {
2534 auto I = Fields.find(
"__counter_handle");
2535 if (I == Fields.end() ||
2536 !I->second->getType()->isHLSLAttributedResourceType())
2541QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam() {
2542 assert(
Template &&
"record it not a template");
2543 if (
const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
2544 Template->getTemplateParameters()->getParam(0))) {
2545 return QualType(TTD->getTypeForDecl(), 0);
2550QualType BuiltinTypeDeclBuilder::getHandleElementType() {
2552 return getFirstTemplateTypeParam();
2554 if (
auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
2555 const auto &Args = Spec->getTemplateArgs();
2557 return Args[0].getAsType();
2561 return SemaRef.getASTContext().Char8Ty;
2564HLSLAttributedResourceType::Attributes
2565BuiltinTypeDeclBuilder::getResourceAttrs()
const {
2566 QualType HandleType = getResourceHandleField()->getType();
2571 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2572 assert(Record->isBeingDefined() &&
2573 "Definition must be started before completing it.");
2575 Record->completeDefinition();
2576 Record->setIsHLSLBuiltinRecord(
true);
2580Expr *BuiltinTypeDeclBuilder::getConstantIntExpr(
int value) {
2587Expr *BuiltinTypeDeclBuilder::getConstantUnsignedIntExpr(
unsigned value) {
2604 if (Record->isCompleteDefinition()) {
2605 assert(Template &&
"existing record it not a template");
2606 assert(Template->getTemplateParameters()->size() == Names.size() &&
2607 "template param count mismatch");
2611 assert((DefaultTypes.empty() || DefaultTypes.size() == Names.size()) &&
2612 "template default argument count mismatch");
2615 for (
unsigned i = 0; i < Names.size(); ++i) {
2617 Builder.addTypeParameter(Names[i], DefaultTy);
2619 return Builder.finalizeTemplateArgs(CD);
2623 StringRef ElementName, StringRef SampleCountName,
ConceptDecl *CD) {
2624 if (Record->isCompleteDefinition()) {
2625 assert(Template &&
"existing record it not a template");
2626 assert(Template->getTemplateParameters()->size() == 2 &&
2627 "template param count mismatch");
2636 Builder.addTypeParameter(ElementName);
2637 Builder.addNonTypeParameter(SampleCountName, AST.
IntTy,
2638 getConstantIntExpr(0));
2639 return Builder.finalizeTemplateArgs(CD);
2643 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2644 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
2646 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
2647 PH::CounterHandle, getConstantIntExpr(1))
2652 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2653 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
2655 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
2656 PH::CounterHandle, getConstantIntExpr(-1))
2663 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2665 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2666 bool NeedsTypedBuiltin = !ReturnTy.
isNull();
2672 if (!NeedsTypedBuiltin)
2673 ReturnTy = getHandleElementType();
2676 MMB.ReturnTy = ReturnTy;
2680 HLSLParamModifierAttr::Keyword_out);
2682 if (NeedsTypedBuiltin)
2683 MMB.
callBuiltin(
"__builtin_hlsl_resource_load_with_status_typed", ReturnTy,
2684 PH::Handle, PH::_0, PH::_1, ReturnTy);
2686 MMB.
callBuiltin(
"__builtin_hlsl_resource_load_with_status", ReturnTy,
2687 PH::Handle, PH::_0, PH::_1);
2694 QualType ElemTy,
bool TransposeResult) {
2695 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2697 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2698 bool NeedsTypedBuiltin = !ElemTy.
isNull();
2704 if (!NeedsTypedBuiltin)
2705 ElemTy = getHandleElementType();
2714 ReturnTy = AddrSpaceElemTy;
2719 assert(!IsConstReturn &&
"There shouldn't be any resource methods with a "
2720 "const ref return value");
2723 MMB.ReturnTy = ReturnTy;
2727 if (NeedsTypedBuiltin)
2728 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2729 PH::Handle, PH::_0, ElemTy);
2731 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer", ElemPtrTy, PH::Handle,
2735 if (TransposeResult)
2736 MMB.
callBuiltin(
"__builtin_hlsl_transpose_if_memory_is_row_major", ElemTy,
2737 PH::LastStmt, getConstantIntExpr(1));
2743 QualType ValueTy,
bool TransposeArg) {
2744 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2746 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2758 MMB.
callBuiltin(
"__builtin_hlsl_transpose_if_memory_is_row_major", ValueTy,
2759 PH::_1, getConstantIntExpr(0));
2760 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2761 PH::Handle, PH::_0, ValueTy)
2763 .
assign(PH::LastStmt, TransposeArg ? PH::LastStmt : PH::_1);
2769 StringRef MethodName,
QualType ValueTy, StringRef BuiltinName,
2770 bool RequiresOriginalValue) {
2771 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2773 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2783 auto BuildOverload = [&](
bool WithOriginalValue) {
2786 if (WithOriginalValue)
2787 MMB.
addParam(
"OriginalValue", ValueTy,
2788 HLSLParamModifierAttr::Keyword_out);
2789 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2790 PH::Handle, PH::_0, ValueTy)
2792 if (WithOriginalValue)
2799 if (!RequiresOriginalValue)
2800 BuildOverload(
false);
2801 BuildOverload(
true);
2806 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2808 QualType ElemTy = getHandleElementType();
2812 .addParam(
"value", ElemTy)
2813 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
2814 PH::CounterHandle, getConstantIntExpr(1))
2815 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
2818 .dereference(PH::LastStmt)
2819 .assign(PH::LastStmt, PH::_0)
2824 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2826 QualType ElemTy = getHandleElementType();
2830 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
2831 PH::CounterHandle, getConstantIntExpr(-1))
2832 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
2835 .dereference(PH::LastStmt)
2841 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2845 QualType HandleTy = getResourceHandleField()->getType();
2850 if (AttrResTy->getAttrs().RawBuffer &&
2851 AttrResTy->getContainedType() != AST.
Char8Ty) {
2853 .addParam(
"numStructs", UIntTy, HLSLParamModifierAttr::Keyword_out)
2854 .addParam(
"stride", UIntTy, HLSLParamModifierAttr::Keyword_out)
2855 .callBuiltin(
"__builtin_hlsl_resource_getdimensions_x",
QualType(),
2857 .callBuiltin(
"__builtin_hlsl_resource_getstride",
QualType(),
2865 .addParam(
"dim", UIntTy, HLSLParamModifierAttr::Keyword_out)
2866 .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
static QualType getVectorOrScalarType(Sema &S, QualType BaseType, unsigned Count)
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
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
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, TemplateName 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 NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
Represents a parameter to a function.
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.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
field_iterator field_begin() const
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....
@ LookupNamespaceName
Look up a namespace name within a C++ using directive or namespace alias definition,...
@ 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
const T * getAs() const
Member-template getAs<specific type>'.
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.
unsigned getNumElements() const
BuiltinTypeDeclBuilder & addMSTextureTemplateParams(StringRef ElementName, StringRef SampleCountName, ConceptDecl *CD)
friend struct BuiltinTypeMethodBuilder
BuiltinTypeDeclBuilder & addRWTextureLoadMethods(ResourceDimension Dim, bool IsArray=false)
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 & 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 & addStoreFunction(DeclarationName &Name, bool IsConst, QualType ValueType, bool TransposeArg=false)
BuiltinTypeDeclBuilder & addGetDimensionsMethodForBuffer()
BuiltinTypeDeclBuilder & addTextureLoadMSMethods(ResourceDimension Dim, bool IsArray=false)
BuiltinTypeDeclBuilder & addConstantBufferConversionToType()
BuiltinTypeDeclBuilder & addSamplerHandle()
BuiltinTypeDeclBuilder & addTextureLoadMethods(ResourceDimension Dim, bool IsArray=false)
BuiltinTypeDeclBuilder & completeDefinition()
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 & addHandleAccessFunction(DeclarationName &Name, bool IsConstReturn, bool IsRef, QualType IndexTy, QualType ElemTy=QualType(), bool TransposeResult=false)
BuiltinTypeDeclBuilder & addHeapResourceInfoConstructor(bool HasCounter=false)
BuiltinTypeDeclBuilder & addByteAddressBufferInterlockedMethod(StringRef MethodName, QualType ValueTy, StringRef BuiltinName, bool RequiresOriginalValue=false)
BuiltinTypeDeclBuilder & addLoadWithStatusFunction(DeclarationName &Name, QualType ReturnTy=QualType())
BuiltinTypeDeclBuilder & addIncrementCounterMethod()
BuiltinTypeDeclBuilder & addSampleCmpMethods(ResourceDimension Dim, bool IsArray=false)
BuiltinTypeDeclBuilder & addMipsMember(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addHeapSamplerInfoConstructor()
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 & addTextureHandle(ResourceClass RC, bool IsROV, bool IsArray, ResourceDimension RD, Expr *SampleCountExpr=nullptr, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addLoadMethods()
BuiltinTypeDeclBuilder & addSampleCmpLevelZeroMethods(ResourceDimension Dim, bool IsArray=false)
uint32_t getResourceDimensions(llvm::dxil::ResourceDimension Dim)
bool hasResourceOffset(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.
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
@ 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.
@ 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.
bool CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, ArrayRef< const Attr * > AttrList, QualType &ResType, HLSLAttributedResourceLocInfo *LocInfo=nullptr, Expr *SampleCountExpr=nullptr)
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
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()
CXXThisExpr * createThisExpr()
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)
MemberExpr * createMemberExpr(T Base, FieldDecl *Field)
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 & addNonTypeParameter(StringRef Name, QualType Ty, Expr *DefaultValue=nullptr)
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