summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohannes Altmanninger <aclopte@gmail.com>2017-08-22 08:56:26 +0000
committerJohannes Altmanninger <aclopte@gmail.com>2017-08-22 08:56:26 +0000
commitc690c1e9f118a8358fc7eb097f080b5b3ab6018f (patch)
treec3fb2ed0089a20880ed8a04063b888621540773e /lib
parentc53cc0a19f751bddd7beb7438dd114d0169fb783 (diff)
downloadclang-c690c1e9f118a8358fc7eb097f080b5b3ab6018f.tar.gz
[clang-diff] Use the relative name for NamedDecl
Summary: If a node referring to a name is within a class or namespace, do not use the full qualified name, but strip the namespace prefix. Reviewers: arphaman, bkramer Subscribers: klimek Differential Revision: https://reviews.llvm.org/D36681 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@311433 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Tooling/ASTDiff/ASTDiff.cpp73
1 files changed, 57 insertions, 16 deletions
diff --git a/lib/Tooling/ASTDiff/ASTDiff.cpp b/lib/Tooling/ASTDiff/ASTDiff.cpp
index 64b853fbce..2dcd1a2856 100644
--- a/lib/Tooling/ASTDiff/ASTDiff.cpp
+++ b/lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -111,24 +111,22 @@ private:
/// Represents the AST of a TranslationUnit.
class SyntaxTree::Impl {
public:
- /// Constructs a tree from the entire translation unit.
- Impl(SyntaxTree *Parent, const ASTContext &AST);
/// Constructs a tree from an AST node.
- Impl(SyntaxTree *Parent, Decl *N, const ASTContext &AST);
- Impl(SyntaxTree *Parent, Stmt *N, const ASTContext &AST);
+ Impl(SyntaxTree *Parent, Decl *N, ASTContext &AST);
+ Impl(SyntaxTree *Parent, Stmt *N, ASTContext &AST);
template <class T>
Impl(SyntaxTree *Parent,
typename std::enable_if<std::is_base_of<Stmt, T>::value, T>::type *Node,
- const ASTContext &AST)
+ ASTContext &AST)
: Impl(Parent, dyn_cast<Stmt>(Node), AST) {}
template <class T>
Impl(SyntaxTree *Parent,
typename std::enable_if<std::is_base_of<Decl, T>::value, T>::type *Node,
- const ASTContext &AST)
+ ASTContext &AST)
: Impl(Parent, dyn_cast<Decl>(Node), AST) {}
SyntaxTree *Parent;
- const ASTContext &AST;
+ ASTContext &AST;
std::vector<NodeId> Leaves;
// Maps preorder indices to postorder ones.
std::vector<int> PostorderIds;
@@ -147,6 +145,10 @@ public:
bool isInSubtree(NodeId Id, NodeId SubtreeRoot) const;
int findPositionInParent(NodeId Id, bool Shifted = false) const;
+ std::string getRelativeName(const NamedDecl *ND,
+ const DeclContext *Context) const;
+ std::string getRelativeName(const NamedDecl *ND) const;
+
std::string getNodeValue(NodeId Id) const;
std::string getNodeValue(const Node &Node) const;
std::string getDeclValue(const Decl *D) const;
@@ -270,7 +272,7 @@ struct PreorderVisitor : public RecursiveASTVisitor<PreorderVisitor> {
};
} // end anonymous namespace
-SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, const ASTContext &AST)
+SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, ASTContext &AST)
: Parent(Parent), AST(AST) {
NodeCountVisitor NodeCounter(*this);
NodeCounter.TraverseDecl(N);
@@ -280,7 +282,7 @@ SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, const ASTContext &AST)
initTree();
}
-SyntaxTree::Impl::Impl(SyntaxTree *Parent, Stmt *N, const ASTContext &AST)
+SyntaxTree::Impl::Impl(SyntaxTree *Parent, Stmt *N, ASTContext &AST)
: Parent(Parent), AST(AST) {
NodeCountVisitor NodeCounter(*this);
NodeCounter.TraverseStmt(N);
@@ -365,6 +367,46 @@ int SyntaxTree::Impl::findPositionInParent(NodeId Id, bool Shifted) const {
llvm_unreachable("Node not found in parent's children.");
}
+// Returns the qualified name of ND. If it is subordinate to Context,
+// then the prefix of the latter is removed from the returned value.
+std::string
+SyntaxTree::Impl::getRelativeName(const NamedDecl *ND,
+ const DeclContext *Context) const {
+ std::string ContextPrefix;
+ if (auto *Namespace = dyn_cast<NamespaceDecl>(Context))
+ ContextPrefix = Namespace->getQualifiedNameAsString();
+ else if (auto *Record = dyn_cast<RecordDecl>(Context))
+ ContextPrefix = Record->getQualifiedNameAsString();
+ else if (AST.getLangOpts().CPlusPlus11)
+ if (auto *Tag = dyn_cast<TagDecl>(Context))
+ ContextPrefix = Tag->getQualifiedNameAsString();
+ std::string Val = ND->getQualifiedNameAsString();
+ // Strip the qualifier, if Val refers to somthing in the current scope.
+ // But leave one leading ':' in place, so that we know that this is a
+ // relative path.
+ if (!ContextPrefix.empty() && StringRef(Val).startswith(ContextPrefix))
+ Val = Val.substr(ContextPrefix.size() + 1);
+ return Val;
+}
+
+std::string SyntaxTree::Impl::getRelativeName(const NamedDecl *ND) const {
+ return getRelativeName(ND, ND->getDeclContext());
+}
+
+static const DeclContext *getEnclosingDeclContext(ASTContext &AST,
+ const Stmt *S) {
+ while (S) {
+ const auto &Parents = AST.getParents(*S);
+ if (Parents.empty())
+ return nullptr;
+ const auto &P = Parents[0];
+ if (const auto *D = P.get<Decl>())
+ return D->getDeclContext();
+ S = P.get<Stmt>();
+ }
+ llvm_unreachable("Could not find Decl ancestor.");
+}
+
std::string SyntaxTree::Impl::getNodeValue(NodeId Id) const {
return getNodeValue(getNode(Id));
}
@@ -384,8 +426,7 @@ std::string SyntaxTree::Impl::getDeclValue(const Decl *D) const {
TypePP.AnonymousTagLocations = false;
if (auto *V = dyn_cast<ValueDecl>(D)) {
- Value += V->getQualifiedNameAsString() + "(" +
- V->getType().getAsString(TypePP) + ")";
+ Value += getRelativeName(V) + "(" + V->getType().getAsString(TypePP) + ")";
if (auto *C = dyn_cast<CXXConstructorDecl>(D)) {
for (auto *Init : C->inits()) {
if (!Init->isWritten())
@@ -397,7 +438,7 @@ std::string SyntaxTree::Impl::getDeclValue(const Decl *D) const {
Value += C->getNameAsString();
} else {
assert(Init->isAnyMemberInitializer());
- Value += Init->getMember()->getQualifiedNameAsString();
+ Value += getRelativeName(Init->getMember());
}
Value += ",";
}
@@ -405,7 +446,7 @@ std::string SyntaxTree::Impl::getDeclValue(const Decl *D) const {
return Value;
}
if (auto *N = dyn_cast<NamedDecl>(D))
- Value += N->getQualifiedNameAsString() + ";";
+ Value += getRelativeName(N) + ";";
if (auto *T = dyn_cast<TypedefNameDecl>(D))
return Value + T->getUnderlyingType().getAsString(TypePP) + ";";
if (auto *T = dyn_cast<TypeDecl>(D))
@@ -429,7 +470,7 @@ std::string SyntaxTree::Impl::getStmtValue(const Stmt *S) const {
if (auto *B = dyn_cast<BinaryOperator>(S))
return B->getOpcodeStr();
if (auto *M = dyn_cast<MemberExpr>(S))
- return M->getMemberDecl()->getQualifiedNameAsString();
+ return getRelativeName(M->getMemberDecl());
if (auto *I = dyn_cast<IntegerLiteral>(S)) {
SmallString<256> Str;
I->getValue().toString(Str, /*Radix=*/10, /*Signed=*/false);
@@ -441,7 +482,7 @@ std::string SyntaxTree::Impl::getStmtValue(const Stmt *S) const {
return Str.str();
}
if (auto *D = dyn_cast<DeclRefExpr>(S))
- return D->getDecl()->getQualifiedNameAsString();
+ return getRelativeName(D->getDecl(), getEnclosingDeclContext(AST, S));
if (auto *String = dyn_cast<StringLiteral>(S))
return String->getString();
if (auto *B = dyn_cast<CXXBoolLiteralExpr>(S))
@@ -949,7 +990,7 @@ NodeId ASTDiff::getMapped(const SyntaxTree &SourceTree, NodeId Id) const {
return DiffImpl->getMapped(SourceTree.TreeImpl, Id);
}
-SyntaxTree::SyntaxTree(const ASTContext &AST)
+SyntaxTree::SyntaxTree(ASTContext &AST)
: TreeImpl(llvm::make_unique<SyntaxTree::Impl>(
this, AST.getTranslationUnitDecl(), AST)) {}