20#include "llvm/Frontend/HLSL/HLSLResource.h"
25using namespace llvm::hlsl;
29struct TemplateParameterListBuilder;
31struct BuiltinTypeDeclBuilder {
36 llvm::StringMap<FieldDecl *> Fields;
40 Template =
Record->getDescribedClassTemplate();
52 if (
auto *TD = dyn_cast<ClassTemplateDecl>(Found)) {
53 PrevDecl = TD->getTemplatedDecl();
56 PrevDecl = dyn_cast<CXXRecordDecl>(Found);
57 assert(PrevDecl &&
"Unexpected lookup result type.");
69 Record->setLexicalDeclContext(HLSLNamespace);
70 Record->setHasExternalLexicalStorage();
74 FinalAttr::Keyword_final));
77 ~BuiltinTypeDeclBuilder() {
78 if (HLSLNamespace && !Template &&
Record->getDeclContext() == HLSLNamespace)
82 BuiltinTypeDeclBuilder &
85 if (
Record->isCompleteDefinition())
87 assert(
Record->isBeingDefined() &&
88 "Definition must be started before adding members!");
96 nullptr,
false, InClassInitStyle::ICIS_NoInit);
97 Field->setAccess(Access);
98 Field->setImplicit(
true);
100 Fields[Name] =
Field;
104 BuiltinTypeDeclBuilder &
105 addHandleMember(
AccessSpecifier Access = AccessSpecifier::AS_private) {
106 if (
Record->isCompleteDefinition())
110 if (
const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
112 Ty =
Record->getASTContext().getPointerType(
113 QualType(TTD->getTypeForDecl(), 0));
115 return addMemberVariable(
"h", Ty, Access);
118 BuiltinTypeDeclBuilder &annotateResourceClass(ResourceClass RC,
119 ResourceKind RK,
bool IsROV) {
120 if (
Record->isCompleteDefinition())
122 Record->addAttr(HLSLResourceAttr::CreateImplicit(
Record->getASTContext(),
135 assert(R.isSingleResult() &&
136 "Since this is a builtin it should always resolve!");
137 auto *VD = cast<ValueDecl>(R.getFoundDecl());
143 static Expr *emitResourceClassExpr(
ASTContext &AST, ResourceClass RC) {
147 static_cast<uint8_t
>(RC)),
151 BuiltinTypeDeclBuilder &addDefaultHandleConstructor(
Sema &S,
153 if (
Record->isCompleteDefinition())
167 ConstexprSpecKind::Unspecified);
170 lookupBuiltinFunction(AST, S,
"__builtin_hlsl_create_handle");
172 Expr *RCExpr = emitResourceClassExpr(AST, RC);
200 Constructor->setAccess(AccessSpecifier::AS_public);
201 Record->addDecl(Constructor);
205 BuiltinTypeDeclBuilder &addArraySubscriptOperators() {
206 if (
Record->isCompleteDefinition())
208 addArraySubscriptOperator(
true);
209 addArraySubscriptOperator(
false);
213 BuiltinTypeDeclBuilder &addArraySubscriptOperator(
bool IsConst) {
214 if (
Record->isCompleteDefinition())
216 assert(Fields.count(
"h") > 0 &&
217 "Subscript operator must be added after the handle.");
223 "Not yet supported for void pointer handles.");
247 MethodTy, TSInfo,
SC_None,
false,
false, ConstexprSpecKind::Unspecified,
256 MethodDecl->setParams({IdxParam});
264 MethodDecl->getFunctionObjectParameterType(),
true);
282 MethodDecl->setLexicalDeclContext(
Record);
283 MethodDecl->setAccess(AccessSpecifier::AS_public);
284 MethodDecl->addAttr(AlwaysInlineAttr::CreateImplicit(
285 AST,
SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
286 Record->addDecl(MethodDecl);
291 BuiltinTypeDeclBuilder &startDefinition() {
292 if (
Record->isCompleteDefinition())
294 Record->startDefinition();
298 BuiltinTypeDeclBuilder &completeDefinition() {
299 if (
Record->isCompleteDefinition())
301 assert(
Record->isBeingDefined() &&
302 "Definition must be started before completing it.");
304 Record->completeDefinition();
308 TemplateParameterListBuilder addTemplateArgumentList();
312struct TemplateParameterListBuilder {
313 BuiltinTypeDeclBuilder &Builder;
317 TemplateParameterListBuilder(BuiltinTypeDeclBuilder &RB)
318 : Builder(RB), AST(RB.
Record->getASTContext()) {}
320 ~TemplateParameterListBuilder() { finalizeTemplateArgs(); }
322 TemplateParameterListBuilder &
324 if (Builder.Record->isCompleteDefinition())
326 unsigned Position =
static_cast<unsigned>(Params.size());
330 &AST.
Idents.
get(Name, tok::TokenKind::identifier),
false,
332 if (!DefaultValue.isNull())
335 Params.emplace_back(
Decl);
339 BuiltinTypeDeclBuilder &finalizeTemplateArgs() {
349 Builder.Record->setDescribedClassTemplate(Builder.Template);
350 Builder.Template->setImplicit(
true);
351 Builder.Template->setLexicalDeclContext(Builder.Record->getDeclContext());
354 Builder.Template->setPreviousDecl(Builder.PrevTemplate);
355 Builder.Record->getDeclContext()->addDecl(Builder.Template);
358 QualType T = Builder.Template->getInjectedClassNameSpecialization();
366TemplateParameterListBuilder BuiltinTypeDeclBuilder::addTemplateArgumentList() {
367 return TemplateParameterListBuilder(*
this);
370BuiltinTypeDeclBuilder &
372 TemplateParameterListBuilder Builder = this->addTemplateArgumentList();
373 for (StringRef Name : Names)
374 Builder.addTypeParameter(Name);
375 return Builder.finalizeTemplateArgs();
401 defineTrivialHLSLTypes();
402 defineHLSLTypesWithForwardDeclarations();
418void HLSLExternalSemaSource::defineHLSLVectorAlias() {
425 &AST.
Idents.
get(
"element", tok::TokenKind::identifier),
false,
false);
428 TemplateParams.emplace_back(TypeParam);
432 &AST.
Idents.
get(
"element_count", tok::TokenKind::identifier), AST.
IntTy,
437 SizeParam->setDefaultArgument(LiteralExpr);
438 TemplateParams.emplace_back(SizeParam);
457 Record->setImplicit(
true);
463 Record->setDescribedAliasTemplate(Template);
466 HLSLNamespace->
addDecl(Template);
469void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
470 defineHLSLVectorAlias();
472 ResourceDecl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
"Resource")
475 .completeDefinition()
481 ResourceClass RC, ResourceKind RK,
483 return BuiltinTypeDeclBuilder(
Decl)
485 .addDefaultHandleConstructor(S, RC)
486 .annotateResourceClass(RC, RK, IsROV);
489void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
491 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
"RWBuffer")
492 .addSimpleTemplateParams({
"element_type"})
496 ResourceKind::TypedBuffer,
false)
497 .addArraySubscriptOperators()
498 .completeDefinition();
502 BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
"RasterizerOrderedBuffer")
503 .addSimpleTemplateParams({
"element_type"})
507 ResourceKind::TypedBuffer,
true)
508 .addArraySubscriptOperators()
509 .completeDefinition();
514 CompletionFunction Fn) {
515 Completions.insert(std::make_pair(
Record->getCanonicalDecl(), Fn));
519 if (!isa<CXXRecordDecl>(Tag))
521 auto Record = cast<CXXRecordDecl>(Tag);
525 if (
auto TDecl = dyn_cast<ClassTemplateSpecializationDecl>(
Record))
526 Record = TDecl->getSpecializedTemplate()->getTemplatedDecl();
528 auto It = Completions.find(
Record);
529 if (It == Completions.end())
Defines the clang::ASTContext interface.
Defines the clang::attr::Kind enum.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV)
Set up common members and attributes for buffer types.
Defines helper utilities for supporting the HLSL runtime environment.
llvm::MachO::Record Record
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
unsigned getIntWidth(QualType T) const
DeclarationNameTable DeclarationNames
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const
getInjectedClassNameType - Return the unique reference to the injected class name type for the specif...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, bool ParameterPack, TemplateTypeParmDecl *ParmDecl=nullptr) const
Retrieve the template type parameter type for a template parameter or parameter pack with the given d...
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType UnsignedCharTy
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getDependentSizedExtVectorType(QualType VectorType, Expr *SizeExpr, SourceLocation AttrLoc) const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
A builtin binary operation expression such as "x + y" or "x <= y".
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
Represents a C++ constructor within a class.
static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited=InheritedConstructor(), Expr *TrailingRequiresClause=nullptr)
static CXXMethodDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin, bool isInline, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause=nullptr)
Represents a C++ struct/union/class.
static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr, bool DelayTypeCreation=false)
Represents a C++ nested-name-specifier or a global scope specifier.
static CXXStaticCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
Represents the this expression in C++.
static CXXThisExpr * Create(const ASTContext &Ctx, SourceLocation L, QualType Ty, bool IsImplicit)
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Declaration of a class template.
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
void addDecl(Decl *D)
Add the declaration D into this context.
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
void setHasExternalLexicalStorage(bool ES=true) const
State whether this DeclContext has external storage for declarations lexically in this context.
decl_iterator decls_begin() const
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
Decl - This represents one declaration (or definition), e.g.
void setImplicit(bool I=true)
void setLexicalDeclContext(DeclContext *DC)
The name of a declaration.
Store information needed for an explicit specifier.
This represents one expression.
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
static FieldDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle)
void setParam(unsigned i, ParmVarDecl *VD)
void CompleteType(TagDecl *Tag) override
Complete an incomplete HLSL builtin type.
void InitializeSema(Sema &S) override
Initialize the semantic source with the Sema instance being used to perform semantic analysis on the ...
~HLSLExternalSemaSource() override
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Represents the results of name lookup.
static MemberExpr * CreateImplicit(const ASTContext &C, Expr *Base, bool IsArrow, ValueDecl *MemberDecl, QualType T, ExprValueKind VK, ExprObjectKind OK)
Create an implicit MemberExpr, with no location, qualifier, template arguments, and so on.
This represents a decl that may have a name.
Represent a C++ namespace.
NamespaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this namespace.
static NamespaceDecl * Create(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested)
A C++ nested-name-specifier augmented with source location information.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
A (possibly-)qualified type.
void addConst()
Add the const type qualifier to this QualType.
QualType getCanonicalType() const
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupNamespaceName
Look up a namespace name within a C++ using directive or namespace alias definition,...
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
ASTContext & getASTContext() const
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Encodes a location in the source.
A trivial tuple used to represent a source range.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
void startDefinition()
Starts the definition of this tag declaration.
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)
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, std::optional< unsigned > NumExpanded=std::nullopt)
static TypeAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
A container of type source information.
The base class of the type hierarchy.
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
Represents a C++ using-declaration.
static UsingDirectiveDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceLocation NamespaceLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor)
bool This(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Result
The result type of a method or function.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
Extra information about a function prototype.