24 bool IsCBuffer,
Parser &P) {
53 assert((Tok.is(tok::kw_cbuffer) || Tok.is(tok::kw_tbuffer)) &&
54 "Not a cbuffer or tbuffer!");
55 bool IsCBuffer = Tok.is(tok::kw_cbuffer);
58 if (!Tok.is(tok::identifier)) {
59 Diag(Tok, diag::err_expected) << tok::identifier;
63 IdentifierInfo *Identifier = Tok.getIdentifierInfo();
66 MaybeParseHLSLAnnotations(Attrs,
nullptr);
70 if (
T.consumeOpen()) {
71 Diag(Tok, diag::err_expected) << tok::l_brace;
75 Decl *D = Actions.HLSL().ActOnStartBuffer(
getCurScope(), IsCBuffer, BufferLoc,
76 Identifier, IdentifierLoc,
78 Actions.ProcessDeclAttributeList(Actions.CurScope, D, Attrs);
80 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
82 ParsedAttributes DeclAttrs(AttrFactory);
83 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
86 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
90 DeclEnd =
T.getCloseLocation();
92 Actions.HLSL().ActOnFinishBuffer(D, DeclEnd);
98 DeclEnd =
T.getCloseLocation();
100 Actions.HLSL().ActOnFinishBuffer(D, DeclEnd);
109 StringRef
Num = StringRef(
Tok.getLiteralData(),
Tok.getLength());
113 std::string FixedArg = ArgStr.str() +
Num.str();
114 P.
Diag(ArgLoc, diag::err_hlsl_separate_attr_arg_and_number)
121Parser::ParsedSemantic Parser::ParseHLSLSemantic() {
122 assert(Tok.is(tok::identifier) &&
"Not a HLSL Annotation");
129 bool Invalid =
false;
130 SmallString<256> Buffer;
131 Buffer.resize(Tok.getLength() + 1);
132 StringRef Identifier = PP.getSpelling(Tok, Buffer);
134 Diag(Tok.getLocation(), diag::err_expected_semantic_identifier);
138 assert(Identifier.size() > 0);
140 unsigned IndexIndex = Identifier.find_last_not_of(
"0123456789") + 1;
145 StringRef SemanticName = Identifier.take_front(IndexIndex);
146 assert(SemanticName.size() > 0);
150 if (IndexIndex != Identifier.size()) {
152 [[maybe_unused]]
bool Failure =
153 Identifier.substr(IndexIndex).getAsInteger(10, Index);
158 return {SemanticName, Index,
Explicit};
163 bool CouldBeBitField) {
165 assert(Tok.is(tok::colon) &&
"Not a HLSL Annotation");
166 Token OldToken = Tok;
169 IdentifierInfo *II =
nullptr;
170 if (Tok.is(tok::kw_register))
171 II = PP.getIdentifierInfo(
"register");
172 else if (Tok.is(tok::identifier))
173 II = Tok.getIdentifierInfo();
176 if (CouldBeBitField) {
177 UnconsumeToken(OldToken);
180 Diag(Tok.getLocation(), diag::err_expected_semantic_identifier);
186 Parser::ParsedSemantic Semantic;
187 if (AttrKind == ParsedAttr::AT_HLSLUnparsedSemantic)
188 Semantic = ParseHLSLSemantic();
192 *EndLoc = Tok.getLocation();
196 case ParsedAttr::AT_HLSLResourceBinding: {
197 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after)) {
201 if (!Tok.is(tok::identifier)) {
202 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
206 StringRef SlotStr = Tok.getIdentifierInfo()->getName();
207 SourceLocation SlotLoc = Tok.getLocation();
208 ArgExprs.push_back(ParseIdentifierLoc());
210 if (SlotStr.size() == 1) {
211 if (!Tok.is(tok::numeric_constant)) {
212 Diag(Tok.getLocation(), diag::err_expected) << tok::numeric_constant;
218 Actions.Context, PP);
220 if (Tok.is(tok::comma)) {
222 if (!Tok.is(tok::identifier)) {
223 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
227 StringRef SpaceStr = Tok.getIdentifierInfo()->getName();
228 SourceLocation SpaceLoc = Tok.getLocation();
229 ArgExprs.push_back(ParseIdentifierLoc());
232 if (SpaceStr ==
"space" && Tok.is(tok::numeric_constant))
234 Actions.Context, PP);
236 if (ExpectAndConsume(tok::r_paren, diag::err_expected)) {
241 case ParsedAttr::AT_HLSLPackOffset: {
244 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after)) {
249 if (!Tok.is(tok::identifier)) {
250 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
254 StringRef OffsetStr = Tok.getIdentifierInfo()->getName();
255 SourceLocation SubComponentLoc = Tok.getLocation();
256 if (OffsetStr[0] !=
'c') {
257 Diag(Tok.getLocation(), diag::err_hlsl_packoffset_invalid_reg)
262 OffsetStr = OffsetStr.substr(1);
263 unsigned SubComponent = 0;
264 if (!OffsetStr.empty()) {
266 if (OffsetStr.getAsInteger(10, SubComponent)) {
268 diag::err_hlsl_unsupported_register_number);
273 unsigned Component = 0;
275 SourceLocation ComponentLoc;
276 if (Tok.is(tok::period)) {
278 if (!Tok.is(tok::identifier)) {
279 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
283 StringRef ComponentStr = Tok.getIdentifierInfo()->getName();
284 ComponentLoc = Tok.getLocation();
287 if (ComponentStr.size() != 1) {
288 Diag(ComponentLoc, diag::err_hlsl_unsupported_component)
293 switch (ComponentStr[0]) {
311 Diag(ComponentLoc, diag::err_hlsl_unsupported_component)
317 ASTContext &Ctx = Actions.getASTContext();
321 Ctx, llvm::APInt(SizeTySize, SubComponent), SizeTy, SubComponentLoc));
323 Ctx, llvm::APInt(SizeTySize, Component), SizeTy, ComponentLoc));
324 if (ExpectAndConsume(tok::r_paren, diag::err_expected)) {
329 case ParsedAttr::AT_HLSLUnparsedSemantic: {
330 ASTContext &Ctx = Actions.getASTContext();
335 Ctx, llvm::APInt(1, Semantic.Explicit), Ctx.
BoolTy, SourceLocation()));
336 II = PP.getIdentifierInfo(Semantic.Name);
342 llvm_unreachable(
"invalid HLSL Annotation");
346 Attrs.
addNew(II, Loc, AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(),
347 ParsedAttr::Form::HLSLAnnotation());
static bool validateDeclsInsideHLSLBuffer(Parser::DeclGroupPtrTy DG, SourceLocation BufferLoc, bool IsCBuffer, Parser &P)
static void fixSeparateAttrArgAndNumber(StringRef ArgStr, SourceLocation ArgLoc, Token Tok, ArgsVector &ArgExprs, Parser &P, ASTContext &Ctx, Preprocessor &PP)
This file declares semantic analysis for HLSL constructs.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
@ AS_HLSLAnnotation
<vardecl> : <annotation>
Kind getParsedKind() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
A simple pair of identifier info and location.
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'.
ParsedAttributes - A collection of parsed attributes.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
@ StopAtSemi
Stop skipping at semicolon.
friend class BalancedDelimiterTracker
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
@ DeclScope
This is a scope that can contain a declaration.
Encodes a location in the source.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
A trivial tuple used to represent a source range.
Token - This structure provides full information about a lexed token.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
@ Result
The result type of a method or function.
const FunctionProtoType * T