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/Type.h"
23#include "clang/Sema/Lookup.h"
24#include "clang/Sema/Sema.h"
25#include "clang/Sema/SemaHLSL.h"
26#include "llvm/ADT/SmallVector.h"
27
28using namespace llvm::hlsl;
29
30namespace clang {
31
32namespace hlsl {
33
34namespace {
35
36static FunctionDecl *lookupBuiltinFunction(Sema &S, StringRef Name) {
37 IdentifierInfo &II =
38 S.getASTContext().Idents.get(Name, tok::TokenKind::identifier);
39 DeclarationNameInfo NameInfo =
40 DeclarationNameInfo(DeclarationName(&II), SourceLocation());
41 LookupResult R(S, NameInfo, Sema::LookupOrdinaryName);
42 // AllowBuiltinCreation is false but LookupDirect will create
43 // the builtin when searching the global scope anyways...
44 S.LookupName(R, S.getCurScope());
45 // FIXME: If the builtin function was user-declared in global scope,
46 // this assert *will* fail. Should this call LookupBuiltin instead?
47 assert(R.isSingleResult() &&
48 "Since this is a builtin it should always resolve!");
49 return cast<FunctionDecl>(R.getFoundDecl());
50}
51} // namespace
52
53// Builder for template arguments of builtin types. Used internally
54// by BuiltinTypeDeclBuilder.
70
71// Builder for methods or constructors of builtin types. Allows creating methods
72// or constructors of builtin types using the builder pattern like this:
73//
74// BuiltinTypeMethodBuilder(RecordBuilder, "MethodName", ReturnType)
75// .addParam("param_name", Type, InOutModifier)
76// .callBuiltin("builtin_name", BuiltinParams...)
77// .finalize();
78//
79// The builder needs to have all of the parameters before it can create
80// a CXXMethodDecl or CXXConstructorDecl. It collects them in addParam calls and
81// when a first method that builds the body is called or when access to 'this`
82// is needed it creates the CXXMethodDecl/CXXConstructorDecl and ParmVarDecls
83// instances. These can then be referenced from the body building methods.
84// Destructor or an explicit call to finalize() will complete the method
85// definition.
86//
87// The callBuiltin helper method accepts constants via `Expr *` or placeholder
88// value arguments to indicate which function arguments to forward to the
89// builtin.
90//
91// If the method that is being built has a non-void return type the
92// finalize() will create a return statement with the value of the last
93// statement (unless the last statement is already a ReturnStmt or the return
94// value is void).
96private:
97 struct Param {
98 const IdentifierInfo &NameII;
99 QualType Ty;
100 HLSLParamModifierAttr::Spelling Modifier;
101 Param(const IdentifierInfo &NameII, QualType Ty,
102 HLSLParamModifierAttr::Spelling Modifier)
103 : NameII(NameII), Ty(Ty), Modifier(Modifier) {}
104 };
105
106 struct LocalVar {
107 StringRef Name;
108 QualType Ty;
109 VarDecl *Decl;
110 LocalVar(StringRef Name, QualType Ty) : Name(Name), Ty(Ty), Decl(nullptr) {}
111 };
112
113 BuiltinTypeDeclBuilder &DeclBuilder;
114 DeclarationName Name;
115 QualType ReturnTy;
116 // method or constructor declaration
117 // (CXXConstructorDecl derives from CXXMethodDecl)
118 CXXMethodDecl *Method;
119 bool IsConst;
120 bool IsCtor;
121 StorageClass SC;
124
125 // Argument placeholders, inspired by std::placeholder. These are the indices
126 // of arguments to forward to `callBuiltin` and other method builder methods.
127 // Additional special values are:
128 // Handle - refers to the resource handle.
129 // LastStmt - refers to the last statement in the method body; referencing
130 // LastStmt will remove the statement from the method body since
131 // it will be linked from the new expression being constructed.
132 enum class PlaceHolder { _0, _1, _2, _3, _4, Handle = 128, LastStmt };
133
134 Expr *convertPlaceholder(PlaceHolder PH);
135 Expr *convertPlaceholder(LocalVar &Var);
136 Expr *convertPlaceholder(Expr *E) { return E; }
137
138public:
140
142 QualType ReturnTy, bool IsConst = false,
143 bool IsCtor = false, StorageClass SC = SC_None)
144 : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(nullptr),
145 IsConst(IsConst), IsCtor(IsCtor), SC(SC) {}
146
148 QualType ReturnTy, bool IsConst = false,
149 bool IsCtor = false, StorageClass SC = SC_None);
151
153
156
157 BuiltinTypeMethodBuilder &addParam(StringRef Name, QualType Ty,
158 HLSLParamModifierAttr::Spelling Modifier =
159 HLSLParamModifierAttr::Keyword_in);
161 template <typename... Ts>
162 BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName,
163 QualType ReturnType, Ts... ArgSpecs);
164 template <typename TLHS, typename TRHS>
165 BuiltinTypeMethodBuilder &assign(TLHS LHS, TRHS RHS);
166 template <typename T> BuiltinTypeMethodBuilder &dereference(T Ptr);
167 template <typename T>
169 template <typename ResourceT, typename ValueT>
170 BuiltinTypeMethodBuilder &setHandleFieldOnResource(ResourceT ResourceRecord,
171 ValueT HandleValue);
172 template <typename T> BuiltinTypeMethodBuilder &returnValue(T ReturnValue);
176
177private:
178 void createDecl();
179
180 // Makes sure the declaration is created; should be called before any
181 // statement added to the body or when access to 'this' is needed.
182 void ensureCompleteDecl() {
183 if (!Method)
184 createDecl();
185 }
186};
187
191
194 QualType DefaultValue) {
195 assert(!Builder.Record->isCompleteDefinition() &&
196 "record is already complete");
197 ASTContext &AST = Builder.SemaRef.getASTContext();
198 unsigned Position = static_cast<unsigned>(Params.size());
200 AST, Builder.Record->getDeclContext(), SourceLocation(), SourceLocation(),
201 /* TemplateDepth */ 0, Position,
202 &AST.Idents.get(Name, tok::TokenKind::identifier),
203 /* Typename */ true,
204 /* ParameterPack */ false,
205 /* HasTypeConstraint*/ false);
206 if (!DefaultValue.isNull())
207 Decl->setDefaultArgument(AST,
208 Builder.SemaRef.getTrivialTemplateArgumentLoc(
209 DefaultValue, QualType(), SourceLocation()));
210
211 Params.emplace_back(Decl);
212 return *this;
213}
214
215// The concept specialization expression (CSE) constructed in
216// constructConceptSpecializationExpr is constructed so that it
217// matches the CSE that is constructed when parsing the below C++ code:
218//
219// template<typename T>
220// concept is_typed_resource_element_compatible =
221// __builtin_hlsl_typed_resource_element_compatible<T>
222//
223// template<typename element_type> requires
224// is_typed_resource_element_compatible<element_type>
225// struct RWBuffer {
226// element_type Val;
227// };
228//
229// int fn() {
230// RWBuffer<int> Buf;
231// }
232//
233// When dumping the AST and filtering for "RWBuffer", the resulting AST
234// structure is what we're trying to construct below, specifically the
235// CSE portion.
238 Sema &S, ConceptDecl *CD) {
239 ASTContext &Context = S.getASTContext();
240 SourceLocation Loc = Builder.Record->getBeginLoc();
241 DeclarationNameInfo DNI(CD->getDeclName(), Loc);
243 DeclContext *DC = Builder.Record->getDeclContext();
244 TemplateArgumentListInfo TALI(Loc, Loc);
245
246 // Assume that the concept decl has just one template parameter
247 // This parameter should have been added when CD was constructed
248 // in getTypedBufferConceptDecl
249 assert(CD->getTemplateParameters()->size() == 1 &&
250 "unexpected concept decl parameter count");
251 TemplateTypeParmDecl *ConceptTTPD =
252 dyn_cast<TemplateTypeParmDecl>(CD->getTemplateParameters()->getParam(0));
253
254 // this TemplateTypeParmDecl is the template for the resource, and is
255 // used to construct a template argumentthat will be used
256 // to construct the ImplicitConceptSpecializationDecl
258 Context, // AST context
259 Builder.Record->getDeclContext(), // DeclContext
261 /*D=*/0, // Depth in the template parameter list
262 /*P=*/0, // Position in the template parameter list
263 /*Id=*/nullptr, // Identifier for 'T'
264 /*Typename=*/true, // Indicates this is a 'typename' or 'class'
265 /*ParameterPack=*/false, // Not a parameter pack
266 /*HasTypeConstraint=*/false // Has no type constraint
267 );
268
269 T->setDeclContext(DC);
270
271 QualType ConceptTType = Context.getTypeDeclType(ConceptTTPD);
272
273 // this is the 2nd template argument node, on which
274 // the concept constraint is actually being applied: 'element_type'
275 TemplateArgument ConceptTA = TemplateArgument(ConceptTType);
276
277 QualType CSETType = Context.getTypeDeclType(T);
278
279 // this is the 1st template argument node, which represents
280 // the abstract type that a concept would refer to: 'T'
281 TemplateArgument CSETA = TemplateArgument(CSETType);
282
283 ImplicitConceptSpecializationDecl *ImplicitCSEDecl =
285 Context, Builder.Record->getDeclContext(), Loc, {CSETA});
286
287 // Constraint satisfaction is used to construct the
288 // ConceptSpecailizationExpr, and represents the 2nd Template Argument,
289 // located at the bottom of the sample AST above.
290 const ConstraintSatisfaction CS(CD, {ConceptTA});
293
294 TALI.addArgument(TAL);
295 const ASTTemplateArgumentListInfo *ATALI =
297
298 // In the concept reference, ATALI is what adds the extra
299 // TemplateArgument node underneath CSE
300 ConceptReference *CR =
301 ConceptReference::Create(Context, NNSLoc, Loc, DNI, CD, CD, ATALI);
302
304 ConceptSpecializationExpr::Create(Context, CR, ImplicitCSEDecl, &CS);
305
306 return CSE;
307}
308
311 if (Params.empty())
312 return Builder;
313
314 ASTContext &AST = Builder.SemaRef.Context;
316 CD ? constructConceptSpecializationExpr(Builder.SemaRef, CD) : nullptr;
317 auto *ParamList = TemplateParameterList::Create(
320 AST, Builder.Record->getDeclContext(), SourceLocation(),
321 DeclarationName(Builder.Record->getIdentifier()), ParamList,
322 Builder.Record);
323
324 Builder.Record->setDescribedClassTemplate(Builder.Template);
325 Builder.Template->setImplicit(true);
326 Builder.Template->setLexicalDeclContext(Builder.Record->getDeclContext());
327
328 // NOTE: setPreviousDecl before addDecl so new decl replace old decl when
329 // make visible.
330 Builder.Template->setPreviousDecl(Builder.PrevTemplate);
331 Builder.Record->getDeclContext()->addDecl(Builder.Template);
332 Params.clear();
333
334 return Builder;
335}
336
337Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) {
338 if (PH == PlaceHolder::Handle)
339 return getResourceHandleExpr();
340
341 if (PH == PlaceHolder::LastStmt) {
342 assert(!StmtsList.empty() && "no statements in the list");
343 Stmt *LastStmt = StmtsList.pop_back_val();
344 assert(isa<ValueStmt>(LastStmt) && "last statement does not have a value");
345 return cast<ValueStmt>(LastStmt)->getExprStmt();
346 }
347
348 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
349 ParmVarDecl *ParamDecl = Method->getParamDecl(static_cast<unsigned>(PH));
350 return DeclRefExpr::Create(
351 AST, NestedNameSpecifierLoc(), SourceLocation(), ParamDecl, false,
353 ParamDecl->getType().getNonReferenceType(), VK_PRValue);
354}
355
356Expr *BuiltinTypeMethodBuilder::convertPlaceholder(LocalVar &Var) {
357 VarDecl *VD = Var.Decl;
358 assert(VD && "local variable is not declared");
359 return DeclRefExpr::Create(
360 VD->getASTContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
361 false, DeclarationNameInfo(VD->getDeclName(), SourceLocation()),
362 VD->getType(), VK_LValue);
363}
364
366 StringRef NameStr,
367 QualType ReturnTy,
368 bool IsConst, bool IsCtor,
369 StorageClass SC)
370 : DeclBuilder(DB), ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst),
371 IsCtor(IsCtor), SC(SC) {
372
373 assert((!NameStr.empty() || IsCtor) && "method needs a name");
374 assert(((IsCtor && !IsConst) || !IsCtor) && "constructor cannot be const");
375
376 ASTContext &AST = DB.SemaRef.getASTContext();
377 if (IsCtor) {
379 AST.getCanonicalTagType(DB.Record));
380 } else {
381 const IdentifierInfo &II =
382 AST.Idents.get(NameStr, tok::TokenKind::identifier);
383 Name = DeclarationName(&II);
384 }
385}
386
389 HLSLParamModifierAttr::Spelling Modifier) {
390 assert(Method == nullptr && "Cannot add param, method already created");
391 const IdentifierInfo &II = DeclBuilder.SemaRef.getASTContext().Idents.get(
392 Name, tok::TokenKind::identifier);
393 Params.emplace_back(II, Ty, Modifier);
394 return *this;
395}
396
397void BuiltinTypeMethodBuilder::createDecl() {
398 assert(Method == nullptr && "Method or constructor is already created");
399
400 // create method or constructor type
401 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
402 SmallVector<QualType> ParamTypes;
403 for (Param &MP : Params)
404 ParamTypes.emplace_back(MP.Ty);
405
407 if (IsConst)
408 ExtInfo.TypeQuals.addConst();
409
410 QualType FuncTy = AST.getFunctionType(ReturnTy, ParamTypes, ExtInfo);
411
412 // create method or constructor decl
413 auto *TSInfo = AST.getTrivialTypeSourceInfo(FuncTy, SourceLocation());
415 if (IsCtor)
417 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo,
418 ExplicitSpecifier(), false, true, false,
420 else
422 AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo, SC,
424
425 // create params & set them to the function prototype
427 unsigned CurScopeDepth = DeclBuilder.SemaRef.getCurScope()->getDepth();
428 auto FnProtoLoc =
429 Method->getTypeSourceInfo()->getTypeLoc().getAs<FunctionProtoTypeLoc>();
430 for (int I = 0, E = Params.size(); I != E; I++) {
431 Param &MP = Params[I];
433 AST, Method->getDeclContext(), SourceLocation(), SourceLocation(),
434 &MP.NameII, MP.Ty,
436 nullptr);
437 if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
438 auto *Mod =
439 HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
440 Parm->addAttr(Mod);
441 }
442 Parm->setScopeInfo(CurScopeDepth, I);
443 ParmDecls.push_back(Parm);
444 FnProtoLoc.setParam(I, Parm);
445 }
446 Method->setParams({ParmDecls});
447}
448
450 ensureCompleteDecl();
451
452 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
454 AST, SourceLocation(), Method->getFunctionObjectParameterType(), true);
455 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
456 return MemberExpr::CreateImplicit(AST, This, false, HandleField,
457 HandleField->getType(), VK_LValue,
459}
460
463 ensureCompleteDecl();
464
465 assert(Var.Decl == nullptr && "local variable is already declared");
466
467 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
468 Var.Decl = VarDecl::Create(
469 AST, Method, SourceLocation(), SourceLocation(),
470 &AST.Idents.get(Var.Name, tok::TokenKind::identifier), Var.Ty,
472 DeclStmt *DS = new (AST) clang::DeclStmt(DeclGroupRef(Var.Decl),
474 StmtsList.push_back(DS);
475 return *this;
476}
477
479 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
481 AST, SourceLocation(), Method->getFunctionObjectParameterType(),
482 /*IsImplicit=*/true);
483 StmtsList.push_back(ThisExpr);
484 return *this;
485}
486
487template <typename... Ts>
490 QualType ReturnType, Ts... ArgSpecs) {
491 ensureCompleteDecl();
492
493 std::array<Expr *, sizeof...(ArgSpecs)> Args{
494 convertPlaceholder(std::forward<Ts>(ArgSpecs))...};
495
496 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
497 FunctionDecl *FD = lookupBuiltinFunction(DeclBuilder.SemaRef, BuiltinName);
499 AST, NestedNameSpecifierLoc(), SourceLocation(), FD, false,
501
502 auto *ImpCast = ImplicitCastExpr::Create(
503 AST, AST.getPointerType(FD->getType()), CK_BuiltinFnToFnPtr, DRE, nullptr,
505
506 if (ReturnType.isNull())
507 ReturnType = FD->getReturnType();
508
509 Expr *Call = CallExpr::Create(AST, ImpCast, Args, ReturnType, VK_PRValue,
511 StmtsList.push_back(Call);
512 return *this;
513}
514
515template <typename TLHS, typename TRHS>
517 Expr *LHSExpr = convertPlaceholder(LHS);
518 Expr *RHSExpr = convertPlaceholder(RHS);
519 Stmt *AssignStmt = BinaryOperator::Create(
520 DeclBuilder.SemaRef.getASTContext(), LHSExpr, RHSExpr, BO_Assign,
523 StmtsList.push_back(AssignStmt);
524 return *this;
525}
526
527template <typename T>
529 Expr *PtrExpr = convertPlaceholder(Ptr);
530 Expr *Deref =
531 UnaryOperator::Create(DeclBuilder.SemaRef.getASTContext(), PtrExpr,
532 UO_Deref, PtrExpr->getType()->getPointeeType(),
534 /*CanOverflow=*/false, FPOptionsOverride());
535 StmtsList.push_back(Deref);
536 return *this;
537}
538
539template <typename T>
542 ensureCompleteDecl();
543
544 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
545
546 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
547 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
549 AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue,
551 StmtsList.push_back(HandleExpr);
552 return *this;
553}
554
555template <typename ResourceT, typename ValueT>
558 ValueT HandleValue) {
559 ensureCompleteDecl();
560
561 Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
562 Expr *HandleValueExpr = convertPlaceholder(HandleValue);
563
564 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
565 FieldDecl *HandleField = DeclBuilder.getResourceHandleField();
566 MemberExpr *HandleMemberExpr = MemberExpr::CreateImplicit(
567 AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue,
569 Stmt *AssignStmt = BinaryOperator::Create(
570 DeclBuilder.SemaRef.getASTContext(), HandleMemberExpr, HandleValueExpr,
571 BO_Assign, HandleMemberExpr->getType(), ExprValueKind::VK_PRValue,
573 StmtsList.push_back(AssignStmt);
574 return *this;
575}
576
577template <typename T>
579 ensureCompleteDecl();
580
581 Expr *ReturnValueExpr = convertPlaceholder(ReturnValue);
582 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
583 StmtsList.push_back(
584 ReturnStmt::Create(AST, SourceLocation(), ReturnValueExpr, nullptr));
585 return *this;
586}
587
589 assert(!DeclBuilder.Record->isCompleteDefinition() &&
590 "record is already complete");
591
592 ensureCompleteDecl();
593
594 if (!Method->hasBody()) {
595 ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
596 assert((ReturnTy == AST.VoidTy || !StmtsList.empty()) &&
597 "nothing to return from non-void method");
598 if (ReturnTy != AST.VoidTy) {
599 if (Expr *LastExpr = dyn_cast<Expr>(StmtsList.back())) {
600 assert(AST.hasSameUnqualifiedType(LastExpr->getType(),
601 ReturnTy.getNonReferenceType()) &&
602 "Return type of the last statement must match the return type "
603 "of the method");
604 if (!isa<ReturnStmt>(LastExpr)) {
605 StmtsList.pop_back();
606 StmtsList.push_back(
607 ReturnStmt::Create(AST, SourceLocation(), LastExpr, nullptr));
608 }
609 }
610 }
611
612 Method->setBody(CompoundStmt::Create(AST, StmtsList, FPOptionsOverride(),
614 Method->setLexicalDeclContext(DeclBuilder.Record);
615 Method->setAccess(AS_public);
616 Method->addAttr(AlwaysInlineAttr::CreateImplicit(
617 AST, SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
618 DeclBuilder.Record->addDecl(Method);
619 }
620 return DeclBuilder;
621}
622
624 : SemaRef(SemaRef), Record(R) {
625 Record->startDefinition();
626 Template = Record->getDescribedClassTemplate();
627}
628
630 NamespaceDecl *Namespace,
631 StringRef Name)
632 : SemaRef(SemaRef), HLSLNamespace(Namespace) {
633 ASTContext &AST = SemaRef.getASTContext();
634 IdentifierInfo &II = AST.Idents.get(Name, tok::TokenKind::identifier);
635
637 CXXRecordDecl *PrevDecl = nullptr;
638 if (SemaRef.LookupQualifiedName(Result, HLSLNamespace)) {
639 // Declaration already exists (from precompiled headers)
640 NamedDecl *Found = Result.getFoundDecl();
641 if (auto *TD = dyn_cast<ClassTemplateDecl>(Found)) {
642 PrevDecl = TD->getTemplatedDecl();
643 PrevTemplate = TD;
644 } else
645 PrevDecl = dyn_cast<CXXRecordDecl>(Found);
646 assert(PrevDecl && "Unexpected lookup result type.");
647 }
648
649 if (PrevDecl && PrevDecl->isCompleteDefinition()) {
650 Record = PrevDecl;
651 Template = PrevTemplate;
652 return;
653 }
654
655 Record =
656 CXXRecordDecl::Create(AST, TagDecl::TagKind::Class, HLSLNamespace,
657 SourceLocation(), SourceLocation(), &II, PrevDecl);
658 Record->setImplicit(true);
659 Record->setLexicalDeclContext(HLSLNamespace);
660 Record->setHasExternalLexicalStorage();
661
662 // Don't let anyone derive from built-in types.
663 Record->addAttr(
664 FinalAttr::CreateImplicit(AST, SourceRange(), FinalAttr::Keyword_final));
665}
666
668 if (HLSLNamespace && !Template && Record->getDeclContext() == HLSLNamespace)
669 HLSLNamespace->addDecl(Record);
670}
671
675 AccessSpecifier Access) {
676 assert(!Record->isCompleteDefinition() && "record is already complete");
677 assert(Record->isBeingDefined() &&
678 "Definition must be started before adding members!");
679 ASTContext &AST = Record->getASTContext();
680
681 IdentifierInfo &II = AST.Idents.get(Name, tok::TokenKind::identifier);
682 TypeSourceInfo *MemTySource =
684 auto *Field = FieldDecl::Create(
685 AST, Record, SourceLocation(), SourceLocation(), &II, Type, MemTySource,
686 nullptr, false, InClassInitStyle::ICIS_NoInit);
687 Field->setAccess(Access);
688 Field->setImplicit(true);
689 for (Attr *A : Attrs) {
690 if (A)
691 Field->addAttr(A);
692 }
693
694 Record->addDecl(Field);
695 Fields[Name] = Field;
696 return *this;
697}
698
700 ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
701 assert(!Record->isCompleteDefinition() && "record is already complete");
702
703 ASTContext &Ctx = SemaRef.getASTContext();
704 TypeSourceInfo *ElementTypeInfo =
705 Ctx.getTrivialTypeSourceInfo(getHandleElementType(), SourceLocation());
706
707 // add handle member with resource type attributes
708 QualType AttributedResTy = QualType();
710 HLSLResourceClassAttr::CreateImplicit(Ctx, RC),
711 IsROV ? HLSLROVAttr::CreateImplicit(Ctx) : nullptr,
712 RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) : nullptr,
713 ElementTypeInfo
714 ? HLSLContainedTypeAttr::CreateImplicit(Ctx, ElementTypeInfo)
715 : nullptr};
716 if (CreateHLSLAttributedResourceType(SemaRef, Ctx.HLSLResourceTy, Attrs,
717 AttributedResTy))
718 addMemberVariable("__handle", AttributedResTy, {}, Access);
719 return *this;
720}
721
722// Adds default constructor to the resource class:
723// Resource::Resource()
725 if (Record->isCompleteDefinition())
726 return *this;
727
728 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
729 QualType HandleType = getResourceHandleField()->getType();
730 return BuiltinTypeMethodBuilder(*this, "", SemaRef.getASTContext().VoidTy,
731 false, true)
732 .callBuiltin("__builtin_hlsl_resource_uninitializedhandle", HandleType,
733 PH::Handle)
734 .assign(PH::Handle, PH::LastStmt)
735 .finalize();
736}
737
740 if (Record->isCompleteDefinition())
741 return *this;
742
743 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
744 ASTContext &AST = SemaRef.getASTContext();
745 QualType HandleType = getResourceHandleField()->getType();
746
747 return BuiltinTypeMethodBuilder(*this, "", AST.VoidTy, false, true)
748 .addParam("registerNo", AST.UnsignedIntTy)
749 .addParam("spaceNo", AST.UnsignedIntTy)
750 .addParam("range", AST.IntTy)
751 .addParam("index", AST.UnsignedIntTy)
752 .addParam("name", AST.getPointerType(AST.CharTy.withConst()))
753 .callBuiltin("__builtin_hlsl_resource_handlefrombinding", HandleType,
754 PH::Handle, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
755 .assign(PH::Handle, PH::LastStmt)
756 .finalize();
757}
758
761 if (Record->isCompleteDefinition())
762 return *this;
763
764 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
765 ASTContext &AST = SemaRef.getASTContext();
766 QualType HandleType = getResourceHandleField()->getType();
767
768 return BuiltinTypeMethodBuilder(*this, "", AST.VoidTy, false, true)
769 .addParam("spaceNo", AST.UnsignedIntTy)
770 .addParam("range", AST.IntTy)
771 .addParam("index", AST.UnsignedIntTy)
772 .addParam("orderId", AST.UnsignedIntTy)
773 .addParam("name", AST.getPointerType(AST.CharTy.withConst()))
774 .callBuiltin("__builtin_hlsl_resource_handlefromimplicitbinding",
775 HandleType, PH::Handle, PH::_3, PH::_0, PH::_1, PH::_2,
776 PH::_4)
777 .assign(PH::Handle, PH::LastStmt)
778 .finalize();
779}
780
781// Adds static method that initializes resource from binding:
782//
783// static Resource<T> __createFromBinding(unsigned registerNo,
784// unsigned spaceNo, int range,
785// unsigned index, const char *name) {
786// Resource<T> tmp;
787// tmp.__handle = __builtin_hlsl_resource_handlefrombinding(
788// tmp.__handle, registerNo, spaceNo,
789// range, index, name);
790// return tmp;
791// }
793 if (Record->isCompleteDefinition())
794 return *this;
795
796 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
797 ASTContext &AST = SemaRef.getASTContext();
798 QualType HandleType = getResourceHandleField()->getType();
799 QualType RecordType = AST.getTypeDeclType(cast<TypeDecl>(Record));
800 BuiltinTypeMethodBuilder::LocalVar TmpVar("tmp", RecordType);
801
802 return BuiltinTypeMethodBuilder(*this, "__createFromBinding", RecordType,
803 false, false, SC_Static)
804 .addParam("registerNo", AST.UnsignedIntTy)
805 .addParam("spaceNo", AST.UnsignedIntTy)
806 .addParam("range", AST.IntTy)
807 .addParam("index", AST.UnsignedIntTy)
808 .addParam("name", AST.getPointerType(AST.CharTy.withConst()))
809 .declareLocalVar(TmpVar)
810 .accessHandleFieldOnResource(TmpVar)
811 .callBuiltin("__builtin_hlsl_resource_handlefrombinding", HandleType,
812 PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4)
813 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
814 .returnValue(TmpVar)
815 .finalize();
816}
817
818// Adds static method that initializes resource from binding:
819//
820// static Resource<T> __createFromImplicitBinding(unsigned orderId,
821// unsigned spaceNo, int range,
822// unsigned index,
823// const char *name) {
824// Resource<T> tmp;
825// tmp.__handle = __builtin_hlsl_resource_handlefromimplicitbinding(
826// tmp.__handle, spaceNo,
827// range, index, orderId, name);
828// return tmp;
829// }
831 if (Record->isCompleteDefinition())
832 return *this;
833
834 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
835 ASTContext &AST = SemaRef.getASTContext();
836 QualType HandleType = getResourceHandleField()->getType();
837 QualType RecordType = AST.getTypeDeclType(cast<TypeDecl>(Record));
838 BuiltinTypeMethodBuilder::LocalVar TmpVar("tmp", RecordType);
839
840 return BuiltinTypeMethodBuilder(*this, "__createFromImplicitBinding",
841 RecordType, false, false, SC_Static)
842 .addParam("orderId", AST.UnsignedIntTy)
843 .addParam("spaceNo", AST.UnsignedIntTy)
844 .addParam("range", AST.IntTy)
845 .addParam("index", AST.UnsignedIntTy)
846 .addParam("name", AST.getPointerType(AST.CharTy.withConst()))
847 .declareLocalVar(TmpVar)
848 .accessHandleFieldOnResource(TmpVar)
849 .callBuiltin("__builtin_hlsl_resource_handlefromimplicitbinding",
850 HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3,
851 PH::_4)
852 .setHandleFieldOnResource(TmpVar, PH::LastStmt)
853 .returnValue(TmpVar)
854 .finalize();
855}
856
858 if (Record->isCompleteDefinition())
859 return *this;
860
861 ASTContext &AST = SemaRef.getASTContext();
862 QualType RecordType = AST.getCanonicalTagType(Record);
863 QualType ConstRecordType = RecordType.withConst();
864 QualType ConstRecordRefType = AST.getLValueReferenceType(ConstRecordType);
865
866 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
867
868 return BuiltinTypeMethodBuilder(*this, /*Name=*/"", AST.VoidTy,
869 /*IsConst=*/false, /*IsCtor=*/true)
870 .addParam("other", ConstRecordRefType)
871 .accessHandleFieldOnResource(PH::_0)
872 .assign(PH::Handle, PH::LastStmt)
873 .finalize();
874}
875
877 if (Record->isCompleteDefinition())
878 return *this;
879
880 ASTContext &AST = SemaRef.getASTContext();
881 QualType RecordType = AST.getCanonicalTagType(Record);
882 QualType ConstRecordType = RecordType.withConst();
883 QualType ConstRecordRefType = AST.getLValueReferenceType(ConstRecordType);
884 QualType RecordRefType = AST.getLValueReferenceType(RecordType);
885
886 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
888 return BuiltinTypeMethodBuilder(*this, Name, RecordRefType)
889 .addParam("other", ConstRecordRefType)
890 .accessHandleFieldOnResource(PH::_0)
891 .assign(PH::Handle, PH::LastStmt)
892 .returnThis()
893 .finalize();
894}
895
897 ASTContext &AST = Record->getASTContext();
898 DeclarationName Subscript =
899 AST.DeclarationNames.getCXXOperatorName(OO_Subscript);
900
901 addHandleAccessFunction(Subscript, /*IsConst=*/true, /*IsRef=*/true);
902 if (getResourceAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV)
903 addHandleAccessFunction(Subscript, /*IsConst=*/false, /*IsRef=*/true);
904
905 return *this;
906}
907
909 if (Record->isCompleteDefinition())
910 return *this;
911
912 ASTContext &AST = Record->getASTContext();
913 IdentifierInfo &II = AST.Idents.get("Load", tok::TokenKind::identifier);
914 DeclarationName Load(&II);
915 // TODO: We also need versions with status for CheckAccessFullyMapped.
916 addHandleAccessFunction(Load, /*IsConst=*/false, /*IsRef=*/false);
917
918 return *this;
919}
920
921FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() const {
922 auto I = Fields.find("__handle");
923 assert(I != Fields.end() &&
924 I->second->getType()->isHLSLAttributedResourceType() &&
925 "record does not have resource handle field");
926 return I->second;
927}
928
929QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam() {
930 assert(Template && "record it not a template");
931 if (const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
932 Template->getTemplateParameters()->getParam(0))) {
933 return QualType(TTD->getTypeForDecl(), 0);
934 }
935 return QualType();
936}
937
938QualType BuiltinTypeDeclBuilder::getHandleElementType() {
939 if (Template)
940 return getFirstTemplateTypeParam();
941 // TODO: Should we default to VoidTy? Using `i8` is arguably ambiguous.
942 return SemaRef.getASTContext().Char8Ty;
943}
944
945HLSLAttributedResourceType::Attributes
946BuiltinTypeDeclBuilder::getResourceAttrs() const {
947 QualType HandleType = getResourceHandleField()->getType();
948 return cast<HLSLAttributedResourceType>(HandleType)->getAttrs();
949}
950
951// BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::startDefinition() {
952// assert(!Record->isCompleteDefinition() && "record is already complete");
953// Record->startDefinition();
954// return *this;
955// }
956
958 assert(!Record->isCompleteDefinition() && "record is already complete");
959 assert(Record->isBeingDefined() &&
960 "Definition must be started before completing it.");
961
962 Record->completeDefinition();
963 return *this;
964}
965
966Expr *BuiltinTypeDeclBuilder::getConstantIntExpr(int value) {
967 ASTContext &AST = SemaRef.getASTContext();
969 AST, llvm::APInt(AST.getTypeSize(AST.IntTy), value, true), AST.IntTy,
971}
972
975 ConceptDecl *CD = nullptr) {
976 if (Record->isCompleteDefinition()) {
977 assert(Template && "existing record it not a template");
978 assert(Template->getTemplateParameters()->size() == Names.size() &&
979 "template param count mismatch");
980 return *this;
981 }
982
984 for (StringRef Name : Names)
985 Builder.addTypeParameter(Name);
986 return Builder.finalizeTemplateArgs(CD);
987}
988
990 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
991 return BuiltinTypeMethodBuilder(*this, "IncrementCounter",
992 SemaRef.getASTContext().UnsignedIntTy)
993 .callBuiltin("__builtin_hlsl_buffer_update_counter", QualType(),
994 PH::Handle, getConstantIntExpr(1))
995 .finalize();
996}
997
999 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1000 return BuiltinTypeMethodBuilder(*this, "DecrementCounter",
1001 SemaRef.getASTContext().UnsignedIntTy)
1002 .callBuiltin("__builtin_hlsl_buffer_update_counter", QualType(),
1003 PH::Handle, getConstantIntExpr(-1))
1004 .finalize();
1005}
1006
1009 bool IsConst, bool IsRef) {
1010 assert(!Record->isCompleteDefinition() && "record is already complete");
1011 ASTContext &AST = SemaRef.getASTContext();
1012 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1013
1014 QualType ElemTy = getHandleElementType();
1015 QualType AddrSpaceElemTy =
1017 QualType ElemPtrTy = AST.getPointerType(AddrSpaceElemTy);
1018 QualType ReturnTy;
1019
1020 if (IsRef) {
1021 ReturnTy = AddrSpaceElemTy;
1022 if (IsConst)
1023 ReturnTy.addConst();
1024 ReturnTy = AST.getLValueReferenceType(ReturnTy);
1025 } else {
1026 ReturnTy = ElemTy;
1027 if (IsConst)
1028 ReturnTy.addConst();
1029 }
1030
1031 return BuiltinTypeMethodBuilder(*this, Name, ReturnTy, IsConst)
1032 .addParam("Index", AST.UnsignedIntTy)
1033 .callBuiltin("__builtin_hlsl_resource_getpointer", ElemPtrTy, PH::Handle,
1034 PH::_0)
1035 .dereference(PH::LastStmt)
1036 .finalize();
1037}
1038
1040 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1041 ASTContext &AST = SemaRef.getASTContext();
1042 QualType ElemTy = getHandleElementType();
1043 QualType AddrSpaceElemTy =
1045 return BuiltinTypeMethodBuilder(*this, "Append", AST.VoidTy)
1046 .addParam("value", ElemTy)
1047 .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy,
1048 PH::Handle, getConstantIntExpr(1))
1049 .callBuiltin("__builtin_hlsl_resource_getpointer",
1050 AST.getPointerType(AddrSpaceElemTy), PH::Handle,
1051 PH::LastStmt)
1052 .dereference(PH::LastStmt)
1053 .assign(PH::LastStmt, PH::_0)
1054 .finalize();
1055}
1056
1058 using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1059 ASTContext &AST = SemaRef.getASTContext();
1060 QualType ElemTy = getHandleElementType();
1061 QualType AddrSpaceElemTy =
1063 return BuiltinTypeMethodBuilder(*this, "Consume", ElemTy)
1064 .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy,
1065 PH::Handle, getConstantIntExpr(-1))
1066 .callBuiltin("__builtin_hlsl_resource_getpointer",
1067 AST.getPointerType(AddrSpaceElemTy), PH::Handle,
1068 PH::LastStmt)
1069 .dereference(PH::LastStmt)
1070 .finalize();
1071}
1072
1073} // namespace hlsl
1074} // 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:4938
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:1272
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:3300
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:3361
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:9288
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
Definition Sema.h:9291
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
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:4995
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 & addHandleConstructorFromImplicitBinding()
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 & addHandleConstructorFromBinding()
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_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)