Skip to content
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

[HLSL][RootSignature] Implement Lexing of DescriptorTables #122981

Merged
merged 22 commits into from
Feb 14, 2025
Merged
Show file tree
Hide file tree
Changes from 12 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 Jan 24, 2025
5f43ed8
Add lexing of integer literals
inbelic Jan 24, 2025
dc0c7ba
Add support for lexing registers
inbelic Jan 24, 2025
c5d3881
Add lexing for example keyword and enum
inbelic Jan 24, 2025
dc784ff
Add lexing for remaining DescriptorTable keywords and enums
inbelic Jan 24, 2025
82c645d
review: update uses of llvm_unreachable
inbelic Feb 4, 2025
1c95e6d
review: update target test triple with comment
inbelic Feb 4, 2025
d648f4c
review: dealing with signed positive integer
inbelic Feb 4, 2025
de2f62e
review: update diagnostics message
inbelic Feb 10, 2025
f557d5a
review: update linked todo
inbelic Feb 10, 2025
de364d8
review: remove api for pre-allocating tokens
inbelic Feb 10, 2025
35c1566
clang format
inbelic Feb 11, 2025
8ac979c
review: fix some typos
inbelic Feb 11, 2025
0c372bf
review: remove unique end_of_stream lexing error
inbelic Feb 11, 2025
e58c89a
review: remove unique invalid_token lexing error
inbelic Feb 11, 2025
aa7a73d
review: punt parsing of a signed integer to the parser
inbelic Feb 11, 2025
ca2a2cb
self-review: define an error token to denote lex errors during peek
inbelic Feb 12, 2025
8345ff1
review: defer handling of numeric constants to the parser -> remove e…
inbelic Feb 13, 2025
5439fa8
review: move to lex dir
inbelic Feb 13, 2025
cf9788e
review: clean up after moving
inbelic Feb 13, 2025
6a5545f
self-review: whoops missed renaming header guards
inbelic Feb 13, 2025
7f27295
Update clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
inbelic Feb 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions clang/include/clang/Basic/DiagnosticLexKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1017,4 +1017,15 @@ Error<"'#pragma unsafe_buffer_usage' was not ended">;

def err_pp_pragma_unsafe_buffer_usage_syntax :
Error<"expected 'begin' or 'end'">;

// HLSL Root Signature Lexing Errors
let CategoryName = "Root Signature Lexical Issue" in {
def err_hlsl_expected_number_literal: Error<"expected numberic literal">;
def err_hlsl_number_literal_overflow :
Error<"integer literal is too large to be represented in any %select{signed |}0 integer type">;
def err_hlsl_invalid_token: Error<"unable to lex a valid Root Signature token">;
def err_hlsl_invalid_register_literal: Error<"expected unsigned integer literal as part of register">;
def err_hlsl_rootsig_unexpected_eos : Error<"unexpected end to token stream">;
}

}
122 changes: 122 additions & 0 deletions clang/include/clang/Parse/HLSLRootSignatureTokenKinds.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//===--- 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, '=')

// 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
99 changes: 99 additions & 0 deletions clang/include/clang/Parse/ParseHLSLRootSignature.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//===--- ParseHLSLRootSignature.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 ParseHLSLRootSignature interface.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_PARSE_PARSEHLSLROOTSIGNATURE_H
#define LLVM_CLANG_PARSE_PARSEHLSLROOTSIGNATURE_H

#include "clang/AST/APValue.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed?

In general it is also best to prefer forward declarations in headers rather than including headers where possible to reduce compile time overhead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this and the other no longer needed headers

#include "clang/Basic/DiagnosticLex.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/Preprocessor.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/Parse/HLSLRootSignatureTokenKinds.def"
};

Kind Kind = Kind::invalid;

// Retain the SouceLocation of the token for diagnostics
clang::SourceLocation TokLoc;

APValue NumLiteral = APValue();

// Constructors
RootSignatureToken() : TokLoc(SourceLocation()) {}
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,
clang::Preprocessor &PP)
: Buffer(Signature), SourceLoc(SourceLoc), PP(PP) {}

/// Updates CurToken to the next token. Either it will take the previously
/// lexed NextToken, or it will lex a token.
///
/// The return value denotes if there was a failure.
bool ConsumeToken();

/// Returns the token that comes after CurToken or std::nullopt if an
/// error is encountered during lexing of the next token.
std::optional<RootSignatureToken> PeekNextToken();

RootSignatureToken GetCurToken() { return CurToken; }

/// Check if we have reached the end of input
bool EndOfBuffer() {
AdvanceBuffer(Buffer.take_while(isspace).size());
return Buffer.empty();
}

private:
// Internal buffer to iterate over
StringRef Buffer;

// Current Token state
RootSignatureToken CurToken;
std::optional<RootSignatureToken> NextToken = std::nullopt;

// Passed down parameters from Sema
clang::SourceLocation SourceLoc;
clang::Preprocessor &PP;

bool LexNumber(RootSignatureToken &Result);
bool LexToken(RootSignatureToken &Result);

// 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_PARSE_PARSEHLSLROOTSIGNATURE_H
1 change: 1 addition & 0 deletions clang/lib/Parse/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ add_clang_library(clangParse
ParseExpr.cpp
ParseExprCXX.cpp
ParseHLSL.cpp
ParseHLSLRootSignature.cpp
ParseInit.cpp
ParseObjc.cpp
ParseOpenMP.cpp
Expand Down
Loading
Loading