Path: blob/main/contrib/llvm-project/clang/lib/Lex/LexHLSLRootSignature.cpp
213766 views
//=== LexHLSLRootSignature.cpp - Lex Root Signature -----------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "clang/Lex/LexHLSLRootSignature.h"910namespace clang {11namespace hlsl {1213using TokenKind = RootSignatureToken::Kind;1415// Lexer Definitions1617static bool isNumberChar(char C) {18return isdigit(C) // integer support19|| C == '.' // float support20|| C == 'e' || C == 'E' || C == '-' || C == '+' // exponent support21|| C == 'f' || C == 'F'; // explicit float support22}2324RootSignatureToken RootSignatureLexer::lexToken() {25// Discard any leading whitespace26advanceBuffer(Buffer.take_while(isspace).size());2728if (isEndOfBuffer())29return RootSignatureToken(TokenKind::end_of_stream, LocOffset);3031// Record where this token is in the text for usage in parser diagnostics32RootSignatureToken Result(LocOffset);3334char C = Buffer.front();3536// Punctuators37switch (C) {38#define PUNCTUATOR(X, Y) \39case Y: { \40Result.TokKind = TokenKind::pu_##X; \41advanceBuffer(); \42return Result; \43}44#include "clang/Lex/HLSLRootSignatureTokenKinds.def"45default:46break;47}4849// Number literal50if (isdigit(C) || C == '.') {51Result.NumSpelling = Buffer.take_while(isNumberChar);5253// If all values are digits then we have an int literal54bool IsInteger = Result.NumSpelling.find_if_not(isdigit) == StringRef::npos;5556Result.TokKind =57IsInteger ? TokenKind::int_literal : TokenKind::float_literal;58advanceBuffer(Result.NumSpelling.size());59return Result;60}6162// All following tokens require at least one additional character63if (Buffer.size() <= 1) {64Result = RootSignatureToken(TokenKind::invalid, LocOffset);65return Result;66}6768// Peek at the next character to deteremine token type69char NextC = Buffer[1];7071// Registers: [tsub][0-9+]72if ((C == 't' || C == 's' || C == 'u' || C == 'b') && isdigit(NextC)) {73// Convert character to the register type.74switch (C) {75case 'b':76Result.TokKind = TokenKind::bReg;77break;78case 't':79Result.TokKind = TokenKind::tReg;80break;81case 'u':82Result.TokKind = TokenKind::uReg;83break;84case 's':85Result.TokKind = TokenKind::sReg;86break;87default:88llvm_unreachable("Switch for an expected token was not provided");89}9091advanceBuffer();9293// Lex the integer literal94Result.NumSpelling = Buffer.take_while(isNumberChar);95advanceBuffer(Result.NumSpelling.size());9697return Result;98}99100// Keywords and Enums:101StringRef TokSpelling =102Buffer.take_while([](char C) { return isalnum(C) || C == '_'; });103104// Define a large string switch statement for all the keywords and enums105auto Switch = llvm::StringSwitch<TokenKind>(TokSpelling);106#define KEYWORD(NAME) Switch.CaseLower(#NAME, TokenKind::kw_##NAME);107#define ENUM(NAME, LIT) Switch.CaseLower(LIT, TokenKind::en_##NAME);108#include "clang/Lex/HLSLRootSignatureTokenKinds.def"109110// Then attempt to retreive a string from it111Result.TokKind = Switch.Default(TokenKind::invalid);112advanceBuffer(TokSpelling.size());113return Result;114}115116RootSignatureToken RootSignatureLexer::consumeToken() {117// If we previously peeked then just return the previous value over118if (NextToken && NextToken->TokKind != TokenKind::end_of_stream) {119RootSignatureToken Result = *NextToken;120NextToken = std::nullopt;121return Result;122}123return lexToken();124}125126RootSignatureToken RootSignatureLexer::peekNextToken() {127// Already peeked from the current token128if (NextToken)129return *NextToken;130131NextToken = lexToken();132return *NextToken;133}134135} // namespace hlsl136} // namespace clang137138139