clang 22.0.0git
HLSLBuiltinTypeDeclBuilder.cpp
Go to the documentation of this file.
1//===--- HLSLBuiltinTypeDeclBuilder.cpp - HLSL Builtin Type Decl Builder --===//
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// Helper classes for creating HLSL builtin class types. Used by external HLSL
10// sema source.
11//
12//===----------------------------------------------------------------------===//
13
16#include "clang/AST/Attr.h"
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/Stmt.h"
21#include "clang/AST/Type.h"
24#include "clang/Sema/Lookup.h"
25#include "clang/Sema/Sema.h"
26#include "clang/Sema/SemaHLSL.h"
27#include "llvm/ADT/SmallVector.h"
28
29using namespace llvm::hlsl;
30
31namespace clang {
32
33namespace hlsl {
34
35namespace {
36
37static FunctionDecl *lookupBuiltinFunction(Sema &S, StringRef Name) {
38 IdentifierInfo &II =
39 S.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
40 DeclarationNameInfo NameInfo =
41 DeclarationNameInfo(DeclarationName(&II), SourceLocation());
42 LookupResult R(S, NameInfo, Sema::LookupOrdinaryName);
43 // AllowBuiltinCreation is false but LookupDirect will create
44 // the builtin when searching the global scope anyways...
45 S.LookupName(R, S.getCurScope());
46 // FIXME: If the builtin function was user-declared in global scope,
47 // this assert *will* fail. Should this call LookupBuiltin instead?
48 assert(R.isSingleResult() &&
49 "Since this is a builtin it should always resolve!");
50 return cast<FunctionDecl>(R.getFoundDecl());
51}
52
53CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
54 assert(ResTy->isRecordType() && "not a CXXRecord type");
55 for (auto *CD : ResTy->getAsCXXRecordDecl()->ctors())
56 if (CD->isCopyConstructor())
57 return CD;
58 return nullptr;
59}
60} // namespace
61
62// Builder for template arguments of builtin types. Used internally
63// by BuiltinTypeDeclBuilder.
79
80// Builder for methods or constructors of builtin types. Allows creating methods
81// or constructors of builtin types using the builder pattern like this:
82//
83// BuiltinTypeMethodBuilder(RecordBuilder, "MethodName", ReturnType)
84// .addParam("param_name", Type, InOutModifier)
85// .callBuiltin("builtin_name", BuiltinParams...)
86// .finalize();
87//
88// The builder needs to have all of the parameters before it can create
89// a CXXMethodDecl or CXXConstructorDecl. It collects them in addParam calls and
90// when a first method that builds the body is called or when access to 'this`
91// is needed it creates the CXXMethodDecl/CXXConstructorDecl and ParmVarDecls
92// instances. These can then be referenced from the body building methods.
93// Destructor or an explicit call to finalize() will complete the method
94// definition.
95//
96// The callBuiltin helper method accepts constants via `Expr *` or placeholder
97// value arguments to indicate which function arguments to forward to the
98// builtin.
99//
100// If the method that is being built has a non-void return type the
101// finalize() will create a return statement with the value of the last
102// statement (unless the last statement is already a ReturnStmt or the return
103// value is void).
105private:
106 struct Param {
107 const IdentifierInfo &NameII;
108 QualType Ty;
109 HLSLParamModifierAttr::Spelling Modifier;
110 Param(const IdentifierInfo &NameII, QualType Ty,
111 HLSLParamModifierAttr::Spelling Modifier)
112 : NameII(NameII), Ty(Ty), Modifier(Modifier) {}
113 };
114
115 struct LocalVar {
116 StringRef Name;
117 QualType Ty;
118 VarDecl *Decl;
119 LocalVar(StringRef Name, QualType Ty) : Name(Name), Ty(Ty), Decl(nullptr) {}
120 };
121
122 BuiltinTypeDeclBuilder &DeclBuilder;
123 DeclarationName Name;
124 QualType ReturnTy;
125 // method or constructor declaration
126 // (CXXConstructorDecl derives from CXXMethodDecl)
127 CXXMethodDecl *Method;
128 bool IsConst;
129 bool IsCtor;
130 StorageClass SC;
133
134 // Argument placeholders, inspired by std::placeholder. These are the indices
135 // of arguments to forward to `callBuiltin` and other method builder methods.
136 // Additional special values are:
137 // Handle - refers to the resource handle.
138 // LastStmt - refers to the last statement in the method body; referencing
139 // LastStmt will remove the statement from the method body since
140 // it will be linked from the new expression being constructed.
141 enum class PlaceHolder { _0, _1, _2, _3, _4, Handle = 128, LastStmt };
142
143 Expr *convertPlaceholder(PlaceHolder PH);
144 Expr *convertPlaceholder(LocalVar &Var);
145 Expr *convertPlaceholder(Expr *E) { return E; }
146
147public:
149
151 QualType ReturnTy, bool IsConst = false,
152 bool IsCtor = false, StorageClass SC = SC_None)
153 : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(nullptr),
154 IsConst(IsConst), IsCtor(IsCtor), SC(SC) {}
155
157 QualType ReturnTy, bool IsConst = false,
158 bool IsCtor = false, StorageClass SC = SC_None);
160
162
165
166 BuiltinTypeMethodBuilder &addParam(StringRef Name, QualType Ty,
167 HLSLParamModifierAttr::Spelling Modifier =
168 HLSLParamModifierAttr::Keyword_in);
170 template <typename... Ts>
171 BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName,
172 QualType ReturnType, Ts... ArgSpecs);
173 template <typename TLHS, typename TRHS>
174 BuiltinTypeMethodBuilder &assign(TLHS LHS, TRHS RHS);
175 template <typename T> BuiltinTypeMethodBuilder &dereference(T Ptr);
176 template <typename T>
178 template <typename ResourceT, typename ValueT>
179 BuiltinTypeMethodBuilder &setHandleFieldOnResource(ResourceT ResourceRecord,
180 ValueT HandleValue);
181 template <typename T> BuiltinTypeMethodBuilder &returnValue(T ReturnValue);
185
186private:
187 void createDecl();
188
189 // Makes sure the declaration is created; should be called before any
190 // statement added to the body or when access to 'this' is needed.
191 void ensureCompleteDecl() {
192 if (!Method)
193 createDecl();
194 }
195};
196
200
203 QualType DefaultValue) {
204 assert(!Builder.Record->isCompleteDefinition() &&
205 "record is already complete");
206 ASTContext &AST = Builder.SemaRef.getASTContext();
207 unsigned Position = static_cast<unsigned>(Params.size());
209 AST, Builder.Record->getDeclContext(), SourceLocation(), SourceLocation(),
210 /* TemplateDepth */ 0, Position,
211 &AST.Idents.get(Name, tok::TokenKind::identifier),
212 /* Typename */ true,
213 /* ParameterPack */ false,
214 /* HasTypeConstraint*/ false);
215 if (!DefaultValue.isNull())
216 Decl->setDefaultArgument(AST,
217 Builder.SemaRef.getTrivialTemplateArgumentLoc(
218 DefaultValue, QualType(), SourceLocation()));
219
220 Params.emplace_back(Decl);
221 return *this;
222}
223
224// The concept specialization expression (CSE) constructed in
225// constructConceptSpecializationExpr is constructed so that it
226// matches the CSE that is constructed when parsing the below C++ code:
227//
228// template<typename T>
229// concept is_typed_resource_element_compatible =
230// __builtin_hlsl_typed_resource_element_compatible<T>
231//
232// template<typename element_type> requires
233// is_typed_resource_element_compatible<element_type>
234// struct RWBuffer {
235// element_type Val;
236// };
237//
238// int fn() {
239// RWBuffer<int> Buf;
240// }
241//
242// When dumping the AST and filtering for "RWBuffer", the resulting AST
243// structure is what we're trying to construct below, specifically the
244// CSE portion.
247 Sema &S, ConceptDecl *CD) {
248 ASTContext &Context = S.getASTContext();
249 SourceLocation Loc = Builder.Record->getBeginLoc();
250 DeclarationNameInfo DNI(CD->getDeclName(), Loc);
252 DeclContext *DC = Builder.Record->getDeclContext();
253 TemplateArgumentListInfo TALI(Loc, Loc);
254
255 // Assume that the concept decl has just one template parameter
256 // This parameter should have been added when CD was constructed
257 // in getTypedBufferConceptDecl
258 assert(CD->getTemplateParameters()->size() == 1 &&
259 "unexpected concept decl parameter count");
260 TemplateTypeParmDecl *ConceptTTPD =
261 dyn_cast<TemplateTypeParmDecl>(CD->getTemplateParameters()->getParam(0));
262
263 // this TemplateTypeParmDecl is the template for the resource, and is
264 // used to construct a template argumentthat will be used
265 // to construct the ImplicitConceptSpecializationDecl
267 Context, // AST context
268 Builder.Record->getDeclContext(), // DeclContext
270 /*D=*/0, // Depth in the template parameter list
271 /*P=*/0, // Position in the template parameter list
272 /*Id=*/nullptr, // Identifier for 'T'
273 /*Typename=*/true, // Indicates this is a 'typename' or 'class'
274 /*ParameterPack=*/false, // Not a parameter pack
275 /*HasTypeConstraint=*/false // Has no type constraint
276 );
277
278 T->setDeclContext(DC);
279
280 QualType ConceptTType = Context.getTypeDeclType(ConceptTTPD);
281
282 // this is the 2nd template argument node, on which
283 // the concept constraint is actually being applied: 'element_type'
284 TemplateArgument ConceptTA = TemplateArgument(ConceptTType);
285
286 QualType CSETType = Context.getTypeDeclType(T);
287
288 // this is the 1st template argument node, which represents
289 // the abstract type that a concept would refer to: 'T'
290 TemplateArgument CSETA = TemplateArgument(CSETType);
291
292 ImplicitConceptSpecializationDecl *ImplicitCSEDecl =
294 Context, Builder.Record->getDeclContext(), Loc, {CSETA});
295
296 // Constraint satisfaction is used to construct the
297 // ConceptSpecailizationExpr, and represents the 2nd Template Argument,
298 // located at the bottom of the sample AST above.
299 const ConstraintSatisfaction CS(CD, {ConceptTA});
302
303 TALI.addArgument(TAL);
304 const ASTTemplateArgumentListInfo *ATALI =
306
307 // In the concept reference, ATALI is what adds the extra
308 // TemplateArgument node underneath CSE
309 ConceptReference *CR =
310 ConceptReference::Create(Context, NNSLoc, Loc, DNI, CD, CD, ATALI);
311
313 ConceptSpecializationExpr::Create(Context, CR, ImplicitCSEDecl, &CS);
314
315 return CSE;
316}
317
320 if (Params.empty())
321 return Builder;
322
323 ASTContext &AST = Builder.SemaRef.Context;
325 CD ? constructConceptSpecializationExpr(Builder.SemaRef, CD) : nullptr;
326 auto *ParamList = TemplateParameterList::Create(
329 AST, Builder.Record->getDeclContext(), SourceLocation(),
330 DeclarationName(Builder.Record->getIdentifier()), ParamList,
331 Builder.Record);
332
333 Builder.Record->setDescribedClassTemplate(Builder.Template);
334 Builder.Template->setImplicit(true);
335 Builder.Template->setLexicalDeclContext(Builder.Record->getDeclContext());
336
337 // NOTE: setPreviousDecl before addDecl so new decl replace old decl when
338 // make visible.
339 Builder.Template->setPreviousDecl(Builder.PrevTemplate);
340 Builder.Record->getDeclContext()->addDecl(Builder.Template);
341 Params.clear();
342
343 return Builder;
344}
345
346Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) {
347 if (PH == PlaceHolder::Handle)
348 return getResourceHandleExpr();
349
350 if (PH == PlaceHolder::LastStmt) {
351 assert(!StmtsList.empty() && "no statements in the list");
352 Stmt *LastStmt = StmtsList.pop_back_val();
353 assert(isa<ValueStmt>(LastStmt) && "last statement does not have a value");
354 return cast<ValueStmt>(LastStmt)->getExprStmt();
355 }
356
357 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
358 ParmVarDecl *ParamDecl = Method->getParamDecl(static_cast<unsigned>(PH));
359 return DeclRefExpr::Create(
360 AST, NestedNameSpecifierLoc(), SourceLocation(), ParamDecl, false,
362 ParamDecl->getType().getNonReferenceType(), VK_PRValue);
363}
364
365Expr *BuiltinTypeMethodBuilder::convertPlaceholder(LocalVar &Var) {
366 VarDecl *VD = Var.Decl;
367 assert(VD && "local variable is not declared");
368 return DeclRefExpr::Create(
369 VD->getASTContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
370 false, DeclarationNameInfo(VD->getDeclName(), SourceLocation()),
371 VD->getType(), VK_LValue);
372}
373
375 StringRef NameStr,
376 QualType ReturnTy,
377 bool IsConst, bool IsCtor,
378 StorageClass SC)
379 : DeclBuilder(DB), ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst),
380 IsCtor(IsCtor), SC(SC) {
381
382 assert((!NameStr.empty() || IsCtor) && "method needs a name");
383 assert(((IsCtor && !IsConst) || !IsCtor) && "constructor cannot be const");
384
385 ASTContext &AST = DB.SemaRef.getASTContext();
386 if (IsCtor) {
388 AST.getCanonicalTagType(DB.Record));
389 } else {
390 const IdentifierInfo &II =
391 AST.Idents.get(NameStr, tok::TokenKind::identifier);
392 Name = DeclarationName(&II);
393 }
394}
395
398 HLSLParamModifierAttr::Spelling Modifier) {
399 assert(Method == nullptr && "Cannot add param, method already created");
400 const IdentifierInfo &II = DeclBuilder.SemaRef.getASTContext().Idents.get(
401 Name, tok::TokenKind::identifier);
402 Params.emplace_back(II, Ty, Modifier);
403 return *this;
404}
405
406void BuiltinTypeMethodBuilder::createDecl() {
407 assert(Method == nullptr && "Method or constructor is already created");
408
409 // create method or constructor type
410 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
411 SmallVector<QualType> ParamTypes;
412 for (Param &MP : Params)
413 ParamTypes.emplace_back(MP.Ty);
414
416 if (IsConst)
417 ExtInfo.TypeQuals.addConst();
418
419 QualType FuncTy = AST.getFunctionType(ReturnTy, ParamTypes, ExtInfo);
420
421 // create method or constructor decl
422 auto *TSInfo = AST.getTrivialTypeSourceInfo(FuncTy, SourceLocation());
424 if (IsCtor)
426 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo,
427 ExplicitSpecifier(), false, true, false,
429 else
431 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo, SC,
433
434 // create params & set them to the function prototype
436 unsigned CurScopeDepth = DeclBuilder.SemaRef.getCurScope()->getDepth();
437 auto FnProtoLoc =
438 Method->getTypeSourceInfo()->getTypeLoc().getAs<FunctionProtoTypeLoc>();
439 for (int I = 0, E = Params.size(); I != E; I++) {
440 Param &MP = Params[I];
442 AST, Method->getDeclContext(), SourceLocation(), SourceLocation(),
443 &MP.NameII, MP.Ty,
445 nullptr);
446 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
447 auto *Mod =
448 HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
449 Parm->addAttr(Mod);
450 }
451 Parm->setScopeInfo(CurScopeDepth, I);
452 ParmDecls.push_back(Parm);
453 FnProtoLoc.setParam(I, Parm);
454 }
455 Method->setParams({ParmDecls});
456}
457
459 ensureCompleteDecl();
460
461 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
463 AST, SourceLocation(), Method->getFunctionObjectParameterType(), true);
464 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
465 return MemberExpr::CreateImplicit(AST, This, false, HandleField,
466 HandleField->getType(), VK_LValue,
468}
469
472 ensureCompleteDecl();
473
474 assert(Var.Decl == nullptr && "local variable is already declared");
475
476 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
477 Var.Decl = VarDecl::Create(
478 AST, Method, SourceLocation(), SourceLocation(),
479 &AST.Idents.get(Var.Name, tok::TokenKind::identifier), Var.Ty,
481 DeclStmt *DS = new (AST) clang::DeclStmt(DeclGroupRef(Var.Decl),
483 StmtsList.push_back(DS);
484 return *this;
485}
486
488 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
490 AST, SourceLocation(), Method->getFunctionObjectParameterType(),
491 /*IsImplicit=*/true);
492 StmtsList.push_back(ThisExpr);
493 return *this;
494}
495
496template <typename... Ts>
499 QualType ReturnType, Ts... ArgSpecs) {
500 ensureCompleteDecl();
501
502 std::array<Expr *, sizeof...(ArgSpecs)> Args{
503 convertPlaceholder(std::forward<Ts>(ArgSpecs))...};
504
505 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
506 FunctionDecl *FD = lookupBuiltinFunction(DeclBuilder.SemaRef, BuiltinName);
508 AST, NestedNameSpecifierLoc(), SourceLocation(), FD, false,
510
511 auto *ImpCast = ImplicitCastExpr::Create(
512 AST, AST.getPointerType(FD->getType()), CK_BuiltinFnToFnPtr, DRE, nullptr,
514
515 if (ReturnType.isNull())
516 ReturnType = FD->getReturnType();
517
518 Expr *Call = CallExpr::Create(AST, ImpCast, Args, ReturnType, VK_PRValue,
520 StmtsList.push_back(Call);
521 return *this;
522}
523
524template <typename TLHS, typename TRHS>
526 Expr *LHSExpr = convertPlaceholder(LHS);
527 Expr *RHSExpr = convertPlaceholder(RHS);
528 Stmt *AssignStmt = BinaryOperator::Create(
529 DeclBuilder.SemaRef.getASTContext(), LHSExpr, RHSExpr, BO_Assign,
532 StmtsList.push_back(AssignStmt);
533 return *this;
534}
535
536template <typename T>
538 Expr *PtrExpr = convertPlaceholder(Ptr);
539 Expr *Deref =
540 UnaryOperator::Create(DeclBuilder.SemaRef.getASTContext(), PtrExpr,
541 UO_Deref, PtrExpr->getType()->getPointeeType(),
543 /*CanOverflow=*/false, FPOptionsOverride());
544 StmtsList.push_back(Deref);
545 return *this;
546}
547
548template <typename T>
551 ensureCompleteDecl();
552
553 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
554
555 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
556 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
558 AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue,
560 StmtsList.push_back(HandleExpr);
561 return *this;
562}
563
564template <typename ResourceT, typename ValueT>
567 ValueT HandleValue) {
568 ensureCompleteDecl();
569
570 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
571 Expr *HandleValueExpr = convertPlaceholder(HandleValue);
572
573 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
574 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
575 MemberExpr *HandleMemberExpr = MemberExpr::CreateImplicit(
576 AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue,
578 Stmt *AssignStmt = BinaryOperator::Create(
579 DeclBuilder.SemaRef.getASTContext(), HandleMemberExpr, HandleValueExpr,
580 BO_Assign, HandleMemberExpr->getType(), ExprValueKind::VK_PRValue,
582 StmtsList.push_back(AssignStmt);
583 return *this;
584}
585
586template <typename T>
588 ensureCompleteDecl();
589
590 Expr *ReturnValueExpr = convertPlaceholder(ReturnValue);
591 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
592
593 QualType Ty = ReturnValueExpr->getType();
594 if (Ty->isRecordType()) {
595 // For record types, create a call to copy constructor to ensure proper copy
596 // semantics.
597 auto *ICE =
598 ImplicitCastExpr::Create(AST, Ty.withConst(), CK_NoOp, ReturnValueExpr,
599 nullptr, VK_XValue, FPOptionsOverride());
600 CXXConstructorDecl *CD = lookupCopyConstructor(Ty);
601 assert(CD && "no copy constructor found");
602 ReturnValueExpr = CXXConstructExpr::Create(
603 AST, Ty, SourceLocation(), CD, /*Elidable=*/false, {ICE},
604 /*HadMultipleCandidates=*/false, /*ListInitialization=*/false,
605 /*StdInitListInitialization=*/false,
606 /*ZeroInitListInitialization=*/false, CXXConstructionKind::Complete,
607 SourceRange());
608 }
609 StmtsList.push_back(
610 ReturnStmt::Create(AST, SourceLocation(), ReturnValueExpr, nullptr));
611 return *this;
612}
613
615 assert(!DeclBuilder.Record->isCompleteDefinition() &&
616 "record is already complete");
617
618 ensureCompleteDecl();
619
620 if (!Method->hasBody()) {
621 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
622 assert((ReturnTy == AST.VoidTy || !StmtsList.empty()) &&
623 "nothing to return from non-void method");
624 if (ReturnTy != AST.VoidTy) {
625 if (Expr *LastExpr = dyn_cast<Expr>(StmtsList.back())) {
626 assert(AST.hasSameUnqualifiedType(LastExpr->getType(),
627 ReturnTy.getNonReferenceType()) &&
628 "Return type of the last statement must match the return type "
629 "of the method");
630 if (!isa<ReturnStmt>(LastExpr)) {
631 StmtsList.pop_back();
632 StmtsList.push_back(
633 ReturnStmt::Create(AST, SourceLocation(), LastExpr, nullptr));
634 }
635 }
636 }
637
638 Method->setBody(CompoundStmt::Create(AST, StmtsList, FPOptionsOverride(),
640 Method->setLexicalDeclContext(DeclBuilder.Record);
641 Method->setAccess(AS_public);
642 Method->addAttr(AlwaysInlineAttr::CreateImplicit(
643 AST, SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
644 DeclBuilder.Record->addDecl(Method);
645 }
646 return DeclBuilder;
647}
648
650 : SemaRef(SemaRef), Record(R) {
651 Record->startDefinition();
652 Template = Record->getDescribedClassTemplate();
653}
654
656 NamespaceDecl *Namespace,
657 StringRef Name)
658 : SemaRef(SemaRef), HLSLNamespace(Namespace) {
659 ASTContext &AST = SemaRef.getASTContext();
660 IdentifierInfo &II = AST.Idents.get(Name, tok::TokenKind::identifier);
661
663 CXXRecordDecl *PrevDecl = nullptr;
664 if (SemaRef.LookupQualifiedName(Result, HLSLNamespace)) {
665 // Declaration already exists (from precompiled headers)
666 NamedDecl *Found = Result.getFoundDecl();
667 if (auto *TD = dyn_cast<ClassTemplateDecl>(Found)) {
668 PrevDecl = TD->getTemplatedDecl();
669 PrevTemplate = TD;
670 } else
671 PrevDecl = dyn_cast<CXXRecordDecl>(Found);
672 assert(PrevDecl && "Unexpected lookup result type.");
673 }
674
675 if (PrevDecl && PrevDecl->isCompleteDefinition()) {
676 Record = PrevDecl;
677 Template = PrevTemplate;
678 return;
679 }
680
681 Record =
682 CXXRecordDecl::Create(AST, TagDecl::TagKind::Class, HLSLNamespace,
683 SourceLocation(), SourceLocation(), &II, PrevDecl);
684 Record->setImplicit(true);
685 Record->setLexicalDeclContext(HLSLNamespace);
686 Record->setHasExternalLexicalStorage();
687
688 // Don't let anyone derive from built-in types.
689 Record->addAttr(
690 FinalAttr::CreateImplicit(AST, SourceRange(), FinalAttr::Keyword_final));
691}
692
694 if (HLSLNamespace && !Template && Record->getDeclContext() == HLSLNamespace)
695 HLSLNamespace->addDecl(Record);
696}
697
701 AccessSpecifier Access) {
702 assert(!Record->isCompleteDefinition() && "record is already complete");
703 assert(Record->isBeingDefined() &&
704 "Definition must be started before adding members!");
705 ASTContext &AST = Record->getASTContext();
706
707 IdentifierInfo &II = AST.Idents.get(Name, tok::TokenKind::identifier);
708 TypeSourceInfo *MemTySource =
710 auto *Field = FieldDecl::Create(
711 AST, Record, SourceLocation(), SourceLocation(), &II, Type, MemTySource,
712 nullptr, false, InClassInitStyle::ICIS_NoInit);
713 Field->setAccess(Access);
714 Field->setImplicit(true);
715 for (Attr *A : Attrs) {
716 if (A)
717 Field->addAttr(A);
718 }
719
720 Record->addDecl(Field);
721 Fields[Name] = Field;
722 return *this;
723}
724
726 ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
727 assert(!Record->isCompleteDefinition() && "record is already complete");
728
729 ASTContext &Ctx = SemaRef.getASTContext();
730 TypeSourceInfo *ElementTypeInfo =
731 Ctx.getTrivialTypeSourceInfo(getHandleElementType(), SourceLocation());
732
733 // add handle member with resource type attributes
734 QualType AttributedResTy = QualType();
736 HLSLResourceClassAttr::CreateImplicit(Ctx, RC),
737 IsROV ? HLSLROVAttr::CreateImplicit(Ctx) : nullptr,
738 RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) : nullptr,
739 ElementTypeInfo
740 ? HLSLContainedTypeAttr::CreateImplicit(Ctx, ElementTypeInfo)
741 : nullptr};
742 if (CreateHLSLAttributedResourceType(SemaRef, Ctx.HLSLResourceTy, Attrs,
743 AttributedResTy))
744 addMemberVariable("__handle", AttributedResTy, {}, Access);
745 return *this;
746}
747
748// Adds default constructor to the resource class:
749// Resource::Resource()
751 assert(!Record->isCompleteDefinition() && "record is already complete");
752
753 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
754 QualType HandleType = getResourceHandleField()->getType();
755 return BuiltinTypeMethodBuilder(*this, "", SemaRef.getASTContext().VoidTy,
756 false, true)
757 .callBuiltin("__builtin_hlsl_resource_uninitializedhandle", HandleType,
758 PH::Handle)
759 .assign(PH::Handle, PH::LastStmt)
760 .finalize();
761}
762
763// Adds static method that initializes resource from binding:
764//
765// static Resource<T> __createFromBinding(unsigned registerNo,
766// unsigned spaceNo, int range,
767// unsigned index, const char *name) {
768// Resource<T> tmp;
769// tmp.__handle = __builtin_hlsl_resource_handlefrombinding(
770// tmp.__handle, registerNo, spaceNo,
771// range, index, name);
772// return tmp;
773// }
775 assert(!Record->isCompleteDefinition() && "record is already complete");
776
777 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
778 ASTContext &AST = SemaRef.getASTContext();
779 QualType HandleType = getResourceHandleField()->getType();
780 QualType RecordType = AST.getTypeDeclType(cast<TypeDecl>(Record));
781 BuiltinTypeMethodBuilder::LocalVar TmpVar("tmp", RecordType);
782
783 return BuiltinTypeMethodBuilder(*this, "__createFromBinding", RecordType,
784 false, false, SC_Static)
785 .addParam("registerNo", AST.UnsignedIntTy)
786 .addParam("spaceNo", AST.UnsignedIntTy)
787 .addParam("range", AST.IntTy)
788 .addParam("index", AST.UnsignedIntTy)
789 .addParam("name", AST.getPointerType(AST.CharTy.withConst()))
790 .declareLocalVar(TmpVar)
791 .accessHandleFieldOnResource(TmpVar)
792 .callBuiltin("__builtin_hlsl_resource_handlefrombinding", HandleType,
793 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
794 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
795 .returnValue(TmpVar)
796 .finalize();
797}
798
799// Adds static method that initializes resource from binding:
800//
801// static Resource<T> __createFromImplicitBinding(unsigned orderId,
802// unsigned spaceNo, int range,
803// unsigned index,
804// const char *name) {
805// Resource<T> tmp;
806// tmp.__handle = __builtin_hlsl_resource_handlefromimplicitbinding(
807// tmp.__handle, spaceNo,
808// range, index, orderId, name);
809// return tmp;
810// }
812 assert(!Record->isCompleteDefinition() && "record is already complete");
813
814 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
815 ASTContext &AST = SemaRef.getASTContext();
816 QualType HandleType = getResourceHandleField()->getType();
817 QualType RecordType = AST.getTypeDeclType(cast<TypeDecl>(Record));
818 BuiltinTypeMethodBuilder::LocalVar TmpVar("tmp", RecordType);
819
820 return BuiltinTypeMethodBuilder(*this, "__createFromImplicitBinding",
821 RecordType, false, false, SC_Static)
822 .addParam("orderId", AST.UnsignedIntTy)
823 .addParam("spaceNo", AST.UnsignedIntTy)
824 .addParam("range", AST.IntTy)
825 .addParam("index", AST.UnsignedIntTy)
826 .addParam("name", AST.getPointerType(AST.CharTy.withConst()))
827 .declareLocalVar(TmpVar)
828 .accessHandleFieldOnResource(TmpVar)
829 .callBuiltin("__builtin_hlsl_resource_handlefromimplicitbinding",
830 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
831 PH::_4)
832 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
833 .returnValue(TmpVar)
834 .finalize();
835}
836
838 assert(!Record->isCompleteDefinition() && "record is already complete");
839
840 ASTContext &AST = SemaRef.getASTContext();
841 QualType RecordType = AST.getCanonicalTagType(Record);
842 QualType ConstRecordType = RecordType.withConst();
843 QualType ConstRecordRefType = AST.getLValueReferenceType(ConstRecordType);
844
845 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
846
847 return BuiltinTypeMethodBuilder(*this, /*Name=*/"", AST.VoidTy,
848 /*IsConst=*/false, /*IsCtor=*/true)
849 .addParam("other", ConstRecordRefType)
850 .accessHandleFieldOnResource(PH::_0)
851 .assign(PH::Handle, PH::LastStmt)
852 .finalize();
853}
854
856 assert(!Record->isCompleteDefinition() && "record is already complete");
857
858 ASTContext &AST = SemaRef.getASTContext();
859 QualType RecordType = AST.getCanonicalTagType(Record);
860 QualType ConstRecordType = RecordType.withConst();
861 QualType ConstRecordRefType = AST.getLValueReferenceType(ConstRecordType);
862 QualType RecordRefType = AST.getLValueReferenceType(RecordType);
863
864 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
866 return BuiltinTypeMethodBuilder(*this, Name, RecordRefType)
867 .addParam("other", ConstRecordRefType)
868 .accessHandleFieldOnResource(PH::_0)
869 .assign(PH::Handle, PH::LastStmt)
870 .returnThis()
871 .finalize();
872}
873
875 ASTContext &AST = Record->getASTContext();
876 DeclarationName Subscript =
877 AST.DeclarationNames.getCXXOperatorName(OO_Subscript);
878
879 addHandleAccessFunction(Subscript, /*IsConst=*/true, /*IsRef=*/true);
880 if (getResourceAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV)
881 addHandleAccessFunction(Subscript, /*IsConst=*/false, /*IsRef=*/true);
882
883 return *this;
884}
885
887 assert(!Record->isCompleteDefinition() && "record is already complete");
888
889 ASTContext &AST = Record->getASTContext();
890 IdentifierInfo &II = AST.Idents.get("Load", tok::TokenKind::identifier);
891 DeclarationName Load(&II);
892 // TODO: We also need versions with status for CheckAccessFullyMapped.
893 addHandleAccessFunction(Load, /*IsConst=*/false, /*IsRef=*/false);
894
895 return *this;
896}
897
898FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() const {
899 auto I = Fields.find("__handle");
900 assert(I != Fields.end() &&
901 I->second->getType()->isHLSLAttributedResourceType() &&
902 "record does not have resource handle field");
903 return I->second;
904}
905
906QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam() {
907 assert(Template && "record it not a template");
908 if (const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
909 Template->getTemplateParameters()->getParam(0))) {
910 return QualType(TTD->getTypeForDecl(), 0);
911 }
912 return QualType();
913}
914
915QualType BuiltinTypeDeclBuilder::getHandleElementType() {
916 if (Template)
917 return getFirstTemplateTypeParam();
918 // TODO: Should we default to VoidTy? Using `i8` is arguably ambiguous.
919 return SemaRef.getASTContext().Char8Ty;
920}
921
922HLSLAttributedResourceType::Attributes
923BuiltinTypeDeclBuilder::getResourceAttrs() const {
924 QualType HandleType = getResourceHandleField()->getType();
925 return cast<HLSLAttributedResourceType>(HandleType)->getAttrs();
926}
927
929 assert(!Record->isCompleteDefinition() && "record is already complete");
930 assert(Record->isBeingDefined() &&
931 "Definition must be started before completing it.");
932
933 Record->completeDefinition();
934 return *this;
935}
936
937Expr *BuiltinTypeDeclBuilder::getConstantIntExpr(int value) {
938 ASTContext &AST = SemaRef.getASTContext();
940 AST, llvm::APInt(AST.getTypeSize(AST.IntTy), value, true), AST.IntTy,
942}
943
946 ConceptDecl *CD = nullptr) {
947 if (Record->isCompleteDefinition()) {
948 assert(Template && "existing record it not a template");
949 assert(Template->getTemplateParameters()->size() == Names.size() &&
950 "template param count mismatch");
951 return *this;
952 }
953
955 for (StringRef Name : Names)
956 Builder.addTypeParameter(Name);
957 return Builder.finalizeTemplateArgs(CD);
958}
959
961 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
962 return BuiltinTypeMethodBuilder(*this, "IncrementCounter",
963 SemaRef.getASTContext().UnsignedIntTy)
964 .callBuiltin("__builtin_hlsl_buffer_update_counter", QualType(),
965 PH::Handle, getConstantIntExpr(1))
966 .finalize();
967}
968
970 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
971 return BuiltinTypeMethodBuilder(*this, "DecrementCounter",
972 SemaRef.getASTContext().UnsignedIntTy)
973 .callBuiltin("__builtin_hlsl_buffer_update_counter", QualType(),
974 PH::Handle, getConstantIntExpr(-1))
975 .finalize();
976}
977
980 bool IsConst, bool IsRef) {
981 assert(!Record->isCompleteDefinition() && "record is already complete");
982 ASTContext &AST = SemaRef.getASTContext();
983 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
984
985 QualType ElemTy = getHandleElementType();
986 QualType AddrSpaceElemTy =
988 QualType ElemPtrTy = AST.getPointerType(AddrSpaceElemTy);
989 QualType ReturnTy;
990
991 if (IsRef) {
992 ReturnTy = AddrSpaceElemTy;
993 if (IsConst)
994 ReturnTy.addConst();
995 ReturnTy = AST.getLValueReferenceType(ReturnTy);
996 } else {
997 ReturnTy = ElemTy;
998 if (IsConst)
999 ReturnTy.addConst();
1000 }
1001
1002 return BuiltinTypeMethodBuilder(*this, Name, ReturnTy, IsConst)
1003 .addParam("Index", AST.UnsignedIntTy)
1004 .callBuiltin("__builtin_hlsl_resource_getpointer", ElemPtrTy, PH::Handle,
1005 PH::_0)
1006 .dereference(PH::LastStmt)
1007 .finalize();
1008}
1009
1011 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1012 ASTContext &AST = SemaRef.getASTContext();
1013 QualType ElemTy = getHandleElementType();
1014 QualType AddrSpaceElemTy =
1016 return BuiltinTypeMethodBuilder(*this, "Append", AST.VoidTy)
1017 .addParam("value", ElemTy)
1018 .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy,
1019 PH::Handle, getConstantIntExpr(1))
1020 .callBuiltin("__builtin_hlsl_resource_getpointer",
1021 AST.getPointerType(AddrSpaceElemTy), PH::Handle,
1022 PH::LastStmt)
1023 .dereference(PH::LastStmt)
1024 .assign(PH::LastStmt, PH::_0)
1025 .finalize();
1026}
1027
1029 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1030 ASTContext &AST = SemaRef.getASTContext();
1031 QualType ElemTy = getHandleElementType();
1032 QualType AddrSpaceElemTy =
1034 return BuiltinTypeMethodBuilder(*this, "Consume", ElemTy)
1035 .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy,
1036 PH::Handle, getConstantIntExpr(-1))
1037 .callBuiltin("__builtin_hlsl_resource_getpointer",
1038 AST.getPointerType(AddrSpaceElemTy), PH::Handle,
1039 PH::LastStmt)
1040 .dereference(PH::LastStmt)
1041 .finalize();
1042}
1043
1044} // namespace hlsl
1045} // namespace clang
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file declares semantic analysis for HLSL constructs.
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
C Language Family Type Representation.
a trap message and trap category.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:188
DeclarationNameTable DeclarationNames
Definition ASTContext.h:741
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.
IdentifierTable & Idents
Definition ASTContext.h:737
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType CharTy
CanQualType IntTy
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType BuiltinFnTy
CanQualType VoidTy
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 getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
Attr - This represents one attribute.
Definition Attr.h:44
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:4979
static CXXConstructExpr * Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor, bool Elidable, ArrayRef< Expr * > Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, bool ZeroInitialization, CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange)
Create a C++ construction expression.
Definition ExprCXX.cpp:1180
Represents a C++ constructor within a class.
Definition DeclCXX.h:2604
static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited=InheritedConstructor(), const AssociatedConstraint &TrailingRequiresClause={})
Definition DeclCXX.cpp:2968
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2129
static CXXMethodDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin, bool isInline, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, const AssociatedConstraint &TrailingRequiresClause={})
Definition DeclCXX.cpp:2488
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr)
Definition DeclCXX.cpp:132
Represents the this expression in C++.
Definition ExprCXX.h:1155
static CXXThisExpr * Create(const ASTContext &Ctx, SourceLocation L, QualType Ty, bool IsImplicit)
Definition ExprCXX.cpp:1585
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.
Definition Expr.cpp:1513
QualType withConst() const
Retrieves a version of this type with const applied.
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Definition Stmt.cpp:390
Declaration of a C++20 concept.
A reference to a concept and its template args, as it appears in the code.
Definition ASTConcept.h:126
static ConceptReference * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, TemplateDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten)
Represents the specialization of a concept - evaluates to a prvalue of type bool.
static ConceptSpecializationExpr * Create(const ASTContext &C, ConceptReference *ConceptRef, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction)
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition ASTConcept.h:37
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1449
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1270
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:484
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1611
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
void addAttr(Attr *A)
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
Get the name of the overloadable C++ operator corresponding to Op.
DeclarationName getCXXConstructorName(CanQualType Ty)
Returns the name of a C++ constructor for the given Type.
The name of a declaration.
Store information needed for an explicit specifier.
Definition DeclCXX.h:1924
This represents one expression.
Definition Expr.h:112
QualType getType() const
Definition Expr.h:144
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
Definition Decl.h:3157
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)
Definition Decl.cpp:4641
Represents a function declaration or definition.
Definition Decl.h:1999
QualType getReturnType() const
Definition Decl.h:2842
DeclarationNameInfo getNameInfo() const
Definition Decl.h:2210
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Definition Expr.cpp:2068
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'.
Definition Expr.cpp:971
Represents the results of name lookup.
Definition Lookup.h:147
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3298
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.
Definition Expr.h:3359
This represents a decl that may have a name.
Definition Decl.h:273
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:339
Represent a C++ namespace.
Definition Decl.h:591
A C++ nested-name-specifier augmented with source location information.
Represents a parameter to a function.
Definition Decl.h:1789
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition Decl.h:1822
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition Decl.cpp:2946
A (possibly-)qualified type.
Definition TypeBase.h:937
QualType withConst() const
Definition TypeBase.h:1159
void addConst()
Add the const type qualifier to this QualType.
Definition TypeBase.h:1156
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition TypeBase.h:8470
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
Definition Stmt.cpp:1248
unsigned getDepth() const
Returns the depth of this scope. The translation-unit has scope depth 0.
Definition Scope.h:339
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:854
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.
Definition Sema.h:1120
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition Sema.h:9291
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
Definition Sema.h:9294
ASTContext & getASTContext() const
Definition Sema.h:925
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition Stmt.h:85
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3809
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
Location wrapper for a TemplateArgument.
Represents a template argument.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
NamedDecl * getParam(unsigned Idx)
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Declaration of a template type parameter.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
A container of type source information.
Definition TypeBase.h:8256
The base class of the type hierarchy.
Definition TypeBase.h:1833
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:752
bool isRecordType() const
Definition TypeBase.h:8649
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:5036
QualType getType() const
Definition Decl.h:722
Represents a variable declaration or definition.
Definition Decl.h:925
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition Decl.cpp:2151
BuiltinTypeDeclBuilder(Sema &SemaRef, CXXRecordDecl *R)
BuiltinTypeDeclBuilder & addSimpleTemplateParams(ArrayRef< StringRef > Names, ConceptDecl *CD)
BuiltinTypeDeclBuilder & addMemberVariable(StringRef Name, QualType Type, llvm::ArrayRef< Attr * > Attrs, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addHandleAccessFunction(DeclarationName &Name, bool IsConst, bool IsRef)
BuiltinTypeDeclBuilder & addHandleMember(ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access=AccessSpecifier::AS_private)
BuiltinTypeDeclBuilder & addCreateFromImplicitBinding()
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ ICIS_NoInit
No in-class initializer.
Definition Specifiers.h:272
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition Specifiers.h:151
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition Specifiers.h:123
@ AS_public
Definition Specifiers.h:124
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
Definition Specifiers.h:248
@ SC_Static
Definition Specifiers.h:252
@ SC_None
Definition Specifiers.h:250
@ Result
The result type of a method or function.
Definition TypeBase.h:905
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
Definition Parser.h:81
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.
Definition Specifiers.h:135
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
Definition Specifiers.h:144
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition Specifiers.h:139
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1745
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
Extra information about a function prototype.
Definition TypeBase.h:5349
BuiltinTypeMethodBuilder & addParam(StringRef Name, QualType Ty, HLSLParamModifierAttr::Spelling Modifier=HLSLParamModifierAttr::Keyword_in)
BuiltinTypeMethodBuilder & accessHandleFieldOnResource(T ResourceRecord)
BuiltinTypeMethodBuilder & operator=(const BuiltinTypeMethodBuilder &Other)=delete
BuiltinTypeMethodBuilder & callBuiltin(StringRef BuiltinName, QualType ReturnType, Ts... ArgSpecs)
BuiltinTypeMethodBuilder & dereference(T Ptr)
BuiltinTypeMethodBuilder & declareLocalVar(LocalVar &Var)
BuiltinTypeMethodBuilder & assign(TLHS LHS, TRHS RHS)
BuiltinTypeMethodBuilder(const BuiltinTypeMethodBuilder &Other)=delete
BuiltinTypeMethodBuilder & setHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue)
BuiltinTypeMethodBuilder & returnValue(T ReturnValue)
BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, DeclarationName &Name, QualType ReturnTy, bool IsConst=false, bool IsCtor=false, StorageClass SC=SC_None)
TemplateParameterListBuilder & addTypeParameter(StringRef Name, QualType DefaultValue=QualType())
BuiltinTypeDeclBuilder & finalizeTemplateArgs(ConceptDecl *CD=nullptr)
ConceptSpecializationExpr * constructConceptSpecializationExpr(Sema &S, ConceptDecl *CD)