diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp index 6f1dc2ccb8..3da4084618 100644 --- a/source/core/slang-string-util.cpp +++ b/source/core/slang-string-util.cpp @@ -690,16 +690,18 @@ String StringUtil::replaceAll( } int radix = 10; + auto isDigit = CharUtil::isDigit; auto getDigit = CharUtil::getDecimalDigitValue; if (cur + 1 < end && *cur == '0' && (*(cur + 1) == 'x' || *(cur + 1) == 'X')) { radix = 16; + isDigit = CharUtil::isHexDigit; getDigit = CharUtil::getHexDigitValue; cur += 2; } // We need at least one digit - if (cur >= end || !CharUtil::isDigit(*cur)) + if (cur >= end || !isDigit(*cur)) { return SLANG_FAIL; } diff --git a/tools/slang-cpp-parser/node.cpp b/tools/slang-cpp-parser/node.cpp index 16484ead39..af15508580 100644 --- a/tools/slang-cpp-parser/node.cpp +++ b/tools/slang-cpp-parser/node.cpp @@ -688,6 +688,26 @@ void ClassLikeNode::dump(int indentCount, StringBuilder& out) out << " {\n"; + if (m_guid != Guid()) + { + _indent(indentCount + 1, out); + StringUtil::appendFormat( + out, + "COM_INTERFACE(0x%08lx, 0x%04hx, 0x%04hx, {0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, " + "0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx})\n", + m_guid.data1, + m_guid.data2, + m_guid.data3, + m_guid.data4[0], + m_guid.data4[1], + m_guid.data4[2], + m_guid.data4[3], + m_guid.data4[4], + m_guid.data4[5], + m_guid.data4[6], + m_guid.data4[7]); + } + for (Node* child : m_children) { child->dump(indentCount + 1, out); diff --git a/tools/slang-cpp-parser/node.h b/tools/slang-cpp-parser/node.h index 4dad9473e0..04cee8d715 100644 --- a/tools/slang-cpp-parser/node.h +++ b/tools/slang-cpp-parser/node.h @@ -316,7 +316,7 @@ struct ClassLikeNode : public ScopeNode virtual void dump(int indent, StringBuilder& out) SLANG_OVERRIDE; ClassLikeNode(Kind kind) - : Super(kind), m_origin(nullptr), m_typeSet(nullptr), m_superNode(nullptr) + : Super(kind), m_origin(nullptr), m_typeSet(nullptr), m_superNode(nullptr), m_guid(Guid()) { SLANG_ASSERT(kind == Kind::ClassType || kind == Kind::StructType); } @@ -333,6 +333,8 @@ struct ClassLikeNode : public ScopeNode Token m_super; ///< Super class name ClassLikeNode* m_superNode; ///< If this is a class/struct, the type it is derived from (or ///< nullptr if base) + + Guid m_guid; ///< The guid associated with this type }; struct CallableNode : public Node diff --git a/tools/slang-cpp-parser/parser.cpp b/tools/slang-cpp-parser/parser.cpp index 9fcf6a6b98..32f68216b3 100644 --- a/tools/slang-cpp-parser/parser.cpp +++ b/tools/slang-cpp-parser/parser.cpp @@ -1109,32 +1109,58 @@ SlangResult Parser::_parseSpecialMacro() Token name; SLANG_RETURN_ON_FAIL(expect(TokenType::Identifier, &name)); - List params; + const UnownedStringSlice suffix = name.getContent().tail(m_options->m_markPrefix.getLength()); - if (m_reader.peekTokenType() == TokenType::LParent) + if (suffix == "COM_INTERFACE") { - // Mark the start - auto startCursor = m_reader.getCursor(); + return _parseGuid(); + } - // Consume the params + if (m_reader.peekTokenType() == TokenType::LParent) + { SLANG_RETURN_ON_FAIL(_consumeBalancedParens()); + } - auto endCursor = m_reader.getCursor(); - m_reader.setCursor(startCursor); + return SLANG_OK; +} - while (!m_reader.isAtCursor(endCursor)) +SlangResult Parser::_parseGuid() +{ + Guid guid{}; + Token guidToken; + Int value; + + SLANG_RETURN_ON_FAIL(expect(TokenType::LParent)); + + SLANG_RETURN_ON_FAIL(expect(TokenType::IntegerLiteral, &guidToken)); + StringUtil::parseInt(guidToken.getContent(), value); + guid.data1 = value; + SLANG_RETURN_ON_FAIL(expect(TokenType::Comma)); + SLANG_RETURN_ON_FAIL(expect(TokenType::IntegerLiteral, &guidToken)); + StringUtil::parseInt(guidToken.getContent(), value); + guid.data2 = value; + SLANG_RETURN_ON_FAIL(expect(TokenType::Comma)); + SLANG_RETURN_ON_FAIL(expect(TokenType::IntegerLiteral, &guidToken)); + StringUtil::parseInt(guidToken.getContent(), value); + guid.data3 = value; + SLANG_RETURN_ON_FAIL(expect(TokenType::Comma)); + SLANG_RETURN_ON_FAIL(expect(TokenType::LBrace)); + for (Index i = 0; i < 8; ++i) + { + SLANG_RETURN_ON_FAIL(expect(TokenType::IntegerLiteral, &guidToken)); + StringUtil::parseInt(guidToken.getContent(), value); + guid.data4[i] = value; + if (i < 7) { - params.add(m_reader.advanceToken()); + SLANG_RETURN_ON_FAIL(expect(TokenType::Comma)); } } + SLANG_RETURN_ON_FAIL(expect(TokenType::RBrace)); + SLANG_RETURN_ON_FAIL(expect(TokenType::RParent)); - // Can do special handling here - const UnownedStringSlice suffix = name.getContent().tail(m_options->m_markPrefix.getLength()); + ClassLikeNode* node = as(m_currentScope); - if (suffix == "COM_INTERFACE") - { - // TODO(JS): It's a com interface. Extact the GUID - } + node->m_guid = guid; return SLANG_OK; } diff --git a/tools/slang-cpp-parser/parser.h b/tools/slang-cpp-parser/parser.h index c3ccf9656a..675fdccde1 100644 --- a/tools/slang-cpp-parser/parser.h +++ b/tools/slang-cpp-parser/parser.h @@ -44,6 +44,7 @@ class Parser SlangResult _parseTypeDef(); SlangResult _parseEnum(); + SlangResult _parseGuid(); SlangResult _parseMarker(); SlangResult _parseSpecialMacro(); diff --git a/tools/slang-cpp-parser/unit-test.cpp b/tools/slang-cpp-parser/unit-test.cpp index 7320e708e8..da8542be45 100644 --- a/tools/slang-cpp-parser/unit-test.cpp +++ b/tools/slang-cpp-parser/unit-test.cpp @@ -42,6 +42,8 @@ struct TestState static const char someSource[] = "class ISomeInterface\n" "{\n" + " SLANG_COM_INTERFACE(0x514027d8, 0x23d1, 0x4093, " + "{0x94,0x85,0xb9,0x2c,0x06,0x95,0x7f,0x5e})\n" " public:\n" " virtual int SLANG_MCALL someMethod(int a, int b) const = 0;\n" " virtual float SLANG_MCALL anotherMethod(float a) = 0;\n"