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
9#include "clang/Lex/LexHLSLRootSignature.h"
10
11namespace clang {
12namespace hlsl {
13
14using TokenKind = RootSignatureToken::Kind;
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(NumCharacters: Buffer.take_while(F: isspace).size());
28
29 if (isEndOfBuffer())
30 return RootSignatureToken(TokenKind::end_of_stream, SourceLoc);
31
32 // Record where this token is in the text for usage in parser diagnostics
33 RootSignatureToken Result(SourceLoc);
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(F: isNumberChar);
53
54 // If all values are digits then we have an int literal
55 bool IsInteger = Result.NumSpelling.find_if_not(F: isdigit) == StringRef::npos;
56
57 Result.TokKind =
58 IsInteger ? TokenKind::int_literal : TokenKind::float_literal;
59 advanceBuffer(NumCharacters: 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, SourceLoc);
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(F: isNumberChar);
96 advanceBuffer(NumCharacters: Result.NumSpelling.size());
97
98 return Result;
99 }
100
101 // Keywords and Enums:
102 StringRef TokSpelling =
103 Buffer.take_while(F: [](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(Value: TokenKind::invalid);
113 advanceBuffer(NumCharacters: TokSpelling.size());
114 return Result;
115}
116
117RootSignatureToken RootSignatureLexer::consumeToken() {
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
127RootSignatureToken RootSignatureLexer::peekNextToken() {
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
138

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang/lib/Lex/LexHLSLRootSignature.cpp