summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/astclone/cloner.hxx
blob: 9e7d16141bee7b5d979355fbbbf598ae61c782c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/**
 ** \file astclone/cloner.hxx
 ** \brief Template methods of astclone::Cloner.
 */

#pragma once

#include <ast/libast.hh>
#include <astclone/cloner.hh>

namespace astclone
{
  using namespace ast;

  template <typename T> T* Cloner::recurse(const T& t)
  {
    t.accept(*this);
    T* res = dynamic_cast<T*>(result_);
    assertion(res);
    return res;
  }

  template <typename T> T* Cloner::recurse(const T* const t)
  {
    T* res = nullptr;
    if (t)
      {
        t->accept(*this);
        res = dynamic_cast<T*>(result_);
        assertion(res);
      }
    return res;
  }

  template <typename CollectionType>
  CollectionType* Cloner::recurse_collection(const CollectionType& c)
  {
    auto res = new CollectionType;

    using elt_type = typename CollectionType::value_type;
    for (const elt_type& e : c)
      {
        e->accept(*this);
        auto elt = dynamic_cast<elt_type>(result_);
        assertion(elt);
        res->emplace_back(elt);
      }

    return res;
  }

  template <typename ChunkType> void Cloner::chunk_visit(const ChunkType& e)
  {
    const Location& location = e.location_get();

    // The type of the list contained by this node.
    using elt_type = typename ChunkType::Ds;
    // The cloned list of declarations.
    auto decs = new elt_type;

    for (const typename elt_type::value_type& i : e)
      {
        i->accept(*this);
        auto dec = dynamic_cast<typename elt_type::value_type>(result_);
        assertion(dec);
        decs->emplace_back(dec);
      }
    // The cloned ChunkInterface.
    result_ = new ChunkType(location, decs);
  }

} // namespace astclone