aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Tooling/Syntax
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Tooling/Syntax')
-rw-r--r--clang/lib/Tooling/Syntax/BuildTree.cpp43
-rw-r--r--clang/lib/Tooling/Syntax/Nodes.cpp28
2 files changed, 71 insertions, 0 deletions
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 11d3997..a77149d 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -881,6 +881,49 @@ public:
return true;
}
+ bool WalkUpFromMemberExpr(MemberExpr *S) {
+ if (auto QualifierLoc = S->getQualifierLoc())
+ Builder.markChild(QualifierLoc, syntax::NodeRole::IdExpression_qualifier);
+
+ auto TemplateKeywordLoc = S->getTemplateKeywordLoc();
+ if (TemplateKeywordLoc.isValid())
+ Builder.markChildToken(TemplateKeywordLoc,
+ syntax::NodeRole::TemplateKeyword);
+
+ auto *TheUnqualifiedId = new (allocator()) syntax::UnqualifiedId;
+ Builder.foldNode(Builder.getRange(S->getMemberLoc(), S->getEndLoc()),
+ TheUnqualifiedId, nullptr);
+
+ Builder.markChild(TheUnqualifiedId, syntax::NodeRole::IdExpression_id);
+
+ auto *TheIdExpression = new (allocator()) syntax::IdExpression;
+ auto MemberRange =
+ Builder.getRange(S->hasQualifier() ? S->getQualifierLoc().getBeginLoc()
+ : S->getMemberLoc(),
+ S->getEndLoc());
+
+ // For `MemberExpr` with implicit `this->` we generate a simple
+ // `id-expression` syntax node, beacuse an implicit `member-expression` is
+ // syntactically undistinguishable from an `id-expression`
+ if (S->isImplicitAccess()) {
+ Builder.foldNode(MemberRange, TheIdExpression, S);
+ return true;
+ }
+ Builder.foldNode(MemberRange, TheIdExpression, nullptr);
+
+ Builder.markChild(TheIdExpression,
+ syntax::NodeRole::MemberExpression_member);
+
+ Builder.markExprChild(S->getBase(),
+ syntax::NodeRole::MemberExpression_object);
+ Builder.markChildToken(S->getOperatorLoc(),
+ syntax::NodeRole::MemberExpression_accessToken);
+
+ Builder.foldNode(Builder.getExprRange(S),
+ new (allocator()) syntax::MemberExpression, S);
+ return true;
+ }
+
bool WalkUpFromDeclRefExpr(DeclRefExpr *S) {
if (auto QualifierLoc = S->getQualifierLoc())
Builder.markChild(QualifierLoc, syntax::NodeRole::IdExpression_qualifier);
diff --git a/clang/lib/Tooling/Syntax/Nodes.cpp b/clang/lib/Tooling/Syntax/Nodes.cpp
index bf3c310..e09c8f2 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -126,6 +126,8 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeKind K) {
return OS << "SimpleTemplateNameSpecifier";
case NodeKind::NestedNameSpecifier:
return OS << "NestedNameSpecifier";
+ case NodeKind::MemberExpression:
+ return OS << "MemberExpression";
}
llvm_unreachable("unknown node kind");
}
@@ -202,6 +204,12 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole R) {
return OS << "IdExpression_qualifier";
case syntax::NodeRole::ParenExpression_subExpression:
return OS << "ParenExpression_subExpression";
+ case syntax::NodeRole::MemberExpression_object:
+ return OS << "MemberExpression_object";
+ case syntax::NodeRole::MemberExpression_accessToken:
+ return OS << "MemberExpression_accessToken";
+ case syntax::NodeRole::MemberExpression_member:
+ return OS << "MemberExpression_member";
}
llvm_unreachable("invalid role");
}
@@ -230,6 +238,26 @@ syntax::NestedNameSpecifier::specifiersAndDoubleColons() {
return Children;
}
+syntax::Expression *syntax::MemberExpression::object() {
+ return cast_or_null<syntax::Expression>(
+ findChild(syntax::NodeRole::MemberExpression_object));
+}
+
+syntax::Leaf *syntax::MemberExpression::templateKeyword() {
+ return llvm::cast_or_null<syntax::Leaf>(
+ findChild(syntax::NodeRole::TemplateKeyword));
+}
+
+syntax::Leaf *syntax::MemberExpression::accessToken() {
+ return llvm::cast_or_null<syntax::Leaf>(
+ findChild(syntax::NodeRole::MemberExpression_accessToken));
+}
+
+syntax::IdExpression *syntax::MemberExpression::member() {
+ return cast_or_null<syntax::IdExpression>(
+ findChild(syntax::NodeRole::MemberExpression_member));
+}
+
syntax::NestedNameSpecifier *syntax::IdExpression::qualifier() {
return cast_or_null<syntax::NestedNameSpecifier>(
findChild(syntax::NodeRole::IdExpression_qualifier));