[clang] fdbd783 - Add parenthesized expression to SyntaxTree

2020-07-01 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-07-02T06:28:41Z
New Revision: fdbd78333fc6f1deb3037d0961130f05dce059e7

URL: 
https://github.com/llvm/llvm-project/commit/fdbd78333fc6f1deb3037d0961130f05dce059e7
DIFF: 
https://github.com/llvm/llvm-project/commit/fdbd78333fc6f1deb3037d0961130f05dce059e7.diff

LOG: Add parenthesized expression to SyntaxTree

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82960

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 9446d911c18e..97605ceb76b7 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -43,6 +43,7 @@ enum class NodeKind : uint16_t {
   PrefixUnaryOperatorExpression,
   PostfixUnaryOperatorExpression,
   BinaryOperatorExpression,
+  ParenExpression,
   IntegerLiteralExpression,
   CharacterLiteralExpression,
   FloatingLiteralExpression,
@@ -161,7 +162,8 @@ enum class NodeRole : uint8_t {
   ParametersAndQualifiers_trailingReturn,
   IdExpression_id,
   IdExpression_qualifier,
-  NestedNameSpecifier_specifier
+  NestedNameSpecifier_specifier,
+  ParenExpression_subExpression
 };
 /// For debugging purposes.
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeRole R);
@@ -248,6 +250,19 @@ class UnknownExpression final : public Expression {
   }
 };
 
+/// Models a parenthesized expression `(E)`. C++ [expr.prim.paren]
+/// e.g. `(3 + 2)` in `a = 1 + (3 + 2);`
+class ParenExpression final : public Expression {
+public:
+  ParenExpression() : Expression(NodeKind::ParenExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::ParenExpression;
+  }
+  syntax::Leaf *openParen();
+  syntax::Expression *subExpression();
+  syntax::Leaf *closeParen();
+};
+
 /// Expression for integer literals. C++ [lex.icon]
 class IntegerLiteralExpression final : public Expression {
 public:

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 6f740b3ab146..8185af2a6cc7 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -647,6 +647,16 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
+  bool WalkUpFromParenExpr(ParenExpr *S) {
+Builder.markChildToken(S->getLParen(), syntax::NodeRole::OpenParen);
+Builder.markExprChild(S->getSubExpr(),
+  syntax::NodeRole::ParenExpression_subExpression);
+Builder.markChildToken(S->getRParen(), syntax::NodeRole::CloseParen);
+Builder.foldNode(Builder.getExprRange(S),
+ new (allocator()) syntax::ParenExpression, S);
+return true;
+  }
+
   bool WalkUpFromIntegerLiteral(IntegerLiteral *S) {
 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
 Builder.foldNode(Builder.getExprRange(S),

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index 1f601fdf180b..3d9b943d6db1 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -18,6 +18,8 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, 
NodeKind K) {
 return OS << "TranslationUnit";
   case NodeKind::UnknownExpression:
 return OS << "UnknownExpression";
+  case NodeKind::ParenExpression:
+return OS << "ParenExpression";
   case NodeKind::IntegerLiteralExpression:
 return OS << "IntegerLiteralExpression";
   case NodeKind::CharacterLiteralExpression:
@@ -180,6 +182,8 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream 
&OS, NodeRole R) {
 return OS << "IdExpression_qualifier";
   case syntax::NodeRole::NestedNameSpecifier_specifier:
 return OS << "NestedNameSpecifier_specifier";
+  case syntax::NodeRole::ParenExpression_subExpression:
+return OS << "ParenExpression_subExpression";
   }
   llvm_unreachable("invalid role");
 }
@@ -203,6 +207,21 @@ syntax::UnqualifiedId 
*syntax::IdExpression::unqualifiedId() {
   findChild(syntax::NodeRole::IdExpression_id));
 }
 
+syntax::Leaf *syntax::ParenExpression::openParen() {
+  return llvm::cast_or_null(
+  findChild(syntax::NodeRole::OpenParen));
+}
+
+syntax::Expression *syntax::ParenExpression::subExpression() {
+  return llvm::cast_or_null(
+  findChild(syntax::NodeRole::ParenExpression_subExpression));
+}
+
+syntax::Leaf *syntax::ParenExpression::closeParen() {
+  return llvm::cast_or_null(
+  findChild(syntax::NodeRole::CloseParen));
+}
+
 syntax::Leaf *syntax::IntegerLiteralExpression::literalToken() {
   return llvm::cast_or_null(
   findChild(syntax::NodeRole::LiteralToken));

diff  --git a/clang/unittests/Tooling/Syntax/Tre

[clang] ea8bba7 - Fix crash on overloaded postfix unary operators due to invalid sloc

2020-07-08 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-07-08T14:09:40Z
New Revision: ea8bba7e8d0db3541a386ad649c4bf21d53e8380

URL: 
https://github.com/llvm/llvm-project/commit/ea8bba7e8d0db3541a386ad649c4bf21d53e8380
DIFF: 
https://github.com/llvm/llvm-project/commit/ea8bba7e8d0db3541a386ad649c4bf21d53e8380.diff

LOG: Fix crash on overloaded postfix unary operators due to invalid sloc

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82954

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 4371a303bb9d..361455e69f5a 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -12,6 +12,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/TypeLoc.h"
@@ -114,6 +115,85 @@ struct GetStartLoc : TypeLocVisitor {
 };
 } // namespace
 
+static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E) {
+  switch (E.getOperator()) {
+  // Comparison
+  case OO_EqualEqual:
+  case OO_ExclaimEqual:
+  case OO_Greater:
+  case OO_GreaterEqual:
+  case OO_Less:
+  case OO_LessEqual:
+  case OO_Spaceship:
+  // Assignment
+  case OO_Equal:
+  case OO_SlashEqual:
+  case OO_PercentEqual:
+  case OO_CaretEqual:
+  case OO_PipeEqual:
+  case OO_LessLessEqual:
+  case OO_GreaterGreaterEqual:
+  case OO_PlusEqual:
+  case OO_MinusEqual:
+  case OO_StarEqual:
+  case OO_AmpEqual:
+  // Binary computation
+  case OO_Slash:
+  case OO_Percent:
+  case OO_Caret:
+  case OO_Pipe:
+  case OO_LessLess:
+  case OO_GreaterGreater:
+  case OO_AmpAmp:
+  case OO_PipePipe:
+  case OO_ArrowStar:
+  case OO_Comma:
+return syntax::NodeKind::BinaryOperatorExpression;
+  case OO_Tilde:
+  case OO_Exclaim:
+return syntax::NodeKind::PrefixUnaryOperatorExpression;
+  // Prefix/Postfix increment/decrement
+  case OO_PlusPlus:
+  case OO_MinusMinus:
+switch (E.getNumArgs()) {
+case 1:
+  return syntax::NodeKind::PrefixUnaryOperatorExpression;
+case 2:
+  return syntax::NodeKind::PostfixUnaryOperatorExpression;
+default:
+  llvm_unreachable("Invalid number of arguments for operator");
+}
+  // Operators that can be unary or binary
+  case OO_Plus:
+  case OO_Minus:
+  case OO_Star:
+  case OO_Amp:
+switch (E.getNumArgs()) {
+case 1:
+  return syntax::NodeKind::PrefixUnaryOperatorExpression;
+case 2:
+  return syntax::NodeKind::BinaryOperatorExpression;
+default:
+  llvm_unreachable("Invalid number of arguments for operator");
+}
+return syntax::NodeKind::BinaryOperatorExpression;
+  // Not yet supported by SyntaxTree
+  case OO_New:
+  case OO_Delete:
+  case OO_Array_New:
+  case OO_Array_Delete:
+  case OO_Coawait:
+  case OO_Call:
+  case OO_Subscript:
+  case OO_Arrow:
+return syntax::NodeKind::UnknownExpression;
+  case OO_Conditional: // not overloadable
+  case NUM_OVERLOADED_OPERATORS:
+  case OO_None:
+llvm_unreachable("Not an overloadable operator");
+  }
+}
+
 /// Gets the range of declarator as defined by the C++ grammar. E.g.
 /// `int a;` -> range of `a`,
 /// `int *a;` -> range of `*a`,
@@ -733,8 +813,29 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
+  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
+if (getOperatorNodeKind(*S) ==
+syntax::NodeKind::PostfixUnaryOperatorExpression) {
+  // A postfix unary operator is declared as taking two operands. The 
second
+  // operand is used to distinguish from its prefix counterpart. In the
+  // semantic AST this "phantom" operand is represented as a
+  // `IntegerLiteral` with invalid `SourceLocation`. We skip visiting this
+  // operand because it does not correspond to anything written in source
+  // code
+  for (auto *child : S->children()) {
+if (child->getSourceRange().isInvalid())
+  continue;
+if (!TraverseStmt(child))
+  return false;
+  }
+  return WalkUpFromCXXOperatorCallExpr(S);
+} else
+  return RecursiveASTVisitor::TraverseCXXOperatorCallExpr(S);
+  }
+
   bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
-if (S->isInfixBinaryOp()) {
+switch (getOperatorNodeKind(*S)) {
+case syntax::NodeKind::BinaryOperatorExpression:
   Builder.markExprChild(
   S->getArg(0),
   syntax::NodeRole::BinaryOperatorExpression_leftHandSide);
@@ -747,8 +848,31 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   Builder.foldNode(Builder.getExprRange(S),
new (allocator()) syntax::BinaryOperato

[clang] 1db5b34 - Add kinded UDL for raw literal operator and numeric literal operator template

2020-07-10 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-07-10T16:21:11Z
New Revision: 1db5b348c4c93b6610afb4fd515b389989efc302

URL: 
https://github.com/llvm/llvm-project/commit/1db5b348c4c93b6610afb4fd515b389989efc302
DIFF: 
https://github.com/llvm/llvm-project/commit/1db5b348c4c93b6610afb4fd515b389989efc302.diff

LOG: Add kinded UDL for raw literal operator and  numeric literal operator 
template

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index fb63c36bc4cc..d97b127638bb 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -50,7 +50,6 @@ enum class NodeKind : uint16_t {
   StringLiteralExpression,
   BoolLiteralExpression,
   CxxNullPtrExpression,
-  UnknownUserDefinedLiteralExpression,
   IntegerUserDefinedLiteralExpression,
   FloatUserDefinedLiteralExpression,
   CharUserDefinedLiteralExpression,
@@ -340,8 +339,7 @@ class UserDefinedLiteralExpression : public Expression {
 public:
   UserDefinedLiteralExpression(NodeKind K) : Expression(K) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::UnknownUserDefinedLiteralExpression ||
-   N->kind() == NodeKind::IntegerUserDefinedLiteralExpression ||
+return N->kind() == NodeKind::IntegerUserDefinedLiteralExpression ||
N->kind() == NodeKind::FloatUserDefinedLiteralExpression ||
N->kind() == NodeKind::CharUserDefinedLiteralExpression ||
N->kind() == NodeKind::StringUserDefinedLiteralExpression;
@@ -349,21 +347,6 @@ class UserDefinedLiteralExpression : public Expression {
   syntax::Leaf *literalToken();
 };
 
-// We cannot yet distinguish between user-defined-integer-literal and
-// user-defined-floating-point-literal, when using raw literal operator or
-// numeric literal operator. C++ [lex.ext]p3, p4
-/// Expression for an unknown user-defined-literal.
-class UnknownUserDefinedLiteralExpression final
-: public UserDefinedLiteralExpression {
-public:
-  UnknownUserDefinedLiteralExpression()
-  : UserDefinedLiteralExpression(
-NodeKind::UnknownUserDefinedLiteralExpression) {}
-  static bool classof(const Node *N) {
-return N->kind() == NodeKind::UnknownUserDefinedLiteralExpression;
-  }
-};
-
 /// Expression for user-defined-integer-literal. C++ [lex.ext]
 class IntegerUserDefinedLiteralExpression final
 : public UserDefinedLiteralExpression {

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 8204d3fc66f3..5afe4965793a 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -23,6 +23,7 @@
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/Lexer.h"
+#include "clang/Lex/LiteralSupport.h"
 #include "clang/Tooling/Syntax/Nodes.h"
 #include "clang/Tooling/Syntax/Tokens.h"
 #include "clang/Tooling/Syntax/Tree.h"
@@ -552,8 +553,8 @@ class syntax::TreeBuilder {
 namespace {
 class BuildTreeVisitor : public RecursiveASTVisitor {
 public:
-  explicit BuildTreeVisitor(ASTContext &Ctx, syntax::TreeBuilder &Builder)
-  : Builder(Builder), LangOpts(Ctx.getLangOpts()) {}
+  explicit BuildTreeVisitor(ASTContext &Context, syntax::TreeBuilder &Builder)
+  : Builder(Builder), Context(Context) {}
 
   bool shouldTraversePostOrder() const { return true; }
 
@@ -718,30 +719,44 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return WalkUpFromUserDefinedLiteral(S);
   }
 
-  syntax::NodeKind getUserDefinedLiteralKind(UserDefinedLiteral *S) {
+  syntax::UserDefinedLiteralExpression *
+  buildUserDefinedLiteral(UserDefinedLiteral *S) {
 switch (S->getLiteralOperatorKind()) {
 case clang::UserDefinedLiteral::LOK_Integer:
-  return syntax::NodeKind::IntegerUserDefinedLiteralExpression;
+  return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
 case clang::UserDefinedLiteral::LOK_Floating:
-  return syntax::NodeKind::FloatUserDefinedLiteralExpression;
+  return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
 case clang::UserDefinedLiteral::LOK_Character:
-  return syntax::NodeKind::CharUserDefinedLiteralExpression;
+  return new (allocator()) syntax::CharUserDefinedLiteralExpression;
 case clang::UserDefinedLiteral::LOK_String:
-  return syntax::NodeKind::StringUserDefinedLiteralExpression;
+  return new (allocator()) syntax::StringUserDefinedLiteralExpression;
 case clang::UserDefinedLiteral::LOK_Raw:
 case clang::UserDefinedLiteral::LOK_Template:
-  // FIXME: Apply `NumericLiteralParser` to the underlying token to deduce
-  // the right UDL k

[clang] a474d5b - Use FileRange::text instead of Lexer::getSpelling

2020-07-10 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-07-10T16:21:12Z
New Revision: a474d5bae4773782d50d4a5a62300c0f4a2dff28

URL: 
https://github.com/llvm/llvm-project/commit/a474d5bae4773782d50d4a5a62300c0f4a2dff28
DIFF: 
https://github.com/llvm/llvm-project/commit/a474d5bae4773782d50d4a5a62300c0f4a2dff28.diff

LOG: Use FileRange::text instead of Lexer::getSpelling

* as we are using them only for integer and floating literals they have
the same behavior
* FileRange::text is simpler to call and is within the context of
syntax trees

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 5afe4965793a..6d13f1ace83b 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -737,20 +737,18 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   // information from the token. As integer and floating point have the 
same
   // token kind, we run `NumericLiteralParser` again to distinguish them.
   auto TokLoc = S->getBeginLoc();
-  auto buffer = SmallVector();
-  bool invalidSpelling = false;
   auto TokSpelling =
-  Lexer::getSpelling(TokLoc, buffer, Context.getSourceManager(),
- Context.getLangOpts(), &invalidSpelling);
-  assert(!invalidSpelling);
+  Builder.findToken(TokLoc)->text(Context.getSourceManager());
   auto Literal =
   NumericLiteralParser(TokSpelling, TokLoc, Context.getSourceManager(),
Context.getLangOpts(), Context.getTargetInfo(),
Context.getDiagnostics());
   if (Literal.isIntegerLiteral())
 return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
-  else
+  else {
+assert(Literal.isFloatingLiteral());
 return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
+  }
 }
   }
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] f33c2c2 - Fix crash on `user defined literals`

2020-07-10 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-07-10T16:21:11Z
New Revision: f33c2c27a8d4ea831aa7c2c2649066be91318d85

URL: 
https://github.com/llvm/llvm-project/commit/f33c2c27a8d4ea831aa7c2c2649066be91318d85
DIFF: 
https://github.com/llvm/llvm-project/commit/f33c2c27a8d4ea831aa7c2c2649066be91318d85.diff

LOG: Fix crash on `user defined literals`

Summary:
Given an UserDefinedLiteral `1.2_w`:
Problem: Lexer generates one Token for the literal, but ClangAST
references two source locations
Fix: Ignore the operator and interpret it as the underlying literal.
e.g.: `1.2_w` token generates syntax node IntegerLiteral(1.2_w)

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82157

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 97605ceb76b7..fb63c36bc4cc 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -50,6 +50,11 @@ enum class NodeKind : uint16_t {
   StringLiteralExpression,
   BoolLiteralExpression,
   CxxNullPtrExpression,
+  UnknownUserDefinedLiteralExpression,
+  IntegerUserDefinedLiteralExpression,
+  FloatUserDefinedLiteralExpression,
+  CharUserDefinedLiteralExpression,
+  StringUserDefinedLiteralExpression,
   IdExpression,
 
   // Statements.
@@ -325,6 +330,88 @@ class CxxNullPtrExpression final : public Expression {
   syntax::Leaf *nullPtrKeyword();
 };
 
+/// Expression for user-defined literal. C++ [lex.ext]
+/// user-defined-literal:
+///   user-defined-integer-literal
+///   user-defined-floating-point-literal
+///   user-defined-string-literal
+///   user-defined-character-literal
+class UserDefinedLiteralExpression : public Expression {
+public:
+  UserDefinedLiteralExpression(NodeKind K) : Expression(K) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::UnknownUserDefinedLiteralExpression ||
+   N->kind() == NodeKind::IntegerUserDefinedLiteralExpression ||
+   N->kind() == NodeKind::FloatUserDefinedLiteralExpression ||
+   N->kind() == NodeKind::CharUserDefinedLiteralExpression ||
+   N->kind() == NodeKind::StringUserDefinedLiteralExpression;
+  }
+  syntax::Leaf *literalToken();
+};
+
+// We cannot yet distinguish between user-defined-integer-literal and
+// user-defined-floating-point-literal, when using raw literal operator or
+// numeric literal operator. C++ [lex.ext]p3, p4
+/// Expression for an unknown user-defined-literal.
+class UnknownUserDefinedLiteralExpression final
+: public UserDefinedLiteralExpression {
+public:
+  UnknownUserDefinedLiteralExpression()
+  : UserDefinedLiteralExpression(
+NodeKind::UnknownUserDefinedLiteralExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::UnknownUserDefinedLiteralExpression;
+  }
+};
+
+/// Expression for user-defined-integer-literal. C++ [lex.ext]
+class IntegerUserDefinedLiteralExpression final
+: public UserDefinedLiteralExpression {
+public:
+  IntegerUserDefinedLiteralExpression()
+  : UserDefinedLiteralExpression(
+NodeKind::IntegerUserDefinedLiteralExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::IntegerUserDefinedLiteralExpression;
+  }
+};
+
+/// Expression for user-defined-floating-point-literal. C++ [lex.ext]
+class FloatUserDefinedLiteralExpression final
+: public UserDefinedLiteralExpression {
+public:
+  FloatUserDefinedLiteralExpression()
+  : UserDefinedLiteralExpression(
+NodeKind::FloatUserDefinedLiteralExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::FloatUserDefinedLiteralExpression;
+  }
+};
+
+/// Expression for user-defined-character-literal. C++ [lex.ext]
+class CharUserDefinedLiteralExpression final
+: public UserDefinedLiteralExpression {
+public:
+  CharUserDefinedLiteralExpression()
+  : UserDefinedLiteralExpression(
+NodeKind::CharUserDefinedLiteralExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::CharUserDefinedLiteralExpression;
+  }
+};
+
+/// Expression for user-defined-string-literal. C++ [lex.ext]
+class StringUserDefinedLiteralExpression final
+: public UserDefinedLiteralExpression {
+public:
+  StringUserDefinedLiteralExpression()
+  : UserDefinedLiteralExpression(
+NodeKind::StringUserDefinedLiteralExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::StringUserDefinedLiteralExpression;
+  }
+};
+
 /// An abstract class for prefix and postfix unary operators.
 class UnaryOperatorExpression : public Expression {
 pub

[clang] 7f7f856 - Add `BoolLiteralExpression` to SyntaxTree

2020-06-25 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-06-25T15:37:53Z
New Revision: 7f7f8564808b51aa62744edf75c07c0df102056a

URL: 
https://github.com/llvm/llvm-project/commit/7f7f8564808b51aa62744edf75c07c0df102056a
DIFF: 
https://github.com/llvm/llvm-project/commit/7f7f8564808b51aa62744edf75c07c0df102056a.diff

LOG: Add `BoolLiteralExpression` to SyntaxTree

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82310

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 139ac9aa8eca..255a108133bc 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -45,6 +45,7 @@ enum class NodeKind : uint16_t {
   BinaryOperatorExpression,
   CxxNullPtrExpression,
   IntegerLiteralExpression,
+  BoolLiteralExpression,
   IdExpression,
 
   // Statements.
@@ -264,6 +265,16 @@ class IntegerLiteralExpression final : public Expression {
   syntax::Leaf *literalToken();
 };
 
+/// Expression for boolean literals. C++ [lex.bool]
+class BoolLiteralExpression final : public Expression {
+public:
+  BoolLiteralExpression() : Expression(NodeKind::BoolLiteralExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::BoolLiteralExpression;
+  }
+  syntax::Leaf *literalToken();
+};
+
 /// An abstract class for prefix and postfix unary operators.
 class UnaryOperatorExpression : public Expression {
 public:

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 3ee66aabfb6d..7ff603fbd33a 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -654,6 +654,13 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
+  bool WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) {
+Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
+Builder.foldNode(Builder.getExprRange(S),
+ new (allocator()) syntax::BoolLiteralExpression, S);
+return true;
+  }
+
   bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
 Builder.foldNode(Builder.getExprRange(S),

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index 623391a7d844..498721d3a371 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -22,6 +22,8 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, 
NodeKind K) {
 return OS << "CxxNullPtrExpression";
   case NodeKind::IntegerLiteralExpression:
 return OS << "IntegerLiteralExpression";
+  case NodeKind::BoolLiteralExpression:
+return OS << "BoolLiteralExpression";
   case NodeKind::PrefixUnaryOperatorExpression:
 return OS << "PrefixUnaryOperatorExpression";
   case NodeKind::PostfixUnaryOperatorExpression:
@@ -200,6 +202,11 @@ syntax::Leaf 
*syntax::IntegerLiteralExpression::literalToken() {
   findChild(syntax::NodeRole::LiteralToken));
 }
 
+syntax::Leaf *syntax::BoolLiteralExpression::literalToken() {
+  return llvm::cast_or_null(
+  findChild(syntax::NodeRole::LiteralToken));
+}
+
 syntax::Leaf *syntax::CxxNullPtrExpression::nullPtrKeyword() {
   return llvm::cast_or_null(
   findChild(syntax::NodeRole::LiteralToken));

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 5f48ef129988..d32ce6203913 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -69,6 +69,10 @@ struct TestClangConfig {
Language == Lang_CXX20;
   }
 
+  bool hasBoolType() const {
+return Language == Lang_C89 || Language == Lang_C99;
+  }
+
   bool supportsCXXDynamicExceptionSpecification() const {
 return Language == Lang_CXX03 || Language == Lang_CXX11 ||
Language == Lang_CXX14;
@@ -1228,6 +1232,40 @@ void test() {
 )txt"));
 }
 
+TEST_P(SyntaxTreeTest, BoolLiteral) {
+  if (GetParam().hasBoolType()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+void test() {
+  true;
+  false;
+}
+)cpp",
+  R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-void
+  |-SimpleDeclarator
+  | |-test
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   `-)
+  `-CompoundStatement
+|-{
+|-ExpressionStatement
+| |-BoolLiteralExpression
+| | `-true
+| `-;
+|-ExpressionStatement
+| |-BoolLiteralExpression
+| | `-false
+| `-;
+`-}
+)txt"));
+}
+
 TEST_P(SyntaxTreeTest, IntegerLiteral) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
@@ -1691,18 +1729,18 @@ void test(int 

[clang] 221d7bb - Add `CharLiteral` to SyntaxTree

2020-06-25 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-06-25T17:05:08Z
New Revision: 221d7bbe49cceb0e408f0f46d9f8371e6c9fee2c

URL: 
https://github.com/llvm/llvm-project/commit/221d7bbe49cceb0e408f0f46d9f8371e6c9fee2c
DIFF: 
https://github.com/llvm/llvm-project/commit/221d7bbe49cceb0e408f0f46d9f8371e6c9fee2c.diff

LOG: Add `CharLiteral` to SyntaxTree

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82312

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 255a108133bc..4310bc5dc81c 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -46,6 +46,7 @@ enum class NodeKind : uint16_t {
   CxxNullPtrExpression,
   IntegerLiteralExpression,
   BoolLiteralExpression,
+  CharacterLiteralExpression,
   IdExpression,
 
   // Statements.
@@ -255,6 +256,17 @@ class CxxNullPtrExpression final : public Expression {
   syntax::Leaf *nullPtrKeyword();
 };
 
+/// Expression for character literals. C++ [lex.ccon]
+class CharacterLiteralExpression final : public Expression {
+public:
+  CharacterLiteralExpression()
+  : Expression(NodeKind::CharacterLiteralExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::CharacterLiteralExpression;
+  }
+  syntax::Leaf *literalToken();
+};
+
 /// Expression for integer literals.
 class IntegerLiteralExpression final : public Expression {
 public:

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 7ff603fbd33a..5912a54d1bee 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -661,6 +661,13 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
+  bool WalkUpFromCharacterLiteral(CharacterLiteral *S) {
+Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
+Builder.foldNode(Builder.getExprRange(S),
+ new (allocator()) syntax::CharacterLiteralExpression, S);
+return true;
+  }
+
   bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
 Builder.foldNode(Builder.getExprRange(S),

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index 498721d3a371..e6e280e9cb13 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -24,6 +24,8 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, 
NodeKind K) {
 return OS << "IntegerLiteralExpression";
   case NodeKind::BoolLiteralExpression:
 return OS << "BoolLiteralExpression";
+  case NodeKind::CharacterLiteralExpression:
+return OS << "CharacterLiteralExpression";
   case NodeKind::PrefixUnaryOperatorExpression:
 return OS << "PrefixUnaryOperatorExpression";
   case NodeKind::PostfixUnaryOperatorExpression:
@@ -207,6 +209,11 @@ syntax::Leaf 
*syntax::BoolLiteralExpression::literalToken() {
   findChild(syntax::NodeRole::LiteralToken));
 }
 
+syntax::Leaf *syntax::CharacterLiteralExpression::literalToken() {
+  return llvm::cast_or_null(
+  findChild(syntax::NodeRole::LiteralToken));
+}
+
 syntax::Leaf *syntax::CxxNullPtrExpression::nullPtrKeyword() {
   return llvm::cast_or_null(
   findChild(syntax::NodeRole::LiteralToken));

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index d32ce6203913..0a20950458d6 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -73,6 +73,10 @@ struct TestClangConfig {
 return Language == Lang_C89 || Language == Lang_C99;
   }
 
+  bool isCXX17OrLater() const {
+return Language == Lang_CXX17 || Language == Lang_CXX20;
+  }
+
   bool supportsCXXDynamicExceptionSpecification() const {
 return Language == Lang_CXX03 || Language == Lang_CXX11 ||
Language == Lang_CXX14;
@@ -1232,6 +1236,135 @@ void test() {
 )txt"));
 }
 
+TEST_P(SyntaxTreeTest, CharacterLiteral) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+void test() {
+  'a';
+  '\n';
+  '\x20';
+  '\0';
+  L'a';
+  L'α';
+}
+)cpp",
+  R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-void
+  |-SimpleDeclarator
+  | |-test
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   `-)
+  `-CompoundStatement
+|-{
+|-ExpressionStatement
+| |-CharacterLiteralExpression
+| | `-'a'
+| `-;
+|-ExpressionStatement
+| |-CharacterLiteralExpression
+| | `-'\n'
+| `-;
+|-ExpressionStatement
+| |-CharacterLiteralExpression
+| | `-'\x20'
+| `-;
+|-ExpressionS

[clang] 466e8b7 - Add StringLiteral to SyntaxTree

2020-06-25 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-06-25T17:05:08Z
New Revision: 466e8b7ea6e162d48cac42ccda210bdeb11080e3

URL: 
https://github.com/llvm/llvm-project/commit/466e8b7ea6e162d48cac42ccda210bdeb11080e3
DIFF: 
https://github.com/llvm/llvm-project/commit/466e8b7ea6e162d48cac42ccda210bdeb11080e3.diff

LOG: Add StringLiteral to SyntaxTree

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82360

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 4310bc5dc81c..e50e80ec1fc3 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -47,6 +47,7 @@ enum class NodeKind : uint16_t {
   IntegerLiteralExpression,
   BoolLiteralExpression,
   CharacterLiteralExpression,
+  StringLiteralExpression,
   IdExpression,
 
   // Statements.
@@ -287,6 +288,16 @@ class BoolLiteralExpression final : public Expression {
   syntax::Leaf *literalToken();
 };
 
+/// Expression for string-literals. C++ [lex.string]
+class StringLiteralExpression final : public Expression {
+public:
+  StringLiteralExpression() : Expression(NodeKind::StringLiteralExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::StringLiteralExpression;
+  }
+  syntax::Leaf *literalToken();
+};
+
 /// An abstract class for prefix and postfix unary operators.
 class UnaryOperatorExpression : public Expression {
 public:

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 5912a54d1bee..bd2f372e057b 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -667,6 +667,12 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
  new (allocator()) syntax::CharacterLiteralExpression, S);
 return true;
   }
+  bool WalkUpFromStringLiteral(StringLiteral *S) {
+Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);
+Builder.foldNode(Builder.getExprRange(S),
+ new (allocator()) syntax::StringLiteralExpression, S);
+return true;
+  }
 
   bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index e6e280e9cb13..290b1e6bafa1 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -26,6 +26,8 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, 
NodeKind K) {
 return OS << "BoolLiteralExpression";
   case NodeKind::CharacterLiteralExpression:
 return OS << "CharacterLiteralExpression";
+  case NodeKind::StringLiteralExpression:
+return OS << "StringLiteralExpression";
   case NodeKind::PrefixUnaryOperatorExpression:
 return OS << "PrefixUnaryOperatorExpression";
   case NodeKind::PostfixUnaryOperatorExpression:
@@ -214,6 +216,11 @@ syntax::Leaf 
*syntax::CharacterLiteralExpression::literalToken() {
   findChild(syntax::NodeRole::LiteralToken));
 }
 
+syntax::Leaf *syntax::StringLiteralExpression::literalToken() {
+  return llvm::cast_or_null(
+  findChild(syntax::NodeRole::LiteralToken));
+}
+
 syntax::Leaf *syntax::CxxNullPtrExpression::nullPtrKeyword() {
   return llvm::cast_or_null(
   findChild(syntax::NodeRole::LiteralToken));

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 0a20950458d6..bc2a65b2dd07 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -1399,6 +1399,109 @@ void test() {
 )txt"));
 }
 
+TEST_P(SyntaxTreeTest, StringLiteral) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+void test() {
+  "a\n\0\x20";
+  L"αβ";
+}
+)cpp",
+  R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-void
+  |-SimpleDeclarator
+  | |-test
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   `-)
+  `-CompoundStatement
+|-{
+|-ExpressionStatement
+| |-StringLiteralExpression
+| | `-"a\n\0\x20"
+| `-;
+|-ExpressionStatement
+| |-StringLiteralExpression
+| | `-L"αβ"
+| `-;
+`-}
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, StringLiteralUtf) {
+  if (!GetParam().isCXX11OrLater()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+void test() {
+  u8"a\x1f\x05";
+  u"C++抽象構文木";
+  U"📖🌲\n";
+}
+)cpp",
+  R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-void
+  |-SimpleDeclarator
+  | |-test
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   `-)
+  `-CompoundStatement
+|-{
+|-ExpressionStatement
+| |-StringLiteralExpression

[clang] 7b404b6 - Add `FloatingLiteral` to SyntaxTree

2020-06-25 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-06-25T17:05:08Z
New Revision: 7b404b6d003181e990f53d27866ee98d5151c4f3

URL: 
https://github.com/llvm/llvm-project/commit/7b404b6d003181e990f53d27866ee98d5151c4f3
DIFF: 
https://github.com/llvm/llvm-project/commit/7b404b6d003181e990f53d27866ee98d5151c4f3.diff

LOG: Add `FloatingLiteral` to SyntaxTree

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82318

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index e50e80ec1fc3..9446d911c18e 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -43,11 +43,12 @@ enum class NodeKind : uint16_t {
   PrefixUnaryOperatorExpression,
   PostfixUnaryOperatorExpression,
   BinaryOperatorExpression,
-  CxxNullPtrExpression,
   IntegerLiteralExpression,
-  BoolLiteralExpression,
   CharacterLiteralExpression,
+  FloatingLiteralExpression,
   StringLiteralExpression,
+  BoolLiteralExpression,
+  CxxNullPtrExpression,
   IdExpression,
 
   // Statements.
@@ -247,14 +248,14 @@ class UnknownExpression final : public Expression {
   }
 };
 
-/// C++11 'nullptr' expression.
-class CxxNullPtrExpression final : public Expression {
+/// Expression for integer literals. C++ [lex.icon]
+class IntegerLiteralExpression final : public Expression {
 public:
-  CxxNullPtrExpression() : Expression(NodeKind::CxxNullPtrExpression) {}
+  IntegerLiteralExpression() : Expression(NodeKind::IntegerLiteralExpression) 
{}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::CxxNullPtrExpression;
+return N->kind() == NodeKind::IntegerLiteralExpression;
   }
-  syntax::Leaf *nullPtrKeyword();
+  syntax::Leaf *literalToken();
 };
 
 /// Expression for character literals. C++ [lex.ccon]
@@ -268,12 +269,23 @@ class CharacterLiteralExpression final : public 
Expression {
   syntax::Leaf *literalToken();
 };
 
-/// Expression for integer literals.
-class IntegerLiteralExpression final : public Expression {
+/// Expression for floating-point literals. C++ [lex.fcon]
+class FloatingLiteralExpression final : public Expression {
 public:
-  IntegerLiteralExpression() : Expression(NodeKind::IntegerLiteralExpression) 
{}
+  FloatingLiteralExpression()
+  : Expression(NodeKind::FloatingLiteralExpression) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::IntegerLiteralExpression;
+return N->kind() == NodeKind::FloatingLiteralExpression;
+  }
+  syntax::Leaf *literalToken();
+};
+
+/// Expression for string-literals. C++ [lex.string]
+class StringLiteralExpression final : public Expression {
+public:
+  StringLiteralExpression() : Expression(NodeKind::StringLiteralExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::StringLiteralExpression;
   }
   syntax::Leaf *literalToken();
 };
@@ -288,14 +300,14 @@ class BoolLiteralExpression final : public Expression {
   syntax::Leaf *literalToken();
 };
 
-/// Expression for string-literals. C++ [lex.string]
-class StringLiteralExpression final : public Expression {
+/// Expression for the `nullptr` literal. C++ [lex.nullptr]
+class CxxNullPtrExpression final : public Expression {
 public:
-  StringLiteralExpression() : Expression(NodeKind::StringLiteralExpression) {}
+  CxxNullPtrExpression() : Expression(NodeKind::CxxNullPtrExpression) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::StringLiteralExpression;
+return N->kind() == NodeKind::CxxNullPtrExpression;
   }
-  syntax::Leaf *literalToken();
+  syntax::Leaf *nullPtrKeyword();
 };
 
 /// An abstract class for prefix and postfix unary operators.

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index bd2f372e057b..6f740b3ab146 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -654,19 +654,20 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
-  bool WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) {
+  bool WalkUpFromCharacterLiteral(CharacterLiteral *S) {
 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
 Builder.foldNode(Builder.getExprRange(S),
- new (allocator()) syntax::BoolLiteralExpression, S);
+ new (allocator()) syntax::CharacterLiteralExpression, S);
 return true;
   }
 
-  bool WalkUpFromCharacterLiteral(CharacterLiteral *S) {
+  bool WalkUpFromFloatingLiteral(FloatingLiteral *S) {
 Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken);
 Builder.foldNode(Builder.getExprR

[clang] 860cbbd - [SyntaxTree] Add support for `LiteralExpression`

2020-08-04 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-04T14:05:09Z
New Revision: 860cbbdd6b84017e6d37e1752b0358a05da6b115

URL: 
https://github.com/llvm/llvm-project/commit/860cbbdd6b84017e6d37e1752b0358a05da6b115
DIFF: 
https://github.com/llvm/llvm-project/commit/860cbbdd6b84017e6d37e1752b0358a05da6b115.diff

LOG: [SyntaxTree] Add support for `LiteralExpression`

We use inheritance to model the grammar's disjunction rule:
literal:
  integer-literal
  character-literal
  floating-point-literal
  string-literal
  boolean-literal
  pointer-literal
  user-defined-literal

Differential Revision: https://reviews.llvm.org/D85186

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/Nodes.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index d97b127638bb..8a873f9d5273 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -267,66 +267,82 @@ class ParenExpression final : public Expression {
   syntax::Leaf *closeParen();
 };
 
+/// Expression for literals. C++ [lex.literal]
+class LiteralExpression : public Expression {
+public:
+  LiteralExpression(NodeKind K) : Expression(K) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::IntegerLiteralExpression ||
+   N->kind() == NodeKind::CharacterLiteralExpression ||
+   N->kind() == NodeKind::FloatingLiteralExpression ||
+   N->kind() == NodeKind::StringLiteralExpression ||
+   N->kind() == NodeKind::BoolLiteralExpression ||
+   N->kind() == NodeKind::CxxNullPtrExpression ||
+   N->kind() == NodeKind::IntegerUserDefinedLiteralExpression ||
+   N->kind() == NodeKind::FloatUserDefinedLiteralExpression ||
+   N->kind() == NodeKind::CharUserDefinedLiteralExpression ||
+   N->kind() == NodeKind::StringUserDefinedLiteralExpression;
+  }
+  syntax::Leaf *literalToken();
+};
+
 /// Expression for integer literals. C++ [lex.icon]
-class IntegerLiteralExpression final : public Expression {
+class IntegerLiteralExpression final : public LiteralExpression {
 public:
-  IntegerLiteralExpression() : Expression(NodeKind::IntegerLiteralExpression) 
{}
+  IntegerLiteralExpression()
+  : LiteralExpression(NodeKind::IntegerLiteralExpression) {}
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::IntegerLiteralExpression;
   }
-  syntax::Leaf *literalToken();
 };
 
 /// Expression for character literals. C++ [lex.ccon]
-class CharacterLiteralExpression final : public Expression {
+class CharacterLiteralExpression final : public LiteralExpression {
 public:
   CharacterLiteralExpression()
-  : Expression(NodeKind::CharacterLiteralExpression) {}
+  : LiteralExpression(NodeKind::CharacterLiteralExpression) {}
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::CharacterLiteralExpression;
   }
-  syntax::Leaf *literalToken();
 };
 
 /// Expression for floating-point literals. C++ [lex.fcon]
-class FloatingLiteralExpression final : public Expression {
+class FloatingLiteralExpression final : public LiteralExpression {
 public:
   FloatingLiteralExpression()
-  : Expression(NodeKind::FloatingLiteralExpression) {}
+  : LiteralExpression(NodeKind::FloatingLiteralExpression) {}
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::FloatingLiteralExpression;
   }
-  syntax::Leaf *literalToken();
 };
 
 /// Expression for string-literals. C++ [lex.string]
-class StringLiteralExpression final : public Expression {
+class StringLiteralExpression final : public LiteralExpression {
 public:
-  StringLiteralExpression() : Expression(NodeKind::StringLiteralExpression) {}
+  StringLiteralExpression()
+  : LiteralExpression(NodeKind::StringLiteralExpression) {}
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::StringLiteralExpression;
   }
-  syntax::Leaf *literalToken();
 };
 
 /// Expression for boolean literals. C++ [lex.bool]
-class BoolLiteralExpression final : public Expression {
+class BoolLiteralExpression final : public LiteralExpression {
 public:
-  BoolLiteralExpression() : Expression(NodeKind::BoolLiteralExpression) {}
+  BoolLiteralExpression()
+  : LiteralExpression(NodeKind::BoolLiteralExpression) {}
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::BoolLiteralExpression;
   }
-  syntax::Leaf *literalToken();
 };
 
 /// Expression for the `nullptr` literal. C++ [lex.nullptr]
-class CxxNullPtrExpression final : public Expression {
+class CxxNullPtrExpression final : public LiteralExpression {
 public:
-  CxxNullPtrExpression() : Expression(NodeKind::CxxNullPtrExpression) {}
+  CxxNullPtrExpression() : LiteralExpression(NodeKind::CxxNullPtrExpression) {}
   static bool classof(const Node *N) {
 return N->kind() =

[clang] 8ce15f7 - [SyntaxTree] Fix crash on pointer to member function

2020-08-04 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-04T14:31:12Z
New Revision: 8ce15f7eeb122c0bba4b676d797217359dd57c30

URL: 
https://github.com/llvm/llvm-project/commit/8ce15f7eeb122c0bba4b676d797217359dd57c30
DIFF: 
https://github.com/llvm/llvm-project/commit/8ce15f7eeb122c0bba4b676d797217359dd57c30.diff

LOG: [SyntaxTree] Fix crash on pointer to member function

Differential Revision: https://reviews.llvm.org/D85146

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 1f192180ec45..15b7c8fab198 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -939,6 +939,8 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
+  // FIXME: Deleting the `TraverseParenTypeLoc` override doesn't change test
+  // results. Find test coverage or remove it.
   bool TraverseParenTypeLoc(ParenTypeLoc L) {
 // We reverse order of traversal to get the proper syntax structure.
 if (!WalkUpFromParenTypeLoc(L))
@@ -987,6 +989,16 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return WalkUpFromFunctionTypeLoc(L);
   }
 
+  bool TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L) {
+// In the source code "void (Y::*mp)()" `MemberPointerTypeLoc` corresponds
+// to "Y::*" but it points to a `ParenTypeLoc` that corresponds to
+// "(Y::*mp)" We thus reverse the order of traversal to get the proper
+// syntax structure.
+if (!WalkUpFromMemberPointerTypeLoc(L))
+  return false;
+return TraverseTypeLoc(L.getPointeeLoc());
+  }
+
   bool WalkUpFromMemberPointerTypeLoc(MemberPointerTypeLoc L) {
 auto SR = L.getLocalSourceRange();
 Builder.foldNode(Builder.getRange(SR),

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index a722ca2b1a45..3ccfabb95da9 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -4074,6 +4074,99 @@ const int X::* b;
 )txt"));
 }
 
+TEST_P(SyntaxTreeTest, MemberFunctionPointer) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+struct X {
+  struct Y {};
+};
+void (X::*xp)();
+void (X::**xpp)(const int*);
+// FIXME: Generate the right syntax tree for this type,
+// i.e. create a syntax node for the outer member pointer
+void (X::Y::*xyp)(const int*, char);
+)cpp",
+  R"txt(
+*: TranslationUnit
+|-SimpleDeclaration
+| |-struct
+| |-X
+| |-{
+| |-SimpleDeclaration
+| | |-struct
+| | |-Y
+| | |-{
+| | |-}
+| | `-;
+| |-}
+| `-;
+|-SimpleDeclaration
+| |-void
+| |-SimpleDeclarator
+| | |-ParenDeclarator
+| | | |-(
+| | | |-MemberPointer
+| | | | |-X
+| | | | |-::
+| | | | `-*
+| | | |-xp
+| | | `-)
+| | `-ParametersAndQualifiers
+| |   |-(
+| |   `-)
+| `-;
+|-SimpleDeclaration
+| |-void
+| |-SimpleDeclarator
+| | |-ParenDeclarator
+| | | |-(
+| | | |-MemberPointer
+| | | | |-X
+| | | | |-::
+| | | | `-*
+| | | |-*
+| | | |-xpp
+| | | `-)
+| | `-ParametersAndQualifiers
+| |   |-(
+| |   |-SimpleDeclaration
+| |   | |-const
+| |   | |-int
+| |   | `-SimpleDeclarator
+| |   |   `-*
+| |   `-)
+| `-;
+`-SimpleDeclaration
+  |-void
+  |-SimpleDeclarator
+  | |-ParenDeclarator
+  | | |-(
+  | | |-X
+  | | |-::
+  | | |-MemberPointer
+  | | | |-Y
+  | | | |-::
+  | | | `-*
+  | | |-xyp
+  | | `-)
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   |-SimpleDeclaration
+  |   | |-const
+  |   | |-int
+  |   | `-SimpleDeclarator
+  |   |   `-*
+  |   |-,
+  |   |-SimpleDeclaration
+  |   | `-char
+  |   `-)
+  `-;
+)txt"));
+}
+
 TEST_P(SyntaxTreeTest, ComplexDeclarator) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] c5cdc3e - [SyntaxTree] Add test coverage for `->*` operator

2020-08-05 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-05T07:36:39Z
New Revision: c5cdc3e801ad1b0aceaf220d78a3ff3fab1e0fdb

URL: 
https://github.com/llvm/llvm-project/commit/c5cdc3e801ad1b0aceaf220d78a3ff3fab1e0fdb
DIFF: 
https://github.com/llvm/llvm-project/commit/c5cdc3e801ad1b0aceaf220d78a3ff3fab1e0fdb.diff

LOG: [SyntaxTree] Add test coverage for `->*` operator

This was the last binary operator that we supported but didn't have any
test coverage. The recent fix in a crash in member pointers allowed us
to add this test.

Differential Revision: https://reviews.llvm.org/D85185

Added: 


Modified: 
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 3ccfabb95da9..e696be3dae7c 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -2329,16 +2329,17 @@ struct X {
   friend bool operator<(const X&, const X&);
   friend X operator<<(X&, const X&);
   X operator,(X&);
-  // TODO: Fix crash on member function pointer and add a test for `->*`
-  // TODO: Unbox operators in syntax tree. 
+  X operator->*(int);
+  // TODO: Unbox operators in syntax tree.
   // Represent operators by `+` instead of `IdExpression-UnqualifiedId-+`
 };
-void test(X x, X y) {
+void test(X x, X y, X* xp, int X::* pmi) {
   x = y;
   x + y;
   x < y;
   x << y;
   x, y;
+  xp->*pmi;
 }
 )cpp",
   R"txt(
@@ -2437,6 +2438,17 @@ void test(X x, X y) {
 | | |   |   `-&
 | | |   `-)
 | | `-;
+| |-SimpleDeclaration
+| | |-X
+| | |-SimpleDeclarator
+| | | |-operator
+| | | |-->*
+| | | `-ParametersAndQualifiers
+| | |   |-(
+| | |   |-SimpleDeclaration
+| | |   | `-int
+| | |   `-)
+| | `-;
 | |-}
 | `-;
 `-SimpleDeclaration
@@ -2454,6 +2466,21 @@ void test(X x, X y) {
   |   | |-X
   |   | `-SimpleDeclarator
   |   |   `-y
+  |   |-,
+  |   |-SimpleDeclaration
+  |   | |-X
+  |   | `-SimpleDeclarator
+  |   |   |-*
+  |   |   `-xp
+  |   |-,
+  |   |-SimpleDeclaration
+  |   | |-int
+  |   | `-SimpleDeclarator
+  |   |   |-MemberPointer
+  |   |   | |-X
+  |   |   | |-::
+  |   |   | `-*
+  |   |   `-pmi
   |   `-)
   `-CompoundStatement
 |-{
@@ -2518,6 +2545,16 @@ void test(X x, X y) {
 | |   `-UnqualifiedId
 | | `-y
 | `-;
+|-ExpressionStatement
+| |-BinaryOperatorExpression
+| | |-IdExpression
+| | | `-UnqualifiedId
+| | |   `-xp
+| | |-->*
+| | `-IdExpression
+| |   `-UnqualifiedId
+| | `-pmi
+| `-;
 `-}
 )txt"));
 }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] ba41a0f - [SyntaxTree][NFC] remove redundant namespace-specifiers

2020-08-07 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-07T08:45:29Z
New Revision: ba41a0f7339c8cbd065f032cc5f8c1d87a74e124

URL: 
https://github.com/llvm/llvm-project/commit/ba41a0f7339c8cbd065f032cc5f8c1d87a74e124
DIFF: 
https://github.com/llvm/llvm-project/commit/ba41a0f7339c8cbd065f032cc5f8c1d87a74e124.diff

LOG: [SyntaxTree][NFC] remove redundant namespace-specifiers

Differential Revision: https://reviews.llvm.org/D85427

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/include/clang/Tooling/Syntax/Tree.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/lib/Tooling/Syntax/Tree.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 8a873f9d5273..a5972a394583 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -100,7 +100,7 @@ enum class NodeKind : uint16_t {
   UnqualifiedId
 };
 /// For debugging purposes.
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeKind K);
+raw_ostream &operator<<(raw_ostream &OS, NodeKind K);
 
 /// A relation between a parent and child node, e.g. 'left-hand-side of
 /// a binary expression'. Used for implementing accessors.
@@ -170,7 +170,7 @@ enum class NodeRole : uint8_t {
   ParenExpression_subExpression
 };
 /// For debugging purposes.
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeRole R);
+raw_ostream &operator<<(raw_ostream &OS, NodeRole R);
 
 class SimpleDeclarator;
 
@@ -212,7 +212,7 @@ class NestedNameSpecifier final : public Tree {
   static bool classof(const Node *N) {
 return N->kind() <= NodeKind::NestedNameSpecifier;
   }
-  std::vector specifiers();
+  std::vector specifiers();
 };
 
 /// Models an `unqualified-id`. C++ [expr.prim.id.unqual]
@@ -238,10 +238,10 @@ class IdExpression final : public Expression {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::IdExpression;
   }
-  syntax::NestedNameSpecifier *qualifier();
+  NestedNameSpecifier *qualifier();
   // TODO after expose `id-expression` from `DependentScopeDeclRefExpr`:
   // Add accessor for `template_opt`.
-  syntax::UnqualifiedId *unqualifiedId();
+  UnqualifiedId *unqualifiedId();
 };
 
 /// An expression of an unknown kind, i.e. one not currently handled by the
@@ -262,9 +262,9 @@ class ParenExpression final : public Expression {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::ParenExpression;
   }
-  syntax::Leaf *openParen();
-  syntax::Expression *subExpression();
-  syntax::Leaf *closeParen();
+  Leaf *openParen();
+  Expression *subExpression();
+  Leaf *closeParen();
 };
 
 /// Expression for literals. C++ [lex.literal]
@@ -283,7 +283,7 @@ class LiteralExpression : public Expression {
N->kind() == NodeKind::CharUserDefinedLiteralExpression ||
N->kind() == NodeKind::StringUserDefinedLiteralExpression;
   }
-  syntax::Leaf *literalToken();
+  Leaf *literalToken();
 };
 
 /// Expression for integer literals. C++ [lex.icon]
@@ -418,8 +418,8 @@ class UnaryOperatorExpression : public Expression {
 return N->kind() == NodeKind::PrefixUnaryOperatorExpression ||
N->kind() == NodeKind::PostfixUnaryOperatorExpression;
   }
-  syntax::Leaf *operatorToken();
-  syntax::Expression *operand();
+  Leaf *operatorToken();
+  Expression *operand();
 };
 
 ///  
@@ -467,9 +467,9 @@ class BinaryOperatorExpression final : public Expression {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::BinaryOperatorExpression;
   }
-  syntax::Expression *lhs();
-  syntax::Leaf *operatorToken();
-  syntax::Expression *rhs();
+  Expression *lhs();
+  Leaf *operatorToken();
+  Expression *rhs();
 };
 
 /// An abstract node for C++ statements, e.g. 'while', 'if', etc.
@@ -518,8 +518,8 @@ class SwitchStatement final : public Statement {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::SwitchStatement;
   }
-  syntax::Leaf *switchKeyword();
-  syntax::Statement *body();
+  Leaf *switchKeyword();
+  Statement *body();
 };
 
 /// case : 
@@ -529,9 +529,9 @@ class CaseStatement final : public Statement {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::CaseStatement;
   }
-  syntax::Leaf *caseKeyword();
-  syntax::Expression *value();
-  syntax::Statement *body();
+  Leaf *caseKeyword();
+  Expression *value();
+  Statement *body();
 };
 
 /// default: 
@@ -541,8 +541,8 @@ class DefaultStatement final : public Statement {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::DefaultStatement;
   }
-  syntax::Leaf *defaultKeyword();
-  syntax::Statement *body();
+  Leaf *defaultKeyword();
+  Statement *body();
 };
 
 /// if (cond)  else 
@@ -553,10 +553,10 @@ class IfStatement final : public Statement {
  

[clang] 8abb5fb - [SyntaxTree] Use simplified grammar rule for `NestedNameSpecifier` grammar nodes

2020-08-07 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-07T18:05:47Z
New Revision: 8abb5fb68f81b0e42d824bf080b1cef9a61559d6

URL: 
https://github.com/llvm/llvm-project/commit/8abb5fb68f81b0e42d824bf080b1cef9a61559d6
DIFF: 
https://github.com/llvm/llvm-project/commit/8abb5fb68f81b0e42d824bf080b1cef9a61559d6.diff

LOG: [SyntaxTree] Use simplified grammar rule for `NestedNameSpecifier` grammar 
nodes

This is our grammar rule for nested-name-specifiers:
globalbal-specifier:
  /*empty*/
simple-template-specifier:
  template_opt simple-template-id
name-specifier:
  global-specifier
  decltype-specifier
  identifier
  simple-template-specifier
nested-name-specifier:
  list(name-specifier, ::, non-empty, terminated)

It is a relaxed version of C++ [expr.prim.id] and quite simpler to map to our 
API.

TODO: refine name specifiers, `simple-template-name-specifier` and
decltype-name-specifier` are token soup for now.

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index a5972a394583..2273cb70307a 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -95,9 +95,13 @@ enum class NodeKind : uint16_t {
   TrailingReturnType,
   ParametersAndQualifiers,
   MemberPointer,
+  UnqualifiedId,
+  // Nested Name Specifiers.
   NestedNameSpecifier,
-  NameSpecifier,
-  UnqualifiedId
+  GlobalNameSpecifier,
+  DecltypeNameSpecifier,
+  IdentifierNameSpecifier,
+  SimpleTemplateNameSpecifier
 };
 /// For debugging purposes.
 raw_ostream &operator<<(raw_ostream &OS, NodeKind K);
@@ -138,6 +142,7 @@ enum class NodeRole : uint8_t {
   /// Tokens or Keywords
   ArrowToken,
   ExternKeyword,
+  TemplateKeyword,
   /// An inner statement for those that have only a single child of kind
   /// statement, e.g. loop body for while, for, etc; inner statement for case,
   /// default, etc.
@@ -167,6 +172,7 @@ enum class NodeRole : uint8_t {
   IdExpression_id,
   IdExpression_qualifier,
   NestedNameSpecifier_specifier,
+  NestedNameSpecifier_delimiter,
   ParenExpression_subExpression
 };
 /// For debugging purposes.
@@ -195,12 +201,60 @@ class Expression : public Tree {
 };
 
 /// A sequence of these specifiers make a `nested-name-specifier`.
-/// e.g. the `std::` or `vector::` in `std::vector::size`.
-class NameSpecifier final : public Tree {
+/// e.g. the `std` or `vector` in `std::vector::size`.
+class NameSpecifier : public Tree {
 public:
-  NameSpecifier() : Tree(NodeKind::NameSpecifier) {}
+  NameSpecifier(NodeKind K) : Tree(K) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::NameSpecifier;
+return N->kind() == NodeKind::GlobalNameSpecifier ||
+   N->kind() == NodeKind::DecltypeNameSpecifier ||
+   N->kind() == NodeKind::IdentifierNameSpecifier ||
+   N->kind() == NodeKind::SimpleTemplateNameSpecifier;
+  }
+};
+
+/// The global namespace name specifier, this specifier doesn't correspond to a
+/// token instead an absence of tokens before a `::` characterizes it, in
+/// `::std::vector` it would be characterized by the absence of a token
+/// before the first `::`
+class GlobalNameSpecifier final : public NameSpecifier {
+public:
+  GlobalNameSpecifier() : NameSpecifier(NodeKind::GlobalNameSpecifier) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::GlobalNameSpecifier;
+  }
+};
+
+/// A name specifier holding a decltype, of the form: `decltype ( expression ) 
`
+/// e.g. the `decltype(s)` in `decltype(s)::size`.
+class DecltypeNameSpecifier final : public NameSpecifier {
+public:
+  DecltypeNameSpecifier() : NameSpecifier(NodeKind::DecltypeNameSpecifier) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::DecltypeNameSpecifier;
+  }
+};
+
+/// A identifier name specifier, of the form `identifier`
+/// e.g. the `std` in `std::vector::size`.
+class IdentifierNameSpecifier final : public NameSpecifier {
+public:
+  IdentifierNameSpecifier()
+  : NameSpecifier(NodeKind::IdentifierNameSpecifier) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::IdentifierNameSpecifier;
+  }
+};
+
+/// A name specifier with a simple-template-id, of the form `template_opt
+/// identifier < template-args >` e.g. the `vector` in
+/// `std::vector::size`.
+class SimpleTemplateNameSpecifier final : public NameSpecifier {
+public:
+  SimpleTemplateNameSpecifier()
+  : NameSpecifier(NodeKind::SimpleTemplateNameSpecifier) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::SimpleTemplateNameSpecifier;
   }
 };
 
@@ -213,6 +267,7 @@ class NestedNameSpecifier final : public Tree {
 return N->kind() <= Node

[clang] a90c78a - [SyntaxTree] Implement the List construct.

2020-08-10 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-10T10:32:28Z
New Revision: a90c78ac52615d256142ecd64fbedabb612dc73f

URL: 
https://github.com/llvm/llvm-project/commit/a90c78ac52615d256142ecd64fbedabb612dc73f
DIFF: 
https://github.com/llvm/llvm-project/commit/a90c78ac52615d256142ecd64fbedabb612dc73f.diff

LOG: [SyntaxTree] Implement the List construct.

We defined a List construct to help with the implementation of list-like
grammar rules. This is a first implementation of this API.

Differential Revision: https://reviews.llvm.org/D85295

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/include/clang/Tooling/Syntax/Tree.h
clang/lib/Tooling/Syntax/Nodes.cpp
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 2273cb70307a..fc44076621d6 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -147,6 +147,8 @@ enum class NodeRole : uint8_t {
   /// statement, e.g. loop body for while, for, etc; inner statement for case,
   /// default, etc.
   BodyStatement,
+  List_element,
+  List_delimiter,
 
   // Roles specific to particular node kinds.
   OperatorExpression_operatorToken,

diff  --git a/clang/include/clang/Tooling/Syntax/Tree.h 
b/clang/include/clang/Tooling/Syntax/Tree.h
index d35bc6467bcc..fcd169cad3ec 100644
--- a/clang/include/clang/Tooling/Syntax/Tree.h
+++ b/clang/include/clang/Tooling/Syntax/Tree.h
@@ -191,6 +191,59 @@ class Tree : public Node {
   Node *FirstChild = nullptr;
 };
 
+/// A list of Elements separated or terminated by a fixed token.
+///
+/// This type models the following grammar construct:
+/// delimited-list(element, delimiter, termination, canBeEmpty)
+class List : public Tree {
+public:
+  template  struct ElementAndDelimiter {
+Element *element;
+Leaf *delimiter;
+  };
+
+  enum class TerminationKind {
+Terminated,
+MaybeTerminated,
+Separated,
+  };
+
+  using Tree::Tree;
+  /// Returns the elements and corresponding delimiters. Missing elements
+  /// and delimiters are represented as null pointers.
+  ///
+  /// For example, in a separated list:
+  /// "a, b, c" <=> [("a", ","), ("b", ","), ("c", null)]
+  /// "a, , c" <=> [("a", ","), (null, ","), ("c", ",)]
+  /// "a, b," <=> [("a", ","), ("b", ","), (null, null)]
+  ///
+  /// In a terminated or maybe-terminated list:
+  /// "a, b," <=> [("a", ","), ("b", ",")]
+  std::vector> getElementsAsNodesAndDelimiters();
+
+  /// Returns the elements of the list. Missing elements are represented
+  /// as null pointers in the same way as in the return value of
+  /// `getElementsAsNodesAndDelimiters()`.
+  std::vector getElementsAsNodes();
+
+  // These can't be implemented with the information we have!
+
+  /// Returns the appropriate delimiter for this list.
+  ///
+  /// Useful for discovering the correct delimiter to use when adding
+  /// elements to empty or one-element lists.
+  clang::tok::TokenKind getDelimiterTokenKind();
+
+  TerminationKind getTerminationKind();
+
+  /// Whether this list can be empty in syntactically and semantically correct
+  /// code.
+  ///
+  /// This list may be empty when the source code has errors even if
+  /// canBeEmpty() returns false.
+  bool canBeEmpty();
+};
+
 } // namespace syntax
 } // namespace clang
 

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index b5a4c50b2875..5e8deb668352 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -152,6 +152,10 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole 
R) {
 return OS << "TemplateKeyword";
   case syntax::NodeRole::BodyStatement:
 return OS << "BodyStatement";
+  case syntax::NodeRole::List_element:
+return OS << "List_element";
+  case syntax::NodeRole::List_delimiter:
+return OS << "List_delimiter";
   case syntax::NodeRole::CaseStatement_value:
 return OS << "CaseStatement_value";
   case syntax::NodeRole::IfStatement_thenStatement:

diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index 6f9ee40a89f2..6070d1603eb8 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -268,3 +268,110 @@ syntax::Node *syntax::Tree::findChild(NodeRole R) {
   }
   return nullptr;
 }
+
+std::vector>
+syntax::List::getElementsAsNodesAndDelimiters() {
+  if (!firstChild())
+return {};
+
+  auto children = std::vector>();
+  syntax::Node *elementWithoutDelimiter = nullptr;
+  for (auto *C = firstChild(); C; C = C->nextSibling()) {
+switch (C->role()) {
+case syntax::NodeRole::List_element: {
+  if (elementWithoutDelimiter) {
+children.push_back({elementWithoutDelimiter, nullptr});
+  }
+  elementWithoutDelimiter = C;
+  break;
+}
+case syntax::NodeRol

[clang] fdbd599 - [SyntaxTree] Implement `NestedNameSpecifier` using the `List` base API

2020-08-10 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-10T13:43:21Z
New Revision: fdbd5996533dad25f00687f27ce8e7a8b7573ba3

URL: 
https://github.com/llvm/llvm-project/commit/fdbd5996533dad25f00687f27ce8e7a8b7573ba3
DIFF: 
https://github.com/llvm/llvm-project/commit/fdbd5996533dad25f00687f27ce8e7a8b7573ba3.diff

LOG: [SyntaxTree] Implement `NestedNameSpecifier` using the `List` base API

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index fc44076621d6..8e65fa1d8923 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -173,8 +173,6 @@ enum class NodeRole : uint8_t {
   ParametersAndQualifiers_trailingReturn,
   IdExpression_id,
   IdExpression_qualifier,
-  NestedNameSpecifier_specifier,
-  NestedNameSpecifier_delimiter,
   ParenExpression_subExpression
 };
 /// For debugging purposes.
@@ -262,14 +260,15 @@ class SimpleTemplateNameSpecifier final : public 
NameSpecifier {
 
 /// Models a `nested-name-specifier`. C++ [expr.prim.id.qual]
 /// e.g. the `std::vector::` in `std::vector::size`.
-class NestedNameSpecifier final : public Tree {
+class NestedNameSpecifier final : public List {
 public:
-  NestedNameSpecifier() : Tree(NodeKind::NestedNameSpecifier) {}
+  NestedNameSpecifier() : List(NodeKind::NestedNameSpecifier) {}
   static bool classof(const Node *N) {
 return N->kind() <= NodeKind::NestedNameSpecifier;
   }
   std::vector specifiers();
-  std::vector delimiters();
+  std::vector>
+  specifiersAndDoubleColons();
 };
 
 /// Models an `unqualified-id`. C++ [expr.prim.id.unqual]

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 4e76b3825b6f..76b86ac6424d 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -809,9 +809,8 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   if (!isa(NS))
 Builder.foldNode(Builder.getRange(getLocalSourceRange(it)).drop_back(),
  NS, it);
-  Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier);
-  Builder.markChildToken(it.getEndLoc(),
- syntax::NodeRole::NestedNameSpecifier_delimiter);
+  Builder.markChild(NS, syntax::NodeRole::List_element);
+  Builder.markChildToken(it.getEndLoc(), syntax::NodeRole::List_delimiter);
 }
 auto *NNS = new (allocator()) syntax::NestedNameSpecifier;
 Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS,

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index 5e8deb668352..bf3c3108cb69 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -200,30 +200,32 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole 
R) {
 return OS << "IdExpression_id";
   case syntax::NodeRole::IdExpression_qualifier:
 return OS << "IdExpression_qualifier";
-  case syntax::NodeRole::NestedNameSpecifier_specifier:
-return OS << "NestedNameSpecifier_specifier";
-  case syntax::NodeRole::NestedNameSpecifier_delimiter:
-return OS << "NestedNameSpecifier_delimiter";
   case syntax::NodeRole::ParenExpression_subExpression:
 return OS << "ParenExpression_subExpression";
   }
   llvm_unreachable("invalid role");
 }
 
-std::vector syntax::NestedNameSpecifier::delimiters() {
-  std::vector Children;
-  for (auto *C = firstChild(); C; C = C->nextSibling()) {
-assert(C->role() == syntax::NodeRole::NestedNameSpecifier_delimiter);
-Children.push_back(llvm::cast(C));
+// We could have an interator in list to not pay memory costs of temporary
+// vector
+std::vector syntax::NestedNameSpecifier::specifiers() 
{
+  auto specifiersAsNodes = getElementsAsNodes();
+  std::vector Children;
+  for (const auto &element : specifiersAsNodes) {
+Children.push_back(llvm::cast(element));
   }
   return Children;
 }
 
-std::vector syntax::NestedNameSpecifier::specifiers() 
{
-  std::vector Children;
-  for (auto *C = firstChild(); C; C = C->nextSibling()) {
-assert(C->role() == syntax::NodeRole::NestedNameSpecifier_specifier);
-Children.push_back(cast(C));
+std::vector>
+syntax::NestedNameSpecifier::specifiersAndDoubleColons() {
+  auto specifiersAsNodesAndDoubleColons = getElementsAsNodesAndDelimiters();
+  std::vector>
+  Children;
+  for (const auto &specifierAndDoubleColon : specifiersAsNodesAndDoubleColons) 
{
+Children.push_back(
+{llvm::cast(specifierAndDoubleColon.element),
+ specifierAndDoubleColon.delimiter});
   }
   return Children;
 }

diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index 

[clang] f9500cc - [SyntaxTree] Expand support for `NestedNameSpecifier`

2020-08-10 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-10T15:47:20Z
New Revision: f9500cc487573c55ea37b4ee6e9162d115753a48

URL: 
https://github.com/llvm/llvm-project/commit/f9500cc487573c55ea37b4ee6e9162d115753a48
DIFF: 
https://github.com/llvm/llvm-project/commit/f9500cc487573c55ea37b4ee6e9162d115753a48.diff

LOG: [SyntaxTree] Expand support for `NestedNameSpecifier`

Summary:
We want NestedNameSpecifier syntax nodes to be generally supported, not
only for `DeclRefExpr` and `DependentScopedDeclRefExpr`.

To achieve this we:
* Use the `RecursiveASTVisitor`'s API to traverse
`NestedNameSpecifierLoc`s and automatically create its syntax nodes
* Add links from the `NestedNameSpecifierLoc`s to their syntax nodes.

In this way, from any semantic construct that has a `NestedNameSpecifier`,
we implicitly generate its syntax node via RAV and we can easily access
this syntax node via the links we added.

Added: 


Modified: 
clang/include/clang/AST/NestedNameSpecifier.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/AST/NestedNameSpecifier.h 
b/clang/include/clang/AST/NestedNameSpecifier.h
index 540ac3df48fe..b11cb5f6b86d 100644
--- a/clang/include/clang/AST/NestedNameSpecifier.h
+++ b/clang/include/clang/AST/NestedNameSpecifier.h
@@ -17,6 +17,7 @@
 #include "clang/AST/DependenceFlags.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/Support/Compiler.h"
@@ -527,4 +528,33 @@ inline const DiagnosticBuilder &operator<<(const 
DiagnosticBuilder &DB,
 
 } // namespace clang
 
+namespace llvm {
+
+template <> struct DenseMapInfo {
+  using FirstInfo = DenseMapInfo;
+  using SecondInfo = DenseMapInfo;
+
+  static clang::NestedNameSpecifierLoc getEmptyKey() {
+return clang::NestedNameSpecifierLoc(FirstInfo::getEmptyKey(),
+ SecondInfo::getEmptyKey());
+  }
+
+  static clang::NestedNameSpecifierLoc getTombstoneKey() {
+return clang::NestedNameSpecifierLoc(FirstInfo::getTombstoneKey(),
+ SecondInfo::getTombstoneKey());
+  }
+
+  static unsigned getHashValue(const clang::NestedNameSpecifierLoc &PairVal) {
+return hash_combine(
+FirstInfo::getHashValue(PairVal.getNestedNameSpecifier()),
+SecondInfo::getHashValue(PairVal.getOpaqueData()));
+  }
+
+  static bool isEqual(const clang::NestedNameSpecifierLoc &LHS,
+  const clang::NestedNameSpecifierLoc &RHS) {
+return LHS == RHS;
+  }
+};
+} // namespace llvm
+
 #endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 76b86ac6424d..90451539b3b4 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -241,10 +241,24 @@ class ASTToSyntaxMapping {
 assert(Added && "mapping added twice");
   }
 
+  void add(NestedNameSpecifierLoc From, syntax::Tree *To) {
+assert(To != nullptr);
+assert(From.hasQualifier());
+
+bool Added = NNSNodes.insert({From, To}).second;
+(void)Added;
+assert(Added && "mapping added twice");
+  }
+
   syntax::Tree *find(ASTPtr P) const { return Nodes.lookup(P); }
 
+  syntax::Tree *find(NestedNameSpecifierLoc P) const {
+return NNSNodes.lookup(P);
+  }
+
 private:
   llvm::DenseMap Nodes;
+  llvm::DenseMap NNSNodes;
 };
 } // namespace
 
@@ -281,16 +295,20 @@ class syntax::TreeBuilder {
 if (From)
   Mapping.add(From, New);
   }
+
   void foldNode(ArrayRef Range, syntax::Tree *New, TypeLoc L) {
 // FIXME: add mapping for TypeLocs
 foldNode(Range, New, nullptr);
   }
 
-  void foldNode(ArrayRef Range, syntax::Tree *New,
-NestedNameSpecifierLoc L) {
-// FIXME: add mapping for NestedNameSpecifierLoc
-foldNode(Range, New, nullptr);
+  void foldNode(llvm::ArrayRef Range, syntax::Tree *New,
+NestedNameSpecifierLoc From) {
+assert(New);
+Pending.foldChildren(Arena, Range, New);
+if (From)
+  Mapping.add(From, New);
   }
+
   /// Notifies that we should not consume trailing semicolon when computing
   /// token range of \p D.
   void noticeDeclWithoutSemicolon(Decl *D);
@@ -312,6 +330,8 @@ class syntax::TreeBuilder {
   void markChild(syntax::Node *N, NodeRole R);
   /// Set role for the syntax node matching \p N.
   void markChild(ASTPtr N, NodeRole R);
+  /// Set role for the syntax node matching \p N.
+  void markChild(NestedNameSpecifierLoc N, NodeRole R);
 
   /// Finish building the tree and consume the root node.
   syntax::TranslationUnit *finalize() && {
@@ -744,45 +764,18 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
-  syntax::NameSpecifier *Buil

[clang] ac37afa - [SyntaxTree] Unbox operators into tokens for nodes generated from `CXXOperatorCallExpr`

2020-08-12 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-12T08:01:18Z
New Revision: ac37afa650271d8366b706d79ff8e217fc624cbb

URL: 
https://github.com/llvm/llvm-project/commit/ac37afa650271d8366b706d79ff8e217fc624cbb
DIFF: 
https://github.com/llvm/llvm-project/commit/ac37afa650271d8366b706d79ff8e217fc624cbb.diff

LOG: [SyntaxTree] Unbox operators into tokens for nodes generated from 
`CXXOperatorCallExpr`

For an user define `<`, `x < y` would yield the syntax tree:
```
BinaryOperatorExpression
|-IdExpression
| `-UnqualifiedId
|   `-x
|-IdExpression
| `-UnqualifiedId
|   `-<
`-IdExpression
  `-UnqualifiedId
`-y
```
But there is no syntatic difference at call site between call site or
built-in `<`. As such they should generate the same syntax tree, namely:
```
BinaryOperatorExpression
|-IdExpression
| `-UnqualifiedId
|   `-x
|-<
`-IdExpression
  `-UnqualifiedId
`-y
```

Differential Revision: https://reviews.llvm.org/D85750

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 90451539b3b4..11d399730040 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -1007,23 +1007,26 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   }
 
   bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
-if (getOperatorNodeKind(*S) ==
-syntax::NodeKind::PostfixUnaryOperatorExpression) {
+// To construct a syntax tree of the same shape for calls to built-in and
+// user-defined operators, ignore the `DeclRefExpr` that refers to the
+// operator and treat it as a simple token. Do that by traversing
+// arguments instead of children.
+for (auto *child : S->arguments()) {
   // A postfix unary operator is declared as taking two operands. The
   // second operand is used to distinguish from its prefix counterpart. In
   // the semantic AST this "phantom" operand is represented as a
   // `IntegerLiteral` with invalid `SourceLocation`. We skip visiting this
   // operand because it does not correspond to anything written in source
-  // code
-  for (auto *child : S->children()) {
-if (child->getSourceRange().isInvalid())
-  continue;
-if (!TraverseStmt(child))
-  return false;
+  // code.
+  if (child->getSourceRange().isInvalid()) {
+assert(getOperatorNodeKind(*S) ==
+   syntax::NodeKind::PostfixUnaryOperatorExpression);
+continue;
   }
-  return WalkUpFromCXXOperatorCallExpr(S);
-} else
-  return RecursiveASTVisitor::TraverseCXXOperatorCallExpr(S);
+  if (!TraverseStmt(child))
+return false;
+}
+return WalkUpFromCXXOperatorCallExpr(S);
   }
 
   bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S) {

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 46101660df8e..a5d1a4bfcacf 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -2592,9 +2592,7 @@ void test(X x, X y, X* xp, int X::* pmi) {
 | | |-IdExpression
 | | | `-UnqualifiedId
 | | |   `-x
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   `-=
+| | |-=
 | | `-IdExpression
 | |   `-UnqualifiedId
 | | `-y
@@ -2605,9 +2603,7 @@ void test(X x, X y, X* xp, int X::* pmi) {
 | | | `-IdExpression
 | | |   `-UnqualifiedId
 | | | `-x
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   `-+
+| | |-+
 | | `-IdExpression
 | |   `-UnqualifiedId
 | | `-y
@@ -2617,9 +2613,7 @@ void test(X x, X y, X* xp, int X::* pmi) {
 | | |-IdExpression
 | | | `-UnqualifiedId
 | | |   `-x
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   `-<
+| | |-<
 | | `-IdExpression
 | |   `-UnqualifiedId
 | | `-y
@@ -2629,9 +2623,7 @@ void test(X x, X y, X* xp, int X::* pmi) {
 | | |-IdExpression
 | | | `-UnqualifiedId
 | | |   `-x
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   `-<<
+| | |-<<
 | | `-IdExpression
 | |   `-UnqualifiedId
 | | `-y
@@ -2641,9 +2633,7 @@ void test(X x, X y, X* xp, int X::* pmi) {
 | | |-IdExpression
 | | | `-UnqualifiedId
 | | |   `-x
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   `-,
+| | |-,
 | | `-IdExpression
 | |   `-UnqualifiedId
 | | `-y
@@ -2730,27 +2720,21 @@ void test(X x) {
 |-{
 |-ExpressionStatement
 | |-PrefixUnaryOperatorExpression
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   `-++
+| | |-++
 | | `-IdExpression
 | |   `-UnqualifiedId
 | | `-x
 | `-;
 |-ExpressionStatement
 | |-PrefixUnaryOperato

[clang] d1211fd - [SyntaxTree] Split tests for expressions

2020-08-13 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-13T08:18:14Z
New Revision: d1211fd1ec037f88c2cc855bc850200948c76940

URL: 
https://github.com/llvm/llvm-project/commit/d1211fd1ec037f88c2cc855bc850200948c76940
DIFF: 
https://github.com/llvm/llvm-project/commit/d1211fd1ec037f88c2cc855bc850200948c76940.diff

LOG: [SyntaxTree] Split tests for expressions

We do that because:
* Big tests generated big tree dumps that could hardly serve as documentation.
* In most cases the tests didn't share setup, thus there was not much addition 
in lines of code.

We split tests for:
* `UserDefinedLiteral`
* `NestedBinaryOperator`
* `UserDefinedBinaryOperator`
* `UserDefinedPrefixOperator`
* `QualifiedId`

Differential Revision: https://reviews.llvm.org/D85819

Added: 


Modified: 
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index a5d1a4bfcacf..834496ce0082 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -632,26 +632,48 @@ void test() {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, UnqualifiedId) {
+TEST_P(SyntaxTreeTest, UnqualifiedIdIdentifier) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+void test(int a) {
+  a;
+}
+)cpp",
+  R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-void
+  |-SimpleDeclarator
+  | |-test
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   |-SimpleDeclaration
+  |   | |-int
+  |   | `-SimpleDeclarator
+  |   |   `-a
+  |   `-)
+  `-CompoundStatement
+|-{
+|-ExpressionStatement
+| |-IdExpression
+| | `-UnqualifiedId
+| |   `-a
+| `-;
+`-}
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, UnqualifiedIdOperatorFunctionId) {
   if (!GetParam().isCXX()) {
 return;
   }
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 struct X {
-  // TODO: Expose `id-expression` from `Declarator`
   friend X operator+(const X&, const X&);
-  operator int();
 };
-template
-void f(T&);
 void test(X x) {
-  x;  // identifier
-  operator+(x, x);// operator-function-id
-  f(x);// template-id
-  // TODO: Expose `id-expression` from `MemberExpr`
-  x.operator int();   // conversion-funtion-id
-  x.~X(); // ~type-name
+  operator+(x, x);
 }
 )cpp",
   R"txt(
@@ -682,35 +704,8 @@ void test(X x) {
 | |   |   |   `-&
 | |   |   `-)
 | |   `-;
-| |-SimpleDeclaration
-| | |-SimpleDeclarator
-| | | |-operator
-| | | |-int
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   `-)
-| | `-;
 | |-}
 | `-;
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-typename
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-void
-|   |-SimpleDeclarator
-|   | |-f
-|   | `-ParametersAndQualifiers
-|   |   |-(
-|   |   |-SimpleDeclaration
-|   |   | |-T
-|   |   | `-SimpleDeclarator
-|   |   |   `-&
-|   |   `-)
-|   `-;
 `-SimpleDeclaration
   |-void
   |-SimpleDeclarator
@@ -725,11 +720,6 @@ void test(X x) {
   `-CompoundStatement
 |-{
 |-ExpressionStatement
-| |-IdExpression
-| | `-UnqualifiedId
-| |   `-x
-| `-;
-|-ExpressionStatement
 | |-UnknownExpression
 | | |-IdExpression
 | | | `-UnqualifiedId
@@ -745,20 +735,53 @@ void test(X x) {
 | | |   `-x
 | | `-)
 | `-;
-|-ExpressionStatement
-| |-UnknownExpression
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   |-f
-| | |   |-<
-| | |   |-X
-| | |   `->
-| | |-(
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   `-x
-| | `-)
-| `-;
+`-}
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, UnqualifiedIdConversionFunctionId) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+struct X {
+  operator int();
+};
+void test(X x) {
+  // TODO: Expose `id-expression` from `MemberExpr`
+  x.operator int();
+}
+)cpp",
+  R"txt(
+*: TranslationUnit
+|-SimpleDeclaration
+| |-struct
+| |-X
+| |-{
+| |-SimpleDeclaration
+| | |-SimpleDeclarator
+| | | |-operator
+| | | |-int
+| | | `-ParametersAndQualifiers
+| | |   |-(
+| | |   `-)
+| | `-;
+| |-}
+| `-;
+`-SimpleDeclaration
+  |-void
+  |-SimpleDeclarator
+  | |-test
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   |-SimpleDeclaration
+  |   | |-X
+  |   | `-SimpleDeclarator
+  |   |   `-x
+  |   `-)
+  `-CompoundStatement
+|-{
 |-ExpressionStatement
 | |-UnknownExpression
 | | |-UnknownExpression
@@ -771,6 +794,93 @@ void test(X x) {
 | | |-(
 | | `-)
 | `-;
+`-}
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, UnqualifiedIdLiteralOperatorId) {
+  if (!GetParam().isCXX11OrLater()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+unsigned operator "" _w(char);
+void test() {
+  operator "" _w('1');
+}
+)cpp",
+  R"txt(
+*: TranslationUnit
+|-SimpleDeclaration
+| |-unsigned
+| |-SimpleDeclarator
+| | |-operator
+

[clang] 833c2b6 - [SyntaxTree] Rename tests following `TestSuite_TestCase` + nits

2020-08-13 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-13T08:18:14Z
New Revision: 833c2b6be26bcdf90aac2f6de6e345bcd858149e

URL: 
https://github.com/llvm/llvm-project/commit/833c2b6be26bcdf90aac2f6de6e345bcd858149e
DIFF: 
https://github.com/llvm/llvm-project/commit/833c2b6be26bcdf90aac2f6de6e345bcd858149e.diff

LOG: [SyntaxTree] Rename tests following `TestSuite_TestCase` + nits

Added: 


Modified: 
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 834496ce0082..e266ef3f5870 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -632,7 +632,7 @@ void test() {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, UnqualifiedIdIdentifier) {
+TEST_P(SyntaxTreeTest, UnqualifiedId_Identifier) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 void test(int a) {
@@ -663,7 +663,7 @@ void test(int a) {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, UnqualifiedIdOperatorFunctionId) {
+TEST_P(SyntaxTreeTest, UnqualifiedId_OperatorFunctionId) {
   if (!GetParam().isCXX()) {
 return;
   }
@@ -739,7 +739,7 @@ void test(X x) {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, UnqualifiedIdConversionFunctionId) {
+TEST_P(SyntaxTreeTest, UnqualifiedId_ConversionFunctionId) {
   if (!GetParam().isCXX()) {
 return;
   }
@@ -798,7 +798,7 @@ void test(X x) {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, UnqualifiedIdLiteralOperatorId) {
+TEST_P(SyntaxTreeTest, UnqualifiedId_LiteralOperatorId) {
   if (!GetParam().isCXX11OrLater()) {
 return;
   }
@@ -848,7 +848,7 @@ void test() {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, UnqualifiedIdDestructor) {
+TEST_P(SyntaxTreeTest, UnqualifiedId_Destructor) {
   if (!GetParam().isCXX()) {
 return;
   }
@@ -897,7 +897,7 @@ void test(X x) {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, UnqualifiedIdDecltypeDestructor) {
+TEST_P(SyntaxTreeTest, UnqualifiedId_DecltypeDestructor) {
   if (!GetParam().isCXX11OrLater()) {
 return;
   }
@@ -949,7 +949,7 @@ void test(X x) {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, UnqualifiedIdTemplateId) {
+TEST_P(SyntaxTreeTest, UnqualifiedId_TemplateId) {
   if (!GetParam().isCXX()) {
 return;
   }
@@ -1002,7 +1002,7 @@ void test() {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, QualifiedIdWithNamespace) {
+TEST_P(SyntaxTreeTest, QualifiedId_NamespaceSpecifier) {
   if (!GetParam().isCXX()) {
 return;
   }
@@ -1065,7 +1065,7 @@ void test() {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, QualifiedIdWithTemplateSpecifier) {
+TEST_P(SyntaxTreeTest, QualifiedId_TemplateSpecifier) {
   if (!GetParam().isCXX()) {
 return;
   }
@@ -1145,7 +1145,73 @@ void test() {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, QualifiedIdWithOptionalTemplateKw) {
+TEST_P(SyntaxTreeTest, QualifiedId_DecltypeSpecifier) {
+  if (!GetParam().isCXX11OrLater()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+struct S {
+  static void f(){}
+};
+void test(S s) {
+  decltype(s)::f();
+}
+)cpp",
+  R"txt(
+*: TranslationUnit
+|-SimpleDeclaration
+| |-struct
+| |-S
+| |-{
+| |-SimpleDeclaration
+| | |-static
+| | |-void
+| | |-SimpleDeclarator
+| | | |-f
+| | | `-ParametersAndQualifiers
+| | |   |-(
+| | |   `-)
+| | `-CompoundStatement
+| |   |-{
+| |   `-}
+| |-}
+| `-;
+`-SimpleDeclaration
+  |-void
+  |-SimpleDeclarator
+  | |-test
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   |-SimpleDeclaration
+  |   | |-S
+  |   | `-SimpleDeclarator
+  |   |   `-s
+  |   `-)
+  `-CompoundStatement
+|-{
+|-ExpressionStatement
+| |-UnknownExpression
+| | |-IdExpression
+| | | |-NestedNameSpecifier
+| | | | |-DecltypeNameSpecifier
+| | | | | |-decltype
+| | | | | |-(
+| | | | | |-IdExpression
+| | | | | | `-UnqualifiedId
+| | | | | |   `-s
+| | | | | `-)
+| | | | `-::
+| | | `-UnqualifiedId
+| | |   `-f
+| | |-(
+| | `-)
+| `-;
+`-}
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, QualifiedId_OptionalTemplateKw) {
   if (!GetParam().isCXX()) {
 return;
   }
@@ -1228,18 +1294,18 @@ void test() {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, QualifiedIdComplex) {
+TEST_P(SyntaxTreeTest, QualifiedId_Complex) {
   if (!GetParam().isCXX()) {
 return;
   }
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 namespace n {
-template
-struct ST {
-  template
-  static U f();
-};
+  template
+  struct ST {
+template
+static U f();
+  };
 }
 void test() {
   ::n::template ST::template f();
@@ -1318,7 +1384,7 @@ void test() {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, QualifiedIdWithDependentType) {
+TEST_P(SyntaxTreeTest, QualifiedId_DependentType) {
   if (!GetParam().isCXX()) {
 return;
   }
@@ -1409,72 +1475,6 @@ void test() {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, QualifiedIdDecltype) {
-  if (!GetParam().isCXX11OrLater()) {
-return;
-  }
-  EXPECT_TRUE(treeDumpEqual(
-  R"cpp(
-struct S {
-  

[clang] d17437d - [SyntaxTree] Split `TreeTest.cpp`

2020-08-13 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-13T13:30:57Z
New Revision: d17437d2bd8e83baee96f2860276d615d216dfbc

URL: 
https://github.com/llvm/llvm-project/commit/d17437d2bd8e83baee96f2860276d615d216dfbc
DIFF: 
https://github.com/llvm/llvm-project/commit/d17437d2bd8e83baee96f2860276d615d216dfbc.diff

LOG: [SyntaxTree] Split `TreeTest.cpp`

We extract the test infrastructure into `TreeTestBase.h` and split the
tests into `MutationsTest.cpp` and `BuildTreeTest.cpp`

Added: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
clang/unittests/Tooling/Syntax/MutationsTest.cpp
clang/unittests/Tooling/Syntax/TreeTestBase.h

Modified: 
clang/unittests/Tooling/Syntax/CMakeLists.txt

Removed: 
clang/unittests/Tooling/Syntax/TreeTest.cpp



diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
similarity index 88%
rename from clang/unittests/Tooling/Syntax/TreeTest.cpp
rename to clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index e266ef3f5870..deffd48da085 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -1,217 +1,20 @@
-//===- TreeTest.cpp 
---===//
+//===- BuildTreeTest.cpp 
--===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 
//===--===//
+//
+// This file tests the syntax tree generation from the ClangAST.
+//
+//===--===//
 
-#include "clang/Tooling/Syntax/Tree.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/TokenKinds.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "clang/Lex/PreprocessorOptions.h"
-#include "clang/Testing/CommandLineArgs.h"
-#include "clang/Testing/TestClangConfig.h"
-#include "clang/Tooling/Core/Replacement.h"
-#include "clang/Tooling/Syntax/BuildTree.h"
-#include "clang/Tooling/Syntax/Mutations.h"
-#include "clang/Tooling/Syntax/Nodes.h"
-#include "clang/Tooling/Syntax/Tokens.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Testing/Support/Annotations.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include 
-#include 
-
-using namespace clang;
+#include "TreeTestBase.h"
 
+namespace clang {
+namespace syntax {
 namespace {
-static ArrayRef tokens(syntax::Node *N) {
-  assert(N->isOriginal() && "tokens of modified nodes are not well-defined");
-  if (auto *L = dyn_cast(N))
-return llvm::makeArrayRef(L->token(), 1);
-  auto *T = cast(N);
-  return llvm::makeArrayRef(T->firstLeaf()->token(),
-T->lastLeaf()->token() + 1);
-}
-
-class SyntaxTreeTest : public ::testing::Test,
-   public ::testing::WithParamInterface {
-protected:
-  // Build a syntax tree for the code.
-  syntax::TranslationUnit *buildTree(StringRef Code,
- const TestClangConfig &ClangConfig) {
-// FIXME: this code is almost the identical to the one in TokensTest. Share
-//it.
-class BuildSyntaxTree : public ASTConsumer {
-public:
-  BuildSyntaxTree(syntax::TranslationUnit *&Root,
-  std::unique_ptr &TB,
-  std::unique_ptr &Arena,
-  std::unique_ptr Tokens)
-  : Root(Root), TB(TB), Arena(Arena), Tokens(std::move(Tokens)) {
-assert(this->Tokens);
-  }
-
-  void HandleTranslationUnit(ASTContext &Ctx) override {
-TB =
-
std::make_unique(std::move(*Tokens).consume());
-Tokens = nullptr; // make sure we fail if this gets called twice.
-Arena = std::make_unique(Ctx.getSourceManager(),
-Ctx.getLangOpts(), *TB);
-Root = syntax::buildSyntaxTree(*Arena, *Ctx.getTranslationUnitDecl());
-  }
-
-private:
-  syntax::TranslationUnit *&Root;
-  std::unique_ptr &TB;
-  std::unique_ptr &Arena;
-  std::unique_ptr Tokens;
-};
-
-class BuildSyntaxTreeAction : public ASTFrontendAction {
-public:
-  BuildSyntaxTreeAction(syntax::TranslationUnit *&Root,
-std::unique_ptr &TB,
-std::unique_ptr &Arena)

[clang] 9c2e708 - [SyntaxTree] Clean `#includes` in `TreeTestBase.h`

2020-08-13 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-13T13:30:57Z
New Revision: 9c2e708f0dc547d386ea528450a33ef4bd2a750b

URL: 
https://github.com/llvm/llvm-project/commit/9c2e708f0dc547d386ea528450a33ef4bd2a750b
DIFF: 
https://github.com/llvm/llvm-project/commit/9c2e708f0dc547d386ea528450a33ef4bd2a750b.diff

LOG: [SyntaxTree] Clean `#includes` in `TreeTestBase.h`

Differential Revision: https://reviews.llvm.org/D85898

Added: 


Modified: 
clang/unittests/Tooling/Syntax/MutationsTest.cpp
clang/unittests/Tooling/Syntax/TreeTestBase.h

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/MutationsTest.cpp 
b/clang/unittests/Tooling/Syntax/MutationsTest.cpp
index 30f8d523b781..088dbe3afbdc 100644
--- a/clang/unittests/Tooling/Syntax/MutationsTest.cpp
+++ b/clang/unittests/Tooling/Syntax/MutationsTest.cpp
@@ -10,6 +10,7 @@
 //
 
//===--===//
 
+#include "clang/Tooling/Syntax/Mutations.h"
 #include "TreeTestBase.h"
 
 namespace clang {

diff  --git a/clang/unittests/Tooling/Syntax/TreeTestBase.h 
b/clang/unittests/Tooling/Syntax/TreeTestBase.h
index 0e66a320d812..37b604dd5cd5 100644
--- a/clang/unittests/Tooling/Syntax/TreeTestBase.h
+++ b/clang/unittests/Tooling/Syntax/TreeTestBase.h
@@ -11,10 +11,7 @@
 
//===--===//
 
 #include "clang/AST/ASTConsumer.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Stmt.h"
 #include "clang/Basic/LLVM.h"
-#include "clang/Basic/TokenKinds.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/FrontendAction.h"
@@ -22,23 +19,16 @@
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Testing/CommandLineArgs.h"
 #include "clang/Testing/TestClangConfig.h"
-#include "clang/Tooling/Core/Replacement.h"
 #include "clang/Tooling/Syntax/BuildTree.h"
-#include "clang/Tooling/Syntax/Mutations.h"
 #include "clang/Tooling/Syntax/Nodes.h"
 #include "clang/Tooling/Syntax/Tokens.h"
-#include "clang/Tooling/Tooling.h"
+#include "clang/Tooling/Syntax/Tree.h"
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Testing/Support/Annotations.h"
-#include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include 
-#include 
 
 namespace clang {
 namespace syntax {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 2e4a20f - [SyntaxTree] Split `TreeTestBase` into header and source

2020-08-14 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-14T07:29:07Z
New Revision: 2e4a20fd7062f65c06b438953de3d340df00b7a7

URL: 
https://github.com/llvm/llvm-project/commit/2e4a20fd7062f65c06b438953de3d340df00b7a7
DIFF: 
https://github.com/llvm/llvm-project/commit/2e4a20fd7062f65c06b438953de3d340df00b7a7.diff

LOG: [SyntaxTree] Split `TreeTestBase` into header and source

* Switch to using directive on source files.
* Remove unused `SyntaxTreeTest::addFile`

Differential Revision: https://reviews.llvm.org/D85913

Added: 
clang/unittests/Tooling/Syntax/TreeTestBase.cpp

Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
clang/unittests/Tooling/Syntax/CMakeLists.txt
clang/unittests/Tooling/Syntax/MutationsTest.cpp
clang/unittests/Tooling/Syntax/TreeTestBase.h

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index deffd48da085..211e8b1ae901 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -12,8 +12,9 @@
 
 #include "TreeTestBase.h"
 
-namespace clang {
-namespace syntax {
+using namespace clang;
+using namespace clang::syntax;
+
 namespace {
 
 TEST_P(SyntaxTreeTest, Simple) {
@@ -4836,26 +4837,4 @@ void x(char a, short (*b)(int), long (**c)(long long));
 )txt"));
 }
 
-static std::vector allTestClangConfigs() {
-  std::vector all_configs;
-  for (TestLanguage lang : {Lang_C89, Lang_C99, Lang_CXX03, Lang_CXX11,
-Lang_CXX14, Lang_CXX17, Lang_CXX20}) {
-TestClangConfig config;
-config.Language = lang;
-config.Target = "x86_64-pc-linux-gnu";
-all_configs.push_back(config);
-
-// Windows target is interesting to test because it enables
-// `-fdelayed-template-parsing`.
-config.Target = "x86_64-pc-win32-msvc";
-all_configs.push_back(config);
-  }
-  return all_configs;
-}
-
-INSTANTIATE_TEST_CASE_P(SyntaxTreeTests, SyntaxTreeTest,
-testing::ValuesIn(allTestClangConfigs()), );
-
 } // namespace
-} // namespace syntax
-} // namespace clang

diff  --git a/clang/unittests/Tooling/Syntax/CMakeLists.txt 
b/clang/unittests/Tooling/Syntax/CMakeLists.txt
index c7634798fb2b..46ff4c9c3e27 100644
--- a/clang/unittests/Tooling/Syntax/CMakeLists.txt
+++ b/clang/unittests/Tooling/Syntax/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
   )
 
 add_clang_unittest(SyntaxTests
+  TreeTestBase.cpp
   BuildTreeTest.cpp
   MutationsTest.cpp
   TokensTest.cpp

diff  --git a/clang/unittests/Tooling/Syntax/MutationsTest.cpp 
b/clang/unittests/Tooling/Syntax/MutationsTest.cpp
index 088dbe3afbdc..6ef71e3a8090 100644
--- a/clang/unittests/Tooling/Syntax/MutationsTest.cpp
+++ b/clang/unittests/Tooling/Syntax/MutationsTest.cpp
@@ -12,9 +12,11 @@
 
 #include "clang/Tooling/Syntax/Mutations.h"
 #include "TreeTestBase.h"
+#include "clang/Tooling/Syntax/BuildTree.h"
+
+using namespace clang;
+using namespace clang::syntax;
 
-namespace clang {
-namespace syntax {
 namespace {
 
 TEST_P(SyntaxTreeTest, Mutations) {
@@ -81,5 +83,3 @@ TEST_P(SyntaxTreeTest, SynthesizedNodes) {
   EXPECT_TRUE(S->isDetached());
 }
 } // namespace
-} // namespace syntax
-} // namespace clang

diff  --git a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp 
b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
new file mode 100644
index ..6d2efeaaa8eb
--- /dev/null
+++ b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
@@ -0,0 +1,200 @@
+//===- TreeTestBase.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file provides the test infrastructure for syntax trees.
+//
+//===--===//
+
+#include "TreeTestBase.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Lex/PreprocessorOptions.h"
+#include "clang/Testing/CommandLineArgs.h"
+#include "clang/Testing/TestClangConfig.h"
+#include "clang/Tooling/Syntax/BuildTree.h"
+#include "clang/Tooling/Syntax/Nodes.h"
+#include "clang/Tooling/Syntax/Tokens.h"
+#include "clang/Tooling/Syntax/Tree.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Testing/Support/Annotations.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace clang::syntax;
+
+namespace {
+ArrayRef tokens(syntax::N

[clang] ab58c9e - [SyntaxTree] Implement annotation-based test infrastructure

2020-08-18 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-18T13:00:56Z
New Revision: ab58c9ee8a6e9ace3a93198496b4d85e8cb2b5a9

URL: 
https://github.com/llvm/llvm-project/commit/ab58c9ee8a6e9ace3a93198496b4d85e8cb2b5a9
DIFF: 
https://github.com/llvm/llvm-project/commit/ab58c9ee8a6e9ace3a93198496b4d85e8cb2b5a9.diff

LOG: [SyntaxTree] Implement annotation-based test infrastructure

We add the method `SyntaxTreeTest::treeDumpEqualOnAnnotations`, which
allows us to compare the treeDump of only annotated code. This will reduce a
lot of noise from our `BuildTreeTest` and make them short and easier to
read.

Added: 


Modified: 
clang/unittests/Tooling/Syntax/TreeTestBase.cpp
clang/unittests/Tooling/Syntax/TreeTestBase.h

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp 
b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
index 6d2efeaaa8eb..05fbac4f47e1 100644
--- a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
@@ -180,6 +180,35 @@ ::testing::AssertionResult 
SyntaxTreeTest::treeDumpEqual(StringRef Code,
   return ::testing::AssertionSuccess();
 }
 
+::testing::AssertionResult
+SyntaxTreeTest::treeDumpEqualOnAnnotations(StringRef CodeWithAnnotations,
+   ArrayRef TreeDumps) {
+  SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
+
+  auto AnnotatedCode = llvm::Annotations(CodeWithAnnotations);
+  auto *Root = buildTree(AnnotatedCode.code(), GetParam());
+
+  if (Diags->getClient()->getNumErrors() != 0) {
+return ::testing::AssertionFailure()
+   << "Source file has syntax errors, they were printed to the test "
+  "log";
+  }
+
+  bool failed = false;
+  auto AnnotatedRanges = AnnotatedCode.ranges();
+  assert(AnnotatedRanges.size() == TreeDumps.size());
+  for (auto i = 0ul; i < AnnotatedRanges.size(); i++) {
+auto *AnnotatedNode = nodeByRange(AnnotatedRanges[i], Root);
+assert(AnnotatedNode);
+auto AnnotatedNodeDump =
+std::string(StringRef(AnnotatedNode->dump(*Arena)).trim());
+// EXPECT_EQ shows the 
diff  between the two strings if they are 
diff erent.
+EXPECT_EQ(TreeDumps[i].trim().str(), AnnotatedNodeDump);
+if (AnnotatedNodeDump != TreeDumps[i].trim().str())
+  failed = true;
+  }
+  return failed ? ::testing::AssertionFailure() : 
::testing::AssertionSuccess();
+}
 syntax::Node *SyntaxTreeTest::nodeByRange(llvm::Annotations::Range R,
   syntax::Node *Root) {
   ArrayRef Toks = tokens(Root);

diff  --git a/clang/unittests/Tooling/Syntax/TreeTestBase.h 
b/clang/unittests/Tooling/Syntax/TreeTestBase.h
index bfa6ecd7909f..c282bbf45fd3 100644
--- a/clang/unittests/Tooling/Syntax/TreeTestBase.h
+++ b/clang/unittests/Tooling/Syntax/TreeTestBase.h
@@ -34,6 +34,9 @@ class SyntaxTreeTest : public ::testing::Test,
 
   ::testing::AssertionResult treeDumpEqual(StringRef Code, StringRef Tree);
 
+  ::testing::AssertionResult
+  treeDumpEqualOnAnnotations(StringRef CodeWithAnnotations,
+ ArrayRef TreeDumps);
   /// Finds the deepest node in the tree that covers exactly \p R.
   /// FIXME: implement this efficiently and move to public syntax tree API.
   syntax::Node *nodeByRange(llvm::Annotations::Range R, syntax::Node *Root);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] c8c92b5 - [SyntaxTree] Use Annotations based tests for expressions

2020-08-18 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-18T13:00:56Z
New Revision: c8c92b54d74c1b9256f9aed6ba89d66fbd1d01ae

URL: 
https://github.com/llvm/llvm-project/commit/c8c92b54d74c1b9256f9aed6ba89d66fbd1d01ae
DIFF: 
https://github.com/llvm/llvm-project/commit/c8c92b54d74c1b9256f9aed6ba89d66fbd1d01ae.diff

LOG: [SyntaxTree] Use Annotations based tests for expressions

In this process we also create some other tests, in order to not lose
coverage when focusing on the annotated code

Differential Revision: https://reviews.llvm.org/D85962

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
clang/unittests/Tooling/Syntax/TreeTestBase.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 211e8b1ae901..fd858dfba91f 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -437,672 +437,355 @@ void test() {
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_Identifier) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 void test(int a) {
-  a;
+  [[a]];
 }
 )cpp",
-  R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-a
-  |   `-)
-  `-CompoundStatement
-|-{
-|-ExpressionStatement
-| |-IdExpression
-| | `-UnqualifiedId
-| |   `-a
-| `-;
-`-}
-)txt"));
+  {R"txt(
+IdExpression
+`-UnqualifiedId
+  `-a
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_OperatorFunctionId) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 struct X {
   friend X operator+(const X&, const X&);
 };
 void test(X x) {
-  operator+(x, x);
-}
-)cpp",
-  R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-UnknownDeclaration
-| | `-SimpleDeclaration
-| |   |-friend
-| |   |-X
-| |   |-SimpleDeclarator
-| |   | |-operator
-| |   | |-+
-| |   | `-ParametersAndQualifiers
-| |   |   |-(
-| |   |   |-SimpleDeclaration
-| |   |   | |-const
-| |   |   | |-X
-| |   |   | `-SimpleDeclarator
-| |   |   |   `-&
-| |   |   |-,
-| |   |   |-SimpleDeclaration
-| |   |   | |-const
-| |   |   | |-X
-| |   |   | `-SimpleDeclarator
-| |   |   |   `-&
-| |   |   `-)
-| |   `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   `-)
-  `-CompoundStatement
-|-{
-|-ExpressionStatement
-| |-UnknownExpression
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   |-operator
-| | |   `-+
-| | |-(
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   `-x
-| | |-,
-| | |-IdExpression
-| | | `-UnqualifiedId
-| | |   `-x
-| | `-)
-| `-;
-`-}
-)txt"));
+  [[operator+(x, x)]];
+}
+)cpp",
+  {R"txt(
+UnknownExpression
+|-IdExpression
+| `-UnqualifiedId
+|   |-operator
+|   `-+
+|-(
+|-IdExpression
+| `-UnqualifiedId
+|   `-x
+|-,
+|-IdExpression
+| `-UnqualifiedId
+|   `-x
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_ConversionFunctionId) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 struct X {
   operator int();
 };
 void test(X x) {
   // TODO: Expose `id-expression` from `MemberExpr`
-  x.operator int();
+  [[x.operator int()]];
 }
 )cpp",
-  R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-SimpleDeclaration
-| | |-SimpleDeclarator
-| | | |-operator
-| | | |-int
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   `-)
-| | `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   `-)
-  `-CompoundStatement
-|-{
-|-ExpressionStatement
-| |-UnknownExpression
-| | |-UnknownExpression
-| | | |-IdExpression
-| | | | `-UnqualifiedId
-| | | |   `-x
-| | | |-.
-| | | |-operator
-| | | `-int
-| | |-(
-| | `-)
-| `-;
-`-}
-)txt"));
+  {R"txt(
+UnknownExpression
+|-UnknownExpression
+| |-IdExpression
+| | `-UnqualifiedId
+| |   `-x
+| |-.
+| |-operator
+| `-int
+|-(
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_LiteralOperatorId) {
   if (!GetParam().isCXX11OrLater()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 unsigned operator "" _w(char);
 void test() {
-  operator "" _w('1');
+  [[operator "" _w('1')]];
 }
 )cpp",
-  R"txt(
-*:

[clang] 4c14ee6 - [SyntaxTree] Rename functions to start with verb

2020-09-11 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-11T14:54:18Z
New Revision: 4c14ee61b73746b314d83e7c52e03d6527b78105

URL: 
https://github.com/llvm/llvm-project/commit/4c14ee61b73746b314d83e7c52e03d6527b78105
DIFF: 
https://github.com/llvm/llvm-project/commit/4c14ee61b73746b314d83e7c52e03d6527b78105.diff

LOG: [SyntaxTree] Rename functions to start with verb

According to LLVM coding standards:
https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly

Differential Revision: https://reviews.llvm.org/D87498

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/include/clang/Tooling/Syntax/Tree.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/ComputeReplacements.cpp
clang/lib/Tooling/Syntax/Mutations.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/lib/Tooling/Syntax/Synthesis.cpp
clang/lib/Tooling/Syntax/Tree.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
clang/unittests/Tooling/Syntax/SynthesisTest.cpp
clang/unittests/Tooling/Syntax/TreeTestBase.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index a6505c8167ee..8b393c5423b4 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -190,7 +190,7 @@ class TranslationUnit final : public Tree {
 public:
   TranslationUnit() : Tree(NodeKind::TranslationUnit) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::TranslationUnit;
+return N->getKind() == NodeKind::TranslationUnit;
   }
 };
 
@@ -200,8 +200,8 @@ class Expression : public Tree {
 public:
   Expression(NodeKind K) : Tree(K) {}
   static bool classof(const Node *N) {
-return NodeKind::UnknownExpression <= N->kind() &&
-   N->kind() <= NodeKind::UnknownExpression;
+return NodeKind::UnknownExpression <= N->getKind() &&
+   N->getKind() <= NodeKind::UnknownExpression;
   }
 };
 
@@ -211,10 +211,10 @@ class NameSpecifier : public Tree {
 public:
   NameSpecifier(NodeKind K) : Tree(K) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::GlobalNameSpecifier ||
-   N->kind() == NodeKind::DecltypeNameSpecifier ||
-   N->kind() == NodeKind::IdentifierNameSpecifier ||
-   N->kind() == NodeKind::SimpleTemplateNameSpecifier;
+return N->getKind() == NodeKind::GlobalNameSpecifier ||
+   N->getKind() == NodeKind::DecltypeNameSpecifier ||
+   N->getKind() == NodeKind::IdentifierNameSpecifier ||
+   N->getKind() == NodeKind::SimpleTemplateNameSpecifier;
   }
 };
 
@@ -226,7 +226,7 @@ class GlobalNameSpecifier final : public NameSpecifier {
 public:
   GlobalNameSpecifier() : NameSpecifier(NodeKind::GlobalNameSpecifier) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::GlobalNameSpecifier;
+return N->getKind() == NodeKind::GlobalNameSpecifier;
   }
 };
 
@@ -236,7 +236,7 @@ class DecltypeNameSpecifier final : public NameSpecifier {
 public:
   DecltypeNameSpecifier() : NameSpecifier(NodeKind::DecltypeNameSpecifier) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::DecltypeNameSpecifier;
+return N->getKind() == NodeKind::DecltypeNameSpecifier;
   }
 };
 
@@ -247,7 +247,7 @@ class IdentifierNameSpecifier final : public NameSpecifier {
   IdentifierNameSpecifier()
   : NameSpecifier(NodeKind::IdentifierNameSpecifier) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::IdentifierNameSpecifier;
+return N->getKind() == NodeKind::IdentifierNameSpecifier;
   }
 };
 
@@ -259,7 +259,7 @@ class SimpleTemplateNameSpecifier final : public 
NameSpecifier {
   SimpleTemplateNameSpecifier()
   : NameSpecifier(NodeKind::SimpleTemplateNameSpecifier) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::SimpleTemplateNameSpecifier;
+return N->getKind() == NodeKind::SimpleTemplateNameSpecifier;
   }
 };
 
@@ -269,7 +269,7 @@ class NestedNameSpecifier final : public List {
 public:
   NestedNameSpecifier() : List(NodeKind::NestedNameSpecifier) {}
   static bool classof(const Node *N) {
-return N->kind() <= NodeKind::NestedNameSpecifier;
+return N->getKind() <= NodeKind::NestedNameSpecifier;
   }
   std::vector getSpecifiers();
   std::vector>
@@ -282,7 +282,7 @@ class UnqualifiedId final : public Tree {
 public:
   UnqualifiedId() : Tree(NodeKind::UnqualifiedId) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::UnqualifiedId;
+return N->getKind() == NodeKind::UnqualifiedId;
   }
 };
 
@@ -297,7 +297,7 @@ class IdExpression final : public Expression {
 public:
   IdExpression() : Expression(NodeKind::IdExpression) {}
   static bool classof(const Node *N) {
-return N->kind() == NodeKind::IdExpression;
+return N->getKind() =

[clang] 5d15212 - [SyntaxTree][Synthesis] Add support for simple Leafs and test based on tree dump

2020-09-11 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-11T18:22:00Z
New Revision: 5d152127d48fbcf47a8d059aa68a84c365ae3cb9

URL: 
https://github.com/llvm/llvm-project/commit/5d152127d48fbcf47a8d059aa68a84c365ae3cb9
DIFF: 
https://github.com/llvm/llvm-project/commit/5d152127d48fbcf47a8d059aa68a84c365ae3cb9.diff

LOG: [SyntaxTree][Synthesis] Add support for simple Leafs and test based on 
tree dump

Differential Revision: https://reviews.llvm.org/D87495

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/BuildTree.h
clang/lib/Tooling/Syntax/Synthesis.cpp
clang/unittests/Tooling/Syntax/SynthesisTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/BuildTree.h 
b/clang/include/clang/Tooling/Syntax/BuildTree.h
index b7ad50c941d1..c2ae4348bc16 100644
--- a/clang/include/clang/Tooling/Syntax/BuildTree.h
+++ b/clang/include/clang/Tooling/Syntax/BuildTree.h
@@ -24,8 +24,17 @@ syntax::TranslationUnit *buildSyntaxTree(Arena &A,
 
 // Create syntax trees from subtrees not backed by the source code.
 
-clang::syntax::Leaf *createPunctuation(clang::syntax::Arena &A,
-   clang::tok::TokenKind K);
+// Synthesis of Leafs
+/// Create `Leaf` from token with `Spelling` and assert it has the desired
+/// `TokenKind`.
+syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K,
+ StringRef Spelling);
+
+/// Infer the token spelling from its `TokenKind`, then create `Leaf` from
+/// this token
+syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K);
+
+// Synthesis of Syntax Nodes
 clang::syntax::EmptyStatement *createEmptyStatement(clang::syntax::Arena &A);
 
 } // namespace syntax

diff  --git a/clang/lib/Tooling/Syntax/Synthesis.cpp 
b/clang/lib/Tooling/Syntax/Synthesis.cpp
index 701a1e60a4f3..8d51325706fa 100644
--- a/clang/lib/Tooling/Syntax/Synthesis.cpp
+++ b/clang/lib/Tooling/Syntax/Synthesis.cpp
@@ -5,13 +5,14 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 
//===--===//
+#include "clang/Basic/TokenKinds.h"
 #include "clang/Tooling/Syntax/BuildTree.h"
 
 using namespace clang;
 
 /// Exposes private syntax tree APIs required to implement node synthesis.
 /// Should not be used for anything else.
-class syntax::FactoryImpl {
+class clang::syntax::FactoryImpl {
 public:
   static void setCanModify(syntax::Node *N) { N->CanModify = true; }
 
@@ -21,24 +22,32 @@ class syntax::FactoryImpl {
   }
 };
 
-clang::syntax::Leaf *syntax::createPunctuation(clang::syntax::Arena &A,
-   clang::tok::TokenKind K) {
-  auto Tokens = A.lexBuffer(llvm::MemoryBuffer::getMemBuffer(
-clang::tok::getPunctuatorSpelling(K)))
-.second;
+syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, tok::TokenKind K,
+StringRef Spelling) {
+  auto Tokens = A.lexBuffer(llvm::MemoryBuffer::getMemBuffer(Spelling)).second;
   assert(Tokens.size() == 1);
-  assert(Tokens.front().kind() == K);
-  auto *L = new (A.getAllocator()) clang::syntax::Leaf(Tokens.begin());
-  FactoryImpl::setCanModify(L);
-  L->assertInvariants();
-  return L;
+  assert(Tokens.front().kind() == K &&
+ "spelling is not lexed into the expected kind of token");
+
+  auto *Leaf = new (A.getAllocator()) syntax::Leaf(Tokens.begin());
+  syntax::FactoryImpl::setCanModify(Leaf);
+  Leaf->assertInvariants();
+  return Leaf;
+}
+
+syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, tok::TokenKind K) {
+  const auto *Spelling = tok::getPunctuatorSpelling(K);
+  if (!Spelling)
+Spelling = tok::getKeywordSpelling(K);
+  assert(Spelling &&
+ "Cannot infer the spelling of the token from its token kind.");
+  return createLeaf(A, K, Spelling);
 }
 
-clang::syntax::EmptyStatement *
-syntax::createEmptyStatement(clang::syntax::Arena &A) {
-  auto *S = new (A.getAllocator()) clang::syntax::EmptyStatement;
+syntax::EmptyStatement *clang::syntax::createEmptyStatement(syntax::Arena &A) {
+  auto *S = new (A.getAllocator()) syntax::EmptyStatement;
   FactoryImpl::setCanModify(S);
-  FactoryImpl::prependChildLowLevel(S, createPunctuation(A, clang::tok::semi),
+  FactoryImpl::prependChildLowLevel(S, createLeaf(A, tok::semi),
 NodeRole::Unknown);
   S->assertInvariants();
   return S;

diff  --git a/clang/unittests/Tooling/Syntax/SynthesisTest.cpp 
b/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
index 884f3797edef..1c1aef8bd8c8 100644
--- a/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
+++ b/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
@@ -12,33 +12,81 @@
 
 #include "TreeTestBase.h"
 #include "clang/Tooling/Syntax/BuildTree.h"
+#include "gtest/gtest.h"
 
 using namespace clang;
 using namespace clang::syntax;
 
 namespace {
 
-INSTANTIATE_TEST_CA

[clang] 515238d - [SyntaxTree] Reduce visibility of `Arena::lexBuffer`.

2020-09-11 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-11T18:32:38Z
New Revision: 515238d5b1133f87f85445b9f35783ca2d3a2e7b

URL: 
https://github.com/llvm/llvm-project/commit/515238d5b1133f87f85445b9f35783ca2d3a2e7b
DIFF: 
https://github.com/llvm/llvm-project/commit/515238d5b1133f87f85445b9f35783ca2d3a2e7b.diff

LOG: [SyntaxTree] Reduce visibility of `Arena::lexBuffer`.

Differential Revision: https://reviews.llvm.org/D87523

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Tree.h
clang/lib/Tooling/Syntax/Synthesis.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Tree.h 
b/clang/include/clang/Tooling/Syntax/Tree.h
index aab904ab65d32..b49a09344c0fb 100644
--- a/clang/include/clang/Tooling/Syntax/Tree.h
+++ b/clang/include/clang/Tooling/Syntax/Tree.h
@@ -47,11 +47,13 @@ class Arena {
   const TokenBuffer &getTokenBuffer() const;
   llvm::BumpPtrAllocator &getAllocator() { return Allocator; }
 
+private:
   /// Add \p Buffer to the underlying source manager, tokenize it and store the
-  /// resulting tokens. Useful when there is a need to materialize tokens that
-  /// were not written in user code.
+  /// resulting tokens. Used exclusively in `FactoryImpl` to materialize tokens
+  /// that were not written in user code.
   std::pair>
   lexBuffer(std::unique_ptr Buffer);
+  friend class FactoryImpl;
 
 private:
   SourceManager &SourceMgr;

diff  --git a/clang/lib/Tooling/Syntax/Synthesis.cpp 
b/clang/lib/Tooling/Syntax/Synthesis.cpp
index 8d51325706fa0..772429ff4c466 100644
--- a/clang/lib/Tooling/Syntax/Synthesis.cpp
+++ b/clang/lib/Tooling/Syntax/Synthesis.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Tooling/Syntax/BuildTree.h"
+#include "clang/Tooling/Syntax/Tree.h"
 
 using namespace clang;
 
@@ -20,11 +21,18 @@ class clang::syntax::FactoryImpl {
syntax::NodeRole R) {
 T->prependChildLowLevel(Child, R);
   }
+
+  static std::pair>
+  lexBuffer(syntax::Arena &A, std::unique_ptr Buffer) {
+return A.lexBuffer(std::move(Buffer));
+  }
 };
 
 syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, tok::TokenKind K,
 StringRef Spelling) {
-  auto Tokens = A.lexBuffer(llvm::MemoryBuffer::getMemBuffer(Spelling)).second;
+  auto Tokens =
+  FactoryImpl::lexBuffer(A, llvm::MemoryBuffer::getMemBuffer(Spelling))
+  .second;
   assert(Tokens.size() == 1);
   assert(Tokens.front().kind() == K &&
  "spelling is not lexed into the expected kind of token");



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 238ae4e - [SyntaxTree] Add const qualifiers, from [llvm-qualified-auto]

2020-09-11 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-11T18:39:02Z
New Revision: 238ae4eee05187758e42c00af237592612d585c2

URL: 
https://github.com/llvm/llvm-project/commit/238ae4eee05187758e42c00af237592612d585c2
DIFF: 
https://github.com/llvm/llvm-project/commit/238ae4eee05187758e42c00af237592612d585c2.diff

LOG: [SyntaxTree] Add const qualifiers, from [llvm-qualified-auto]

Differential Revision: https://reviews.llvm.org/D87522

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/ComputeReplacements.cpp
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 8de50dd02162..dab1457fbdba 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -558,7 +558,7 @@ class syntax::TreeBuilder {
   assert(A.getTokenBuffer().expandedTokens().back().kind() == tok::eof);
   // Create all leaf nodes.
   // Note that we do not have 'eof' in the tree.
-  for (auto &T : A.getTokenBuffer().expandedTokens().drop_back()) {
+  for (const auto &T : A.getTokenBuffer().expandedTokens().drop_back()) {
 auto *L = new (A.getAllocator()) syntax::Leaf(&T);
 L->Original = true;
 L->CanModify = A.getTokenBuffer().spelledForExpanded(T).hasValue();

diff  --git a/clang/lib/Tooling/Syntax/ComputeReplacements.cpp 
b/clang/lib/Tooling/Syntax/ComputeReplacements.cpp
index 93b1c4416bf4..31e1a40c74b6 100644
--- a/clang/lib/Tooling/Syntax/ComputeReplacements.cpp
+++ b/clang/lib/Tooling/Syntax/ComputeReplacements.cpp
@@ -32,7 +32,7 @@ void enumerateTokenSpans(const syntax::Tree *Root, 
ProcessTokensFn Callback) {
   private:
 void process(const syntax::Node *N) {
   if (auto *T = dyn_cast(N)) {
-for (auto *C = T->getFirstChild(); C != nullptr;
+for (const auto *C = T->getFirstChild(); C != nullptr;
  C = C->getNextSibling())
   process(C);
 return;
@@ -64,8 +64,8 @@ void enumerateTokenSpans(const syntax::Tree *Root, 
ProcessTokensFn Callback) {
 
 syntax::FileRange rangeOfExpanded(const syntax::Arena &A,
   llvm::ArrayRef Expanded) {
-  auto &Buffer = A.getTokenBuffer();
-  auto &SM = A.getSourceManager();
+  const auto &Buffer = A.getTokenBuffer();
+  const auto &SM = A.getSourceManager();
 
   // Check that \p Expanded actually points into expanded tokens.
   assert(Buffer.expandedTokens().begin() <= Expanded.begin());
@@ -85,8 +85,8 @@ syntax::FileRange rangeOfExpanded(const syntax::Arena &A,
 tooling::Replacements
 syntax::computeReplacements(const syntax::Arena &A,
 const syntax::TranslationUnit &TU) {
-  auto &Buffer = A.getTokenBuffer();
-  auto &SM = A.getSourceManager();
+  const auto &Buffer = A.getTokenBuffer();
+  const auto &SM = A.getSourceManager();
 
   tooling::Replacements Replacements;
   // Text inserted by the replacement we are building now.

diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index f9d1fa6110ff..ca1e2880af9f 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -19,7 +19,7 @@ namespace {
 static void traverse(const syntax::Node *N,
  llvm::function_ref Visit) {
   if (auto *T = dyn_cast(N)) {
-for (auto *C = T->getFirstChild(); C; C = C->getNextSibling())
+for (const auto *C = T->getFirstChild(); C; C = C->getNextSibling())
   traverse(C, Visit);
   }
   Visit(N);
@@ -226,7 +226,7 @@ void syntax::Node::assertInvariants() const {
   auto *T = dyn_cast(this);
   if (!T)
 return;
-  for (auto *C = T->getFirstChild(); C; C = C->getNextSibling()) {
+  for (const auto *C = T->getFirstChild(); C; C = C->getNextSibling()) {
 if (T->isOriginal())
   assert(C->isOriginal());
 assert(!C->isDetached());



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 7c37b82 - [SyntaxTree][Synthesis] Add support for Tree.

2020-09-11 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-11T20:37:23Z
New Revision: 7c37b82f5ba5883b331608b0077c0b30bf301874

URL: 
https://github.com/llvm/llvm-project/commit/7c37b82f5ba5883b331608b0077c0b30bf301874
DIFF: 
https://github.com/llvm/llvm-project/commit/7c37b82f5ba5883b331608b0077c0b30bf301874.diff

LOG: [SyntaxTree][Synthesis] Add support for Tree.

In a future patch
* Implement helper function to generate Trees for tests
* and test Tree methods, namely `findFirstLeaf` and `findLastLeaf`

Differential Revision: https://reviews.llvm.org/D87533

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/BuildTree.h
clang/lib/Tooling/Syntax/Synthesis.cpp
clang/unittests/Tooling/Syntax/SynthesisTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/BuildTree.h 
b/clang/include/clang/Tooling/Syntax/BuildTree.h
index c2ae4348bc16..b9405167bf99 100644
--- a/clang/include/clang/Tooling/Syntax/BuildTree.h
+++ b/clang/include/clang/Tooling/Syntax/BuildTree.h
@@ -34,6 +34,12 @@ syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K,
 /// this token
 syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K);
 
+// Synthesis of Trees
+syntax::Tree *
+createTree(Arena &A,
+   std::vector> Children,
+   syntax::NodeKind K);
+
 // Synthesis of Syntax Nodes
 clang::syntax::EmptyStatement *createEmptyStatement(clang::syntax::Arena &A);
 

diff  --git a/clang/lib/Tooling/Syntax/Synthesis.cpp 
b/clang/lib/Tooling/Syntax/Synthesis.cpp
index 772429ff4c46..6de3d5b5752d 100644
--- a/clang/lib/Tooling/Syntax/Synthesis.cpp
+++ b/clang/lib/Tooling/Syntax/Synthesis.cpp
@@ -52,6 +52,20 @@ syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, 
tok::TokenKind K) {
   return createLeaf(A, K, Spelling);
 }
 
+syntax::Tree *clang::syntax::createTree(
+syntax::Arena &A,
+std::vector> Children,
+syntax::NodeKind K) {
+  auto *T = new (A.getAllocator()) syntax::Tree(K);
+  FactoryImpl::setCanModify(T);
+  for (auto ChildIt = Children.rbegin(); ChildIt != Children.rend();
+   std::advance(ChildIt, 1))
+FactoryImpl::prependChildLowLevel(T, ChildIt->first, ChildIt->second);
+
+  T->assertInvariants();
+  return T;
+}
+
 syntax::EmptyStatement *clang::syntax::createEmptyStatement(syntax::Arena &A) {
   auto *S = new (A.getAllocator()) syntax::EmptyStatement;
   FactoryImpl::setCanModify(S);

diff  --git a/clang/unittests/Tooling/Syntax/SynthesisTest.cpp 
b/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
index 1c1aef8bd8c8..a882714ccf33 100644
--- a/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
+++ b/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
@@ -12,6 +12,7 @@
 
 #include "TreeTestBase.h"
 #include "clang/Tooling/Syntax/BuildTree.h"
+#include "clang/Tooling/Syntax/Nodes.h"
 #include "gtest/gtest.h"
 
 using namespace clang;
@@ -80,6 +81,62 @@ TEST_P(SynthesisTest, Leaf_Number) {
   )txt"));
 }
 
+TEST_P(SynthesisTest, Tree_Empty) {
+  buildTree("", GetParam());
+
+  auto *Tree = createTree(*Arena, {}, NodeKind::UnknownExpression);
+
+  EXPECT_TRUE(treeDumpEqual(Tree, R"txt(
+UnknownExpression Detached synthesized
+  )txt"));
+}
+
+TEST_P(SynthesisTest, Tree_Flat) {
+  buildTree("", GetParam());
+
+  auto *LeafLParen = createLeaf(*Arena, tok::l_paren);
+  auto *LeafRParen = createLeaf(*Arena, tok::r_paren);
+  auto *TreeParen = createTree(*Arena,
+   {{LeafLParen, NodeRole::LeftHandSide},
+{LeafRParen, NodeRole::RightHandSide}},
+   NodeKind::ParenExpression);
+
+  EXPECT_TRUE(treeDumpEqual(TreeParen, R"txt(
+ParenExpression Detached synthesized
+|-'(' LeftHandSide synthesized
+`-')' RightHandSide synthesized
+  )txt"));
+}
+
+TEST_P(SynthesisTest, Tree_OfTree) {
+  buildTree("", GetParam());
+
+  auto *Leaf1 = createLeaf(*Arena, tok::numeric_constant, "1");
+  auto *Int1 = createTree(*Arena, {{Leaf1, NodeRole::LiteralToken}},
+  NodeKind::IntegerLiteralExpression);
+
+  auto *LeafPlus = createLeaf(*Arena, tok::plus);
+
+  auto *Leaf2 = createLeaf(*Arena, tok::numeric_constant, "2");
+  auto *Int2 = createTree(*Arena, {{Leaf2, NodeRole::LiteralToken}},
+  NodeKind::IntegerLiteralExpression);
+
+  auto *TreeBinaryOperator = createTree(*Arena,
+{{Int1, NodeRole::LeftHandSide},
+ {LeafPlus, NodeRole::OperatorToken},
+ {Int2, NodeRole::RightHandSide}},
+NodeKind::BinaryOperatorExpression);
+
+  EXPECT_TRUE(treeDumpEqual(TreeBinaryOperator, R"txt(
+BinaryOperatorExpression Detached synthesized
+|-IntegerLiteralExpression LeftHandSide synthesized
+| `-'1' LiteralToken synthesized
+|-'+' OperatorToken synthesized
+`-IntegerLiteralExpression RightHandSide synthesized
+  `-'2' LiteralToken synthesized

[clang] 12232dc - [SyntaxTree][List] Fix: `ParameterDeclarationList` is the `List` inside `ParametersAndQualifiers`

2020-09-14 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-14T10:35:41Z
New Revision: 12232dc181cbe78fbd40a6ed1a89795a2c9a1154

URL: 
https://github.com/llvm/llvm-project/commit/12232dc181cbe78fbd40a6ed1a89795a2c9a1154
DIFF: 
https://github.com/llvm/llvm-project/commit/12232dc181cbe78fbd40a6ed1a89795a2c9a1154.diff

LOG: [SyntaxTree][List] Fix: `ParameterDeclarationList` is the `List` inside 
`ParametersAndQualifiers`

Differential Revision: https://reviews.llvm.org/D87598

Added: 


Modified: 
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index ca1e2880af9f..2bff159696c1 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -366,7 +366,7 @@ clang::tok::TokenKind syntax::List::getDelimiterTokenKind() 
{
   case NodeKind::NestedNameSpecifier:
 return clang::tok::coloncolon;
   case NodeKind::CallArguments:
-  case NodeKind::ParametersAndQualifiers:
+  case NodeKind::ParameterDeclarationList:
 return clang::tok::comma;
   default:
 llvm_unreachable("This is not a subclass of List, thus "
@@ -379,7 +379,7 @@ syntax::List::TerminationKind 
syntax::List::getTerminationKind() {
   case NodeKind::NestedNameSpecifier:
 return TerminationKind::Terminated;
   case NodeKind::CallArguments:
-  case NodeKind::ParametersAndQualifiers:
+  case NodeKind::ParameterDeclarationList:
 return TerminationKind::Separated;
   default:
 llvm_unreachable("This is not a subclass of List, thus "
@@ -393,7 +393,7 @@ bool syntax::List::canBeEmpty() {
 return false;
   case NodeKind::CallArguments:
 return true;
-  case NodeKind::ParametersAndQualifiers:
+  case NodeKind::ParameterDeclarationList:
 return true;
   default:
 llvm_unreachable("This is not a subclass of List, thus canBeEmpty() "



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 0f4cc64 - [SyntaxTree] Provide `List::classof`

2020-09-14 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-14T10:35:41Z
New Revision: 0f4cc64fd747fbb33aeccfaccb8873762d2511f2

URL: 
https://github.com/llvm/llvm-project/commit/0f4cc64fd747fbb33aeccfaccb8873762d2511f2
DIFF: 
https://github.com/llvm/llvm-project/commit/0f4cc64fd747fbb33aeccfaccb8873762d2511f2.diff

LOG: [SyntaxTree] Provide `List::classof`

Differential Revision: https://reviews.llvm.org/D87599

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Tree.h
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Tree.h 
b/clang/include/clang/Tooling/Syntax/Tree.h
index b49a09344c0f..5a09d4564969 100644
--- a/clang/include/clang/Tooling/Syntax/Tree.h
+++ b/clang/include/clang/Tooling/Syntax/Tree.h
@@ -213,6 +213,7 @@ class List : public Tree {
   };
 
   using Tree::Tree;
+  static bool classof(const Node *N);
   /// Returns the elements and corresponding delimiters. Missing elements
   /// and delimiters are represented as null pointers.
   ///

diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index 2bff159696c1..1c705f6fd7cf 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -273,6 +273,17 @@ syntax::Node *syntax::Tree::findChild(NodeRole R) {
   return nullptr;
 }
 
+bool classof(const syntax::Node *N) {
+  switch (N->getKind()) {
+  case syntax::NodeKind::NestedNameSpecifier:
+  case syntax::NodeKind::CallArguments:
+  case syntax::NodeKind::ParameterDeclarationList:
+return true;
+  default:
+return false;
+  }
+}
+
 std::vector>
 syntax::List::getElementsAsNodesAndDelimiters() {
   if (!getFirstChild())



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] ceb0128 - [SyntaxTree][List] `assertInvariants` for `List`s

2020-09-14 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-14T10:36:11Z
New Revision: ceb0128509c51100afbf804bda84d82b7ebe06b1

URL: 
https://github.com/llvm/llvm-project/commit/ceb0128509c51100afbf804bda84d82b7ebe06b1
DIFF: 
https://github.com/llvm/llvm-project/commit/ceb0128509c51100afbf804bda84d82b7ebe06b1.diff

LOG: [SyntaxTree][List] `assertInvariants` for `List`s

Differential Revision: https://reviews.llvm.org/D87600

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Tree.h
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Tree.h 
b/clang/include/clang/Tooling/Syntax/Tree.h
index 5a09d4564969..a544fc1827b7 100644
--- a/clang/include/clang/Tooling/Syntax/Tree.h
+++ b/clang/include/clang/Tooling/Syntax/Tree.h
@@ -237,16 +237,16 @@ class List : public Tree {
   ///
   /// Useful for discovering the correct delimiter to use when adding
   /// elements to empty or one-element lists.
-  clang::tok::TokenKind getDelimiterTokenKind();
+  clang::tok::TokenKind getDelimiterTokenKind() const;
 
-  TerminationKind getTerminationKind();
+  TerminationKind getTerminationKind() const;
 
   /// Whether this list can be empty in syntactically and semantically correct
   /// code.
   ///
   /// This list may be empty when the source code has errors even if
   /// canBeEmpty() returns false.
-  bool canBeEmpty();
+  bool canBeEmpty() const;
 };
 
 } // namespace syntax

diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index 1c705f6fd7cf..1edd2583105a 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -223,7 +223,7 @@ void syntax::Node::assertInvariants() const {
   else
 assert(getParent() != nullptr);
 
-  auto *T = dyn_cast(this);
+  const auto *T = dyn_cast(this);
   if (!T)
 return;
   for (const auto *C = T->getFirstChild(); C; C = C->getNextSibling()) {
@@ -232,6 +232,19 @@ void syntax::Node::assertInvariants() const {
 assert(!C->isDetached());
 assert(C->getParent() == T);
   }
+
+  const auto *L = dyn_cast(T);
+  if (!L)
+return;
+  for (const auto *C = T->getFirstChild(); C; C = C->getNextSibling()) {
+assert(C->getRole() == NodeRole::ListElement ||
+   C->getRole() == NodeRole::ListDelimiter);
+if (C->getRole() == NodeRole::ListDelimiter) {
+  assert(isa(C));
+  assert(cast(C)->getToken()->kind() == L->getDelimiterTokenKind());
+}
+  }
+
 #endif
 }
 
@@ -273,7 +286,7 @@ syntax::Node *syntax::Tree::findChild(NodeRole R) {
   return nullptr;
 }
 
-bool classof(const syntax::Node *N) {
+bool syntax::List::classof(const syntax::Node *N) {
   switch (N->getKind()) {
   case syntax::NodeKind::NestedNameSpecifier:
   case syntax::NodeKind::CallArguments:
@@ -372,7 +385,7 @@ std::vector 
syntax::List::getElementsAsNodes() {
   return children;
 }
 
-clang::tok::TokenKind syntax::List::getDelimiterTokenKind() {
+clang::tok::TokenKind syntax::List::getDelimiterTokenKind() const {
   switch (this->getKind()) {
   case NodeKind::NestedNameSpecifier:
 return clang::tok::coloncolon;
@@ -385,7 +398,7 @@ clang::tok::TokenKind syntax::List::getDelimiterTokenKind() 
{
   }
 }
 
-syntax::List::TerminationKind syntax::List::getTerminationKind() {
+syntax::List::TerminationKind syntax::List::getTerminationKind() const {
   switch (this->getKind()) {
   case NodeKind::NestedNameSpecifier:
 return TerminationKind::Terminated;
@@ -398,7 +411,7 @@ syntax::List::TerminationKind 
syntax::List::getTerminationKind() {
   }
 }
 
-bool syntax::List::canBeEmpty() {
+bool syntax::List::canBeEmpty() const {
   switch (this->getKind()) {
   case NodeKind::NestedNameSpecifier:
 return false;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 1e19165 - [SyntaxTree][Synthesis] Fix allocation in `createTree` for more general use

2020-09-17 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-17T16:09:35Z
New Revision: 1e19165bd89db6671a80e0b25b32d5c7ae79455c

URL: 
https://github.com/llvm/llvm-project/commit/1e19165bd89db6671a80e0b25b32d5c7ae79455c
DIFF: 
https://github.com/llvm/llvm-project/commit/1e19165bd89db6671a80e0b25b32d5c7ae79455c.diff

LOG: [SyntaxTree][Synthesis] Fix allocation in `createTree` for more general use

Prior to this change `createTree` could not create arbitrary syntax
trees. Now it dispatches to the constructor of the concrete syntax tree
according to the `NodeKind` passed as argument. This allows reuse inside
the Synthesis API.  # Please enter the commit message for your changes.
Lines starting

Differential Revision: https://reviews.llvm.org/D87820

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/BuildTree.h
clang/lib/Tooling/Syntax/Synthesis.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/BuildTree.h 
b/clang/include/clang/Tooling/Syntax/BuildTree.h
index b9405167bf99..452edf580ae1 100644
--- a/clang/include/clang/Tooling/Syntax/BuildTree.h
+++ b/clang/include/clang/Tooling/Syntax/BuildTree.h
@@ -35,13 +35,15 @@ syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K,
 syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K);
 
 // Synthesis of Trees
+/// Creates the concrete syntax node according to the specified `NodeKind` `K`.
+/// Returns it as a pointer to the base class `Tree`.
 syntax::Tree *
-createTree(Arena &A,
+createTree(syntax::Arena &A,
std::vector> Children,
syntax::NodeKind K);
 
 // Synthesis of Syntax Nodes
-clang::syntax::EmptyStatement *createEmptyStatement(clang::syntax::Arena &A);
+syntax::EmptyStatement *createEmptyStatement(syntax::Arena &A);
 
 } // namespace syntax
 } // namespace clang

diff  --git a/clang/lib/Tooling/Syntax/Synthesis.cpp 
b/clang/lib/Tooling/Syntax/Synthesis.cpp
index 6de3d5b5752d..2fe95a40cb32 100644
--- a/clang/lib/Tooling/Syntax/Synthesis.cpp
+++ b/clang/lib/Tooling/Syntax/Synthesis.cpp
@@ -52,11 +52,144 @@ syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, 
tok::TokenKind K) {
   return createLeaf(A, K, Spelling);
 }
 
+namespace {
+// Allocates the concrete syntax `Tree` according to its `NodeKind`.
+syntax::Tree *allocateTree(syntax::Arena &A, syntax::NodeKind Kind) {
+  switch (Kind) {
+  case syntax::NodeKind::Leaf:
+assert(false);
+  case syntax::NodeKind::TranslationUnit:
+return new (A.getAllocator()) syntax::TranslationUnit;
+  case syntax::NodeKind::UnknownExpression:
+return new (A.getAllocator()) syntax::UnknownExpression;
+  case syntax::NodeKind::ParenExpression:
+return new (A.getAllocator()) syntax::ParenExpression;
+  case syntax::NodeKind::ThisExpression:
+return new (A.getAllocator()) syntax::ThisExpression;
+  case syntax::NodeKind::IntegerLiteralExpression:
+return new (A.getAllocator()) syntax::IntegerLiteralExpression;
+  case syntax::NodeKind::CharacterLiteralExpression:
+return new (A.getAllocator()) syntax::CharacterLiteralExpression;
+  case syntax::NodeKind::FloatingLiteralExpression:
+return new (A.getAllocator()) syntax::FloatingLiteralExpression;
+  case syntax::NodeKind::StringLiteralExpression:
+return new (A.getAllocator()) syntax::StringLiteralExpression;
+  case syntax::NodeKind::BoolLiteralExpression:
+return new (A.getAllocator()) syntax::BoolLiteralExpression;
+  case syntax::NodeKind::CxxNullPtrExpression:
+return new (A.getAllocator()) syntax::CxxNullPtrExpression;
+  case syntax::NodeKind::IntegerUserDefinedLiteralExpression:
+return new (A.getAllocator()) syntax::IntegerUserDefinedLiteralExpression;
+  case syntax::NodeKind::FloatUserDefinedLiteralExpression:
+return new (A.getAllocator()) syntax::FloatUserDefinedLiteralExpression;
+  case syntax::NodeKind::CharUserDefinedLiteralExpression:
+return new (A.getAllocator()) syntax::CharUserDefinedLiteralExpression;
+  case syntax::NodeKind::StringUserDefinedLiteralExpression:
+return new (A.getAllocator()) syntax::StringUserDefinedLiteralExpression;
+  case syntax::NodeKind::PrefixUnaryOperatorExpression:
+return new (A.getAllocator()) syntax::PrefixUnaryOperatorExpression;
+  case syntax::NodeKind::PostfixUnaryOperatorExpression:
+return new (A.getAllocator()) syntax::PostfixUnaryOperatorExpression;
+  case syntax::NodeKind::BinaryOperatorExpression:
+return new (A.getAllocator()) syntax::BinaryOperatorExpression;
+  case syntax::NodeKind::UnqualifiedId:
+return new (A.getAllocator()) syntax::UnqualifiedId;
+  case syntax::NodeKind::IdExpression:
+return new (A.getAllocator()) syntax::IdExpression;
+  case syntax::NodeKind::CallExpression:
+return new (A.getAllocator()) syntax::CallExpression;
+  case syntax::NodeKind::UnknownStatement:
+return new (A.getAllocator()) syntax::UnknownStatement;
+  case syntax::NodeKind::DeclarationStatement:
+r

[clang] bb5b28f - [SyntaxTree][Synthesis] Improve testing `createLeaf`

2020-09-20 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-21T06:11:46Z
New Revision: bb5b28f12fbd029773dc93d18a82ef42f4889b2a

URL: 
https://github.com/llvm/llvm-project/commit/bb5b28f12fbd029773dc93d18a82ef42f4889b2a
DIFF: 
https://github.com/llvm/llvm-project/commit/bb5b28f12fbd029773dc93d18a82ef42f4889b2a.diff

LOG: [SyntaxTree][Synthesis] Improve testing `createLeaf`

The new test shows that `createLeaf` depends on the C++ version.

Differential Revision: https://reviews.llvm.org/D87896

Added: 


Modified: 
clang/unittests/Tooling/Syntax/SynthesisTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/SynthesisTest.cpp 
b/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
index a882714ccf33..8d9fb706eac3 100644
--- a/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
+++ b/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
@@ -51,6 +51,19 @@ TEST_P(SynthesisTest, Leaf_Punctuation) {
   )txt"));
 }
 
+TEST_P(SynthesisTest, Leaf_Punctuation_CXX) {
+  if (!GetParam().isCXX())
+return;
+
+  buildTree("", GetParam());
+
+  auto *Leaf = createLeaf(*Arena, tok::coloncolon);
+
+  EXPECT_TRUE(treeDumpEqual(Leaf, R"txt(
+'::' Detached synthesized
+  )txt"));
+}
+
 TEST_P(SynthesisTest, Leaf_Keyword) {
   buildTree("", GetParam());
 
@@ -61,6 +74,19 @@ TEST_P(SynthesisTest, Leaf_Keyword) {
   )txt"));
 }
 
+TEST_P(SynthesisTest, Leaf_Keyword_CXX11) {
+  if (!GetParam().isCXX11OrLater())
+return;
+
+  buildTree("", GetParam());
+
+  auto *Leaf = createLeaf(*Arena, tok::kw_nullptr);
+
+  EXPECT_TRUE(treeDumpEqual(Leaf, R"txt(
+'nullptr' Detached synthesized
+  )txt"));
+}
+
 TEST_P(SynthesisTest, Leaf_Identifier) {
   buildTree("", GetParam());
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] e616a42 - [SyntaxTree] Test for '\' inside token.

2020-09-20 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-21T06:56:14Z
New Revision: e616a4259889b55ed1bf5bf095f0e59658c6e311

URL: 
https://github.com/llvm/llvm-project/commit/e616a4259889b55ed1bf5bf095f0e59658c6e311
DIFF: 
https://github.com/llvm/llvm-project/commit/e616a4259889b55ed1bf5bf095f0e59658c6e311.diff

LOG: [SyntaxTree] Test for '\' inside token.

Differential Revision: https://reviews.llvm.org/D87895

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 95ebeb2c5940..52bd5988b44e 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -167,6 +167,23 @@ TranslationUnit Detached
 )txt"));
 }
 
+TEST_P(BuildSyntaxTreeTest, Simple_BackslashInsideToken) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+in\
+t a;
+)cpp",
+  R"txt(
+TranslationUnit Detached
+`-SimpleDeclaration
+  |-'in\
+t'
+  |-SimpleDeclarator Declarator
+  | `-'a'
+  `-';'
+)txt"));
+}
+
 TEST_P(BuildSyntaxTreeTest, If) {
   EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 4a5cc38 - [SyntaxTree][Synthesis] Implement `deepCopy`

2020-09-21 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-21T09:27:15Z
New Revision: 4a5cc389c51d267f39286a9a8c58c32f758b9d4b

URL: 
https://github.com/llvm/llvm-project/commit/4a5cc389c51d267f39286a9a8c58c32f758b9d4b
DIFF: 
https://github.com/llvm/llvm-project/commit/4a5cc389c51d267f39286a9a8c58c32f758b9d4b.diff

LOG: [SyntaxTree][Synthesis] Implement `deepCopy`

Differential Revision: https://reviews.llvm.org/D87749

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/BuildTree.h
clang/lib/Tooling/Syntax/Synthesis.cpp
clang/unittests/Tooling/Syntax/SynthesisTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/BuildTree.h 
b/clang/include/clang/Tooling/Syntax/BuildTree.h
index 452edf580ae1..7b36dff123f6 100644
--- a/clang/include/clang/Tooling/Syntax/BuildTree.h
+++ b/clang/include/clang/Tooling/Syntax/BuildTree.h
@@ -45,6 +45,17 @@ createTree(syntax::Arena &A,
 // Synthesis of Syntax Nodes
 syntax::EmptyStatement *createEmptyStatement(syntax::Arena &A);
 
+/// Creates a completely independent copy of `N` (a deep copy).
+///
+/// The copy is:
+/// * Detached, i.e. `Parent == NextSibling == nullptr` and
+/// `Role == Detached`.
+/// * Synthesized, i.e. `Original == false`.
+///
+/// `N` might be backed by source code but if any descendants of `N` are
+/// unmodifiable returns `nullptr`.
+syntax::Node *deepCopy(syntax::Arena &A, const syntax::Node *N);
+
 } // namespace syntax
 } // namespace clang
 #endif

diff  --git a/clang/lib/Tooling/Syntax/Synthesis.cpp 
b/clang/lib/Tooling/Syntax/Synthesis.cpp
index f171d26512d9..c8fcac27e0d5 100644
--- a/clang/lib/Tooling/Syntax/Synthesis.cpp
+++ b/clang/lib/Tooling/Syntax/Synthesis.cpp
@@ -28,10 +28,12 @@ class clang::syntax::FactoryImpl {
   }
 };
 
+// FIXME: `createLeaf` is based on `syntax::tokenize` internally, as such it
+// doesn't support digraphs or line continuations.
 syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, tok::TokenKind K,
 StringRef Spelling) {
   auto Tokens =
-  FactoryImpl::lexBuffer(A, llvm::MemoryBuffer::getMemBuffer(Spelling))
+  FactoryImpl::lexBuffer(A, llvm::MemoryBuffer::getMemBufferCopy(Spelling))
   .second;
   assert(Tokens.size() == 1);
   assert(Tokens.front().kind() == K &&
@@ -192,14 +194,52 @@ syntax::Tree *clang::syntax::createTree(
 syntax::NodeKind K) {
   auto *T = allocateTree(A, K);
   FactoryImpl::setCanModify(T);
-  for (auto ChildIt = Children.rbegin(); ChildIt != Children.rend();
-   std::advance(ChildIt, 1))
+  for (auto ChildIt = Children.rbegin(); ChildIt != Children.rend(); ++ChildIt)
 FactoryImpl::prependChildLowLevel(T, ChildIt->first, ChildIt->second);
 
   T->assertInvariants();
   return T;
 }
 
+namespace {
+bool canModifyAllDescendants(const syntax::Node *N) {
+  if (const auto *L = dyn_cast(N))
+return L->canModify();
+
+  const auto *T = cast(N);
+
+  if (!T->canModify())
+return false;
+  for (const auto *Child = T->getFirstChild(); Child;
+   Child = Child->getNextSibling())
+if (!canModifyAllDescendants(Child))
+  return false;
+
+  return true;
+}
+
+syntax::Node *deepCopyImpl(syntax::Arena &A, const syntax::Node *N) {
+  if (const auto *L = dyn_cast(N))
+return createLeaf(A, L->getToken()->kind(),
+  L->getToken()->text(A.getSourceManager()));
+
+  const auto *T = cast(N);
+  std::vector> Children;
+  for (const auto *Child = T->getFirstChild(); Child;
+   Child = Child->getNextSibling())
+Children.push_back({deepCopyImpl(A, Child), Child->getRole()});
+
+  return createTree(A, Children, N->getKind());
+}
+} // namespace
+
+syntax::Node *clang::syntax::deepCopy(syntax::Arena &A, const Node *N) {
+  if (!canModifyAllDescendants(N))
+return nullptr;
+
+  return deepCopyImpl(A, N);
+}
+
 syntax::EmptyStatement *clang::syntax::createEmptyStatement(syntax::Arena &A) {
   return cast(
   createTree(A, {{createLeaf(A, tok::semi), NodeRole::Unknown}},

diff  --git a/clang/unittests/Tooling/Syntax/SynthesisTest.cpp 
b/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
index 8d9fb706eac3..2af1fcf8f317 100644
--- a/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
+++ b/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
@@ -163,6 +163,63 @@ BinaryOperatorExpression Detached synthesized
   )txt"));
 }
 
+TEST_P(SynthesisTest, DeepCopy_Synthesized) {
+  buildTree("", GetParam());
+
+  auto *LeafContinue = createLeaf(*Arena, tok::kw_continue);
+  auto *LeafSemiColon = createLeaf(*Arena, tok::semi);
+  auto *StatementContinue = createTree(*Arena,
+   {{LeafContinue, NodeRole::LiteralToken},
+{LeafSemiColon, NodeRole::Unknown}},
+   NodeKind::ContinueStatement);
+
+  auto *Copy = deepCopy(*Arena, StatementContinue);
+  EXPECT_TRUE(
+  treeDumpEqual(Copy, StatementCont

[clang] 87f0b51 - [SyntaxTree][NFC] follow naming convention + remove auto on empty vector declaration

2020-09-21 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-21T11:45:15Z
New Revision: 87f0b51d68de40e7106be89d934b5191d983e3d5

URL: 
https://github.com/llvm/llvm-project/commit/87f0b51d68de40e7106be89d934b5191d983e3d5
DIFF: 
https://github.com/llvm/llvm-project/commit/87f0b51d68de40e7106be89d934b5191d983e3d5.diff

LOG: [SyntaxTree][NFC] follow naming convention + remove auto on empty vector 
declaration

Differential Revision: https://reviews.llvm.org/D88004

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 3e0573ac4ffc..4d365090abf1 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -155,10 +155,10 @@ struct GetStartLoc : TypeLocVisitor {
 } // namespace
 
 static CallExpr::arg_range dropDefaultArgs(CallExpr::arg_range Args) {
-  auto firstDefaultArg = std::find_if(Args.begin(), Args.end(), [](auto it) {
-return isa(it);
+  auto FirstDefaultArg = std::find_if(Args.begin(), Args.end(), [](auto It) {
+return isa(It);
   });
-  return llvm::make_range(Args.begin(), firstDefaultArg);
+  return llvm::make_range(Args.begin(), FirstDefaultArg);
 }
 
 static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E) {
@@ -954,12 +954,12 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc) {
 if (!QualifierLoc)
   return true;
-for (auto it = QualifierLoc; it; it = it.getPrefix()) {
-  auto *NS = buildNameSpecifier(it);
+for (auto It = QualifierLoc; It; It = It.getPrefix()) {
+  auto *NS = buildNameSpecifier(It);
   if (!NS)
 return false;
   Builder.markChild(NS, syntax::NodeRole::ListElement);
-  Builder.markChildToken(it.getEndLoc(), syntax::NodeRole::ListDelimiter);
+  Builder.markChildToken(It.getEndLoc(), syntax::NodeRole::ListDelimiter);
 }
 Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()),
  new (allocator()) syntax::NestedNameSpecifier,

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index bb63585cbd7c..24b7a8596382 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -226,23 +226,23 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole 
R) {
 // vector
 std::vector
 syntax::NestedNameSpecifier::getSpecifiers() {
-  auto specifiersAsNodes = getElementsAsNodes();
+  auto SpecifiersAsNodes = getElementsAsNodes();
   std::vector Children;
-  for (const auto &element : specifiersAsNodes) {
-Children.push_back(llvm::cast(element));
+  for (const auto &Element : SpecifiersAsNodes) {
+Children.push_back(llvm::cast(Element));
   }
   return Children;
 }
 
 std::vector>
 syntax::NestedNameSpecifier::getSpecifiersAndDoubleColons() {
-  auto specifiersAsNodesAndDoubleColons = getElementsAsNodesAndDelimiters();
+  auto SpecifiersAsNodesAndDoubleColons = getElementsAsNodesAndDelimiters();
   std::vector>
   Children;
-  for (const auto &specifierAndDoubleColon : specifiersAsNodesAndDoubleColons) 
{
+  for (const auto &SpecifierAndDoubleColon : SpecifiersAsNodesAndDoubleColons) 
{
 Children.push_back(
-{llvm::cast(specifierAndDoubleColon.element),
- specifierAndDoubleColon.delimiter});
+{llvm::cast(SpecifierAndDoubleColon.element),
+ SpecifierAndDoubleColon.delimiter});
   }
   return Children;
 }

diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index 1edd2583105a..2c77e8f64944 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -153,7 +153,7 @@ static void dumpLeaf(raw_ostream &OS, const syntax::Leaf *L,
 
 static void dumpNode(raw_ostream &OS, const syntax::Node *N,
  const SourceManager &SM, std::vector IndentMask) {
-  auto dumpExtraInfo = [&OS](const syntax::Node *N) {
+  auto DumpExtraInfo = [&OS](const syntax::Node *N) {
 if (N->getRole() != syntax::NodeRole::Unknown)
   OS << " " << N->getRole();
 if (!N->isOriginal())
@@ -167,14 +167,14 @@ static void dumpNode(raw_ostream &OS, const syntax::Node 
*N,
 OS << "'";
 dumpLeaf(OS, L, SM);
 OS << "'";
-dumpExtraInfo(N);
+DumpExtraInfo(N);
 OS << "\n";
 return;
   }
 
   const auto *T = cast(N);
   OS << T->getKind();
-  dumpExtraInfo(N);
+  DumpExtraInfo(N);
   OS << "\n";
 
   for (const auto *It = T->getFirstChild(); It; It = It->getNextSibling()) {
@@ -302,20 +302,20 @@ syntax::List::getElementsAsNodesAndDelimiters() {
   if (!getFirstChild())
 return {};
 
-  auto children = std::vector>();
-  syntax::Node *elementWithoutDelimiter = nullptr;
+  std::vector> Children;
+  syntax::Node *Elemen

[clang] af582c9 - [SyntaxTree] Test `findFirstLeaf` and `findLastLeaf`

2020-09-21 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-22T06:47:36Z
New Revision: af582c9b0f3a09b6a1b5101fd30dcbcef5c188b0

URL: 
https://github.com/llvm/llvm-project/commit/af582c9b0f3a09b6a1b5101fd30dcbcef5c188b0
DIFF: 
https://github.com/llvm/llvm-project/commit/af582c9b0f3a09b6a1b5101fd30dcbcef5c188b0.diff

LOG: [SyntaxTree] Test `findFirstLeaf` and `findLastLeaf`

* Introduce `TreeTest.cpp` to unit test `Tree.h`
* Add `generateAllTreesWithShape` to generating test cases
* Add tests for `findFirstLeaf` and `findLastLeaf`
* Fix implementations of `findFirstLeaf` and `findLastLeaf` that had
been broken when empty `Tree` were present.

Differential Revision: https://reviews.llvm.org/D87779

Added: 
clang/unittests/Tooling/Syntax/TreeTest.cpp

Modified: 
clang/lib/Tooling/Syntax/Tree.cpp
clang/unittests/Tooling/Syntax/CMakeLists.txt

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index 2c77e8f64944..b558e7ab9a1b 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -255,27 +255,24 @@ void syntax::Node::assertInvariantsRecursive() const {
 }
 
 syntax::Leaf *syntax::Tree::findFirstLeaf() {
-  auto *T = this;
-  while (auto *C = T->getFirstChild()) {
+  for (auto *C = getFirstChild(); C; C = C->getNextSibling()) {
 if (auto *L = dyn_cast(C))
   return L;
-T = cast(C);
+if (auto *L = cast(C)->findFirstLeaf())
+  return L;
   }
   return nullptr;
 }
 
 syntax::Leaf *syntax::Tree::findLastLeaf() {
-  auto *T = this;
-  while (auto *C = T->getFirstChild()) {
-// Find the last child.
-while (auto *Next = C->getNextSibling())
-  C = Next;
-
+  syntax::Leaf *Last = nullptr;
+  for (auto *C = getFirstChild(); C; C = C->getNextSibling()) {
 if (auto *L = dyn_cast(C))
-  return L;
-T = cast(C);
+  Last = L;
+else if (auto *L = cast(C)->findLastLeaf())
+  Last = L;
   }
-  return nullptr;
+  return Last;
 }
 
 syntax::Node *syntax::Tree::findChild(NodeRole R) {

diff  --git a/clang/unittests/Tooling/Syntax/CMakeLists.txt 
b/clang/unittests/Tooling/Syntax/CMakeLists.txt
index 34a480503def..174f3e7bf573 100644
--- a/clang/unittests/Tooling/Syntax/CMakeLists.txt
+++ b/clang/unittests/Tooling/Syntax/CMakeLists.txt
@@ -7,6 +7,7 @@ add_clang_unittest(SyntaxTests
   BuildTreeTest.cpp
   MutationsTest.cpp
   SynthesisTest.cpp
+  TreeTest.cpp
   TokensTest.cpp
 )
 

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
new file mode 100644
index ..2448db36a465
--- /dev/null
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -0,0 +1,125 @@
+//===- TreeTest.cpp -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "clang/Tooling/Syntax/Tree.h"
+#include "TreeTestBase.h"
+#include "clang/Tooling/Syntax/BuildTree.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace clang::syntax;
+
+namespace {
+
+class TreeTest : public SyntaxTreeTest {
+private:
+  Tree *createTree(ArrayRef Children) {
+std::vector> ChildrenWithRoles;
+ChildrenWithRoles.reserve(Children.size());
+for (const auto *Child : Children) {
+  ChildrenWithRoles.push_back(
+  std::make_pair(deepCopy(*Arena, Child), NodeRole::Unknown));
+}
+return clang::syntax::createTree(*Arena, ChildrenWithRoles,
+ NodeKind::UnknownExpression);
+  }
+
+  // Generate Forests by combining `Children` into `ParentCount` Trees.
+  //
+  // We do this recursively.
+  std::vector>
+  generateAllForests(ArrayRef Children, unsigned ParentCount) {
+assert(ParentCount > 0);
+// If there is only one Parent node, then combine `Children` under
+// this Parent.
+if (ParentCount == 1)
+  return {{createTree(Children)}};
+
+// Otherwise, combine `ChildrenCount` children under the last parent and
+// solve the smaller problem without these children and this parent. Do 
this
+// for every `ChildrenCount` and combine the results.
+std::vector> AllForests;
+for (unsigned ChildrenCount = 0; ChildrenCount <= Children.size();
+ ++ChildrenCount) {
+  auto *LastParent = createTree(Children.take_back(ChildrenCount));
+  for (auto &Forest : generateAllForests(Children.drop_back(ChildrenCount),
+ ParentCount - 1)) {
+Forest.push_back(LastParent);
+AllForests.push_back(Forest);
+  }
+}
+return AllForests;
+  }
+
+protected:
+  // Generates all trees with a `Base` of `Node`s and `NodeCountPerLayer`
+  // `Node`s pe

[clang] 1dc7836 - [SyntaxTree][Nit] Take `ArrayRef` instead of `std::vector` as argument for `createTree`

2020-09-21 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-22T06:47:36Z
New Revision: 1dc7836aed134b4543bad6aa54f15cc0e51a627f

URL: 
https://github.com/llvm/llvm-project/commit/1dc7836aed134b4543bad6aa54f15cc0e51a627f
DIFF: 
https://github.com/llvm/llvm-project/commit/1dc7836aed134b4543bad6aa54f15cc0e51a627f.diff

LOG: [SyntaxTree][Nit] Take `ArrayRef` instead of `std::vector` as argument for 
`createTree`

I also assured that there are no other functions unnecessarily using 
std::vector as argument.

Differential Revision: https://reviews.llvm.org/D88024

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/BuildTree.h
clang/lib/Tooling/Syntax/Synthesis.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/BuildTree.h 
b/clang/include/clang/Tooling/Syntax/BuildTree.h
index 7b36dff123f6..ab4868747e69 100644
--- a/clang/include/clang/Tooling/Syntax/BuildTree.h
+++ b/clang/include/clang/Tooling/Syntax/BuildTree.h
@@ -39,7 +39,7 @@ syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K);
 /// Returns it as a pointer to the base class `Tree`.
 syntax::Tree *
 createTree(syntax::Arena &A,
-   std::vector> Children,
+   ArrayRef> Children,
syntax::NodeKind K);
 
 // Synthesis of Syntax Nodes

diff  --git a/clang/lib/Tooling/Syntax/Synthesis.cpp 
b/clang/lib/Tooling/Syntax/Synthesis.cpp
index c8fcac27e0d5..9dc83f966d8c 100644
--- a/clang/lib/Tooling/Syntax/Synthesis.cpp
+++ b/clang/lib/Tooling/Syntax/Synthesis.cpp
@@ -190,7 +190,7 @@ syntax::Tree *allocateTree(syntax::Arena &A, 
syntax::NodeKind Kind) {
 
 syntax::Tree *clang::syntax::createTree(
 syntax::Arena &A,
-std::vector> Children,
+ArrayRef> Children,
 syntax::NodeKind K) {
   auto *T = allocateTree(A, K);
   FactoryImpl::setCanModify(T);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 66bcb14 - [SyntaxTree][Synthesis] Fix: `deepCopy` -> `deepCopyExpandingMacros`.

2020-09-22 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-22T09:15:21Z
New Revision: 66bcb14312a08b5d7e1197d23d748b2e23c4d852

URL: 
https://github.com/llvm/llvm-project/commit/66bcb14312a08b5d7e1197d23d748b2e23c4d852
DIFF: 
https://github.com/llvm/llvm-project/commit/66bcb14312a08b5d7e1197d23d748b2e23c4d852.diff

LOG: [SyntaxTree][Synthesis] Fix: `deepCopy` -> `deepCopyExpandingMacros`.

There can be Macros that are tagged with `modifiable`. Thus verifying
`canModifyAllDescendants` is not sufficient to avoid macros when deep
copying.

We think the `TokenBuffer` could inform us whether a `Token` comes from
a macro. We'll look into that when we can surface this information
easily, for instance in unit tests for `ComputeReplacements`.

Differential Revision: https://reviews.llvm.org/D88034

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/BuildTree.h
clang/lib/Tooling/Syntax/Synthesis.cpp
clang/unittests/Tooling/Syntax/SynthesisTest.cpp
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/BuildTree.h 
b/clang/include/clang/Tooling/Syntax/BuildTree.h
index ab4868747e69..537ade4b7151 100644
--- a/clang/include/clang/Tooling/Syntax/BuildTree.h
+++ b/clang/include/clang/Tooling/Syntax/BuildTree.h
@@ -45,17 +45,13 @@ createTree(syntax::Arena &A,
 // Synthesis of Syntax Nodes
 syntax::EmptyStatement *createEmptyStatement(syntax::Arena &A);
 
-/// Creates a completely independent copy of `N` (a deep copy).
+/// Creates a completely independent copy of `N` with its macros expanded.
 ///
 /// The copy is:
 /// * Detached, i.e. `Parent == NextSibling == nullptr` and
 /// `Role == Detached`.
 /// * Synthesized, i.e. `Original == false`.
-///
-/// `N` might be backed by source code but if any descendants of `N` are
-/// unmodifiable returns `nullptr`.
-syntax::Node *deepCopy(syntax::Arena &A, const syntax::Node *N);
-
+syntax::Node *deepCopyExpandingMacros(syntax::Arena &A, const syntax::Node *N);
 } // namespace syntax
 } // namespace clang
 #endif

diff  --git a/clang/lib/Tooling/Syntax/Synthesis.cpp 
b/clang/lib/Tooling/Syntax/Synthesis.cpp
index 9dc83f966d8c..e197c8d35bde 100644
--- a/clang/lib/Tooling/Syntax/Synthesis.cpp
+++ b/clang/lib/Tooling/Syntax/Synthesis.cpp
@@ -201,25 +201,11 @@ syntax::Tree *clang::syntax::createTree(
   return T;
 }
 
-namespace {
-bool canModifyAllDescendants(const syntax::Node *N) {
-  if (const auto *L = dyn_cast(N))
-return L->canModify();
-
-  const auto *T = cast(N);
-
-  if (!T->canModify())
-return false;
-  for (const auto *Child = T->getFirstChild(); Child;
-   Child = Child->getNextSibling())
-if (!canModifyAllDescendants(Child))
-  return false;
-
-  return true;
-}
-
-syntax::Node *deepCopyImpl(syntax::Arena &A, const syntax::Node *N) {
+syntax::Node *clang::syntax::deepCopyExpandingMacros(syntax::Arena &A,
+ const syntax::Node *N) {
   if (const auto *L = dyn_cast(N))
+// `L->getToken()` gives us the expanded token, thus we implicitly expand
+// any macros here.
 return createLeaf(A, L->getToken()->kind(),
   L->getToken()->text(A.getSourceManager()));
 
@@ -227,18 +213,10 @@ syntax::Node *deepCopyImpl(syntax::Arena &A, const 
syntax::Node *N) {
   std::vector> Children;
   for (const auto *Child = T->getFirstChild(); Child;
Child = Child->getNextSibling())
-Children.push_back({deepCopyImpl(A, Child), Child->getRole()});
+Children.push_back({deepCopyExpandingMacros(A, Child), Child->getRole()});
 
   return createTree(A, Children, N->getKind());
 }
-} // namespace
-
-syntax::Node *clang::syntax::deepCopy(syntax::Arena &A, const Node *N) {
-  if (!canModifyAllDescendants(N))
-return nullptr;
-
-  return deepCopyImpl(A, N);
-}
 
 syntax::EmptyStatement *clang::syntax::createEmptyStatement(syntax::Arena &A) {
   return cast(

diff  --git a/clang/unittests/Tooling/Syntax/SynthesisTest.cpp 
b/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
index 2af1fcf8f317..7f67b4e2e203 100644
--- a/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
+++ b/clang/unittests/Tooling/Syntax/SynthesisTest.cpp
@@ -173,7 +173,7 @@ TEST_P(SynthesisTest, DeepCopy_Synthesized) {
 {LeafSemiColon, NodeRole::Unknown}},
NodeKind::ContinueStatement);
 
-  auto *Copy = deepCopy(*Arena, StatementContinue);
+  auto *Copy = deepCopyExpandingMacros(*Arena, StatementContinue);
   EXPECT_TRUE(
   treeDumpEqual(Copy, StatementContinue->dump(Arena->getSourceManager(;
   // FIXME: Test that copy is independent of original, once the Mutations API 
is
@@ -183,7 +183,7 @@ TEST_P(SynthesisTest, DeepCopy_Synthesized) {
 TEST_P(SynthesisTest, DeepCopy_Original) {
   auto *OriginalTree = buildTree("int a;", GetParam());
 
-  auto *Copy = deepCopy(*Arena, OriginalTree);
+  aut

[clang] 6dc06fa - [SyntaxTree] Add tests for the assignment of the `canModify` tag.

2020-09-22 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-22T13:17:33Z
New Revision: 6dc06fa09d1a259df1f897dc821ba1544e2bcd24

URL: 
https://github.com/llvm/llvm-project/commit/6dc06fa09d1a259df1f897dc821ba1544e2bcd24
DIFF: 
https://github.com/llvm/llvm-project/commit/6dc06fa09d1a259df1f897dc821ba1544e2bcd24.diff

LOG: [SyntaxTree] Add tests for the assignment of the `canModify` tag.

Differential Revision: https://reviews.llvm.org/D88077

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 52bd5988b44ec..ecb4a7ce73a50 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -3855,8 +3855,76 @@ TranslationUnit Detached
 )txt"));
 }
 
-TEST_P(BuildSyntaxTreeTest, NonModifiableNodes) {
-  // Some nodes are non-modifiable, they are marked with 'I:'.
+TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_Leaf) {
+  // All nodes can be mutated.
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+#define OPEN {
+#define CLOSE }
+
+void test() {
+  OPEN
+1;
+  CLOSE
+
+  OPEN
+2;
+  }
+}
+)cpp",
+  R"txt(
+TranslationUnit Detached
+`-SimpleDeclaration
+  |-'void'
+  |-SimpleDeclarator Declarator
+  | |-'test'
+  | `-ParametersAndQualifiers
+  |   |-'(' OpenParen
+  |   `-')' CloseParen
+  `-CompoundStatement
+|-'{' OpenParen
+|-CompoundStatement Statement
+| |-'{' OpenParen
+| |-ExpressionStatement Statement
+| | |-IntegerLiteralExpression Expression
+| | | `-'1' LiteralToken
+| | `-';'
+| `-'}' CloseParen
+|-CompoundStatement Statement
+| |-'{' OpenParen
+| |-ExpressionStatement Statement
+| | |-IntegerLiteralExpression Expression
+| | | `-'2' LiteralToken
+| | `-';'
+| `-'}' CloseParen
+`-'}' CloseParen
+)txt"));
+}
+
+TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MatchTree) {
+  // Some nodes are unmodifiable, they are marked with 'unmodifiable'.
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+#define BRACES {}
+
+void test() BRACES
+)cpp",
+  R"txt(
+TranslationUnit Detached
+`-SimpleDeclaration
+  |-'void'
+  |-SimpleDeclarator Declarator
+  | |-'test'
+  | `-ParametersAndQualifiers
+  |   |-'(' OpenParen
+  |   `-')' CloseParen
+  `-CompoundStatement
+|-'{' OpenParen unmodifiable
+`-'}' CloseParen unmodifiable
+)txt"));
+}
+
+TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MismatchTree) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 #define HALF_IF if (1+
@@ -3896,21 +3964,16 @@ TranslationUnit Detached
 )txt"));
 }
 
-TEST_P(BuildSyntaxTreeTest, ModifiableNodes) {
-  // All nodes can be mutated.
+TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_ModifiableArguments) {
+  // FIXME: Note that the substitutions for `X` and `Y` are marked modifiable.
+  // However we cannot change `X` freely. Indeed if we change its substitution
+  // in the condition we should also change it the then-branch.
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
-#define OPEN {
-#define CLOSE }
+#define MIN(X,Y) X < Y ? X : Y
 
 void test() {
-  OPEN
-1;
-  CLOSE
-
-  OPEN
-2;
-  }
+  MIN(1,2);
 }
 )cpp",
   R"txt(
@@ -3924,24 +3987,109 @@ TranslationUnit Detached
   |   `-')' CloseParen
   `-CompoundStatement
 |-'{' OpenParen
-|-CompoundStatement Statement
-| |-'{' OpenParen
-| |-ExpressionStatement Statement
-| | |-IntegerLiteralExpression Expression
+|-ExpressionStatement Statement
+| |-UnknownExpression Expression
+| | |-BinaryOperatorExpression unmodifiable
+| | | |-IntegerLiteralExpression LeftHandSide
+| | | | `-'1' LiteralToken
+| | | |-'<' OperatorToken unmodifiable
+| | | `-IntegerLiteralExpression RightHandSide
+| | |   `-'2' LiteralToken
+| | |-'?' unmodifiable
+| | |-IntegerLiteralExpression
 | | | `-'1' LiteralToken
-| | `-';'
-| `-'}' CloseParen
-|-CompoundStatement Statement
-| |-'{' OpenParen
-| |-ExpressionStatement Statement
-| | |-IntegerLiteralExpression Expression
-| | | `-'2' LiteralToken
-| | `-';'
-| `-'}' CloseParen
+| | |-':' unmodifiable
+| | `-IntegerLiteralExpression
+| |   `-'2' LiteralToken
+| `-';'
 `-'}' CloseParen
 )txt"));
 }
 
+TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_MismatchTree) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+#define HALF_IF(X) if (X &&
+#define HALF_IF_2(Y) Y) {}
+void test() {
+  HALF_IF(1) HALF_IF_2(0) else {}
+})cpp",
+  R"txt(
+TranslationUnit Detached
+`-SimpleDeclaration
+  |-'void'
+  |-SimpleDeclarator Declarator
+  | |-'test'
+  | `-ParametersAndQualifiers
+  |   |-'(' OpenParen
+  |   `-')' CloseParen
+  `-CompoundStatement
+|-'{' OpenParen
+|-IfStatement Statement
+| |-'if' IntroducerKeyword unmodifiable
+| |-'(' unmodifiable
+| |-BinaryOperatorExpression unmodifiabl

[clang] c3c08bf - [SyntaxTree] Test the List API

2020-09-22 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-22T17:07:41Z
New Revision: c3c08bfdfd6244e0429753ee56df39c90187d772

URL: 
https://github.com/llvm/llvm-project/commit/c3c08bfdfd6244e0429753ee56df39c90187d772
DIFF: 
https://github.com/llvm/llvm-project/commit/c3c08bfdfd6244e0429753ee56df39c90187d772.diff

LOG: [SyntaxTree] Test the List API

Differential Revision: https://reviews.llvm.org/D87839

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Tree.h
clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Tree.h 
b/clang/include/clang/Tooling/Syntax/Tree.h
index a544fc1827b7..5840a86199eb 100644
--- a/clang/include/clang/Tooling/Syntax/Tree.h
+++ b/clang/include/clang/Tooling/Syntax/Tree.h
@@ -218,12 +218,16 @@ class List : public Tree {
   /// and delimiters are represented as null pointers.
   ///
   /// For example, in a separated list:
-  /// "a, b, c" <=> [("a", ","), ("b", ","), ("c", null)]
-  /// "a, , c" <=> [("a", ","), (null, ","), ("c", ",)]
-  /// "a, b," <=> [("a", ","), ("b", ","), (null, null)]
+  /// "a, b, c"  <=> [("a" , ","), ("b" , "," ), ("c" , null)]
+  /// "a,  , c"  <=> [("a" , ","), (null, "," ), ("c" , null)]
+  /// "a, b  c"  <=> [("a" , ","), ("b" , null), ("c" , null)]
+  /// "a, b,"<=> [("a" , ","), ("b" , "," ), (null, null)]
   ///
   /// In a terminated or maybe-terminated list:
-  /// "a, b," <=> [("a", ","), ("b", ",")]
+  /// "a; b; c;" <=> [("a" , ";"), ("b" , ";" ), ("c" , ";" )]
+  /// "a;  ; c;" <=> [("a" , ";"), (null, ";" ), ("c" , ";" )]
+  /// "a; b  c;" <=> [("a" , ";"), ("b" , null), ("c" , ";" )]
+  /// "a; b; c"  <=> [("a" , ";"), ("b" , ";" ), ("c" , null)]
   std::vector> getElementsAsNodesAndDelimiters();
 
   /// Returns the elements of the list. Missing elements are represented

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 6e777b353b04..fba3164e5966 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -9,6 +9,8 @@
 #include "clang/Tooling/Syntax/Tree.h"
 #include "TreeTestBase.h"
 #include "clang/Tooling/Syntax/BuildTree.h"
+#include "clang/Tooling/Syntax/Nodes.h"
+#include "llvm/ADT/STLExtras.h"
 #include "gtest/gtest.h"
 
 using namespace clang;
@@ -122,4 +124,231 @@ TEST_P(TreeTest, LastLeaf) {
   }
 }
 
+class ListTest : public SyntaxTreeTest {
+private:
+  std::string dumpQuotedTokensOrNull(const Node *N) {
+return N ? "'" +
+   StringRef(N->dumpTokens(Arena->getSourceManager()))
+   .trim()
+   .str() +
+   "'"
+ : "null";
+  }
+
+protected:
+  std::string
+  dumpElementsAndDelimiters(ArrayRef> EDs) {
+std::string Storage;
+llvm::raw_string_ostream OS(Storage);
+
+OS << "[";
+
+llvm::interleaveComma(
+EDs, OS, [&OS, this](const List::ElementAndDelimiter &ED) {
+  OS << "(" << dumpQuotedTokensOrNull(ED.element) << ", "
+ << dumpQuotedTokensOrNull(ED.delimiter) << ")";
+});
+
+OS << "]";
+
+return OS.str();
+  }
+
+  std::string dumpNodes(ArrayRef Nodes) {
+std::string Storage;
+llvm::raw_string_ostream OS(Storage);
+
+OS << "[";
+
+llvm::interleaveComma(Nodes, OS, [&OS, this](const Node *N) {
+  OS << dumpQuotedTokensOrNull(N);
+});
+
+OS << "]";
+
+return OS.str();
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(TreeTests, ListTest,
+::testing::ValuesIn(allTestClangConfigs()), );
+
+/// "a, b, c"  <=> [("a", ","), ("b", ","), ("c", null)]
+TEST_P(ListTest, List_Separated_WellFormed) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(syntax::createTree(
+  *Arena,
+  {
+  {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+  {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+  {createLeaf(*Arena, tok::identifier, "b"), NodeRole::ListElement},
+  {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+  {createLeaf(*Arena, tok::identifier, "c"), NodeRole::ListElement},
+  },
+  NodeKind::CallArguments));
+
+  EXPECT_EQ(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', ','), ('c', null)]");
+  EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', 'b', 'c']");
+}
+
+/// "a,  , c"  <=> [("a", ","), (null, ","), ("c", null)]
+TEST_P(ListTest, List_Separated_MissingElement) {
+  buildTree("", GetParam());
+
+  // "a,  , c"
+  auto *List = dyn_cast(syntax::createTree(
+  *Arena,
+  {
+  {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+  {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+  {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+  {createLeaf(*Arena, tok::

[clang] ba32915 - [SyntaxTree] Add support for `MemberExpression`

2020-08-20 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-20T14:57:35Z
New Revision: ba32915db2ce78256115a9db7b07bb3806e6364a

URL: 
https://github.com/llvm/llvm-project/commit/ba32915db2ce78256115a9db7b07bb3806e6364a
DIFF: 
https://github.com/llvm/llvm-project/commit/ba32915db2ce78256115a9db7b07bb3806e6364a.diff

LOG: [SyntaxTree] Add support for `MemberExpression`

Differential Revision: https://reviews.llvm.org/D86227

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 8e65fa1d8923..8b499bc5ceb9 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -55,6 +55,7 @@ enum class NodeKind : uint16_t {
   CharUserDefinedLiteralExpression,
   StringUserDefinedLiteralExpression,
   IdExpression,
+  MemberExpression,
 
   // Statements.
   UnknownStatement,
@@ -173,7 +174,10 @@ enum class NodeRole : uint8_t {
   ParametersAndQualifiers_trailingReturn,
   IdExpression_id,
   IdExpression_qualifier,
-  ParenExpression_subExpression
+  ParenExpression_subExpression,
+  MemberExpression_object,
+  MemberExpression_accessToken,
+  MemberExpression_member,
 };
 /// For debugging purposes.
 raw_ostream &operator<<(raw_ostream &OS, NodeRole R);
@@ -322,6 +326,26 @@ class ParenExpression final : public Expression {
   Leaf *closeParen();
 };
 
+/// Models a class member access. C++ [expr.ref]
+/// member-expression:
+///   expression -> template_opt id-expression
+///   expression .  template_opt id-expression
+/// e.g. `x.a`, `xp->a`
+///
+/// Note: An implicit member access inside a class, i.e. `a` instead of
+/// `this->a`, is an `id-expression`.
+class MemberExpression final : public Expression {
+public:
+  MemberExpression() : Expression(NodeKind::MemberExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::MemberExpression;
+  }
+  Expression *object();
+  Leaf *accessToken();
+  Leaf *templateKeyword();
+  IdExpression *member();
+};
+
 /// Expression for literals. C++ [lex.literal]
 class LiteralExpression : public Expression {
 public:

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 11d399730040..a77149d66207 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -881,6 +881,49 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 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 bf3c3108cb69..e09c8f20f210 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -126,6 +126,8 @@ raw_ostream &synt

[clang] a4ef9e8 - [SyntaxTree] Unify logic for generating `id-expression`

2020-08-20 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-20T14:57:35Z
New Revision: a4ef9e8643e2f3f8972e19c5b25f4dd81ba03508

URL: 
https://github.com/llvm/llvm-project/commit/a4ef9e8643e2f3f8972e19c5b25f4dd81ba03508
DIFF: 
https://github.com/llvm/llvm-project/commit/a4ef9e8643e2f3f8972e19c5b25f4dd81ba03508.diff

LOG: [SyntaxTree] Unify logic for generating `id-expression`

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index a77149d66207..37d29a270463 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -881,35 +881,46 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
-  bool WalkUpFromMemberExpr(MemberExpr *S) {
-if (auto QualifierLoc = S->getQualifierLoc())
+  syntax::IdExpression *buildIdExpression(NestedNameSpecifierLoc QualifierLoc,
+  SourceLocation TemplateKeywordLoc,
+  SourceRange UnqualifiedIdLoc,
+  ASTPtr From) {
+if (QualifierLoc) {
   Builder.markChild(QualifierLoc, 
syntax::NodeRole::IdExpression_qualifier);
-
-auto TemplateKeywordLoc = S->getTemplateKeywordLoc();
-if (TemplateKeywordLoc.isValid())
-  Builder.markChildToken(TemplateKeywordLoc,
- syntax::NodeRole::TemplateKeyword);
+  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.foldNode(Builder.getRange(UnqualifiedIdLoc), TheUnqualifiedId,
+ nullptr);
 Builder.markChild(TheUnqualifiedId, syntax::NodeRole::IdExpression_id);
 
+auto IdExpressionBeginLoc =
+QualifierLoc ? QualifierLoc.getBeginLoc() : 
UnqualifiedIdLoc.getBegin();
+
 auto *TheIdExpression = new (allocator()) syntax::IdExpression;
-auto MemberRange =
-Builder.getRange(S->hasQualifier() ? S->getQualifierLoc().getBeginLoc()
-   : S->getMemberLoc(),
- S->getEndLoc());
+Builder.foldNode(
+Builder.getRange(IdExpressionBeginLoc, UnqualifiedIdLoc.getEnd()),
+TheIdExpression, From);
 
+return TheIdExpression;
+  }
+
+  bool WalkUpFromMemberExpr(MemberExpr *S) {
 // 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);
+  buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
+SourceRange(S->getMemberLoc(), S->getEndLoc()), S);
   return true;
 }
-Builder.foldNode(MemberRange, TheIdExpression, nullptr);
+
+auto *TheIdExpression = buildIdExpression(
+S->getQualifierLoc(), S->getTemplateKeywordLoc(),
+SourceRange(S->getMemberLoc(), S->getEndLoc()), nullptr);
 
 Builder.markChild(TheIdExpression,
   syntax::NodeRole::MemberExpression_member);
@@ -925,45 +936,17 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   }
 
   bool WalkUpFromDeclRefExpr(DeclRefExpr *S) {
-if (auto QualifierLoc = S->getQualifierLoc())
-  Builder.markChild(QualifierLoc, 
syntax::NodeRole::IdExpression_qualifier);
+buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
+  SourceRange(S->getLocation(), S->getEndLoc()), S);
 
-auto TemplateKeywordLoc = S->getTemplateKeywordLoc();
-if (TemplateKeywordLoc.isValid())
-  Builder.markChildToken(TemplateKeywordLoc,
- syntax::NodeRole::TemplateKeyword);
-
-auto *unqualifiedId = new (allocator()) syntax::UnqualifiedId;
-
-Builder.foldNode(Builder.getRange(S->getLocation(), S->getEndLoc()),
- unqualifiedId, nullptr);
-
-Builder.markChild(unqualifiedId, syntax::NodeRole::IdExpression_id);
-
-Builder.foldNode(Builder.getExprRange(S),
- new (allocator()) syntax::IdExpression, S);
 return true;
   }
 
   // Same logic as DeclRefExpr.
   bool WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) {
-if (auto QualifierLoc = S->getQualifierLoc())
-  Builder.markChild(QualifierLoc, 
syntax::NodeRole::IdExpression_qualifier);
+buildIdExpression(S->getQualifierLoc(), S->getTemplateKeywordLoc(),
+  SourceRange(S->getLocation(), S->getEndLoc()), S);
 
-

[clang] e4e983e - [SyntaxTree] Split tests related to Namespace

2020-08-20 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-20T15:14:56Z
New Revision: e4e983e240430b3a0dc92402cc940292bd0d263f

URL: 
https://github.com/llvm/llvm-project/commit/e4e983e240430b3a0dc92402cc940292bd0d263f
DIFF: 
https://github.com/llvm/llvm-project/commit/e4e983e240430b3a0dc92402cc940292bd0d263f.diff

LOG: [SyntaxTree] Split tests related to Namespace

Differential Revision: https://reviews.llvm.org/D86139

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 2692c1f6ff58..a3e86dac50c5 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -2454,7 +2454,7 @@ typedef decltype(sizeof(void *)) size_t;
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, Namespaces) {
+TEST_P(SyntaxTreeTest, Namespace_Nested) {
   if (!GetParam().isCXX()) {
 return;
   }
@@ -2462,9 +2462,6 @@ TEST_P(SyntaxTreeTest, Namespaces) {
   R"cpp(
 namespace a { namespace b {} }
 namespace a::b {}
-namespace {}
-
-namespace foo = a;
 )cpp",
   R"txt(
 *: TranslationUnit
@@ -2478,82 +2475,91 @@ namespace foo = a;
 | | |-{
 | | `-}
 | `-}
-|-NamespaceDefinition
-| |-namespace
-| |-a
-| |-::
-| |-b
-| |-{
-| `-}
-|-NamespaceDefinition
-| |-namespace
-| |-{
-| `-}
-`-NamespaceAliasDefinition
+`-NamespaceDefinition
   |-namespace
-  |-foo
-  |-=
   |-a
-  `-;
+  |-::
+  |-b
+  |-{
+  `-}
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, UsingDirective) {
+TEST_P(SyntaxTreeTest, Namespace_Unnamed) {
   if (!GetParam().isCXX()) {
 return;
   }
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
-namespace ns {}
-using namespace ::ns;
+namespace {}
 )cpp",
   R"txt(
 *: TranslationUnit
-|-NamespaceDefinition
-| |-namespace
-| |-ns
-| |-{
-| `-}
-`-UsingNamespaceDirective
-  |-using
+`-NamespaceDefinition
   |-namespace
-  |-NestedNameSpecifier
-  | `-::
-  |-ns
-  `-;
+  |-{
+  `-}
 )txt"));
 }
 
+TEST_P(SyntaxTreeTest, Namespace_Alias) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+namespace a {}
+[[namespace foo = a;]]
+)cpp",
+  {R"txt(
+NamespaceAliasDefinition
+|-namespace
+|-foo
+|-=
+|-a
+`-;
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, UsingDirective) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+namespace ns {}
+[[using namespace ::ns;]]
+)cpp",
+  {R"txt(
+UsingNamespaceDirective
+|-using
+|-namespace
+|-NestedNameSpecifier
+| `-::
+|-ns
+`-;
+)txt"}));
+}
+
 TEST_P(SyntaxTreeTest, UsingDeclaration) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 namespace ns { int a; }
-using ns::a;
+[[using ns::a;]]
 )cpp",
-  R"txt(
-*: TranslationUnit
-|-NamespaceDefinition
-| |-namespace
-| |-ns
-| |-{
-| |-SimpleDeclaration
-| | |-int
-| | |-SimpleDeclarator
-| | | `-a
-| | `-;
-| `-}
-`-UsingDeclaration
-  |-using
-  |-NestedNameSpecifier
-  | |-IdentifierNameSpecifier
-  | | `-ns
-  | `-::
-  |-a
-  `-;
-)txt"));
+  {R"txt(
+UsingDeclaration
+|-using
+|-NestedNameSpecifier
+| |-IdentifierNameSpecifier
+| | `-ns
+| `-::
+|-a
+`-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, FreeStandingClasses) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 85c15f1 - [SyntaxTree] Add support for `this`

2020-08-21 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-21T08:01:29Z
New Revision: 85c15f17cc684b35cdb4a5f3a76d45160de7b597

URL: 
https://github.com/llvm/llvm-project/commit/85c15f17cc684b35cdb4a5f3a76d45160de7b597
DIFF: 
https://github.com/llvm/llvm-project/commit/85c15f17cc684b35cdb4a5f3a76d45160de7b597.diff

LOG: [SyntaxTree] Add support for `this`

Differential Revision: https://reviews.llvm.org/D86298

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 8b499bc5ceb9..0b3991768008 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -56,6 +56,7 @@ enum class NodeKind : uint16_t {
   StringUserDefinedLiteralExpression,
   IdExpression,
   MemberExpression,
+  ThisExpression,
 
   // Statements.
   UnknownStatement,
@@ -313,6 +314,16 @@ class UnknownExpression final : public Expression {
   }
 };
 
+/// Models a this expression `this`. C++ [expr.prim.this]
+class ThisExpression final : public Expression {
+public:
+  ThisExpression() : Expression(NodeKind::ThisExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::ThisExpression;
+  }
+  Leaf *thisKeyword();
+};
+
 /// Models a parenthesized expression `(E)`. C++ [expr.prim.paren]
 /// e.g. `(3 + 2)` in `a = 1 + (3 + 2);`
 class ParenExpression final : public Expression {

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 37d29a270463..3ab52ce5b7b4 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -950,6 +950,16 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
+  bool WalkUpFromCXXThisExpr(CXXThisExpr *S) {
+if (!S->isImplicit()) {
+  Builder.markChildToken(S->getLocation(),
+ syntax::NodeRole::IntroducerKeyword);
+  Builder.foldNode(Builder.getExprRange(S),
+   new (allocator()) syntax::ThisExpression, S);
+}
+return true;
+  }
+
   bool WalkUpFromParenExpr(ParenExpr *S) {
 Builder.markChildToken(S->getLParen(), syntax::NodeRole::OpenParen);
 Builder.markExprChild(S->getSubExpr(),

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index e09c8f20f210..ecd4c4dac728 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -20,6 +20,8 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeKind K) {
 return OS << "UnknownExpression";
   case NodeKind::ParenExpression:
 return OS << "ParenExpression";
+  case NodeKind::ThisExpression:
+return OS << "ThisExpression";
   case NodeKind::IntegerLiteralExpression:
 return OS << "IntegerLiteralExpression";
   case NodeKind::CharacterLiteralExpression:
@@ -286,6 +288,11 @@ syntax::Leaf *syntax::ParenExpression::closeParen() {
   return cast_or_null(findChild(syntax::NodeRole::CloseParen));
 }
 
+syntax::Leaf *syntax::ThisExpression::thisKeyword() {
+  return cast_or_null(
+  findChild(syntax::NodeRole::IntroducerKeyword));
+}
+
 syntax::Leaf *syntax::LiteralExpression::literalToken() {
   return cast_or_null(findChild(syntax::NodeRole::LiteralToken));
 }

diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index a3e86dac50c5..d4e2684934f3 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -905,6 +905,68 @@ UnknownExpression
 )txt"}));
 }
 
+TEST_P(SyntaxTreeTest, This_Simple) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+struct S {
+  S* test(){
+return [[this]];
+  }
+};
+)cpp",
+  {R"txt(
+ThisExpression
+`-this
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, This_ExplicitMemberAccess) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+struct S {
+  int a;
+  void test(){
+[[this->a]];
+  }
+};
+)cpp",
+  {R"txt(
+MemberExpression
+|-ThisExpression
+| `-this
+|-->
+`-IdExpression
+  `-UnqualifiedId
+`-a
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, This_ImplicitMemberAccess) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+struct S {
+  int a;
+  void test(){
+[[a]];
+  }
+};
+)cpp",
+  {R"txt(
+IdExpression
+`-UnqualifiedId
+  `-a
+)txt"}));
+}
+
 TEST_P(SyntaxTreeTest, ParenExpr) {
   EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
@@ -2099,29 +2161,6 @@ UnknownExpression
 )txt"}));
 }
 
-TEST_P(SyntaxTreeTest, MemberExpression_Implicit) {
-  if (!GetParam().isCX

[clang] 1beb11c - [SyntaxTree] Use annotations in Statement tests

2020-08-21 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-21T14:42:33Z
New Revision: 1beb11c61ae4b0130cb87ed56b9e010ef6a06691

URL: 
https://github.com/llvm/llvm-project/commit/1beb11c61ae4b0130cb87ed56b9e010ef6a06691
DIFF: 
https://github.com/llvm/llvm-project/commit/1beb11c61ae4b0130cb87ed56b9e010ef6a06691.diff

LOG: [SyntaxTree] Use annotations in Statement tests

Differential Revision: https://reviews.llvm.org/D86345

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index d4e2684934f3..994dd68028ea 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -102,282 +102,196 @@ void foo(int a, int b) {}
 }
 
 TEST_P(SyntaxTreeTest, If) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
-int main() {
-  if (1) {}
-  if (1) {} else if (0) {}
+void test() {
+  [[if (1) {}]]
+  [[if (1) {} else if (0) {}]]
 }
 )cpp",
-  R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-int
-  |-SimpleDeclarator
-  | |-main
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
+  {R"txt(
+IfStatement
+|-if
+|-(
+|-IntegerLiteralExpression
+| `-1
+|-)
+`-CompoundStatement
+  |-{
+  `-}
+  )txt",
+   R"txt(
+IfStatement
+|-if
+|-(
+|-IntegerLiteralExpression
+| `-1
+|-)
+|-CompoundStatement
+| |-{
+| `-}
+|-else
+`-IfStatement
+  |-if
+  |-(
+  |-IntegerLiteralExpression
+  | `-0
+  |-)
   `-CompoundStatement
 |-{
-|-IfStatement
-| |-if
-| |-(
-| |-IntegerLiteralExpression
-| | `-1
-| |-)
-| `-CompoundStatement
-|   |-{
-|   `-}
-|-IfStatement
-| |-if
-| |-(
-| |-IntegerLiteralExpression
-| | `-1
-| |-)
-| |-CompoundStatement
-| | |-{
-| | `-}
-| |-else
-| `-IfStatement
-|   |-if
-|   |-(
-|   |-IntegerLiteralExpression
-|   | `-0
-|   |-)
-|   `-CompoundStatement
-| |-{
-| `-}
 `-}
-)txt"));
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, For) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 void test() {
-  for (;;)  {}
+  [[for (;;)  {}]]
 }
 )cpp",
-  R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-|-{
-|-ForStatement
-| |-for
-| |-(
-| |-;
-| |-;
-| |-)
-| `-CompoundStatement
-|   |-{
-|   `-}
-`-}
-)txt"));
+  {R"txt(
+ForStatement
+|-for
+|-(
+|-;
+|-;
+|-)
+`-CompoundStatement
+  |-{
+  `-}
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, RangeBasedFor) {
   if (!GetParam().isCXX11OrLater()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 void test() {
   int a[3];
-  for (int x : a)
-;
+  [[for (int x : a)
+;]]
 }
 )cpp",
-  R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-|-{
-|-DeclarationStatement
-| |-SimpleDeclaration
-| | |-int
-| | `-SimpleDeclarator
-| |   |-a
-| |   `-ArraySubscript
-| | |-[
-| | |-IntegerLiteralExpression
-| | | `-3
-| | `-]
-| `-;
-|-RangeBasedForStatement
-| |-for
-| |-(
-| |-SimpleDeclaration
-| | |-int
-| | |-SimpleDeclarator
-| | | `-x
-| | `-:
-| |-IdExpression
-| | `-UnqualifiedId
-| |   `-a
-| |-)
-| `-EmptyStatement
-|   `-;
-`-}
-)txt"));
+  {R"txt(
+RangeBasedForStatement
+|-for
+|-(
+|-SimpleDeclaration
+| |-int
+| |-SimpleDeclarator
+| | `-x
+| `-:
+|-IdExpression
+| `-UnqualifiedId
+|   `-a
+|-)
+`-EmptyStatement
+  `-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, DeclarationStatement) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 void test() {
-  int a = 10;
+  [[int a = 10;]]
 }
 )cpp",
-  R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-|-{
-|-DeclarationStatement
-| |-SimpleDeclaration
-| | |-int
-| | `-SimpleDeclarator
-| |   |-a
-| |   |-=
-| |   `-IntegerLiteralExpression
-| | `-10
-| `-;
-`-}
-)txt"));
+  {R"txt(
+DeclarationStatement
+|-SimpleDeclaration
+| |-int
+| `-SimpleDeclarator
+|   |-a
+|   |-=
+|   `-IntegerLiteralExpression
+| `-10
+`-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, Switch) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 void test() {
-  switch (1) {
+  [[switch (1) {
 case 0:
 default:;
-  }
+  }]]
 }
 )cpp",
-  R"txt(

[clang] 235f9f7 - [SyntaxTree] Split `DynamicExceptionSpecification` test

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-24T14:31:46Z
New Revision: 235f9f7fe94488904a60a8a1f5430183b0504945

URL: 
https://github.com/llvm/llvm-project/commit/235f9f7fe94488904a60a8a1f5430183b0504945
DIFF: 
https://github.com/llvm/llvm-project/commit/235f9f7fe94488904a60a8a1f5430183b0504945.diff

LOG: [SyntaxTree] Split `DynamicExceptionSpecification` test

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 005f0a384d58..ce37a952ac1a 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -3800,79 +3800,72 @@ TEST_P(SyntaxTreeTest, DynamicExceptionSpecification) {
   if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 struct MyException1 {};
 struct MyException2 {};
-int a() throw();
-int b() throw(...);
-int c() throw(MyException1);
-int d() throw(MyException1, MyException2);
+[[int a() throw();]]
+[[int b() throw(...);]]
+[[int c() throw(MyException1);]]
+[[int d() throw(MyException1, MyException2);]]
 )cpp",
-  R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-MyException1
-| |-{
-| |-}
-| `-;
-|-SimpleDeclaration
-| |-struct
-| |-MyException2
-| |-{
-| |-}
-| `-;
-|-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-a
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-)
-| |   |-throw
-| |   |-(
-| |   `-)
-| `-;
-|-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-b
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-)
-| |   |-throw
-| |   |-(
-| |   |-...
-| |   `-)
-| `-;
-|-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-c
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-)
-| |   |-throw
-| |   |-(
-| |   |-MyException1
-| |   `-)
-| `-;
-`-SimpleDeclaration
-  |-int
-  |-SimpleDeclarator
-  | |-d
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-)
-  |   |-throw
-  |   |-(
-  |   |-MyException1
-  |   |-,
-  |   |-MyException2
-  |   `-)
-  `-;
-)txt"));
+  {R"txt(
+SimpleDeclaration
+|-int
+|-SimpleDeclarator
+| |-a
+| `-ParametersAndQualifiers
+|   |-(
+|   |-)
+|   |-throw
+|   |-(
+|   `-)
+`-;
+)txt",
+   R"txt(
+SimpleDeclaration
+|-int
+|-SimpleDeclarator
+| |-b
+| `-ParametersAndQualifiers
+|   |-(
+|   |-)
+|   |-throw
+|   |-(
+|   |-...
+|   `-)
+`-;
+)txt",
+   R"txt(
+SimpleDeclaration
+|-int
+|-SimpleDeclarator
+| |-c
+| `-ParametersAndQualifiers
+|   |-(
+|   |-)
+|   |-throw
+|   |-(
+|   |-MyException1
+|   `-)
+`-;
+)txt",
+   R"txt(
+SimpleDeclaration
+|-int
+|-SimpleDeclarator
+| |-d
+| `-ParametersAndQualifiers
+|   |-(
+|   |-)
+|   |-throw
+|   |-(
+|   |-MyException1
+|   |-,
+|   |-MyException2
+|   `-)
+`-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, NoexceptExceptionSpecification) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] ed83095 - [SyntaxTree] Use annotations to reduce noise on member function tests

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-24T14:31:45Z
New Revision: ed83095254a3e212d14b293a6a0e6c85d1f3331c

URL: 
https://github.com/llvm/llvm-project/commit/ed83095254a3e212d14b293a6a0e6c85d1f3331c
DIFF: 
https://github.com/llvm/llvm-project/commit/ed83095254a3e212d14b293a6a0e6c85d1f3331c.diff

LOG: [SyntaxTree] Use annotations to reduce noise on member function tests

Differential Revision: https://reviews.llvm.org/D86439

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index a8e675468257..93f510e0a890 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -2570,61 +2570,47 @@ TEST_P(SyntaxTreeTest, StaticMemberFunction) {
   if (!GetParam().isCXX11OrLater()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 struct S {
-  static void f(){}
+  [[static void f(){}]]
 };
 )cpp",
-  R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-struct
-  |-S
+  {R"txt(
+SimpleDeclaration
+|-static
+|-void
+|-SimpleDeclarator
+| |-f
+| `-ParametersAndQualifiers
+|   |-(
+|   `-)
+`-CompoundStatement
   |-{
-  |-SimpleDeclaration
-  | |-static
-  | |-void
-  | |-SimpleDeclarator
-  | | |-f
-  | | `-ParametersAndQualifiers
-  | |   |-(
-  | |   `-)
-  | `-CompoundStatement
-  |   |-{
-  |   `-}
-  |-}
-  `-;
-)txt"));
+  `-}
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, ConversionMemberFunction) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 struct X {
-  operator int();
+  [[operator int();]]
 };
 )cpp",
-  R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-struct
-  |-X
-  |-{
-  |-SimpleDeclaration
-  | |-SimpleDeclarator
-  | | |-operator
-  | | |-int
-  | | `-ParametersAndQualifiers
-  | |   |-(
-  | |   `-)
-  | `-;
-  |-}
-  `-;
-)txt"));
+  {R"txt(
+SimpleDeclaration
+|-SimpleDeclarator
+| |-operator
+| |-int
+| `-ParametersAndQualifiers
+|   |-(
+|   `-)
+`-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, LiteralOperatorDeclaration) {
@@ -2687,76 +2673,62 @@ TEST_P(SyntaxTreeTest, OverloadedOperatorDeclaration) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 struct X {
-  X& operator=(const X&);
+  [[X& operator=(const X&);]]
 };
 )cpp",
-  R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-struct
-  |-X
-  |-{
-  |-SimpleDeclaration
-  | |-X
-  | |-SimpleDeclarator
-  | | |-&
-  | | |-operator
-  | | |-=
-  | | `-ParametersAndQualifiers
-  | |   |-(
-  | |   |-SimpleDeclaration
-  | |   | |-const
-  | |   | |-X
-  | |   | `-SimpleDeclarator
-  | |   |   `-&
-  | |   `-)
-  | `-;
-  |-}
-  `-;
-)txt"));
+  {R"txt(
+SimpleDeclaration
+|-X
+|-SimpleDeclarator
+| |-&
+| |-operator
+| |-=
+| `-ParametersAndQualifiers
+|   |-(
+|   |-SimpleDeclaration
+|   | |-const
+|   | |-X
+|   | `-SimpleDeclarator
+|   |   `-&
+|   `-)
+`-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperatorFriendDeclarataion) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 struct X {
-  friend X operator+(X, const X&);
+  [[friend X operator+(X, const X&);]]
 };
 )cpp",
-  R"txt(
-*: TranslationUnit
+  {R"txt(
+UnknownDeclaration
 `-SimpleDeclaration
-  |-struct
+  |-friend
   |-X
-  |-{
-  |-UnknownDeclaration
-  | `-SimpleDeclaration
-  |   |-friend
-  |   |-X
-  |   |-SimpleDeclarator
-  |   | |-operator
-  |   | |-+
-  |   | `-ParametersAndQualifiers
-  |   |   |-(
-  |   |   |-SimpleDeclaration
-  |   |   | `-X
-  |   |   |-,
-  |   |   |-SimpleDeclaration
-  |   |   | |-const
-  |   |   | |-X
-  |   |   | `-SimpleDeclarator
-  |   |   |   `-&
-  |   |   `-)
-  |   `-;
-  |-}
+  |-SimpleDeclarator
+  | |-operator
+  | |-+
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   |-SimpleDeclaration
+  |   | `-X
+  |   |-,
+  |   |-SimpleDeclaration
+  |   | |-const
+  |   | |-X
+  |   | `-SimpleDeclarator
+  |   |   `-&
+  |   `-)
   `-;
-)txt"));
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, ClassTemplateDeclaration) {
@@ -2847,38 +2819,31 @@ TEST_P(SyntaxTreeTest, StaticMemberFunctionTemplate) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 struct S {
-  template
-  static U f();
+  [[template
+  static U f();]]
 };
 )cpp",
-  R"txt(
-*: TranslationUnit
+  {R"txt(
+TemplateDeclaration
+|-template
+|-<
+|-UnknownDeclaration
+| |-typename
+| `-U
+|->
 `-SimpleDeclaration
-  |-struct
-  |-S
-  |-{
-  |-TemplateDeclaration
-  | |-template
-  | |-<
-  | |-UnknownDeclaration
-  | | |-typename
-  | | `-U
-  |

[clang] 90f85df - [SyntaxTree] Group tests related to `using`

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-24T14:31:46Z
New Revision: 90f85dfc14bc6020486eb2d2c6399f8207ef3625

URL: 
https://github.com/llvm/llvm-project/commit/90f85dfc14bc6020486eb2d2c6399f8207ef3625
DIFF: 
https://github.com/llvm/llvm-project/commit/90f85dfc14bc6020486eb2d2c6399f8207ef3625.diff

LOG: [SyntaxTree] Group tests related to `using`

Differential Revision: https://reviews.llvm.org/D86443

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 4fc648df90b3..acbe90526fcb 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -2494,7 +2494,7 @@ UsingNamespaceDirective
 )txt"}));
 }
 
-TEST_P(SyntaxTreeTest, UsingDeclaration) {
+TEST_P(SyntaxTreeTest, UsingDeclaration_Namespace) {
   if (!GetParam().isCXX()) {
 return;
   }
@@ -2515,6 +2515,59 @@ UsingDeclaration
 )txt"}));
 }
 
+TEST_P(SyntaxTreeTest, UsingDeclaration_ClassMember) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+template  struct X {
+  [[using T::foo;]]
+  [[using typename T::bar;]]
+};
+)cpp",
+  {R"txt(
+UsingDeclaration
+|-using
+|-NestedNameSpecifier
+| |-IdentifierNameSpecifier
+| | `-T
+| `-::
+|-foo
+`-;
+)txt",
+   R"txt(
+UsingDeclaration
+|-using
+|-typename
+|-NestedNameSpecifier
+| |-IdentifierNameSpecifier
+| | `-T
+| `-::
+|-bar
+`-;
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, UsingTypeAlias) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+using type = int;
+)cpp",
+  R"txt(
+*: TranslationUnit
+`-TypeAliasDeclaration
+  |-using
+  |-type
+  |-=
+  |-int
+  `-;
+)txt"));
+}
+
 TEST_P(SyntaxTreeTest, FreeStandingClass_ForwardDeclaration) {
   EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
@@ -3005,52 +3058,6 @@ template  struct X::Y {};
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, TemplatesUsingUsing) {
-  if (!GetParam().isCXX()) {
-return;
-  }
-  EXPECT_TRUE(treeDumpEqual(
-  R"cpp(
-template  struct X {
-  using T::foo;
-  using typename T::bar;
-};
-)cpp",
-  R"txt(
-*: TranslationUnit
-`-TemplateDeclaration
-  |-template
-  |-<
-  |-UnknownDeclaration
-  | |-class
-  | `-T
-  |->
-  `-SimpleDeclaration
-|-struct
-|-X
-|-{
-|-UsingDeclaration
-| |-using
-| |-NestedNameSpecifier
-| | |-IdentifierNameSpecifier
-| | | `-T
-| | `-::
-| |-foo
-| `-;
-|-UsingDeclaration
-| |-using
-| |-typename
-| |-NestedNameSpecifier
-| | |-IdentifierNameSpecifier
-| | | `-T
-| | `-::
-| |-bar
-| `-;
-|-}
-`-;
-)txt"));
-}
-
 TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Definition) {
   if (!GetParam().isCXX()) {
 return;
@@ -3152,25 +3159,6 @@ TemplateDeclaration
 )txt"}));
 }
 
-TEST_P(SyntaxTreeTest, UsingType) {
-  if (!GetParam().isCXX()) {
-return;
-  }
-  EXPECT_TRUE(treeDumpEqual(
-  R"cpp(
-using type = int;
-)cpp",
-  R"txt(
-*: TranslationUnit
-`-TypeAliasDeclaration
-  |-using
-  |-type
-  |-=
-  |-int
-  `-;
-)txt"));
-}
-
 TEST_P(SyntaxTreeTest, EmptyDeclaration) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 4baa163 - [SyntaxTree] Split `ParametersAndQualifiers` tests

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-24T14:31:46Z
New Revision: 4baa163c74237b30c5094c1fafd7ed355575bcfa

URL: 
https://github.com/llvm/llvm-project/commit/4baa163c74237b30c5094c1fafd7ed355575bcfa
DIFF: 
https://github.com/llvm/llvm-project/commit/4baa163c74237b30c5094c1fafd7ed355575bcfa.diff

LOG: [SyntaxTree] Split `ParametersAndQualifiers` tests

Differential Revision: https://reviews.llvm.org/D86459

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index acbe90526fcb..005f0a384d58 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -3438,19 +3438,30 @@ void f(int xs[static 10]);
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, ParametersAndQualifiersInFreeFunctions) {
-  if (!GetParam().isCXX()) {
-return;
-  }
+TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+int func();
+)cpp",
+  R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-int
+  |-SimpleDeclarator
+  | |-func
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   `-)
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
-int func1();
-int func2a(int a);
-int func2b(int);
-int func3a(int *ap);
-int func3b(int *);
-int func4a(int a, float b);
-int func4b(int, float);
+int func1(int a);
+int func2(int *ap);
+int func3(int a, float b);
 )cpp",
   R"txt(
 *: TranslationUnit
@@ -3460,14 +3471,6 @@ int func4b(int, float);
 | | |-func1
 | | `-ParametersAndQualifiers
 | |   |-(
-| |   `-)
-| `-;
-|-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-func2a
-| | `-ParametersAndQualifiers
-| |   |-(
 | |   |-SimpleDeclaration
 | |   | |-int
 | |   | `-SimpleDeclarator
@@ -3477,17 +3480,7 @@ int func4b(int, float);
 |-SimpleDeclaration
 | |-int
 | |-SimpleDeclarator
-| | |-func2b
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | `-int
-| |   `-)
-| `-;
-|-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-func3a
+| | |-func2
 | | `-ParametersAndQualifiers
 | |   |-(
 | |   |-SimpleDeclaration
@@ -3497,39 +3490,61 @@ int func4b(int, float);
 | |   |   `-ap
 | |   `-)
 | `-;
+`-SimpleDeclaration
+  |-int
+  |-SimpleDeclarator
+  | |-func3
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   |-SimpleDeclaration
+  |   | |-int
+  |   | `-SimpleDeclarator
+  |   |   `-a
+  |   |-,
+  |   |-SimpleDeclaration
+  |   | |-float
+  |   | `-SimpleDeclarator
+  |   |   `-b
+  |   `-)
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+int func1(int);
+int func2(int *);
+int func3(int, float);
+)cpp",
+  R"txt(
+*: TranslationUnit
 |-SimpleDeclaration
 | |-int
 | |-SimpleDeclarator
-| | |-func3b
+| | |-func1
 | | `-ParametersAndQualifiers
 | |   |-(
 | |   |-SimpleDeclaration
-| |   | |-int
-| |   | `-SimpleDeclarator
-| |   |   `-*
+| |   | `-int
 | |   `-)
 | `-;
 |-SimpleDeclaration
 | |-int
 | |-SimpleDeclarator
-| | |-func4a
+| | |-func2
 | | `-ParametersAndQualifiers
 | |   |-(
 | |   |-SimpleDeclaration
 | |   | |-int
 | |   | `-SimpleDeclarator
-| |   |   `-a
-| |   |-,
-| |   |-SimpleDeclaration
-| |   | |-float
-| |   | `-SimpleDeclarator
-| |   |   `-b
+| |   |   `-*
 | |   `-)
 | `-;
 `-SimpleDeclaration
   |-int
   |-SimpleDeclarator
-  | |-func4b
+  | |-func3
   | `-ParametersAndQualifiers
   |   |-(
   |   |-SimpleDeclaration
@@ -3542,47 +3557,60 @@ int func4b(int, float);
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, ParametersAndQualifiersInFreeFunctionsCxx) {
+TEST_P(SyntaxTreeTest,
+   ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) {
   if (!GetParam().isCXX()) {
 return;
   }
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
-int func1(const int a, volatile int b, const volatile int c);
-int func2(int& a);
+int func(const int a, volatile int b, const volatile int c);
 )cpp",
   R"txt(
 *: TranslationUnit
-|-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-func1
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | |-const
-| |   | |-int
-| |   | `-SimpleDeclarator
-| |   |   `-a
-| |   |-,
-| |   |-SimpleDeclaration
-| |   | |-volatile
-| |   | |-int
-| |   | `-SimpleDeclarator
-| |   |   `-b
-| |   |-,
-| |   |-SimpleDeclaration
-| |   | |-const
-| |   | |-volatile
-| |   | |-int
-| |   | `-SimpleDeclarator
-| |   |   `-c
-| |   `-)
-| `-;
 `-SimpleDeclaration
   |-int
   |-SimpleDeclarator
-  | |-func2
+  | |-func
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   |-SimpleDeclaration
+  |   | |-const
+  |   | |-int
+  |   | `-SimpleDeclarator
+  |   |   `-a
+  |   |-,
+  |   |-SimpleDeclaration
+  |   | |-volatile
+  |   | |-in

[clang] a722d6a - [SyntaxTree] Split ExplicitTemplateInstantiation test

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-24T14:31:45Z
New Revision: a722d6a197c7a4f7a1afb72b4732b8ebe8272628

URL: 
https://github.com/llvm/llvm-project/commit/a722d6a197c7a4f7a1afb72b4732b8ebe8272628
DIFF: 
https://github.com/llvm/llvm-project/commit/a722d6a197c7a4f7a1afb72b4732b8ebe8272628.diff

LOG: [SyntaxTree] Split ExplicitTemplateInstantiation test

Differential Revision: https://reviews.llvm.org/D86441

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 8dbf99c32db8..4fc648df90b3 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -3051,84 +3051,105 @@ template  struct X {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, ExplicitTemplateInstantations) {
+TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Definition) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 template  struct X {};
-template  struct X {};
-template <> struct X {};
+[[template struct X;]]
+)cpp",
+  {R"txt(
+ExplicitTemplateInstantiation
+|-template
+`-SimpleDeclaration
+  |-struct
+  |-X
+  |-<
+  |-double
+  |->
+  `-;
+)txt"}));
+}
 
-template struct X;
-extern template struct X;
+TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Declaration) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+template  struct X {};
+[[extern template struct X;]]
 )cpp",
-  R"txt(
-*: TranslationUnit
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-class
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-X
-|   |-{
-|   |-}
-|   `-;
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-class
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-X
-|   |-<
-|   |-T
-|   |-*
-|   |->
-|   |-{
-|   |-}
-|   `-;
-|-TemplateDeclaration
-| |-template
-| |-<
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-X
-|   |-<
-|   |-int
-|   |->
-|   |-{
-|   |-}
-|   `-;
-|-ExplicitTemplateInstantiation
-| |-template
-| `-SimpleDeclaration
-|   |-struct
-|   |-X
-|   |-<
-|   |-double
-|   |->
-|   `-;
-`-ExplicitTemplateInstantiation
-  |-extern
-  |-template
-  `-SimpleDeclaration
-|-struct
-|-X
-|-<
-|-float
-|->
-`-;
-)txt"));
+  {R"txt(
+ExplicitTemplateInstantiation
+|-extern
+|-template
+`-SimpleDeclaration
+  |-struct
+  |-X
+  |-<
+  |-float
+  |->
+  `-;
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, ClassTemplateSpecialization_Partial) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+template  struct X {};
+[[template  struct X {};]]
+)cpp",
+  {R"txt(
+TemplateDeclaration
+|-template
+|-<
+|-UnknownDeclaration
+| |-class
+| `-T
+|->
+`-SimpleDeclaration
+  |-struct
+  |-X
+  |-<
+  |-T
+  |-*
+  |->
+  |-{
+  |-}
+  `-;
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, ClassTemplateSpecialization_Full) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+template  struct X {};
+[[template <> struct X {};]]
+)cpp",
+  {R"txt(
+TemplateDeclaration
+|-template
+|-<
+|->
+`-SimpleDeclaration
+  |-struct
+  |-X
+  |-<
+  |-int
+  |->
+  |-{
+  |-}
+  `-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UsingType) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 4e8dd50 - [SyntaxTree] Split array declarator tests

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-24T14:31:45Z
New Revision: 4e8dd506e66642329dcd530524f43b0d2b528521

URL: 
https://github.com/llvm/llvm-project/commit/4e8dd506e66642329dcd530524f43b0d2b528521
DIFF: 
https://github.com/llvm/llvm-project/commit/4e8dd506e66642329dcd530524f43b0d2b528521.diff

LOG: [SyntaxTree] Split array declarator tests

Differential Revision: https://reviews.llvm.org/D86437

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 994dd68028ea..a8e675468257 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -3342,45 +3342,63 @@ void test() {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, ArraySubscriptsInDeclarators) {
+TEST_P(SyntaxTreeTest, ArrayDeclarator_Simple) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 int a[10];
+)cpp",
+  R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-int
+  |-SimpleDeclarator
+  | |-a
+  | `-ArraySubscript
+  |   |-[
+  |   |-IntegerLiteralExpression
+  |   | `-10
+  |   `-]
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, ArrayDeclarator_Multidimensional) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
 int b[1][2][3];
+)cpp",
+  R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-int
+  |-SimpleDeclarator
+  | |-b
+  | |-ArraySubscript
+  | | |-[
+  | | |-IntegerLiteralExpression
+  | | | `-1
+  | | `-]
+  | |-ArraySubscript
+  | | |-[
+  | | |-IntegerLiteralExpression
+  | | | `-2
+  | | `-]
+  | `-ArraySubscript
+  |   |-[
+  |   |-IntegerLiteralExpression
+  |   | `-3
+  |   `-]
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, ArrayDeclarator_UnknownBound) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
 int c[] = {1,2,3};
 )cpp",
   R"txt(
 *: TranslationUnit
-|-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-a
-| | `-ArraySubscript
-| |   |-[
-| |   |-IntegerLiteralExpression
-| |   | `-10
-| |   `-]
-| `-;
-|-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-b
-| | |-ArraySubscript
-| | | |-[
-| | | |-IntegerLiteralExpression
-| | | | `-1
-| | | `-]
-| | |-ArraySubscript
-| | | |-[
-| | | |-IntegerLiteralExpression
-| | | | `-2
-| | | `-]
-| | `-ArraySubscript
-| |   |-[
-| |   |-IntegerLiteralExpression
-| |   | `-3
-| |   `-]
-| `-;
 `-SimpleDeclaration
   |-int
   |-SimpleDeclarator
@@ -3405,7 +3423,7 @@ int c[] = {1,2,3};
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, StaticArraySubscriptsInDeclarators) {
+TEST_P(SyntaxTreeTest, ArrayDeclarator_Static) {
   if (!GetParam().isC99OrLater()) {
 return;
   }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b4093d6 - [SyntaxTree] Split FreeStandingClass tests

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-24T14:31:45Z
New Revision: b4093d663f8377b3ca3746ff104c83c9c5510c0a

URL: 
https://github.com/llvm/llvm-project/commit/b4093d663f8377b3ca3746ff104c83c9c5510c0a
DIFF: 
https://github.com/llvm/llvm-project/commit/b4093d663f8377b3ca3746ff104c83c9c5510c0a.diff

LOG: [SyntaxTree] Split FreeStandingClass tests

Differential Revision: https://reviews.llvm.org/D86440

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 93f510e0a890..8dbf99c32db8 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -2515,55 +2515,65 @@ UsingDeclaration
 )txt"}));
 }
 
-TEST_P(SyntaxTreeTest, FreeStandingClasses) {
-  // Free-standing classes, must live inside a SimpleDeclaration.
-  EXPECT_TRUE(treeDumpEqual(
+TEST_P(SyntaxTreeTest, FreeStandingClass_ForwardDeclaration) {
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
-struct X;
-struct X {};
-
-struct Y *y1;
-struct Y {} *y2;
+[[struct X;]]
+[[struct Y *y1;]]
+)cpp",
+  {R"txt(
+SimpleDeclaration
+|-struct
+|-X
+`-;
+)txt",
+   R"txt(
+SimpleDeclaration
+|-struct
+|-Y
+|-SimpleDeclarator
+| |-*
+| `-y1
+`-;
+)txt"}));
+}
 
-struct {} *a1;
+TEST_P(SyntaxTreeTest, FreeStandingClasses_Definition) {
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+[[struct X {};]]
+[[struct Y {} *y2;]]
+[[struct {} *a1;]]
 )cpp",
-  R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| `-;
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-}
-| `-;
-|-SimpleDeclaration
-| |-struct
-| |-Y
-| |-SimpleDeclarator
-| | |-*
-| | `-y1
-| `-;
-|-SimpleDeclaration
-| |-struct
-| |-Y
-| |-{
-| |-}
-| |-SimpleDeclarator
-| | |-*
-| | `-y2
-| `-;
-`-SimpleDeclaration
-  |-struct
-  |-{
-  |-}
-  |-SimpleDeclarator
-  | |-*
-  | `-a1
-  `-;
-)txt"));
+  {R"txt(
+SimpleDeclaration
+|-struct
+|-X
+|-{
+|-}
+`-;
+)txt",
+   R"txt(
+SimpleDeclaration
+|-struct
+|-Y
+|-{
+|-}
+|-SimpleDeclarator
+| |-*
+| `-y2
+`-;
+)txt",
+   R"txt(
+SimpleDeclaration
+|-struct
+|-{
+|-}
+|-SimpleDeclarator
+| |-*
+| `-a1
+`-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, StaticMemberFunction) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 61273f2 - [SyntaxTree] Split `MemberPointer` tests with annotations

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-25T06:07:40Z
New Revision: 61273f298f2ccca5a474013ff59a94eef0371efb

URL: 
https://github.com/llvm/llvm-project/commit/61273f298f2ccca5a474013ff59a94eef0371efb
DIFF: 
https://github.com/llvm/llvm-project/commit/61273f298f2ccca5a474013ff59a94eef0371efb.diff

LOG: [SyntaxTree] Split `MemberPointer` tests with annotations

Differential Revision: https://reviews.llvm.org/D86467

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index ce37a952ac1a..8ce83e927672 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -4059,133 +4059,119 @@ TEST_P(SyntaxTreeTest, MemberPointers) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 struct X {};
-int X::* a;
-const int X::* b;
+[[int X::* a;]]
+[[const int X::* b;]]
 )cpp",
-  R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-}
-| `-;
-|-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-MemberPointer
-| | | |-X
-| | | |-::
-| | | `-*
-| | `-a
-| `-;
-`-SimpleDeclaration
-  |-const
-  |-int
-  |-SimpleDeclarator
-  | |-MemberPointer
-  | | |-X
-  | | |-::
-  | | `-*
-  | `-b
-  `-;
-)txt"));
+  {R"txt(
+SimpleDeclaration
+|-int
+|-SimpleDeclarator
+| |-MemberPointer
+| | |-X
+| | |-::
+| | `-*
+| `-a
+`-;
+)txt",
+   R"txt(
+SimpleDeclaration
+|-const
+|-int
+|-SimpleDeclarator
+| |-MemberPointer
+| | |-X
+| | |-::
+| | `-*
+| `-b
+`-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, MemberFunctionPointer) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 struct X {
   struct Y {};
 };
-void (X::*xp)();
-void (X::**xpp)(const int*);
+[[void (X::*xp)();]]
+[[void (X::**xpp)(const int*);]]
 // FIXME: Generate the right syntax tree for this type,
 // i.e. create a syntax node for the outer member pointer
-void (X::Y::*xyp)(const int*, char);
+[[void (X::Y::*xyp)(const int*, char);]]
 )cpp",
-  R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-SimpleDeclaration
-| | |-struct
-| | |-Y
-| | |-{
-| | |-}
-| | `-;
-| |-}
-| `-;
-|-SimpleDeclaration
-| |-void
-| |-SimpleDeclarator
-| | |-ParenDeclarator
-| | | |-(
-| | | |-MemberPointer
-| | | | |-X
-| | | | |-::
-| | | | `-*
-| | | |-xp
-| | | `-)
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   `-)
-| `-;
-|-SimpleDeclaration
-| |-void
-| |-SimpleDeclarator
-| | |-ParenDeclarator
-| | | |-(
-| | | |-MemberPointer
-| | | | |-X
-| | | | |-::
-| | | | `-*
-| | | |-*
-| | | |-xpp
-| | | `-)
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | |-const
-| |   | |-int
-| |   | `-SimpleDeclarator
-| |   |   `-*
-| |   `-)
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-ParenDeclarator
-  | | |-(
-  | | |-X
-  | | |-::
-  | | |-MemberPointer
-  | | | |-Y
-  | | | |-::
-  | | | `-*
-  | | |-xyp
-  | | `-)
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-const
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-*
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | `-char
-  |   `-)
-  `-;
-)txt"));
+  {R"txt(
+SimpleDeclaration
+|-void
+|-SimpleDeclarator
+| |-ParenDeclarator
+| | |-(
+| | |-MemberPointer
+| | | |-X
+| | | |-::
+| | | `-*
+| | |-xp
+| | `-)
+| `-ParametersAndQualifiers
+|   |-(
+|   `-)
+`-;
+)txt",
+   R"txt(
+SimpleDeclaration
+|-void
+|-SimpleDeclarator
+| |-ParenDeclarator
+| | |-(
+| | |-MemberPointer
+| | | |-X
+| | | |-::
+| | | `-*
+| | |-*
+| | |-xpp
+| | `-)
+| `-ParametersAndQualifiers
+|   |-(
+|   |-SimpleDeclaration
+|   | |-const
+|   | |-int
+|   | `-SimpleDeclarator
+|   |   `-*
+|   `-)
+`-;
+)txt",
+   R"txt(
+SimpleDeclaration
+|-void
+|-SimpleDeclarator
+| |-ParenDeclarator
+| | |-(
+| | |-X
+| | |-::
+| | |-MemberPointer
+| | | |-Y
+| | | |-::
+| | | `-*
+| | |-xyp
+| | `-)
+| `-ParametersAndQualifiers
+|   |-(
+|   |-SimpleDeclaration
+|   | |-const
+|   | |-int
+|   | `-SimpleDeclarator
+|   |   `-*
+|   |-,
+|   |-SimpleDeclaration
+|   | `-char
+|   `-)
+`-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, ComplexDeclarator) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 7f426c6 - [SyntaxTree] Use annotations on ClassTemplate_MemberClassDefinition test

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-25T06:07:40Z
New Revision: 7f426c65b06f2d19546b2d50fccc15de9dde3d85

URL: 
https://github.com/llvm/llvm-project/commit/7f426c65b06f2d19546b2d50fccc15de9dde3d85
DIFF: 
https://github.com/llvm/llvm-project/commit/7f426c65b06f2d19546b2d50fccc15de9dde3d85.diff

LOG: [SyntaxTree] Use annotations on ClassTemplate_MemberClassDefinition test

Differential Revision: https://reviews.llvm.org/D86470

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 2ad01f09596e..0d24432115cc 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -3007,55 +3007,37 @@ namespace n {
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, Templates2) {
+TEST_P(SyntaxTreeTest, ClassTemplate_MemberClassDefinition) {
   if (!GetParam().isCXX()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 template  struct X { struct Y; };
-template  struct X::Y {};
+[[template  struct X::Y {};]]
 )cpp",
-  R"txt(
-*: TranslationUnit
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-class
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-X
-|   |-{
-|   |-SimpleDeclaration
-|   | |-struct
-|   | |-Y
-|   | `-;
-|   |-}
-|   `-;
-`-TemplateDeclaration
-  |-template
-  |-<
-  |-UnknownDeclaration
-  | |-class
-  | `-T
-  |->
-  `-SimpleDeclaration
-|-struct
-|-NestedNameSpecifier
-| |-SimpleTemplateNameSpecifier
-| | |-X
-| | |-<
-| | |-T
-| | `->
-| `-::
-|-Y
-|-{
-|-}
-`-;
-)txt"));
+  {R"txt(
+TemplateDeclaration
+|-template
+|-<
+|-UnknownDeclaration
+| |-class
+| `-T
+|->
+`-SimpleDeclaration
+  |-struct
+  |-NestedNameSpecifier
+  | |-SimpleTemplateNameSpecifier
+  | | |-X
+  | | |-<
+  | | |-T
+  | | `->
+  | `-::
+  |-Y
+  |-{
+  |-}
+  `-;
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Definition) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b493e4c - [SyntaxTree] Split ConstVolatileQualifiers tests

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-25T06:07:40Z
New Revision: b493e4cb3e37401d4fe5c0b2ba1adf7e66758bb0

URL: 
https://github.com/llvm/llvm-project/commit/b493e4cb3e37401d4fe5c0b2ba1adf7e66758bb0
DIFF: 
https://github.com/llvm/llvm-project/commit/b493e4cb3e37401d4fe5c0b2ba1adf7e66758bb0.diff

LOG: [SyntaxTree] Split ConstVolatileQualifiers tests

Differential Revision: https://reviews.llvm.org/D86469

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 8ce83e927672..2ad01f09596e 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -3962,13 +3962,11 @@ int *(d)(int);
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, ConstVolatileQualifiers) {
+TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 const int west = -1;
 int const east = 1;
-const int const universal = 0;
-const int const *const *volatile b;
 )cpp",
   R"txt(
 *: TranslationUnit
@@ -3983,25 +3981,45 @@ const int const *const *volatile b;
 | |   `-IntegerLiteralExpression
 | | `-1
 | `-;
-|-SimpleDeclaration
-| |-int
-| |-const
-| |-SimpleDeclarator
-| | |-east
-| | |-=
-| | `-IntegerLiteralExpression
-| |   `-1
-| `-;
-|-SimpleDeclaration
-| |-const
-| |-int
-| |-const
-| |-SimpleDeclarator
-| | |-universal
-| | |-=
-| | `-IntegerLiteralExpression
-| |   `-0
-| `-;
+`-SimpleDeclaration
+  |-int
+  |-const
+  |-SimpleDeclarator
+  | |-east
+  | |-=
+  | `-IntegerLiteralExpression
+  |   `-1
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+const int const universal = 0;
+)cpp",
+  R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-const
+  |-int
+  |-const
+  |-SimpleDeclarator
+  | |-universal
+  | |-=
+  | `-IntegerLiteralExpression
+  |   `-0
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_ConstAndVolatile) {
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+const int const *const *volatile b;
+)cpp",
+  R"txt(
+*: TranslationUnit
 `-SimpleDeclaration
   |-const
   |-int



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 5c11c08 - [SyntaxTree] Update `Declaration` tests to dump `NodeRole`

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-25T06:34:47Z
New Revision: 5c11c08d86f3ae45ec3b2b2766c48a3dc572d05e

URL: 
https://github.com/llvm/llvm-project/commit/5c11c08d86f3ae45ec3b2b2766c48a3dc572d05e
DIFF: 
https://github.com/llvm/llvm-project/commit/5c11c08d86f3ae45ec3b2b2766c48a3dc572d05e.diff

LOG: [SyntaxTree] Update `Declaration` tests to dump `NodeRole`

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 04954c4ab73a..6fa4ff9b1094 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -2294,25 +2294,25 @@ int *a, b;
 int *c, d;
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 |-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-*
-| | `-a
-| |-,
-| |-SimpleDeclarator
-| | `-b
-| `-;
+| |-'int'
+| |-SimpleDeclarator SimpleDeclaration_declarator
+| | |-'*'
+| | `-'a'
+| |-','
+| |-SimpleDeclarator SimpleDeclaration_declarator
+| | `-'b'
+| `-';'
 `-SimpleDeclaration
-  |-int
-  |-SimpleDeclarator
-  | |-*
-  | `-c
-  |-,
-  |-SimpleDeclarator
-  | `-d
-  `-;
+  |-'int'
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | |-'*'
+  | `-'c'
+  |-','
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | `-'d'
+  `-';'
 )txt"));
 }
 
@@ -2322,17 +2322,17 @@ TEST_P(SyntaxTreeTest, 
MultipleDeclaratorsGroupingTypedef) {
 typedef int *a, b;
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 `-SimpleDeclaration
-  |-typedef
-  |-int
-  |-SimpleDeclarator
-  | |-*
-  | `-a
-  |-,
-  |-SimpleDeclarator
-  | `-b
-  `-;
+  |-'typedef'
+  |-'int'
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | |-'*'
+  | `-'a'
+  |-','
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | `-'b'
+  `-';'
 )txt"));
 }
 
@@ -2345,38 +2345,38 @@ void foo() {
 }
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 `-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-foo
+  |-'void'
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | |-'foo'
   | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
+  |   |-'(' OpenParen
+  |   `-')' CloseParen
   `-CompoundStatement
-|-{
-|-DeclarationStatement
+|-'{' OpenParen
+|-DeclarationStatement CompoundStatement_statement
 | |-SimpleDeclaration
-| | |-int
-| | |-SimpleDeclarator
-| | | |-*
-| | | `-a
-| | |-,
-| | `-SimpleDeclarator
-| |   `-b
-| `-;
-|-DeclarationStatement
+| | |-'int'
+| | |-SimpleDeclarator SimpleDeclaration_declarator
+| | | |-'*'
+| | | `-'a'
+| | |-','
+| | `-SimpleDeclarator SimpleDeclaration_declarator
+| |   `-'b'
+| `-';'
+|-DeclarationStatement CompoundStatement_statement
 | |-SimpleDeclaration
-| | |-typedef
-| | |-int
-| | |-SimpleDeclarator
-| | | |-*
-| | | `-ta
-| | |-,
-| | `-SimpleDeclarator
-| |   `-tb
-| `-;
-`-}
+| | |-'typedef'
+| | |-'int'
+| | |-SimpleDeclarator SimpleDeclaration_declarator
+| | | |-'*'
+| | | `-'ta'
+| | |-','
+| | `-SimpleDeclarator SimpleDeclaration_declarator
+| |   `-'tb'
+| `-';'
+`-'}' CloseParen
 )txt"));
 }
 
@@ -2389,21 +2389,21 @@ TEST_P(SyntaxTreeTest, SizeTTypedef) {
 typedef decltype(sizeof(void *)) size_t;
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 `-SimpleDeclaration
-  |-typedef
-  |-decltype
-  |-(
+  |-'typedef'
+  |-'decltype'
+  |-'('
   |-UnknownExpression
-  | |-sizeof
-  | |-(
-  | |-void
-  | |-*
-  | `-)
-  |-)
-  |-SimpleDeclarator
-  | `-size_t
-  `-;
+  | |-'sizeof'
+  | |-'('
+  | |-'void'
+  | |-'*'
+  | `-')'
+  |-')'
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | `-'size_t'
+  `-';'
 )txt"));
 }
 
@@ -2417,24 +2417,24 @@ namespace a { namespace b {} }
 namespace a::b {}
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 |-NamespaceDefinition
-| |-namespace
-| |-a
-| |-{
+| |-'namespace'
+| |-'a'
+| |-'{'
 | |-NamespaceDefinition
-| | |-namespace
-| | |-b
-| | |-{
-| | `-}
-| `-}
+| | |-'namespace'
+| | |-'b'
+| | |-'{'
+| | `-'}'
+| `-'}'
 `-NamespaceDefinition
-  |-namespace
-  |-a
-  |-::
-  |-b
-  |-{
-  `-}
+  |-'namespace'
+  |-'a'
+  |-'::'
+  |-'b'
+  |-'{'
+  `-'}'
 )txt"));
 }
 
@@ -2447,11 +2447,11 @@ TEST_P(SyntaxTreeTest, Namespace_Unnamed) {
 namespace {}
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 `-NamespaceDefinition
-  |-namespace
-  |-{
-  `-}
+  |-'namespace'
+  |-'{'
+  `-'}'
 )txt"));
 }
 
@@ -2466,11 +2466,11 @@ namespace a {}
 )cpp",
   {R"txt(
 NamespaceAliasDefinition
-|-namespace
-|-foo
-|-=
-|-a
-`-;
+|-'namespace'
+|-'foo'
+|-'='
+|-'a'
+`-';'
 )txt"}));
 }
 
@@ -2485,12 +2485,12 @@ namespace ns {}
 )cpp",
   {R"txt(
 UsingNamespaceDirect

[clang] 6118ce7 - [SyntaxTree] Update `Expression` tests to dump `NodeRole`

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-25T06:34:47Z
New Revision: 6118ce79a3d3832c8bcbd985fbd2bf0bee4ea8a2

URL: 
https://github.com/llvm/llvm-project/commit/6118ce79a3d3832c8bcbd985fbd2bf0bee4ea8a2
DIFF: 
https://github.com/llvm/llvm-project/commit/6118ce79a3d3832c8bcbd985fbd2bf0bee4ea8a2.diff

LOG: [SyntaxTree] Update `Expression` tests to dump `NodeRole`

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 2e84e78e4ac4..04954c4ab73a 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -305,48 +305,48 @@ void test() {
 }
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 `-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
+  |-'void'
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | |-'test'
   | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
+  |   |-'(' OpenParen
+  |   `-')' CloseParen
   `-CompoundStatement
-|-{
-|-ExpressionStatement
-| |-UnknownExpression
+|-'{' OpenParen
+|-ExpressionStatement CompoundStatement_statement
+| |-UnknownExpression ExpressionStatement_expression
 | | |-IdExpression
-| | | `-UnqualifiedId
-| | |   `-test
-| | |-(
-| | `-)
-| `-;
-|-IfStatement
-| |-if
-| |-(
+| | | `-UnqualifiedId IdExpression_id
+| | |   `-'test'
+| | |-'('
+| | `-')'
+| `-';'
+|-IfStatement CompoundStatement_statement
+| |-'if' IntroducerKeyword
+| |-'('
 | |-IntegerLiteralExpression
-| | `-1
-| |-)
-| |-ExpressionStatement
-| | |-UnknownExpression
+| | `-'1' LiteralToken
+| |-')'
+| |-ExpressionStatement IfStatement_thenStatement
+| | |-UnknownExpression ExpressionStatement_expression
 | | | |-IdExpression
-| | | | `-UnqualifiedId
-| | | |   `-test
-| | | |-(
-| | | `-)
-| | `-;
-| |-else
-| `-ExpressionStatement
-|   |-UnknownExpression
+| | | | `-UnqualifiedId IdExpression_id
+| | | |   `-'test'
+| | | |-'('
+| | | `-')'
+| | `-';'
+| |-'else' IfStatement_elseKeyword
+| `-ExpressionStatement IfStatement_elseStatement
+|   |-UnknownExpression ExpressionStatement_expression
 |   | |-IdExpression
-|   | | `-UnqualifiedId
-|   | |   `-test
-|   | |-(
-|   | `-)
-|   `-;
-`-}
+|   | | `-UnqualifiedId IdExpression_id
+|   | |   `-'test'
+|   | |-'('
+|   | `-')'
+|   `-';'
+`-'}' CloseParen
 )txt"));
 }
 
@@ -358,9 +358,9 @@ void test(int a) {
 }
 )cpp",
   {R"txt(
-IdExpression
-`-UnqualifiedId
-  `-a
+IdExpression ExpressionStatement_expression
+`-UnqualifiedId IdExpression_id
+  `-'a'
 )txt"}));
 }
 
@@ -378,20 +378,20 @@ void test(X x) {
 }
 )cpp",
   {R"txt(
-UnknownExpression
+UnknownExpression ExpressionStatement_expression
 |-IdExpression
-| `-UnqualifiedId
-|   |-operator
-|   `-+
-|-(
+| `-UnqualifiedId IdExpression_id
+|   |-'operator'
+|   `-'+'
+|-'('
 |-IdExpression
-| `-UnqualifiedId
-|   `-x
-|-,
+| `-UnqualifiedId IdExpression_id
+|   `-'x'
+|-','
 |-IdExpression
-| `-UnqualifiedId
-|   `-x
-`-)
+| `-UnqualifiedId IdExpression_id
+|   `-'x'
+`-')'
 )txt"}));
 }
 
@@ -409,18 +409,18 @@ void test(X x) {
 }
 )cpp",
   {R"txt(
-UnknownExpression
+UnknownExpression ExpressionStatement_expression
 |-MemberExpression
-| |-IdExpression
-| | `-UnqualifiedId
-| |   `-x
-| |-.
-| `-IdExpression
-|   `-UnqualifiedId
-| |-operator
-| `-int
-|-(
-`-)
+| |-IdExpression MemberExpression_object
+| | `-UnqualifiedId IdExpression_id
+| |   `-'x'
+| |-'.' MemberExpression_accessToken
+| `-IdExpression MemberExpression_member
+|   `-UnqualifiedId IdExpression_id
+| |-'operator'
+| `-'int'
+|-'('
+`-')'
 )txt"}));
 }
 
@@ -436,16 +436,16 @@ void test() {
 }
 )cpp",
   {R"txt(
-UnknownExpression
+UnknownExpression ExpressionStatement_expression
 |-IdExpression
-| `-UnqualifiedId
-|   |-operator
-|   |-""
-|   `-_w
-|-(
+| `-UnqualifiedId IdExpression_id
+|   |-'operator'
+|   |-'""'
+|   `-'_w'
+|-'('
 |-CharacterLiteralExpression
-| `-'1'
-`-)
+| `-''1'' LiteralToken
+`-')'
 )txt"}));
 }
 
@@ -461,18 +461,18 @@ void test(X x) {
 }
 )cpp",
   {R"txt(
-UnknownExpression
+UnknownExpression ExpressionStatement_expression
 |-MemberExpression
-| |-IdExpression
-| | `-UnqualifiedId
-| |   `-x
-| |-.
-| `-IdExpression
-|   `-UnqualifiedId
-| |-~
-| `-X
-|-(
-`-)
+| |-IdExpression MemberExpression_object
+| | `-UnqualifiedId IdExpression_id
+| |   `-'x'
+| |-'.' MemberExpression_accessToken
+| `-IdExpression MemberExpression_member
+|   `-UnqualifiedId IdExpression_id
+| |-'~'
+| `-'X'
+|-'('
+`-')'
 )txt"}));
 }
 
@@ -492,21 +492,21 @@ void test(X x) {
 }
 )cpp",
   {R"txt(
-U

[clang] c655d80 - [SyntaxTree] Extend the syntax tree dump to also cover `NodeRole`

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-25T06:34:40Z
New Revision: c655d8081570336dda109502ed1e7a2eff1b26e2

URL: 
https://github.com/llvm/llvm-project/commit/c655d8081570336dda109502ed1e7a2eff1b26e2
DIFF: 
https://github.com/llvm/llvm-project/commit/c655d8081570336dda109502ed1e7a2eff1b26e2.diff

LOG: [SyntaxTree] Extend the syntax tree dump to also cover `NodeRole`

We should see `NodeRole` information in the dump because that exposes how the
accessors will behave.

Functional changes in the dump:
* Surround Leaf tokens with `'`
* Append `Node` dumps with `NodeRole` information, except for unknown roles
* Append marks to `Node` dumps, instead of prepending

Non-functional changes:
* `::dumpTokens(llvm::raw_ostream, ArrayRef, const
SourceManager &SM)` always received as parameter a `syntax::Token *`
pointing to `Leaf::token()`. Changed the function to
`dumpLeaf(llvm::raw_ostream, syntax::Leaf *, const SourceManager&)`
* `dumpTree` acted on a Node, rename to `dumpNode`

Differential Revision: https://reviews.llvm.org/D85330

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Tree.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Tree.cpp
clang/unittests/Tooling/Syntax/TreeTestBase.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Tree.h 
b/clang/include/clang/Tooling/Syntax/Tree.h
index fcd169cad3ec..f7f9e6bdc5a0 100644
--- a/clang/include/clang/Tooling/Syntax/Tree.h
+++ b/clang/include/clang/Tooling/Syntax/Tree.h
@@ -106,9 +106,9 @@ class Node {
   Node *nextSibling() { return NextSibling; }
 
   /// Dumps the structure of a subtree. For debugging and testing purposes.
-  std::string dump(const Arena &A) const;
+  std::string dump(const SourceManager &SM) const;
   /// Dumps the tokens forming this subtree.
-  std::string dumpTokens(const Arena &A) const;
+  std::string dumpTokens(const SourceManager &SM) const;
 
   /// Asserts invariants on this node of the tree and its immediate children.
   /// Will not recurse into the subtree. No-op if NDEBUG is set.

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 3ab52ce5b7b4..f027a60030b7 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -546,7 +546,7 @@ class syntax::TreeBuilder {
 R += std::string(
 formatv("- '{0}' covers '{1}'+{2} tokens\n", It->second->kind(),
 It->first->text(A.sourceManager()), CoveredTokens));
-R += It->second->dump(A);
+R += It->second->dump(A.sourceManager());
   }
   return R;
 }

diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index 70e3c8e02783..7dbceedfb48f 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -133,46 +133,45 @@ void syntax::Tree::replaceChildRangeLowLevel(Node 
*BeforeBegin, Node *End,
 }
 
 namespace {
-static void dumpTokens(raw_ostream &OS, ArrayRef Tokens,
-   const SourceManager &SM) {
-  assert(!Tokens.empty());
-  bool First = true;
-  for (const auto &T : Tokens) {
-if (!First)
-  OS << " ";
-else
-  First = false;
-// Handle 'eof' separately, calling text() on it produces an empty string.
-if (T.kind() == tok::eof) {
-  OS << "";
-  continue;
-}
-OS << T.text(SM);
-  }
+static void dumpLeaf(raw_ostream &OS, const syntax::Leaf *L,
+ const SourceManager &SM) {
+  assert(L);
+  const auto *Token = L->token();
+  assert(Token);
+  // Handle 'eof' separately, calling text() on it produces an empty string.
+  if (Token->kind() == tok::eof)
+OS << "";
+  else
+OS << Token->text(SM);
 }
 
-static void dumpTree(raw_ostream &OS, const syntax::Node *N,
- const syntax::Arena &A, std::vector IndentMask) {
-  std::string Marks;
-  if (!N->isOriginal())
-Marks += "M";
-  if (N->role() == syntax::NodeRole::Detached)
-Marks += "*"; // FIXME: find a nice way to print other roles.
-  if (!N->canModify())
-Marks += "I";
-  if (!Marks.empty())
-OS << Marks << ": ";
-
-  if (auto *L = dyn_cast(N)) {
-dumpTokens(OS, *L->token(), A.sourceManager());
+static void dumpNode(raw_ostream &OS, const syntax::Node *N,
+ const SourceManager &SM, std::vector IndentMask) {
+  auto dumpExtraInfo = [&OS](const syntax::Node *N) {
+if (N->role() != syntax::NodeRole::Unknown)
+  OS << " " << N->role();
+if (!N->isOriginal())
+  OS << " synthesized";
+if (!N->canModify())
+  OS << " unmodifiable";
+  };
+
+  assert(N);
+  if (const auto *L = dyn_cast(N)) {
+OS << "'";
+dumpLeaf(OS, L, SM);
+OS << "'";
+dumpExtraInfo(N);
 OS << "\n";
 return;
   }
 
-  auto *T = cast(N);
-  OS << T->kind() << "\n";
+  const auto *T = cast(N);
+  OS << T->kind();
+  dumpExtraInfo(N);
+  OS << "\n

[clang] 02a9f8a - [SyntaxTree] Update `Statement` tests to dump `NodeRole`

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-25T06:34:47Z
New Revision: 02a9f8a27b7f22e4a499c5511142bd2650defad1

URL: 
https://github.com/llvm/llvm-project/commit/02a9f8a27b7f22e4a499c5511142bd2650defad1
DIFF: 
https://github.com/llvm/llvm-project/commit/02a9f8a27b7f22e4a499c5511142bd2650defad1.diff

LOG: [SyntaxTree] Update `Statement` tests to dump `NodeRole`

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 0d24432115cc..2e84e78e4ac4 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -24,27 +24,27 @@ int main() {}
 void foo() {}
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 |-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | |-main
+| |-'int'
+| |-SimpleDeclarator SimpleDeclaration_declarator
+| | |-'main'
 | | `-ParametersAndQualifiers
-| |   |-(
-| |   `-)
+| |   |-'(' OpenParen
+| |   `-')' CloseParen
 | `-CompoundStatement
-|   |-{
-|   `-}
+|   |-'{' OpenParen
+|   `-'}' CloseParen
 `-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-foo
+  |-'void'
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | |-'foo'
   | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
+  |   |-'(' OpenParen
+  |   `-')' CloseParen
   `-CompoundStatement
-|-{
-`-}
+|-'{' OpenParen
+`-'}' CloseParen
 )txt"));
 }
 
@@ -55,20 +55,20 @@ int a;
 int b = 42;
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 |-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | `-a
-| `-;
+| |-'int'
+| |-SimpleDeclarator SimpleDeclaration_declarator
+| | `-'a'
+| `-';'
 `-SimpleDeclaration
-  |-int
-  |-SimpleDeclarator
-  | |-b
-  | |-=
+  |-'int'
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | |-'b'
+  | |-'='
   | `-IntegerLiteralExpression
-  |   `-42
-  `-;
+  |   `-'42' LiteralToken
+  `-';'
 )txt"));
 }
 
@@ -78,26 +78,26 @@ TEST_P(SyntaxTreeTest, SimpleFunction) {
 void foo(int a, int b) {}
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 `-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-foo
+  |-'void'
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | |-'foo'
   | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-a
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-b
-  |   `-)
+  |   |-'(' OpenParen
+  |   |-SimpleDeclaration ParametersAndQualifiers_parameter
+  |   | |-'int'
+  |   | `-SimpleDeclarator SimpleDeclaration_declarator
+  |   |   `-'a'
+  |   |-','
+  |   |-SimpleDeclaration ParametersAndQualifiers_parameter
+  |   | |-'int'
+  |   | `-SimpleDeclarator SimpleDeclaration_declarator
+  |   |   `-'b'
+  |   `-')' CloseParen
   `-CompoundStatement
-|-{
-`-}
+|-'{' OpenParen
+`-'}' CloseParen
 )txt"));
 }
 
@@ -110,36 +110,36 @@ void test() {
 }
 )cpp",
   {R"txt(
-IfStatement
-|-if
-|-(
+IfStatement CompoundStatement_statement
+|-'if' IntroducerKeyword
+|-'('
 |-IntegerLiteralExpression
-| `-1
-|-)
-`-CompoundStatement
-  |-{
-  `-}
+| `-'1' LiteralToken
+|-')'
+`-CompoundStatement IfStatement_thenStatement
+  |-'{' OpenParen
+  `-'}' CloseParen
   )txt",
R"txt(
-IfStatement
-|-if
-|-(
+IfStatement CompoundStatement_statement
+|-'if' IntroducerKeyword
+|-'('
 |-IntegerLiteralExpression
-| `-1
-|-)
-|-CompoundStatement
-| |-{
-| `-}
-|-else
-`-IfStatement
-  |-if
-  |-(
+| `-'1' LiteralToken
+|-')'
+|-CompoundStatement IfStatement_thenStatement
+| |-'{' OpenParen
+| `-'}' CloseParen
+|-'else' IfStatement_elseKeyword
+`-IfStatement IfStatement_elseStatement
+  |-'if' IntroducerKeyword
+  |-'('
   |-IntegerLiteralExpression
-  | `-0
-  |-)
-  `-CompoundStatement
-|-{
-`-}
+  | `-'0' LiteralToken
+  |-')'
+  `-CompoundStatement IfStatement_thenStatement
+|-'{' OpenParen
+`-'}' CloseParen
 )txt"}));
 }
 
@@ -151,15 +151,15 @@ void test() {
 }
 )cpp",
   {R"txt(
-ForStatement
-|-for
-|-(
-|-;
-|-;
-|-)
-`-CompoundStatement
-  |-{
-  `-}
+ForStatement CompoundStatement_statement
+|-'for' IntroducerKeyword
+|-'('
+|-';'
+|-';'
+|-')'
+`-CompoundStatement BodyStatement
+  |-'{' OpenParen
+  `-'}' CloseParen
 )txt"}));
 }
 
@@ -176,20 +176,20 @@ void test() {
 }
 )cpp",
   {R"txt(
-RangeBasedForStatement
-|-for
-|-(
+RangeBasedForStatement CompoundStatement_statement
+|-'for' IntroducerKeyword
+|-'('
 |-SimpleDeclaration
-| |-int
-| |-SimpleDeclarator
-| | `-x
-| `-:
+| |-'int'
+| |-SimpleDeclarator SimpleDeclaration_declarator
+| | `-'x'
+| `-':'
 |-IdExpression
-| `-UnqualifiedId
-|   `-a
-|-)
-`-EmptyStatement
-  `-;
+| `-UnqualifiedId IdExpression_id
+|   `-'a'
+|-')'
+`-EmptyStatement BodyStatement
+  `-';'
 )txt"}));
 }
 
@@ -201,15 +201,15 @@ void 

[clang] be2bc7d - [SyntaxTree] Update `Modifiable` tests to dump `NodeRole` and `unmodifiable` tag

2020-08-24 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-25T06:34:48Z
New Revision: be2bc7d4cef2edd66c7fb74b70adf62fc68754db

URL: 
https://github.com/llvm/llvm-project/commit/be2bc7d4cef2edd66c7fb74b70adf62fc68754db
DIFF: 
https://github.com/llvm/llvm-project/commit/be2bc7d4cef2edd66c7fb74b70adf62fc68754db.diff

LOG: [SyntaxTree] Update `Modifiable` tests to dump `NodeRole` and 
`unmodifiable` tag

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 6fa4ff9b1094..398f12c45081 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -3231,34 +3231,34 @@ void test() {
   HALF_IF HALF_IF_2 else {}
 })cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 `-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
+  |-'void'
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | |-'test'
   | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
+  |   |-'(' OpenParen
+  |   `-')' CloseParen
   `-CompoundStatement
-|-{
-|-IfStatement
-| |-I: if
-| |-I: (
-| |-I: BinaryOperatorExpression
-| | |-I: IntegerLiteralExpression
-| | | `-I: 1
-| | |-I: +
-| | `-I: IntegerLiteralExpression
-| |   `-I: 1
-| |-I: )
-| |-I: CompoundStatement
-| | |-I: {
-| | `-I: }
-| |-else
-| `-CompoundStatement
-|   |-{
-|   `-}
-`-}
+|-'{' OpenParen
+|-IfStatement CompoundStatement_statement
+| |-'if' IntroducerKeyword unmodifiable
+| |-'(' unmodifiable
+| |-BinaryOperatorExpression unmodifiable
+| | |-IntegerLiteralExpression BinaryOperatorExpression_leftHandSide 
unmodifiable
+| | | `-'1' LiteralToken unmodifiable
+| | |-'+' OperatorExpression_operatorToken unmodifiable
+| | `-IntegerLiteralExpression BinaryOperatorExpression_rightHandSide 
unmodifiable
+| |   `-'1' LiteralToken unmodifiable
+| |-')' unmodifiable
+| |-CompoundStatement IfStatement_thenStatement unmodifiable
+| | |-'{' OpenParen unmodifiable
+| | `-'}' CloseParen unmodifiable
+| |-'else' IfStatement_elseKeyword
+| `-CompoundStatement IfStatement_elseStatement
+|   |-'{' OpenParen
+|   `-'}' CloseParen
+`-'}' CloseParen
 )txt"));
 }
 
@@ -3280,31 +3280,31 @@ void test() {
 }
 )cpp",
   R"txt(
-*: TranslationUnit
+TranslationUnit Detached
 `-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
+  |-'void'
+  |-SimpleDeclarator SimpleDeclaration_declarator
+  | |-'test'
   | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
+  |   |-'(' OpenParen
+  |   `-')' CloseParen
   `-CompoundStatement
-|-{
-|-CompoundStatement
-| |-{
-| |-ExpressionStatement
-| | |-IntegerLiteralExpression
-| | | `-1
-| | `-;
-| `-}
-|-CompoundStatement
-| |-{
-| |-ExpressionStatement
-| | |-IntegerLiteralExpression
-| | | `-2
-| | `-;
-| `-}
-`-}
+|-'{' OpenParen
+|-CompoundStatement CompoundStatement_statement
+| |-'{' OpenParen
+| |-ExpressionStatement CompoundStatement_statement
+| | |-IntegerLiteralExpression ExpressionStatement_expression
+| | | `-'1' LiteralToken
+| | `-';'
+| `-'}' CloseParen
+|-CompoundStatement CompoundStatement_statement
+| |-'{' OpenParen
+| |-ExpressionStatement CompoundStatement_statement
+| | |-IntegerLiteralExpression ExpressionStatement_expression
+| | | `-'2' LiteralToken
+| | `-';'
+| `-'}' CloseParen
+`-'}' CloseParen
 )txt"));
 }
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 2de2ca3 - [SyntaxTree] Add support for `CallExpression`

2020-08-26 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-26T07:03:49Z
New Revision: 2de2ca348dfa09963eb33ddf71c9cbb59612c16a

URL: 
https://github.com/llvm/llvm-project/commit/2de2ca348dfa09963eb33ddf71c9cbb59612c16a
DIFF: 
https://github.com/llvm/llvm-project/commit/2de2ca348dfa09963eb33ddf71c9cbb59612c16a.diff

LOG: [SyntaxTree] Add support for `CallExpression`

* Generate `CallExpression` syntax node for all semantic nodes inheriting from
`CallExpr` with call-expression syntax - except `CUDAKernelCallExpr`.
* Implement all the accessors
* Arguments of `CallExpression` have their own syntax node which is based on
the `List` base API

Differential Revision: https://reviews.llvm.org/D86544

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 0b3991768008..9a14aac130b4 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -57,6 +57,7 @@ enum class NodeKind : uint16_t {
   IdExpression,
   MemberExpression,
   ThisExpression,
+  CallExpression,
 
   // Statements.
   UnknownStatement,
@@ -103,7 +104,8 @@ enum class NodeKind : uint16_t {
   GlobalNameSpecifier,
   DecltypeNameSpecifier,
   IdentifierNameSpecifier,
-  SimpleTemplateNameSpecifier
+  SimpleTemplateNameSpecifier,
+  CallArguments
 };
 /// For debugging purposes.
 raw_ostream &operator<<(raw_ostream &OS, NodeKind K);
@@ -179,6 +181,8 @@ enum class NodeRole : uint8_t {
   MemberExpression_object,
   MemberExpression_accessToken,
   MemberExpression_member,
+  CallExpression_callee,
+  CallExpression_arguments,
 };
 /// For debugging purposes.
 raw_ostream &operator<<(raw_ostream &OS, NodeRole R);
@@ -324,6 +328,37 @@ class ThisExpression final : public Expression {
   Leaf *thisKeyword();
 };
 
+/// Models arguments of a function call.
+///   call-arguments:
+/// delimited_list(expression, ',')
+/// Note: This construct is a simplification of the grammar rule for
+/// `expression-list`, that is used in the definition of `call-expression`
+class CallArguments final : public List {
+public:
+  CallArguments() : List(NodeKind::CallArguments) {}
+  static bool classof(const Node *N) {
+return N->kind() <= NodeKind::CallArguments;
+  }
+  std::vector arguments();
+  std::vector> argumentsAndCommas();
+};
+
+/// A function call. C++ [expr.call]
+/// call-expression:
+///   expression '(' call-arguments ')'
+/// e.g `f(1, '2')` or `this->Base::f()`
+class CallExpression final : public Expression {
+public:
+  CallExpression() : Expression(NodeKind::CallExpression) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::CallExpression;
+  }
+  Expression *callee();
+  Leaf *openParen();
+  CallArguments *arguments();
+  Leaf *closeParen();
+};
+
 /// Models a parenthesized expression `(E)`. C++ [expr.prim.paren]
 /// e.g. `(3 + 2)` in `a = 1 + (3 + 2);`
 class ParenExpression final : public Expression {

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index f027a60030b7..2e3dbc6c6fbd 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -184,10 +184,11 @@ static syntax::NodeKind getOperatorNodeKind(const 
CXXOperatorCallExpr &E) {
   case OO_Array_New:
   case OO_Array_Delete:
   case OO_Coawait:
-  case OO_Call:
   case OO_Subscript:
   case OO_Arrow:
 return syntax::NodeKind::UnknownExpression;
+  case OO_Call:
+return syntax::NodeKind::CallExpression;
   case OO_Conditional: // not overloadable
   case NUM_OVERLOADED_OPERATORS:
   case OO_None:
@@ -1042,6 +1043,46 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
+  syntax::CallArguments *buildCallArguments(CallExpr::arg_range Args) {
+for (const auto &Arg : Args) {
+  Builder.markExprChild(Arg, syntax::NodeRole::List_element);
+  const auto *DelimiterToken =
+  std::next(Builder.findToken(Arg->getEndLoc()));
+  if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
+Builder.markChildToken(DelimiterToken,
+   syntax::NodeRole::List_delimiter);
+}
+
+auto *Arguments = new (allocator()) syntax::CallArguments;
+if (!Args.empty())
+  Builder.foldNode(Builder.getRange((*Args.begin())->getBeginLoc(),
+(*(Args.end() - 1))->getEndLoc()),
+   Arguments, nullptr);
+
+return Arguments;
+  }
+
+  bool WalkUpFromCallExpr(CallExpr *S) {
+Builder.markExprChild(S->getCallee(),
+  syntax::NodeRole::CallExpression_callee);
+
+const auto *LParenToken =
+std::next(Builder.findToken(S->getCa

[clang] 3b75f65 - [SyntaxTree] Fix C++ versions on tests of `BuildTreeTest.cpp`

2020-08-26 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-26T07:19:49Z
New Revision: 3b75f65e6ba4862977fd193ddb4918c4fc380fa5

URL: 
https://github.com/llvm/llvm-project/commit/3b75f65e6ba4862977fd193ddb4918c4fc380fa5
DIFF: 
https://github.com/llvm/llvm-project/commit/3b75f65e6ba4862977fd193ddb4918c4fc380fa5.diff

LOG: [SyntaxTree] Fix C++ versions on tests of `BuildTreeTest.cpp`

Differential Revision: https://reviews.llvm.org/D86591

Added: 


Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 6ab01e8f65f0..e386646ee667 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -2870,20 +2870,32 @@ TEST_P(SyntaxTreeTest, Namespace_Nested) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 namespace a { namespace b {} }
+)cpp",
+  R"txt(
+TranslationUnit Detached
+`-NamespaceDefinition
+  |-'namespace'
+  |-'a'
+  |-'{'
+  |-NamespaceDefinition
+  | |-'namespace'
+  | |-'b'
+  | |-'{'
+  | `-'}'
+  `-'}'
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, Namespace_NestedDefinition) {
+  if (!GetParam().isCXX17OrLater()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
 namespace a::b {}
 )cpp",
   R"txt(
 TranslationUnit Detached
-|-NamespaceDefinition
-| |-'namespace'
-| |-'a'
-| |-'{'
-| |-NamespaceDefinition
-| | |-'namespace'
-| | |-'b'
-| | |-'{'
-| | `-'}'
-| `-'}'
 `-NamespaceDefinition
   |-'namespace'
   |-'a'
@@ -3006,7 +3018,7 @@ UsingDeclaration
 }
 
 TEST_P(SyntaxTreeTest, UsingTypeAlias) {
-  if (!GetParam().isCXX()) {
+  if (!GetParam().isCXX11OrLater()) {
 return;
   }
   EXPECT_TRUE(treeDumpEqual(
@@ -3307,7 +3319,7 @@ TranslationUnit Detached
 }
 
 TEST_P(SyntaxTreeTest, VariableTemplateDeclaration) {
-  if (!GetParam().isCXX()) {
+  if (!GetParam().isCXX14OrLater()) {
 return;
   }
   EXPECT_TRUE(treeDumpEqual(
@@ -3616,20 +3628,32 @@ TEST_P(SyntaxTreeTest, StaticAssert) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 static_assert(true, "message");
+)cpp",
+  R"txt(
+TranslationUnit Detached
+`-StaticAssertDeclaration
+  |-'static_assert'
+  |-'('
+  |-BoolLiteralExpression StaticAssertDeclaration_condition
+  | `-'true' LiteralToken
+  |-','
+  |-StringLiteralExpression StaticAssertDeclaration_message
+  | `-'"message"' LiteralToken
+  |-')'
+  `-';'
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, StaticAssert_WithoutMessage) {
+  if (!GetParam().isCXX17OrLater()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
 static_assert(true);
 )cpp",
   R"txt(
 TranslationUnit Detached
-|-StaticAssertDeclaration
-| |-'static_assert'
-| |-'('
-| |-BoolLiteralExpression StaticAssertDeclaration_condition
-| | `-'true' LiteralToken
-| |-','
-| |-StringLiteralExpression StaticAssertDeclaration_message
-| | `-'"message"' LiteralToken
-| |-')'
-| `-';'
 `-StaticAssertDeclaration
   |-'static_assert'
   |-'('
@@ -4165,7 +4189,7 @@ SimpleDeclaration
 }
 
 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) {
-  if (!GetParam().isCXX()) {
+  if (!GetParam().isCXX11OrLater()) {
 return;
   }
   EXPECT_TRUE(treeDumpEqualOnAnnotations(



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] dc3d474 - [SyntaxTree] Migrate `ParamatersAndQualifiers` to use the new List API

2020-08-26 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-26T16:46:19Z
New Revision: dc3d4743277b47c0bc8cddbeb4b5e265252ee304

URL: 
https://github.com/llvm/llvm-project/commit/dc3d4743277b47c0bc8cddbeb4b5e265252ee304
DIFF: 
https://github.com/llvm/llvm-project/commit/dc3d4743277b47c0bc8cddbeb4b5e265252ee304.diff

LOG: [SyntaxTree] Migrate `ParamatersAndQualifiers` to use the new List API

Fix: Add missing `List::getTerminationKind()`, `List::canBeEmpty()`,
`List::getDelimiterTokenKind()` for `CallArguments`.

Differential Revision: https://reviews.llvm.org/D86600

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/lib/Tooling/Syntax/Tree.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 9a14aac130b4..38f936f603dd 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -99,6 +99,7 @@ enum class NodeKind : uint16_t {
   ParametersAndQualifiers,
   MemberPointer,
   UnqualifiedId,
+  ParameterDeclarationList,
   // Nested Name Specifiers.
   NestedNameSpecifier,
   GlobalNameSpecifier,
@@ -173,7 +174,7 @@ enum class NodeRole : uint8_t {
   ExplicitTemplateInstantiation_declaration,
   ArraySubscript_sizeExpression,
   TrailingReturnType_declarator,
-  ParametersAndQualifiers_parameter,
+  ParametersAndQualifiers_parameters,
   ParametersAndQualifiers_trailingReturn,
   IdExpression_id,
   IdExpression_qualifier,
@@ -988,6 +989,19 @@ class TrailingReturnType final : public Tree {
   SimpleDeclarator *declarator();
 };
 
+/// Models a `parameter-declaration-list` which appears within
+/// `parameters-and-qualifiers`. See C++ [dcl.fct]
+class ParameterDeclarationList final : public List {
+public:
+  ParameterDeclarationList() : List(NodeKind::ParameterDeclarationList) {}
+  static bool classof(const Node *N) {
+return N->kind() == NodeKind::ParameterDeclarationList;
+  }
+  std::vector parameterDeclarations();
+  std::vector>
+  parametersAndCommas();
+};
+
 /// Parameter list for a function type and a trailing return type, if the
 /// function has one.
 /// E.g.:
@@ -1006,8 +1020,7 @@ class ParametersAndQualifiers final : public Tree {
 return N->kind() == NodeKind::ParametersAndQualifiers;
   }
   Leaf *lparen();
-  /// FIXME: use custom iterator instead of 'vector'.
-  std::vector parameters();
+  ParameterDeclarationList *parameters();
   Leaf *rparen();
   TrailingReturnType *trailingReturn();
 };

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 2e3dbc6c6fbd..deae46d58eee 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -1209,11 +1209,29 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
+  syntax::ParameterDeclarationList *
+  buildParameterDeclarationList(ArrayRef Params) {
+for (auto *P : Params) {
+  Builder.markChild(P, syntax::NodeRole::List_element);
+  const auto *DelimiterToken = 
std::next(Builder.findToken(P->getEndLoc()));
+  if (DelimiterToken->kind() == clang::tok::TokenKind::comma)
+Builder.markChildToken(DelimiterToken,
+   syntax::NodeRole::List_delimiter);
+}
+auto *Parameters = new (allocator()) syntax::ParameterDeclarationList;
+if (!Params.empty())
+  Builder.foldNode(Builder.getRange(Params.front()->getBeginLoc(),
+Params.back()->getEndLoc()),
+   Parameters, nullptr);
+return Parameters;
+  }
+
   bool WalkUpFromFunctionTypeLoc(FunctionTypeLoc L) {
 Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen);
-for (auto *P : L.getParams()) {
-  Builder.markChild(P, 
syntax::NodeRole::ParametersAndQualifiers_parameter);
-}
+
+Builder.markChild(buildParameterDeclarationList(L.getParams()),
+  syntax::NodeRole::ParametersAndQualifiers_parameters);
+
 Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen);
 Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getEndLoc()),
  new (allocator()) syntax::ParametersAndQualifiers, L);

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index 6a7be0f0ea79..984cc5d1f1fc 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -134,6 +134,8 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeKind 
K) {
 return OS << "MemberExpression";
   case NodeKind::CallArguments:
 return OS << "CallArguments";
+  case NodeKind::ParameterDeclarationList:
+return OS << "ParameterDeclarationList";
   }
   llvm_unreachable("unknown node kind");
 }
@@ -200,8 +

[clang] ac87a0b - [SyntaxTree][NFC][Style] Functions start with lowercase

2020-08-27 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-27T12:55:24Z
New Revision: ac87a0b5873cc14b23eeb25a0586b26cc5c2c33f

URL: 
https://github.com/llvm/llvm-project/commit/ac87a0b5873cc14b23eeb25a0586b26cc5c2c33f
DIFF: 
https://github.com/llvm/llvm-project/commit/ac87a0b5873cc14b23eeb25a0586b26cc5c2c33f.diff

LOG: [SyntaxTree][NFC][Style] Functions start with lowercase

Differential Revision: https://reviews.llvm.org/D86682

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 9e2f8178df90..b07e9c3faf9d 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -820,7 +820,7 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   }
 
   syntax::NameSpecifier *
-  BuildNameSpecifier(const NestedNameSpecifierLoc &NNSLoc) {
+  buildNameSpecifier(const NestedNameSpecifierLoc &NNSLoc) {
 assert(NNSLoc.hasQualifier());
 auto NameSpecifierTokens =
 Builder.getRange(getLocalSourceRange(NNSLoc)).drop_back();
@@ -870,7 +870,7 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 if (!QualifierLoc)
   return true;
 for (auto it = QualifierLoc; it; it = it.getPrefix()) {
-  auto *NS = BuildNameSpecifier(it);
+  auto *NS = buildNameSpecifier(it);
   if (!NS)
 return false;
   Builder.markChild(NS, syntax::NodeRole::ListElement);
@@ -1221,7 +1221,7 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 if (!L.getTypePtr()->hasTrailingReturn())
   return WalkUpFromFunctionTypeLoc(L);
 
-auto *TrailingReturnTokens = BuildTrailingReturn(L);
+auto *TrailingReturnTokens = buildTrailingReturn(L);
 // Finish building the node for parameters.
 Builder.markChild(TrailingReturnTokens, syntax::NodeRole::TrailingReturn);
 return WalkUpFromFunctionTypeLoc(L);
@@ -1459,7 +1459,7 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   }
 
   /// Returns the range of the built node.
-  syntax::TrailingReturnType *BuildTrailingReturn(FunctionProtoTypeLoc L) {
+  syntax::TrailingReturnType *buildTrailingReturn(FunctionProtoTypeLoc L) {
 assert(L.getTypePtr()->hasTrailingReturn());
 
 auto ReturnedType = L.getReturnLoc();



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] fda3fa8 - [SyntaxTree][NFC] Append "get" to syntax Nodes accessor names

2020-08-27 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-27T12:55:23Z
New Revision: fda3fa822cb6812c8db63f7cee4a8387e71e66ff

URL: 
https://github.com/llvm/llvm-project/commit/fda3fa822cb6812c8db63f7cee4a8387e71e66ff
DIFF: 
https://github.com/llvm/llvm-project/commit/fda3fa822cb6812c8db63f7cee4a8387e71e66ff.diff

LOG: [SyntaxTree][NFC] Append "get" to syntax Nodes accessor names

Differential Revision: https://reviews.llvm.org/D86679

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/Nodes.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 4a483111aad3..a6505c8167ee 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -271,9 +271,9 @@ class NestedNameSpecifier final : public List {
   static bool classof(const Node *N) {
 return N->kind() <= NodeKind::NestedNameSpecifier;
   }
-  std::vector specifiers();
+  std::vector getSpecifiers();
   std::vector>
-  specifiersAndDoubleColons();
+  getSpecifiersAndDoubleColons();
 };
 
 /// Models an `unqualified-id`. C++ [expr.prim.id.unqual]
@@ -299,9 +299,9 @@ class IdExpression final : public Expression {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::IdExpression;
   }
-  NestedNameSpecifier *qualifier();
-  Leaf *templateKeyword();
-  UnqualifiedId *unqualifiedId();
+  NestedNameSpecifier *getQualifier();
+  Leaf *getTemplateKeyword();
+  UnqualifiedId *getUnqualifiedId();
 };
 
 /// An expression of an unknown kind, i.e. one not currently handled by the
@@ -321,7 +321,7 @@ class ThisExpression final : public Expression {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::ThisExpression;
   }
-  Leaf *thisKeyword();
+  Leaf *getThisKeyword();
 };
 
 /// Models arguments of a function call.
@@ -335,8 +335,8 @@ class CallArguments final : public List {
   static bool classof(const Node *N) {
 return N->kind() <= NodeKind::CallArguments;
   }
-  std::vector arguments();
-  std::vector> argumentsAndCommas();
+  std::vector getArguments();
+  std::vector> getArgumentsAndCommas();
 };
 
 /// A function call. C++ [expr.call]
@@ -349,10 +349,10 @@ class CallExpression final : public Expression {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::CallExpression;
   }
-  Expression *callee();
-  Leaf *openParen();
-  CallArguments *arguments();
-  Leaf *closeParen();
+  Expression *getCallee();
+  Leaf *getOpenParen();
+  CallArguments *getArguments();
+  Leaf *getCloseParen();
 };
 
 /// Models a parenthesized expression `(E)`. C++ [expr.prim.paren]
@@ -363,9 +363,9 @@ class ParenExpression final : public Expression {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::ParenExpression;
   }
-  Leaf *openParen();
-  Expression *subExpression();
-  Leaf *closeParen();
+  Leaf *getOpenParen();
+  Expression *getSubExpression();
+  Leaf *getCloseParen();
 };
 
 /// Models a class member access. C++ [expr.ref]
@@ -382,10 +382,10 @@ class MemberExpression final : public Expression {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::MemberExpression;
   }
-  Expression *object();
-  Leaf *accessToken();
-  Leaf *templateKeyword();
-  IdExpression *member();
+  Expression *getObject();
+  Leaf *getAccessToken();
+  Leaf *getTemplateKeyword();
+  IdExpression *getMember();
 };
 
 /// Expression for literals. C++ [lex.literal]
@@ -404,7 +404,7 @@ class LiteralExpression : public Expression {
N->kind() == NodeKind::CharUserDefinedLiteralExpression ||
N->kind() == NodeKind::StringUserDefinedLiteralExpression;
   }
-  Leaf *literalToken();
+  Leaf *getLiteralToken();
 };
 
 /// Expression for integer literals. C++ [lex.icon]
@@ -539,8 +539,8 @@ class UnaryOperatorExpression : public Expression {
 return N->kind() == NodeKind::PrefixUnaryOperatorExpression ||
N->kind() == NodeKind::PostfixUnaryOperatorExpression;
   }
-  Leaf *operatorToken();
-  Expression *operand();
+  Leaf *getOperatorToken();
+  Expression *getOperand();
 };
 
 ///  
@@ -588,9 +588,9 @@ class BinaryOperatorExpression final : public Expression {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::BinaryOperatorExpression;
   }
-  Expression *lhs();
-  Leaf *operatorToken();
-  Expression *rhs();
+  Expression *getLhs();
+  Leaf *getOperatorToken();
+  Expression *getRhs();
 };
 
 /// An abstract node for C++ statements, e.g. 'while', 'if', etc.
@@ -639,8 +639,8 @@ class SwitchStatement final : public Statement {
   static bool classof(const Node *N) {
 return N->kind() == NodeKind::SwitchStatement;
   }
-  Leaf *switchKeyword();
-  Statement *body();
+  Leaf *getSwitchKeyword();
+  Statement *getBody();
 };
 
 /// case : 
@@ -650,9 +650,9 @@ class CaseStatement final : public

[clang] 38bc006 - [SyntaxTree][NFC] Refactor function templates into functions taking base class

2020-08-28 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-28T12:19:38Z
New Revision: 38bc0060e60fef5395c23b8b75163e5bdee23af6

URL: 
https://github.com/llvm/llvm-project/commit/38bc0060e60fef5395c23b8b75163e5bdee23af6
DIFF: 
https://github.com/llvm/llvm-project/commit/38bc0060e60fef5395c23b8b75163e5bdee23af6.diff

LOG: [SyntaxTree][NFC] Refactor function templates into functions taking base 
class

The refactored functions were
* `isReponsibleForCreatingDeclaration`
* `getQualifiedNameStart`

Differential Revision: https://reviews.llvm.org/D86719

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index b07e9c3faf9d..2e9e74401e71 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -197,18 +197,57 @@ static syntax::NodeKind getOperatorNodeKind(const 
CXXOperatorCallExpr &E) {
   llvm_unreachable("Unknown OverloadedOperatorKind enum");
 }
 
+/// Get the start of the qualified name. In the examples below it gives the
+/// location of the `^`:
+/// `int ^a;`
+/// `int ^a::S::f(){}`
+static SourceLocation getQualifiedNameStart(NamedDecl *D) {
+  assert((isa(D)) &&
+ "only DeclaratorDecl and TypedefNameDecl are supported.");
+
+  auto DN = D->getDeclName();
+  bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo();
+  if (IsAnonymous)
+return SourceLocation();
+
+  if (const auto *DD = dyn_cast(D)) {
+if (DD->getQualifierLoc()) {
+  return DD->getQualifierLoc().getBeginLoc();
+}
+  }
+
+  return D->getLocation();
+}
+
+/// Gets the range of the initializer inside an init-declarator C++ [dcl.decl].
+/// `int a;` -> range of ``,
+/// `int *a = nullptr` -> range of `= nullptr`.
+/// `int a{}` -> range of `{}`.
+/// `int a()` -> range of `()`.
+static SourceRange getInitializerRange(Decl *D) {
+  if (auto *V = dyn_cast(D)) {
+auto *I = V->getInit();
+// Initializers in range-based-for are not part of the declarator
+if (I && !V->isCXXForRangeDecl())
+  return I->getSourceRange();
+  }
+
+  return SourceRange();
+}
+
 /// Gets the range of declarator as defined by the C++ grammar. E.g.
 /// `int a;` -> range of `a`,
 /// `int *a;` -> range of `*a`,
 /// `int a[10];` -> range of `a[10]`,
 /// `int a[1][2][3];` -> range of `a[1][2][3]`,
 /// `int *a = nullptr` -> range of `*a = nullptr`.
-/// FIMXE: \p Name must be a source range, e.g. for `operator+`.
+/// `int S::f(){}` -> range of `S::f()`.
+/// FIXME: \p Name must be a source range, e.g. for `operator+`.
 static SourceRange getDeclaratorRange(const SourceManager &SM, TypeLoc T,
   SourceLocation Name,
   SourceRange Initializer) {
   SourceLocation Start = GetStartLoc().Visit(T);
-  SourceLocation End = T.getSourceRange().getEnd();
+  SourceLocation End = T.getEndLoc();
   assert(End.isValid());
   if (Name.isValid()) {
 if (Start.isInvalid())
@@ -378,11 +417,9 @@ class syntax::TreeBuilder {
 
   /// Returns true if \p D is the last declarator in a chain and is thus
   /// reponsible for creating SimpleDeclaration for the whole chain.
-  template 
-  bool isResponsibleForCreatingDeclaration(const T *D) const {
-static_assert((std::is_base_of::value ||
-   std::is_base_of::value),
-  "only DeclaratorDecl and TypedefNameDecl are supported.");
+  bool isResponsibleForCreatingDeclaration(const Decl *D) const {
+assert((isa(D)) &&
+   "only DeclaratorDecl and TypedefNameDecl are supported.");
 
 const Decl *Next = D->getNextDeclInContext();
 
@@ -390,15 +427,14 @@ class syntax::TreeBuilder {
 if (Next == nullptr) {
   return true;
 }
-const auto *NextT = dyn_cast(Next);
 
 // Next sibling is not the same type, this one is responsible.
-if (NextT == nullptr) {
+if (D->getKind() != Next->getKind()) {
   return true;
 }
 // Next sibling doesn't begin at the same loc, it must be a 
diff erent
 // declaration, so this declarator is responsible.
-if (NextT->getBeginLoc() != D->getBeginLoc()) {
+if (Next->getBeginLoc() != D->getBeginLoc()) {
   return true;
 }
 
@@ -1405,43 +1441,12 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   }
 
 private:
-  template  SourceLocation getQualifiedNameStart(T *D) {
-static_assert((std::is_base_of::value ||
-   std::is_base_of::value),
-  "only DeclaratorDecl and TypedefNameDecl are supported.");
-
-auto DN = D->getDeclName();
-bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo();
-if (IsAnonymous)
-  return SourceLocation();
-
-if (const auto *DD = dyn_cast(D)) {
-  if (DD->getQualifierLoc()) {
-return DD->getQualifierLoc().getBeginL

[clang] a146195 - [SyntaxTree] Add coverage for declarators and init-declarators

2020-08-28 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-08-28T12:19:38Z
New Revision: a1461953f4efe574e3fdecfbae68bd18707748fb

URL: 
https://github.com/llvm/llvm-project/commit/a1461953f4efe574e3fdecfbae68bd18707748fb
DIFF: 
https://github.com/llvm/llvm-project/commit/a1461953f4efe574e3fdecfbae68bd18707748fb.diff

LOG: [SyntaxTree] Add coverage for declarators and init-declarators

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 2e9e74401e71..a9f326439a2a 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -200,6 +200,7 @@ static syntax::NodeKind getOperatorNodeKind(const 
CXXOperatorCallExpr &E) {
 /// Get the start of the qualified name. In the examples below it gives the
 /// location of the `^`:
 /// `int ^a;`
+/// `int *^a;`
 /// `int ^a::S::f(){}`
 static SourceLocation getQualifiedNameStart(NamedDecl *D) {
   assert((isa(D)) &&
@@ -242,7 +243,7 @@ static SourceRange getInitializerRange(Decl *D) {
 /// `int a[1][2][3];` -> range of `a[1][2][3]`,
 /// `int *a = nullptr` -> range of `*a = nullptr`.
 /// `int S::f(){}` -> range of `S::f()`.
-/// FIXME: \p Name must be a source range, e.g. for `operator+`.
+/// FIXME: \p Name must be a source range.
 static SourceRange getDeclaratorRange(const SourceManager &SM, TypeLoc T,
   SourceLocation Name,
   SourceRange Initializer) {

diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index a07187e22e93..aab20008a497 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -3123,6 +3123,35 @@ SimpleDeclaration
 )txt"}));
 }
 
+TEST_P(SyntaxTreeTest, OutOfLineMemberFunctionDefinition) {
+  if (!GetParam().isCXX11OrLater()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+struct S {
+  void f();
+};
+[[void S::f(){}]]
+)cpp",
+  {R"txt(
+SimpleDeclaration
+|-'void'
+|-SimpleDeclarator Declarator
+| |-NestedNameSpecifier
+| | |-IdentifierNameSpecifier ListElement
+| | | `-'S'
+| | `-'::' ListDelimiter
+| |-'f'
+| `-ParametersAndQualifiers
+|   |-'(' OpenParen
+|   `-')' CloseParen
+`-CompoundStatement
+  |-'{' OpenParen
+  `-'}' CloseParen
+)txt"}));
+}
+
 TEST_P(SyntaxTreeTest, ConversionMemberFunction) {
   if (!GetParam().isCXX()) {
 return;
@@ -3792,6 +3821,53 @@ TranslationUnit Detached
 )txt"));
 }
 
+TEST_P(SyntaxTreeTest, InitDeclarator_Brace) {
+  if (!GetParam().isCXX11OrLater()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+  R"cpp(
+int a {};
+)cpp",
+  R"txt(
+TranslationUnit Detached
+`-SimpleDeclaration
+  |-'int'
+  |-SimpleDeclarator Declarator
+  | |-'a'
+  | `-UnknownExpression
+  |   `-UnknownExpression
+  | |-'{'
+  | `-'}'
+  `-';'
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, InitDeclarator_Paren) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+struct S {
+  S(int);
+};
+[[S s(1);]]
+)cpp",
+  {R"txt(
+SimpleDeclaration
+|-'S'
+|-SimpleDeclarator Declarator
+| `-UnknownExpression
+|   |-'s'
+|   |-'('
+|   |-IntegerLiteralExpression
+|   | `-'1' LiteralToken
+|   `-')'
+`-';'
+)txt"}));
+}
+
 TEST_P(SyntaxTreeTest, ArrayDeclarator_Simple) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 1a7a2cd - [Ignore Expressions][NFC] Refactor to better use `IgnoreExpr.h` and nits

2020-09-07 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-07T09:32:30Z
New Revision: 1a7a2cd7474e6d321120ffe7ca9c52163eb228f0

URL: 
https://github.com/llvm/llvm-project/commit/1a7a2cd7474e6d321120ffe7ca9c52163eb228f0
DIFF: 
https://github.com/llvm/llvm-project/commit/1a7a2cd7474e6d321120ffe7ca9c52163eb228f0.diff

LOG: [Ignore Expressions][NFC] Refactor to better use `IgnoreExpr.h` and nits

This change groups
* Rename: `ignoreParenBaseCasts` -> `IgnoreParenBaseCasts` for uniformity
* Rename: `IgnoreConversionOperator` -> `IgnoreConversionOperatorSingleStep` 
for uniformity
* Inline `IgnoreNoopCastsSingleStep` into a lambda inside `IgnoreNoopCasts`
* Refactor `IgnoreUnlessSpelledInSource` to make adequate use of 
`IgnoreExprNodes`

Differential Revision: https://reviews.llvm.org/D86880

Added: 


Modified: 
clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
clang/include/clang/AST/Expr.h
clang/lib/AST/Expr.cpp
clang/lib/CodeGen/CGExprCXX.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/StaticAnalyzer/Core/CallEvent.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
index 04dc61f02df1..44ae380b63b2 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
@@ -338,7 +338,7 @@ void UseAutoCheck::replaceIterators(const DeclStmt *D, 
ASTContext *Context) {
 
 // Drill down to the as-written initializer.
 const Expr *E = (*Construct->arg_begin())->IgnoreParenImpCasts();
-if (E != E->IgnoreConversionOperator()) {
+if (E != E->IgnoreConversionOperatorSingleStep()) {
   // We hit a conversion operator. Early-out now as they imply an implicit
   // conversion from a 
diff erent type. Could also mean an explicit
   // conversion from the same type but that's pretty rare.

diff  --git 
a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
index 9dcb10b9d20c..7e8ba4eb90c6 100644
--- a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
@@ -205,7 +205,7 @@ std::string compareExpressionToZero(const 
MatchFinder::MatchResult &Result,
 
 std::string replacementExpression(const MatchFinder::MatchResult &Result,
   bool Negated, const Expr *E) {
-  E = E->ignoreParenBaseCasts();
+  E = E->IgnoreParenBaseCasts();
   if (const auto *EC = dyn_cast(E))
 E = EC->getSubExpr();
 

diff  --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 5edca2593789..26e52ad367f8 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -867,9 +867,9 @@ class Expr : public ValueStmt {
 
   /// Skip conversion operators. If this Expr is a call to a conversion
   /// operator, return the argument.
-  Expr *IgnoreConversionOperator() LLVM_READONLY;
-  const Expr *IgnoreConversionOperator() const {
-return const_cast(this)->IgnoreConversionOperator();
+  Expr *IgnoreConversionOperatorSingleStep() LLVM_READONLY;
+  const Expr *IgnoreConversionOperatorSingleStep() const {
+return const_cast(this)->IgnoreConversionOperatorSingleStep();
   }
 
   /// Skip past any parentheses and lvalue casts which might surround this
@@ -901,9 +901,9 @@ class Expr : public ValueStmt {
   /// * What IgnoreParens() skips
   /// * CastExpr which represent a derived-to-base cast (CK_DerivedToBase,
   ///   CK_UncheckedDerivedToBase and CK_NoOp)
-  Expr *ignoreParenBaseCasts() LLVM_READONLY;
-  const Expr *ignoreParenBaseCasts() const {
-return const_cast(this)->ignoreParenBaseCasts();
+  Expr *IgnoreParenBaseCasts() LLVM_READONLY;
+  const Expr *IgnoreParenBaseCasts() const {
+return const_cast(this)->IgnoreParenBaseCasts();
   }
 
   /// Determine whether this expression is a default function argument.

diff  --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 1029acbf68cd..15f3df0fd216 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -40,7 +40,7 @@ using namespace clang;
 const Expr *Expr::getBestDynamicClassTypeExpr() const {
   const Expr *E = this;
   while (true) {
-E = E->ignoreParenBaseCasts();
+E = E->IgnoreParenBaseCasts();
 
 // Follow the RHS of a comma operator.
 if (auto *BO = dyn_cast(E)) {
@@ -2780,29 +2780,6 @@ QualType Expr::findBoundMemberType(const Expr *expr) {
   return QualType();
 }
 
-static Expr *IgnoreNoopCastsSingleStep(const ASTContext &Ctx, Expr *E) {
-  if (auto *CE = dyn_cast(E)) {
-// We ignore integer <-> casts that are of the same width, ptr<->ptr and
-// ptr<->int casts of the same width. We also ignore all identity casts.
-Expr *SubExpr = CE->g

[clang] 81aa66f - Extract infrastructure to ignore intermediate expressions into `clang/AST/IgnoreExpr.h`

2020-09-07 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-07T09:32:30Z
New Revision: 81aa66f65f504af18982baa078a5f3f7d2aa88fa

URL: 
https://github.com/llvm/llvm-project/commit/81aa66f65f504af18982baa078a5f3f7d2aa88fa
DIFF: 
https://github.com/llvm/llvm-project/commit/81aa66f65f504af18982baa078a5f3f7d2aa88fa.diff

LOG: Extract infrastructure to ignore intermediate expressions into 
`clang/AST/IgnoreExpr.h`

Rationale:
This allows users to use `IgnoreExprNodes` and `Ignore*SingleStep` outside of
`clang/AST/Expr.cpp`.

Minor:
Rename `IgnoreImp...SingleStep`  into `IgnoreImplicit...SingleStep`.

Differential Revision: https://reviews.llvm.org/D86778

Added: 
clang/include/clang/AST/IgnoreExpr.h
clang/lib/AST/IgnoreExpr.cpp

Modified: 
clang/lib/AST/CMakeLists.txt
clang/lib/AST/Expr.cpp

Removed: 




diff  --git a/clang/include/clang/AST/IgnoreExpr.h 
b/clang/include/clang/AST/IgnoreExpr.h
new file mode 100644
index ..15d31f3af995
--- /dev/null
+++ b/clang/include/clang/AST/IgnoreExpr.h
@@ -0,0 +1,61 @@
+//===--- IgnoreExpr.h - Ignore intermediate Expressions -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines common functions to ignore intermediate expression nodes
+//
+//===--===//
+
+#ifndef LLVM_CLANG_AST_IGNOREEXPR_H
+#define LLVM_CLANG_AST_IGNOREEXPR_H
+
+#include "clang/AST/Expr.h"
+
+namespace clang {
+namespace detail {
+/// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *,
+/// Return Fn_n(...(Fn_1(E)))
+inline Expr *IgnoreExprNodesImpl(Expr *E) { return E; };
+template 
+Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) {
+  return IgnoreExprNodesImpl(Fn(E), std::forward(Fns)...);
+}
+} // namespace detail
+
+/// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *,
+/// Recursively apply each of the functions to E until reaching a fixed point.
+/// Note that a null E is valid; in this case nothing is done.
+template  Expr *IgnoreExprNodes(Expr *E, FnTys &&... Fns) {
+  Expr *LastE = nullptr;
+  while (E != LastE) {
+LastE = E;
+E = detail::IgnoreExprNodesImpl(E, std::forward(Fns)...);
+  }
+  return E;
+}
+
+Expr *IgnoreImplicitCastsSingleStep(Expr *E);
+
+Expr *IgnoreImplicitCastsExtraSingleStep(Expr *E);
+
+Expr *IgnoreCastsSingleStep(Expr *E);
+
+Expr *IgnoreLValueCastsSingleStep(Expr *E);
+
+Expr *IgnoreBaseCastsSingleStep(Expr *E);
+
+Expr *IgnoreImplicitSingleStep(Expr *E);
+
+Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E);
+
+Expr *IgnoreParensOnlySingleStep(Expr *E);
+
+Expr *IgnoreParensSingleStep(Expr *E);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_IGNOREEXPR_H

diff  --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 35099fd0dacf..dfd26fd97bc6 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -55,6 +55,7 @@ add_clang_library(clangAST
   ExternalASTMerger.cpp
   ExternalASTSource.cpp
   FormatString.cpp
+  IgnoreExpr.cpp
   InheritViz.cpp
   Interp/ByteCodeEmitter.cpp
   Interp/ByteCodeExprGen.cpp

diff  --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 8efd6837c541..1029acbf68cd 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/DependenceFlags.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/IgnoreExpr.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtVisitor.h"
@@ -2779,118 +2780,6 @@ QualType Expr::findBoundMemberType(const Expr *expr) {
   return QualType();
 }
 
-static Expr *IgnoreImpCastsSingleStep(Expr *E) {
-  if (auto *ICE = dyn_cast(E))
-return ICE->getSubExpr();
-
-  if (auto *FE = dyn_cast(E))
-return FE->getSubExpr();
-
-  return E;
-}
-
-static Expr *IgnoreImpCastsExtraSingleStep(Expr *E) {
-  // FIXME: Skip MaterializeTemporaryExpr and SubstNonTypeTemplateParmExpr in
-  // addition to what IgnoreImpCasts() skips to account for the current
-  // behaviour of IgnoreParenImpCasts().
-  Expr *SubE = IgnoreImpCastsSingleStep(E);
-  if (SubE != E)
-return SubE;
-
-  if (auto *MTE = dyn_cast(E))
-return MTE->getSubExpr();
-
-  if (auto *NTTP = dyn_cast(E))
-return NTTP->getReplacement();
-
-  return E;
-}
-
-static Expr *IgnoreCastsSingleStep(Expr *E) {
-  if (auto *CE = dyn_cast(E))
-return CE->getSubExpr();
-
-  if (auto *FE = dyn_cast(E))
-return FE->getSubExpr();
-
-  if (auto *MTE = dyn_cast(E))
-return MTE->getSubExpr();
-
-  if (auto *NTTP = dyn_cast(E))
-return NTTP->getReplacement();
-
-  return E;
-}
-
-static 

[clang] 46f4439 - [SyntaxTree] Ignore implicit leaf `CXXConstructExpr`

2020-09-08 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-08T09:44:23Z
New Revision: 46f4439dc9bf9b8cfee0001b6752c3d074c83b00

URL: 
https://github.com/llvm/llvm-project/commit/46f4439dc9bf9b8cfee0001b6752c3d074c83b00
DIFF: 
https://github.com/llvm/llvm-project/commit/46f4439dc9bf9b8cfee0001b6752c3d074c83b00.diff

LOG: [SyntaxTree] Ignore implicit leaf `CXXConstructExpr`

Differential Revision: https://reviews.llvm.org/D86700

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index e5389ae4eff4..72083eeefa31 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -1132,6 +1132,14 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
+  bool WalkUpFromCXXConstructExpr(CXXConstructExpr *S) {
+// Ignore the implicit calls to default constructors.
+if ((S->getNumArgs() == 0 || isa(S->getArg(0))) &&
+S->getParenOrBraceRange().isInvalid())
+  return true;
+return RecursiveASTVisitor::WalkUpFromCXXConstructExpr(S);
+  }
+
   bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
 // To construct a syntax tree of the same shape for calls to built-in and
 // user-defined operators, ignore the `DeclRefExpr` that refers to the

diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index fe89e0d7d1a2..00e18057d7be 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -548,9 +548,6 @@ namespace n {
   struct S { };
 }
 void test() {
-  // FIXME: Remove the `UnknownExpression` wrapping `s1` and `s2`. This
-  // `UnknownExpression` comes from a leaf `CXXConstructExpr` in the
-  // ClangAST. We need to ignore leaf implicit nodes.
   [[::n::S s1]];
   [[n::S s2]];
 }
@@ -564,8 +561,7 @@ SimpleDeclaration
 | `-'::' ListDelimiter
 |-'S'
 `-SimpleDeclarator Declarator
-  `-UnknownExpression
-`-'s1'
+  `-'s1'
 )txt",
R"txt(
 SimpleDeclaration
@@ -575,8 +571,7 @@ SimpleDeclaration
 | `-'::' ListDelimiter
 |-'S'
 `-SimpleDeclarator Declarator
-  `-UnknownExpression
-`-'s2'
+  `-'s2'
 )txt"}));
 }
 
@@ -608,8 +603,7 @@ SimpleDeclaration
 | `-'::' ListDelimiter
 |-'S'
 `-SimpleDeclarator Declarator
-  `-UnknownExpression
-`-'s1'
+  `-'s1'
 )txt",
R"txt(
 SimpleDeclaration
@@ -623,8 +617,7 @@ SimpleDeclaration
 | `-'::' ListDelimiter
 |-'S'
 `-SimpleDeclarator Declarator
-  `-UnknownExpression
-`-'s2'
+  `-'s2'
 )txt"}));
 }
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 134455a - [SyntaxTree] Ignore implicit `CXXFunctionalCastExpr` wrapping constructor

2020-09-08 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-08T09:44:23Z
New Revision: 134455a07c1f1de4cff62a6afb4ccd98b98343ec

URL: 
https://github.com/llvm/llvm-project/commit/134455a07c1f1de4cff62a6afb4ccd98b98343ec
DIFF: 
https://github.com/llvm/llvm-project/commit/134455a07c1f1de4cff62a6afb4ccd98b98343ec.diff

LOG: [SyntaxTree] Ignore implicit `CXXFunctionalCastExpr` wrapping constructor

Differential Revision: https://reviews.llvm.org/D87229

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 72083eeefa31..bb2b1494793a 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/IgnoreExpr.h"
+#include "clang/AST/OperationKinds.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/TypeLoc.h"
@@ -60,9 +61,25 @@ static Expr *IgnoreImplicitConstructorSingleStep(Expr *E) {
   return E;
 }
 
+// In:
+// struct X {
+//   X(int)
+// };
+// X x = X(1);
+// Ignores the implicit `CXXFunctionalCastExpr` that wraps
+// `CXXConstructExpr X(1)`.
+static Expr *IgnoreCXXFunctionalCastExprWrappingConstructor(Expr *E) {
+  if (auto *F = dyn_cast(E)) {
+if (F->getCastKind() == CK_ConstructorConversion)
+  return F->getSubExpr();
+  }
+  return E;
+}
+
 static Expr *IgnoreImplicit(Expr *E) {
   return IgnoreExprNodes(E, IgnoreImplicitSingleStep,
- IgnoreImplicitConstructorSingleStep);
+ IgnoreImplicitConstructorSingleStep,
+ IgnoreCXXFunctionalCastExprWrappingConstructor);
 }
 
 LLVM_ATTRIBUTE_UNUSED

diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 00e18057d7be..7a106e9297b9 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -4069,7 +4069,6 @@ struct X {
   X(int);
 };
 X test() {
-  // FIXME: Remove `UnknownExpression` due to implicit `CXXFunctionalCastExpr`
   [[return X(1);]]
 }
 )cpp",
@@ -4077,12 +4076,11 @@ X test() {
 ReturnStatement Statement
 |-'return' IntroducerKeyword
 |-UnknownExpression ReturnValue
-| `-UnknownExpression
-|   |-'X'
-|   |-'('
-|   |-IntegerLiteralExpression
-|   | `-'1' LiteralToken
-|   `-')'
+| |-'X'
+| |-'('
+| |-IntegerLiteralExpression
+| | `-'1' LiteralToken
+| `-')'
 `-';'
 )txt"}));
 }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 2325d6b - [SyntaxTree] Ignore implicit non-leaf `CXXConstructExpr`

2020-09-08 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-08T09:44:23Z
New Revision: 2325d6b42f096bf93d2ab0bed7096759e5c96ce8

URL: 
https://github.com/llvm/llvm-project/commit/2325d6b42f096bf93d2ab0bed7096759e5c96ce8
DIFF: 
https://github.com/llvm/llvm-project/commit/2325d6b42f096bf93d2ab0bed7096759e5c96ce8.diff

LOG: [SyntaxTree] Ignore implicit non-leaf `CXXConstructExpr`

Differential Revision: https://reviews.llvm.org/D86699

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index a9f326439a2a..e5389ae4eff4 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -13,6 +13,7 @@
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/IgnoreExpr.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/TypeLoc.h"
@@ -44,8 +45,28 @@
 
 using namespace clang;
 
+// Ignores the implicit `CXXConstructExpr` for copy/move constructor calls
+// generated by the compiler, as well as in implicit conversions like the one
+// wrapping `1` in `X x = 1;`.
+static Expr *IgnoreImplicitConstructorSingleStep(Expr *E) {
+  if (auto *C = dyn_cast(E)) {
+auto NumArgs = C->getNumArgs();
+if (NumArgs == 1 || (NumArgs > 1 && isa(C->getArg(1 
{
+  Expr *A = C->getArg(0);
+  if (C->getParenOrBraceRange().isInvalid())
+return A;
+}
+  }
+  return E;
+}
+
+static Expr *IgnoreImplicit(Expr *E) {
+  return IgnoreExprNodes(E, IgnoreImplicitSingleStep,
+ IgnoreImplicitConstructorSingleStep);
+}
+
 LLVM_ATTRIBUTE_UNUSED
-static bool isImplicitExpr(Expr *E) { return E->IgnoreImplicit() != E; }
+static bool isImplicitExpr(Expr *E) { return IgnoreImplicit(E) != E; }
 
 namespace {
 /// Get start location of the Declarator from the TypeLoc.
@@ -740,7 +761,7 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   for (auto *D : DS->decls())
 Builder.noticeDeclWithoutSemicolon(D);
 } else if (auto *E = dyn_cast_or_null(S)) {
-  return RecursiveASTVisitor::TraverseStmt(E->IgnoreImplicit());
+  return RecursiveASTVisitor::TraverseStmt(IgnoreImplicit(E));
 }
 return RecursiveASTVisitor::TraverseStmt(S);
   }
@@ -1579,7 +1600,7 @@ void syntax::TreeBuilder::markStmtChild(Stmt *Child, 
NodeRole Role) {
 void syntax::TreeBuilder::markExprChild(Expr *Child, NodeRole Role) {
   if (!Child)
 return;
-  Child = Child->IgnoreImplicit();
+  Child = IgnoreImplicit(Child);
 
   syntax::Tree *ChildNode = Mapping.find(Child);
   assert(ChildNode != nullptr);

diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index aab20008a497..fe89e0d7d1a2 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -1745,19 +1745,15 @@ TEST_P(SyntaxTreeTest, OverloadedOperator_Plus) {
 struct X {
   friend X operator+(X, const X&);
 };
-// FIXME: Remove additional `UnknownExpression` wrapping `x`. For that, ignore
-// implicit copy constructor called on `x`. This should've been ignored 
already,
-// as we `IgnoreImplicit` when traversing an `Stmt`.
 void test(X x, X y) {
   [[x + y]];
 }
 )cpp",
   {R"txt(
 BinaryOperatorExpression Expression
-|-UnknownExpression LeftHandSide
-| `-IdExpression
-|   `-UnqualifiedId UnqualifiedId
-| `-'x'
+|-IdExpression LeftHandSide
+| `-UnqualifiedId UnqualifiedId
+|   `-'x'
 |-'+' OperatorToken
 `-IdExpression RightHandSide
   `-UnqualifiedId UnqualifiedId
@@ -3821,26 +3817,137 @@ TranslationUnit Detached
 )txt"));
 }
 
+TEST_P(SyntaxTreeTest, InitDeclarator_Equal) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+struct S { S(int);};
+void test() {
+  [[S s = 1]];
+}
+)cpp",
+  {R"txt(
+SimpleDeclaration
+|-'S'
+`-SimpleDeclarator Declarator
+  |-'s'
+  |-'='
+  `-IntegerLiteralExpression
+`-'1' LiteralToken
+)txt"}));
+}
+
 TEST_P(SyntaxTreeTest, InitDeclarator_Brace) {
   if (!GetParam().isCXX11OrLater()) {
 return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
-int a {};
+struct S { 
+  S();
+  S(int);
+  S(int, float);
+};
+void test(){
+  // FIXME: 's...' is a declarator and '{...}' is initializer
+  [[S s0{}]];
+  [[S s1{1}]];
+  [[S s2{1, 2.}]];
+}
 )cpp",
-  R"txt(
-TranslationUnit Detached
-`-SimpleDeclaration
-  |-'int'
-  |-SimpleDeclarator Declarator
-  | |-'a'
-  | `-UnknownExpression
-  |   `-UnknownExpression
-  | |-'{'
-  | `-'}'
-  `-';'
-)txt"));
+  {R"txt(
+SimpleDeclaration
+|-'S'
+`-SimpleDeclarator Declarator
+  `-UnknownExpression
+|-'s0'
+|-'{'
+`-'}'
+  )txt",

[clang] f5087d5 - [SyntaxTree] Fix crash on functions with default arguments.

2020-09-08 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-08T09:49:30Z
New Revision: f5087d5c7248104b6580c7b079ed5f227332c2ef

URL: 
https://github.com/llvm/llvm-project/commit/f5087d5c7248104b6580c7b079ed5f227332c2ef
DIFF: 
https://github.com/llvm/llvm-project/commit/f5087d5c7248104b6580c7b079ed5f227332c2ef.diff

LOG: [SyntaxTree] Fix crash on functions with default arguments.

* Do not visit `CXXDefaultArgExpr`
* To build `CallArguments` nodes, just go through non-default arguments

Differential Revision: https://reviews.llvm.org/D87249

Added: 


Modified: 
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index bb2b1494793a..1942290b5abc 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -154,6 +154,13 @@ struct GetStartLoc : TypeLocVisitor {
 };
 } // namespace
 
+static CallExpr::arg_range dropDefaultArgs(CallExpr::arg_range Args) {
+  auto firstDefaultArg = std::find_if(Args.begin(), Args.end(), [](auto it) {
+return isa(it);
+  });
+  return llvm::make_range(Args.begin(), firstDefaultArg);
+}
+
 static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E) {
   switch (E.getOperator()) {
   // Comparison
@@ -,7 +1118,11 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 return true;
   }
 
-  syntax::CallArguments *buildCallArguments(CallExpr::arg_range Args) {
+  /// Builds `CallArguments` syntax node from arguments that appear in source
+  /// code, i.e. not default arguments.
+  syntax::CallArguments *
+  buildCallArguments(CallExpr::arg_range ArgsAndDefaultArgs) {
+auto Args = dropDefaultArgs(ArgsAndDefaultArgs);
 for (const auto &Arg : Args) {
   Builder.markExprChild(Arg, syntax::NodeRole::ListElement);
   const auto *DelimiterToken =
@@ -1233,6 +1244,8 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
 }
   }
 
+  bool WalkUpFromCXXDefaultArgExpr(CXXDefaultArgExpr *S) { return true; }
+
   bool WalkUpFromNamespaceDecl(NamespaceDecl *S) {
 auto Tokens = Builder.getDeclarationRange(S);
 if (Tokens.front().kind() == tok::coloncolon) {

diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 7a106e9297b9..225885437267 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -2733,6 +2733,54 @@ CallExpression Expression
 )txt"}));
 }
 
+TEST_P(SyntaxTreeTest, CallExpression_DefaultArguments) {
+  if (!GetParam().isCXX11OrLater()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+void f(int i = 1, char c = '2');
+void test() {
+  [[f()]];
+  [[f(1)]];
+  [[f(1, '2')]];
+}
+)cpp",
+  {R"txt(
+CallExpression Expression
+|-IdExpression Callee
+| `-UnqualifiedId UnqualifiedId
+|   `-'f'
+|-'(' OpenParen
+`-')' CloseParen
+  )txt",
+   R"txt(
+CallExpression Expression
+|-IdExpression Callee
+| `-UnqualifiedId UnqualifiedId
+|   `-'f'
+|-'(' OpenParen
+|-CallArguments Arguments
+| `-IntegerLiteralExpression ListElement
+|   `-'1' LiteralToken
+`-')' CloseParen
+  )txt",
+   R"txt(
+CallExpression Expression
+|-IdExpression Callee
+| `-UnqualifiedId UnqualifiedId
+|   `-'f'
+|-'(' OpenParen
+|-CallArguments Arguments
+| |-IntegerLiteralExpression ListElement
+| | `-'1' LiteralToken
+| |-',' ListDelimiter
+| `-CharacterLiteralExpression ListElement
+|   `-''2'' LiteralToken
+`-')' CloseParen
+)txt"}));
+}
+
 TEST_P(SyntaxTreeTest, MultipleDeclaratorsGrouping) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
@@ -3986,6 +4034,56 @@ SimpleDeclaration
 )txt"}));
 }
 
+TEST_P(SyntaxTreeTest, InitDeclarator_Paren_DefaultArguments) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+  R"cpp(
+struct S {
+  S(int i = 1, float = 2.);
+};
+[[S s0;]]
+// FIXME: 's...' is a declarator and '(...)' is initializer
+[[S s1(1);]]
+[[S s2(1, 2.);]]
+)cpp",
+  {R"txt(
+SimpleDeclaration
+|-'S'
+|-SimpleDeclarator Declarator
+| `-'s0'
+`-';'
+  )txt",
+   R"txt(
+SimpleDeclaration
+|-'S'
+|-SimpleDeclarator Declarator
+| `-UnknownExpression
+|   |-'s1'
+|   |-'('
+|   |-IntegerLiteralExpression
+|   | `-'1' LiteralToken
+|   `-')'
+`-';'
+  )txt",
+   R"txt(
+SimpleDeclaration
+|-'S'
+|-SimpleDeclarator Declarator
+| `-UnknownExpression
+|   |-'s2'
+|   |-'('
+|   |-IntegerLiteralExpression
+|   | `-'1' LiteralToken
+|   |-','
+|   |-FloatingLiteralExpression
+|   | `-'2.' LiteralToken
+|   `-')'
+`-';'
+)txt"}));
+}
+
 TEST_P(SyntaxTreeTest, ImplicitConversion_Argument) {
   if (!GetParam().isCXX()) {
 return;
@@ -4114,6 +4212,48 @@ ReturnStatement Statement
 )txt"}));
 }
 
+TEST_P(SyntaxTreeTest, ConstructorCall_DefaultArguments) {
+  if (!GetParam().isCXX(

[clang] c0e5e3f - [Ignore Expressions] Fix performance regression by inlining `Ignore*SingleStep`

2020-09-09 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-09T07:32:40Z
New Revision: c0e5e3fbfa504c3792023d0db9008b08caa6b6d7

URL: 
https://github.com/llvm/llvm-project/commit/c0e5e3fbfa504c3792023d0db9008b08caa6b6d7
DIFF: 
https://github.com/llvm/llvm-project/commit/c0e5e3fbfa504c3792023d0db9008b08caa6b6d7.diff

LOG: [Ignore Expressions] Fix performance regression by inlining 
`Ignore*SingleStep`

We also add a `const` versions of `IgnoreExprNodes`

Differential Revision: https://reviews.llvm.org/D87278

Added: 


Modified: 
clang/include/clang/AST/IgnoreExpr.h
clang/lib/AST/CMakeLists.txt

Removed: 
clang/lib/AST/IgnoreExpr.cpp



diff  --git a/clang/include/clang/AST/IgnoreExpr.h 
b/clang/include/clang/AST/IgnoreExpr.h
index 0aeb547606a2..1c2b538e5b63 100644
--- a/clang/include/clang/AST/IgnoreExpr.h
+++ b/clang/include/clang/AST/IgnoreExpr.h
@@ -14,6 +14,7 @@
 #define LLVM_CLANG_AST_IGNOREEXPR_H
 
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 
 namespace clang {
 namespace detail {
@@ -38,23 +39,122 @@ template  Expr *IgnoreExprNodes(Expr 
*E, FnTys &&... Fns) {
   return E;
 }
 
-Expr *IgnoreImplicitCastsSingleStep(Expr *E);
+template 
+const Expr *IgnoreExprNodes(const Expr *E, FnTys &&...Fns) {
+  return const_cast(IgnoreExprNodes(E, std::forward(Fns)...));
+}
+
+inline Expr *IgnoreImplicitCastsSingleStep(Expr *E) {
+  if (auto *ICE = dyn_cast(E))
+return ICE->getSubExpr();
+
+  if (auto *FE = dyn_cast(E))
+return FE->getSubExpr();
+
+  return E;
+}
+
+inline Expr *IgnoreImplicitCastsExtraSingleStep(Expr *E) {
+  // FIXME: Skip MaterializeTemporaryExpr and SubstNonTypeTemplateParmExpr in
+  // addition to what IgnoreImpCasts() skips to account for the current
+  // behaviour of IgnoreParenImpCasts().
+  Expr *SubE = IgnoreImplicitCastsSingleStep(E);
+  if (SubE != E)
+return SubE;
+
+  if (auto *MTE = dyn_cast(E))
+return MTE->getSubExpr();
+
+  if (auto *NTTP = dyn_cast(E))
+return NTTP->getReplacement();
+
+  return E;
+}
+
+inline Expr *IgnoreCastsSingleStep(Expr *E) {
+  if (auto *CE = dyn_cast(E))
+return CE->getSubExpr();
+
+  if (auto *FE = dyn_cast(E))
+return FE->getSubExpr();
+
+  if (auto *MTE = dyn_cast(E))
+return MTE->getSubExpr();
+
+  if (auto *NTTP = dyn_cast(E))
+return NTTP->getReplacement();
+
+  return E;
+}
+
+inline Expr *IgnoreLValueCastsSingleStep(Expr *E) {
+  // Skip what IgnoreCastsSingleStep skips, except that only
+  // lvalue-to-rvalue casts are skipped.
+  if (auto *CE = dyn_cast(E))
+if (CE->getCastKind() != CK_LValueToRValue)
+  return E;
 
-Expr *IgnoreImplicitCastsExtraSingleStep(Expr *E);
+  return IgnoreCastsSingleStep(E);
+}
+
+inline Expr *IgnoreBaseCastsSingleStep(Expr *E) {
+  if (auto *CE = dyn_cast(E))
+if (CE->getCastKind() == CK_DerivedToBase ||
+CE->getCastKind() == CK_UncheckedDerivedToBase ||
+CE->getCastKind() == CK_NoOp)
+  return CE->getSubExpr();
+
+  return E;
+}
+
+inline Expr *IgnoreImplicitSingleStep(Expr *E) {
+  Expr *SubE = IgnoreImplicitCastsSingleStep(E);
+  if (SubE != E)
+return SubE;
+
+  if (auto *MTE = dyn_cast(E))
+return MTE->getSubExpr();
+
+  if (auto *BTE = dyn_cast(E))
+return BTE->getSubExpr();
+
+  return E;
+}
+
+inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
+  if (auto *ICE = dyn_cast(E))
+return ICE->getSubExprAsWritten();
 
-Expr *IgnoreCastsSingleStep(Expr *E);
+  return IgnoreImplicitSingleStep(E);
+}
 
-Expr *IgnoreLValueCastsSingleStep(Expr *E);
+inline Expr *IgnoreParensOnlySingleStep(Expr *E) {
+  if (auto *PE = dyn_cast(E))
+return PE->getSubExpr();
+  return E;
+}
 
-Expr *IgnoreBaseCastsSingleStep(Expr *E);
+inline Expr *IgnoreParensSingleStep(Expr *E) {
+  if (auto *PE = dyn_cast(E))
+return PE->getSubExpr();
 
-Expr *IgnoreImplicitSingleStep(Expr *E);
+  if (auto *UO = dyn_cast(E)) {
+if (UO->getOpcode() == UO_Extension)
+  return UO->getSubExpr();
+  }
 
-Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E);
+  else if (auto *GSE = dyn_cast(E)) {
+if (!GSE->isResultDependent())
+  return GSE->getResultExpr();
+  }
 
-Expr *IgnoreParensOnlySingleStep(Expr *E);
+  else if (auto *CE = dyn_cast(E)) {
+if (!CE->isConditionDependent())
+  return CE->getChosenSubExpr();
+  }
 
-Expr *IgnoreParensSingleStep(Expr *E);
+  return E;
+}
 
 } // namespace clang
 

diff  --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index dfd26fd97bc6..35099fd0dacf 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -55,7 +55,6 @@ add_clang_library(clangAST
   ExternalASTMerger.cpp
   ExternalASTSource.cpp
   FormatString.cpp
-  IgnoreExpr.cpp
   InheritViz.cpp
   Interp/ByteCodeEmitter.cpp
   Interp/ByteCodeExprGen.cpp

diff  --git a/clang/lib/AST/IgnoreExpr.cpp b/clang/lib/AST/IgnoreExpr.cpp
deleted file mode 100644
index 65aaaeb6a1ed..
--- a/clang/lib/AST/IgnoreEx

[clang] c01d28d - [SyntaxTree] Specialize `TreeTestBase` for `BuildTreeTest`, `MutationsTest` and `SynthesisTest`

2020-09-10 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-09-10T16:44:14Z
New Revision: c01d28dc51bdd33404828a327320e3307a51bb22

URL: 
https://github.com/llvm/llvm-project/commit/c01d28dc51bdd33404828a327320e3307a51bb22
DIFF: 
https://github.com/llvm/llvm-project/commit/c01d28dc51bdd33404828a327320e3307a51bb22.diff

LOG: [SyntaxTree] Specialize `TreeTestBase` for `BuildTreeTest`, 
`MutationsTest` and `SynthesisTest`

Differential Revision: https://reviews.llvm.org/D87374

Added: 
clang/unittests/Tooling/Syntax/SynthesisTest.cpp

Modified: 
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
clang/unittests/Tooling/Syntax/CMakeLists.txt
clang/unittests/Tooling/Syntax/MutationsTest.cpp
clang/unittests/Tooling/Syntax/TreeTestBase.cpp
clang/unittests/Tooling/Syntax/TreeTestBase.h

Removed: 




diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp 
b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 225885437267..6fcc74ba55d0 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -17,7 +17,70 @@ using namespace clang::syntax;
 
 namespace {
 
-TEST_P(SyntaxTreeTest, Simple) {
+class BuildSyntaxTreeTest : public SyntaxTreeTest {
+protected:
+  ::testing::AssertionResult treeDumpEqual(StringRef Code, StringRef Tree) {
+SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
+
+auto *Root = buildTree(Code, GetParam());
+if (Diags->getClient()->getNumErrors() != 0) {
+  return ::testing::AssertionFailure()
+ << "Source file has syntax errors, they were printed to the test "
+"log";
+}
+auto Actual = StringRef(Root->dump(Arena->sourceManager())).trim().str();
+// EXPECT_EQ shows the 
diff  between the two strings if they are 
diff erent.
+EXPECT_EQ(Tree.trim().str(), Actual);
+if (Actual != Tree.trim().str()) {
+  return ::testing::AssertionFailure();
+}
+return ::testing::AssertionSuccess();
+  }
+
+  ::testing::AssertionResult
+  treeDumpEqualOnAnnotations(StringRef CodeWithAnnotations,
+ ArrayRef TreeDumps) {
+SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
+
+auto AnnotatedCode = llvm::Annotations(CodeWithAnnotations);
+auto *Root = buildTree(AnnotatedCode.code(), GetParam());
+
+if (Diags->getClient()->getNumErrors() != 0) {
+  return ::testing::AssertionFailure()
+ << "Source file has syntax errors, they were printed to the test "
+"log";
+}
+
+auto AnnotatedRanges = AnnotatedCode.ranges();
+if (AnnotatedRanges.size() != TreeDumps.size()) {
+  return ::testing::AssertionFailure()
+ << "The number of annotated ranges in the source code is "
+"
diff erent "
+"to the number of their corresponding tree dumps.";
+}
+bool Failed = false;
+for (unsigned i = 0; i < AnnotatedRanges.size(); i++) {
+  auto *AnnotatedNode = nodeByRange(AnnotatedRanges[i], Root);
+  assert(AnnotatedNode);
+  auto AnnotatedNodeDump =
+  StringRef(AnnotatedNode->dump(Arena->sourceManager())).trim().str();
+  // EXPECT_EQ shows the 
diff  between the two strings if they are 
diff erent.
+  EXPECT_EQ(TreeDumps[i].trim().str(), AnnotatedNodeDump)
+  << "Dumps diverged for the code:\n"
+  << AnnotatedCode.code().slice(AnnotatedRanges[i].Begin,
+AnnotatedRanges[i].End);
+  if (AnnotatedNodeDump != TreeDumps[i].trim().str())
+Failed = true;
+}
+return Failed ? ::testing::AssertionFailure()
+  : ::testing::AssertionSuccess();
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(SyntaxTreeTests, BuildSyntaxTreeTest,
+testing::ValuesIn(allTestClangConfigs()), );
+
+TEST_P(BuildSyntaxTreeTest, Simple) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 int main() {}
@@ -48,7 +111,7 @@ TranslationUnit Detached
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, SimpleVariable) {
+TEST_P(BuildSyntaxTreeTest, SimpleVariable) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 int a;
@@ -72,7 +135,7 @@ TranslationUnit Detached
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, SimpleFunction) {
+TEST_P(BuildSyntaxTreeTest, SimpleFunction) {
   EXPECT_TRUE(treeDumpEqual(
   R"cpp(
 void foo(int a, int b) {}
@@ -102,7 +165,7 @@ TranslationUnit Detached
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, If) {
+TEST_P(BuildSyntaxTreeTest, If) {
   EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 void test() {
@@ -144,7 +207,7 @@ IfStatement Statement
 )txt"}));
 }
 
-TEST_P(SyntaxTreeTest, For) {
+TEST_P(BuildSyntaxTreeTest, For) {
   EXPECT_TRUE(treeDumpEqualOnAnnotations(
   R"cpp(
 void test() {
@@ -164,7 +227,7 @@ ForStatement Statement
 )txt"}));
 }
 
-TEST_P(SyntaxTreeTest, RangeBasedFor) {
+TEST_P(BuildSyntaxTreeTest, RangeBasedFor) {
   if (!GetParam().isC

[clang] 23657d9 - [SyntaxTree] Add reverse links to syntax Nodes.

2020-11-05 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-11-05T09:33:53Z
New Revision: 23657d9cc33282208bdac074abccd73bd4d4f8be

URL: 
https://github.com/llvm/llvm-project/commit/23657d9cc33282208bdac074abccd73bd4d4f8be
DIFF: 
https://github.com/llvm/llvm-project/commit/23657d9cc33282208bdac074abccd73bd4d4f8be.diff

LOG: [SyntaxTree] Add reverse links to syntax Nodes.

Rationale:
Children of a syntax tree had forward links only, because there was no
need for reverse links.

This need appeared when we started mutating the syntax tree.
On a forward list, to remove a target node in O(1) we need a pointer to the 
node before the target. If we don't have this "before" pointer, we have to find 
it, and that requires O(n).
So in order to remove a syntax node from a tree, we would similarly need to 
find the node before to then remove. This is both not ergonomic nor does it 
have a good complexity.

Differential Revision: https://reviews.llvm.org/D90240

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Tree.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Mutations.cpp
clang/lib/Tooling/Syntax/Synthesis.cpp
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Tree.h 
b/clang/include/clang/Tooling/Syntax/Tree.h
index 4bfa15517ba4..b92e92305417 100644
--- a/clang/include/clang/Tooling/Syntax/Tree.h
+++ b/clang/include/clang/Tooling/Syntax/Tree.h
@@ -118,6 +118,8 @@ class Node {
 
   const Node *getNextSibling() const { return NextSibling; }
   Node *getNextSibling() { return NextSibling; }
+  const Node *getPreviousSibling() const { return PreviousSibling; }
+  Node *getPreviousSibling() { return PreviousSibling; }
 
   /// Dumps the structure of a subtree. For debugging and testing purposes.
   std::string dump(const SourceManager &SM) const;
@@ -144,6 +146,7 @@ class Node {
 
   Tree *Parent;
   Node *NextSibling;
+  Node *PreviousSibling;
   unsigned Kind : 16;
   unsigned Role : 8;
   unsigned Original : 1;
@@ -197,6 +200,8 @@ class Tree : public Node {
 
   Node *getFirstChild() { return FirstChild; }
   const Node *getFirstChild() const { return FirstChild; }
+  Node *getLastChild() { return LastChild; }
+  const Node *getLastChild() const { return LastChild; }
 
   const Leaf *findFirstLeaf() const;
   Leaf *findFirstLeaf() {
@@ -236,25 +241,32 @@ class Tree : public Node {
   using Node::Node;
 
 private:
-  /// Prepend \p Child to the list of children and and sets the parent pointer.
+  /// Append \p Child to the list of children and sets the parent pointer.
   /// A very low-level operation that does not check any invariants, only used
   /// by TreeBuilder and FactoryImpl.
   /// EXPECTS: Role != Detached.
+  void appendChildLowLevel(Node *Child, NodeRole Role);
+  /// Similar but prepends.
   void prependChildLowLevel(Node *Child, NodeRole Role);
-  /// Like the previous overload, but does not set role for \p Child.
+
+  /// Like the previous overloads, but does not set role for \p Child.
   /// EXPECTS: Child->Role != Detached
+  void appendChildLowLevel(Node *Child);
   void prependChildLowLevel(Node *Child);
   friend class TreeBuilder;
   friend class FactoryImpl;
 
-  /// Replace a range of children [BeforeBegin->NextSibling, End) with a list 
of
+  /// Replace a range of children [Begin, End) with a list of
   /// new nodes starting at \p New.
   /// Only used by MutationsImpl to implement higher-level mutation operations.
   /// (!) \p New can be null to model removal of the child range.
-  void replaceChildRangeLowLevel(Node *BeforeBegin, Node *End, Node *New);
+  /// (!) \p End can be null to model one past the end.
+  /// (!) \p Begin can be null to model an append.
+  void replaceChildRangeLowLevel(Node *Begin, Node *End, Node *New);
   friend class MutationsImpl;
 
   Node *FirstChild = nullptr;
+  Node *LastChild = nullptr;
 };
 
 // Provide missing non_const == const overload.

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 197590522e36..682e070d 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -636,12 +636,11 @@ class syntax::TreeBuilder {
   (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) &&
   "fold crosses boundaries of existing subtrees");
 
-  // We need to go in reverse order, because we can only prepend.
-  for (auto It = EndChildren; It != BeginChildren; --It) {
-auto *C = std::prev(It)->second;
+  for (auto It = BeginChildren; It != EndChildren; ++It) {
+auto *C = It->second;
 if (C->getRole() == NodeRole::Detached)
   C->setRole(NodeRole::Unknown);
-Node->prependChildLowLevel(C);
+Node->appendChildLowLevel(C);
   }
 
   // Mark that this node came from the AST and is backed by the source 
code.

diff  --git a/clang/lib/

[clang] 5011d43 - Migrate Declarators to use the List API

2020-10-01 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-10-01T13:56:31Z
New Revision: 5011d43108d1de30a056d66e73fa19062e0e84b7

URL: 
https://github.com/llvm/llvm-project/commit/5011d43108d1de30a056d66e73fa19062e0e84b7
DIFF: 
https://github.com/llvm/llvm-project/commit/5011d43108d1de30a056d66e73fa19062e0e84b7.diff

LOG: Migrate Declarators to use the List API

After this change all nodes that have a delimited-list are using the
`List` API.

Implementation details:
Let's look at a declaration with multiple declarators:
`int a, b;`
To generate a declarator list node we need to have the range of
declarators: `a, b`:
However, the `ClangAST` actually stores them as separate declarations:
`int a   ;`
`intb;`
We solve that by appropriately marking the declarators on each separate
declaration in the `ClangAST` and then for the final declarator `int
b`, shrinking its range to fit to the already marked declarators.

Differential Revision: https://reviews.llvm.org/D88403

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/lib/Tooling/Syntax/Synthesis.cpp
clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
clang/unittests/Tooling/Syntax/SynthesisTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 8b393c5423b4..ed4449adb0f0 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -99,10 +99,14 @@ enum class NodeKind : uint16_t {
   ParametersAndQualifiers,
   MemberPointer,
   UnqualifiedId,
+
+  // Lists
+  DeclaratorList,
   ParameterDeclarationList,
   CallArguments,
-  // Nested Name Specifiers.
   NestedNameSpecifier,
+
+  // Name Specifiers.
   GlobalNameSpecifier,
   DecltypeNameSpecifier,
   IdentifierNameSpecifier,
@@ -179,6 +183,7 @@ enum class NodeRole : uint8_t {
   Member,
   Callee,
   Arguments,
+  Declarators
 };
 /// For debugging purposes.
 raw_ostream &operator<<(raw_ostream &OS, NodeRole R);
@@ -823,6 +828,17 @@ class LinkageSpecificationDeclaration final : public 
Declaration {
   }
 };
 
+class DeclaratorList final : public List {
+public:
+  DeclaratorList() : List(NodeKind::DeclaratorList) {}
+  static bool classof(const Node *N) {
+return N->getKind() == NodeKind::DeclaratorList;
+  }
+  std::vector getDeclarators();
+  std::vector>
+  getDeclaratorsAndCommas();
+};
+
 /// Groups multiple declarators (e.g. variables, typedefs, etc.) together. All
 /// grouped declarators share the same declaration specifiers (e.g. 'int' or
 /// 'typedef').

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 4d365090abf1..e1ed55f2e4eb 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -397,6 +397,17 @@ class syntax::TreeBuilder {
   Mapping.add(From, New);
   }
 
+  /// Populate children for \p New list, assuming it covers tokens from a
+  /// subrange of \p SuperRange.
+  void foldList(ArrayRef SuperRange, syntax::List *New,
+ASTPtr From) {
+assert(New);
+auto ListRange = Pending.shrinkToFitList(SuperRange);
+Pending.foldChildren(Arena, ListRange, New);
+if (From)
+  Mapping.add(From, New);
+  }
+
   /// Notifies that we should not consume trailing semicolon when computing
   /// token range of \p D.
   void noticeDeclWithoutSemicolon(Decl *D);
@@ -579,6 +590,35 @@ class syntax::TreeBuilder {
   It->second->setRole(Role);
 }
 
+/// Shrink \p Range to a subrange that only contains tokens of a list.
+/// List elements and delimiters should already have correct roles.
+ArrayRef shrinkToFitList(ArrayRef Range) {
+  auto BeginChildren = Trees.lower_bound(Range.begin());
+  assert((BeginChildren == Trees.end() ||
+  BeginChildren->first == Range.begin()) &&
+ "Range crosses boundaries of existing subtrees");
+
+  auto EndChildren = Trees.lower_bound(Range.end());
+  assert(
+  (EndChildren == Trees.end() || EndChildren->first == Range.end()) &&
+  "Range crosses boundaries of existing subtrees");
+
+  auto BelongsToList = [](decltype(Trees)::value_type KV) {
+auto Role = KV.second->getRole();
+return Role == syntax::NodeRole::ListElement ||
+   Role == syntax::NodeRole::ListDelimiter;
+  };
+
+  auto BeginListChildren =
+  std::find_if(BeginChildren, EndChildren, BelongsToList);
+
+  auto EndListChildren =
+  std::find_if_not(BeginListChildren, EndChildren, BelongsToList);
+
+  return ArrayRef(BeginListChildren->first,
+ EndListChildren->first);
+}
+
 /// Add \p Node to the forest and attach child nodes based on \p Tokens.
 void foldChildren(const syntax::Arena &A, ArrayRef Tokens,

[clang] a8f1790 - [SyntaxTree] Fix rtti for `Expression`.

2020-10-13 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-10-13T14:47:43Z
New Revision: a8f1790fdb8ce1c53f024870cd51f32724d4c55f

URL: 
https://github.com/llvm/llvm-project/commit/a8f1790fdb8ce1c53f024870cd51f32724d4c55f
DIFF: 
https://github.com/llvm/llvm-project/commit/a8f1790fdb8ce1c53f024870cd51f32724d4c55f.diff

LOG: [SyntaxTree] Fix rtti for `Expression`.

Differential Revision: https://reviews.llvm.org/D89146

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index ed4449adb0f0..33ed2ec5c349 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -206,7 +206,7 @@ class Expression : public Tree {
   Expression(NodeKind K) : Tree(K) {}
   static bool classof(const Node *N) {
 return NodeKind::UnknownExpression <= N->getKind() &&
-   N->getKind() <= NodeKind::UnknownExpression;
+   N->getKind() <= NodeKind::CallExpression;
   }
 };
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 4178f8f - [SyntaxTree] Improve safety of `replaceChildRangeLowLevel`

2020-10-14 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-10-14T09:18:32Z
New Revision: 4178f8f2f08e14abb341fb32dd0f4cc9320df072

URL: 
https://github.com/llvm/llvm-project/commit/4178f8f2f08e14abb341fb32dd0f4cc9320df072
DIFF: 
https://github.com/llvm/llvm-project/commit/4178f8f2f08e14abb341fb32dd0f4cc9320df072.diff

LOG: [SyntaxTree] Improve safety of `replaceChildRangeLowLevel`

* Add assertions for other preconditions.
* If nothing is modified, don't mark it.

Differential Revision: https://reviews.llvm.org/D89303

Added: 


Modified: 
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index b558e7ab9a1b..74cd3c1f68b1 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -94,48 +94,65 @@ void syntax::Tree::prependChildLowLevel(Node *Child) {
 
 void syntax::Tree::replaceChildRangeLowLevel(Node *BeforeBegin, Node *End,
  Node *New) {
-  assert(!BeforeBegin || BeforeBegin->Parent == this);
+  assert((!BeforeBegin || BeforeBegin->Parent == this) &&
+ "`BeforeBegin` is not a child of `this`.");
+  assert((!End || End->Parent == this) && "`End` is not a child of `this`.");
+  assert(canModify() && "Cannot modify `this`.");
 
 #ifndef NDEBUG
-  for (auto *N = New; N; N = N->getNextSibling()) {
+  for (auto *N = New; N; N = N->NextSibling) {
 assert(N->Parent == nullptr);
 assert(N->getRole() != NodeRole::Detached && "Roles must be set");
 // FIXME: sanity-check the role.
   }
+
+  auto Reachable = [](Node *From, Node *N) {
+if (!N)
+  return true;
+for (auto *It = From; It; It = It->NextSibling)
+  if (It == N)
+return true;
+return false;
+  };
+  assert(Reachable(FirstChild, BeforeBegin) &&
+ "`BeforeBegin` is not reachable.");
+  assert(Reachable(BeforeBegin ? BeforeBegin->NextSibling : FirstChild, End) &&
+ "`End` is not after `BeforeBegin`.");
 #endif
+  Node *&Begin = BeforeBegin ? BeforeBegin->NextSibling : FirstChild;
+
+  if (!New && Begin == End)
+return;
+
+  // Mark modification.
+  for (auto *T = this; T && T->Original; T = T->Parent)
+T->Original = false;
 
   // Detach old nodes.
-  for (auto *N = !BeforeBegin ? FirstChild : BeforeBegin->getNextSibling();
-   N != End;) {
+  for (auto *N = Begin; N != End;) {
 auto *Next = N->NextSibling;
 
 N->setRole(NodeRole::Detached);
 N->Parent = nullptr;
 N->NextSibling = nullptr;
 if (N->Original)
-  traverse(N, [&](Node *C) { C->Original = false; });
+  traverse(N, [](Node *C) { C->Original = false; });
 
 N = Next;
   }
 
+  if (!New) {
+Begin = End;
+return;
+  }
   // Attach new nodes.
-  if (BeforeBegin)
-BeforeBegin->NextSibling = New ? New : End;
-  else
-FirstChild = New ? New : End;
-
-  if (New) {
-auto *Last = New;
-for (auto *N = New; N != nullptr; N = N->getNextSibling()) {
-  Last = N;
-  N->Parent = this;
-}
-Last->NextSibling = End;
+  Begin = New;
+  auto *Last = New;
+  for (auto *N = New; N != nullptr; N = N->NextSibling) {
+Last = N;
+N->Parent = this;
   }
-
-  // Mark the node as modified.
-  for (auto *T = this; T && T->Original; T = T->Parent)
-T->Original = false;
+  Last->NextSibling = End;
 }
 
 namespace {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 72732ac - [SyntaxTree] Bug fix in `MutationsImpl::addAfter`.

2020-10-14 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-10-14T09:22:01Z
New Revision: 72732acade77d5ee55a818e2da77a2c5b7033ccb

URL: 
https://github.com/llvm/llvm-project/commit/72732acade77d5ee55a818e2da77a2c5b7033ccb
DIFF: 
https://github.com/llvm/llvm-project/commit/72732acade77d5ee55a818e2da77a2c5b7033ccb.diff

LOG: [SyntaxTree] Bug fix in `MutationsImpl::addAfter`.

* Add assertions to other `MutationsImpl` member functions
* `findPrevious` is a free function

Differential Revision: https://reviews.llvm.org/D89314

Added: 


Modified: 
clang/lib/Tooling/Syntax/Mutations.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/Mutations.cpp 
b/clang/lib/Tooling/Syntax/Mutations.cpp
index bf1bcda26455..8def1c729689 100644
--- a/clang/lib/Tooling/Syntax/Mutations.cpp
+++ b/clang/lib/Tooling/Syntax/Mutations.cpp
@@ -23,6 +23,19 @@
 
 using namespace clang;
 
+static syntax::Node *findPrevious(syntax::Node *N) {
+  assert(N);
+  assert(N->getParent());
+  if (N->getParent()->getFirstChild() == N)
+return nullptr;
+  for (syntax::Node *C = N->getParent()->getFirstChild(); C != nullptr;
+   C = C->getNextSibling()) {
+if (C->getNextSibling() == N)
+  return C;
+  }
+  llvm_unreachable("could not find a child node");
+}
+
 // This class has access to the internals of tree nodes. Its sole purpose is to
 // define helpers that allow implementing the high-level mutation operations.
 class syntax::MutationsImpl {
@@ -30,14 +43,15 @@ class syntax::MutationsImpl {
   /// Add a new node with a specified role.
   static void addAfter(syntax::Node *Anchor, syntax::Node *New, NodeRole Role) 
{
 assert(Anchor != nullptr);
+assert(Anchor->Parent != nullptr);
 assert(New->Parent == nullptr);
 assert(New->NextSibling == nullptr);
-assert(!New->isDetached());
+assert(New->isDetached());
 assert(Role != NodeRole::Detached);
 
 New->setRole(Role);
 auto *P = Anchor->getParent();
-P->replaceChildRangeLowLevel(Anchor, Anchor, New);
+P->replaceChildRangeLowLevel(Anchor, Anchor->getNextSibling(), New);
 
 P->assertInvariants();
   }
@@ -60,6 +74,10 @@ class syntax::MutationsImpl {
 
   /// Completely remove the node from its parent.
   static void remove(syntax::Node *N) {
+assert(N != nullptr);
+assert(N->Parent != nullptr);
+assert(N->canModify());
+
 auto *P = N->getParent();
 P->replaceChildRangeLowLevel(findPrevious(N), N->getNextSibling(),
  /*New=*/nullptr);
@@ -67,18 +85,6 @@ class syntax::MutationsImpl {
 P->assertInvariants();
 N->assertInvariants();
   }
-
-private:
-  static syntax::Node *findPrevious(syntax::Node *N) {
-if (N->getParent()->getFirstChild() == N)
-  return nullptr;
-for (syntax::Node *C = N->getParent()->getFirstChild(); C != nullptr;
- C = C->getNextSibling()) {
-  if (C->getNextSibling() == N)
-return C;
-}
-llvm_unreachable("could not find a child node");
-  }
 };
 
 void syntax::removeStatement(syntax::Arena &A, syntax::Statement *S) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 6fbad9b - [SyntaxTree][NFC] Nit on `replaceChildRangeLowLevel`

2020-10-14 Thread Eduardo Caldas via cfe-commits

Author: Eduardo Caldas
Date: 2020-10-14T09:40:37Z
New Revision: 6fbad9bf304c05d37454420f7d5a1c2ab3adab20

URL: 
https://github.com/llvm/llvm-project/commit/6fbad9bf304c05d37454420f7d5a1c2ab3adab20
DIFF: 
https://github.com/llvm/llvm-project/commit/6fbad9bf304c05d37454420f7d5a1c2ab3adab20.diff

LOG: [SyntaxTree][NFC] Nit on `replaceChildRangeLowLevel`

Added: 


Modified: 
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index 74cd3c1f68b1..87526ad7a976 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -99,6 +99,8 @@ void syntax::Tree::replaceChildRangeLowLevel(Node 
*BeforeBegin, Node *End,
   assert((!End || End->Parent == this) && "`End` is not a child of `this`.");
   assert(canModify() && "Cannot modify `this`.");
 
+  Node *&Begin = BeforeBegin ? BeforeBegin->NextSibling : FirstChild;
+
 #ifndef NDEBUG
   for (auto *N = New; N; N = N->NextSibling) {
 assert(N->Parent == nullptr);
@@ -116,10 +118,8 @@ void syntax::Tree::replaceChildRangeLowLevel(Node 
*BeforeBegin, Node *End,
   };
   assert(Reachable(FirstChild, BeforeBegin) &&
  "`BeforeBegin` is not reachable.");
-  assert(Reachable(BeforeBegin ? BeforeBegin->NextSibling : FirstChild, End) &&
- "`End` is not after `BeforeBegin`.");
+  assert(Reachable(Begin, End) && "`End` is not after `BeforeBegin`.");
 #endif
-  Node *&Begin = BeforeBegin ? BeforeBegin->NextSibling : FirstChild;
 
   if (!New && Begin == End)
 return;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits