Skip to content

Commit

Permalink
Always parse all node kinds
Browse files Browse the repository at this point in the history
  • Loading branch information
laurooyen committed Dec 8, 2024
1 parent 1bafc1a commit 102cf24
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 78 deletions.
2 changes: 0 additions & 2 deletions include/slang.h
Original file line number Diff line number Diff line change
Expand Up @@ -1729,8 +1729,6 @@ public: \
typedef slang::IGlobalSession SlangSession;


typedef struct SlangProgramLayout SlangProgramLayout;

/*!
@brief A request for one or more compilation actions to be performed.
*/
Expand Down
105 changes: 51 additions & 54 deletions tools/slang-cpp-parser/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,8 @@ SLANG_COMPILE_TIME_ASSERT(int(Node::Kind::CountOf) <= 8 * sizeof(uint32_t));
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Parser !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Parser::Parser(NodeTree* nodeTree, DiagnosticSink* sink)
: m_sink(sink), m_nodeTree(nodeTree), m_nodeTypeEnabled(0)
: m_sink(sink), m_nodeTree(nodeTree)
{
// Enable types by default
const Node::Kind defaultEnabled[] = {
Node::Kind::ClassType,
Node::Kind::StructType,
Node::Kind::Namespace,
Node::Kind::AnonymousNamespace,
Node::Kind::Field,

// These are disabled by default because AST uses macro magic to build up the types
// Node::Type::TypeDef,
// Node::Type::Enum,
// Node::Type::EnumClass,

Node::Kind::Callable,
};
setKindsEnabled(defaultEnabled, SLANG_COUNT_OF(defaultEnabled));
}

void Parser::setKindEnabled(Node::Kind kind, bool isEnabled)
{
if (isEnabled)
{
m_nodeTypeEnabled |= (NodeTypeBitType(1) << int(kind));
}
else
{
m_nodeTypeEnabled &= ~(NodeTypeBitType(1) << int(kind));
}
}

void Parser::setKindsEnabled(const Node::Kind* kinds, Index kindsCount, bool isEnabled)
{
for (Index i = 0; i < kindsCount; ++i)
{
setKindEnabled(kinds[i], isEnabled);
}
}

bool Parser::_isMarker(const UnownedStringSlice& name)
Expand Down Expand Up @@ -413,6 +377,33 @@ SlangResult Parser::_parseEnum()
break;
}

// TODO:
// The SlangImageFormat enum #includes "slang-image-format-defs.h" to define its cases.
// Since this parser has no preprocessor, it can't unfold those enum cases. For now skip
// the # directives in the enum body, resulting in an empty parsed enum. Maybe fix it by
// unfolding the enum manually where it is #included, resulting in some code duplication.
if (tokenType == TokenType::Pound)
{
while (m_reader.peekTokenType() == TokenType::Pound)
{
Token token = m_reader.peekToken();
if (token.flags & TokenFlag::AtStartOfLine)
{
m_reader.advanceToken();
for (;;)
{
auto t = m_reader.peekToken();
if (t.type == TokenType::EndOfFile || (t.flags & TokenFlag::AtStartOfLine))
{
break;
}
m_reader.advanceToken();
}
}
}
break;
}

RefPtr<EnumCaseNode> caseNode(new EnumCaseNode);

