Skip to content

Commit

Permalink
Added printing of source line info (#1011)
Browse files Browse the repository at this point in the history
  • Loading branch information
KennethDRoe committed Jun 11, 2024
1 parent a4d08eb commit 62d3958
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 9 deletions.
4 changes: 4 additions & 0 deletions docs/command-line-ref.dox
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ When dumping AST to JSON, include only the scope (or symbol) specified by the gi
This option can be specified more than once to include more than one scope. If not provided, all
symbols are dumped.

`--ast-json-source-info`

When dumping AST to JSON, include source line and file information.

@section compilation-limits Compilation

`--top <name>`
Expand Down
3 changes: 3 additions & 0 deletions include/slang/ast/ASTSerializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class SLANG_EXPORT ASTSerializer {
/// should be included in the JSON output.
void setIncludeAddresses(bool set) { includeAddrs = set; }

void setIncludeSourceInfo(bool set) { includeSourceInfo = set; }

/// Serializes a symbol to JSON.
void serialize(const Symbol& symbol, bool inMembersArray = false);

Expand Down Expand Up @@ -169,6 +171,7 @@ class SLANG_EXPORT ASTSerializer {
Compilation& compilation;
JsonWriter& writer;
bool includeAddrs = true;
bool includeSourceInfo = false;
};

} // namespace slang::ast
33 changes: 29 additions & 4 deletions source/ast/ASTSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
#include "slang/ast/ASTVisitor.h"
#include "slang/ast/Compilation.h"
#include "slang/ast/EvalContext.h"
#include "slang/syntax/AllSyntax.h"
#include "slang/text/CharInfo.h"
#include "slang/text/FormatBuffer.h"
#include "slang/text/Json.h"
#include "slang/text/SourceManager.h"

namespace slang::ast {

Expand Down Expand Up @@ -171,11 +175,29 @@ void ASTSerializer::writeProperty(std::string_view name) {

template<typename T>
void ASTSerializer::visit(const T& elem, bool inMembersArray) {
if constexpr (std::is_base_of_v<Expression, T>) {
if constexpr (std::is_base_of_v<Expression, T> || std::is_base_of_v<Statement, T> ||
std::is_base_of_v<TimingControl, T> || std::is_base_of_v<Constraint, T> ||
std::is_base_of_v<AssertionExpr, T> || std::is_base_of_v<BinsSelectExpr, T> ||
std::is_base_of_v<Pattern, T>) {
writer.startObject();
if (elem.syntax != nullptr && includeSourceInfo) {
write("source_file_start",
compilation.getSourceManager()->getFileName(elem.syntax->sourceRange().start()));
write("source_file_end",
compilation.getSourceManager()->getFileName(elem.syntax->sourceRange().end()));
write("source_line_start", compilation.getSourceManager()->getLineNumber(
elem.syntax->sourceRange().start()));
write("source_line_end",
compilation.getSourceManager()->getLineNumber(elem.syntax->sourceRange().end()));
write("source_column_start", compilation.getSourceManager()->getColumnNumber(
elem.syntax->sourceRange().start()));
write("source_column_end", compilation.getSourceManager()->getColumnNumber(
elem.syntax->sourceRange().end()));
}
}
if constexpr (std::is_base_of_v<Expression, T>) {
write("kind", toString(elem.kind));
write("type", *elem.type);

auto attributes = compilation.getAttributes(elem);
if (!attributes.empty()) {
startArray("attributes");
Expand All @@ -196,7 +218,6 @@ void ASTSerializer::visit(const T& elem, bool inMembersArray) {
writer.endObject();
}
else if constexpr (std::is_base_of_v<Statement, T>) {
writer.startObject();
write("kind", toString(elem.kind));

auto attributes = compilation.getAttributes(elem);
Expand All @@ -216,7 +237,6 @@ void ASTSerializer::visit(const T& elem, bool inMembersArray) {
else if constexpr (std::is_base_of_v<TimingControl, T> || std::is_base_of_v<Constraint, T> ||
std::is_base_of_v<AssertionExpr, T> ||
std::is_base_of_v<BinsSelectExpr, T> || std::is_base_of_v<Pattern, T>) {
writer.startObject();
write("kind", toString(elem.kind));
if constexpr (!std::is_same_v<TimingControl, T> && !std::is_same_v<Constraint, T> &&
!std::is_same_v<AssertionExpr, T> && !std::is_same_v<BinsSelectExpr, T> &&
Expand Down Expand Up @@ -246,6 +266,11 @@ void ASTSerializer::visit(const T& elem, bool inMembersArray) {
writer.startObject();
write("name", elem.name);
write("kind", toString(elem.kind));
if (includeSourceInfo) {
write("source_file", compilation.getSourceManager()->getFileName(elem.location));
write("source_line", compilation.getSourceManager()->getLineNumber(elem.location));
write("source_column", compilation.getSourceManager()->getColumnNumber(elem.location));
}

if (includeAddrs)
write("addr", uintptr_t(&elem));
Expand Down
52 changes: 49 additions & 3 deletions tests/unittests/ast/MemberTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,43 +365,74 @@ endmodule

ASTSerializer serializer(compilation, writer);
serializer.setIncludeAddresses(false);
serializer.setIncludeSourceInfo(true);
serializer.serialize(compilation.getRoot());

std::string result = "\n"s + std::string(writer.view());
CHECK(result == R"(
{
"name": "$root",
"kind": "Root",
"source_file": "",
"source_line": 0,
"source_column": 0,
"members": [
{
"name": "",
"kind": "CompilationUnit"
"kind": "CompilationUnit",
"source_file": "",
"source_line": 0,
"source_column": 0
},
{
"name": "test_enum",
"kind": "Instance",
"source_file": "source",
"source_line": 2,
"source_column": 8,
"body": {
"name": "test_enum",
"kind": "InstanceBody",
"source_file": "source",
"source_line": 2,
"source_column": 8,
"members": [
{
"name": "STATE_0",
"kind": "TransparentMember"
"kind": "TransparentMember",
"source_file": "source",
"source_line": 4,
"source_column": 9
},
{
"name": "STATE_1",
"kind": "TransparentMember"
"kind": "TransparentMember",
"source_file": "source",
"source_line": 5,
"source_column": 9
},
{
"name": "STATE",
"kind": "TypeAlias",
"source_file": "source",
"source_line": 6,
"source_column": 7,
"target": "enum{STATE_0=1'd0,STATE_1=1'd1}test_enum.e$1"
},
{
"name": "a",
"kind": "Variable",
"source_file": "source",
"source_line": 8,
"source_column": 11,
"type": "enum{STATE_0=1'd0,STATE_1=1'd1}test_enum.STATE",
"initializer": {
"source_file_start": "source",
"source_file_end": "source",
"source_line_start": 8,
"source_line_end": 8,
"source_column_start": 15,
"source_column_end": 22,
"kind": "NamedValue",
"type": "enum{STATE_0=1'd0,STATE_1=1'd1}test_enum.STATE",
"symbol": "STATE_0",
Expand All @@ -412,10 +443,16 @@ endmodule
{
"name": "C",
"kind": "ClassType",
"source_file": "source",
"source_line": 10,
"source_column": 11,
"members": [
{
"name": "i",
"kind": "ClassProperty",
"source_file": "source",
"source_line": 11,
"source_column": 13,
"type": "int",
"lifetime": "Automatic",
"visibility": "Public"
Expand All @@ -430,8 +467,17 @@ endmodule
{
"name": "c",
"kind": "Variable",
"source_file": "source",
"source_line": 14,
"source_column": 7,
"type": "C",
"initializer": {
"source_file_start": "source",
"source_file_end": "source",
"source_line_start": 14,
"source_line_end": 14,
"source_column_start": 11,
"source_column_end": 14,
"kind": "NewClass",
"type": "C",
"isSuperClass": false
Expand Down
10 changes: 8 additions & 2 deletions tools/driver/slang_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ using namespace slang::ast;
using namespace slang::driver;

void printJson(Compilation& compilation, const std::string& fileName,
const std::vector<std::string>& scopes) {
const std::vector<std::string>& scopes, bool includeSourceInfo = false) {
JsonWriter writer;
writer.setPrettyPrint(true);

ASTSerializer serializer(compilation, writer);
serializer.setIncludeSourceInfo(includeSourceInfo);
if (scopes.empty()) {
serializer.startObject();
serializer.writeProperty("design");
Expand Down Expand Up @@ -101,6 +102,10 @@ int driverMain(int argc, TArgs argv) {
"given hierarchical paths",
"<path>");

std::optional<bool> includeSourceInfo;
driver.cmdLine.add("--ast-json-source-info", includeSourceInfo,
"When dumping AST to JSON, include source line and file information");

std::optional<std::string> timeTrace;
driver.cmdLine.add("--time-trace", timeTrace,
"Do performance profiling of the slang compiler and output "
Expand Down Expand Up @@ -162,7 +167,8 @@ int driverMain(int argc, TArgs argv) {
auto compilation = driver.createCompilation();
ok &= driver.reportCompilation(*compilation, quiet == true);
if (astJsonFile)
printJson(*compilation, *astJsonFile, astJsonScopes);
printJson(*compilation, *astJsonFile, astJsonScopes,
(includeSourceInfo == true));
}
}
}
Expand Down

0 comments on commit 62d3958

Please sign in to comment.