summaryrefslogtreecommitdiffstats
path: root/tools/slang-cpp-extractor
diff options
context:
space:
mode:
Diffstat (limited to 'tools/slang-cpp-extractor')
-rw-r--r--tools/slang-cpp-extractor/slang-cpp-extractor-diagnostic-defs.h1
-rw-r--r--tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp822
2 files changed, 478 insertions, 345 deletions
diff --git a/tools/slang-cpp-extractor/slang-cpp-extractor-diagnostic-defs.h b/tools/slang-cpp-extractor/slang-cpp-extractor-diagnostic-defs.h
index 3ab133414..284e02d19 100644
--- a/tools/slang-cpp-extractor/slang-cpp-extractor-diagnostic-defs.h
+++ b/tools/slang-cpp-extractor/slang-cpp-extractor-diagnostic-defs.h
@@ -20,6 +20,7 @@
DIAGNOSTIC(-1, Note, seeDeclarationOf, "see declaration of '$0'")
DIAGNOSTIC(-1, Note, seeOpen, "see open $0")
+DIAGNOSTIC(-1, Note, commandLine, "Command line: $0")
DIAGNOSTIC(1, Error, cannotOpenFile, "cannot open file '$0'.")
diff --git a/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp b/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
index d7928d953..2aa8446ad 100644
--- a/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
+++ b/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
@@ -158,43 +158,44 @@ enum class ReflectionType
class TypeSet;
class SourceOrigin;
+struct ScopeNode;
+
class Node : public RefObject
{
public:
enum class Type
{
Invalid,
+
StructType,
ClassType,
+
Namespace,
AnonymousNamespace,
+
+ Field,
};
- struct Field
+ static bool isScopeType(Type type) { return int(type) >= int(Type::StructType) && int(type) <= int(Type::AnonymousNamespace); }
+ static bool isClassLikeType(Type type) { return type == Type::StructType || type == Type::ClassType; }
+
+ enum class TypeRange
{
- bool isReflected() const { return reflectionType == ReflectionType::Reflected; }
+ ScopeStart = int(Type::StructType),
+ ScopeEnd = int(Type::AnonymousNamespace),
- UnownedStringSlice type;
- Token name;
- ReflectionType reflectionType;
+ ClassLikeStart = int(Type::StructType),
+ ClassLikeEnd = int(Type::ClassType),
};
- bool isClassLike() const { return m_type == Type::StructType || m_type == Type::ClassType; }
+ static bool isType(Type type) { return true; }
- /// Add a child node to this nodes scope
- void addChild(Node* child);
+ bool isClassLike() const { return isClassLikeType(m_type); }
- /// Find a child node in this scope with the specified name. Return nullptr if not found
- Node* findChild(const UnownedStringSlice& name) const;
+ virtual void dump(int indent, StringBuilder& out) = 0;
- /// Add a node that is derived from this
- void addDerived(Node* derived);
-
- /// True if can accept fields (class like types can)
- bool acceptsFields() const { return isClassLike(); }
-
- void dump(int indent, StringBuilder& out);
- void dumpDerived(int indentCount, StringBuilder& out);
+ /// Do depth first traversal of nodes in scopes
+ virtual void calcScopeDepthFirst(List<Node*>& outNodes);
/// Calculate the absolute name for this namespace/type
void calcAbsoluteName(StringBuilder& outName) const;
@@ -202,117 +203,164 @@ public:
/// Get the absolute name
String getAbsoluteName() const { StringBuilder buf; calcAbsoluteName(buf); return buf.ProduceString(); }
- /// Do depth first traversal of nodes
- void calcScopeDepthFirst(List<Node*>& outNodes);
-
- /// Traverse the hierarchy of derived nodes, in depth first order
- void calcDerivedDepthFirst(List<Node*>& outNodes);
-
/// Calculate the scope path to this node, from the root
void calcScopePath(List<Node*>& outPath) { calcScopePath(this, outPath); }
-
- /// Calculates the derived depth
- Index calcDerivedDepth() const;
-
- /// Gets the anonymous namespace associated with this scope
- Node* getAnonymousNamespace();
-
- /// Find the last (reflected) derived type
- Node* findLastDerived();
-
+
/// True if reflected
bool isReflected() const { return m_reflectionType == ReflectionType::Reflected; }
- /// Gets the reflection for any contained types
- ReflectionType getContainedReflectionType() const { return m_reflectionType == ReflectionType::NotReflected ? ReflectionType::NotReflected : m_reflectionOverride; }
-
- /// True if has a derived type that is reflected
- bool hasReflectedDerivedType() const;
- /// Stores in out any reflected derived types
- void getReflectedDerivedTypes(List<Node*>& out) const;
-
typedef bool (*Filter)(Node* node);
- static bool isClassLikeAndReflected(Node* node)
- {
- return node->isClassLike() && node->isReflected();
- }
- static bool isClassLike(Node* node)
- {
- return node->isClassLike();
- }
+ static bool isClassLikeAndReflected(Node* node) { return node->isClassLike() && node->isReflected(); }
+ static bool isClassLike(Node* node) { return isClassLikeType(node->m_type); }
+
+ template <typename T>
+ static void filter(Filter filter, List<T*>& io) { const Node* _isNodeDerived = (T*)nullptr; SLANG_UNUSED(_isNodeDerived); filterImpl(filter, reinterpret_cast<List<Node*>&>(io)); }
- static void filter(Filter filter, List<Node*>& io);
+ static void filterImpl(Filter filter, List<Node*>& io);
static void calcScopePath(Node* node, List<Node*>& outPath);
Node(Type type):
m_type(type),
m_parentScope(nullptr),
- m_reflectionType(ReflectionType::NotReflected),
+ m_reflectionType(ReflectionType::NotReflected)
+ {
+ }
+
+ Type m_type; ///< The type of node this is
+
+ ReflectionType m_reflectionType; /// Classes can be traversed, but not reflected. To be reflected they have to contain the marker
+
+ Token m_name; ///< The name of this scope/type
+
+ ScopeNode* m_parentScope; ///< The scope this type/scope is defined in
+};
+
+struct ScopeNode : public Node
+{
+ typedef Node Super;
+
+ static bool isType(Type type) { return isScopeType(type); }
+
+ virtual void dump(int indent, StringBuilder& out) SLANG_OVERRIDE;
+ virtual void calcScopeDepthFirst(List<Node*>& outNodes) SLANG_OVERRIDE;
+
+ /// True if can accept fields (class like types can)
+ bool acceptsFields() const { return isClassLike(); }
+
+ /// Gets the reflection for any contained types
+ ReflectionType getContainedReflectionType() const { return m_reflectionType == ReflectionType::NotReflected ? ReflectionType::NotReflected : m_reflectionOverride; }
+
+ /// Add a child node to this nodes scope
+ void addChild(Node* child);
+
+ /// Find a child node in this scope with the specified name. Return nullptr if not found
+ Node* findChild(const UnownedStringSlice& name) const;
+
+ /// Gets the anonymous namespace associated with this scope
+ ScopeNode* getAnonymousNamespace();
+
+ ScopeNode(Type type) :
+ Super(type),
m_reflectionOverride(ReflectionType::Reflected),
- m_superNode(nullptr),
- m_origin(nullptr),
- m_typeSet(nullptr)
+ m_anonymousNamespace(nullptr)
{
- m_anonymousNamespace = nullptr;
}
- /// The type of node this is
- Type m_type;
+ /// For child types, fields, how reflection is handled. If this type is not reflected
+ ReflectionType m_reflectionOverride;
/// All of the types and namespaces in this *scope*
List<RefPtr<Node>> m_children;
- /// All of the types derived from this type
- List<RefPtr<Node>> m_derivedTypes;
-
/// Map from a name (in this scope) to the Node
Dictionary<UnownedStringSlice, Node*> m_childMap;
- /// All of the fields within a *type*
- List<Field> m_fields;
-
/// There can only be one anonymousNamespace for a scope. If there is one it's held here
- Node* m_anonymousNamespace;
+ ScopeNode* m_anonymousNamespace;
+};
- /// Defines where this was uniquely defined. For namespaces if it straddles multiple source files will be the first instance.
- SourceOrigin* m_origin;
+struct FieldNode : public Node
+{
+ typedef Node Super;
- /// Classes can be traversed, but not reflected. To be reflected they have to contain the marker
- ReflectionType m_reflectionType;
+ static bool isType(Type type) { return type == Type::Field; }
- /// For child types, fields, how reflection is handled. If this type is not reflected
- ReflectionType m_reflectionOverride;
+ virtual void dump(int indent, StringBuilder& out) SLANG_OVERRIDE;
- Token m_name; ///< The name of this scope/type
- Token m_super; ///< Super class name
- Token m_marker; ///< The marker associated with this scope (typically the marker is SLANG_CLASS etc, that is used to identify reflectedType)
+ FieldNode():
+ Super(Type::Field)
+ {
+ }
- TypeSet* m_typeSet; ///< The typeset this type belongs to.
+ UnownedStringSlice m_fieldType;
- Node* m_parentScope; ///< The scope this type/scope is defined in
- Node* m_superNode; ///< If this is a class/struct, the type it is derived from (or nullptr if base)
+ // We may want to add initializer tokens
};
+struct ClassLikeNode : public ScopeNode
+{
+ typedef ScopeNode Super;
+
+ static bool isType(Type type) { return isClassLikeType(type); }
+
+ /// Add a node that is derived from this
+ void addDerived(ClassLikeNode* derived);
+ void dumpDerived(int indentCount, StringBuilder& out);
+
+ /// Calculates the derived depth
+ Index calcDerivedDepth() const;
+
+ /// Find the last (reflected) derived type
+ ClassLikeNode* findLastDerived();
+
+ /// Traverse the hierarchy of derived nodes, in depth first order
+ void calcDerivedDepthFirst(List<ClassLikeNode*>& outNodes);
+
+ /// True if has a derived type that is reflected
+ bool hasReflectedDerivedType() const;
+ /// Stores in out any reflected derived types
+ void getReflectedDerivedTypes(List<ClassLikeNode*>& out) const;
+
+ virtual void dump(int indent, StringBuilder& out) SLANG_OVERRIDE;
+
+ ClassLikeNode(Type type):
+ Super(type),
+ m_origin(nullptr),
+ m_typeSet(nullptr),
+ m_superNode(nullptr)
+ {
+ SLANG_ASSERT(type == Type::ClassType || type == Type::StructType);
+ }
+
+ SourceOrigin* m_origin; ///< Defines where this was uniquely defined.
+
+ Token m_marker; ///< The marker associated with this scope (typically the marker is SLANG_CLASS etc, that is used to identify reflectedType)
+
+ List<RefPtr<ClassLikeNode>> m_derivedTypes; ///< All of the types derived from this type
+
+ TypeSet* m_typeSet; ///< The typeset this type belongs to.
+
+ 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)
+};
+
+template <typename T>
+T* as(Node* node) { return (node && T::isType(node->m_type)) ? static_cast<T*>(node) : nullptr; }
+
class SourceOrigin : public RefObject
{
public:
void addNode(Node* node)
{
- if (node->isClassLike())
- {
- SLANG_ASSERT(node->m_origin == nullptr);
- node->m_origin = this;
- }
- else
+ if (auto classLike = as<ClassLikeNode>(node))
{
- if (node->m_origin == nullptr)
- {
- node->m_origin = this;
- }
+ SLANG_ASSERT(classLike->m_origin == nullptr);
+ classLike->m_origin = this;
}
+
m_nodes.add(node);
}
@@ -341,7 +389,7 @@ public:
String m_typeName; ///< The enum type name associated with this type for AST it is ASTNode
String m_fileMark; ///< This 'mark' becomes of the output filename
- List<Node*> m_baseTypes; ///< The base types for this type set
+ List<ClassLikeNode*> m_baseTypes; ///< The base types for this type set
};
struct Options;
@@ -357,9 +405,9 @@ public:
bool advanceIfStyle(IdentifierStyle style, Token* outToken = nullptr);
SlangResult pushAnonymousNamespace();
- SlangResult pushNode(Node* node);
+ SlangResult pushScope(ScopeNode* node);
SlangResult consumeToClosingBrace(const Token* openBraceToken = nullptr);
- SlangResult popBrace();
+ SlangResult popScope();
/// Parse the contents of the source file
SlangResult parse(SourceFile* sourceFile, const Options* options);
@@ -369,7 +417,7 @@ public:
SlangResult calcDerivedTypes();
/// Find the name starting in specified scope
- Node* findNode(Node* scope, const UnownedStringSlice& name);
+ Node* findNode(ScopeNode* scope, const UnownedStringSlice& name);
/// Get all of the parsed source origins
const List<RefPtr<SourceOrigin> >& getSourceOrigins() const { return m_origins; }
@@ -405,7 +453,7 @@ protected:
/// Parse balanced - if a sink is set will report to that sink
SlangResult _parseBalanced(DiagnosticSink* sink);
- SlangResult _calcDerivedTypesRec(Node* node);
+ SlangResult _calcDerivedTypesRec(ScopeNode* node);
static String _calcMacroOrigin(const String& filePath, const Options& options);
/// Concatenate all tokens from start to the current position
@@ -418,9 +466,9 @@ protected:
TokenList m_tokenList;
TokenReader m_reader;
- Node* m_currentNode; ///< The current scope being processed
+ ScopeNode* m_currentScope; ///< The current scope being processed
- RefPtr<Node> m_rootNode; ///< The root scope
+ RefPtr<ScopeNode> m_rootNode; ///< The root scope
SourceOrigin* m_origin;
@@ -442,89 +490,126 @@ protected:
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Node Impl !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-Node* Node::getAnonymousNamespace()
+
+
+static void _indent(Index indentCount, StringBuilder& out)
{
-
- if (!m_anonymousNamespace)
+ for (Index i = 0; i < indentCount; ++i)
{
- m_anonymousNamespace = new Node(Type::AnonymousNamespace);
- m_anonymousNamespace->m_parentScope = this;
- m_children.add(m_anonymousNamespace);
+ out << " ";
}
-
- return m_anonymousNamespace;
}
-void Node::addChild(Node* child)
+void Node::calcScopeDepthFirst(List<Node*>& outNodes)
{
- SLANG_ASSERT(child->m_parentScope == nullptr);
- // Can't add anonymous namespace this way - should be added via getAnonymousNamespace
- SLANG_ASSERT(child->m_type != Type::AnonymousNamespace);
+ outNodes.add(this);
+}
- child->m_parentScope = this;
- m_children.add(child);
+void Node::calcAbsoluteName(StringBuilder& outName) const
+{
+ List<Node*> path;
+ calcScopePath(const_cast<Node*>(this), path);
- if (child->m_name.hasContent())
+ // 1 so we skip the global scope
+ for (Index i = 1; i < path.getCount(); ++i)
{
- m_childMap.Add(child->m_name.getContent(), child);
+ Node* node = path[i];
+
+ if (i > 1)
+ {
+ outName << "::";
+ }
+
+ if (node->m_type == Type::AnonymousNamespace)
+ {
+ outName << "{Anonymous}";
+ }
+ else
+ {
+ outName << node->m_name.getContent();
+ }
}
}
-Node* Node::findChild(const UnownedStringSlice& name) const
+/* static */void Node::calcScopePath(Node* node, List<Node*>& outPath)
{
- Node** nodePtr = m_childMap.TryGetValue(name);
- return (nodePtr) ? *nodePtr : nullptr;
-}
+ outPath.clear();
-/// Add a node that is derived from this
-void Node::addDerived(Node* derived)
-{
- SLANG_ASSERT(derived->m_superNode == nullptr);
- derived->m_superNode = this;
- m_derivedTypes.add(derived);
+ while (node)
+ {
+ outPath.add(node);
+ node = node->m_parentScope;
+ }
+
+ // reverse the order, so we go from root to the node
+ outPath.reverse();
}
-void Node::calcScopeDepthFirst(List<Node*>& outNodes)
+/* static */void Node::filterImpl(Filter inFilter, List<Node*>& ioNodes)
{
- outNodes.add(this);
- for (Node* child : m_children)
+ // Filter out all the unreflected nodes
+ Index count = ioNodes.getCount();
+ for (Index j = 0; j < count; )
{
- child->calcScopeDepthFirst(outNodes);
+ Node* node = ioNodes[j];
+
+ if (!inFilter(node))
+ {
+ ioNodes.removeAt(j);
+ count--;
+ }
+ else
+ {
+ j++;
+ }
}
}
-void Node::calcDerivedDepthFirst(List<Node*>& outNodes)
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ScopeNode !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ScopeNode* ScopeNode::getAnonymousNamespace()
{
- outNodes.add(this);
- for (Node* derivedType : m_derivedTypes)
+ if (!m_anonymousNamespace)
{
- derivedType->calcDerivedDepthFirst(outNodes);
+ m_anonymousNamespace = new ScopeNode(Type::AnonymousNamespace);
+ m_anonymousNamespace->m_parentScope = this;
+ m_children.add(m_anonymousNamespace);
}
+
+ return m_anonymousNamespace;
}
-static void _indent(Index indentCount, StringBuilder& out)
+void ScopeNode::addChild(Node* child)
{
- for (Index i = 0; i < indentCount; ++i)
+ SLANG_ASSERT(child->m_parentScope == nullptr);
+ // Can't add anonymous namespace this way - should be added via getAnonymousNamespace
+ SLANG_ASSERT(child->m_type != Type::AnonymousNamespace);
+
+ child->m_parentScope = this;
+ m_children.add(child);
+
+ if (child->m_name.hasContent())
{
- out << " ";
+ m_childMap.Add(child->m_name.getContent(), child);
}
}
-void Node::dumpDerived(int indentCount, StringBuilder& out)
+Node* ScopeNode::findChild(const UnownedStringSlice& name) const
{
- if (isClassLike() && isReflected() && m_name.hasContent())
- {
- _indent(indentCount, out);
- out << m_name.getContent() << "\n";
- }
+ Node** nodePtr = m_childMap.TryGetValue(name);
+ return (nodePtr) ? *nodePtr : nullptr;
+}
- for (Node* derivedType : m_derivedTypes)
+void ScopeNode::calcScopeDepthFirst(List<Node*>& outNodes)
+{
+ outNodes.add(this);
+ for (Node* child : m_children)
{
- derivedType->dumpDerived(indentCount + 1, out);
+ child->calcScopeDepthFirst(outNodes);
}
}
-void Node::dump(int indentCount, StringBuilder& out)
+void ScopeNode::dump(int indentCount, StringBuilder& out)
{
_indent(indentCount, out);
@@ -546,31 +631,6 @@ void Node::dump(int indentCount, StringBuilder& out)
}
break;
}
- case Type::StructType:
- case Type::ClassType:
- {
- const char* typeName = (m_type == Type::StructType) ? "struct" : "class";
-
- out << typeName << " ";
-
- if (!isReflected())
- {
- out << " (";
- }
- out << m_name.getContent();
- if (!isReflected())
- {
- out << ") ";
- }
-
- if (m_super.hasContent())
- {
- out << " : " << m_super.getContent();
- }
-
- out << " {\n";
- break;
- }
}
for (Node* child : m_children)
@@ -578,48 +638,57 @@ void Node::dump(int indentCount, StringBuilder& out)
child->dump(indentCount + 1, out);
}
- for (const Field& field : m_fields)
- {
- if (field.isReflected())
- {
- _indent(indentCount + 1, out);
- out << field.type << " " << field.name.getContent() << "\n";
- }
- }
-
_indent(indentCount, out);
out << "}\n";
}
-void Node::calcAbsoluteName(StringBuilder& outName) const
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FieldNode !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void FieldNode::dump(int indent, StringBuilder& out)
{
- List<Node*> path;
- calcScopePath(const_cast<Node*>(this), path);
+ if (isReflected())
+ {
+ _indent(indent, out);
+ out << m_fieldType << " " << m_name.getContent() << "\n";
+ }
+}
- // 1 so we skip the global scope
- for (Index i = 1; i < path.getCount(); ++i)
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ClassLikeNode !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+/// Add a node that is derived from this
+void ClassLikeNode::addDerived(ClassLikeNode* derived)
+{
+ SLANG_ASSERT(derived->m_superNode == nullptr);
+ derived->m_superNode = this;
+ m_derivedTypes.add(derived);
+}
+
+void ClassLikeNode::calcDerivedDepthFirst(List<ClassLikeNode*>& outNodes)
+{
+ outNodes.add(this);
+ for (ClassLikeNode* derivedType : m_derivedTypes)
{
- Node* node = path[i];
+ derivedType->calcDerivedDepthFirst(outNodes);
+ }
+}
- if (i > 1)
- {
- outName << "::";
- }
+void ClassLikeNode::dumpDerived(int indentCount, StringBuilder& out)
+{
+ if (isClassLike() && isReflected() && m_name.hasContent())
+ {
+ _indent(indentCount, out);
+ out << m_name.getContent() << "\n";
+ }
- if (node->m_type == Type::AnonymousNamespace)
- {
- outName << "{Anonymous}";
- }
- else
- {
- outName << node->m_name.getContent();
- }
+ for (ClassLikeNode* derivedType : m_derivedTypes)
+ {
+ derivedType->dumpDerived(indentCount + 1, out);
}
}
-Index Node::calcDerivedDepth() const
+Index ClassLikeNode::calcDerivedDepth() const
{
- const Node* node = this;
+ const ClassLikeNode* node = this;
Index count = 0;
while (node)
@@ -631,12 +700,12 @@ Index Node::calcDerivedDepth() const
return count;
}
-Node* Node::findLastDerived()
+ClassLikeNode* ClassLikeNode::findLastDerived()
{
for (Index i = m_derivedTypes.getCount() - 1; i >= 0; --i)
{
- Node* derivedType = m_derivedTypes[i];
- Node* found = derivedType->findLastDerived();
+ ClassLikeNode* derivedType = m_derivedTypes[i];
+ ClassLikeNode* found = derivedType->findLastDerived();
if (found)
{
return found;
@@ -645,23 +714,9 @@ Node* Node::findLastDerived()
return this;
}
-/* static */void Node::calcScopePath(Node* node, List<Node*>& outPath)
+bool ClassLikeNode::hasReflectedDerivedType() const
{
- outPath.clear();
-
- while (node)
- {
- outPath.add(node);
- node = node->m_parentScope;
- }
-
- // reverse the order, so we go from root to the node
- outPath.reverse();
-}
-
-bool Node::hasReflectedDerivedType() const
-{
- for (Node* type : m_derivedTypes)
+ for (ClassLikeNode* type : m_derivedTypes)
{
if (type->isReflected())
{
@@ -671,10 +726,10 @@ bool Node::hasReflectedDerivedType() const
return false;
}
-void Node::getReflectedDerivedTypes(List<Node*>& out) const
+void ClassLikeNode::getReflectedDerivedTypes(List<ClassLikeNode*>& out) const
{
out.clear();
- for (Node* type : m_derivedTypes)
+ for (ClassLikeNode* type : m_derivedTypes)
{
if (type->isReflected())
{
@@ -683,24 +738,38 @@ void Node::getReflectedDerivedTypes(List<Node*>& out) const
}
}
-/* static */void Node::filter(Filter inFilter, List<Node*>& ioNodes)
+void ClassLikeNode::dump(int indentCount, StringBuilder& out)
{
- // Filter out all the unreflected nodes
- Index count = ioNodes.getCount();
- for (Index j = 0; j < count; )
+ _indent(indentCount, out);
+
+ const char* typeName = (m_type == Type::StructType) ? "struct" : "class";
+
+ out << typeName << " ";
+
+ if (!isReflected())
{
- Node* node = ioNodes[j];
+ out << " (";
+ }
+ out << m_name.getContent();
+ if (!isReflected())
+ {
+ out << ") ";
+ }
- if (!inFilter(node))
- {
- ioNodes.removeAt(j);
- count--;
- }
- else
- {
- j++;
- }
+ if (m_super.hasContent())
+ {
+ out << " : " << m_super.getContent();
+ }
+
+ out << " {\n";
+
+ for (Node* child : m_children)
+ {
+ child->dump(indentCount + 1, out);
}
+
+ _indent(indentCount, out);
+ out << "}\n";
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Options !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -729,7 +798,7 @@ struct Options
String m_inputDirectory; ///< The input directory that is by default used for reading m_inputPaths from.
String m_markPrefix; ///< The prefix of the 'marker' used to identify a reflected type
- String m_markSuffix; ///< The postfix of the 'marker' used to identify a reflected type
+ String m_markSuffix; ///< The postfix of the 'marker' used to identify a reflected type
String m_stripFilePrefix; ///< Used for the 'origin' information, this is stripped from the source filename, and the remainder of the filename (without extension) is 'macroized'
};
@@ -886,7 +955,7 @@ CPPExtractor::CPPExtractor(StringSlicePool* typePool, NamePool* namePool, Diagno
m_identifierLookup(identifierLookup),
m_typeSetPool(StringSlicePool::Style::Empty)
{
- m_rootNode = new Node(Node::Type::Namespace);
+ m_rootNode = new ScopeNode(Node::Type::Namespace);
m_rootNode->m_reflectionType = ReflectionType::Reflected;
}
@@ -992,52 +1061,74 @@ bool CPPExtractor::advanceIfStyle(IdentifierStyle style, Token* outToken)
SlangResult CPPExtractor::pushAnonymousNamespace()
{
- m_currentNode = m_currentNode->getAnonymousNamespace();
+ m_currentScope = m_currentScope->getAnonymousNamespace();
if (m_origin)
{
- m_origin->addNode(m_currentNode);
+ m_origin->addNode(m_currentScope);
}
return SLANG_OK;
}
-SlangResult CPPExtractor::pushNode(Node* node)
+SlangResult CPPExtractor::pushScope(ScopeNode* scopeNode)
{
if (m_origin)
{
- m_origin->addNode(node);
+ m_origin->addNode(scopeNode);
}
- if (node->m_name.hasContent())
+ if (scopeNode->m_name.hasContent())
{
// For anonymous namespace, we should look if we already have one and just reopen that. Doing so will mean will
// find anonymous namespace clashes
- if (Node* foundNode = m_currentNode->findChild(node->m_name.getContent()))
+ if (Node* foundNode = m_currentScope->findChild(scopeNode->m_name.getContent()))
{
- if (node->isClassLike())
+ if (scopeNode->isClassLike())
{
- m_sink->diagnose(m_reader.peekToken(), CPPDiagnostics::typeAlreadyDeclared, node->m_name.getContent());
- m_sink->diagnose(foundNode->m_name, CPPDiagnostics::seeDeclarationOf, node->m_name.getContent());
+ m_sink->diagnose(m_reader.peekToken(), CPPDiagnostics::typeAlreadyDeclared, scopeNode->m_name.getContent());
+ m_sink->diagnose(foundNode->m_name, CPPDiagnostics::seeDeclarationOf, scopeNode->m_name.getContent());
return SLANG_FAIL;
}
-
- if (node->m_type == Node::Type::Namespace)
+
+ if (foundNode->m_type == Node::Type::Namespace)
{
+ if (foundNode->m_type != scopeNode->m_type)
+ {
+ // Different types can't work
+ m_sink->diagnose(m_reader.peekToken(), CPPDiagnostics::typeAlreadyDeclared, scopeNode->m_name.getContent());
+ return SLANG_FAIL;
+ }
+
+ ScopeNode* foundScopeNode = as<ScopeNode>(foundNode);
+ SLANG_ASSERT(foundScopeNode);
+
// Make sure the node is empty, as we are *not* going to add it, we are just going to use
// the pre-existing namespace
- SLANG_ASSERT(node->m_children.getCount() == 0);
+ SLANG_ASSERT(scopeNode->m_children.getCount() == 0);
// We can just use the pre-existing namespace
- m_currentNode = foundNode;
+ m_currentScope = foundScopeNode;
return SLANG_OK;
}
}
}
- m_currentNode->addChild(node);
- m_currentNode = node;
+ m_currentScope->addChild(scopeNode);
+ m_currentScope = scopeNode;
+ return SLANG_OK;
+}
+
+SlangResult CPPExtractor::popScope()
+{
+ if (m_currentScope->m_parentScope == nullptr)
+ {
+ m_sink->diagnose(m_reader.peekLoc(), CPPDiagnostics::scopeNotClosed);
+ return SLANG_FAIL;
+ }
+
+ m_currentScope = m_currentScope->m_parentScope;
return SLANG_OK;
}
@@ -1082,17 +1173,6 @@ SlangResult CPPExtractor::consumeToClosingBrace(const Token* inOpenBraceToken)
}
}
-SlangResult CPPExtractor::popBrace()
-{
- if (m_currentNode->m_parentScope == nullptr)
- {
- m_sink->diagnose(m_reader.peekLoc(), CPPDiagnostics::scopeNotClosed);
- return SLANG_FAIL;
- }
-
- m_currentNode = m_currentNode->m_parentScope;
- return SLANG_OK;
-}
SlangResult CPPExtractor::_maybeParseNode(Node::Type type)
{
@@ -1114,10 +1194,10 @@ SlangResult CPPExtractor::_maybeParseNode(Node::Type type)
if (advanceIfToken(TokenType::LBrace))
{
// Okay looks like we are opening a namespace
- RefPtr<Node> node(new Node(Node::Type::Namespace));
+ RefPtr<ScopeNode> node(new ScopeNode(Node::Type::Namespace));
node->m_name = name;
// Push the node
- return pushNode(node);
+ return pushScope(node);
}
}
@@ -1142,7 +1222,7 @@ SlangResult CPPExtractor::_maybeParseNode(Node::Type type)
return SLANG_OK;
}
- RefPtr<Node> node(new Node(type));
+ RefPtr<ClassLikeNode> node(new ClassLikeNode(type));
node->m_name = name;
// Defaults to not reflected
@@ -1178,7 +1258,7 @@ SlangResult CPPExtractor::_maybeParseNode(Node::Type type)
m_reader.advanceToken();
}
- return pushNode(node);
+ return pushScope(node);
}
Token braceToken = m_reader.advanceToken();
@@ -1202,14 +1282,14 @@ SlangResult CPPExtractor::_maybeParseNode(Node::Type type)
case TokenType::Identifier: break;
case TokenType::RBrace:
{
- SLANG_RETURN_ON_FAIL(pushNode(node));
- SLANG_RETURN_ON_FAIL(popBrace());
+ SLANG_RETURN_ON_FAIL(pushScope(node));
+ SLANG_RETURN_ON_FAIL(popScope());
m_reader.advanceToken();
return SLANG_OK;
}
default:
{
- SLANG_RETURN_ON_FAIL(pushNode(node));
+ SLANG_RETURN_ON_FAIL(pushScope(node));
return SLANG_OK;
}
}
@@ -1221,7 +1301,7 @@ SlangResult CPPExtractor::_maybeParseNode(Node::Type type)
}
// We still need to add the node,
- SLANG_RETURN_ON_FAIL(pushNode(node));
+ SLANG_RETURN_ON_FAIL(pushScope(node));
return SLANG_OK;
}
@@ -1262,7 +1342,7 @@ SlangResult CPPExtractor::_maybeParseNode(Node::Type type)
}
node->m_reflectionType = ReflectionType::Reflected;
- return pushNode(node);
+ return pushScope(node);
}
SlangResult CPPExtractor::_consumeToSync()
@@ -1400,7 +1480,7 @@ static bool _canRepeatTokenType(TokenType type)
return true;
}
-// Returns true if there needs to be a spave between the previous token type, and the current token
+// Returns true if there needs to be a space between the previous token type, and the current token
// type for correct output. It is assumed that the token stream is appropriate.
// The implementation might need more sophistication, but this at least avoids Blah const * -> Blahconst*
static bool _tokenConcatNeedsSpace(TokenType prev, TokenType cur)
@@ -1602,7 +1682,8 @@ SlangResult CPPExtractor::_parseBalanced(DiagnosticSink* sink)
SlangResult CPPExtractor::_maybeParseField()
{
- Node::Field field;
+ // Can only add a field if we are in a class
+ SLANG_ASSERT(m_currentScope->isClassLike());
UnownedStringSlice typeName;
if (SLANG_FAILED(_maybeParseType(typeName)))
@@ -1660,12 +1741,13 @@ SlangResult CPPExtractor::_maybeParseField()
}
case TokenType::Semicolon:
{
- Node::Field field;
- field.type = typeName;
- field.name = fieldName;
- field.reflectionType = m_currentNode->getContainedReflectionType();
+ FieldNode* fieldNode = new FieldNode;
- m_currentNode->m_fields.add(field);
+ fieldNode->m_fieldType = typeName;
+ fieldNode->m_name = fieldName;
+ fieldNode->m_reflectionType = m_currentScope->getContainedReflectionType();
+
+ m_currentScope->addChild(fieldNode);
break;
}
default: break;
@@ -1741,18 +1823,31 @@ SlangResult CPPExtractor::_parsePreDeclare()
SLANG_RETURN_ON_FAIL(expect(TokenType::RParent));
- RefPtr<Node> node(new Node(nodeType));
+ switch (nodeType)
+ {
+ case Node::Type::ClassType:
+ case Node::Type::StructType:
+ {
+ RefPtr<ClassLikeNode> node(new ClassLikeNode(nodeType));
+
+ node->m_name = name;
+ node->m_super = super;
+ node->m_typeSet = typeSet;
- node->m_name = name;
- node->m_super = super;
- node->m_typeSet = typeSet;
+ // Assume it is reflected
+ node->m_reflectionType = ReflectionType::Reflected;
- // Assume it is reflected
- node->m_reflectionType = ReflectionType::Reflected;
+ SLANG_RETURN_ON_FAIL(pushScope(node));
+ // Pop out of the node
+ popScope();
+ break;
+ }
+ default:
+ {
+ return SLANG_FAIL;
+ }
+ }
- SLANG_RETURN_ON_FAIL(pushNode(node));
- // Pop out of the node
- popBrace();
return SLANG_OK;
}
@@ -1803,7 +1898,7 @@ SlangResult CPPExtractor::parse(SourceFile* sourceFile, const Options* options)
Lexer lexer;
- m_currentNode = m_rootNode;
+ m_currentScope = m_rootNode;
lexer.initialize(sourceView, m_sink, m_namePool, manager->getMemoryArena());
m_tokenList = lexer.lexAllTokens();
@@ -1838,18 +1933,18 @@ SlangResult CPPExtractor::parse(SourceFile* sourceFile, const Options* options)
case IdentifierStyle::Reflected:
{
m_reader.advanceToken();
- if (m_currentNode)
+ if (m_currentScope)
{
- m_currentNode->m_reflectionOverride = ReflectionType::Reflected;
+ m_currentScope->m_reflectionOverride = ReflectionType::Reflected;
}
break;
}
case IdentifierStyle::Unreflected:
{
m_reader.advanceToken();
- if (m_currentNode)
+ if (m_currentScope)
{
- m_currentNode->m_reflectionOverride = ReflectionType::NotReflected;
+ m_currentScope->m_reflectionOverride = ReflectionType::NotReflected;
}
break;
}
@@ -1872,7 +1967,7 @@ SlangResult CPPExtractor::parse(SourceFile* sourceFile, const Options* options)
{
// Special case the node that's the root of the hierarchy (as far as reflection is concerned)
// This could be a field
- if (m_currentNode->acceptsFields())
+ if (m_currentScope->acceptsFields())
{
SLANG_RETURN_ON_FAIL(_maybeParseField());
}
@@ -1893,14 +1988,14 @@ SlangResult CPPExtractor::parse(SourceFile* sourceFile, const Options* options)
}
case TokenType::RBrace:
{
- SLANG_RETURN_ON_FAIL(popBrace());
+ SLANG_RETURN_ON_FAIL(popScope());
m_reader.advanceToken();
break;
}
case TokenType::EndOfFile:
{
// Okay we need to confirm that we are in the root node, and with no open braces
- if (m_currentNode != m_rootNode)
+ if (m_currentScope != m_rootNode)
{
m_sink->diagnose(m_reader.peekToken(), CPPDiagnostics::braceOpenAtEndOfFile);
return SLANG_FAIL;
@@ -1935,7 +2030,7 @@ SlangResult CPPExtractor::parse(SourceFile* sourceFile, const Options* options)
}
}
-Node* CPPExtractor::findNode(Node* scope, const UnownedStringSlice& name)
+Node* CPPExtractor::findNode(ScopeNode* scope, const UnownedStringSlice& name)
{
// TODO(JS): We may want to lookup based on the path.
// If the name is qualified, we give up for not
@@ -1958,60 +2053,68 @@ Node* CPPExtractor::findNode(Node* scope, const UnownedStringSlice& name)
return nullptr;
}
-SlangResult CPPExtractor::_calcDerivedTypesRec(Node* node)
+SlangResult CPPExtractor::_calcDerivedTypesRec(ScopeNode* inScopeNode)
{
- if (node->isClassLike())
+ if (inScopeNode->isClassLike())
{
- if (node->m_super.hasContent())
+ ClassLikeNode* classLikeNode = static_cast<ClassLikeNode*>(inScopeNode);
+
+ if (classLikeNode->m_super.hasContent())
{
- Node* parentScope = node->m_parentScope;
+ ScopeNode* parentScope = classLikeNode->m_parentScope;
if (parentScope == nullptr)
{
m_sink->diagnoseRaw(Severity::Error, UnownedStringSlice::fromLiteral("Can't lookup in scope if there is none!"));
return SLANG_FAIL;
}
- Node* superType = findNode(parentScope, node->m_super.getContent());
+ Node* superNode = findNode(parentScope, classLikeNode->m_super.getContent());
- if (!superType)
+ if (!superNode)
{
- if (node->isReflected())
+ if (classLikeNode->isReflected())
{
- m_sink->diagnose(node->m_name, CPPDiagnostics::superTypeNotFound, node->getAbsoluteName());
+ m_sink->diagnose(classLikeNode->m_name, CPPDiagnostics::superTypeNotFound, classLikeNode->getAbsoluteName());
return SLANG_FAIL;
}
}
else
{
- if (!superType->isClassLike())
+ ClassLikeNode* superType = as<ClassLikeNode>(superNode);
+
+ if (!superType)
{
- m_sink->diagnose(node->m_name, CPPDiagnostics::superTypeNotAType, node->getAbsoluteName());
+ m_sink->diagnose(classLikeNode->m_name, CPPDiagnostics::superTypeNotAType, classLikeNode->getAbsoluteName());
return SLANG_FAIL;
}
- if (superType->m_typeSet != node->m_typeSet)
+ if (superType->m_typeSet != classLikeNode->m_typeSet)
{
- m_sink->diagnose(node->m_name, CPPDiagnostics::typeInDifferentTypeSet, node->m_name.getContent(), node->m_typeSet->m_macroName, superType->m_typeSet->m_macroName);
+ m_sink->diagnose(classLikeNode->m_name, CPPDiagnostics::typeInDifferentTypeSet, classLikeNode->m_name.getContent(), classLikeNode->m_typeSet->m_macroName, superType->m_typeSet->m_macroName);
return SLANG_FAIL;
}
// The base class must be defined in same scope (as we didn't allow different scopes for base classes)
- superType->addDerived(node);
+ superType->addDerived(classLikeNode);
}
}
else
{
- // Add the root nodes
- if (node->isReflected())
+ // Add to it's own typeset
+ if (classLikeNode->isReflected())
{
- node->m_typeSet->m_baseTypes.add(node);
+ classLikeNode->m_typeSet->m_baseTypes.add(classLikeNode);
}
}
}
- for (Node* child : node->m_children)
+ for (Node* child : inScopeNode->m_children)
{
- SLANG_RETURN_ON_FAIL(_calcDerivedTypesRec(child));
+ ScopeNode* childScope = as<ScopeNode>(child);
+ if (childScope)
+ {
+ SLANG_RETURN_ON_FAIL(_calcDerivedTypesRec(childScope));
+ }
}
return SLANG_OK;
@@ -2148,15 +2251,18 @@ SlangResult CPPExtractorApp::calcDef(CPPExtractor& extractor, SourceOrigin* orig
for (Node* node : origin->m_nodes)
{
- if (node->isClassLike() && node->isReflected())
+ if (node->isReflected())
{
- if (node->m_marker.getContent().indexOf(UnownedStringSlice::fromLiteral("ABSTRACT")) >= 0)
+ if (auto classLikeNode = as<ClassLikeNode>(node))
{
- out << "ABSTRACT_";
- }
+ if (classLikeNode->m_marker.getContent().indexOf(UnownedStringSlice::fromLiteral("ABSTRACT")) >= 0)
+ {
+ out << "ABSTRACT_";
+ }
- out << "SYNTAX_CLASS(" << node->m_name.getContent() << ", " << node->m_super.getContent() << ")\n";
- out << "END_SYNTAX_CLASS()\n\n";
+ out << "SYNTAX_CLASS(" << node->m_name.getContent() << ", " << classLikeNode->m_super.getContent() << ")\n";
+ out << "END_SYNTAX_CLASS()\n\n";
+ }
}
}
return SLANG_OK;
@@ -2164,32 +2270,32 @@ SlangResult CPPExtractorApp::calcDef(CPPExtractor& extractor, SourceOrigin* orig
SlangResult CPPExtractorApp::calcChildrenHeader(CPPExtractor& extractor, TypeSet* typeSet, StringBuilder& out)
{
- const List<Node*>& baseTypes = typeSet->m_baseTypes;
+ const List<ClassLikeNode*>& baseTypes = typeSet->m_baseTypes;
const String& reflectTypeName = typeSet->m_typeName;
out << "#pragma once\n\n";
out << "// Do not edit this file is generated from slang-cpp-extractor tool\n\n";
- List<Node*> nodes;
+ List<ClassLikeNode*> classNodes;
for (Index i = 0; i < baseTypes.getCount(); ++i)
{
- Node* baseType = baseTypes[i];
- baseType->calcDerivedDepthFirst(nodes);
+ ClassLikeNode* baseType = baseTypes[i];
+ baseType->calcDerivedDepthFirst(classNodes);
}
- Node::filter(Node::isClassLike, nodes);
+ //Node::filter(Node::isClassLike, nodes);
- List<Node*> derivedTypes;
+ List<ClassLikeNode*> derivedTypes;
out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! CHILDREN !!!!!!!!!!!!!!!!!!!!!!!!!!!! */ \n\n";
// Now the children
- for (Node* node : nodes)
+ for (ClassLikeNode* classNode : classNodes)
{
- node->getReflectedDerivedTypes(derivedTypes);
+ classNode->getReflectedDerivedTypes(derivedTypes);
// Define the derived types
- out << "#define " << m_options.m_markPrefix << "CHILDREN_" << reflectTypeName << "_" << node->m_name.getContent() << "(x, param)";
+ out << "#define " << m_options.m_markPrefix << "CHILDREN_" << reflectTypeName << "_" << classNode->m_name.getContent() << "(x, param)";
if (derivedTypes.getCount())
{
@@ -2210,19 +2316,19 @@ SlangResult CPPExtractorApp::calcChildrenHeader(CPPExtractor& extractor, TypeSet
out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ALL !!!!!!!!!!!!!!!!!!!!!!!!!!!! */\n\n";
- for (Node* node : nodes)
+ for (ClassLikeNode* classNode : classNodes)
{
// Define the derived types
- out << "#define " << m_options.m_markPrefix << "ALL_" << reflectTypeName << "_" << node->m_name.getContent() << "(x, param) \\\n";
+ out << "#define " << m_options.m_markPrefix << "ALL_" << reflectTypeName << "_" << classNode->m_name.getContent() << "(x, param) \\\n";
_indent(1, out);
- out << m_options.m_markPrefix << reflectTypeName << "_" << node->m_name.getContent() << "(x, param)";
+ out << m_options.m_markPrefix << reflectTypeName << "_" << classNode->m_name.getContent() << "(x, param)";
// If has derived types output them
- if (node->hasReflectedDerivedType())
+ if (classNode->hasReflectedDerivedType())
{
out << " \\\n";
_indent(1, out);
- out << m_options.m_markPrefix << "CHILDREN_" << reflectTypeName << "_" << node->m_name.getContent() << "(x, param)";
+ out << m_options.m_markPrefix << "CHILDREN_" << reflectTypeName << "_" << classNode->m_name.getContent() << "(x, param)";
}
out << "\n\n";
}
@@ -2231,22 +2337,32 @@ SlangResult CPPExtractorApp::calcChildrenHeader(CPPExtractor& extractor, TypeSet
{
out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! FIELDS !!!!!!!!!!!!!!!!!!!!!!!!!!!! */\n\n";
- for (Node* node : nodes)
+ for (ClassLikeNode* classNode : classNodes)
{
// Define the derived types
- out << "#define " << m_options.m_markPrefix << "FIELDS_" << reflectTypeName << "_" << node->m_name.getContent() << "(_x_, _param_)";
+ out << "#define " << m_options.m_markPrefix << "FIELDS_" << reflectTypeName << "_" << classNode->m_name.getContent() << "(_x_, _param_)";
+
+ // Find all of the fields
+ List<FieldNode*> fields;
+ for (Node* child : classNode->m_children)
+ {
+ if (auto field = as<FieldNode>(child))
+ {
+ fields.add(field);
+ }
+ }
- if (node->m_fields.getCount() > 0)
+ if (fields.getCount() > 0)
{
out << "\\\n";
- const Index fieldsCount = node->m_fields.getCount();
+ const Index fieldsCount = fields.getCount();
bool previousField = false;
for (Index j = 0; j < fieldsCount; ++j)
{
- const auto& field = node->m_fields[j];
+ const FieldNode* field = fields[j];
- if (field.isReflected())
+ if (field->isReflected())
{
if (previousField)
{
@@ -2257,7 +2373,7 @@ SlangResult CPPExtractorApp::calcChildrenHeader(CPPExtractor& extractor, TypeSet
// NOTE! We put the type field in brackets, such that there is no issue with templates containing a comma.
// If stringified
- out << "_x_(" << field.name.getContent() << ", (" << field.type << "), _param_)";
+ out << "_x_(" << field->m_name.getContent() << ", (" << field->m_fieldType << "), _param_)";
previousField = true;
}
}
@@ -2298,7 +2414,7 @@ SlangResult CPPExtractorApp::calcOriginHeader(CPPExtractor& extractor, StringBui
SlangResult CPPExtractorApp::calcTypeHeader(CPPExtractor& extractor, TypeSet* typeSet, StringBuilder& out)
{
- const List<Node*>& baseTypes = typeSet->m_baseTypes;
+ const List<ClassLikeNode*>& baseTypes = typeSet->m_baseTypes;
const String& reflectTypeName = typeSet->m_typeName;
out << "#pragma once\n\n";
@@ -2325,10 +2441,10 @@ SlangResult CPPExtractorApp::calcTypeHeader(CPPExtractor& extractor, TypeSet* ty
}
// Add all the base types, with in order traversals
- List<Node*> nodes;
+ List<ClassLikeNode*> nodes;
for (Index i = 0; i < baseTypes.getCount(); ++i)
{
- Node* baseType = baseTypes[i];
+ ClassLikeNode* baseType = baseTypes[i];
baseType->calcDerivedDepthFirst(nodes);
}
@@ -2341,7 +2457,7 @@ SlangResult CPPExtractorApp::calcTypeHeader(CPPExtractor& extractor, TypeSet* ty
out << "{\n";
Index typeIndex = 0;
- for (Node* node : nodes)
+ for (ClassLikeNode* node : nodes)
{
// Okay first we are going to output the enum values
const Index depth = node->calcDerivedDepth() - 1;
@@ -2363,9 +2479,8 @@ SlangResult CPPExtractorApp::calcTypeHeader(CPPExtractor& extractor, TypeSet* ty
// Predeclare the classes
{
out << "// Predeclare\n\n";
- for (Node* node : nodes)
+ for (ClassLikeNode* node : nodes)
{
- SLANG_ASSERT(node->isClassLike());
// If it's not reflected we don't output, in the enum list
if (node->isReflected())
{
@@ -2390,7 +2505,7 @@ SlangResult CPPExtractorApp::calcTypeHeader(CPPExtractor& extractor, TypeSet* ty
out << "// param is a user defined parameter that can be parsed to the invoked x macro\n\n";
// Output all of the definitions for each type
- for (Node* node : nodes)
+ for (ClassLikeNode* node : nodes)
{
out << "#define " << m_options.m_markPrefix << reflectTypeName << "_" << node->m_name.getContent() << "(x, param) ";
@@ -2657,9 +2772,9 @@ SlangResult CPPExtractorApp::execute(const Options& options)
for (TypeSet* typeSet : extractor.getTypeSets())
{
- const List<Node*>& baseTypes = typeSet->m_baseTypes;
+ const List<ClassLikeNode*>& baseTypes = typeSet->m_baseTypes;
- for (Node* baseType : baseTypes)
+ for (ClassLikeNode* baseType : baseTypes)
{
StringBuilder buf;
baseType->dumpDerived(0, buf);
@@ -2698,6 +2813,7 @@ int main(int argc, const char*const* argv)
using namespace SlangExperimental;
using namespace Slang;
+
{
ComPtr<ISlangWriter> writer(new FileWriter(stderr, WriterFlag::AutoFlush));
@@ -2709,6 +2825,22 @@ int main(int argc, const char*const* argv)
DiagnosticSink sink(&sourceManager, Lexer::sourceLocationLexer);
sink.writer = writer;
+ // Set to true to see command line that initiated C++ extractor. Helpful when finding issues from solution building failing, and then so
+ // being able to repeat the issue
+ bool dumpCommandLine = false;
+
+ if (dumpCommandLine)
+ {
+ StringBuilder builder;
+
+ for (Index i = 1; i < argc; ++i)
+ {
+ builder << argv[i] << " ";
+ }
+
+ sink.diagnose(SourceLoc(), CPPDiagnostics::commandLine, builder);
+ }
+
CPPExtractorApp app(&sink, &sourceManager, &rootNamePool);
try