30#include "llvm/ADT/SmallVector.h"
32using namespace llvm::hlsl;
40static FunctionDecl *lookupBuiltinFunction(Sema &S, StringRef Name) {
42 S.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
43 DeclarationNameInfo NameInfo =
44 DeclarationNameInfo(DeclarationName(&II), SourceLocation());
48 S.LookupName(R, S.getCurScope());
51 assert(
R.isSingleResult() &&
52 "Since this is a builtin it should always resolve!");
56static QualType lookupBuiltinType(Sema &S, StringRef Name, DeclContext *DC) {
58 S.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
60 S.LookupQualifiedName(
Result, DC);
61 assert(!
Result.empty() &&
"Builtin type not found");
63 S.getASTContext().getTypeDeclType(
Result.getAsSingle<TypeDecl>());
64 S.RequireCompleteType(SourceLocation(), Ty,
65 diag::err_tentative_def_incomplete_type);
69CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
70 assert(ResTy->isRecordType() &&
"not a CXXRecord type");
71 for (
auto *CD : ResTy->getAsCXXRecordDecl()->ctors())
72 if (CD->isCopyConstructor())
78convertParamModifierToParamABI(HLSLParamModifierAttr::Spelling Modifier) {
79 assert(Modifier != HLSLParamModifierAttr::Spelling::Keyword_in &&
80 "HLSL 'in' parameters modifier cannot be converted to ParameterABI");
82 case HLSLParamModifierAttr::Spelling::Keyword_out:
84 case HLSLParamModifierAttr::Spelling::Keyword_inout:
87 llvm_unreachable(
"Invalid HLSL parameter modifier");
91QualType getInoutParameterType(ASTContext &AST, QualType Ty) {
92 assert(!Ty->isReferenceType() &&
93 "Pointer and reference types cannot be inout or out parameters");
148 HLSLParamModifierAttr::Spelling Modifier;
150 HLSLParamModifierAttr::Spelling Modifier)
151 : NameII(NameII), Ty(Ty), Modifier(Modifier) {}
158 LocalVar(StringRef Name,
QualType Ty) : Name(Name), Ty(Ty),
Decl(
nullptr) {}
182 enum class PlaceHolder {
195 Expr *convertPlaceholder(PlaceHolder PH);
196 Expr *convertPlaceholder(LocalVar &Var);
197 Expr *convertPlaceholder(
Expr *E) {
return E; }
205 QualType ReturnTy,
bool IsConst =
false,
207 : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(
nullptr),
208 IsConst(IsConst), IsCtor(IsCtor), SC(SC) {}
211 QualType ReturnTy,
bool IsConst =
false,
221 HLSLParamModifierAttr::Spelling Modifier =
222 HLSLParamModifierAttr::Keyword_in);
225 template <
typename... Ts>
227 QualType ReturnType, Ts &&...ArgSpecs);
228 template <
typename TLHS,
typename TRHS>
231 template <
typename V,
typename S>
234 template <
typename T>
236 template <
typename T>
239 template <
typename ValueT>
242 template <
typename ResourceT,
typename ValueT>
247 template <
typename T>
250 template <
typename ResourceT,
typename ValueT>
265 void ensureCompleteDecl() {
278 assert(!
Builder.Record->isCompleteDefinition() &&
279 "record is already complete");
281 unsigned Position =
static_cast<unsigned>(
Params.size());
285 &AST.
Idents.
get(Name, tok::TokenKind::identifier),
289 if (!DefaultValue.
isNull())
290 Decl->setDefaultArgument(AST,
291 Builder.SemaRef.getTrivialTemplateArgumentLoc(
333 "unexpected concept decl parameter count");
342 Builder.Record->getDeclContext(),
352 T->setDeclContext(DC);
354 QualType ConceptTType = Context.getTypeDeclType(ConceptTTPD);
360 QualType CSETType = Context.getTypeDeclType(T);
368 Context,
Builder.Record->getDeclContext(), Loc, {CSETA});
408 Builder.Template->setImplicit(
true);
409 Builder.Template->setLexicalDeclContext(
Builder.Record->getDeclContext());
420Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) {
421 if (PH == PlaceHolder::Handle)
423 if (PH == PlaceHolder::CounterHandle)
425 if (PH == PlaceHolder::This) {
428 Method->getFunctionObjectParameterType(),
432 if (PH == PlaceHolder::LastStmt) {
433 assert(!StmtsList.empty() &&
"no statements in the list");
434 Stmt *LastStmt = StmtsList.pop_back_val();
435 assert(
isa<ValueStmt>(LastStmt) &&
"last statement does not have a value");
444 ParmVarDecl *ParamDecl = Method->getParamDecl(
static_cast<unsigned>(PH));
446 AST, NestedNameSpecifierLoc(), SourceLocation(), ParamDecl,
false,
447 DeclarationNameInfo(ParamDecl->getDeclName(), SourceLocation()),
448 ParamDecl->getType().getNonReferenceType(),
VK_LValue);
451Expr *BuiltinTypeMethodBuilder::convertPlaceholder(LocalVar &Var) {
452 VarDecl *VD = Var.Decl;
453 assert(VD &&
"local variable is not declared");
455 VD->getASTContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
456 false, DeclarationNameInfo(VD->getDeclName(), SourceLocation()),
460Expr *BuiltinTypeMethodBuilder::convertPlaceholder(QualType Ty) {
461 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
464 return new (AST) CXXScalarValueInitExpr(
472 bool IsConst,
bool IsCtor,
474 : DeclBuilder(DB), ReturnTy(ReturnTy), Method(
nullptr), IsConst(IsConst),
475 IsCtor(IsCtor), SC(SC) {
477 assert((!NameStr.empty() || IsCtor) &&
"method needs a name");
478 assert(((IsCtor && !IsConst) || !IsCtor) &&
"constructor cannot be const");
486 AST.
Idents.
get(NameStr, tok::TokenKind::identifier);
493 HLSLParamModifierAttr::Spelling Modifier) {
494 assert(Method ==
nullptr &&
"Cannot add param, method already created");
495 const IdentifierInfo &II = DeclBuilder.SemaRef.getASTContext().Idents.get(
496 Name, tok::TokenKind::identifier);
497 Params.emplace_back(II, Ty, Modifier);
501 assert(Method ==
nullptr &&
502 "Cannot add template param, method already created");
503 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
504 unsigned Position =
static_cast<unsigned>(TemplateParamDecls.size());
508 &AST.
Idents.
get(Name, tok::TokenKind::identifier),
512 TemplateParamDecls.push_back(
Decl);
517void BuiltinTypeMethodBuilder::createDecl() {
518 assert(
Method ==
nullptr &&
"Method or constructor is already created");
524 uint32_t ArgIndex = 0;
527 bool UseParamExtInfo =
false;
528 for (Param &MP : Params) {
529 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
530 UseParamExtInfo =
true;
532 ParamExtInfos[ArgIndex] =
533 PI.
withABI(convertParamModifierToParamABI(MP.Modifier));
534 if (!MP.Ty->isDependentType())
535 MP.Ty = getInoutParameterType(AST, MP.Ty);
537 ParamTypes.emplace_back(MP.Ty);
541 FunctionProtoType::ExtProtoInfo ExtInfo;
543 ExtInfo.ExtParameterInfos = ParamExtInfos.data();
545 ExtInfo.TypeQuals.addConst();
551 DeclarationNameInfo NameInfo = DeclarationNameInfo(Name, SourceLocation());
554 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo,
555 ExplicitSpecifier(),
false,
true,
false,
559 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo,
560 false,
true, ExplicitSpecifier(),
564 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo, SC,
571 Method->getTypeSourceInfo()->getTypeLoc().getAs<FunctionProtoTypeLoc>();
572 for (
int I = 0, E = Params.size(); I != E; I++) {
573 Param &MP = Params[I];
575 AST, Method, SourceLocation(), SourceLocation(), &MP.NameII, MP.Ty,
578 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
580 HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
583 Parm->setScopeInfo(CurScopeDepth, I);
584 ParmDecls.push_back(Parm);
585 FnProtoLoc.setParam(I, Parm);
587 Method->setParams({ParmDecls});
591 ensureCompleteDecl();
593 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
595 AST,
SourceLocation(), Method->getFunctionObjectParameterType(),
true);
596 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
603 ensureCompleteDecl();
605 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
607 AST,
SourceLocation(), Method->getFunctionObjectParameterType(),
true);
608 FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
616 ensureCompleteDecl();
618 assert(Var.Decl ==
nullptr &&
"local variable is already declared");
620 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
623 &AST.
Idents.
get(Var.Name, tok::TokenKind::identifier), Var.Ty,
627 StmtsList.push_back(DS);
631template <
typename V,
typename S>
634 assert(ResultTy->
isVectorType() &&
"The result type must be a vector type.");
635 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
636 Expr *VecExpr = convertPlaceholder(Vec);
638 Expr *ScalarExpr = convertPlaceholder(Scalar);
642 LocalVar VecVar(
"vec_tmp", VecTy->desugar());
646 QualType EltTy = VecTy->getElementType();
647 unsigned NumElts = VecTy->getNumElements();
650 for (
unsigned I = 0; I < NumElts; ++I) {
652 convertPlaceholder(VecVar), DeclBuilder.getConstantIntExpr(I), EltTy,
655 Elts.push_back(ScalarExpr);
661 ExprResult Cast = DeclBuilder.SemaRef.BuildCStyleCastExpr(
664 assert(!Cast.isInvalid() &&
"Cast cannot fail!");
665 StmtsList.push_back(Cast.get());
671 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
675 StmtsList.push_back(ThisExpr);
679template <
typename... Ts>
682 QualType ReturnType, Ts &&...ArgSpecs) {
683 ensureCompleteDecl();
685 std::array<
Expr *,
sizeof...(ArgSpecs)> Args{
686 convertPlaceholder(std::forward<Ts>(ArgSpecs))...};
688 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
689 FunctionDecl *FD = lookupBuiltinFunction(DeclBuilder.SemaRef, BuiltinName);
697 assert(!
Call.isInvalid() &&
"Call to builtin cannot fail!");
700 if (!ReturnType.
isNull() &&
702 ExprResult CastResult = DeclBuilder.SemaRef.BuildCStyleCastExpr(
705 assert(!CastResult.isInvalid() &&
"Cast cannot fail!");
706 E = CastResult.get();
709 StmtsList.push_back(E);
713template <
typename TLHS,
typename TRHS>
715 Expr *LHSExpr = convertPlaceholder(LHS);
716 Expr *RHSExpr = convertPlaceholder(RHS);
718 DeclBuilder.SemaRef.getASTContext(), LHSExpr, RHSExpr, BO_Assign,
721 StmtsList.push_back(AssignStmt);
727 Expr *PtrExpr = convertPlaceholder(Ptr);
733 StmtsList.push_back(Deref);
740 ensureCompleteDecl();
742 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
745 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
748 if (ResourceTypeDecl == DeclBuilder.Record)
749 HandleField = DeclBuilder.getResourceHandleField();
752 for (
auto *
Decl : ResourceTypeDecl->lookup(&II)) {
753 if ((HandleField = dyn_cast<FieldDecl>(
Decl)))
756 assert(HandleField &&
"Resource handle field not found");
762 StmtsList.push_back(HandleExpr);
770 ensureCompleteDecl();
771 Expr *
Base = convertPlaceholder(ResourceRecord);
773 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
777 StmtsList.push_back(
Member);
782 FieldDecl *MipsField = DeclBuilder.Fields.lookup(
"mips");
786 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
788 const auto *RT = MipsTy->
castAs<RecordType>();
792 assert(MipsRecord->field_begin() != MipsRecord->field_end() &&
793 "mips_type must have at least one field");
794 assert(std::next(MipsRecord->field_begin()) == MipsRecord->field_end() &&
795 "mips_type must have exactly one field");
796 FieldDecl *MipsHandleField = *MipsRecord->field_begin();
798 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
799 Expr *ResExpr = convertPlaceholder(ResourceRecord);
808 AST, MipsMemberExpr,
false, MipsHandleField, MipsHandleField->
getType(),
812 AST, MipsHandleMemberExpr, HandleMemberExpr, BO_Assign,
816 StmtsList.push_back(AssignStmt);
819template <
typename ValueT>
822 ValueT HandleValue) {
824 DeclBuilder.getResourceHandleField());
829template <
typename ResourceT,
typename ValueT>
832 ResourceT ResourceRecord, ValueT HandleValue) {
834 DeclBuilder.getResourceCounterHandleField());
837template <
typename ResourceT,
typename ValueT>
839 ResourceT ResourceRecord, ValueT HandleValue,
FieldDecl *HandleField) {
840 ensureCompleteDecl();
842 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
845 "Getting the field from the wrong resource type.");
847 Expr *HandleValueExpr = convertPlaceholder(HandleValue);
849 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
854 DeclBuilder.SemaRef.getASTContext(), HandleMemberExpr, HandleValueExpr,
857 StmtsList.push_back(AssignStmt);
864 ensureCompleteDecl();
866 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
868 "Getting the field from the wrong resource type.");
870 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
871 FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
875 StmtsList.push_back(HandleExpr);
881 ensureCompleteDecl();
883 Expr *ReturnValueExpr = convertPlaceholder(ReturnValue);
884 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
887 if (Ty->
isRecordType() && !Method->getReturnType()->isReferenceType()) {
894 assert(CD &&
"no copy constructor found");
909 assert(!DeclBuilder.Record->isCompleteDefinition() &&
910 "record is already complete");
912 ensureCompleteDecl();
914 if (!Method->hasBody()) {
915 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
916 assert((ReturnTy == AST.
VoidTy || !StmtsList.empty()) &&
917 "nothing to return from non-void method");
918 if (ReturnTy != AST.
VoidTy) {
919 if (
Expr *LastExpr = dyn_cast<Expr>(StmtsList.back())) {
921 ReturnTy.getNonReferenceType()) &&
922 "Return type of the last statement must match the return type "
925 StmtsList.pop_back();
934 Method->setLexicalDeclContext(DeclBuilder.Record);
935 Method->setAccess(Access);
936 Method->setImplicitlyInline();
937 Method->addAttr(AlwaysInlineAttr::CreateImplicit(
938 AST,
SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
939 Method->addAttr(ConvergentAttr::CreateImplicit(AST));
940 if (!TemplateParamDecls.empty()) {
947 TemplateParams, Method);
949 FuncTemplate->setLexicalDeclContext(DeclBuilder.Record);
950 FuncTemplate->setImplicit(
true);
951 Method->setDescribedFunctionTemplate(FuncTemplate);
952 DeclBuilder.Record->addDecl(FuncTemplate);
954 DeclBuilder.Record->addDecl(Method);
961 : SemaRef(SemaRef), Record(R) {
962 Record->startDefinition();
963 Template = Record->getDescribedClassTemplate();
969 : SemaRef(SemaRef), HLSLNamespace(Namespace) {
975 if (SemaRef.LookupQualifiedName(
Result, HLSLNamespace)) {
978 if (
auto *TD = dyn_cast<ClassTemplateDecl>(
Found)) {
979 PrevDecl = TD->getTemplatedDecl();
982 PrevDecl = dyn_cast<CXXRecordDecl>(
Found);
983 assert(PrevDecl &&
"Unexpected lookup result type.");
988 Template = PrevTemplate;
995 Record->setImplicit(
true);
996 Record->setLexicalDeclContext(HLSLNamespace);
997 Record->setHasExternalLexicalStorage();
1001 FinalAttr::CreateImplicit(AST,
SourceRange(), FinalAttr::Keyword_final));
1005 if (HLSLNamespace && !Template && Record->getDeclContext() == HLSLNamespace)
1006 HLSLNamespace->addDecl(Record);
1013 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1014 assert(Record->isBeingDefined() &&
1015 "Definition must be started before adding members!");
1024 Field->setAccess(Access);
1025 Field->setImplicit(
true);
1026 for (
Attr *A : Attrs) {
1031 Record->addDecl(Field);
1032 Fields[Name] = Field;
1038 bool RawBuffer,
bool HasCounter,
1040 QualType ElementTy = getHandleElementType();
1041 addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer, ElementTy,
1044 addCounterHandleMember(RC, IsROV, RawBuffer, ElementTy, Access);
1050 ResourceDimension RD,
1052 addHandleMember(RC, RD, IsROV,
false, getHandleElementType(),
1058 addHandleMember(ResourceClass::Sampler, ResourceDimension::Unknown,
1059 false,
false, getHandleElementType());
1065 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1067 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1069 QualType ElemTy = getHandleElementType();
1079 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
1081 .dereference(PH::LastStmt)
1087 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1098CXXRecordDecl *BuiltinTypeDeclBuilder::addPrivateNestedRecord(StringRef Name) {
1099 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1108 Record->addDecl(NestedRecord);
1109 return NestedRecord;
1113 ResourceClass RC, ResourceDimension RD,
bool IsROV,
bool RawBuffer,
1114 QualType ElementTy, AccessSpecifier Access) {
1115 return addResourceMember(
"__handle", RC, RD, IsROV, RawBuffer,
1116 false, ElementTy, Access);
1120 ResourceClass RC,
bool IsROV,
bool RawBuffer, QualType ElementTy,
1122 return addResourceMember(
"__counter_handle", RC, ResourceDimension::Unknown,
1124 true, ElementTy, Access);
1128 StringRef MemberName,
ResourceClass RC, ResourceDimension RD,
bool IsROV,
1129 bool RawBuffer,
bool IsCounter, QualType ElementTy,
1131 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1133 ASTContext &Ctx = SemaRef.getASTContext();
1135 assert(!ElementTy.isNull() &&
1136 "The caller should always pass in the type for the handle.");
1137 TypeSourceInfo *ElementTypeInfo =
1141 QualType AttributedResTy = QualType();
1142 SmallVector<const Attr *> Attrs = {
1143 HLSLResourceClassAttr::CreateImplicit(Ctx, RC),
1144 IsROV ? HLSLROVAttr::CreateImplicit(Ctx) :
nullptr,
1145 RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) :
nullptr,
1146 RD != ResourceDimension::
Unknown
1147 ? HLSLResourceDimensionAttr::CreateImplicit(Ctx, RD)
1150 ? HLSLContainedTypeAttr::CreateImplicit(Ctx, ElementTypeInfo)
1153 Attrs.push_back(HLSLIsCounterAttr::CreateImplicit(Ctx));
1165 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1167 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1168 QualType HandleType = getResourceHandleField()->getType();
1171 .callBuiltin(
"__builtin_hlsl_resource_uninitializedhandle", HandleType,
1173 .assign(PH::Handle, PH::LastStmt)
1180 addCreateFromBindingWithImplicitCounter();
1181 addCreateFromImplicitBindingWithImplicitCounter();
1183 addCreateFromBinding();
1184 addCreateFromImplicitBinding();
1201 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1203 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1207 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1213 .addParam(
"range", AST.
IntTy)
1216 .declareLocalVar(TmpVar)
1217 .accessHandleFieldOnResource(TmpVar)
1218 .callBuiltin(
"__builtin_hlsl_resource_handlefrombinding", HandleType,
1219 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
1220 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1221 .returnValue(TmpVar)
1238 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1240 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1244 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1250 .addParam(
"range", AST.
IntTy)
1253 .declareLocalVar(TmpVar)
1254 .accessHandleFieldOnResource(TmpVar)
1255 .callBuiltin(
"__builtin_hlsl_resource_handlefromimplicitbinding",
1256 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
1258 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1259 .returnValue(TmpVar)
1279BuiltinTypeDeclBuilder::addCreateFromBindingWithImplicitCounter() {
1280 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1282 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1284 QualType HandleType = getResourceHandleField()->
getType();
1285 QualType CounterHandleType = getResourceCounterHandleField()->
getType();
1287 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1290 "__createFromBindingWithImplicitCounter",
1294 .addParam(
"range", AST.
IntTy)
1298 .declareLocalVar(TmpVar)
1299 .accessHandleFieldOnResource(TmpVar)
1300 .callBuiltin(
"__builtin_hlsl_resource_handlefrombinding", HandleType,
1301 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
1302 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1303 .accessHandleFieldOnResource(TmpVar)
1304 .callBuiltin(
"__builtin_hlsl_resource_counterhandlefromimplicitbinding",
1305 CounterHandleType, PH::LastStmt, PH::_5, PH::_1)
1306 .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt)
1307 .returnValue(TmpVar)
1328BuiltinTypeDeclBuilder::addCreateFromImplicitBindingWithImplicitCounter() {
1329 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1331 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1332 ASTContext &AST = SemaRef.getASTContext();
1333 QualType HandleType = getResourceHandleField()->getType();
1334 QualType CounterHandleType = getResourceCounterHandleField()->getType();
1336 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1339 *
this,
"__createFromImplicitBindingWithImplicitCounter",
1343 .addParam(
"range", AST.
IntTy)
1347 .declareLocalVar(TmpVar)
1348 .accessHandleFieldOnResource(TmpVar)
1349 .callBuiltin(
"__builtin_hlsl_resource_handlefromimplicitbinding",
1350 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
1352 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1353 .accessHandleFieldOnResource(TmpVar)
1354 .callBuiltin(
"__builtin_hlsl_resource_counterhandlefromimplicitbinding",
1355 CounterHandleType, PH::LastStmt, PH::_5, PH::_1)
1356 .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt)
1357 .returnValue(TmpVar)
1363 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1370 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1374 MMB.
addParam(
"other", ConstRecordRefType);
1376 for (
auto *Field : Record->fields()) {
1386 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1394 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1397 MMB.
addParam(
"other", ConstRecordRefType);
1399 for (
auto *Field : Record->fields()) {
1409 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1412 uint32_t VecSize = 1;
1413 if (
Dim != ResourceDimension::Unknown)
1424 getResourceAttrs().ResourceClass !=
1425 llvm::dxil::ResourceClass::UAV,
1432 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1446CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsSliceType(ResourceDimension
Dim,
1453 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1458 CXXRecordDecl *MipsSliceRecord = addPrivateNestedRecord(
"mips_slice_type");
1460 MipsSliceBuilder.addFriend(
Record)
1461 .addHandleMember(getResourceAttrs().ResourceClass,
Dim,
1462 getResourceAttrs().IsROV,
false, ReturnType,
1469 FieldDecl *LevelField = MipsSliceBuilder.Fields[
"__level"];
1470 assert(LevelField &&
"Could not find the level field.");
1478 .addParam(
"Coord", IndexTy)
1479 .accessFieldOnResource(PH::This, LevelField)
1480 .concat(PH::_0, PH::LastStmt, CoordLevelTy)
1481 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1485 MipsSliceBuilder.completeDefinition();
1486 return MipsSliceRecord;
1489CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsType(ResourceDimension Dim,
1490 QualType ReturnType) {
1492 QualType IntTy = AST.
IntTy;
1493 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1496 CXXRecordDecl *MipsSliceRecord = addMipsSliceType(Dim, ReturnType);
1501 CXXRecordDecl *MipsRecord = addPrivateNestedRecord(
"mips_type");
1503 MipsBuilder.addFriend(
Record)
1505 getResourceAttrs().IsROV,
false, ReturnType,
1513 DeclarationName SubscriptName =
1517 auto FieldIt = MipsSliceRecord->field_begin();
1518 FieldDecl *MipsSliceHandleField = *FieldIt;
1520 assert(MipsSliceHandleField->getName() ==
"__handle" &&
1521 LevelField->getName() ==
"__level" &&
1522 "Could not find fields on mips_slice_type");
1525 BuiltinTypeMethodBuilder::LocalVar MipsSliceVar(
"slice", MipsSliceTy);
1528 .addParam(
"Level", IntTy)
1529 .declareLocalVar(MipsSliceVar)
1530 .accessHandleFieldOnResource(PH::This)
1531 .setFieldOnResource(MipsSliceVar, PH::LastStmt, MipsSliceHandleField)
1532 .setFieldOnResource(MipsSliceVar, PH::_0, LevelField)
1533 .returnValue(MipsSliceVar)
1536 MipsBuilder.completeDefinition();
1542 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1544 QualType ReturnType = getHandleElementType();
1557 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1563 QualType ReturnType = getHandleElementType();
1565 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1569 .addParam(
"Location", LocationTy)
1570 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1576 .addParam(
"Location", LocationTy)
1577 .addParam(
"Offset", OffsetTy)
1578 .callBuiltin(
"__builtin_hlsl_resource_load_level", ReturnType, PH::Handle,
1585 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1589 auto AddLoads = [&](StringRef MethodName,
QualType ReturnType) {
1609 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1613 auto AddStore = [&](StringRef MethodName,
QualType ValueType) {
1631 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1633 QualType ReturnType = getHandleElementType();
1635 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1641 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1645 .addParam(
"Sampler", SamplerStateType)
1646 .addParam(
"Location", Float2Ty)
1647 .accessHandleFieldOnResource(PH::_0)
1648 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1649 PH::LastStmt, PH::_1)
1650 .returnValue(PH::LastStmt)
1655 .addParam(
"Sampler", SamplerStateType)
1656 .addParam(
"Location", Float2Ty)
1657 .addParam(
"Offset", Int2Ty)
1658 .accessHandleFieldOnResource(PH::_0)
1659 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1660 PH::LastStmt, PH::_1, PH::_2)
1661 .returnValue(PH::LastStmt)
1666 .addParam(
"Sampler", SamplerStateType)
1667 .addParam(
"Location", Float2Ty)
1668 .addParam(
"Offset", Int2Ty)
1669 .addParam(
"Clamp", FloatTy)
1670 .accessHandleFieldOnResource(PH::_0)
1671 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1672 PH::LastStmt, PH::_1, PH::_2, PH::_3)
1673 .returnValue(PH::LastStmt)
1679 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1681 QualType ReturnType = getHandleElementType();
1683 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1689 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1693 .addParam(
"Sampler", SamplerStateType)
1694 .addParam(
"Location", Float2Ty)
1695 .addParam(
"Bias", FloatTy)
1696 .accessHandleFieldOnResource(PH::_0)
1697 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
1698 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
1699 .returnValue(PH::LastStmt)
1704 .addParam(
"Sampler", SamplerStateType)
1705 .addParam(
"Location", Float2Ty)
1706 .addParam(
"Bias", FloatTy)
1707 .addParam(
"Offset", Int2Ty)
1708 .accessHandleFieldOnResource(PH::_0)
1709 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
1710 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1711 .returnValue(PH::LastStmt)
1717 .addParam(
"Sampler", SamplerStateType)
1718 .addParam(
"Location", Float2Ty)
1719 .addParam(
"Bias", FloatTy)
1720 .addParam(
"Offset", Int2Ty)
1721 .addParam(
"Clamp", FloatTy)
1722 .accessHandleFieldOnResource(PH::_0)
1723 .callBuiltin(
"__builtin_hlsl_resource_sample_bias", ReturnType,
1724 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
1725 .returnValue(PH::LastStmt)
1731 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1733 QualType ReturnType = getHandleElementType();
1735 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1741 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1745 .addParam(
"Sampler", SamplerStateType)
1746 .addParam(
"Location", Float2Ty)
1747 .addParam(
"DDX", Float2Ty)
1748 .addParam(
"DDY", Float2Ty)
1749 .accessHandleFieldOnResource(PH::_0)
1750 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
1751 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1752 .returnValue(PH::LastStmt)
1758 .addParam(
"Sampler", SamplerStateType)
1759 .addParam(
"Location", Float2Ty)
1760 .addParam(
"DDX", Float2Ty)
1761 .addParam(
"DDY", Float2Ty)
1762 .addParam(
"Offset", Int2Ty)
1763 .accessHandleFieldOnResource(PH::_0)
1764 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
1765 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
1766 .returnValue(PH::LastStmt)
1772 .addParam(
"Sampler", SamplerStateType)
1773 .addParam(
"Location", Float2Ty)
1774 .addParam(
"DDX", Float2Ty)
1775 .addParam(
"DDY", Float2Ty)
1776 .addParam(
"Offset", Int2Ty)
1777 .addParam(
"Clamp", FloatTy)
1778 .accessHandleFieldOnResource(PH::_0)
1779 .callBuiltin(
"__builtin_hlsl_resource_sample_grad", ReturnType,
1780 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4,
1782 .returnValue(PH::LastStmt)
1788 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1790 QualType ReturnType = getHandleElementType();
1792 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1798 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1802 .addParam(
"Sampler", SamplerStateType)
1803 .addParam(
"Location", Float2Ty)
1804 .addParam(
"LOD", FloatTy)
1805 .accessHandleFieldOnResource(PH::_0)
1806 .callBuiltin(
"__builtin_hlsl_resource_sample_level", ReturnType,
1807 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
1808 .returnValue(PH::LastStmt)
1813 .addParam(
"Sampler", SamplerStateType)
1814 .addParam(
"Location", Float2Ty)
1815 .addParam(
"LOD", FloatTy)
1816 .addParam(
"Offset", Int2Ty)
1817 .accessHandleFieldOnResource(PH::_0)
1818 .callBuiltin(
"__builtin_hlsl_resource_sample_level", ReturnType,
1819 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1820 .returnValue(PH::LastStmt)
1826 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1829 QualType SamplerComparisonStateType = lookupBuiltinType(
1830 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
1836 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1840 .addParam(
"Sampler", SamplerComparisonStateType)
1841 .addParam(
"Location", Float2Ty)
1842 .addParam(
"CompareValue", FloatTy)
1843 .accessHandleFieldOnResource(PH::_0)
1844 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
1845 PH::LastStmt, PH::_1, PH::_2)
1846 .returnValue(PH::LastStmt)
1852 .addParam(
"Sampler", SamplerComparisonStateType)
1853 .addParam(
"Location", Float2Ty)
1854 .addParam(
"CompareValue", FloatTy)
1855 .addParam(
"Offset", Int2Ty)
1856 .accessHandleFieldOnResource(PH::_0)
1857 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
1858 PH::LastStmt, PH::_1, PH::_2, PH::_3)
1859 .returnValue(PH::LastStmt)
1865 .addParam(
"Sampler", SamplerComparisonStateType)
1866 .addParam(
"Location", Float2Ty)
1867 .addParam(
"CompareValue", FloatTy)
1868 .addParam(
"Offset", Int2Ty)
1869 .addParam(
"Clamp", FloatTy)
1870 .accessHandleFieldOnResource(PH::_0)
1871 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp", ReturnType, PH::Handle,
1872 PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
1873 .returnValue(PH::LastStmt)
1879 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1882 QualType SamplerComparisonStateType = lookupBuiltinType(
1883 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
1889 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1894 .addParam(
"Sampler", SamplerComparisonStateType)
1895 .addParam(
"Location", Float2Ty)
1896 .addParam(
"CompareValue", FloatTy)
1897 .accessHandleFieldOnResource(PH::_0)
1898 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
1899 PH::Handle, PH::LastStmt, PH::_1, PH::_2)
1900 .returnValue(PH::LastStmt)
1906 .addParam(
"Sampler", SamplerComparisonStateType)
1907 .addParam(
"Location", Float2Ty)
1908 .addParam(
"CompareValue", FloatTy)
1909 .addParam(
"Offset", Int2Ty)
1910 .accessHandleFieldOnResource(PH::_0)
1911 .callBuiltin(
"__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
1912 PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
1913 .returnValue(PH::LastStmt)
1919 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1920 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1924 assert(
Dim != ResourceDimension::Unknown);
1928 QualType Params[] = {UIntTy, FloatTy};
1931 if (
Dim == ResourceDimension::Dim2D) {
1932 StringRef XYName =
"__builtin_hlsl_resource_getdimensions_xy";
1933 StringRef LevelsXYName =
1934 "__builtin_hlsl_resource_getdimensions_levels_xy";
1936 if (OutTy == FloatTy) {
1937 XYName =
"__builtin_hlsl_resource_getdimensions_xy_float";
1938 LevelsXYName =
"__builtin_hlsl_resource_getdimensions_levels_xy_float";
1943 .addParam(
"width", OutTy, HLSLParamModifierAttr::Keyword_out)
1944 .addParam(
"height", OutTy, HLSLParamModifierAttr::Keyword_out)
1945 .callBuiltin(XYName,
QualType(), PH::Handle, PH::_0, PH::_1)
1951 .addParam(
"mipLevel", UIntTy)
1952 .addParam(
"width", OutTy, HLSLParamModifierAttr::Keyword_out)
1953 .addParam(
"height", OutTy, HLSLParamModifierAttr::Keyword_out)
1954 .addParam(
"numberOfLevels", OutTy, HLSLParamModifierAttr::Keyword_out)
1955 .callBuiltin(LevelsXYName,
QualType(), PH::Handle, PH::_0, PH::_1,
1966 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1970 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1974 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1978 .addParam(
"Sampler", SamplerStateType)
1979 .addParam(
"Location", LocationTy)
1980 .accessHandleFieldOnResource(PH::_0)
1981 .callBuiltin(
"__builtin_hlsl_resource_calculate_lod", ReturnType,
1982 PH::Handle, PH::LastStmt, PH::_1)
1988 .addParam(
"Sampler", SamplerStateType)
1989 .addParam(
"Location", LocationTy)
1990 .accessHandleFieldOnResource(PH::_0)
1991 .callBuiltin(
"__builtin_hlsl_resource_calculate_lod_unclamped",
1992 ReturnType, PH::Handle, PH::LastStmt, PH::_1)
1996QualType BuiltinTypeDeclBuilder::getGatherReturnType() {
1998 QualType T = getHandleElementType();
2003 T = VT->getElementType();
2005 T = DT->getElementType();
2012 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2014 QualType ReturnType = getGatherReturnType();
2017 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
2023 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2026 struct GatherVariant {
2030 GatherVariant Variants[] = {{
"Gather", 0},
2034 {
"GatherAlpha", 3}};
2036 for (
const auto &
V : Variants) {
2039 .addParam(
"Sampler", SamplerStateType)
2040 .addParam(
"Location", Float2Ty)
2041 .accessHandleFieldOnResource(PH::_0)
2042 .callBuiltin(
"__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
2043 PH::LastStmt, PH::_1,
2044 getConstantUnsignedIntExpr(
V.Component))
2049 .addParam(
"Sampler", SamplerStateType)
2050 .addParam(
"Location", Float2Ty)
2051 .addParam(
"Offset", OffsetTy)
2052 .accessHandleFieldOnResource(PH::_0)
2053 .callBuiltin(
"__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
2054 PH::LastStmt, PH::_1,
2055 getConstantUnsignedIntExpr(
V.Component), PH::_2)
2064 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2068 QualType SamplerComparisonStateType = lookupBuiltinType(
2069 SemaRef,
"SamplerComparisonState", Record->getDeclContext());
2075 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2079 struct GatherVariant {
2083 GatherVariant Variants[] = {{
"GatherCmp", 0},
2084 {
"GatherCmpRed", 0},
2085 {
"GatherCmpGreen", 1},
2086 {
"GatherCmpBlue", 2},
2087 {
"GatherCmpAlpha", 3}};
2089 for (
const auto &
V : Variants) {
2093 .addParam(
"Sampler", SamplerComparisonStateType)
2094 .addParam(
"Location", Float2Ty)
2095 .addParam(
"CompareValue", FloatTy)
2096 .accessHandleFieldOnResource(PH::_0)
2097 .callBuiltin(
"__builtin_hlsl_resource_gather_cmp", ReturnType,
2098 PH::Handle, PH::LastStmt, PH::_1, PH::_2,
2099 getConstantUnsignedIntExpr(
V.Component))
2105 .addParam(
"Sampler", SamplerComparisonStateType)
2106 .addParam(
"Location", Float2Ty)
2107 .addParam(
"CompareValue", FloatTy)
2108 .addParam(
"Offset", Int2Ty)
2109 .accessHandleFieldOnResource(PH::_0)
2110 .callBuiltin(
"__builtin_hlsl_resource_gather_cmp", ReturnType,
2111 PH::Handle, PH::LastStmt, PH::_1, PH::_2,
2112 getConstantUnsignedIntExpr(
V.Component), PH::_3)
2119FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField()
const {
2120 auto I = Fields.find(
"__handle");
2121 assert(I != Fields.end() &&
2122 I->second->getType()->isHLSLAttributedResourceType() &&
2123 "record does not have resource handle field");
2127FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField()
const {
2128 auto I = Fields.find(
"__counter_handle");
2129 if (I == Fields.end() ||
2130 !I->second->getType()->isHLSLAttributedResourceType())
2135QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam() {
2136 assert(
Template &&
"record it not a template");
2137 if (
const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
2138 Template->getTemplateParameters()->getParam(0))) {
2139 return QualType(TTD->getTypeForDecl(), 0);
2144QualType BuiltinTypeDeclBuilder::getHandleElementType() {
2146 return getFirstTemplateTypeParam();
2148 if (
auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
2149 const auto &Args = Spec->getTemplateArgs();
2151 return Args[0].getAsType();
2155 return SemaRef.getASTContext().Char8Ty;
2158HLSLAttributedResourceType::Attributes
2159BuiltinTypeDeclBuilder::getResourceAttrs()
const {
2160 QualType HandleType = getResourceHandleField()->getType();
2165 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2166 assert(Record->isBeingDefined() &&
2167 "Definition must be started before completing it.");
2169 Record->completeDefinition();
2173Expr *BuiltinTypeDeclBuilder::getConstantIntExpr(
int value) {
2180Expr *BuiltinTypeDeclBuilder::getConstantUnsignedIntExpr(
unsigned value) {
2197 if (Record->isCompleteDefinition()) {
2198 assert(Template &&
"existing record it not a template");
2199 assert(Template->getTemplateParameters()->size() == Names.size() &&
2200 "template param count mismatch");
2204 assert((DefaultTypes.empty() || DefaultTypes.size() == Names.size()) &&
2205 "template default argument count mismatch");
2208 for (
unsigned i = 0; i < Names.size(); ++i) {
2210 Builder.addTypeParameter(Names[i], DefaultTy);
2212 return Builder.finalizeTemplateArgs(CD);
2216 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2217 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
2219 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
2220 PH::CounterHandle, getConstantIntExpr(1))
2225 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2226 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
2228 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
2229 PH::CounterHandle, getConstantIntExpr(-1))
2236 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2238 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2239 bool NeedsTypedBuiltin = !ReturnTy.
isNull();
2245 if (!NeedsTypedBuiltin)
2246 ReturnTy = getHandleElementType();
2249 MMB.ReturnTy = ReturnTy;
2253 HLSLParamModifierAttr::Keyword_out);
2255 if (NeedsTypedBuiltin)
2256 MMB.
callBuiltin(
"__builtin_hlsl_resource_load_with_status_typed", ReturnTy,
2257 PH::Handle, PH::_0, PH::_1, ReturnTy);
2259 MMB.
callBuiltin(
"__builtin_hlsl_resource_load_with_status", ReturnTy,
2260 PH::Handle, PH::_0, PH::_1);
2268 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2270 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2271 bool NeedsTypedBuiltin = !ElemTy.
isNull();
2277 if (!NeedsTypedBuiltin)
2278 ElemTy = getHandleElementType();
2287 ReturnTy = AddrSpaceElemTy;
2292 assert(!IsConstReturn &&
"There shouldn't be any resource methods with a "
2293 "const ref return value");
2296 MMB.ReturnTy = ReturnTy;
2300 if (NeedsTypedBuiltin)
2301 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2302 PH::Handle, PH::_0, ElemTy);
2304 MMB.
callBuiltin(
"__builtin_hlsl_resource_getpointer", ElemPtrTy, PH::Handle,
2313 assert(!Record->isCompleteDefinition() &&
"record is already complete");
2315 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2327 .
callBuiltin(
"__builtin_hlsl_resource_getpointer_typed", ElemPtrTy,
2328 PH::Handle, PH::_0, ValueTy)
2330 .
assign(PH::LastStmt, PH::_1)
2335 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2337 QualType ElemTy = getHandleElementType();
2341 .addParam(
"value", ElemTy)
2342 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
2343 PH::CounterHandle, getConstantIntExpr(1))
2344 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
2347 .dereference(PH::LastStmt)
2348 .assign(PH::LastStmt, PH::_0)
2353 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2355 QualType ElemTy = getHandleElementType();
2359 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
2360 PH::CounterHandle, getConstantIntExpr(-1))
2361 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
2364 .dereference(PH::LastStmt)
2370 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
2374 QualType HandleTy = getResourceHandleField()->getType();
2379 if (AttrResTy->getAttrs().RawBuffer &&
2380 AttrResTy->getContainedType() != AST.
Char8Ty) {
2382 .addParam(
"numStructs", UIntTy, HLSLParamModifierAttr::Keyword_out)
2383 .addParam(
"stride", UIntTy, HLSLParamModifierAttr::Keyword_out)
2384 .callBuiltin(
"__builtin_hlsl_resource_getdimensions_x",
QualType(),
2386 .callBuiltin(
"__builtin_hlsl_resource_getstride",
QualType(),
2394 .addParam(
"dim", UIntTy, HLSLParamModifierAttr::Keyword_out)
2395 .callBuiltin(
"__builtin_hlsl_resource_getdimensions_x",
QualType(),
Defines the clang::ASTContext interface.
llvm::dxil::ResourceClass ResourceClass
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
llvm::MachO::Record Record
This file declares semantic analysis for HLSL constructs.
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
DeclarationNameTable DeclarationNames
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
CanQualType UnsignedIntTy
CanQualType getCanonicalTagType(const TagDecl *TD) const
Represents a member of a struct/union/class.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
DeclarationNameTable DeclarationNames
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Attr - This represents one attribute.
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
static CXXConstructExpr * Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor, bool Elidable, ArrayRef< Expr * > Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, bool ZeroInitialization, CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange)
Create a C++ construction expression.
Represents a C++ constructor within a class.
static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited=InheritedConstructor(), const AssociatedConstraint &TrailingRequiresClause={})
static CXXConversionDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, const AssociatedConstraint &TrailingRequiresClause={})
Represents a static or instance method of a struct/union/class.
static CXXMethodDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin, bool isInline, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, const AssociatedConstraint &TrailingRequiresClause={})
Represents a C++ struct/union/class.
static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr)
Represents the this expression in C++.
static CXXThisExpr * Create(const ASTContext &Ctx, SourceLocation L, QualType Ty, bool IsImplicit)
QualType withConst() const
Retrieves a version of this type with const applied.
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Declaration of a C++20 concept.
A reference to a concept and its template args, as it appears in the code.
static ConceptReference * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, TemplateDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten)
Represents the specialization of a concept - evaluates to a prvalue of type bool.
static ConceptSpecializationExpr * Create(const ASTContext &C, ConceptReference *ConceptRef, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction)
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
void setAccess(AccessSpecifier AS)
void setImplicit(bool I=true)
void setLexicalDeclContext(DeclContext *DC)
The name of a declaration.
@ CXXConversionFunctionName
NameKind getNameKind() const
Determine what kind of name this is.
Represents an extended vector type where either the type or size is dependent.
This represents one expression.
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
static FieldDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle)
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
static FriendDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, SourceLocation EllipsisLoc={}, ArrayRef< TemplateParameterList * > FriendTypeTPLists={})
Represents a function declaration or definition.
DeclarationNameInfo getNameInfo() const
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
ExtParameterInfo withABI(ParameterABI kind) const
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
Describes an C or C++ initializer list.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Represents the results of name lookup.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
static MemberExpr * CreateImplicit(const ASTContext &C, Expr *Base, bool IsArrow, ValueDecl *MemberDecl, QualType T, ExprValueKind VK, ExprObjectKind OK)
Create an implicit MemberExpr, with no location, qualifier, template arguments, and so on.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represent a C++ namespace.
A C++ nested-name-specifier augmented with source location information.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
A (possibly-)qualified type.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
unsigned getDepth() const
Returns the depth of this scope. The translation-unit has scope depth 0.
Sema - This implements semantic analysis and AST building for C.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
Scope * getCurScope() const
Retrieve the parser's current scope.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
ASTContext & getASTContext() const
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
Location wrapper for a TemplateArgument.
Represents a template argument.
@ Type
The template argument is a type.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Declaration of a template type parameter.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
A container of type source information.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const T * castAs() const
Member-template castAs<specific type>.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVectorType() const
bool isRecordType() const
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Represents a GCC generic vector type.
BuiltinTypeDeclBuilder & addStoreFunction(DeclarationName &Name, bool IsConst, QualType ValueType)
friend struct BuiltinTypeMethodBuilder
BuiltinTypeDeclBuilder & addDefaultHandleConstructor(AccessSpecifier Access=AccessSpecifier::AS_public)
BuiltinTypeDeclBuilder(Sema &SemaRef, CXXRecordDecl *R)
BuiltinTypeDeclBuilder & addMemberVariable(StringRef Name, QualType Type, llvm::ArrayRef< Attr * > Attrs, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addHandleAccessFunction(DeclarationName &Name, bool IsConstReturn, bool IsRef, QualType IndexTy, QualType ElemTy=QualType())
BuiltinTypeDeclBuilder & addConsumeMethod()
BuiltinTypeDeclBuilder & addCopyAssignmentOperator(AccessSpecifier Access=AccessSpecifier::AS_public)
~BuiltinTypeDeclBuilder()
friend struct TemplateParameterListBuilder
BuiltinTypeDeclBuilder & addArraySubscriptOperators(ResourceDimension Dim=ResourceDimension::Unknown)
BuiltinTypeDeclBuilder & addSampleGradMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addGetDimensionsMethodForBuffer()
BuiltinTypeDeclBuilder & addGatherCmpMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addConstantBufferConversionToType()
BuiltinTypeDeclBuilder & addSamplerHandle()
BuiltinTypeDeclBuilder & addSampleBiasMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & completeDefinition()
BuiltinTypeDeclBuilder & addBufferHandles(ResourceClass RC, bool IsROV, bool RawBuffer, bool HasCounter, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addByteAddressBufferStoreMethods()
BuiltinTypeDeclBuilder & addTextureHandle(ResourceClass RC, bool IsROV, ResourceDimension RD, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addCopyConstructor(AccessSpecifier Access=AccessSpecifier::AS_public)
BuiltinTypeDeclBuilder & addAppendMethod()
BuiltinTypeDeclBuilder & addTextureLoadMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addLoadWithStatusFunction(DeclarationName &Name, QualType ReturnTy=QualType())
BuiltinTypeDeclBuilder & addIncrementCounterMethod()
BuiltinTypeDeclBuilder & addSampleLevelMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addMipsMember(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addByteAddressBufferLoadMethods()
BuiltinTypeDeclBuilder & addSampleMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addStaticInitializationFunctions(bool HasCounter)
BuiltinTypeDeclBuilder & addCalculateLodMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addGetDimensionsMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addSampleCmpLevelZeroMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addSimpleTemplateParams(ArrayRef< StringRef > Names, ConceptDecl *CD=nullptr)
BuiltinTypeDeclBuilder & addGatherMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addDecrementCounterMethod()
BuiltinTypeDeclBuilder & addSampleCmpMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addLoadMethods()
uint32_t getResourceDimensions(llvm::dxil::ResourceDimension Dim)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ ICIS_NoInit
No in-class initializer.
@ OK_Ordinary
An ordinary object is located at an address in memory.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
MutableArrayRef< Expr * > MultiExprArg
@ Result
The result type of a method or function.
ParameterABI
Kinds of parameter ABI.
@ Template
We are parsing a template declaration.
bool CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, ArrayRef< const Attr * > AttrList, QualType &ResType, HLSLAttributedResourceLocInfo *LocInfo=nullptr)
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
BuiltinTypeMethodBuilder & concat(V Vec, S Scalar, QualType ResultTy)
BuiltinTypeMethodBuilder & addParam(StringRef Name, QualType Ty, HLSLParamModifierAttr::Spelling Modifier=HLSLParamModifierAttr::Keyword_in)
BuiltinTypeMethodBuilder & accessFieldOnResource(T ResourceRecord, FieldDecl *Field)
Expr * getResourceHandleExpr()
BuiltinTypeDeclBuilder & finalize(AccessSpecifier Access=AccessSpecifier::AS_public)
BuiltinTypeMethodBuilder & callBuiltin(StringRef BuiltinName, QualType ReturnType, Ts &&...ArgSpecs)
BuiltinTypeMethodBuilder & accessHandleFieldOnResource(T ResourceRecord)
Expr * getResourceCounterHandleExpr()
BuiltinTypeMethodBuilder & setHandleFieldOnResource(LocalVar &ResourceRecord, ValueT HandleValue)
BuiltinTypeMethodBuilder & operator=(const BuiltinTypeMethodBuilder &Other)=delete
BuiltinTypeMethodBuilder & returnThis()
BuiltinTypeMethodBuilder & dereference(T Ptr)
~BuiltinTypeMethodBuilder()
BuiltinTypeMethodBuilder & declareLocalVar(LocalVar &Var)
BuiltinTypeMethodBuilder & assign(TLHS LHS, TRHS RHS)
BuiltinTypeMethodBuilder(const BuiltinTypeMethodBuilder &Other)=delete
BuiltinTypeMethodBuilder & accessCounterHandleFieldOnResource(T ResourceRecord)
BuiltinTypeMethodBuilder & setFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue, FieldDecl *HandleField)
BuiltinTypeMethodBuilder & setCounterHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue)
friend BuiltinTypeDeclBuilder
BuiltinTypeMethodBuilder & returnValue(T ReturnValue)
QualType addTemplateTypeParam(StringRef Name)
BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, DeclarationName &Name, QualType ReturnTy, bool IsConst=false, bool IsCtor=false, StorageClass SC=SC_None)
void setMipsHandleField(LocalVar &ResourceRecord)
TemplateParameterListBuilder & addTypeParameter(StringRef Name, QualType DefaultValue=QualType())
BuiltinTypeDeclBuilder & finalizeTemplateArgs(ConceptDecl *CD=nullptr)
llvm::SmallVector< NamedDecl * > Params
~TemplateParameterListBuilder()
TemplateParameterListBuilder(BuiltinTypeDeclBuilder &RB)
ConceptSpecializationExpr * constructConceptSpecializationExpr(Sema &S, ConceptDecl *CD)
BuiltinTypeDeclBuilder & Builder