Author: krobelus Date: Sun Aug 20 09:18:43 2017 New Revision: 311292 URL: http://llvm.org/viewvc/llvm-project?rev=311292&view=rev Log: [clang-diff] Improve and test getNodeValue
Summary: Use qualified names if available. Reviewers: arphaman Subscribers: klimek Differential Revision: https://reviews.llvm.org/D36186 Modified: cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp cfe/trunk/test/Tooling/clang-diff-ast.cpp cfe/trunk/test/Tooling/clang-diff-basic.cpp cfe/trunk/test/Tooling/clang-diff-bottomup.cpp cfe/trunk/test/Tooling/clang-diff-html.test cfe/trunk/test/Tooling/clang-diff-opt.cpp cfe/trunk/test/Tooling/clang-diff-topdown.cpp cfe/trunk/tools/clang-diff/ClangDiff.cpp Modified: cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h?rev=311292&r1=311291&r2=311292&view=diff ============================================================================== --- cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h (original) +++ cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h Sun Aug 20 09:18:43 2017 @@ -45,6 +45,8 @@ struct Node { ast_type_traits::ASTNodeKind getType() const; StringRef getTypeLabel() const; bool isLeaf() const { return Children.empty(); } + llvm::Optional<StringRef> getIdentifier() const; + llvm::Optional<std::string> getQualifiedIdentifier() const; }; class ASTDiff { Modified: cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp?rev=311292&r1=311291&r2=311292&view=diff ============================================================================== --- cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp (original) +++ cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp Sun Aug 20 09:18:43 2017 @@ -149,6 +149,8 @@ public: std::string getNodeValue(NodeId Id) const; std::string getNodeValue(const Node &Node) const; + std::string getDeclValue(const Decl *D) const; + std::string getStmtValue(const Stmt *S) const; private: /// Nodes in preorder. @@ -268,9 +270,6 @@ struct PreorderVisitor : public Recursiv }; } // end anonymous namespace -SyntaxTree::Impl::Impl(SyntaxTree *Parent, const ASTContext &AST) - : Impl(Parent, AST.getTranslationUnitDecl(), AST) {} - SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, const ASTContext &AST) : Parent(Parent), AST(AST) { NodeCountVisitor NodeCounter(*this); @@ -372,49 +371,82 @@ std::string SyntaxTree::Impl::getNodeVal std::string SyntaxTree::Impl::getNodeValue(const Node &N) const { const DynTypedNode &DTN = N.ASTNode; - if (auto *X = DTN.get<BinaryOperator>()) - return X->getOpcodeStr(); - if (auto *X = DTN.get<AccessSpecDecl>()) { - CharSourceRange Range(X->getSourceRange(), false); + if (auto *S = DTN.get<Stmt>()) + return getStmtValue(S); + if (auto *D = DTN.get<Decl>()) + return getDeclValue(D); + llvm_unreachable("Fatal: unhandled AST node.\n"); +} + +std::string SyntaxTree::Impl::getDeclValue(const Decl *D) const { + std::string Value; + PrintingPolicy TypePP(AST.getLangOpts()); + TypePP.AnonymousTagLocations = false; + + if (auto *V = dyn_cast<ValueDecl>(D)) { + Value += V->getQualifiedNameAsString() + "(" + + V->getType().getAsString(TypePP) + ")"; + if (auto *C = dyn_cast<CXXConstructorDecl>(D)) { + for (auto *Init : C->inits()) { + if (!Init->isWritten()) + continue; + if (Init->isBaseInitializer()) { + Value += Init->getBaseClass()->getCanonicalTypeInternal().getAsString( + TypePP); + } else if (Init->isDelegatingInitializer()) { + Value += C->getNameAsString(); + } else { + assert(Init->isAnyMemberInitializer()); + Value += Init->getMember()->getQualifiedNameAsString(); + } + Value += ","; + } + } + return Value; + } + if (auto *N = dyn_cast<NamedDecl>(D)) + Value += N->getQualifiedNameAsString() + ";"; + if (auto *T = dyn_cast<TypedefNameDecl>(D)) + return Value + T->getUnderlyingType().getAsString(TypePP) + ";"; + if (auto *T = dyn_cast<TypeDecl>(D)) + if (T->getTypeForDecl()) + Value += + T->getTypeForDecl()->getCanonicalTypeInternal().getAsString(TypePP) + + ";"; + if (auto *U = dyn_cast<UsingDirectiveDecl>(D)) + return U->getNominatedNamespace()->getName(); + if (auto *A = dyn_cast<AccessSpecDecl>(D)) { + CharSourceRange Range(A->getSourceRange(), false); return Lexer::getSourceText(Range, AST.getSourceManager(), AST.getLangOpts()); } - if (auto *X = DTN.get<IntegerLiteral>()) { + return Value; +} + +std::string SyntaxTree::Impl::getStmtValue(const Stmt *S) const { + if (auto *U = dyn_cast<UnaryOperator>(S)) + return UnaryOperator::getOpcodeStr(U->getOpcode()); + if (auto *B = dyn_cast<BinaryOperator>(S)) + return B->getOpcodeStr(); + if (auto *M = dyn_cast<MemberExpr>(S)) + return M->getMemberDecl()->getQualifiedNameAsString(); + if (auto *I = dyn_cast<IntegerLiteral>(S)) { SmallString<256> Str; - X->getValue().toString(Str, /*Radix=*/10, /*Signed=*/false); + I->getValue().toString(Str, /*Radix=*/10, /*Signed=*/false); return Str.str(); } - if (auto *X = DTN.get<StringLiteral>()) - return X->getString(); - if (auto *X = DTN.get<ValueDecl>()) - return X->getNameAsString() + "(" + X->getType().getAsString() + ")"; - if (DTN.get<DeclStmt>() || DTN.get<TranslationUnitDecl>()) - return ""; - std::string Value; - if (auto *X = DTN.get<DeclRefExpr>()) { - if (X->hasQualifier()) { - llvm::raw_string_ostream OS(Value); - PrintingPolicy PP(AST.getLangOpts()); - X->getQualifier()->print(OS, PP); - } - Value += X->getDecl()->getNameAsString(); - return Value; + if (auto *F = dyn_cast<FloatingLiteral>(S)) { + SmallString<256> Str; + F->getValue().toString(Str); + return Str.str(); } - if (auto *X = DTN.get<NamedDecl>()) - Value += X->getNameAsString() + ";"; - if (auto *X = DTN.get<TypedefNameDecl>()) - return Value + X->getUnderlyingType().getAsString() + ";"; - if (DTN.get<NamespaceDecl>()) - return Value; - if (auto *X = DTN.get<TypeDecl>()) - if (X->getTypeForDecl()) - Value += - X->getTypeForDecl()->getCanonicalTypeInternal().getAsString() + ";"; - if (DTN.get<Decl>()) - return Value; - if (DTN.get<Stmt>()) - return ""; - llvm_unreachable("Fatal: unhandled AST node.\n"); + if (auto *D = dyn_cast<DeclRefExpr>(S)) + return D->getDecl()->getQualifiedNameAsString(); + if (auto *String = dyn_cast<StringLiteral>(S)) + return String->getString(); + if (auto *B = dyn_cast<CXXBoolLiteralExpr>(S)) + return B->getValue() ? "true" : "false"; + return ""; } /// Identifies a node in a subtree by its postorder offset, starting at 1. @@ -637,6 +669,22 @@ ast_type_traits::ASTNodeKind Node::getTy StringRef Node::getTypeLabel() const { return getType().asStringRef(); } +llvm::Optional<std::string> Node::getQualifiedIdentifier() const { + if (auto *ND = ASTNode.get<NamedDecl>()) { + if (ND->getDeclName().isIdentifier()) + return ND->getQualifiedNameAsString(); + } + return llvm::None; +} + +llvm::Optional<StringRef> Node::getIdentifier() const { + if (auto *ND = ASTNode.get<NamedDecl>()) { + if (ND->getDeclName().isIdentifier()) + return ND->getName(); + } + return llvm::None; +} + namespace { // Compares nodes by their depth. struct HeightLess { Modified: cfe/trunk/test/Tooling/clang-diff-ast.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-ast.cpp?rev=311292&r1=311291&r2=311292&view=diff ============================================================================== --- cfe/trunk/test/Tooling/clang-diff-ast.cpp (original) +++ cfe/trunk/test/Tooling/clang-diff-ast.cpp Sun Aug 20 09:18:43 2017 @@ -5,22 +5,31 @@ // CHECK: {{^}} NamespaceDecl: test;( namespace test { -// CHECK: {{^}} FunctionDecl: f( +// CHECK: {{^}} FunctionDecl: test::f( // CHECK: CompoundStmt( void f() { // CHECK: VarDecl: i(int)( // CHECK: IntegerLiteral: 1 auto i = 1; + // CHECK: FloatingLiteral: 1.5( + auto r = 1.5; + // CHECK: CXXBoolLiteralExpr: true( + auto b = true; // CHECK: CallExpr( // CHECK-NOT: ImplicitCastExpr - // CHECK-NEXT: DeclRefExpr: f( + // CHECK: DeclRefExpr: test::f( f(); + // CHECK: UnaryOperator: ++( + ++i; // CHECK: BinaryOperator: =( i = i; } } // end namespace test +// CHECK: UsingDirectiveDecl: test( +using namespace test; + // CHECK: TypedefDecl: nat;unsigned int;( typedef unsigned nat; // CHECK: TypeAliasDecl: real;double;( @@ -29,10 +38,10 @@ using real = double; class Base { }; -// CHECK: CXXRecordDecl: X;class X;( +// CHECK: CXXRecordDecl: X;X;( class X : Base { int m; - // CHECK: CXXMethodDecl: foo(const char *(int) + // CHECK: CXXMethodDecl: X::foo(const char *(int) // CHECK: ParmVarDecl: i(int)( const char *foo(int i) { if (i == 0) @@ -44,11 +53,16 @@ class X : Base { // CHECK: AccessSpecDecl: public( public: - // CHECK: CXXConstructorDecl: X(void (char, int){{( __attribute__\(\(thiscall\)\))?}})( - X(char, int) : Base(), m(0) { - // CHECK: MemberExpr( + int not_initialized; + // All initialized members, bases and delegating initializers are are + // appended, separated by commas. + // CHECK: CXXConstructorDecl: X::X(void (char, int){{( __attribute__\(\(thiscall\)\))?}})Base,X::m,( + X(char c, int) : Base(), m(0) { + // CHECK: MemberExpr: X::m( int x = m; } + // CHECK: CXXConstructorDecl: X::X(void (char))X,( + X(char s) : X(s, 4) {} }; #define M (void)1 Modified: cfe/trunk/test/Tooling/clang-diff-basic.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-basic.cpp?rev=311292&r1=311291&r2=311292&view=diff ============================================================================== --- cfe/trunk/test/Tooling/clang-diff-basic.cpp (original) +++ cfe/trunk/test/Tooling/clang-diff-basic.cpp Sun Aug 20 09:18:43 2017 @@ -11,18 +11,18 @@ void foo() { } } -// CHECK: Match DeclRefExpr: foo{{.*}} to DeclRefExpr: inner::foo +// CHECK: Match DeclRefExpr: src::foo{{.*}} to DeclRefExpr: dst::inner::foo void main() { inner::foo(); } // CHECK: Match StringLiteral: foo{{.*}} to StringLiteral: foo const char *b = "f" "o" "o"; // unsigned is canonicalized to unsigned int -// CHECK: Match TypedefDecl: nat;unsigned int;{{.*}} to TypedefDecl: nat;unsigned int; +// CHECK: Match TypedefDecl: src::nat;unsigned int;{{.*}} to TypedefDecl: dst::nat;unsigned int; typedef unsigned nat; -// CHECK: Match VarDecl: p(int){{.*}} to VarDecl: prod(double) -// CHECK: Update VarDecl: p(int){{.*}} to prod(double) +// CHECK: Match VarDecl: src::p(int){{.*}} to VarDecl: dst::prod(double) +// CHECK: Update VarDecl: src::p(int){{.*}} to dst::prod(double) // CHECK: Match BinaryOperator: *{{.*}} to BinaryOperator: * double prod = 1 * 2 * 10; // CHECK: Update DeclRefExpr @@ -49,7 +49,7 @@ int um = 1 + 7; namespace { // match with parents of different type -// CHECK: Match FunctionDecl: f1{{.*}} to FunctionDecl: f1 +// CHECK: Match FunctionDecl: f1{{.*}} to FunctionDecl: (anonymous namespace)::f1 void f1() {{ (void) __func__;;; }} } Modified: cfe/trunk/test/Tooling/clang-diff-bottomup.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-bottomup.cpp?rev=311292&r1=311291&r2=311292&view=diff ============================================================================== --- cfe/trunk/test/Tooling/clang-diff-bottomup.cpp (original) +++ cfe/trunk/test/Tooling/clang-diff-bottomup.cpp Sun Aug 20 09:18:43 2017 @@ -16,7 +16,7 @@ void f2() { ;; {{;}} } void f1() { // CompoundStmt: 3 matched descendants, subtree sizes 4 and 5 // Jaccard similarity = 3 / (4 + 5 - 3) = 3 / 6 >= 0.5 -// CHECK: Match FunctionDecl: f1(void (void))(1) to FunctionDecl: f1(void (void))(1) +// CHECK: Match FunctionDecl: f1(void ())(1) to FunctionDecl: f1(void ())(1) // CHECK: Match CompoundStmt(2) to CompoundStmt(2) // CHECK: Match CompoundStmt(4) to CompoundStmt(3) // CHECK: Match CompoundStmt(5) to CompoundStmt(4) Modified: cfe/trunk/test/Tooling/clang-diff-html.test URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-html.test?rev=311292&r1=311291&r2=311292&view=diff ============================================================================== --- cfe/trunk/test/Tooling/clang-diff-html.test (original) +++ cfe/trunk/test/Tooling/clang-diff-html.test Sun Aug 20 09:18:43 2017 @@ -11,12 +11,12 @@ // match, move // CHECK: <span id='L[[L:[0-9]+]]' tid='R[[R:[0-9]+]]' title='FunctionDecl // CHECK-NEXT: [[L]] -> [[R]] -// CHECK-NEXT: foo(void (void))' class='m'>void foo() +// CHECK-NEXT: src::foo(void ())' class='u m'>void foo() // match // CHECK: <span id='L[[L:[0-9]+]]' tid='R[[R:[0-9]+]]' title='FunctionDecl // CHECK-NEXT: [[L]] -> [[R]] -// CHECK-NEXT: main(void (void))'>void main() +// CHECK-NEXT: src::main(void ())' class='u'>void main() // deletion // CHECK: <span id='L[[L:[0-9]+]]' tid='R-1' title='IntegerLiteral Modified: cfe/trunk/test/Tooling/clang-diff-opt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-opt.cpp?rev=311292&r1=311291&r2=311292&view=diff ============================================================================== --- cfe/trunk/test/Tooling/clang-diff-opt.cpp (original) +++ cfe/trunk/test/Tooling/clang-diff-opt.cpp Sun Aug 20 09:18:43 2017 @@ -41,4 +41,5 @@ void f3() { // CHECK: Delete NullStmt(22) ;; {{;;;;;;}} } + #endif Modified: cfe/trunk/test/Tooling/clang-diff-topdown.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-topdown.cpp?rev=311292&r1=311291&r2=311292&view=diff ============================================================================== --- cfe/trunk/test/Tooling/clang-diff-topdown.cpp (original) +++ cfe/trunk/test/Tooling/clang-diff-topdown.cpp Sun Aug 20 09:18:43 2017 @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -E %s > %t.src.cpp // RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST -// RUN: clang-diff -dump-matches -stop-after=topdown %t.src.cpp %t.dst.cpp -- | FileCheck %s +// RUN: clang-diff -dump-matches -stop-after=topdown %t.src.cpp %t.dst.cpp -- -std=c++11 | FileCheck %s // // Test the top-down matching of identical subtrees only. Modified: cfe/trunk/tools/clang-diff/ClangDiff.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-diff/ClangDiff.cpp?rev=311292&r1=311291&r2=311292&view=diff ============================================================================== --- cfe/trunk/tools/clang-diff/ClangDiff.cpp (original) +++ cfe/trunk/tools/clang-diff/ClangDiff.cpp Sun Aug 20 09:18:43 2017 @@ -316,6 +316,18 @@ static void printNodeAsJson(raw_ostream const diff::Node &N = Tree.getNode(Id); OS << "{"; printNodeAttributes(OS, Tree, Id); + auto Identifier = N.getIdentifier(); + auto QualifiedIdentifier = N.getQualifiedIdentifier(); + if (Identifier) { + OS << R"(,"identifier":")"; + printJsonString(OS, *Identifier); + OS << R"(")"; + if (QualifiedIdentifier && *Identifier != *QualifiedIdentifier) { + OS << R"(,"qualified_identifier":")"; + printJsonString(OS, *QualifiedIdentifier); + OS << R"(")"; + } + } OS << R"(,"children":[)"; if (N.Children.size() > 0) { printNodeAsJson(OS, Tree, N.Children[0]); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits