Program Listing for File sageFunctors.h

Program Listing for File sageFunctors.h#

Return to documentation for file (src/frontend/SageIII/sageInterface/sageFunctors.h)

#ifndef _SAGEFUNCTORS_H
#define _SAGEFUNCTORS_H


#include "sageInterface.h"
#include "sageBuilder.h"

namespace sg
{
  template <class SageNode>
  static inline
  SageNode* cloneNode(const SageNode* n)
  {
    if (!n) return 0;

    return SageInterface::deepCopy(n);
  }

  static inline
  void _append(SgExprListExp& container, SgExpression* elem)
  {
    SageInterface::appendExpression(&container, elem);
  }

  static inline
  void _append(SgFunctionParameterList& container, SgInitializedName* elem)
  {
    SageInterface::appendArg(&container, elem);
  }

  struct ScopeSetter
  {
      explicit
      ScopeSetter(SgScopeStatement& the_scope)
      : scope(the_scope)
      {}

      template <class ScopedSageNode>
      void handle(ScopedSageNode* scopeElem) const
      {
        ROSE_ASSERT(scopeElem);

        scopeElem->set_scope(&scope);
      }

      void operator()(SgStatement* scopeElem)       const { handle(scopeElem); }
      void operator()(SgInitializedName* scopeElem) const { handle(scopeElem); }

    private:
      SgScopeStatement& scope;
  };

  struct VarRefBuilder
  {
      explicit
      VarRefBuilder(SgScopeStatement& the_scope)
      : scope(the_scope)
      {}

      SgVarRefExp* operator()(SgInitializedName* initName) const
      {
        return SageBuilder::buildVarRefExp(initName, &scope);
      }

    private:
      SgScopeStatement& scope;
  };

  struct InitNameCloner
  {
      InitNameCloner(SgDeclarationStatement& declaration, SgScopeStatement* enclosing_scope = 0)
   // DQ (3/25/2017): Remove to avoid Clang warning about unused private variable.
   // : decl(declaration),
      : scope(enclosing_scope)
      {}

      SgInitializedName* operator()(const SgInitializedName* orig) const
      {
        SgInitializer*     copy_init = cloneNode(orig->get_initializer());
        SgInitializedName* res = SageBuilder::buildInitializedName(orig->get_name(), orig->get_type(), copy_init);

        res->set_scope(scope);

        return res;
      }

    private:
   // DQ (3/25/2017): Remove to avoid Clang warning about unused private variable.
   // SgDeclarationStatement& decl;
      SgScopeStatement*       scope;
  };

  template <class SageSequenceContainer>
  struct SageInserter
  {
    using iterator_category = std::output_iterator_tag;
    using value_type = void;
    using difference_type = void;
    using pointer = void;
    using reference = void;

    typedef SageSequenceContainer Container;

    Container& container;

    explicit
    SageInserter(Container& cont)
    : container(cont)
    {}

    // \todo SageElem should be derived form the container type
    template <class SageElem>
    SageInserter& operator=(SageElem* elem)
    {
      _append(container, elem);
      return *this;
    }

    SageInserter& operator*()     { return *this; }
    SageInserter& operator++()    { return *this; }
    SageInserter& operator++(int) { return *this; }
  };

  template <class SageSequenceContainer>
  SageInserter<SageSequenceContainer>
  sage_inserter(SageSequenceContainer& cont)
  {
    return SageInserter<SageSequenceContainer>(cont);
  }
}

#endif /* _SAGEFUNCTORS_H */