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;
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_compare_exchange",
1851 "InterlockedCompareExchangeFloatBitwise", AST.
FloatTy,
1852 "__builtin_hlsl_interlocked_compare_exchange_float_bitwise",
1856 "__builtin_hlsl_interlocked_compare_store");
1858 "InterlockedCompareStoreFloatBitwise", AST.
FloatTy,
1859 "__builtin_hlsl_interlocked_compare_store_float_bitwise");
1862 "__builtin_hlsl_interlocked_exchange",
true);
1864 "__builtin_hlsl_interlocked_exchange",
1867 "__builtin_hlsl_interlocked_max");
1869 "__builtin_hlsl_interlocked_max");
1871 "__builtin_hlsl_interlocked_min");
1873 "__builtin_hlsl_interlocked_min");
1875 "__builtin_hlsl_interlocked_or");
1877 "__builtin_hlsl_interlocked_xor");
1881 bool HasInt64AtomicSupport =
1882 TT.getArch() != llvm::Triple::dxil ||
1884 if (HasInt64AtomicSupport) {
1888 "__builtin_hlsl_interlocked_add");
1891 "__builtin_hlsl_interlocked_and");
1894 "__builtin_hlsl_interlocked_compare_exchange",
1898 "__builtin_hlsl_interlocked_compare_store");
1901 "__builtin_hlsl_interlocked_exchange",
true);
1903 "__builtin_hlsl_interlocked_max");
1906 "__builtin_hlsl_interlocked_max");
1908 "__builtin_hlsl_interlocked_min");
1911 "__builtin_hlsl_interlocked_min");
1913 "__builtin_hlsl_interlocked_or");
1916 "__builtin_hlsl_interlocked_xor");
1923BuiltinTypeDeclBuilder::addDerivativeAvailability(StringRef MethodName) {
1927 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
1928 D = FTD->getTemplatedDecl();
1929 if (
auto *MD = dyn_cast<CXXMethodDecl>(D))
1930 addDerivativeAvailabilityAttrs(AST, MD);
1937 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1939 QualType ReturnType = getHandleElementType();
1941 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1943 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
1948 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1952 .addParam(
"Sampler", SamplerStateType)
1953 .addParam(
"Location", CoordTy)
1954 .accessHandleFieldOnResource(PH::_0)
1955 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1956 PH::LastStmt, PH::_1)
1957 .returnValue(PH::LastStmt)
1964 .addParam(
"Sampler", SamplerStateType)
1965 .addParam(
"Location", CoordTy)
1966 .addParam(
"Clamp", FloatTy)
1967 .accessHandleFieldOnResource(PH::_0)
1968 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1969 PH::LastStmt, PH::_1, PH::_2)
1970 .returnValue(PH::LastStmt)
1974 return addDerivativeAvailability(
"Sample");
1979 .addParam(
"Sampler", SamplerStateType)
1980 .addParam(
"Location", CoordTy)
1981 .addParam(
"Offset", OffsetTy)
1982 .accessHandleFieldOnResource(PH::_0)
1983 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1984 PH::LastStmt, PH::_1, PH::_2)
1985 .returnValue(PH::LastStmt)
1990 .addParam(
"Sampler", SamplerStateType)
1991 .addParam(
"Location", CoordTy)
1992 .addParam(
"Offset", OffsetTy)
1993 .addParam(
"Clamp", FloatTy)
1994 .accessHandleFieldOnResource(PH::_0)
1995 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1996 PH::LastStmt, PH::_1, PH::_2, PH::_3)
1997 .returnValue(PH::LastStmt)
2001 return addDerivativeAvailability(
"Sample");
2007 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2009 QualType ReturnType = getHandleElementType();
2011 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2013 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2018 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2022 .addParam(
"Sampler", SamplerStateType)
2023 .addParam(
"Location", CoordTy)
2024 .addParam(
"Bias", FloatTy)
2025 .accessHandleFieldOnResource(PH::_0)
2026 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
2027 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
2028 .returnValue(PH::LastStmt)
2035 .addParam(
"Sampler", SamplerStateType)
2036 .addParam(
"Location", CoordTy)
2037 .addParam(
"Bias", FloatTy)
2038 .addParam(
"Clamp", FloatTy)
2039 .accessHandleFieldOnResource(PH::_0)
2040 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
2041 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2042 .returnValue(PH::LastStmt)
2046 return addDerivativeAvailability(
"SampleBias");
2051 .addParam(
"Sampler", SamplerStateType)
2052 .addParam(
"Location", CoordTy)
2053 .addParam(
"Bias", FloatTy)
2054 .addParam(
"Offset", OffsetTy)
2055 .accessHandleFieldOnResource(PH::_0)
2056 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
2057 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2058 .returnValue(PH::LastStmt)
2064 .addParam(
"Sampler", SamplerStateType)
2065 .addParam(
"Location", CoordTy)
2066 .addParam(
"Bias", FloatTy)
2067 .addParam(
"Offset", OffsetTy)
2068 .addParam(
"Clamp", FloatTy)
2069 .accessHandleFieldOnResource(PH::_0)
2070 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
2071 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
2072 .returnValue(PH::LastStmt)
2076 return addDerivativeAvailability(
"SampleBias");
2082 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2084 QualType ReturnType = getHandleElementType();
2086 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2088 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2094 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2098 .addParam(
"Sampler", SamplerStateType)
2099 .addParam(
"Location", CoordTy)
2100 .addParam(
"DDX", OffsetFloatTy)
2101 .addParam(
"DDY", OffsetFloatTy)
2102 .accessHandleFieldOnResource(PH::_0)
2103 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
2104 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2105 .returnValue(PH::LastStmt)
2113 .addParam(
"Sampler", SamplerStateType)
2114 .addParam(
"Location", CoordTy)
2115 .addParam(
"DDX", OffsetFloatTy)
2116 .addParam(
"DDY", OffsetFloatTy)
2117 .addParam(
"Clamp", FloatTy)
2118 .accessHandleFieldOnResource(PH::_0)
2119 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
2120 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
2121 .returnValue(PH::LastStmt)
2129 .addParam(
"Sampler", SamplerStateType)
2130 .addParam(
"Location", CoordTy)
2131 .addParam(
"DDX", OffsetFloatTy)
2132 .addParam(
"DDY", OffsetFloatTy)
2133 .addParam(
"Offset", OffsetTy)
2134 .accessHandleFieldOnResource(PH::_0)
2135 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
2136 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
2137 .returnValue(PH::LastStmt)
2143 .addParam(
"Sampler", SamplerStateType)
2144 .addParam(
"Location", CoordTy)
2145 .addParam(
"DDX", OffsetFloatTy)
2146 .addParam(
"DDY", OffsetFloatTy)
2147 .addParam(
"Offset", OffsetTy)
2148 .addParam(
"Clamp", FloatTy)
2149 .accessHandleFieldOnResource(PH::_0)
2150 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
2151 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4,
2153 .returnValue(PH::LastStmt)
2162 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2164 QualType ReturnType = getHandleElementType();
2166 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2168 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2173 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2177 .addParam(
"Sampler", SamplerStateType)
2178 .addParam(
"Location", CoordTy)
2179 .addParam(
"LOD", FloatTy)
2180 .accessHandleFieldOnResource(PH::_0)
2181 .callBuiltin(
"__builtin_hlsl_resource_sample_level", ReturnType,
2182 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
2183 .returnValue(PH::LastStmt)
2192 .addParam(
"Sampler", SamplerStateType)
2193 .addParam(
"Location", CoordTy)
2194 .addParam(
"LOD", FloatTy)
2195 .addParam(
"Offset", OffsetTy)
2196 .accessHandleFieldOnResource(PH::_0)
2197 .callBuiltin(
"__builtin_hlsl_resource_sample_level", ReturnType,
2198 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2199 .returnValue(PH::LastStmt)
2208 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2211 QualType SamplerComparisonStateType = lookupBuiltinType(
2212 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
2214 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2219 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2223 .addParam(
"Sampler", SamplerComparisonStateType)
2224 .addParam(
"Location", CoordTy)
2225 .addParam(
"CompareValue", FloatTy)
2226 .accessHandleFieldOnResource(PH::_0)
2227 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
2228 PH::LastStmt, PH::_1, PH::_2)
2229 .returnValue(PH::LastStmt)
2237 .addParam(
"Sampler", SamplerComparisonStateType)
2238 .addParam(
"Location", CoordTy)
2239 .addParam(
"CompareValue", FloatTy)
2240 .addParam(
"Clamp", FloatTy)
2241 .accessHandleFieldOnResource(PH::_0)
2242 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType,
2243 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2244 .returnValue(PH::LastStmt)
2248 return addDerivativeAvailability(
"SampleCmp");
2254 .addParam(
"Sampler", SamplerComparisonStateType)
2255 .addParam(
"Location", CoordTy)
2256 .addParam(
"CompareValue", FloatTy)
2257 .addParam(
"Offset", OffsetTy)
2258 .accessHandleFieldOnResource(PH::_0)
2259 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
2260 PH::LastStmt, PH::_1, PH::_2, PH::_3)
2261 .returnValue(PH::LastStmt)
2267 .addParam(
"Sampler", SamplerComparisonStateType)
2268 .addParam(
"Location", CoordTy)
2269 .addParam(
"CompareValue", FloatTy)
2270 .addParam(
"Offset", OffsetTy)
2271 .addParam(
"Clamp", FloatTy)
2272 .accessHandleFieldOnResource(PH::_0)
2273 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
2274 PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
2275 .returnValue(PH::LastStmt)
2279 return addDerivativeAvailability(
"SampleCmp");
2285 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2288 QualType SamplerComparisonStateType = lookupBuiltinType(
2289 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
2291 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2296 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2301 .addParam(
"Sampler", SamplerComparisonStateType)
2302 .addParam(
"Location", CoordTy)
2303 .addParam(
"CompareValue", FloatTy)
2304 .accessHandleFieldOnResource(PH::_0)
2305 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
2306 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
2307 .returnValue(PH::LastStmt)
2317 .addParam(
"Sampler", SamplerComparisonStateType)
2318 .addParam(
"Location", CoordTy)
2319 .addParam(
"CompareValue", FloatTy)
2320 .addParam(
"Offset", OffsetTy)
2321 .accessHandleFieldOnResource(PH::_0)
2322 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
2323 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
2324 .returnValue(PH::LastStmt)
2332 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2333 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2337 assert(
Dim != ResourceDimension::Unknown);
2341 QualType Params[] = {UIntTy, FloatTy};
2344 if (
Dim == ResourceDimension::Dim2D) {
2345 StringRef XYName =
"__builtin_hlsl_resource_getdimensions_xy";
2346 StringRef LevelsXYName =
2347 "__builtin_hlsl_resource_getdimensions_levels_xy";
2349 if (OutTy == FloatTy) {
2350 XYName =
"__builtin_hlsl_resource_getdimensions_xy_float";
2351 LevelsXYName =
"__builtin_hlsl_resource_getdimensions_levels_xy_float";
2356 .addParam(
"width", OutTy, HLSLParamModifierAttr::Keyword_out)
2357 .addParam(
"height", OutTy, HLSLParamModifierAttr::Keyword_out)
2358 .callBuiltin(XYName,
QualType(), PH::Handle, PH::_0, PH::_1)
2364 .addParam(
"mipLevel", UIntTy)
2365 .addParam(
"width", OutTy, HLSLParamModifierAttr::Keyword_out)
2366 .addParam(
"height", OutTy, HLSLParamModifierAttr::Keyword_out)
2367 .addParam(
"numberOfLevels", OutTy, HLSLParamModifierAttr::Keyword_out)
2368 .callBuiltin(LevelsXYName,
QualType(), PH::Handle, PH::_0, PH::_1,
2379 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2383 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2387 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2391 .addParam(
"Sampler", SamplerStateType)
2392 .addParam(
"Location", LocationTy)
2393 .accessHandleFieldOnResource(PH::_0)
2394 .callBuiltin(
"__builtin_hlsl_resource_calculate_lod", ReturnType,
2395 PH::Handle, PH::LastStmt, PH::_1)
2400 .addParam(
"Sampler", SamplerStateType)
2401 .addParam(
"Location", LocationTy)
2402 .accessHandleFieldOnResource(PH::_0)
2403 .callBuiltin(
"__builtin_hlsl_resource_calculate_lod_unclamped",
2404 ReturnType, PH::Handle, PH::LastStmt, PH::_1)
2408 addDerivativeAvailability(
"CalculateLevelOfDetail");
2409 return addDerivativeAvailability(
"CalculateLevelOfDetailUnclamped");
2412QualType BuiltinTypeDeclBuilder::getGatherReturnType() {
2419 T = VT->getElementType();
2421 T = DT->getElementType();
2428 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2430 QualType ReturnType = getGatherReturnType();
2433 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2435 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2440 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2443 struct GatherVariant {
2447 GatherVariant Variants[] = {{
"Gather", 0},
2451 {
"GatherAlpha", 3}};
2453 for (
const auto &
V : Variants) {
2456 .addParam(
"Sampler", SamplerStateType)
2457 .addParam(
"Location", CoordTy)
2458 .accessHandleFieldOnResource(PH::_0)
2459 .callBuiltin(
"__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
2460 PH::LastStmt, PH::_1,
2461 getConstantUnsignedIntExpr(
V.Component))
2470 .addParam(
"Sampler", SamplerStateType)
2471 .addParam(
"Location", CoordTy)
2472 .addParam(
"Offset", OffsetTy)
2473 .accessHandleFieldOnResource(PH::_0)
2474 .callBuiltin(
"__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
2475 PH::LastStmt, PH::_1,
2476 getConstantUnsignedIntExpr(
V.Component), PH::_2)
2486 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2490 QualType SamplerComparisonStateType = lookupBuiltinType(
2491 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
2493 uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
2498 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2502 struct GatherVariant {
2506 GatherVariant Variants[] = {{
"GatherCmp", 0},
2507 {
"GatherCmpRed", 0},
2508 {
"GatherCmpGreen", 1},
2509 {
"GatherCmpBlue", 2},
2510 {
"GatherCmpAlpha", 3}};
2512 for (
const auto &
V : Variants) {
2516 .addParam(
"Sampler", SamplerComparisonStateType)
2517 .addParam(
"Location", CoordTy)
2518 .addParam(
"CompareValue", FloatTy)
2519 .accessHandleFieldOnResource(PH::_0)
2520 .callBuiltin(
"__builtin_hlsl_resource_gather_cmp", ReturnType,
2521 PH::Handle, PH::LastStmt, PH::_1, PH::_2,
2522 getConstantUnsignedIntExpr(
V.Component))
2532 .addParam(
"Sampler", SamplerComparisonStateType)
2533 .addParam(
"Location", CoordTy)
2534 .addParam(
"CompareValue", FloatTy)
2535 .addParam(
"Offset", OffsetTy)
2536 .accessHandleFieldOnResource(PH::_0)
2537 .callBuiltin(
"__builtin_hlsl_resource_gather_cmp", ReturnType,
2538 PH::Handle, PH::LastStmt, PH::_1, PH::_2,
2539 getConstantUnsignedIntExpr(
V.Component), PH::_3)
2546FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField()
const {
2547 auto I = Fields.find(
"__handle");
2548 assert(I != Fields.end() &&
2549 I->second->getType()->isHLSLAttributedResourceType() &&
2550 "record does not have resource handle field");
2554FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField()
const {
2555 auto I = Fields.find(
"__counter_handle");
2556 if (I == Fields.end() ||
2557 !I->second->getType()->isHLSLAttributedResourceType())
2562QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam() {
2563 assert(
Template &&
"record it not a template");
2564 if (
const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
2565 Template->getTemplateParameters()->getParam(0))) {
2566 return QualType(TTD->getTypeForDecl(), 0);
2571QualType BuiltinTypeDeclBuilder::getHandleElementType() {
2573 return getFirstTemplateTypeParam();
2575 if (
auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
2576 const auto &Args = Spec->getTemplateArgs();
2578 return Args[0].getAsType();
2582 return SemaRef.getASTContext().Char8Ty;
2585HLSLAttributedResourceType::Attributes
2586BuiltinTypeDeclBuilder::getResourceAttrs()
const {
2587 QualType HandleType = getResourceHandleField()->getType();
2592 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2593 assert(Record->isBeingDefined() &&
2594 "Definition must be started before completing it.");
2596 Record->completeDefinition();
2597 Record->setIsHLSLBuiltinRecord(
true);
2601Expr *BuiltinTypeDeclBuilder::getConstantIntExpr(
int value) {
2608Expr *BuiltinTypeDeclBuilder::getConstantUnsignedIntExpr(
unsigned value) {
2625 if (Record->isCompleteDefinition()) {
2626 assert(Template &&
"existing record it not a template");
2627 assert(Template->getTemplateParameters()->size() == Names.size() &&
2628 "template param count mismatch");
2632 assert((DefaultTypes.empty() || DefaultTypes.size() == Names.size()) &&
2633 "template default argument count mismatch");
2636 for (
unsigned i = 0; i < Names.size(); ++i) {
2638 Builder.addTypeParameter(Names[i], DefaultTy);
2640 return Builder.finalizeTemplateArgs(CD);
2644 StringRef ElementName, StringRef SampleCountName,
ConceptDecl *CD) {
2645 if (Record->isCompleteDefinition()) {
2646 assert(Template &&
"existing record it not a template");
2647 assert(Template->getTemplateParameters()->size() == 2 &&
2648 "template param count mismatch");
2657 Builder.addTypeParameter(ElementName);
2658 Builder.addNonTypeParameter(SampleCountName, AST.
IntTy,
2659 getConstantIntExpr(0));
2660 return Builder.finalizeTemplateArgs(CD);
2664 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2665 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
2667 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
2668 PH::CounterHandle, getConstantIntExpr(1))
2673 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2674 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
2676 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
2677 PH::CounterHandle, getConstantIntExpr(-1))
2684 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2686 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2687 bool NeedsTypedBuiltin = !ReturnTy.
isNull();
2693 if (!NeedsTypedBuiltin)
2694 ReturnTy = getHandleElementType();
2697 MMB.ReturnTy = ReturnTy;
2701 HLSLParamModifierAttr::Keyword_out);
2703 if (NeedsTypedBuiltin)
2704 MMB.
callBuiltin(
"__builtin_hlsl_resource_load_with_status_typed", ReturnTy,
2705 PH::Handle, PH::_0, PH::_1, ReturnTy);
2707 MMB.
callBuiltin(
"__builtin_hlsl_resource_load_with_status", ReturnTy,
2708 PH::Handle, PH::_0, PH::_1);
2715 QualType ElemTy,
bool TransposeResult) {
2716 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2718 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2719 bool NeedsTypedBuiltin = !ElemTy.
isNull();
2725 if (!NeedsTypedBuiltin)
2726 ElemTy = getHandleElementType();
2735 ReturnTy = AddrSpaceElemTy;
2740 assert(!IsConstReturn &&
"There shouldn't be any resource methods with a "
2741 "const ref return value");
2744 MMB.ReturnTy = ReturnTy;
2748 if (NeedsTypedBuiltin)
2749 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2750 PH::Handle, PH::_0, ElemTy);
2752 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer", ElemPtrTy, PH::Handle,
2756 if (TransposeResult)
2757 MMB.
callBuiltin(
"__builtin_hlsl_transpose_if_memory_is_row_major", ElemTy,
2758 PH::LastStmt, getConstantIntExpr(1));
2764 QualType ValueTy,
bool TransposeArg) {
2765 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2767 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2779 MMB.
callBuiltin(
"__builtin_hlsl_transpose_if_memory_is_row_major", ValueTy,
2780 PH::_1, getConstantIntExpr(0));
2781 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2782 PH::Handle, PH::_0, ValueTy)
2784 .
assign(PH::LastStmt, TransposeArg ? PH::LastStmt : PH::_1);
2790 StringRef MethodName,
QualType ValueTy, StringRef BuiltinName,
2791 bool RequiresOriginalValue) {
2792 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2794 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2804 auto BuildOverload = [&](
bool WithOriginalValue) {
2807 if (WithOriginalValue)
2808 MMB.
addParam(
"OriginalValue", ValueTy,
2809 HLSLParamModifierAttr::Keyword_out);
2810 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2811 PH::Handle, PH::_0, ValueTy)
2813 if (WithOriginalValue)
2820 if (!RequiresOriginalValue)
2821 BuildOverload(
false);
2822 BuildOverload(
true);
2828 StringRef MethodName,
QualType ValueTy, StringRef BuiltinName,
2829 bool WithOriginalValue) {
2830 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2832 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2842 if (WithOriginalValue)
2843 MMB.
addParam(
"OriginalValue", ValueTy, HLSLParamModifierAttr::Keyword_out);
2844 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2845 PH::Handle, PH::_0, ValueTy)
2847 if (WithOriginalValue)
2857 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2859 QualType ElemTy = getHandleElementType();
2863 .addParam(
"value", ElemTy)
2864 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
2865 PH::CounterHandle, getConstantIntExpr(1))
2866 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
2869 .dereference(PH::LastStmt)
2870 .assign(PH::LastStmt, PH::_0)
2875 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2877 QualType ElemTy = getHandleElementType();
2881 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
2882 PH::CounterHandle, getConstantIntExpr(-1))
2883 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
2886 .dereference(PH::LastStmt)
2892 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2896 QualType HandleTy = getResourceHandleField()->getType();
2901 if (AttrResTy->getAttrs().RawBuffer &&
2902 AttrResTy->getContainedType() != AST.
Char8Ty) {
2904 .addParam(
"numStructs", UIntTy, HLSLParamModifierAttr::Keyword_out)
2905 .addParam(
"stride", UIntTy, HLSLParamModifierAttr::Keyword_out)
2906 .callBuiltin(
"__builtin_hlsl_resource_getdimensions_x",
QualType(),
2908 .callBuiltin(
"__builtin_hlsl_resource_getstride",
QualType(),
2916 .addParam(
"dim", UIntTy, HLSLParamModifierAttr::Keyword_out)
2917 .callBuiltin(
"__builtin_hlsl_resource_getdimensions_x",
QualType(),
Defines the clang::ASTContext interface.
static const FieldDecl * getResourceHandleField(QualType ResourceTy)
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 & addByteAddressBufferInterlockedCompareMethod(StringRef MethodName, QualType ValueTy, StringRef BuiltinName, bool WithOriginalValue=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.
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