//===- MCLDAttribute.h ----------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_ATTRIBUTE_H
#define MCLD_ATTRIBUTE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include <vector>
#include <string>

namespace mcld
{
class AttributeFactory;

/** \class AttributeBase
 *  \brief AttributeBase provides the real storage for attributes of options.
 *
 *  Attributes are options affecting the link editing of input files.
 *  Some options affects the input files mentioned on the command line after
 *  them. For example, --whole-archive option affects archives mentioned on
 *  the command line after the --whole-archve option. We call such options
 *  "attributes of input files"
 *
 *  AttributeBase is the storage for attributes of input files. Each input
 *  file (@see mcld::Input in MCLinker) has a pointer of an attribute. Since
 *  most attributes of input files are identical, our design lets input files
 *  which have identical attributes share common attribute. AttributeBase is
 *  the shared storage for attribute.
 */
class AttributeBase
{
public:
  AttributeBase()
  : m_WholeArchive(false),
    m_AsNeeded(false),
    m_AddNeeded(true),
    m_Static(false)
  { }

  AttributeBase(const AttributeBase& pBase)
  : m_WholeArchive(pBase.m_WholeArchive),
    m_AsNeeded(pBase.m_AsNeeded),
    m_AddNeeded(pBase.m_AddNeeded),
    m_Static(pBase.m_Static)
  { }

  virtual ~AttributeBase()
  { }

  // ----- observers  ----- //
  // represent GNU ld --whole-archive/--no-whole-archive options
  bool isWholeArchive() const
  { return m_WholeArchive; }

  // represent GNU ld --as-needed/--no-as-needed options
  bool isAsNeeded() const
  { return m_AsNeeded; }

  // represent GNU ld --add-needed/--no-add-needed options
  bool isAddNeeded() const
  { return m_AddNeeded; }

  // represent GNU ld -static option
  bool isStatic() const
  { return m_Static; }

  // represent GNU ld -call_shared option
  bool isDynamic() const
  { return !m_Static; }
public:
  bool m_WholeArchive : 1;
  bool m_AsNeeded : 1;
  bool m_AddNeeded : 1;
  bool m_Static : 1;
};

/** \class Attribute
 *  \brief The base class of attributes. Providing the raw operations of an
 *  attributes
 *
 *  For conventience and producing less bugs, we move the stoarges of attributes
 *  onto AttributeBase, and modifiers remains with the class Attribute.
 */
class Attribute : public AttributeBase
{
public:
  // -----  modifiers  ----- //
  void setWholeArchive()
  { m_WholeArchive = true; }

  void unsetWholeArchive()
  { m_WholeArchive = false; }

  void setAsNeeded()
  { m_AsNeeded = true; }

  void unsetAsNeeded()
  { m_AsNeeded = false; }

  void setAddNeeded()
  { m_AddNeeded = true; }

  void unsetAddNeeded()
  { m_AddNeeded = false; }

  void setStatic()
  { m_Static = true; }

  void setDynamic()
  { m_Static = false; }
};

/** \class AttrConstraint
 *  \brief AttrConstarint is the constraint of a system.
 *
 *  Some systems can not enable certain attributes of a input file.
 *  For example, systems which have no shared libraries can not enable
 *  --call_shared options. We call the ability of enabling attributes
 *  as the constraint of attributes of a system.
 *
 *  Systems enable attributes at the target implementation of SectLinker.
 *
 *  @see SectLinker
 */
class AttrConstraint : public AttributeBase
{
public:
  void enableWholeArchive()
  { m_WholeArchive = true; }

  void disableWholeArchive()
  { m_WholeArchive = false; }

  void enableAsNeeded()
  { m_AsNeeded = true; }

  void disableAsNeeded()
  { m_AsNeeded = false; }

  void enableAddNeeded()
  { m_AddNeeded = true; }

  void disableAddNeeded()
  { m_AddNeeded = false; }

  void setSharedSystem()
  { m_Static = false; }

  void setStaticSystem()
  { m_Static = true; }

  bool isSharedSystem() const
  { return !m_Static; }

  bool isStaticSystem() const
  { return m_Static; }
  
  bool isLegal(const Attribute& pAttr, std::string& pErrMesg) const;
};

/** \class AttributeProxy
 *  \brief AttributeProxys is the illusion of private attribute of each
 *  input file.
 *
 *  We designers want to hide the details of sharing common attributes
 *  between input files. We want input files under the illusion that they
 *  have their own private attributes to simplify the linking algorithms.
 *
 *  AttributeProxy hides the reality of sharing. An input file can change
 *  its attribute without explicit searching of existing attributes
 *  as it has a private ownership of the attribute. AttributeProxy does
 *  the searching in the AttributeFactory and changes the pointer of
 *  the attribute of the input file. If the searching fails, AttributeProxy
 *  requests a new attribute from the AttributeFactory.
 */
class AttributeProxy
{
private:
  friend class AttributeFactory;

  explicit AttributeProxy(AttributeFactory& pParent, Attribute& pBase);
  ~AttributeProxy();

public:
  // ----- observers  ----- //
  bool isWholeArchive() const;

  bool isAsNeeded() const;

  bool isAddNeeded() const;

  bool isStatic() const;

  bool isDynamic() const;

  Attribute* attr()
  { return m_pBase; }

  const Attribute* attr() const
  { return m_pBase; }

  // -----  modifiers  ----- //
  void setWholeArchive();
  void unsetWholeArchive();
  void setAsNeeded();
  void unsetAsNeeded();
  void setAddNeeded();
  void unsetAddNeeded();
  void setStatic();
  void setDynamic();

private:
  AttributeProxy* clone() const;

  void change(Attribute* pBase)
  { m_pBase = pBase; }

private:
  AttributeFactory &m_AttrPool;
  Attribute *m_pBase;
};


// -----  comparisons  ----- //
inline bool operator== (const Attribute& pLHS, const Attribute& pRHS)
{
  return ((pLHS.isWholeArchive() == pRHS.isWholeArchive()) &&
    (pLHS.isAsNeeded() == pRHS.isAsNeeded()) && 
    (pLHS.isAddNeeded() == pRHS.isAddNeeded()) && 
    (pLHS.isStatic() == pRHS.isStatic()));
}

inline bool operator!= (const Attribute& pLHS, const Attribute& pRHS)
{
  return !(pLHS == pRHS);
}

} // namespace of mcld

#endif

