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);
99 for (
Attr *A : Attrs) {
105 Fields[Name] =
Field;
109 BuiltinTypeDeclBuilder &
110 addHandleMember(ResourceClass RC, ResourceKind RK,
bool IsROV,
112 if (
Record->isCompleteDefinition())
116 if (
const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
118 Ty =
Record->getASTContext().getPointerType(
119 QualType(TTD->getTypeForDecl(), 0));
122 Attr *ResourceClassAttr =
123 HLSLResourceClassAttr::CreateImplicit(
Record->getASTContext(), RC);
125 HLSLResourceAttr::CreateImplicit(
Record->getASTContext(), RK);
127 IsROV ? HLSLROVAttr::CreateImplicit(
Record->getASTContext()) : nullptr;
128 addMemberVariable(
"h", Ty, {ResourceClassAttr, ResourceAttr, ROVAttr},
145 assert(R.isSingleResult() &&
146 "Since this is a builtin it should always resolve!");
147 auto *VD = cast<ValueDecl>(R.getFoundDecl());
153 static Expr *emitResourceClassExpr(
ASTContext &AST, ResourceClass RC) {
157 static_cast<uint8_t
>(RC)),
161 BuiltinTypeDeclBuilder &addDefaultHandleConstructor(
Sema &S,
163 if (
Record->isCompleteDefinition())
177 ConstexprSpecKind::Unspecified);
180 lookupBuiltinFunction(AST, S,
"__builtin_hlsl_create_handle");
181 Expr *RCExpr = emitResourceClassExpr(AST, RC);
209 Constructor->setAccess(AccessSpecifier::AS_public);
210 Record->addDecl(Constructor);
214 BuiltinTypeDeclBuilder &addArraySubscriptOperators() {
215 if (
Record->isCompleteDefinition())
217 addArraySubscriptOperator(
true);
218 addArraySubscriptOperator(
false);
222 BuiltinTypeDeclBuilder &addArraySubscriptOperator(
bool IsConst) {
223 if (
Record->isCompleteDefinition())
225 assert(Fields.count(
"h") > 0 &&
226 "Subscript operator must be added after the handle.");
232 "Not yet supported for void pointer handles.");
256 MethodTy, TSInfo,
SC_None,
false,
false, ConstexprSpecKind::Unspecified,
265 MethodDecl->setParams({IdxParam});
273 MethodDecl->getFunctionObjectParameterType(),
true);
291 MethodDecl->setLexicalDeclContext(
Record);
292 MethodDecl->setAccess(AccessSpecifier::AS_public);
293 MethodDecl->addAttr(AlwaysInlineAttr::CreateImplicit(
294 AST,
SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
295 Record->addDecl(MethodDecl);
300 BuiltinTypeDeclBuilder &startDefinition() {
301 if (
Record->isCompleteDefinition())
303 Record->startDefinition();
307 BuiltinTypeDeclBuilder &completeDefinition() {
308 if (
Record->isCompleteDefinition())
310 assert(
Record->isBeingDefined() &&
311 "Definition must be started before completing it.");
313 Record->completeDefinition();
317 TemplateParameterListBuilder addTemplateArgumentList(
Sema &S);
318 BuiltinTypeDeclBuilder &addSimpleTemplateParams(
Sema &S,
322struct TemplateParameterListBuilder {
323 BuiltinTypeDeclBuilder &Builder;
327 TemplateParameterListBuilder(
Sema &S, BuiltinTypeDeclBuilder &RB)
328 : Builder(RB), S(S) {}
330 ~TemplateParameterListBuilder() { finalizeTemplateArgs(); }
332 TemplateParameterListBuilder &
334 if (Builder.Record->isCompleteDefinition())
336 unsigned Position =
static_cast<unsigned>(Params.size());
343 if (!DefaultValue.isNull())
344 Decl->setDefaultArgument(
348 Params.emplace_back(
Decl);
352 BuiltinTypeDeclBuilder &finalizeTemplateArgs() {
362 Builder.Record->setDescribedClassTemplate(Builder.Template);
363 Builder.Template->setImplicit(
true);
364 Builder.Template->setLexicalDeclContext(Builder.Record->getDeclContext());
367 Builder.Template->setPreviousDecl(Builder.PrevTemplate);
368 Builder.Record->getDeclContext()->addDecl(Builder.Template);
371 QualType T = Builder.Template->getInjectedClassNameSpecialization();
379TemplateParameterListBuilder
380BuiltinTypeDeclBuilder::addTemplateArgumentList(
Sema &S) {
381 return TemplateParameterListBuilder(S, *
this);
384BuiltinTypeDeclBuilder &
385BuiltinTypeDeclBuilder::addSimpleTemplateParams(
Sema &S,
387 TemplateParameterListBuilder Builder = this->addTemplateArgumentList(S);
388 for (StringRef Name : Names)
389 Builder.addTypeParameter(Name);
390 return Builder.finalizeTemplateArgs();
416 defineTrivialHLSLTypes();
417 defineHLSLTypesWithForwardDeclarations();
433void HLSLExternalSemaSource::defineHLSLVectorAlias() {
440 &AST.
Idents.
get(
"element", tok::TokenKind::identifier),
false,
false);
441 TypeParam->setDefaultArgument(
445 TemplateParams.emplace_back(TypeParam);
449 &AST.
Idents.
get(
"element_count", tok::TokenKind::identifier), AST.
IntTy,
454 SizeParam->setDefaultArgument(
457 TemplateParams.emplace_back(SizeParam);
476 Record->setImplicit(
true);
482 Record->setDescribedAliasTemplate(Template);
485 HLSLNamespace->
addDecl(Template);
488void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
489 defineHLSLVectorAlias();
494 ResourceClass RC, ResourceKind RK,
496 return BuiltinTypeDeclBuilder(
Decl)
497 .addHandleMember(RC, RK, IsROV)
498 .addDefaultHandleConstructor(S, RC);
501void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
503 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
"RWBuffer")
504 .addSimpleTemplateParams(*SemaPtr, {
"element_type"})
508 ResourceKind::TypedBuffer,
false)
509 .addArraySubscriptOperators()
510 .completeDefinition();
514 BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
"RasterizerOrderedBuffer")
515 .addSimpleTemplateParams(*SemaPtr, {
"element_type"})
519 ResourceKind::TypedBuffer,
true)
520 .addArraySubscriptOperators()
521 .completeDefinition();
526 CompletionFunction Fn) {
527 Completions.insert(std::make_pair(
Record->getCanonicalDecl(), Fn));
531 if (!isa<CXXRecordDecl>(Tag))
533 auto Record = cast<CXXRecordDecl>(Tag);
537 if (
auto TDecl = dyn_cast<ClassTemplateSpecializationDecl>(
Record))
538 Record = TDecl->getSpecializedTemplate()->getTemplatedDecl();
540 auto It = Completions.find(
Record);
541 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.
Attr - This represents one attribute.
A builtin binary operation expression such as "x + y" or "x <= y".
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
Represents a C++ constructor within a class.
static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited=InheritedConstructor(), Expr *TrailingRequiresClause=nullptr)
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)
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.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
Scope * getCurScope() const
Retrieve the parser's current scope.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupNamespaceName
Look up a namespace name within a C++ using directive or namespace alias definition,...
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
ASTContext & getASTContext() const
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
Encodes a location in the source.
A trivial tuple used to represent a source range.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
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)
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.