forked from OSchip/llvm-project
Revert "[clang-diff] Move the JSON export function to clang-diff"
This reverts commit r311199, it was causing widespread build failures. llvm-svn: 311211
This commit is contained in:
parent
ebcb773f7d
commit
deb2a2adc8
|
@ -57,8 +57,8 @@ struct Node {
|
||||||
ast_type_traits::DynTypedNode ASTNode;
|
ast_type_traits::DynTypedNode ASTNode;
|
||||||
SmallVector<NodeId, 4> Children;
|
SmallVector<NodeId, 4> Children;
|
||||||
|
|
||||||
ast_type_traits::ASTNodeKind getType() const;
|
ast_type_traits::ASTNodeKind getType() const { return ASTNode.getNodeKind(); }
|
||||||
StringRef getTypeLabel() const;
|
const StringRef getTypeLabel() const { return getType().asStringRef(); }
|
||||||
bool isLeaf() const { return Children.empty(); }
|
bool isLeaf() const { return Children.empty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,20 +96,15 @@ public:
|
||||||
SyntaxTree(SyntaxTree &&Other) = default;
|
SyntaxTree(SyntaxTree &&Other) = default;
|
||||||
~SyntaxTree();
|
~SyntaxTree();
|
||||||
|
|
||||||
const ASTContext &getASTContext() const;
|
|
||||||
StringRef getFilename() const;
|
|
||||||
|
|
||||||
const Node &getNode(NodeId Id) const;
|
const Node &getNode(NodeId Id) const;
|
||||||
NodeId getRootId() const;
|
|
||||||
|
|
||||||
// Returns the starting and ending offset of the node in its source file.
|
|
||||||
std::pair<unsigned, unsigned> getSourceRangeOffsets(const Node &N) const;
|
|
||||||
|
|
||||||
/// Serialize the node attributes to a string representation. This should
|
/// Serialize the node attributes to a string representation. This should
|
||||||
/// uniquely distinguish nodes of the same kind. Note that this function just
|
/// uniquely distinguish nodes of the same kind. Note that this function just
|
||||||
/// returns a representation of the node value, not considering descendants.
|
/// returns a representation of the node value, not considering descendants.
|
||||||
std::string getNodeValue(const DynTypedNode &DTN) const;
|
std::string getNodeValue(const DynTypedNode &DTN) const;
|
||||||
|
|
||||||
|
void printAsJson(raw_ostream &OS);
|
||||||
|
|
||||||
class Impl;
|
class Impl;
|
||||||
std::unique_ptr<Impl> TreeImpl;
|
std::unique_ptr<Impl> TreeImpl;
|
||||||
};
|
};
|
||||||
|
|
|
@ -176,6 +176,9 @@ public:
|
||||||
void printTree(NodeId Root) const;
|
void printTree(NodeId Root) const;
|
||||||
void printTree(raw_ostream &OS, NodeId Root) const;
|
void printTree(raw_ostream &OS, NodeId Root) const;
|
||||||
|
|
||||||
|
void printAsJsonImpl(raw_ostream &OS) const;
|
||||||
|
void printNodeAsJson(raw_ostream &OS, NodeId Id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Nodes in preorder.
|
/// Nodes in preorder.
|
||||||
std::vector<Node> Nodes;
|
std::vector<Node> Nodes;
|
||||||
|
@ -435,6 +438,28 @@ void SyntaxTree::Impl::printNode(raw_ostream &OS, NodeId Id) const {
|
||||||
OS << "(" << PostorderIds[Id] << ")";
|
OS << "(" << PostorderIds[Id] << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SyntaxTree::Impl::printNodeAsJson(raw_ostream &OS, NodeId Id) const {
|
||||||
|
auto N = getNode(Id);
|
||||||
|
OS << R"({"type":")" << N.getTypeLabel() << R"(")";
|
||||||
|
if (getNodeValue(Id) != "")
|
||||||
|
OS << R"(,"value":")" << getNodeValue(Id) << R"(")";
|
||||||
|
OS << R"(,"children":[)";
|
||||||
|
if (N.Children.size() > 0) {
|
||||||
|
printNodeAsJson(OS, N.Children[0]);
|
||||||
|
for (size_t I = 1, E = N.Children.size(); I < E; ++I) {
|
||||||
|
OS << ",";
|
||||||
|
printNodeAsJson(OS, N.Children[I]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OS << "]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
void SyntaxTree::Impl::printAsJsonImpl(raw_ostream &OS) const {
|
||||||
|
OS << R"({"root":)";
|
||||||
|
printNodeAsJson(OS, getRootId());
|
||||||
|
OS << "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
/// Identifies a node in a subtree by its postorder offset, starting at 1.
|
/// Identifies a node in a subtree by its postorder offset, starting at 1.
|
||||||
struct SNodeId {
|
struct SNodeId {
|
||||||
int Id = 0;
|
int Id = 0;
|
||||||
|
@ -649,12 +674,6 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ast_type_traits::ASTNodeKind Node::getType() const {
|
|
||||||
return ASTNode.getNodeKind();
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRef Node::getTypeLabel() const { return getType().asStringRef(); }
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Compares nodes by their depth.
|
// Compares nodes by their depth.
|
||||||
struct HeightLess {
|
struct HeightLess {
|
||||||
|
@ -980,28 +999,7 @@ void ASTDiff::printMatch(raw_ostream &OS, const Match &M) const {
|
||||||
|
|
||||||
SyntaxTree::~SyntaxTree() = default;
|
SyntaxTree::~SyntaxTree() = default;
|
||||||
|
|
||||||
const ASTContext &SyntaxTree::getASTContext() const { return TreeImpl->AST; }
|
void SyntaxTree::printAsJson(raw_ostream &OS) { TreeImpl->printAsJsonImpl(OS); }
|
||||||
|
|
||||||
const Node &SyntaxTree::getNode(NodeId Id) const {
|
|
||||||
return TreeImpl->getNode(Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeId SyntaxTree::getRootId() const { return TreeImpl->getRootId(); }
|
|
||||||
|
|
||||||
std::pair<unsigned, unsigned> SyntaxTree::getSourceRangeOffsets(const Node &N) const {
|
|
||||||
const SourceManager &SrcMgr = TreeImpl->AST.getSourceManager();
|
|
||||||
SourceRange Range = N.ASTNode.getSourceRange();
|
|
||||||
SourceLocation BeginLoc = Range.getBegin();
|
|
||||||
SourceLocation EndLoc = Lexer::getLocForEndOfToken(
|
|
||||||
Range.getEnd(), /*Offset=*/0, SrcMgr, TreeImpl->AST.getLangOpts());
|
|
||||||
if (auto *ThisExpr = N.ASTNode.get<CXXThisExpr>()) {
|
|
||||||
if (ThisExpr->isImplicit())
|
|
||||||
EndLoc = BeginLoc;
|
|
||||||
}
|
|
||||||
unsigned Begin = SrcMgr.getFileOffset(SrcMgr.getExpansionLoc(BeginLoc));
|
|
||||||
unsigned End = SrcMgr.getFileOffset(SrcMgr.getExpansionLoc(EndLoc));
|
|
||||||
return {Begin, End};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SyntaxTree::getNodeValue(const DynTypedNode &DTN) const {
|
std::string SyntaxTree::getNodeValue(const DynTypedNode &DTN) const {
|
||||||
return TreeImpl->getNodeValue(DTN);
|
return TreeImpl->getNodeValue(DTN);
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
// RUN: clang-diff -ast-dump %s -- \
|
|
||||||
// RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
|
|
||||||
// RUN: | FileCheck %s
|
|
||||||
|
|
||||||
// CHECK: "begin": 294,
|
|
||||||
// CHECK: "type": "CXXRecordDecl",
|
|
||||||
// CHECK: "type": "FieldDecl",
|
|
||||||
// CHECK: "end": 314,
|
|
||||||
class A {
|
|
||||||
int x;
|
|
||||||
};
|
|
||||||
|
|
||||||
// CHECK: "children": [
|
|
||||||
// CHECK-NEXT: {
|
|
||||||
// CHECK-NEXT: "begin":
|
|
||||||
// CHECK-NEXT: "children": []
|
|
||||||
// CHECK-NEXT: "end":
|
|
||||||
// CHECK-NEXT: "id":
|
|
||||||
// CHECK-NEXT: "type": "CharacterLiteral"
|
|
||||||
// CHECK-NEXT: }
|
|
||||||
// CHECK: ]
|
|
||||||
// CHECK: "type": "VarDecl",
|
|
||||||
char nl = '\n';
|
|
||||||
|
|
||||||
// CHECK: "value": "abc \n\t\u0000\u001f\u0123 \ub370\ubc15"
|
|
||||||
char s[] = "abc \n\t\0\x1f\u0123 데박";
|
|
||||||
|
|
|
@ -276,7 +276,6 @@ config.substitutions.append( ('%test_debuginfo', ' ' + config.llvm_src_root + '/
|
||||||
config.substitutions.append( ('%itanium_abi_triple', makeItaniumABITriple(config.target_triple)) )
|
config.substitutions.append( ('%itanium_abi_triple', makeItaniumABITriple(config.target_triple)) )
|
||||||
config.substitutions.append( ('%ms_abi_triple', makeMSABITriple(config.target_triple)) )
|
config.substitutions.append( ('%ms_abi_triple', makeMSABITriple(config.target_triple)) )
|
||||||
config.substitutions.append( ('%resource_dir', getClangBuiltinIncludeDir(config.clang)) )
|
config.substitutions.append( ('%resource_dir', getClangBuiltinIncludeDir(config.clang)) )
|
||||||
config.substitutions.append( ('%python', config.python_executable) )
|
|
||||||
|
|
||||||
# The host triple might not be set, at least if we're compiling clang from
|
# The host triple might not be set, at least if we're compiling clang from
|
||||||
# an already installed llvm.
|
# an already installed llvm.
|
||||||
|
|
|
@ -25,7 +25,6 @@ config.enable_shared = @ENABLE_SHARED@
|
||||||
config.enable_backtrace = @ENABLE_BACKTRACES@
|
config.enable_backtrace = @ENABLE_BACKTRACES@
|
||||||
config.host_arch = "@HOST_ARCH@"
|
config.host_arch = "@HOST_ARCH@"
|
||||||
config.enable_abi_breaking_checks = "@LLVM_ENABLE_ABI_BREAKING_CHECKS@"
|
config.enable_abi_breaking_checks = "@LLVM_ENABLE_ABI_BREAKING_CHECKS@"
|
||||||
config.python_executable = "@PYTHON_EXECUTABLE@"
|
|
||||||
|
|
||||||
# Support substitution of the tools and libs dirs with user parameters. This is
|
# Support substitution of the tools and libs dirs with user parameters. This is
|
||||||
# used when we can't determine the tool dir at configuration time.
|
# used when we can't determine the tool dir at configuration time.
|
||||||
|
|
|
@ -94,65 +94,6 @@ getAST(const std::unique_ptr<CompilationDatabase> &CommonCompilations,
|
||||||
return std::move(ASTs[0]);
|
return std::move(ASTs[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char hexdigit(int N) { return N &= 0xf, N + (N < 10 ? '0' : 'a' - 10); }
|
|
||||||
|
|
||||||
static void printJsonString(raw_ostream &OS, const StringRef Str) {
|
|
||||||
for (char C : Str) {
|
|
||||||
switch (C) {
|
|
||||||
case '"':
|
|
||||||
OS << R"(\")";
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
OS << R"(\\)";
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
OS << R"(\n)";
|
|
||||||
break;
|
|
||||||
case '\t':
|
|
||||||
OS << R"(\t)";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if ('\x00' <= C && C <= '\x1f') {
|
|
||||||
OS << R"(\u00)" << hexdigit(C >> 4) << hexdigit(C);
|
|
||||||
} else {
|
|
||||||
OS << C;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printNodeAttributes(raw_ostream &OS, diff::SyntaxTree &Tree,
|
|
||||||
diff::NodeId Id) {
|
|
||||||
const diff::Node &N = Tree.getNode(Id);
|
|
||||||
OS << R"("id":)" << int(Id);
|
|
||||||
OS << R"(,"type":")" << N.getTypeLabel() << '"';
|
|
||||||
auto Offsets = Tree.getSourceRangeOffsets(N);
|
|
||||||
OS << R"(,"begin":)" << Offsets.first;
|
|
||||||
OS << R"(,"end":)" << Offsets.second;
|
|
||||||
std::string Value = Tree.getNodeValue(N.ASTNode);
|
|
||||||
if (!Value.empty()) {
|
|
||||||
OS << R"(,"value":")";
|
|
||||||
printJsonString(OS, Value);
|
|
||||||
OS << '"';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printNodeAsJson(raw_ostream &OS, diff::SyntaxTree &Tree,
|
|
||||||
diff::NodeId Id) {
|
|
||||||
const diff::Node &N = Tree.getNode(Id);
|
|
||||||
OS << "{";
|
|
||||||
printNodeAttributes(OS, Tree, Id);
|
|
||||||
OS << R"(,"children":[)";
|
|
||||||
if (N.Children.size() > 0) {
|
|
||||||
printNodeAsJson(OS, Tree, N.Children[0]);
|
|
||||||
for (size_t I = 1, E = N.Children.size(); I < E; ++I) {
|
|
||||||
OS << ",";
|
|
||||||
printNodeAsJson(OS, Tree, N.Children[I]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OS << "]}";
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, const char **argv) {
|
int main(int argc, const char **argv) {
|
||||||
std::string ErrorMessage;
|
std::string ErrorMessage;
|
||||||
std::unique_ptr<CompilationDatabase> CommonCompilations =
|
std::unique_ptr<CompilationDatabase> CommonCompilations =
|
||||||
|
@ -176,11 +117,7 @@ int main(int argc, const char **argv) {
|
||||||
if (!AST)
|
if (!AST)
|
||||||
return 1;
|
return 1;
|
||||||
diff::SyntaxTree Tree(AST->getASTContext());
|
diff::SyntaxTree Tree(AST->getASTContext());
|
||||||
llvm::outs() << R"({"filename":")";
|
Tree.printAsJson(llvm::outs());
|
||||||
printJsonString(llvm::outs(), SourcePath);
|
|
||||||
llvm::outs() << R"(","root":)";
|
|
||||||
printNodeAsJson(llvm::outs(), Tree, Tree.getRootId());
|
|
||||||
llvm::outs() << "}\n";
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue