clang: lib/Parse/ParseHLSL.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

19

20using namespace clang;

21

24 bool IsCBuffer, Parser &P) {

25

26 if (!DG)

27 return false;

29 bool IsValid = true;

30

33 if (isa<CXXRecordDecl, RecordDecl, FunctionDecl, VarDecl>(D))

34 continue;

35

36

37 if (isa<HLSLBufferDecl, NamespaceDecl>(D)) {

38 P.Diag(D->getLocation(), diag::err_invalid_declaration_in_hlsl_buffer)

39 << IsCBuffer;

40 IsValid = false;

41 continue;

42 }

43

44 IsValid = false;

45 P.Diag(D->getLocation(), diag::err_invalid_declaration_in_hlsl_buffer)

46 << IsCBuffer;

47 }

48 return IsValid;

49}

50

52 assert((Tok.is(tok::kw_cbuffer) || Tok.is(tok::kw_tbuffer)) &&

53 "Not a cbuffer or tbuffer!");

54 bool IsCBuffer = Tok.is(tok::kw_cbuffer);

56

57 if (!Tok.is(tok::identifier)) {

58 Diag(Tok, diag::err_expected) << tok::identifier;

59 return nullptr;

60 }

61

64

66 MaybeParseHLSLAnnotations(Attrs, nullptr);

67

70 if (T.consumeOpen()) {

71 Diag(Tok, diag::err_expected) << tok::l_brace;

72 return nullptr;

73 }

74

77 T.getOpenLocation());

78

79 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {

80

83

85 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);

87 *this)) {

88 T.skipToEnd();

89 DeclEnd = T.getCloseLocation();

90 BufferScope.Exit();

92 return nullptr;

93 }

94 }

95

96 T.consumeClose();

97 DeclEnd = T.getCloseLocation();

98 BufferScope.Exit();

100

102 return D;

103}

104

111

112 P.ConsumeToken();

113 std::string FixedArg = ArgStr.str() + Num.str();

114 P.Diag(ArgLoc, diag::err_hlsl_separate_attr_arg_and_number)

115 << FixedArg

117 ArgsUnion &Slot = ArgExprs.back();

119}

120

123 bool CouldBeBitField) {

124

125 assert(Tok.is(tok::colon) && "Not a HLSL Annotation");

126 Token OldToken = Tok;

128

130 if (Tok.is(tok::kw_register))

132 else if (Tok.is(tok::identifier))

134

135 if (!II) {

136 if (CouldBeBitField) {

137 UnconsumeToken(OldToken);

138 return;

139 }

140 Diag(Tok.getLocation(), diag::err_expected_semantic_identifier);

141 return;

142 }

143

145 if (EndLoc)

149

151 switch (AttrKind) {

152 case ParsedAttr::AT_HLSLResourceBinding: {

153 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after)) {

155 return;

156 }

157 if (!Tok.is(tok::identifier)) {

158 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;

160 return;

161 }

164 ArgExprs.push_back(ParseIdentifierLoc());

165

166

167 if (SlotStr.size() == 1 && Tok.is(tok::numeric_constant))

170

171 if (Tok.is(tok::comma)) {

173 if (!Tok.is(tok::identifier)) {

174 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;

176 return;

177 }

180 ArgExprs.push_back(ParseIdentifierLoc());

181

182

183 if (SpaceStr == "space" && Tok.is(tok::numeric_constant))

186 }

187 if (ExpectAndConsume(tok::r_paren, diag::err_expected)) {

189 return;

190 }

191 } break;

192 case ParsedAttr::AT_HLSLPackOffset: {

193

194

195 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after)) {

197 return;

198 }

199

200 if (!Tok.is(tok::identifier)) {

201 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;

203 return;

204 }

207 if (OffsetStr[0] != 'c') {

208 Diag(Tok.getLocation(), diag::err_hlsl_packoffset_invalid_reg)

209 << OffsetStr;

211 return;

212 }

213 OffsetStr = OffsetStr.substr(1);

214 unsigned SubComponent = 0;

215 if (!OffsetStr.empty()) {

216

217 if (OffsetStr.getAsInteger(10, SubComponent)) {

219 diag::err_hlsl_unsupported_register_number);

221 return;

222 }

223 }

224 unsigned Component = 0;

227 if (Tok.is(tok::period)) {

229 if (!Tok.is(tok::identifier)) {

230 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;

232 return;

233 }

237

238 if (ComponentStr.size() != 1) {

239 Diag(ComponentLoc, diag::err_hlsl_unsupported_component)

240 << ComponentStr;

242 return;

243 }

244 switch (ComponentStr[0]) {

245 case 'x':

246 case 'r':

247 Component = 0;

248 break;

249 case 'y':

250 case 'g':

251 Component = 1;

252 break;

253 case 'z':

254 case 'b':

255 Component = 2;

256 break;

257 case 'w':

258 case 'a':

259 Component = 3;

260 break;

261 default:

262 Diag(ComponentLoc, diag::err_hlsl_unsupported_component)

263 << ComponentStr;

265 return;

266 }

267 }

272 Ctx, llvm::APInt(SizeTySize, SubComponent), SizeTy, SubComponentLoc));

274 Ctx, llvm::APInt(SizeTySize, Component), SizeTy, ComponentLoc));

275 if (ExpectAndConsume(tok::r_paren, diag::err_expected)) {

277 return;

278 }

279 } break;

281 Diag(Loc, diag::err_unknown_hlsl_semantic) << II;

282 return;

283 case ParsedAttr::AT_HLSLSV_GroupThreadID:

284 case ParsedAttr::AT_HLSLSV_GroupID:

285 case ParsedAttr::AT_HLSLSV_GroupIndex:

286 case ParsedAttr::AT_HLSLSV_DispatchThreadID:

287 break;

288 default:

289 llvm_unreachable("invalid HLSL Annotation");

290 break;

291 }

292

294 ArgExprs.size(), ParsedAttr::Form::HLSLAnnotation());

295}

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 ...

CanQualType getSizeType() const

Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

@ AS_HLSLAnnotation

:

Kind getParsedKind() const

RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....

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.

One of these records is kept for each identifier that is lexed.

StringRef getName() const

Return the actual identifier string.

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'.

Wrapper for void* pointer.

ParsedAttributes - A collection of parsed attributes.

ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())

Add attribute with expression arguments.

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.

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.

A (possibly-)qualified type.

@ DeclScope

This is a scope that can contain a declaration.

void ActOnFinishBuffer(Decl *Dcl, SourceLocation RBrace)

Decl * ActOnStartBuffer(Scope *BufferScope, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *Ident, SourceLocation IdentLoc, SourceLocation LBrace)

ASTContext & getASTContext() const

void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())

ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...

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.

IdentifierInfo * getIdentifierInfo() const

SourceLocation getEndLoc() const

SourceLocation getLocation() const

Return a source location identifier for the specified offset in the current file.

unsigned getLength() const

bool is(tok::TokenKind K) const

is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....

bool isNot(tok::TokenKind K) const

const char * getLiteralData() const

getLiteralData - For a literal token (numeric constant, string, etc), this returns a pointer to the s...

The JSON file list parser is used to communicate input to InstallAPI.

llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion

A union of the various pointer types that can be passed to an ParsedAttr as an argument.

@ Result

The result type of a method or function.

const FunctionProtoType * T

Wraps an identifier and optional source location for the identifier.

static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)