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(Record->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(Record->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(Record->isCompleteDefinition() && "record is already complete");

233 Record->startDefinition();

234 return *this;

235 }

236

237 BuiltinTypeDeclBuilder &completeDefinition() {

238 assert(Record->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(Record->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 (Record->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.