// We could also check if the name is a valid identifier for name, for now just assume.
Expand Down Expand Up @@ -1013,6 +1004,13 @@ SlangResult Parser::_maybeParseType(
// TODO(JS):
// Doesn't handle all the modifiers just (*SomeName)

// Skip the class name in case of a pointer to member function (Class::*Member)
if (m_reader.peekTokenType() == TokenType::Identifier)
{
m_reader.advanceToken();
expect(TokenType::Scope);
}

SLANG_RETURN_ON_FAIL(expect(TokenType::OpMul));
outNameCursor = m_reader.getCursor();
SLANG_RETURN_ON_FAIL(expect(TokenType::Identifier));
Expand Down Expand Up @@ -1471,6 +1469,9 @@ SlangResult Parser::_parseTypeDef()
// Consume the typedef
SLANG_RETURN_ON_FAIL(expect(TokenType::Identifier));

_maybeConsume(IdentifierStyle::Struct);
_maybeConsume(IdentifierStyle::Enum);

Token nameToken;
// Parse the type
List<Token> toks;
Expand All @@ -1484,6 +1485,17 @@ SlangResult Parser::_parseTypeDef()

if (Node::lookupNameInScope(m_currentScope, nameToken.getContent()))
{
// TODO:
// In slang.h these types are defined twice as different sizes and then conditionally
// enabled based on a define. Since this parser has no preprocessor, it can't handle this.
// Maybe fix it by moving all of the platform-detection stuff out to a separate file as
// suggested here: https://github.com/shader-slang/slang/pull/954#discussion_r278687475
if (nameToken.getContent() == "SlangInt" || nameToken.getContent() == "SlangUInt" ||
nameToken.getContent() == "SlangSSizeT" || nameToken.getContent() == "SlangSizeT")
{
return SLANG_OK;
}

m_sink->diagnose(
nameToken.loc,
CPPDiagnostics::identifierAlreadyDefined,
Expand Down Expand Up @@ -2129,15 +2141,7 @@ SlangResult Parser::parse(SourceOrigin* sourceOrigin, const Options* options)
}
case IdentifierStyle::TypeDef:
{
if (isTypeEnabled(Node::Kind::TypeDef))
{
SLANG_RETURN_ON_FAIL(_parseTypeDef());
}
else
{
m_reader.advanceToken();
SLANG_RETURN_ON_FAIL(_consumeToSync());
}
SLANG_RETURN_ON_FAIL(_parseTypeDef());
break;
}
default:
Expand All @@ -2149,14 +2153,7 @@ SlangResult Parser::parse(SourceOrigin* sourceOrigin, const Options* options)
Node::Kind kind = _toNodeKind(style);
SLANG_ASSERT(kind != Node::Kind::Invalid);

if (isTypeEnabled(kind))
{
SLANG_RETURN_ON_FAIL(_maybeParseNode(kind));
}
else
{
SLANG_RETURN_ON_FAIL(_maybeConsumeScope());
}
SLANG_RETURN_ON_FAIL(_maybeParseNode(kind));
}
else
{
Expand Down
12 changes: 0 additions & 12 deletions tools/slang-cpp-parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ using namespace Slang;
class Parser
{
public:
typedef uint32_t NodeTypeBitType;

SlangResult expect(TokenType type, Token* outToken = nullptr);

bool advanceIfMarker(Token* outToken = nullptr);
Expand All @@ -29,14 +27,6 @@ class Parser
/// Parse the contents of the source file
SlangResult parse(SourceOrigin* sourceOrigin, const Options* options);

void setKindEnabled(Node::Kind kind, bool isEnabled = true);
bool isTypeEnabled(Node::Kind kind)
{
return (m_nodeTypeEnabled & (NodeTypeBitType(1) << int(kind))) != 0;
}

void setKindsEnabled(const Node::Kind* kinds, Index kindsCount, bool isEnabled = true);

Parser(NodeTree* nodeTree, DiagnosticSink* sink);

protected:
Expand Down Expand Up @@ -92,8 +82,6 @@ class Parser
/// Consumes balanced parens. Will return an error if not matched. Assumes starts on opening (
SlangResult _consumeBalancedParens();

NodeTypeBitType m_nodeTypeEnabled;

TokenList m_tokenList;
TokenReader m_reader;

Expand Down
10 changes: 0 additions & 10 deletions tools/slang-cpp-parser/unit-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,6 @@ static const char someSource[] = "class ISomeInterface\n"

Parser parser(&tree, &state.m_sink);


{
const Node::Kind enableKinds[] = {
Node::Kind::Enum,
Node::Kind::EnumClass,
Node::Kind::EnumCase,
Node::Kind::TypeDef};
parser.setKindsEnabled(enableKinds, SLANG_COUNT_OF(enableKinds));
}

SlangResult res = parser.parse(sourceOrigin, &state.m_options);

if (state.m_sink.outputBuffer.getLength())
Expand Down

0 comments on commit 102cf24

Please sign in to comment.