clang 22.0.0git
LexHLSLRootSignature.cpp
Go to the documentation of this file.
1//=== LexHLSLRootSignature.cpp - Lex Root Signature -----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11namespace clang {
12namespace hlsl {
13
15
16// Lexer Definitions
17
18static bool isNumberChar(char C) {
19 return isdigit(C) // integer support
20 || C == '.' // float support
21 || C == 'e' || C == 'E' || C == '-' || C == '+' // exponent support
22 || C == 'f' || C == 'F'; // explicit float support
23}
24
25RootSignatureToken RootSignatureLexer::lexToken() {
26 // Discard any leading whitespace
27 advanceBuffer(Buffer.take_while(isspace).size());
28
29 if (isEndOfBuffer())
30 return RootSignatureToken(TokenKind::end_of_stream, LocOffset);
31
32 // Record where this token is in the text for usage in parser diagnostics
33 RootSignatureToken Result(LocOffset);
34
35 char C = Buffer.front();
36
37 // Punctuators
38 switch (C) {
39#define PUNCTUATOR(X, Y) \
40 case Y: { \
41 Result.TokKind = TokenKind::pu_##X; \
42 advanceBuffer(); \
43 return Result; \
44 }
45#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
46 default:
47 break;
48 }
49
50 // Number literal
51 if (isdigit(C) || C == '.') {
52 Result.NumSpelling = Buffer.take_while(isNumberChar);
53
54 // If all values are digits then we have an int literal
55 bool IsInteger = Result.NumSpelling.find_if_not(isdigit) == StringRef::npos;
56
57 Result.TokKind =
58 IsInteger ? TokenKind::int_literal : TokenKind::float_literal;
59 advanceBuffer(Result.NumSpelling.size());
60 return Result;
61 }
62
63 // All following tokens require at least one additional character
64 if (Buffer.size() <= 1) {
65 Result = RootSignatureToken(TokenKind::invalid, LocOffset);
66 return Result;
67 }
68
69 // Peek at the next character to deteremine token type
70 char NextC = Buffer[1];
71
72 // Registers: [tsub][0-9+]
73 if ((C == 't' || C == 's' || C == 'u' || C == 'b') && isdigit(NextC)) {
74 // Convert character to the register type.
75 switch (C) {
76 case 'b':
77 Result.TokKind = TokenKind::bReg;
78 break;
79 case 't':
80 Result.TokKind = TokenKind::tReg;
81 break;
82 case 'u':
83 Result.TokKind = TokenKind::uReg;
84 break;
85 case 's':
86 Result.TokKind = TokenKind::sReg;
87 break;
88 default:
89 llvm_unreachable("Switch for an expected token was not provided");
90 }
91
92 advanceBuffer();
93
94 // Lex the integer literal
95 Result.NumSpelling = Buffer.take_while(isNumberChar);
96 advanceBuffer(Result.NumSpelling.size());
97
98 return Result;
99 }
100
101 // Keywords and Enums:
102 StringRef TokSpelling =
103 Buffer.take_while([](char C) { return isalnum(C) || C == '_'; });
104
105 // Define a large string switch statement for all the keywords and enums
106 auto Switch = llvm::StringSwitch<TokenKind>(TokSpelling);
107#define KEYWORD(NAME) Switch.CaseLower(#NAME, TokenKind::kw_##NAME);
108#define ENUM(NAME, LIT) Switch.CaseLower(LIT, TokenKind::en_##NAME);
109#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
110
111 // Then attempt to retreive a string from it
112 Result.TokKind = Switch.Default(TokenKind::invalid);
113 advanceBuffer(TokSpelling.size());
114 return Result;
115}
116
118 // If we previously peeked then just return the previous value over
119 if (NextToken && NextToken->TokKind != TokenKind::end_of_stream) {
120 RootSignatureToken Result = *NextToken;
121 NextToken = std::nullopt;
122 return Result;
123 }
124 return lexToken();
125}
126
128 // Already peeked from the current token
129 if (NextToken)
130 return *NextToken;
131
132 NextToken = lexToken();
133 return *NextToken;
134}
135
136} // namespace hlsl
137} // namespace clang
RootSignatureToken peekNextToken()
Returns the token that proceeds CurToken.
RootSignatureToken consumeToken()
Consumes and returns the next token.
static bool isNumberChar(char C)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.