clang 23.0.0git
HLSLExternalSemaSource.cpp
Go to the documentation of this file.
1//===--- HLSLExternalSemaSource.cpp - HLSL Sema Source --------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//
10//===----------------------------------------------------------------------===//
11
15#include "clang/AST/Attr.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclCXX.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/Type.h"
22#include "clang/Sema/Lookup.h"
23#include "clang/Sema/Sema.h"
24#include "clang/Sema/SemaHLSL.h"
26#include "llvm/ADT/SmallVector.h"
27
28using namespace clang;
29using namespace llvm::hlsl;
30
32
34 SemaPtr = &S;
35 ASTContext &AST = SemaPtr->getASTContext();
36 // If the translation unit has external storage force external decls to load.
39
40 IdentifierInfo &HLSL = AST.Idents.get("hlsl", tok::TokenKind::identifier);
42 NamespaceDecl *PrevDecl = nullptr;
44 PrevDecl = Result.getAsSingle<NamespaceDecl>();
45 HLSLNamespace = NamespaceDecl::Create(
46 AST, AST.getTranslationUnitDecl(), /*Inline=*/false, SourceLocation(),
47 SourceLocation(), &HLSL, PrevDecl, /*Nested=*/false);
48 HLSLNamespace->setImplicit(true);
49 HLSLNamespace->setHasExternalLexicalStorage();
50 AST.getTranslationUnitDecl()->addDecl(HLSLNamespace);
51
52 // Force external decls in the HLSL namespace to load from the PCH.
53 (void)HLSLNamespace->getCanonicalDecl()->decls_begin();
54 defineTrivialHLSLTypes();
55 defineHLSLTypesWithForwardDeclarations();
56
57 // This adds a `using namespace hlsl` directive. In DXC, we don't put HLSL's
58 // built in types inside a namespace, but we are planning to change that in
59 // the near future. In order to be source compatible older versions of HLSL
60 // will need to implicitly use the hlsl namespace. For now in clang everything
61 // will get added to the namespace, and we can remove the using directive for
62 // future language versions to match HLSL's evolution.
65 NestedNameSpecifierLoc(), SourceLocation(), HLSLNamespace,
67
69}
70
71void HLSLExternalSemaSource::defineHLSLVectorAlias() {
72 ASTContext &AST = SemaPtr->getASTContext();
73
74 llvm::SmallVector<NamedDecl *> TemplateParams;
75
76 auto *TypeParam = TemplateTypeParmDecl::Create(
77 AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 0,
78 &AST.Idents.get("element", tok::TokenKind::identifier), false, false);
79 TypeParam->setDefaultArgument(
82
83 TemplateParams.emplace_back(TypeParam);
84
85 auto *SizeParam = NonTypeTemplateParmDecl::Create(
86 AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 1,
87 &AST.Idents.get("element_count", tok::TokenKind::identifier), AST.IntTy,
88 false, AST.getTrivialTypeSourceInfo(AST.IntTy));
89 llvm::APInt Val(AST.getIntWidth(AST.IntTy), 4);
90 TemplateArgument Default(AST, llvm::APSInt(std::move(Val)), AST.IntTy,
91 /*IsDefaulted=*/true);
92 SizeParam->setDefaultArgument(
94 SourceLocation(), SizeParam));
95 TemplateParams.emplace_back(SizeParam);
96
97 auto *ParamList =
99 TemplateParams, SourceLocation(), nullptr);
100
101 IdentifierInfo &II = AST.Idents.get("vector", tok::TokenKind::identifier);
102
104 AST.getTemplateTypeParmType(0, 0, false, TypeParam),
106 AST, NestedNameSpecifierLoc(), SourceLocation(), SizeParam, false,
107 DeclarationNameInfo(SizeParam->getDeclName(), SourceLocation()),
108 AST.IntTy, VK_LValue),
110
111 auto *Record = TypeAliasDecl::Create(AST, HLSLNamespace, SourceLocation(),
112 SourceLocation(), &II,
113 AST.getTrivialTypeSourceInfo(AliasType));
114 Record->setImplicit(true);
115
116 auto *Template =
117 TypeAliasTemplateDecl::Create(AST, HLSLNamespace, SourceLocation(),
118 Record->getIdentifier(), ParamList, Record);
119
120 Record->setDescribedAliasTemplate(Template);
121 Template->setImplicit(true);
122 Template->setLexicalDeclContext(Record->getDeclContext());
123 HLSLNamespace->addDecl(Template);
124}
125
126void HLSLExternalSemaSource::defineHLSLMatrixAlias() {
127 ASTContext &AST = SemaPtr->getASTContext();
128 llvm::SmallVector<NamedDecl *> TemplateParams;
129
130 auto *TypeParam = TemplateTypeParmDecl::Create(
131 AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 0,
132 &AST.Idents.get("element", tok::TokenKind::identifier), false, false);
133 TypeParam->setDefaultArgument(
134 AST, SemaPtr->getTrivialTemplateArgumentLoc(
136
137 TemplateParams.emplace_back(TypeParam);
138
139 // these should be 64 bit to be consistent with other clang matrices.
140 auto *RowsParam = NonTypeTemplateParmDecl::Create(
141 AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 1,
142 &AST.Idents.get("rows_count", tok::TokenKind::identifier), AST.IntTy,
143 false, AST.getTrivialTypeSourceInfo(AST.IntTy));
144 llvm::APInt RVal(AST.getIntWidth(AST.IntTy), 4);
145 TemplateArgument RDefault(AST, llvm::APSInt(std::move(RVal)), AST.IntTy,
146 /*IsDefaulted=*/true);
147 RowsParam->setDefaultArgument(
148 AST, SemaPtr->getTrivialTemplateArgumentLoc(RDefault, AST.IntTy,
149 SourceLocation(), RowsParam));
150 TemplateParams.emplace_back(RowsParam);
151
152 auto *ColsParam = NonTypeTemplateParmDecl::Create(
153 AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 2,
154 &AST.Idents.get("cols_count", tok::TokenKind::identifier), AST.IntTy,
155 false, AST.getTrivialTypeSourceInfo(AST.IntTy));
156 llvm::APInt CVal(AST.getIntWidth(AST.IntTy), 4);
157 TemplateArgument CDefault(AST, llvm::APSInt(std::move(CVal)), AST.IntTy,
158 /*IsDefaulted=*/true);
159 ColsParam->setDefaultArgument(
160 AST, SemaPtr->getTrivialTemplateArgumentLoc(CDefault, AST.IntTy,
161 SourceLocation(), ColsParam));
162 TemplateParams.emplace_back(ColsParam);
163
164 const unsigned MaxMatDim = SemaPtr->getLangOpts().MaxMatrixDimension;
165
166 auto *MaxRow = IntegerLiteral::Create(
167 AST, llvm::APInt(AST.getIntWidth(AST.IntTy), MaxMatDim), AST.IntTy,
169 auto *MaxCol = IntegerLiteral::Create(
170 AST, llvm::APInt(AST.getIntWidth(AST.IntTy), MaxMatDim), AST.IntTy,
172
173 auto *RowsRef = DeclRefExpr::Create(
174 AST, NestedNameSpecifierLoc(), SourceLocation(), RowsParam,
175 /*RefersToEnclosingVariableOrCapture*/ false,
176 DeclarationNameInfo(RowsParam->getDeclName(), SourceLocation()),
177 AST.IntTy, VK_LValue);
178 auto *ColsRef = DeclRefExpr::Create(
179 AST, NestedNameSpecifierLoc(), SourceLocation(), ColsParam,
180 /*RefersToEnclosingVariableOrCapture*/ false,
181 DeclarationNameInfo(ColsParam->getDeclName(), SourceLocation()),
182 AST.IntTy, VK_LValue);
183
184 auto *RowsLE = BinaryOperator::Create(AST, RowsRef, MaxRow, BO_LE, AST.BoolTy,
187 auto *ColsLE = BinaryOperator::Create(AST, ColsRef, MaxCol, BO_LE, AST.BoolTy,
190
192 AST, RowsLE, ColsLE, BO_LAnd, AST.BoolTy, VK_PRValue, OK_Ordinary,
194
195 auto *ParamList = TemplateParameterList::Create(
196 AST, SourceLocation(), SourceLocation(), TemplateParams, SourceLocation(),
198
199 IdentifierInfo &II = AST.Idents.get("matrix", tok::TokenKind::identifier);
200
202 AST.getTemplateTypeParmType(0, 0, false, TypeParam),
204 AST, NestedNameSpecifierLoc(), SourceLocation(), RowsParam, false,
205 DeclarationNameInfo(RowsParam->getDeclName(), SourceLocation()),
206 AST.IntTy, VK_LValue),
208 AST, NestedNameSpecifierLoc(), SourceLocation(), ColsParam, false,
209 DeclarationNameInfo(ColsParam->getDeclName(), SourceLocation()),
210 AST.IntTy, VK_LValue),
212
213 auto *Record = TypeAliasDecl::Create(AST, HLSLNamespace, SourceLocation(),
214 SourceLocation(), &II,
215 AST.getTrivialTypeSourceInfo(AliasType));
216 Record->setImplicit(true);
217
218 auto *Template =
219 TypeAliasTemplateDecl::Create(AST, HLSLNamespace, SourceLocation(),
220 Record->getIdentifier(), ParamList, Record);
221
222 Record->setDescribedAliasTemplate(Template);
223 Template->setImplicit(true);
224 Template->setLexicalDeclContext(Record->getDeclContext());
225 HLSLNamespace->addDecl(Template);
226}
227
228void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
229 defineHLSLVectorAlias();
230 defineHLSLMatrixAlias();
231}
232
233/// Set up common members and attributes for buffer types
235 ResourceClass RC, bool IsROV,
236 bool RawBuffer, bool HasCounter) {
238 .addBufferHandles(RC, IsROV, RawBuffer, HasCounter)
243}
244
245/// Set up common members and attributes for sampler types
254
255/// Set up common members and attributes for texture types
279
280// Add a partial specialization for a template. The `TextureTemplate` is
281// `Texture<element_type>`, and it will be specialized for vectors:
282// `Texture<vector<element_type, element_count>>`.
285 ClassTemplateDecl *TextureTemplate) {
286 ASTContext &AST = S.getASTContext();
287
288 // Create the template parameters: element_type and element_count.
289 auto *ElementType = TemplateTypeParmDecl::Create(
290 AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 0,
291 &AST.Idents.get("element_type"), false, false);
292 auto *ElementCount = NonTypeTemplateParmDecl::Create(
293 AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 1,
294 &AST.Idents.get("element_count"), AST.IntTy, false,
296
297 auto *TemplateParams = TemplateParameterList::Create(
298 AST, SourceLocation(), SourceLocation(), {ElementType, ElementCount},
299 SourceLocation(), nullptr);
300
301 // Create the dependent vector type: vector<element_type, element_count>.
303 AST.getTemplateTypeParmType(0, 0, false, ElementType),
305 AST, NestedNameSpecifierLoc(), SourceLocation(), ElementCount, false,
306 DeclarationNameInfo(ElementCount->getDeclName(), SourceLocation()),
307 AST.IntTy, VK_LValue),
309
310 // Create the partial specialization declaration.
311 QualType CanonInjectedTST =
315
317 AST, TagDecl::TagKind::Class, HLSLNamespace, SourceLocation(),
318 SourceLocation(), TemplateParams, TextureTemplate,
320 CanQualType::CreateUnsafe(CanonInjectedTST), nullptr);
321
322 // Set the template arguments as written.
324 TemplateArgumentLoc ArgLoc =
326 TemplateArgumentListInfo ArgsInfo =
328 ArgsInfo.addArgument(ArgLoc);
329 PartialSpec->setTemplateArgsAsWritten(
331
332 PartialSpec->setImplicit(true);
333 PartialSpec->setLexicalDeclContext(HLSLNamespace);
334 PartialSpec->setHasExternalLexicalStorage();
335
336 // Add the partial specialization to the namespace and the class template.
337 HLSLNamespace->addDecl(PartialSpec);
338 TextureTemplate->AddPartialSpecialization(PartialSpec, nullptr);
339
340 return PartialSpec;
341}
342
343// This function is responsible for constructing the constraint expression for
344// this concept:
345// template<typename T> concept is_typed_resource_element_compatible =
346// __is_typed_resource_element_compatible<T>;
349 ASTContext &Context = S.getASTContext();
350
351 // Obtain the QualType for 'bool'
352 QualType BoolTy = Context.BoolTy;
353
354 // Create a QualType that points to this TemplateTypeParmDecl
355 QualType TType = Context.getTypeDeclType(T);
356
357 // Create a TypeSourceInfo for the template type parameter 'T'
358 TypeSourceInfo *TTypeSourceInfo =
359 Context.getTrivialTypeSourceInfo(TType, NameLoc);
360
361 TypeTraitExpr *TypedResExpr = TypeTraitExpr::Create(
362 Context, BoolTy, NameLoc, UTT_IsTypedResourceElementCompatible,
363 {TTypeSourceInfo}, NameLoc, true);
364
365 return TypedResExpr;
366}
367
368// This function is responsible for constructing the constraint expression for
369// this concept:
370// template<typename T> concept is_constant_buffer_element_compatible =
371// std::is_class_v<T> && !__is_intangible(T);
373 SourceLocation NameLoc,
375 ASTContext &Context = S.getASTContext();
376
377 // Obtain the QualType for 'bool'
378 QualType BoolTy = Context.BoolTy;
379
380 // Create a QualType that points to this TemplateTypeParmDecl
381 QualType TType = Context.getTypeDeclType(T);
382
383 // Create a TypeSourceInfo for the template type parameter 'T'
384 TypeSourceInfo *TTypeSourceInfo =
385 Context.getTrivialTypeSourceInfo(TType, NameLoc);
386
388 Context, BoolTy, NameLoc, UTT_IsConstantBufferElementCompatible,
389 {TTypeSourceInfo}, NameLoc, true);
390
391 return ResExpr;
392}
393
394// This function is responsible for constructing the constraint expression for
395// this concept:
396// template<typename T> concept is_structured_resource_element_compatible =
397// !__is_intangible<T> && sizeof(T) >= 1;
399 SourceLocation NameLoc,
401 ASTContext &Context = S.getASTContext();
402
403 // Obtain the QualType for 'bool'
404 QualType BoolTy = Context.BoolTy;
405
406 // Create a QualType that points to this TemplateTypeParmDecl
407 QualType TType = Context.getTypeDeclType(T);
408
409 // Create a TypeSourceInfo for the template type parameter 'T'
410 TypeSourceInfo *TTypeSourceInfo =
411 Context.getTrivialTypeSourceInfo(TType, NameLoc);
412
413 TypeTraitExpr *IsIntangibleExpr =
414 TypeTraitExpr::Create(Context, BoolTy, NameLoc, UTT_IsIntangibleType,
415 {TTypeSourceInfo}, NameLoc, true);
416
417 // negate IsIntangibleExpr
418 UnaryOperator *NotIntangibleExpr = UnaryOperator::Create(
419 Context, IsIntangibleExpr, UO_LNot, BoolTy, VK_LValue, OK_Ordinary,
420 NameLoc, false, FPOptionsOverride());
421
422 // element types also may not be of 0 size
423 UnaryExprOrTypeTraitExpr *SizeOfExpr = new (Context) UnaryExprOrTypeTraitExpr(
424 UETT_SizeOf, TTypeSourceInfo, BoolTy, NameLoc, NameLoc);
425
426 // Create a BinaryOperator that checks if the size of the type is not equal to
427 // 1 Empty structs have a size of 1 in HLSL, so we need to check for that
429 Context, llvm::APInt(Context.getTypeSize(Context.getSizeType()), 1, true),
430 Context.getSizeType(), NameLoc);
431
432 BinaryOperator *SizeGEQOneExpr =
433 BinaryOperator::Create(Context, SizeOfExpr, rhs, BO_GE, BoolTy, VK_LValue,
434 OK_Ordinary, NameLoc, FPOptionsOverride());
435
436 // Combine the two constraints
438 Context, NotIntangibleExpr, SizeGEQOneExpr, BO_LAnd, BoolTy, VK_LValue,
439 OK_Ordinary, NameLoc, FPOptionsOverride());
440
441 return CombinedExpr;
442}
443
445
447 HLSLBufferType BT) {
448 ASTContext &Context = S.getASTContext();
449 DeclContext *DC = NSD->getDeclContext();
450 SourceLocation DeclLoc = SourceLocation();
451
452 IdentifierInfo &ElementTypeII = Context.Idents.get("element_type");
454 Context, NSD->getDeclContext(), DeclLoc, DeclLoc,
455 /*D=*/0,
456 /*P=*/0,
457 /*Id=*/&ElementTypeII,
458 /*Typename=*/true,
459 /*ParameterPack=*/false);
460
461 T->setDeclContext(DC);
462 T->setReferenced();
463
464 // Create and Attach Template Parameter List to ConceptDecl
466 Context, DeclLoc, DeclLoc, {T}, DeclLoc, nullptr);
467
468 DeclarationName DeclName;
469 Expr *ConstraintExpr = nullptr;
470
471 switch (BT) {
473 DeclName = DeclarationName(
474 &Context.Idents.get("__is_typed_resource_element_compatible"));
475 ConstraintExpr = constructTypedBufferConstraintExpr(S, DeclLoc, T);
476 break;
478 DeclName = DeclarationName(
479 &Context.Idents.get("__is_structured_resource_element_compatible"));
480 ConstraintExpr = constructStructuredBufferConstraintExpr(S, DeclLoc, T);
481 break;
483 DeclName = DeclarationName(
484 &Context.Idents.get("__is_constant_buffer_element_compatible"));
485 ConstraintExpr = constructConstantBufferConstraintExpr(S, DeclLoc, T);
486 break;
487 }
488
489 // Create a ConceptDecl
490 ConceptDecl *CD =
491 ConceptDecl::Create(Context, NSD->getDeclContext(), DeclLoc, DeclName,
492 ConceptParams, ConstraintExpr);
493
494 // Attach the template parameter list to the ConceptDecl
495 CD->setTemplateParameters(ConceptParams);
496
497 // Add the concept declaration to the Translation Unit Decl
498 NSD->getDeclContext()->addDecl(CD);
499
500 return CD;
501}
502
503void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
504 ASTContext &AST = SemaPtr->getASTContext();
505 CXXRecordDecl *Decl;
506 ConceptDecl *TypedBufferConcept = constructBufferConceptDecl(
507 *SemaPtr, HLSLNamespace, HLSLBufferType::Typed);
508 ConceptDecl *StructuredBufferConcept = constructBufferConceptDecl(
509 *SemaPtr, HLSLNamespace, HLSLBufferType::Structured);
510 ConceptDecl *ConstantBufferConcept = constructBufferConceptDecl(
511 *SemaPtr, HLSLNamespace, HLSLBufferType::Constant);
512
513 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ConstantBuffer")
514 .addSimpleTemplateParams({"element_type"}, ConstantBufferConcept)
515 .finalizeForwardDeclaration();
516
517 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
518 setupBufferType(Decl, *SemaPtr, ResourceClass::CBuffer, /*IsROV=*/false,
519 /*RawBuffer=*/false, /*HasCounter=*/false)
522 });
523
524 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "Buffer")
525 .addSimpleTemplateParams({"element_type"}, TypedBufferConcept)
526 .finalizeForwardDeclaration();
527
528 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
529 setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
530 /*RawBuffer=*/false, /*HasCounter=*/false)
535 });
536
537 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer")
538 .addSimpleTemplateParams({"element_type"}, TypedBufferConcept)
539 .finalizeForwardDeclaration();
540
541 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
542 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
543 /*RawBuffer=*/false, /*HasCounter=*/false)
548 });
549
550 Decl =
551 BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RasterizerOrderedBuffer")
552 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
553 .finalizeForwardDeclaration();
554 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
555 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
556 /*RawBuffer=*/false, /*HasCounter=*/false)
561 });
562
563 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "StructuredBuffer")
564 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
565 .finalizeForwardDeclaration();
566 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
567 setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
568 /*RawBuffer=*/true, /*HasCounter=*/false)
573 });
574
575 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWStructuredBuffer")
576 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
577 .finalizeForwardDeclaration();
578 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
579 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
580 /*RawBuffer=*/true, /*HasCounter=*/true)
587 });
588
589 Decl =
590 BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "AppendStructuredBuffer")
591 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
592 .finalizeForwardDeclaration();
593 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
594 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
595 /*RawBuffer=*/true, /*HasCounter=*/true)
599 });
600
601 Decl =
602 BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ConsumeStructuredBuffer")
603 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
604 .finalizeForwardDeclaration();
605 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
606 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
607 /*RawBuffer=*/true, /*HasCounter=*/true)
611 });
612
613 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
614 "RasterizerOrderedStructuredBuffer")
615 .addSimpleTemplateParams({"element_type"}, StructuredBufferConcept)
616 .finalizeForwardDeclaration();
617 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
618 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
619 /*RawBuffer=*/true, /*HasCounter=*/true)
626 });
627
628 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ByteAddressBuffer")
629 .finalizeForwardDeclaration();
630 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
631 setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
632 /*RawBuffer=*/true, /*HasCounter=*/false)
636 });
637 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWByteAddressBuffer")
638 .finalizeForwardDeclaration();
639 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
640 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
641 /*RawBuffer=*/true, /*HasCounter=*/false)
646 });
647 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
648 "RasterizerOrderedByteAddressBuffer")
649 .finalizeForwardDeclaration();
650 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
651 setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
652 /*RawBuffer=*/true, /*HasCounter=*/false)
655 });
656
657 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "SamplerState")
658 .finalizeForwardDeclaration();
659 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
660 setupSamplerType(Decl, *SemaPtr).completeDefinition();
661 });
662
663 Decl =
664 BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "SamplerComparisonState")
665 .finalizeForwardDeclaration();
666 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
667 setupSamplerType(Decl, *SemaPtr).completeDefinition();
668 });
669
670 QualType Float4Ty = AST.getExtVectorType(AST.FloatTy, 4);
671 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "Texture2D")
672 .addSimpleTemplateParams({"element_type"}, {Float4Ty},
673 TypedBufferConcept)
674 .finalizeForwardDeclaration();
675
676 onCompletion(Decl, [this](CXXRecordDecl *Decl) {
677 setupTextureType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
678 ResourceDimension::Dim2D)
680 });
681
682 auto *PartialSpec = addVectorTexturePartialSpecialization(
683 *SemaPtr, HLSLNamespace, Decl->getDescribedClassTemplate());
684 onCompletion(PartialSpec, [this](CXXRecordDecl *Decl) {
685 setupTextureType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
686 ResourceDimension::Dim2D)
688 });
689}
690
691void HLSLExternalSemaSource::onCompletion(CXXRecordDecl *Record,
692 CompletionFunction Fn) {
693 if (!Record->isCompleteDefinition())
694 Completions.insert(std::make_pair(Record->getCanonicalDecl(), Fn));
695}
696
698 if (!isa<CXXRecordDecl>(Tag))
699 return;
700 auto Record = cast<CXXRecordDecl>(Tag);
701
702 // If this is a specialization, we need to get the underlying templated
703 // declaration and complete that.
704 if (auto TDecl = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
706 ClassTemplateDecl *Template = TDecl->getSpecializedTemplate();
708 Template->getPartialSpecializations(Partials);
709 ClassTemplatePartialSpecializationDecl *MatchedPartial = nullptr;
710 for (auto *Partial : Partials) {
711 sema::TemplateDeductionInfo Info(TDecl->getLocation());
712 if (SemaPtr->DeduceTemplateArguments(Partial, TDecl->getTemplateArgs(),
713 Info) ==
715 MatchedPartial = Partial;
716 break;
717 }
718 }
719 if (MatchedPartial)
720 Record = MatchedPartial;
721 else
722 Record = Template->getTemplatedDecl();
723 }
724 }
725 Record = Record->getCanonicalDecl();
726 auto It = Completions.find(Record);
727 if (It == Completions.end())
728 return;
729 It->second(Record);
730 Completions.erase(It);
731}
Defines the clang::ASTContext interface.
llvm::dxil::ResourceClass ResourceClass
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, ResourceClass RC, bool IsROV, bool RawBuffer, bool HasCounter)
Set up common members and attributes for buffer types.
static BuiltinTypeDeclBuilder setupSamplerType(CXXRecordDecl *Decl, Sema &S)
Set up common members and attributes for sampler types.
static Expr * constructTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc, TemplateTypeParmDecl *T)
static ConceptDecl * constructBufferConceptDecl(Sema &S, NamespaceDecl *NSD, HLSLBufferType BT)
static BuiltinTypeDeclBuilder setupTextureType(CXXRecordDecl *Decl, Sema &S, ResourceClass RC, bool IsROV, ResourceDimension Dim)
Set up common members and attributes for texture types.
static Expr * constructConstantBufferConstraintExpr(Sema &S, SourceLocation NameLoc, TemplateTypeParmDecl *T)
static ClassTemplatePartialSpecializationDecl * addVectorTexturePartialSpecialization(Sema &S, NamespaceDecl *HLSLNamespace, ClassTemplateDecl *TextureTemplate)
static Expr * constructStructuredBufferConstraintExpr(Sema &S, SourceLocation NameLoc, TemplateTypeParmDecl *T)
llvm::MachO::Record Record
Definition MachO.h:31
This file declares semantic analysis for HLSL constructs.
Defines the clang::SourceLocation class and associated facilities.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:227
TranslationUnitDecl * getTranslationUnitDecl() const
QualType getDependentSizedMatrixType(QualType ElementType, Expr *RowExpr, Expr *ColumnExpr, SourceLocation AttrLoc) const
Return the unique reference to the matrix type of the specified element type and size.
unsigned getIntWidth(QualType T) const
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CanQualType FloatTy
IdentifierTable & Idents
Definition ASTContext.h:805
CanQualType BoolTy
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType IntTy
QualType getTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T, ArrayRef< TemplateArgument > SpecifiedArgs, ArrayRef< TemplateArgument > CanonicalArgs, QualType Underlying=QualType()) const
QualType getTemplateTypeParmType(int Depth, int Index, bool ParameterPack, TemplateTypeParmDecl *ParmDecl=nullptr) const
Retrieve the template type parameter type for a template parameter or parameter pack with the given d...
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
QualType getDependentSizedExtVectorType(QualType VectorType, Expr *SizeExpr, SourceLocation AttrLoc) const
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4041
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
Definition Expr.cpp:5102
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
static CanQual< Type > CreateUnsafe(QualType Other)
Declaration of a class template.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, CanQualType CanonInjectedTST, ClassTemplatePartialSpecializationDecl *PrevDecl)
Declaration of a C++20 concept.
static ConceptDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr=nullptr)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
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...
Definition DeclBase.h:2701
decl_iterator decls_begin() const
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)
Definition Expr.cpp:493
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
DeclContext * getDeclContext()
Definition DeclBase.h:456
The name of a declaration.
This represents one expression.
Definition Expr.h:112
Represents difference between two FPOptions values.
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 ...
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 IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Definition Expr.cpp:980
Represents the results of name lookup.
Definition Lookup.h:147
Represent a C++ namespace.
Definition Decl.h:592
static NamespaceDecl * Create(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested)
Definition DeclCXX.cpp:3366
A C++ nested-name-specifier augmented with source location information.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
A (possibly-)qualified type.
Definition TypeBase.h:937
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
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.
@ LookupNamespaceName
Look up a namespace name within a C++ using directive or namespace alias definition,...
Definition Sema.h:9440
ASTContext & getASTContext() const
Definition Sema.h:939
const LangOptions & getLangOpts() const
Definition Sema.h:932
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Encodes a location in the source.
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3735
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
Location wrapper for a TemplateArgument.
Represents a template argument.
void setTemplateParameters(TemplateParameterList *TParams)
Represents a C++ template name within the type system.
Stores a list of template parameters for a TemplateDecl and its derived classes.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Declaration of a template type parameter.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, int D, int P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
static TypeAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
Definition Decl.cpp:5817
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
A container of type source information.
Definition TypeBase.h:8416
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition ExprCXX.h:2900
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.
Definition ExprCXX.cpp:1919
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2628
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2247
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Definition Expr.cpp:5159
Represents a C++ using-declaration.
Definition DeclCXX.h:3596
static UsingDirectiveDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceLocation NamespaceLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor)
Definition DeclCXX.cpp:3322
Represents a GCC generic vector type.
Definition TypeBase.h:4237
BuiltinTypeDeclBuilder & addDefaultHandleConstructor(AccessSpecifier Access=AccessSpecifier::AS_public)
BuiltinTypeDeclBuilder & addCopyAssignmentOperator(AccessSpecifier Access=AccessSpecifier::AS_public)
BuiltinTypeDeclBuilder & addArraySubscriptOperators(ResourceDimension Dim=ResourceDimension::Unknown)
BuiltinTypeDeclBuilder & addSampleGradMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addGetDimensionsMethodForBuffer()
BuiltinTypeDeclBuilder & addGatherCmpMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addConstantBufferConversionToType()
BuiltinTypeDeclBuilder & addSampleBiasMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addBufferHandles(ResourceClass RC, bool IsROV, bool RawBuffer, bool HasCounter, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addByteAddressBufferStoreMethods()
BuiltinTypeDeclBuilder & addTextureHandle(ResourceClass RC, bool IsROV, ResourceDimension RD, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addCopyConstructor(AccessSpecifier Access=AccessSpecifier::AS_public)
BuiltinTypeDeclBuilder & addTextureLoadMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addSampleLevelMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addMipsMember(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addByteAddressBufferLoadMethods()
BuiltinTypeDeclBuilder & addSampleMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addStaticInitializationFunctions(bool HasCounter)
BuiltinTypeDeclBuilder & addCalculateLodMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addGetDimensionsMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addSampleCmpLevelZeroMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addGatherMethods(ResourceDimension Dim)
BuiltinTypeDeclBuilder & addSampleCmpMethods(ResourceDimension Dim)
Provides information about an attempted template argument deduction, whose success or failure was des...
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition Specifiers.h:152
@ Result
The result type of a method or function.
Definition TypeBase.h:905
@ Template
We are parsing a template declaration.
Definition Parser.h:81
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition Specifiers.h:136
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition Specifiers.h:140
@ Success
Template argument deduction was successful.
Definition Sema.h:371
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5979
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...