25 bool IsCBuffer,
Parser &P) {
54 assert((Tok.is(tok::kw_cbuffer) || Tok.is(tok::kw_tbuffer)) &&
55 "Not a cbuffer or tbuffer!");
56 bool IsCBuffer = Tok.is(tok::kw_cbuffer);
59 if (!Tok.is(tok::identifier)) {
60 Diag(Tok, diag::err_expected) << tok::identifier;
64 IdentifierInfo *Identifier = Tok.getIdentifierInfo();
67 MaybeParseHLSLAnnotations(Attrs,
nullptr);
71 if (
T.consumeOpen()) {
72 Diag(Tok, diag::err_expected) << tok::l_brace;
76 Decl *D = Actions.HLSL().ActOnStartBuffer(
getCurScope(), IsCBuffer, BufferLoc,
77 Identifier, IdentifierLoc,
79 Actions.ProcessDeclAttributeList(Actions.CurScope, D, Attrs);
81 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
83 ParsedAttributes DeclAttrs(AttrFactory);
84 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
87 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
91 DeclEnd =
T.getCloseLocation();
93 Actions.HLSL().ActOnFinishBuffer(D, DeclEnd);
99 DeclEnd =
T.getCloseLocation();
101 Actions.HLSL().ActOnFinishBuffer(D, DeclEnd);
110 StringRef
Num = StringRef(
Tok.getLiteralData(),
Tok.getLength());
114 std::string FixedArg = ArgStr.str() +
Num.str();
115 P.
Diag(ArgLoc, diag::err_hlsl_separate_attr_arg_and_number)
122Parser::ParsedSemantic Parser::ParseHLSLSemantic() {
123 assert(Tok.is(tok::identifier) &&
"Not a HLSL Annotation");
130 SmallString<256> Buffer;
131 Buffer.resize(Tok.getLength() + 1);
132 StringRef Identifier = PP.getSpelling(Tok, Buffer);
133 assert(Identifier.size() > 0);
135 unsigned IndexIndex = Identifier.find_last_not_of(
"0123456789") + 1;
140 StringRef SemanticName = Identifier.take_front(IndexIndex);
141 assert(SemanticName.size() > 0);
145 if (IndexIndex != Identifier.size()) {
147 StringRef IndexStr = Identifier.substr(IndexIndex);
148 if (IndexStr.getAsInteger(10, Index)) {
149 Diag(Tok, diag::err_hlsl_semantic_index_out_of_range)
150 << PP.getIdentifierInfo(SemanticName) << IndexStr
151 << std::numeric_limits<uint32_t>::max();
155 return {SemanticName, Index,
Explicit};
160 bool CouldBeBitField) {
162 assert(Tok.is(tok::colon) &&
"Not a HLSL Annotation");
163 Token OldToken = Tok;
166 IdentifierInfo *II =
nullptr;
167 if (Tok.is(tok::kw_register))
168 II = PP.getIdentifierInfo(
"register");
169 else if (Tok.is(tok::identifier))
170 II = Tok.getIdentifierInfo();
173 if (CouldBeBitField) {
174 UnconsumeToken(OldToken);
177 Diag(Tok.getLocation(), diag::err_expected_semantic_identifier);
183 Parser::ParsedSemantic Semantic;
184 if (AttrKind == ParsedAttr::AT_HLSLUnparsedSemantic)
185 Semantic = ParseHLSLSemantic();
189 *EndLoc = Tok.getLocation();
191 SourceLocation AttrEndLoc = Loc;
194 case ParsedAttr::AT_HLSLResourceBinding: {
195 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after)) {
199 if (!Tok.is(tok::identifier)) {
200 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
204 StringRef SlotStr = Tok.getIdentifierInfo()->getName();
205 SourceLocation SlotLoc = Tok.getLocation();
206 ArgExprs.push_back(ParseIdentifierLoc());
208 if (SlotStr.size() == 1) {
209 if (!Tok.is(tok::numeric_constant)) {
210 Diag(Tok.getLocation(), diag::err_expected) << tok::numeric_constant;
216 Actions.Context, PP);
218 if (Tok.is(tok::comma)) {
220 if (!Tok.is(tok::identifier)) {
221 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
225 StringRef SpaceStr = Tok.getIdentifierInfo()->getName();
226 SourceLocation SpaceLoc = Tok.getLocation();
227 ArgExprs.push_back(ParseIdentifierLoc());
230 if (SpaceStr ==
"space" && Tok.is(tok::numeric_constant))
232 Actions.Context, PP);
234 AttrEndLoc = Tok.getLocation();
235 if (ExpectAndConsume(tok::r_paren, diag::err_expected)) {
240 case ParsedAttr::AT_HLSLPackOffset: {
243 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after)) {
248 if (!Tok.is(tok::identifier)) {
249 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
253 StringRef OffsetStr = Tok.getIdentifierInfo()->getName();
254 SourceLocation SubComponentLoc = Tok.getLocation();
255 if (OffsetStr[0] !=
'c') {
256 Diag(Tok.getLocation(), diag::err_hlsl_packoffset_invalid_reg)
261 OffsetStr = OffsetStr.substr(1);
262 unsigned SubComponent = 0;
263 if (!OffsetStr.empty()) {
265 if (OffsetStr.getAsInteger(10, SubComponent)) {
267 diag::err_hlsl_unsupported_register_number);
272 unsigned Component = 0;
274 SourceLocation ComponentLoc;
275 if (Tok.is(tok::period)) {
277 if (!Tok.is(tok::identifier)) {
278 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
282 StringRef ComponentStr = Tok.getIdentifierInfo()->getName();
283 ComponentLoc = Tok.getLocation();
286 if (ComponentStr.size() != 1) {
287 Diag(ComponentLoc, diag::err_hlsl_unsupported_component)
292 switch (ComponentStr[0]) {
310 Diag(ComponentLoc, diag::err_hlsl_unsupported_component)
316 ASTContext &Ctx = Actions.getASTContext();
320 Ctx, llvm::APInt(SizeTySize, SubComponent), SizeTy, SubComponentLoc));
322 Ctx, llvm::APInt(SizeTySize, Component), SizeTy, ComponentLoc));
323 if (ExpectAndConsume(tok::r_paren, diag::err_expected)) {
328 case ParsedAttr::AT_HLSLUnparsedSemantic: {
329 ASTContext &Ctx = Actions.getASTContext();
334 Ctx, llvm::APInt(1, Semantic.Explicit), Ctx.
BoolTy, SourceLocation()));
335 II = PP.getIdentifierInfo(Semantic.Name);
341 llvm_unreachable(
"invalid HLSL Annotation");
345 Attrs.
addNew(II, SourceRange(Loc, AttrEndLoc), AttributeScopeInfo(),
346 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.
Top level wrappers for InstallAPI frontend operations.
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