From 102cf24171c72e06a75c1fab56397ec7e4920090 Mon Sep 17 00:00:00 2001 From: Lauro Oyen Date: Sun, 8 Dec 2024 21:18:44 +0100 Subject: [PATCH] Always parse all node kinds --- include/slang.h | 2 - tools/slang-cpp-parser/parser.cpp | 105 +++++++++++++-------------- tools/slang-cpp-parser/parser.h | 12 --- tools/slang-cpp-parser/unit-test.cpp | 10 --- 4 files changed, 51 insertions(+), 78 deletions(-) diff --git a/include/slang.h b/include/slang.h index 2dfee6b281..9959bfa5c6 100644 --- a/include/slang.h +++ b/include/slang.h @@ -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. */ diff --git a/tools/slang-cpp-parser/parser.cpp b/tools/slang-cpp-parser/parser.cpp index 1edc38ac73..9fcf6a6b98 100644 --- a/tools/slang-cpp-parser/parser.cpp +++ b/tools/slang-cpp-parser/parser.cpp @@ -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) @@ -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 caseNode(new EnumCaseNode); // We could also check if the name is a valid identifier for name, for now just assume. @@ -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)); @@ -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 toks; @@ -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, @@ -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: @@ -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 { diff --git a/tools/slang-cpp-parser/parser.h b/tools/slang-cpp-parser/parser.h index 519ad69355..c3ccf9656a 100644 --- a/tools/slang-cpp-parser/parser.h +++ b/tools/slang-cpp-parser/parser.h @@ -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); @@ -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: @@ -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; diff --git a/tools/slang-cpp-parser/unit-test.cpp b/tools/slang-cpp-parser/unit-test.cpp index 70851fd7c8..7320e708e8 100644 --- a/tools/slang-cpp-parser/unit-test.cpp +++ b/tools/slang-cpp-parser/unit-test.cpp @@ -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())