-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[HLSL][RootSignature] Implement Lexing of DescriptorTables #122981
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
98deff6
[HLSL][RootSignature] Initial Lexer Definition with puncuators
inbelic 5f43ed8
Add lexing of integer literals
inbelic dc0c7ba
Add support for lexing registers
inbelic c5d3881
Add lexing for example keyword and enum
inbelic dc784ff
Add lexing for remaining DescriptorTable keywords and enums
inbelic 82c645d
review: update uses of llvm_unreachable
inbelic 1c95e6d
review: update target test triple with comment
inbelic d648f4c
review: dealing with signed positive integer
inbelic de2f62e
review: update diagnostics message
inbelic f557d5a
review: update linked todo
inbelic de364d8
review: remove api for pre-allocating tokens
inbelic 35c1566
clang format
inbelic 8ac979c
review: fix some typos
inbelic 0c372bf
review: remove unique end_of_stream lexing error
inbelic e58c89a
review: remove unique invalid_token lexing error
inbelic aa7a73d
review: punt parsing of a signed integer to the parser
inbelic ca2a2cb
self-review: define an error token to denote lex errors during peek
inbelic 8345ff1
review: defer handling of numeric constants to the parser -> remove e…
inbelic 5439fa8
review: move to lex dir
inbelic cf9788e
review: clean up after moving
inbelic 6a5545f
self-review: whoops missed renaming header guards
inbelic 7f27295
Update clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
inbelic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
124 changes: 124 additions & 0 deletions
124
clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
//===--- HLSLRootSignature.def - Tokens and Enum Database -------*- C++ -*-===// | ||
|
||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file defines the TokenKinds used in the Root Signature DSL. This | ||
// includes keywords, enums and a small subset of punctuators. Users of this | ||
// file must optionally #define the TOK, KEYWORD, ENUM or specific ENUM macros | ||
// to make use of this file. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef TOK | ||
#define TOK(X) | ||
#endif | ||
#ifndef PUNCTUATOR | ||
#define PUNCTUATOR(X,Y) TOK(pu_ ## X) | ||
#endif | ||
#ifndef KEYWORD | ||
#define KEYWORD(X) TOK(kw_ ## X) | ||
#endif | ||
#ifndef ENUM | ||
#define ENUM(NAME, LIT) TOK(en_ ## NAME) | ||
#endif | ||
|
||
// Defines the various types of enum | ||
#ifndef DESCRIPTOR_RANGE_OFFSET_ENUM | ||
#define DESCRIPTOR_RANGE_OFFSET_ENUM(NAME, LIT) ENUM(NAME, LIT) | ||
#endif | ||
#ifndef ROOT_DESCRIPTOR_FLAG_ENUM | ||
#define ROOT_DESCRIPTOR_FLAG_ENUM(NAME, LIT) ENUM(NAME, LIT) | ||
#endif | ||
// Note: ON denotes that the flag is unique from the above Root Descriptor | ||
// Flags. This is required to avoid token kind enum conflicts. | ||
#ifndef DESCRIPTOR_RANGE_FLAG_ENUM_OFF | ||
#define DESCRIPTOR_RANGE_FLAG_ENUM_OFF(NAME, LIT) | ||
#endif | ||
#ifndef DESCRIPTOR_RANGE_FLAG_ENUM_ON | ||
#define DESCRIPTOR_RANGE_FLAG_ENUM_ON(NAME, LIT) ENUM(NAME, LIT) | ||
#endif | ||
#ifndef DESCRIPTOR_RANGE_FLAG_ENUM | ||
#define DESCRIPTOR_RANGE_FLAG_ENUM(NAME, LIT, ON) DESCRIPTOR_RANGE_FLAG_ENUM_##ON(NAME, LIT) | ||
#endif | ||
#ifndef SHADER_VISIBILITY_ENUM | ||
#define SHADER_VISIBILITY_ENUM(NAME, LIT) ENUM(NAME, LIT) | ||
#endif | ||
|
||
// General Tokens: | ||
TOK(invalid) | ||
TOK(end_of_stream) | ||
TOK(int_literal) | ||
|
||
// Register Tokens: | ||
TOK(bReg) | ||
TOK(tReg) | ||
TOK(uReg) | ||
TOK(sReg) | ||
|
||
// Punctuators: | ||
PUNCTUATOR(l_paren, '(') | ||
PUNCTUATOR(r_paren, ')') | ||
PUNCTUATOR(comma, ',') | ||
PUNCTUATOR(or, '|') | ||
PUNCTUATOR(equal, '=') | ||
PUNCTUATOR(plus, '+') | ||
PUNCTUATOR(minus, '-') | ||
|
||
// RootElement Keywords: | ||
KEYWORD(DescriptorTable) | ||
|
||
// DescriptorTable Keywords: | ||
KEYWORD(CBV) | ||
KEYWORD(SRV) | ||
KEYWORD(UAV) | ||
KEYWORD(Sampler) | ||
|
||
// General Parameter Keywords: | ||
KEYWORD(space) | ||
KEYWORD(visibility) | ||
KEYWORD(flags) | ||
|
||
// View Parameter Keywords: | ||
KEYWORD(numDescriptors) | ||
KEYWORD(offset) | ||
|
||
// Descriptor Range Offset Enum: | ||
DESCRIPTOR_RANGE_OFFSET_ENUM(DescriptorRangeOffsetAppend, "DESCRIPTOR_RANGE_OFFSET_APPEND") | ||
|
||
// Root Descriptor Flag Enums: | ||
ROOT_DESCRIPTOR_FLAG_ENUM(DataVolatile, "DATA_VOLATILE") | ||
ROOT_DESCRIPTOR_FLAG_ENUM(DataStaticWhileSetAtExecute, "DATA_STATIC_WHILE_SET_AT_EXECUTE") | ||
ROOT_DESCRIPTOR_FLAG_ENUM(DataStatic, "DATA_STATIC") | ||
|
||
// Descriptor Range Flag Enums: | ||
DESCRIPTOR_RANGE_FLAG_ENUM(DescriptorsVolatile, "DESCRIPTORS_VOLATILE", ON) | ||
DESCRIPTOR_RANGE_FLAG_ENUM(DataVolatile, "DATA_VOLATILE", OFF) | ||
DESCRIPTOR_RANGE_FLAG_ENUM(DataStaticWhileSetAtExecute, "DATA_STATIC_WHILE_SET_AT_EXECUTE", OFF) | ||
DESCRIPTOR_RANGE_FLAG_ENUM(DataStatic, "DATA_STATIC", OFF) | ||
DESCRIPTOR_RANGE_FLAG_ENUM(DescriptorsStaticKeepingBufferBoundsChecks, "DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS", ON) | ||
|
||
// Shader Visibiliy Enums: | ||
SHADER_VISIBILITY_ENUM(All, "SHADER_VISIBILITY_ALL") | ||
SHADER_VISIBILITY_ENUM(Vertex, "SHADER_VISIBILITY_VERTEX") | ||
SHADER_VISIBILITY_ENUM(Hull, "SHADER_VISIBILITY_HULL") | ||
SHADER_VISIBILITY_ENUM(Domain, "SHADER_VISIBILITY_DOMAIN") | ||
SHADER_VISIBILITY_ENUM(Geometry, "SHADER_VISIBILITY_GEOMETRY") | ||
SHADER_VISIBILITY_ENUM(Pixel, "SHADER_VISIBILITY_PIXEL") | ||
SHADER_VISIBILITY_ENUM(Amplification, "SHADER_VISIBILITY_AMPLIFICATION") | ||
SHADER_VISIBILITY_ENUM(Mesh, "SHADER_VISIBILITY_MESH") | ||
|
||
#undef SHADER_VISIBILITY_ENUM | ||
#undef DESCRIPTOR_RANGE_FLAG_ENUM | ||
#undef DESCRIPTOR_RANGE_FLAG_ENUM_OFF | ||
#undef DESCRIPTOR_RANGE_FLAG_ENUM_ON | ||
#undef ROOT_DESCRIPTOR_FLAG_ENUM | ||
#undef DESCRIPTOR_RANGE_OFFSET_ENUM | ||
#undef ENUM | ||
#undef KEYWORD | ||
#undef PUNCTUATOR | ||
#undef TOK |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
//===--- LexHLSLRootSignature.h ---------------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file defines the LexHLSLRootSignature interface. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_LEX_LEXHLSLROOTSIGNATURE_H | ||
#define LLVM_CLANG_LEX_LEXHLSLROOTSIGNATURE_H | ||
|
||
#include "clang/Basic/SourceLocation.h" | ||
|
||
#include "llvm/ADT/SmallVector.h" | ||
#include "llvm/ADT/StringRef.h" | ||
#include "llvm/ADT/StringSwitch.h" | ||
|
||
namespace clang { | ||
namespace hlsl { | ||
|
||
struct RootSignatureToken { | ||
enum Kind { | ||
#define TOK(X) X, | ||
#include "clang/Lex/HLSLRootSignatureTokenKinds.def" | ||
}; | ||
|
||
Kind Kind = Kind::invalid; | ||
|
||
// Retain the SouceLocation of the token for diagnostics | ||
clang::SourceLocation TokLoc; | ||
|
||
// Retain spelling of an numeric constant to be parsed later | ||
StringRef NumSpelling; | ||
|
||
// Constructors | ||
RootSignatureToken(clang::SourceLocation TokLoc) : TokLoc(TokLoc) {} | ||
RootSignatureToken(enum Kind Kind, clang::SourceLocation TokLoc) | ||
: Kind(Kind), TokLoc(TokLoc) {} | ||
}; | ||
using TokenKind = enum RootSignatureToken::Kind; | ||
|
||
class RootSignatureLexer { | ||
public: | ||
RootSignatureLexer(StringRef Signature, clang::SourceLocation SourceLoc) | ||
: Buffer(Signature), SourceLoc(SourceLoc) {} | ||
|
||
/// Consumes and returns the next token. | ||
RootSignatureToken ConsumeToken(); | ||
|
||
/// Returns the token that proceeds CurToken | ||
RootSignatureToken PeekNextToken(); | ||
|
||
bool EndOfBuffer() { | ||
AdvanceBuffer(Buffer.take_while(isspace).size()); | ||
return Buffer.empty(); | ||
} | ||
|
||
private: | ||
// Internal buffer to iterate over | ||
StringRef Buffer; | ||
|
||
// Current peek state | ||
std::optional<RootSignatureToken> NextToken = std::nullopt; | ||
|
||
// Passed down parameters from Sema | ||
clang::SourceLocation SourceLoc; | ||
|
||
/// Consumes the buffer and returns the lexed token. | ||
RootSignatureToken LexToken(); | ||
|
||
/// Advance the buffer by the specified number of characters. | ||
/// Updates the SourceLocation appropriately. | ||
void AdvanceBuffer(unsigned NumCharacters = 1) { | ||
Buffer = Buffer.drop_front(NumCharacters); | ||
SourceLoc = SourceLoc.getLocWithOffset(NumCharacters); | ||
} | ||
}; | ||
|
||
} // namespace hlsl | ||
} // namespace clang | ||
|
||
#endif // LLVM_CLANG_LEX_PARSEHLSLROOTSIGNATURE_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#include "clang/Lex/LexHLSLRootSignature.h" | ||
|
||
namespace clang { | ||
namespace hlsl { | ||
|
||
// Lexer Definitions | ||
|
||
static bool IsNumberChar(char C) { | ||
// TODO(#126565): extend for float support exponents | ||
return isdigit(C); // integer support | ||
} | ||
|
||
RootSignatureToken RootSignatureLexer::LexToken() { | ||
// Discard any leading whitespace | ||
AdvanceBuffer(Buffer.take_while(isspace).size()); | ||
|
||
if (EndOfBuffer()) | ||
return RootSignatureToken(TokenKind::end_of_stream, SourceLoc); | ||
|
||
// Record where this token is in the text for usage in parser diagnostics | ||
RootSignatureToken Result(SourceLoc); | ||
|
||
char C = Buffer.front(); | ||
|
||
// Punctuators | ||
switch (C) { | ||
#define PUNCTUATOR(X, Y) \ | ||
case Y: { \ | ||
Result.Kind = TokenKind::pu_##X; \ | ||
AdvanceBuffer(); \ | ||
return Result; \ | ||
} | ||
#include "clang/Lex/HLSLRootSignatureTokenKinds.def" | ||
default: | ||
break; | ||
} | ||
|
||
// Integer literal | ||
if (isdigit(C)) { | ||
Result.Kind = TokenKind::int_literal; | ||
Result.NumSpelling = Buffer.take_while(IsNumberChar); | ||
AdvanceBuffer(Result.NumSpelling.size()); | ||
return Result; | ||
} | ||
|
||
// All following tokens require at least one additional character | ||
if (Buffer.size() <= 1) { | ||
Result = RootSignatureToken(TokenKind::invalid, SourceLoc); | ||
return Result; | ||
} | ||
|
||
// Peek at the next character to deteremine token type | ||
char NextC = Buffer[1]; | ||
|
||
// Registers: [tsub][0-9+] | ||
if ((C == 't' || C == 's' || C == 'u' || C == 'b') && isdigit(NextC)) { | ||
// Convert character to the register type. | ||
switch (C) { | ||
case 'b': | ||
Result.Kind = TokenKind::bReg; | ||
break; | ||
case 't': | ||
Result.Kind = TokenKind::tReg; | ||
break; | ||
case 'u': | ||
Result.Kind = TokenKind::uReg; | ||
break; | ||
case 's': | ||
Result.Kind = TokenKind::sReg; | ||
break; | ||
default: | ||
llvm_unreachable("Switch for an expected token was not provided"); | ||
} | ||
|
||
AdvanceBuffer(); | ||
|
||
// Lex the integer literal | ||
Result.NumSpelling = Buffer.take_while(IsNumberChar); | ||
AdvanceBuffer(Result.NumSpelling.size()); | ||
|
||
return Result; | ||
} | ||
|
||
// Keywords and Enums: | ||
StringRef TokSpelling = | ||
Buffer.take_while([](char C) { return isalnum(C) || C == '_'; }); | ||
|
||
// Define a large string switch statement for all the keywords and enums | ||
auto Switch = llvm::StringSwitch<TokenKind>(TokSpelling); | ||
#define KEYWORD(NAME) Switch.Case(#NAME, TokenKind::kw_##NAME); | ||
#define ENUM(NAME, LIT) Switch.CaseLower(LIT, TokenKind::en_##NAME); | ||
#include "clang/Lex/HLSLRootSignatureTokenKinds.def" | ||
|
||
// Then attempt to retreive a string from it | ||
Result.Kind = Switch.Default(TokenKind::invalid); | ||
AdvanceBuffer(TokSpelling.size()); | ||
return Result; | ||
} | ||
|
||
RootSignatureToken RootSignatureLexer::ConsumeToken() { | ||
// If we previously peeked then just return the previous value over | ||
if (NextToken && NextToken->Kind != TokenKind::end_of_stream) { | ||
RootSignatureToken Result = *NextToken; | ||
NextToken = std::nullopt; | ||
return Result; | ||
} | ||
return LexToken(); | ||
} | ||
|
||
RootSignatureToken RootSignatureLexer::PeekNextToken() { | ||
// Already peeked from the current token | ||
if (NextToken) | ||
return *NextToken; | ||
|
||
NextToken = LexToken(); | ||
return *NextToken; | ||
} | ||
|
||
} // namespace hlsl | ||
} // namespace clang |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.