Skip to content

Commit

Permalink
Parse GUIDs in COM_INTERFACE macros
Browse files Browse the repository at this point in the history
  • Loading branch information
laurooyen committed Dec 9, 2024
1 parent 102cf24 commit d778e6f
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 17 deletions.
4 changes: 3 additions & 1 deletion source/core/slang-string-util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
20 changes: 20 additions & 0 deletions tools/slang-cpp-parser/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion tools/slang-cpp-parser/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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
Expand Down
56 changes: 41 additions & 15 deletions tools/slang-cpp-parser/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1109,32 +1109,58 @@ SlangResult Parser::_parseSpecialMacro()
Token name;
SLANG_RETURN_ON_FAIL(expect(TokenType::Identifier, &name));

List<Token> 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<ClassLikeNode>(m_currentScope);

if (suffix == "COM_INTERFACE")
{
// TODO(JS): It's a com interface. Extact the GUID
}
node->m_guid = guid;

return SLANG_OK;
}
Expand Down
1 change: 1 addition & 0 deletions tools/slang-cpp-parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class Parser

SlangResult _parseTypeDef();
SlangResult _parseEnum();
SlangResult _parseGuid();
SlangResult _parseMarker();
SlangResult _parseSpecialMacro();

Expand Down
2 changes: 2 additions & 0 deletions tools/slang-cpp-parser/unit-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit d778e6f

Please sign in to comment.