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)
RootSignatureToken::Kind TokenKind
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
Definition TypeBase.h:905