Commit 07a41018 authored by Ilya Biryukov's avatar Ilya Biryukov
Browse files

[Syntax] Mark synthesized nodes as modifiable

This was an oversight in the original patch.
Also add corresponding tests.
parent 3b929fe7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -123,6 +123,8 @@ private:
  friend class TreeBuilder;
  // MutationsImpl sets roles and CanModify flag.
  friend class MutationsImpl;
  // FactoryImpl sets CanModify flag.
  friend class FactoryImpl;

  Tree *Parent;
  Node *NextSibling;
+4 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ using namespace clang;
/// Should not be used for anything else.
class syntax::FactoryImpl {
public:
  static void setCanModify(syntax::Node *N) { N->CanModify = true; }

  static void prependChildLowLevel(syntax::Tree *T, syntax::Node *Child,
                                   syntax::NodeRole R) {
    T->prependChildLowLevel(Child, R);
@@ -27,6 +29,7 @@ clang::syntax::Leaf *syntax::createPunctuation(clang::syntax::Arena &A,
  assert(Tokens.size() == 1);
  assert(Tokens.front().kind() == K);
  auto *L = new (A.allocator()) clang::syntax::Leaf(Tokens.begin());
  FactoryImpl::setCanModify(L);
  L->assertInvariants();
  return L;
}
@@ -34,6 +37,7 @@ clang::syntax::Leaf *syntax::createPunctuation(clang::syntax::Arena &A,
clang::syntax::EmptyStatement *
syntax::createEmptyStatement(clang::syntax::Arena &A) {
  auto *S = new (A.allocator()) clang::syntax::EmptyStatement;
  FactoryImpl::setCanModify(S);
  FactoryImpl::prependChildLowLevel(S, createPunctuation(A, clang::tok::semi),
                                    NodeRole::Unknown);
  S->assertInvariants();
+18 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#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"
@@ -906,4 +907,21 @@ TEST_F(SyntaxTreeTest, Mutations) {
    CheckTransformation(C.first, C.second, RemoveStatement);
}

TEST_F(SyntaxTreeTest, SynthesizedNodes) {
  buildTree("");

  auto *C = syntax::createPunctuation(*Arena, tok::comma);
  ASSERT_NE(C, nullptr);
  EXPECT_EQ(C->token()->kind(), tok::comma);
  EXPECT_TRUE(C->canModify());
  EXPECT_FALSE(C->isOriginal());
  EXPECT_TRUE(C->isDetached());

  auto *S = syntax::createEmptyStatement(*Arena);
  ASSERT_NE(S, nullptr);
  EXPECT_TRUE(S->canModify());
  EXPECT_FALSE(S->isOriginal());
  EXPECT_TRUE(S->isDetached());
}

} // namespace