20 #include "llvm/Frontend/HLSL/HLSLResource.h"
24 using namespace clang;
25 using namespace llvm::hlsl;
29 struct TemplateParameterListBuilder;
31 struct 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!");
97 Field->setAccess(Access);
98 Field->setImplicit(
true);
100 Fields[Name] =
Field;
104 BuiltinTypeDeclBuilder &
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(),
138 assert(R.isSingleResult() &&
139 "Since this is a builtin it should always resolve!");
140 auto *VD = cast<ValueDecl>(R.getFoundDecl());
146 static Expr *emitResourceClassExpr(
ASTContext &AST, ResourceClass RC) {
150 static_cast<uint8_t
>(RC)),
154 BuiltinTypeDeclBuilder &addDefaultHandleConstructor(
Sema &S,
156 if (
Record->isCompleteDefinition())
173 lookupBuiltinFunction(AST, S,
"__builtin_hlsl_create_handle");
175 Expr *RCExpr = emitResourceClassExpr(AST, RC);
204 Record->addDecl(Constructor);
208 BuiltinTypeDeclBuilder &addArraySubscriptOperators() {
209 if (
Record->isCompleteDefinition())
211 addArraySubscriptOperator(
true);
212 addArraySubscriptOperator(
false);
216 BuiltinTypeDeclBuilder &addArraySubscriptOperator(
bool IsConst) {
217 if (
Record->isCompleteDefinition())
219 assert(Fields.count(
"h") > 0 &&
220 "Subscript operator must be added after the handle.");
226 "Not yet supported for void pointer handles.");
259 MethodDecl->setParams({IdxParam});
267 MethodDecl->getFunctionObjectParameterType(),
true);
285 MethodDecl->setLexicalDeclContext(
Record);
287 MethodDecl->addAttr(AlwaysInlineAttr::CreateImplicit(
288 AST,
SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
289 Record->addDecl(MethodDecl);
294 BuiltinTypeDeclBuilder &startDefinition() {
295 if (
Record->isCompleteDefinition())
297 Record->startDefinition();
301 BuiltinTypeDeclBuilder &completeDefinition() {
302 if (
Record->isCompleteDefinition())
304 assert(
Record->isBeingDefined() &&
305 "Definition must be started before completing it.");
307 Record->completeDefinition();
311 TemplateParameterListBuilder addTemplateArgumentList(
Sema &S);
312 BuiltinTypeDeclBuilder &addSimpleTemplateParams(
Sema &S,
316 struct TemplateParameterListBuilder {
317 BuiltinTypeDeclBuilder &Builder;
321 TemplateParameterListBuilder(
Sema &S, BuiltinTypeDeclBuilder &RB)
322 : Builder(RB), S(S) {}
324 ~TemplateParameterListBuilder() { finalizeTemplateArgs(); }
326 TemplateParameterListBuilder &
328 if (Builder.Record->isCompleteDefinition())
330 unsigned Position =
static_cast<unsigned>(Params.size());
337 if (!DefaultValue.isNull())
338 Decl->setDefaultArgument(
342 Params.emplace_back(
Decl);
346 BuiltinTypeDeclBuilder &finalizeTemplateArgs() {
356 Builder.Record->setDescribedClassTemplate(Builder.Template);
357 Builder.Template->setImplicit(
true);
358 Builder.Template->setLexicalDeclContext(Builder.Record->getDeclContext());
361 Builder.Template->setPreviousDecl(Builder.PrevTemplate);
362 Builder.Record->getDeclContext()->addDecl(Builder.Template);
365 QualType T = Builder.Template->getInjectedClassNameSpecialization();
373 TemplateParameterListBuilder
374 BuiltinTypeDeclBuilder::addTemplateArgumentList(
Sema &S) {
375 return TemplateParameterListBuilder(S, *
this);
378 BuiltinTypeDeclBuilder &
379 BuiltinTypeDeclBuilder::addSimpleTemplateParams(
Sema &S,
381 TemplateParameterListBuilder Builder = this->addTemplateArgumentList(S);
382 for (StringRef Name : Names)
383 Builder.addTypeParameter(Name);
384 return Builder.finalizeTemplateArgs();
410 defineTrivialHLSLTypes();
411 defineHLSLTypesWithForwardDeclarations();
427 void HLSLExternalSemaSource::defineHLSLVectorAlias() {
434 &AST.
Idents.
get(
"element", tok::TokenKind::identifier),
false,
false);
435 TypeParam->setDefaultArgument(
436 AST, SemaPtr->getTrivialTemplateArgumentLoc(
439 TemplateParams.emplace_back(TypeParam);
443 &AST.
Idents.
get(
"element_count", tok::TokenKind::identifier), AST.
IntTy,
448 SizeParam->setDefaultArgument(
449 AST, SemaPtr->getTrivialTemplateArgumentLoc(Default, AST.
IntTy,
451 TemplateParams.emplace_back(SizeParam);
470 Record->setImplicit(
true);
476 Record->setDescribedAliasTemplate(Template);
479 HLSLNamespace->
addDecl(Template);
482 void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
483 defineHLSLVectorAlias();
485 ResourceDecl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
"Resource")
488 .completeDefinition()
494 ResourceClass RC, ResourceKind RK,
496 return BuiltinTypeDeclBuilder(
Decl)
498 .addDefaultHandleConstructor(S, RC)
499 .annotateResourceClass(RC, RK, IsROV);
502 void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
504 Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
"RWBuffer")
505 .addSimpleTemplateParams(*SemaPtr, {
"element_type"})
509 ResourceKind::TypedBuffer,
false)
510 .addArraySubscriptOperators()
511 .completeDefinition();
515 BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
"RasterizerOrderedBuffer")
516 .addSimpleTemplateParams(*SemaPtr, {
"element_type"})
520 ResourceKind::TypedBuffer,
true)
521 .addArraySubscriptOperators()
522 .completeDefinition();
527 CompletionFunction Fn) {
528 Completions.insert(std::make_pair(
Record->getCanonicalDecl(), Fn));
532 if (!isa<CXXRecordDecl>(Tag))
534 auto Record = cast<CXXRecordDecl>(Tag);
538 if (
auto TDecl = dyn_cast<ClassTemplateSpecializationDecl>(
Record))
539 Record = TDecl->getSpecializedTemplate()->getTemplatedDecl();
541 auto It = Completions.find(
Record);
542 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 ...
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
TranslationUnitDecl * getTranslationUnitDecl() 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)
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 InitializeSema(Sema &S) override
Initialize the semantic source with the Sema instance being used to perform semantic analysis on the ...
~HLSLExternalSemaSource() override
virtual void CompleteType(TagDecl *Tag)
Gives the external AST source an opportunity to complete an incomplete type.
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.
@ 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.
Scope * getCurScope() const
Retrieve the parser's current scope.
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.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
NamedDecl * getParam(unsigned Idx)
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 Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
bool This(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ ICIS_NoInit
No in-class initializer.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Class
The "class" keyword.
@ 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.