clang: lib/Sema/HLSLExternalSemaSource.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/Frontend/HLSL/HLSLResource.h"
25#include "llvm/Support/ErrorHandling.h"
26
27#include
28
29using namespace clang;
30using namespace llvm::hlsl;
31
33
34namespace {
35
36struct TemplateParameterListBuilder;
37
38class BuiltinTypeDeclBuilder {
42 llvm::StringMap<FieldDecl *> Fields;
43
44public:
45 Sema &SemaRef;
47 friend struct TemplateParameterListBuilder;
48
50 : SemaRef(SemaRef), Record(R) {
51 Record->startDefinition();
52 Template = Record->getDescribedClassTemplate();
53 }
54
56 StringRef Name)
57 : HLSLNamespace(Namespace), SemaRef(SemaRef) {
60
64
66 if (auto *TD = dyn_cast(Found)) {
67 PrevDecl = TD->getTemplatedDecl();
68 PrevTemplate = TD;
69 } else
70 PrevDecl = dyn_cast(Found);
71 assert(PrevDecl && "Unexpected lookup result type.");
72 }
73
76 Template = PrevTemplate;
77 return;
78 }
79
82 PrevDecl, true);
83 Record->setImplicit(true);
84 Record->setLexicalDeclContext(HLSLNamespace);
85 Record->setHasExternalLexicalStorage();
86
87
89 FinalAttr::Keyword_final));
90 }
91
92 ~BuiltinTypeDeclBuilder() {
93 if (HLSLNamespace && !Template && Record->getDeclContext() == HLSLNamespace)
95 }
96
98
99
100
101
102
103
104
107 }
108
109 BuiltinTypeDeclBuilder &
112 assert(->isCompleteDefinition() && "record is already complete");
113 assert(Record->isBeingDefined() &&
114 "Definition must be started before adding members!");
116
122 nullptr, false, InClassInitStyle::ICIS_NoInit);
123 Field->setAccess(Access);
124 Field->setImplicit(true);
125 for (Attr *A : Attrs) {
126 if (A)
127 Field->addAttr(A);
128 }
129
130 Record->addDecl(Field);
131 Fields[Name] = Field;
132 return *this;
133 }
134
135 BuiltinTypeDeclBuilder &
136 addHandleMember(ResourceClass RC, ResourceKind RK, bool IsROV, bool RawBuffer,
138 assert(->isCompleteDefinition() && "record is already complete");
139
143
144
147 HLSLResourceClassAttr::CreateImplicit(Ctx, RC),
148 IsROV ? HLSLROVAttr::CreateImplicit(Ctx) : nullptr,
149 RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) : nullptr,
150 ElementTypeInfo
151 ? HLSLContainedTypeAttr::CreateImplicit(Ctx, ElementTypeInfo)
152 : nullptr};
153 Attr *ResourceAttr = HLSLResourceAttr::CreateImplicit(Ctx, RK);
155 AttributedResTy))
156 addMemberVariable("__handle", AttributedResTy, {ResourceAttr}, Access);
157 return *this;
158 }
159
160 BuiltinTypeDeclBuilder &addDefaultHandleConstructor() {
161 if (Record->isCompleteDefinition())
162 return *this;
164
167
168 CanQualType CanTy = Record->getTypeForDecl()->getCanonicalTypeUnqualified();
175 ConstexprSpecKind::Unspecified);
176
179 Constructor->setAccess(AccessSpecifier::AS_public);
180 Record->addDecl(Constructor);
181 return *this;
182 }
183
184 BuiltinTypeDeclBuilder &addArraySubscriptOperators() {
188
189 addHandleAccessFunction(Subscript, true, true);
190 addHandleAccessFunction(Subscript, false, true);
191 return *this;
192 }
193
194 BuiltinTypeDeclBuilder &addLoadMethods() {
195 if (Record->isCompleteDefinition())
196 return *this;
197
201
202 addHandleAccessFunction(Load, false, false);
203
204 return *this;
205 }
206
207 FieldDecl *getResourceHandleField() {
208 auto I = Fields.find("__handle");
209 assert(I != Fields.end() &&
210 I->second->getType()->isHLSLAttributedResourceType() &&
211 "record does not have resource handle field");
212 return I->second;
213 }
214
215 QualType getFirstTemplateTypeParam() {
216 assert(Template && "record it not a template");
217 if (const auto *TTD = dyn_cast(
219 return QualType(TTD->getTypeForDecl(), 0);
220 }
222 }
223
224 QualType getHandleElementType() {
225 if (Template)
226 return getFirstTemplateTypeParam();
227
229 }
230
231 BuiltinTypeDeclBuilder &startDefinition() {
232 assert(->isCompleteDefinition() && "record is already complete");
233 Record->startDefinition();
234 return *this;
235 }
236
237 BuiltinTypeDeclBuilder &completeDefinition() {
238 assert(->isCompleteDefinition() && "record is already complete");
239 assert(Record->isBeingDefined() &&
240 "Definition must be started before completing it.");
241
242 Record->completeDefinition();
243 return *this;
244 }
245
246 Expr *getConstantIntExpr(int value) {
251 }
252
253 TemplateParameterListBuilder addTemplateArgumentList();
254 BuiltinTypeDeclBuilder &addSimpleTemplateParams(ArrayRef Names,
256
257
258 BuiltinTypeDeclBuilder &addIncrementCounterMethod();
259 BuiltinTypeDeclBuilder &addDecrementCounterMethod();
260 BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name,
261 bool IsConst, bool IsRef);
262 BuiltinTypeDeclBuilder &addAppendMethod();
263 BuiltinTypeDeclBuilder &addConsumeMethod();
264};
265
266struct TemplateParameterListBuilder {
267 BuiltinTypeDeclBuilder &Builder;
269
270 TemplateParameterListBuilder(BuiltinTypeDeclBuilder &RB) : Builder(RB) {}
271
272 ~TemplateParameterListBuilder() { finalizeTemplateArgs(); }
273
274 TemplateParameterListBuilder &
275 addTypeParameter(StringRef Name, QualType DefaultValue = QualType()) {
276 assert(!Builder.Record->isCompleteDefinition() &&
277 "record is already complete");
278 ASTContext &AST = Builder.SemaRef.getASTContext();
279 unsigned Position = static_cast<unsigned>(Params.size());
281 AST, Builder.Record->getDeclContext(), SourceLocation(),
283 &AST.Idents.get(Name, tok::TokenKind::identifier),
284 true,
285 false,
286 false);
287 if (!DefaultValue.isNull())
288 Decl->setDefaultArgument(AST,
289 Builder.SemaRef.getTrivialTemplateArgumentLoc(
291
292 Params.emplace_back(Decl);
293 return *this;
294 }
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
318 constructConceptSpecializationExpr(Sema &S, ConceptDecl *CD) {
323 DeclContext *DC = Builder.Record->getDeclContext();
325
326
327
328
330 "unexpected concept decl parameter count");
333
334
335
336
338 Context,
339 Builder.Record->getDeclContext(),
341 0,
342 0,
343 nullptr,
344 true,
345 false,
346 false
347 );
348
349 T->setDeclContext(DC);
350
352
353
354
356
358
359
360
362
365 Context, Builder.Record->getDeclContext(), Loc, {CSETA});
366
367
368
369
373
374 TALI.addArgument(TAL);
377
378
379
382
385
386 return CSE;
387 }
388
389 BuiltinTypeDeclBuilder &finalizeTemplateArgs(ConceptDecl *CD = nullptr) {
390 if (Params.empty())
391 return Builder;
392
393 ASTContext &AST = Builder.SemaRef.Context;
395 CD ? constructConceptSpecializationExpr(Builder.SemaRef, CD) : nullptr;
396 auto *ParamList = TemplateParameterList::Create(
399 AST, Builder.Record->getDeclContext(), SourceLocation(),
400 DeclarationName(Builder.Record->getIdentifier()), ParamList,
401 Builder.Record);
402
403 Builder.Record->setDescribedClassTemplate(Builder.Template);
404 Builder.Template->setImplicit(true);
405 Builder.Template->setLexicalDeclContext(Builder.Record->getDeclContext());
406
407
408
409 Builder.Template->setPreviousDecl(Builder.PrevTemplate);
410 Builder.Record->getDeclContext()->addDecl(Builder.Template);
411 Params.clear();
412
413 QualType T = Builder.Template->getInjectedClassNameSpecialization();
415
416 return Builder;
417 }
418};
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442struct BuiltinTypeMethodBuilder {
443 struct MethodParam {
446 HLSLParamModifierAttr::Spelling Modifier;
448 HLSLParamModifierAttr::Spelling Modifier)
449 : NameII(NameII), Ty(Ty), Modifier(Modifier) {}
450 };
451
452 BuiltinTypeDeclBuilder &DeclBuilder;
456 bool IsConst;
459
460
461
462
463
464
465
466
467 enum class PlaceHolder { _0, _1, _2, _3, Handle = 128, LastStmt };
468
469 Expr *convertPlaceholder(PlaceHolder PH) {
470 if (PH == PlaceHolder::Handle)
471 return getResourceHandleExpr();
472
473 if (PH == PlaceHolder::LastStmt) {
474 assert(!StmtsList.empty() && "no statements in the list");
475 Stmt *LastStmt = StmtsList.pop_back_val();
476 assert(isa(LastStmt) &&
477 "last statement does not have a value");
478 return cast(LastStmt)->getExprStmt();
479 }
480
481 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
487 }
488 Expr *convertPlaceholder(Expr *E) { return E; }
489
490public:
491 BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, DeclarationName &Name,
492 QualType ReturnTy, bool IsConst = false)
494 ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst) {}
495
496 BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, StringRef Name,
497 QualType ReturnTy, bool IsConst = false)
498 : DeclBuilder(DB), ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst) {
500 DB.SemaRef.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
502 }
503
504 BuiltinTypeMethodBuilder &addParam(StringRef Name, QualType Ty,
505 HLSLParamModifierAttr::Spelling Modifier =
506 HLSLParamModifierAttr::Keyword_in) {
507 assert(Method == nullptr && "Cannot add param, method already created");
508 const IdentifierInfo &II = DeclBuilder.SemaRef.getASTContext().Idents.get(
509 Name, tok::TokenKind::identifier);
510 Params.emplace_back(II, Ty, Modifier);
511 return *this;
512 }
513
514private:
515 void createMethodDecl() {
516 assert(Method == nullptr && "Method already created");
517
518
519 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
521 for (MethodParam &MP : Params)
522 ParamTypes.emplace_back(MP.Ty);
523
525 if (IsConst)
527
529
530
532 Method =
534 NameInfo, MethodTy, TSInfo, SC_None, false, false,
536
537
539 auto FnProtoLoc =
541 for (int I = 0, E = Params.size(); I != E; I++) {
542 MethodParam &MP = Params[I];
545 &MP.NameII, MP.Ty,
547 nullptr);
548 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
549 auto *Mod =
550 HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
552 }
553 ParmDecls.push_back(Parm);
554 FnProtoLoc.setParam(I, Parm);
555 }
557 }
558
559public:
560 ~BuiltinTypeMethodBuilder() { finalizeMethod(); }
561
562 BuiltinTypeMethodBuilder(const BuiltinTypeMethodBuilder &Other) = delete;
563 BuiltinTypeMethodBuilder &
564 operator=(const BuiltinTypeMethodBuilder &Other) = delete;
565
566 Expr *getResourceHandleExpr() {
567
568
569 if (!Method)
570 createMethodDecl();
571
572 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
575 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
579 }
580
581 template <typename... Ts>
582 BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName,
583 QualType ReturnType, Ts... ArgSpecs) {
584 std::array<Expr *, sizeof...(ArgSpecs)> Args{
585 convertPlaceholder(std::forward(ArgSpecs))...};
586
587
588
589 if (!Method)
590 createMethodDecl();
591
592 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
597
598 if (ReturnType.isNull())
600
603 StmtsList.push_back(Call);
604 return *this;
605 }
606
607 template <typename TLHS, typename TRHS>
608 BuiltinTypeMethodBuilder &assign(TLHS LHS, TRHS RHS) {
609 Expr *LHSExpr = convertPlaceholder(LHS);
610 Expr *RHSExpr = convertPlaceholder(RHS);
612 DeclBuilder.SemaRef.getASTContext(), LHSExpr, RHSExpr, BO_Assign,
613 LHSExpr->getType(), ExprValueKind::VK_PRValue,
615 StmtsList.push_back(AssignStmt);
616 return *this;
617 }
618
619 template BuiltinTypeMethodBuilder &dereference(T Ptr) {
620 Expr *PtrExpr = convertPlaceholder(Ptr);
621 Expr *Deref =
626 StmtsList.push_back(Deref);
627 return *this;
628 }
629
630 BuiltinTypeDeclBuilder &finalizeMethod() {
631 assert(!DeclBuilder.Record->isCompleteDefinition() &&
632 "record is already complete");
633 assert(
634 Method != nullptr &&
635 "method decl not created; are you missing a call to build the body?");
636
637 if (!Method->hasBody()) {
638 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
639 assert((ReturnTy == AST.VoidTy || !StmtsList.empty()) &&
640 "nothing to return from non-void method");
641 if (ReturnTy != AST.VoidTy) {
642 if (Expr *LastExpr = dyn_cast(StmtsList.back())) {
645 "Return type of the last statement must match the return type "
646 "of the method");
647 if (!isa(LastExpr)) {
648 StmtsList.pop_back();
649 StmtsList.push_back(
651 }
652 }
653 }
654
658 Method->setAccess(AccessSpecifier::AS_public);
659 Method->addAttr(AlwaysInlineAttr::CreateImplicit(
660 AST, SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
661 DeclBuilder.Record->addDecl(Method);
662 }
663 return DeclBuilder;
664 }
665};
666
667}
668
669TemplateParameterListBuilder BuiltinTypeDeclBuilder::addTemplateArgumentList() {
670 return TemplateParameterListBuilder(*this);
671}
672
673BuiltinTypeDeclBuilder &
674BuiltinTypeDeclBuilder::addSimpleTemplateParams(ArrayRef Names,
676 if (Record->isCompleteDefinition()) {
677 assert(Template && "existing record it not a template");
679 "template param count mismatch");
680 return *this;
681 }
682
683 TemplateParameterListBuilder Builder = this->addTemplateArgumentList();
684 for (StringRef Name : Names)
685 Builder.addTypeParameter(Name);
686 return Builder.finalizeTemplateArgs(CD);
687}
688
689BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addIncrementCounterMethod() {
690 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
691 return BuiltinTypeMethodBuilder(*this, "IncrementCounter",
693 .callBuiltin("__builtin_hlsl_buffer_update_counter", QualType(),
694 PH::Handle, getConstantIntExpr(1))
695 .finalizeMethod();
696}
697
698BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDecrementCounterMethod() {
699 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
700 return BuiltinTypeMethodBuilder(*this, "DecrementCounter",
702 .callBuiltin("__builtin_hlsl_buffer_update_counter", QualType(),
703 PH::Handle, getConstantIntExpr(-1))
704 .finalizeMethod();
705}
706
707BuiltinTypeDeclBuilder &
708BuiltinTypeDeclBuilder::addHandleAccessFunction(DeclarationName &Name,
709 bool IsConst, bool IsRef) {
710 assert(->isCompleteDefinition() && "record is already complete");
712 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
713
714 QualType ElemTy = getHandleElementType();
715
718 if (IsConst)
720 if (IsRef)
722
723 return BuiltinTypeMethodBuilder(*this, Name, ReturnTy, IsConst)
725 .callBuiltin("__builtin_hlsl_resource_getpointer", ElemPtrTy, PH::Handle,
726 PH::_0)
727 .dereference(PH::LastStmt)
728 .finalizeMethod();
729}
730
731BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addAppendMethod() {
732 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
734 QualType ElemTy = getHandleElementType();
735 return BuiltinTypeMethodBuilder(*this, "Append", AST.VoidTy)
736 .addParam("value", ElemTy)
737 .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy,
738 PH::Handle, getConstantIntExpr(1))
739 .callBuiltin("__builtin_hlsl_resource_getpointer",
740 AST.getPointerType(ElemTy), PH::Handle, PH::LastStmt)
741 .dereference(PH::LastStmt)
742 .assign(PH::LastStmt, PH::_0)
743 .finalizeMethod();
744}
745
746BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() {
747 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
749 QualType ElemTy = getHandleElementType();
750 return BuiltinTypeMethodBuilder(*this, "Consume", ElemTy)
751 .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy,
752 PH::Handle, getConstantIntExpr(-1))
753 .callBuiltin("__builtin_hlsl_resource_getpointer",
754 AST.getPointerType(ElemTy), PH::Handle, PH::LastStmt)
755 .dereference(PH::LastStmt)
756 .finalizeMethod();
757}
758
760
762 SemaPtr = &S;
764
767
779
780
782 defineTrivialHLSLTypes();
783 defineHLSLTypesWithForwardDeclarations();
784
785
786
787
788
789
790
795
797}
798
799void HLSLExternalSemaSource::defineHLSLVectorAlias() {
801
803
806 &AST.Idents.get("element", tok::TokenKind::identifier), false, false);
807 TypeParam->setDefaultArgument(
810
811 TemplateParams.emplace_back(TypeParam);
812
815 &AST.Idents.get("element_count", tok::TokenKind::identifier), AST.IntTy,
819 true);
820 SizeParam->setDefaultArgument(
823 TemplateParams.emplace_back(SizeParam);
824
825 auto *ParamList =
828
830
838
842 Record->setImplicit(true);
843
844 auto *Template =
847
848 Record->setDescribedAliasTemplate(Template);
851 HLSLNamespace->addDecl(Template);
852}
853
854void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
855 defineHLSLVectorAlias();
856}
857
858
860 ResourceClass RC, ResourceKind RK,
861 bool IsROV, bool RawBuffer) {
862 return BuiltinTypeDeclBuilder(S, Decl)
863 .addHandleMember(RC, RK, IsROV, RawBuffer)
864 .addDefaultHandleConstructor();
865}
866
867
868
869
870
874
875
877
878
880
881
884
886 Context, BoolTy, NameLoc, UTT_IsTypedResourceElementCompatible,
887 {TTypeSourceInfo}, NameLoc, true);
888
889 return TypedResExpr;
890}
891
892
893
894
895
900
901
903
904
906
907
910
913 {TTypeSourceInfo}, NameLoc, true);
914
915
919
920
922 UETT_SizeOf, TTypeSourceInfo, BoolTy, NameLoc, NameLoc);
923
924
925
929
933
934
936 Context, NotIntangibleExpr, SizeGEQOneExpr, BO_LAnd, BoolTy, VK_LValue,
938
939 return CombinedExpr;
940}
941
943 bool isTypedBuffer) {
947
951 0,
952 0,
953 &ElementTypeII,
954 true,
955 false);
956
957 T->setDeclContext(DC);
958 T->setReferenced();
959
960
962 Context, DeclLoc, DeclLoc, {T}, DeclLoc, nullptr);
963
965 Expr *ConstraintExpr = nullptr;
966
967 if (isTypedBuffer) {
969 &Context.Idents.get("__is_typed_resource_element_compatible"));
971 } else {
973 &Context.Idents.get("__is_structured_resource_element_compatible"));
975 }
976
977
980 ConceptParams, ConstraintExpr);
981
982
984
985
987
988 return CD;
989}
990
991void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
994 *SemaPtr, HLSLNamespace, true);
996 *SemaPtr, HLSLNamespace, false);
997 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer")
998 .addSimpleTemplateParams({"element_type"}, TypedBufferConcept)
999 .finalizeForwardDeclaration();
1000
1003 ResourceKind::TypedBuffer, false,
1004 false)
1005 .addArraySubscriptOperators()
1006 .addLoadMethods()
1007 .completeDefinition();
1008 });
1009
1011 BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RasterizerOrderedBuffer")
1012 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
1013 .finalizeForwardDeclaration();
1016 ResourceKind::TypedBuffer, true,
1017 false)
1018 .addArraySubscriptOperators()
1019 .addLoadMethods()
1020 .completeDefinition();
1021 });
1022
1023 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "StructuredBuffer")
1024 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
1025 .finalizeForwardDeclaration();
1027 setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer,
1028 false, true)
1029 .addArraySubscriptOperators()
1030 .addLoadMethods()
1031 .completeDefinition();
1032 });
1033
1034 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWStructuredBuffer")
1035 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
1036 .finalizeForwardDeclaration();
1038 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
1039 false, true)
1040 .addArraySubscriptOperators()
1041 .addLoadMethods()
1042 .addIncrementCounterMethod()
1043 .addDecrementCounterMethod()
1044 .completeDefinition();
1045 });
1046
1048 BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "AppendStructuredBuffer")
1049 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
1050 .finalizeForwardDeclaration();
1052 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
1053 false, true)
1054 .addAppendMethod()
1055 .completeDefinition();
1056 });
1057
1059 BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ConsumeStructuredBuffer")
1060 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
1061 .finalizeForwardDeclaration();
1063 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
1064 false, true)
1065 .addConsumeMethod()
1066 .completeDefinition();
1067 });
1068
1069 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
1070 "RasterizerOrderedStructuredBuffer")
1071 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
1072 .finalizeForwardDeclaration();
1074 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
1075 true, true)
1076 .addArraySubscriptOperators()
1077 .addLoadMethods()
1078 .addIncrementCounterMethod()
1079 .addDecrementCounterMethod()
1080 .completeDefinition();
1081 });
1082
1083 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ByteAddressBuffer")
1084 .finalizeForwardDeclaration();
1086 setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer,
1087 false,
1088 true)
1089 .completeDefinition();
1090 });
1091 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWByteAddressBuffer")
1092 .finalizeForwardDeclaration();
1094 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
1095 false,
1096 true)
1097 .completeDefinition();
1098 });
1099 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
1100 "RasterizerOrderedByteAddressBuffer")
1101 .finalizeForwardDeclaration();
1103 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
1104 true,
1105 true)
1106 .completeDefinition();
1107 });
1108}
1109
1111 CompletionFunction Fn) {
1112 if (->isCompleteDefinition())
1113 Completions.insert(std::make_pair(Record->getCanonicalDecl(), Fn));
1114}
1115
1117 if (!isa(Tag))
1118 return;
1119 auto Record = cast(Tag);
1120
1121
1122
1123 if (auto TDecl = dyn_cast(Record))
1124 Record = TDecl->getSpecializedTemplate()->getTemplatedDecl();
1126 auto It = Completions.find(Record);
1127 if (It == Completions.end())
1128 return;
1130}
1131
1138
1139
1141
1142
1144 "Since this is a builtin it should always resolve!");
1145 return cast(R.getFoundDecl());
1146}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV, bool RawBuffer)
Set up common members and attributes for buffer types.
static ConceptDecl * constructBufferConceptDecl(Sema &S, NamespaceDecl *NSD, bool isTypedBuffer)
static Expr * constructTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc, TemplateTypeParmDecl *T)
static FunctionDecl * lookupBuiltinFunction(Sema &S, StringRef Name)
static Expr * constructStructuredBufferConstraintExpr(Sema &S, SourceLocation NameLoc, TemplateTypeParmDecl *T)
llvm::MachO::Record Record
This file declares semantic analysis for HLSL constructs.
Defines the clang::SourceLocation class and associated facilities.
C Language Family Type Representation.
static std::optional< DereferenceInfo > dereference(ProgramStateRef State, const FieldRegion *FR)
Dereferences FR and returns with the pointee's region, and whether it needs to be casted back to it's...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
unsigned getIntWidth(QualType T) const
DeclarationNameTable DeclarationNames
QualType getRecordType(const RecordDecl *Decl) const
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const
getInjectedClassNameType - Return the unique reference to the injected class name type for the specif...
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.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, bool ParameterPack, TemplateTypeParmDecl *ParmDecl=nullptr) const
Retrieve the template type parameter type for a template parameter or parameter pack with the given d...
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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 getDependentSizedExtVectorType(QualType VectorType, Expr *SizeExpr, SourceLocation AttrLoc) const
Attr - This represents one attribute.
A builtin binary operation expression such as "x + y" or "x <= y".
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
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(), Expr *TrailingRequiresClause=nullptr)
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, Expr *TrailingRequiresClause=nullptr)
QualType getFunctionObjectParameterType() const
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, bool DelayTypeCreation=false)
Represents the this expression in C++.
static CXXThisExpr * Create(const ASTContext &Ctx, SourceLocation L, QualType Ty, bool IsImplicit)
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Declaration of a class template.
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.
static ConceptDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr=nullptr)
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, ConceptDecl *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...
void addDecl(Decl *D)
Add the declaration D into this context.
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
void setHasExternalLexicalStorage(bool ES=true) const
State whether this DeclContext has external storage for declarations lexically in this context.
decl_iterator decls_begin() const
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)
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
void setAccess(AccessSpecifier AS)
void setImplicit(bool I=true)
DeclContext * getDeclContext()
void setLexicalDeclContext(DeclContext *DC)
The name of a declaration.
TypeSourceInfo * getTypeSourceInfo() const
Store information needed for an explicit specifier.
This represents one expression.
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
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.
const ParmVarDecl * getParamDecl(unsigned i) const
QualType getReturnType() const
DeclarationNameInfo getNameInfo() const
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
void setParams(ArrayRef< ParmVarDecl * > NewParamInfo)
void CompleteType(TagDecl *Tag) override
Complete an incomplete HLSL builtin type.
void InitializeSema(Sema &S) override
Initialize the semantic source with the Sema instance being used to perform semantic analysis on the ...
~HLSLExternalSemaSource() override
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 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.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
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.
NamespaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this namespace.
static NamespaceDecl * Create(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested)
A C++ nested-name-specifier augmented with source location information.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
A (possibly-)qualified type.
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.
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.
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....
@ LookupNamespaceName
Look up a namespace name within a C++ using directive or namespace alias definition,...
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
ASTContext & getASTContext() const
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A convenient class for passing around template argument information.
Location wrapper for a TemplateArgument.
Represents a template argument.
void setTemplateParameters(TemplateParameterList *TParams)
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, std::optional< unsigned > NumExpanded=std::nullopt)
static TypeAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
static TypeTraitExpr * Create(const ASTContext &C, QualType T, SourceLocation Loc, TypeTrait Kind, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool Value)
Create a new type trait expression.
The base class of the type hierarchy.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represents a C++ using-declaration.
static UsingDirectiveDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceLocation NamespaceLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor)
__inline void unsigned int _2
bool This(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Result
The result type of a method or function.
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_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
@ Other
Other implicit parameter.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Represents an explicit template argument list in C++, e.g., the "" in "sort".
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
Extra information about a function prototype.