28#include "llvm/ADT/SmallVector.h"
30using namespace llvm::hlsl;
38static FunctionDecl *lookupBuiltinFunction(Sema &S, StringRef Name) {
40 S.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
41 DeclarationNameInfo NameInfo =
42 DeclarationNameInfo(DeclarationName(&II), SourceLocation());
46 S.LookupName(R, S.getCurScope());
49 assert(R.isSingleResult() &&
50 "Since this is a builtin it should always resolve!");
54static QualType lookupBuiltinType(Sema &S, StringRef Name, DeclContext *DC) {
56 S.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
58 S.LookupQualifiedName(
Result, DC);
59 assert(!
Result.empty() &&
"Builtin type not found");
61 S.getASTContext().getTypeDeclType(
Result.getAsSingle<TypeDecl>());
62 S.RequireCompleteType(SourceLocation(), Ty,
63 diag::err_tentative_def_incomplete_type);
67CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
68 assert(ResTy->isRecordType() &&
"not a CXXRecord type");
69 for (
auto *CD : ResTy->getAsCXXRecordDecl()->ctors())
70 if (CD->isCopyConstructor())
76convertParamModifierToParamABI(HLSLParamModifierAttr::Spelling Modifier) {
77 assert(Modifier != HLSLParamModifierAttr::Spelling::Keyword_in &&
78 "HLSL 'in' parameters modifier cannot be converted to ParameterABI");
80 case HLSLParamModifierAttr::Spelling::Keyword_out:
82 case HLSLParamModifierAttr::Spelling::Keyword_inout:
85 llvm_unreachable(
"Invalid HLSL parameter modifier");
89QualType getInoutParameterType(ASTContext &AST, QualType Ty) {
90 assert(!Ty->isReferenceType() &&
91 "Pointer and reference types cannot be inout or out parameters");
146 HLSLParamModifierAttr::Spelling Modifier;
148 HLSLParamModifierAttr::Spelling Modifier)
149 : NameII(NameII), Ty(Ty), Modifier(Modifier) {}
156 LocalVar(StringRef Name,
QualType Ty) : Name(Name), Ty(Ty),
Decl(
nullptr) {}
178 enum class PlaceHolder {
190 Expr *convertPlaceholder(PlaceHolder PH);
191 Expr *convertPlaceholder(LocalVar &Var);
192 Expr *convertPlaceholder(
Expr *E) {
return E; }
198 QualType ReturnTy,
bool IsConst =
false,
200 : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(
nullptr),
201 IsConst(IsConst), IsCtor(IsCtor), SC(SC) {}
204 QualType ReturnTy,
bool IsConst =
false,
214 HLSLParamModifierAttr::Spelling Modifier =
215 HLSLParamModifierAttr::Keyword_in);
217 template <
typename... Ts>
219 QualType ReturnType, Ts &&...ArgSpecs);
220 template <
typename TLHS,
typename TRHS>
224 template <
typename T>
226 template <
typename ResourceT,
typename ValueT>
229 template <
typename T>
232 template <
typename ResourceT,
typename ValueT>
246 void ensureCompleteDecl() {
251 template <
typename ResourceT,
typename ValueT>
264 assert(!
Builder.Record->isCompleteDefinition() &&
265 "record is already complete");
267 unsigned Position =
static_cast<unsigned>(
Params.size());
271 &AST.
Idents.
get(Name, tok::TokenKind::identifier),
275 if (!DefaultValue.
isNull())
276 Decl->setDefaultArgument(AST,
277 Builder.SemaRef.getTrivialTemplateArgumentLoc(
319 "unexpected concept decl parameter count");
328 Builder.Record->getDeclContext(),
338 T->setDeclContext(DC);
340 QualType ConceptTType = Context.getTypeDeclType(ConceptTTPD);
346 QualType CSETType = Context.getTypeDeclType(
T);
354 Context,
Builder.Record->getDeclContext(), Loc, {CSETA});
394 Builder.Template->setImplicit(
true);
395 Builder.Template->setLexicalDeclContext(
Builder.Record->getDeclContext());
406Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) {
407 if (PH == PlaceHolder::Handle)
409 if (PH == PlaceHolder::CounterHandle)
412 if (PH == PlaceHolder::LastStmt) {
413 assert(!StmtsList.empty() &&
"no statements in the list");
414 Stmt *LastStmt = StmtsList.pop_back_val();
415 assert(
isa<ValueStmt>(LastStmt) &&
"last statement does not have a value");
431Expr *BuiltinTypeMethodBuilder::convertPlaceholder(LocalVar &Var) {
432 VarDecl *VD = Var.Decl;
433 assert(VD &&
"local variable is not declared");
435 VD->getASTContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
436 false, DeclarationNameInfo(VD->getDeclName(), SourceLocation()),
443 bool IsConst,
bool IsCtor,
445 : DeclBuilder(DB), ReturnTy(ReturnTy), Method(
nullptr), IsConst(IsConst),
446 IsCtor(IsCtor), SC(SC) {
448 assert((!NameStr.empty() || IsCtor) &&
"method needs a name");
449 assert(((IsCtor && !IsConst) || !IsCtor) &&
"constructor cannot be const");
457 AST.
Idents.
get(NameStr, tok::TokenKind::identifier);
464 HLSLParamModifierAttr::Spelling Modifier) {
465 assert(Method ==
nullptr &&
"Cannot add param, method already created");
466 const IdentifierInfo &II = DeclBuilder.SemaRef.getASTContext().Idents.get(
467 Name, tok::TokenKind::identifier);
468 Params.emplace_back(II, Ty, Modifier);
472void BuiltinTypeMethodBuilder::createDecl() {
473 assert(
Method ==
nullptr &&
"Method or constructor is already created");
479 uint32_t ArgIndex = 0;
482 bool UseParamExtInfo =
false;
483 for (Param &MP : Params) {
484 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
485 UseParamExtInfo =
true;
487 ParamExtInfos[ArgIndex] =
488 PI.
withABI(convertParamModifierToParamABI(MP.Modifier));
489 if (!MP.Ty->isDependentType())
490 MP.Ty = getInoutParameterType(AST, MP.Ty);
492 ParamTypes.emplace_back(MP.Ty);
496 FunctionProtoType::ExtProtoInfo ExtInfo;
498 ExtInfo.ExtParameterInfos = ParamExtInfos.data();
500 ExtInfo.TypeQuals.addConst();
506 DeclarationNameInfo NameInfo = DeclarationNameInfo(Name, SourceLocation());
509 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo,
510 ExplicitSpecifier(),
false,
true,
false,
514 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo, SC,
521 Method->getTypeSourceInfo()->getTypeLoc().getAs<FunctionProtoTypeLoc>();
522 for (
int I = 0, E = Params.size(); I != E; I++) {
523 Param &MP = Params[I];
525 AST, Method->getDeclContext(), SourceLocation(), SourceLocation(),
529 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
531 HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
534 Parm->setScopeInfo(CurScopeDepth, I);
535 ParmDecls.push_back(Parm);
536 FnProtoLoc.setParam(I, Parm);
538 Method->setParams({ParmDecls});
542 ensureCompleteDecl();
544 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
546 AST,
SourceLocation(), Method->getFunctionObjectParameterType(),
true);
547 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
554 ensureCompleteDecl();
556 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
558 AST,
SourceLocation(), Method->getFunctionObjectParameterType(),
true);
559 FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
567 ensureCompleteDecl();
569 assert(Var.Decl ==
nullptr &&
"local variable is already declared");
571 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
574 &AST.
Idents.
get(Var.Name, tok::TokenKind::identifier), Var.Ty,
578 StmtsList.push_back(DS);
583 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
587 StmtsList.push_back(ThisExpr);
591template <
typename... Ts>
594 QualType ReturnType, Ts &&...ArgSpecs) {
595 ensureCompleteDecl();
597 std::array<
Expr *,
sizeof...(ArgSpecs)> Args{
598 convertPlaceholder(std::forward<Ts>(ArgSpecs))...};
600 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
601 FunctionDecl *FD = lookupBuiltinFunction(DeclBuilder.SemaRef, BuiltinName);
609 assert(!
Call.isInvalid() &&
"Call to builtin cannot fail!");
612 if (!ReturnType.
isNull() &&
614 ExprResult CastResult = DeclBuilder.SemaRef.BuildCStyleCastExpr(
617 assert(!CastResult.isInvalid() &&
"Cast cannot fail!");
618 E = CastResult.get();
621 StmtsList.push_back(E);
625template <
typename TLHS,
typename TRHS>
627 Expr *LHSExpr = convertPlaceholder(LHS);
628 Expr *RHSExpr = convertPlaceholder(RHS);
630 DeclBuilder.SemaRef.getASTContext(), LHSExpr, RHSExpr, BO_Assign,
633 StmtsList.push_back(AssignStmt);
639 Expr *PtrExpr = convertPlaceholder(Ptr);
645 StmtsList.push_back(Deref);
652 ensureCompleteDecl();
654 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
657 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
660 if (ResourceTypeDecl == DeclBuilder.Record)
661 HandleField = DeclBuilder.getResourceHandleField();
664 for (
auto *
Decl : ResourceTypeDecl->lookup(&II)) {
665 if ((HandleField = dyn_cast<FieldDecl>(
Decl)))
668 assert(HandleField &&
"Resource handle field not found");
674 StmtsList.push_back(HandleExpr);
678template <
typename ResourceT,
typename ValueT>
681 ValueT HandleValue) {
682 return setFieldOnResource(ResourceRecord, HandleValue,
683 DeclBuilder.getResourceHandleField());
686template <
typename ResourceT,
typename ValueT>
689 ResourceT ResourceRecord, ValueT HandleValue) {
690 return setFieldOnResource(ResourceRecord, HandleValue,
691 DeclBuilder.getResourceCounterHandleField());
694template <
typename ResourceT,
typename ValueT>
696 ResourceT ResourceRecord, ValueT HandleValue,
FieldDecl *HandleField) {
697 ensureCompleteDecl();
699 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
702 "Getting the field from the wrong resource type.");
704 Expr *HandleValueExpr = convertPlaceholder(HandleValue);
711 DeclBuilder.SemaRef.
getASTContext(), HandleMemberExpr, HandleValueExpr,
714 StmtsList.push_back(AssignStmt);
719BuiltinTypeMethodBuilder &
721 ensureCompleteDecl();
723 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
725 "Getting the field from the wrong resource type.");
727 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
728 FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
732 StmtsList.push_back(HandleExpr);
738 ensureCompleteDecl();
740 Expr *ReturnValueExpr = convertPlaceholder(ReturnValue);
741 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
751 assert(CD &&
"no copy constructor found");
765 assert(!DeclBuilder.Record->isCompleteDefinition() &&
766 "record is already complete");
768 ensureCompleteDecl();
770 if (!Method->hasBody()) {
771 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
772 assert((ReturnTy == AST.
VoidTy || !StmtsList.empty()) &&
773 "nothing to return from non-void method");
774 if (ReturnTy != AST.
VoidTy) {
775 if (
Expr *LastExpr = dyn_cast<Expr>(StmtsList.back())) {
777 ReturnTy.getNonReferenceType()) &&
778 "Return type of the last statement must match the return type "
781 StmtsList.pop_back();
790 Method->setLexicalDeclContext(DeclBuilder.Record);
792 Method->addAttr(AlwaysInlineAttr::CreateImplicit(
793 AST,
SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
794 DeclBuilder.Record->addDecl(Method);
800 : SemaRef(SemaRef), Record(R) {
801 Record->startDefinition();
802 Template = Record->getDescribedClassTemplate();
808 : SemaRef(SemaRef), HLSLNamespace(Namespace) {
814 if (SemaRef.LookupQualifiedName(
Result, HLSLNamespace)) {
817 if (
auto *TD = dyn_cast<ClassTemplateDecl>(
Found)) {
818 PrevDecl = TD->getTemplatedDecl();
821 PrevDecl = dyn_cast<CXXRecordDecl>(
Found);
822 assert(PrevDecl &&
"Unexpected lookup result type.");
827 Template = PrevTemplate;
834 Record->setImplicit(
true);
835 Record->setLexicalDeclContext(HLSLNamespace);
836 Record->setHasExternalLexicalStorage();
840 FinalAttr::CreateImplicit(AST,
SourceRange(), FinalAttr::Keyword_final));
844 if (HLSLNamespace && !Template && Record->getDeclContext() == HLSLNamespace)
845 HLSLNamespace->addDecl(Record);
852 assert(!Record->isCompleteDefinition() &&
"record is already complete");
853 assert(Record->isBeingDefined() &&
854 "Definition must be started before adding members!");
863 Field->setAccess(Access);
864 Field->setImplicit(
true);
865 for (
Attr *A : Attrs) {
870 Record->addDecl(Field);
871 Fields[Name] = Field;
877 bool RawBuffer,
bool HasCounter,
879 addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer, Access);
881 addCounterHandleMember(RC, IsROV, RawBuffer, Access);
887 ResourceDimension RD,
889 addHandleMember(RC, RD, IsROV,
false, Access);
894 addHandleMember(ResourceClass::Sampler, ResourceDimension::Unknown,
900BuiltinTypeDeclBuilder::addHandleMember(ResourceClass RC, ResourceDimension RD,
901 bool IsROV,
bool RawBuffer,
903 return addResourceMember(
"__handle", RC, RD, IsROV, RawBuffer,
908 ResourceClass RC,
bool IsROV,
bool RawBuffer,
AccessSpecifier Access) {
909 return addResourceMember(
"__counter_handle", RC, ResourceDimension::Unknown,
915 StringRef MemberName,
ResourceClass RC, ResourceDimension RD,
bool IsROV,
916 bool RawBuffer,
bool IsCounter, AccessSpecifier Access) {
917 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
920 TypeSourceInfo *ElementTypeInfo =
924 QualType AttributedResTy = QualType();
926 HLSLResourceClassAttr::CreateImplicit(Ctx, RC),
927 IsROV ? HLSLROVAttr::CreateImplicit(Ctx) :
nullptr,
928 RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) :
nullptr,
929 RD != ResourceDimension::
Unknown
930 ? HLSLResourceDimensionAttr::CreateImplicit(Ctx, RD)
933 ? HLSLContainedTypeAttr::CreateImplicit(Ctx, ElementTypeInfo)
936 Attrs.push_back(HLSLIsCounterAttr::CreateImplicit(Ctx));
947 assert(!Record->isCompleteDefinition() &&
"record is already complete");
949 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
950 QualType HandleType = getResourceHandleField()->getType();
953 .callBuiltin(
"__builtin_hlsl_resource_uninitializedhandle", HandleType,
955 .assign(PH::Handle, PH::LastStmt)
962 addCreateFromBindingWithImplicitCounter();
963 addCreateFromImplicitBindingWithImplicitCounter();
965 addCreateFromBinding();
966 addCreateFromImplicitBinding();
983 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
985 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
989 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
995 .addParam(
"range", AST.
IntTy)
998 .declareLocalVar(TmpVar)
999 .accessHandleFieldOnResource(TmpVar)
1000 .callBuiltin(
"__builtin_hlsl_resource_handlefrombinding", HandleType,
1001 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
1002 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1003 .returnValue(TmpVar)
1020 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1022 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1026 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1032 .addParam(
"range", AST.
IntTy)
1035 .declareLocalVar(TmpVar)
1036 .accessHandleFieldOnResource(TmpVar)
1037 .callBuiltin(
"__builtin_hlsl_resource_handlefromimplicitbinding",
1038 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
1040 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1041 .returnValue(TmpVar)
1061BuiltinTypeDeclBuilder::addCreateFromBindingWithImplicitCounter() {
1062 assert(!
Record->isCompleteDefinition() &&
"record is already complete");
1064 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1066 QualType HandleType = getResourceHandleField()->
getType();
1067 QualType CounterHandleType = getResourceCounterHandleField()->
getType();
1069 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1072 "__createFromBindingWithImplicitCounter",
1076 .addParam(
"range", AST.
IntTy)
1080 .declareLocalVar(TmpVar)
1081 .accessHandleFieldOnResource(TmpVar)
1082 .callBuiltin(
"__builtin_hlsl_resource_handlefrombinding", HandleType,
1083 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
1084 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1085 .accessHandleFieldOnResource(TmpVar)
1086 .callBuiltin(
"__builtin_hlsl_resource_counterhandlefromimplicitbinding",
1087 CounterHandleType, PH::LastStmt, PH::_5, PH::_1)
1088 .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt)
1089 .returnValue(TmpVar)
1110BuiltinTypeDeclBuilder::addCreateFromImplicitBindingWithImplicitCounter() {
1111 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1113 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1114 ASTContext &AST = SemaRef.getASTContext();
1115 QualType HandleType = getResourceHandleField()->getType();
1116 QualType CounterHandleType = getResourceCounterHandleField()->getType();
1118 BuiltinTypeMethodBuilder::LocalVar TmpVar(
"tmp", RecordType);
1121 *
this,
"__createFromImplicitBindingWithImplicitCounter",
1125 .addParam(
"range", AST.
IntTy)
1129 .declareLocalVar(TmpVar)
1130 .accessHandleFieldOnResource(TmpVar)
1131 .callBuiltin(
"__builtin_hlsl_resource_handlefromimplicitbinding",
1132 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
1134 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
1135 .accessHandleFieldOnResource(TmpVar)
1136 .callBuiltin(
"__builtin_hlsl_resource_counterhandlefromimplicitbinding",
1137 CounterHandleType, PH::LastStmt, PH::_5, PH::_1)
1138 .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt)
1139 .returnValue(TmpVar)
1144 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1151 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1155 MMB.
addParam(
"other", ConstRecordRefType)
1157 .
assign(PH::Handle, PH::LastStmt);
1159 if (getResourceCounterHandleField())
1167 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1175 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1178 MMB.
addParam(
"other", ConstRecordRefType)
1180 .
assign(PH::Handle, PH::LastStmt);
1182 if (getResourceCounterHandleField())
1195 if (getResourceAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV)
1202 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1216 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1219 QualType ReturnType = getFirstTemplateTypeParam();
1222 lookupBuiltinType(SemaRef,
"SamplerState", Record->getDeclContext());
1232 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1236 .addParam(
"Sampler", SamplerStateType)
1237 .addParam(
"Location", Float2Ty)
1238 .accessHandleFieldOnResource(PH::_0)
1239 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1240 PH::LastStmt, PH::_1)
1241 .returnValue(PH::LastStmt)
1246 .addParam(
"Sampler", SamplerStateType)
1247 .addParam(
"Location", Float2Ty)
1248 .addParam(
"Offset", Int2Ty)
1249 .accessHandleFieldOnResource(PH::_0)
1250 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1251 PH::LastStmt, PH::_1, PH::_2)
1252 .returnValue(PH::LastStmt)
1257 .addParam(
"Sampler", SamplerStateType)
1258 .addParam(
"Location", Float2Ty)
1259 .addParam(
"Offset", Int2Ty)
1260 .addParam(
"Clamp", FloatTy)
1261 .accessHandleFieldOnResource(PH::_0)
1262 .callBuiltin(
"__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
1263 PH::LastStmt, PH::_1, PH::_2, PH::_3)
1264 .returnValue(PH::LastStmt)
1268FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField()
const {
1269 auto I = Fields.find(
"__handle");
1270 assert(I != Fields.end() &&
1271 I->second->getType()->isHLSLAttributedResourceType() &&
1272 "record does not have resource handle field");
1276FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField()
const {
1277 auto I = Fields.find(
"__counter_handle");
1278 if (I == Fields.end() ||
1279 !I->second->getType()->isHLSLAttributedResourceType())
1284QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam() {
1285 assert(
Template &&
"record it not a template");
1286 if (
const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
1287 Template->getTemplateParameters()->getParam(0))) {
1288 return QualType(TTD->getTypeForDecl(), 0);
1293QualType BuiltinTypeDeclBuilder::getHandleElementType() {
1295 return getFirstTemplateTypeParam();
1297 return SemaRef.getASTContext().Char8Ty;
1300HLSLAttributedResourceType::Attributes
1301BuiltinTypeDeclBuilder::getResourceAttrs()
const {
1302 QualType HandleType = getResourceHandleField()->getType();
1307 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1308 assert(Record->isBeingDefined() &&
1309 "Definition must be started before completing it.");
1311 Record->completeDefinition();
1315Expr *BuiltinTypeDeclBuilder::getConstantIntExpr(
int value) {
1325 if (Record->isCompleteDefinition()) {
1326 assert(Template &&
"existing record it not a template");
1327 assert(Template->getTemplateParameters()->size() == Names.size() &&
1328 "template param count mismatch");
1333 for (StringRef Name : Names)
1334 Builder.addTypeParameter(Name);
1335 return Builder.finalizeTemplateArgs(CD);
1339 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1340 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
1342 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
1343 PH::CounterHandle, getConstantIntExpr(1))
1348 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1349 QualType UnsignedIntTy = SemaRef.getASTContext().UnsignedIntTy;
1351 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", UnsignedIntTy,
1352 PH::CounterHandle, getConstantIntExpr(-1))
1359 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1361 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1363 QualType ReturnTy = getHandleElementType();
1366 .addParam(
"Status", AST.
UnsignedIntTy, HLSLParamModifierAttr::Keyword_out)
1367 .callBuiltin(
"__builtin_hlsl_resource_load_with_status", ReturnTy,
1368 PH::Handle, PH::_0, PH::_1)
1374 bool IsConst,
bool IsRef) {
1375 assert(!Record->isCompleteDefinition() &&
"record is already complete");
1377 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1379 QualType ElemTy = getHandleElementType();
1386 ReturnTy = AddrSpaceElemTy;
1398 .callBuiltin(
"__builtin_hlsl_resource_getpointer", ElemPtrTy, PH::Handle,
1400 .dereference(PH::LastStmt)
1405 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1407 QualType ElemTy = getHandleElementType();
1411 .addParam(
"value", ElemTy)
1412 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
1413 PH::CounterHandle, getConstantIntExpr(1))
1414 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
1417 .dereference(PH::LastStmt)
1418 .assign(PH::LastStmt, PH::_0)
1423 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1425 QualType ElemTy = getHandleElementType();
1429 .callBuiltin(
"__builtin_hlsl_buffer_update_counter", AST.
UnsignedIntTy,
1430 PH::CounterHandle, getConstantIntExpr(-1))
1431 .callBuiltin(
"__builtin_hlsl_resource_getpointer",
1434 .dereference(PH::LastStmt)
1440 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1444 QualType HandleTy = getResourceHandleField()->getType();
1449 if (AttrResTy->getAttrs().RawBuffer &&
1450 AttrResTy->getContainedType() != AST.
Char8Ty) {
1452 .addParam(
"numStructs", UIntTy, HLSLParamModifierAttr::Keyword_out)
1453 .addParam(
"stride", UIntTy, HLSLParamModifierAttr::Keyword_out)
1454 .callBuiltin(
"__builtin_hlsl_resource_getdimensions_x",
QualType(),
1456 .callBuiltin(
"__builtin_hlsl_resource_getstride",
QualType(),
1464 .addParam(
"dim", UIntTy, HLSLParamModifierAttr::Keyword_out)
1465 .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....
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 ...
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
a trap message and trap category.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
DeclarationNameTable DeclarationNames
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Attr - This represents one attribute.
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
static CXXConstructExpr * Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor, bool Elidable, ArrayRef< Expr * > Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, bool ZeroInitialization, CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange)
Create a C++ construction expression.
Represents a C++ constructor within a class.
static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited=InheritedConstructor(), const AssociatedConstraint &TrailingRequiresClause={})
Represents a static or instance method of a struct/union/class.
static CXXMethodDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin, bool isInline, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, const AssociatedConstraint &TrailingRequiresClause={})
Represents a C++ struct/union/class.
static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr)
Represents the this expression in C++.
static CXXThisExpr * Create(const ASTContext &Ctx, SourceLocation L, QualType Ty, bool IsImplicit)
QualType withConst() const
Retrieves a version of this type with const applied.
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Declaration of a C++20 concept.
A reference to a concept and its template args, as it appears in the code.
static ConceptReference * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, TemplateDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten)
Represents the specialization of a concept - evaluates to a prvalue of type bool.
static ConceptSpecializationExpr * Create(const ASTContext &C, ConceptReference *ConceptRef, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction)
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
The name of a declaration.
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)
Represents a function declaration or definition.
DeclarationNameInfo getNameInfo() const
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)
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.
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...
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.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
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...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
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)
friend struct BuiltinTypeMethodBuilder
BuiltinTypeDeclBuilder(Sema &SemaRef, CXXRecordDecl *R)
BuiltinTypeDeclBuilder & addSimpleTemplateParams(ArrayRef< StringRef > Names, ConceptDecl *CD)
BuiltinTypeDeclBuilder & addMemberVariable(StringRef Name, QualType Type, llvm::ArrayRef< Attr * > Attrs, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addConsumeMethod()
BuiltinTypeDeclBuilder & addLoadWithStatusFunction(DeclarationName &Name, bool IsConst)
~BuiltinTypeDeclBuilder()
BuiltinTypeDeclBuilder & addHandleAccessFunction(DeclarationName &Name, bool IsConst, bool IsRef)
friend struct TemplateParameterListBuilder
BuiltinTypeDeclBuilder & addGetDimensionsMethodForBuffer()
BuiltinTypeDeclBuilder & addSamplerHandle()
BuiltinTypeDeclBuilder & addArraySubscriptOperators()
BuiltinTypeDeclBuilder & completeDefinition()
BuiltinTypeDeclBuilder & addBufferHandles(ResourceClass RC, bool IsROV, bool RawBuffer, bool HasCounter, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addTextureHandle(ResourceClass RC, bool IsROV, ResourceDimension RD, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addAppendMethod()
BuiltinTypeDeclBuilder & addIncrementCounterMethod()
BuiltinTypeDeclBuilder & addCopyAssignmentOperator()
BuiltinTypeDeclBuilder & addCopyConstructor()
BuiltinTypeDeclBuilder & addSampleMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addStaticInitializationFunctions(bool HasCounter)
BuiltinTypeDeclBuilder & addDefaultHandleConstructor()
BuiltinTypeDeclBuilder & addDecrementCounterMethod()
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)
@ ICIS_NoInit
No in-class initializer.
@ OK_Ordinary
An ordinary object is located at an address in memory.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
MutableArrayRef< Expr * > MultiExprArg
@ Result
The result type of a method or function.
ParameterABI
Kinds of parameter ABI.
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
bool CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, ArrayRef< const Attr * > AttrList, QualType &ResType, HLSLAttributedResourceLocInfo *LocInfo=nullptr)
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
BuiltinTypeMethodBuilder & addParam(StringRef Name, QualType Ty, HLSLParamModifierAttr::Spelling Modifier=HLSLParamModifierAttr::Keyword_in)
Expr * getResourceHandleExpr()
BuiltinTypeMethodBuilder & callBuiltin(StringRef BuiltinName, QualType ReturnType, Ts &&...ArgSpecs)
BuiltinTypeMethodBuilder & accessHandleFieldOnResource(T ResourceRecord)
BuiltinTypeDeclBuilder & finalize()
Expr * getResourceCounterHandleExpr()
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 & setCounterHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue)
BuiltinTypeMethodBuilder & setHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue)
friend BuiltinTypeDeclBuilder
BuiltinTypeMethodBuilder & returnValue(T ReturnValue)
BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, DeclarationName &Name, QualType ReturnTy, bool IsConst=false, bool IsCtor=false, StorageClass SC=SC_None)
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