Home | History | Annotate | Download | only in MC
      1 //===- Attribute.h --------------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #ifndef MCLD_MC_ATTRIBUTE_H
     10 #define MCLD_MC_ATTRIBUTE_H
     11 
     12 namespace mcld {
     13 
     14 class AttributeSet;
     15 
     16 /** \class AttributeBase
     17  *  \brief AttributeBase provides the real storage for attributes of options.
     18  *
     19  *  Attributes are options affecting the link editing of input files.
     20  *  Some options affects the input files mentioned on the command line after
     21  *  them. For example, --whole-archive option affects archives mentioned on
     22  *  the command line after the --whole-archve option. We call such options
     23  *  "attributes of input files"
     24  *
     25  *  AttributeBase is the storage for attributes of input files. Each input
     26  *  file (@see mcld::Input in MCLinker) has a pointer of an attribute. Since
     27  *  most attributes of input files are identical, our design lets input files
     28  *  which have identical attributes share common attribute. AttributeBase is
     29  *  the shared storage for attribute.
     30  */
     31 class AttributeBase
     32 {
     33 public:
     34   AttributeBase()
     35   : m_WholeArchive(false),
     36     m_AsNeeded(false),
     37     m_AddNeeded(true),
     38     m_Static(false)
     39   { }
     40 
     41   AttributeBase(const AttributeBase& pBase)
     42   : m_WholeArchive(pBase.m_WholeArchive),
     43     m_AsNeeded(pBase.m_AsNeeded),
     44     m_AddNeeded(pBase.m_AddNeeded),
     45     m_Static(pBase.m_Static)
     46   { }
     47 
     48   virtual ~AttributeBase()
     49   { }
     50 
     51   // ----- observers  ----- //
     52   // represent GNU ld --whole-archive/--no-whole-archive options
     53   bool isWholeArchive() const
     54   { return m_WholeArchive; }
     55 
     56   // represent GNU ld --as-needed/--no-as-needed options
     57   bool isAsNeeded() const
     58   { return m_AsNeeded; }
     59 
     60   // represent GNU ld --add-needed/--no-add-needed options
     61   bool isAddNeeded() const
     62   { return m_AddNeeded; }
     63 
     64   // represent GNU ld -static option
     65   bool isStatic() const
     66   { return m_Static; }
     67 
     68   // represent GNU ld -call_shared option
     69   bool isDynamic() const
     70   { return !m_Static; }
     71 
     72 public:
     73   bool m_WholeArchive : 1;
     74   bool m_AsNeeded : 1;
     75   bool m_AddNeeded : 1;
     76   bool m_Static : 1;
     77 };
     78 
     79 /** \class Attribute
     80  *  \brief The base class of attributes. Providing the raw operations of an
     81  *  attributes
     82  *
     83  *  For conventience and producing less bugs, we move the stoarges of attributes
     84  *  onto AttributeBase, and modifiers remains with the class Attribute.
     85  */
     86 class Attribute : public AttributeBase
     87 {
     88 public:
     89   // -----  modifiers  ----- //
     90   void setWholeArchive()
     91   { m_WholeArchive = true; }
     92 
     93   void unsetWholeArchive()
     94   { m_WholeArchive = false; }
     95 
     96   void setAsNeeded()
     97   { m_AsNeeded = true; }
     98 
     99   void unsetAsNeeded()
    100   { m_AsNeeded = false; }
    101 
    102   void setAddNeeded()
    103   { m_AddNeeded = true; }
    104 
    105   void unsetAddNeeded()
    106   { m_AddNeeded = false; }
    107 
    108   void setStatic()
    109   { m_Static = true; }
    110 
    111   void setDynamic()
    112   { m_Static = false; }
    113 };
    114 
    115 /** \class AttrConstraint
    116  *  \brief AttrConstarint is the constraint of a system.
    117  *
    118  *  Some systems can not enable certain attributes of a input file.
    119  *  For example, systems which have no shared libraries can not enable
    120  *  --call_shared options. We call the ability of enabling attributes
    121  *  as the constraint of attributes of a system.
    122  *
    123  *  Systems enable attributes at the target implementation of SectLinker.
    124  *
    125  *  @see SectLinker
    126  */
    127 class AttrConstraint : public AttributeBase
    128 {
    129 public:
    130   void enableWholeArchive()
    131   { m_WholeArchive = true; }
    132 
    133   void disableWholeArchive()
    134   { m_WholeArchive = false; }
    135 
    136   void enableAsNeeded()
    137   { m_AsNeeded = true; }
    138 
    139   void disableAsNeeded()
    140   { m_AsNeeded = false; }
    141 
    142   void enableAddNeeded()
    143   { m_AddNeeded = true; }
    144 
    145   void disableAddNeeded()
    146   { m_AddNeeded = false; }
    147 
    148   void setSharedSystem()
    149   { m_Static = false; }
    150 
    151   void setStaticSystem()
    152   { m_Static = true; }
    153 
    154   bool isSharedSystem() const
    155   { return !m_Static; }
    156 
    157   bool isStaticSystem() const
    158   { return m_Static; }
    159 
    160   bool isLegal(const Attribute& pAttr) const;
    161 };
    162 
    163 /** \class AttributeProxy
    164  *  \brief AttributeProxys is the illusion of private attribute of each
    165  *  input file.
    166  *
    167  *  We designers want to hide the details of sharing common attributes
    168  *  between input files. We want input files under the illusion that they
    169  *  have their own private attributes to simplify the linking algorithms.
    170  *
    171  *  AttributeProxy hides the reality of sharing. An input file can change
    172  *  its attribute without explicit searching of existing attributes
    173  *  as it has a private ownership of the attribute. AttributeProxy does
    174  *  the searching in the AttributeSet and changes the pointer of
    175  *  the attribute of the input file. If the searching fails, AttributeProxy
    176  *  requests a new attribute from the AttributeSet.
    177  */
    178 class AttributeProxy
    179 {
    180 public:
    181   AttributeProxy(AttributeSet& pParent,
    182                  const Attribute& pBase,
    183                  const AttrConstraint& pConstraint);
    184 
    185   ~AttributeProxy();
    186 
    187   // ----- observers  ----- //
    188   bool isWholeArchive() const;
    189 
    190   bool isAsNeeded() const;
    191 
    192   bool isAddNeeded() const;
    193 
    194   bool isStatic() const;
    195 
    196   bool isDynamic() const;
    197 
    198   const Attribute* attr() const
    199   { return m_pBase; }
    200 
    201   // -----  modifiers  ----- //
    202   void setWholeArchive();
    203   void unsetWholeArchive();
    204   void setAsNeeded();
    205   void unsetAsNeeded();
    206   void setAddNeeded();
    207   void unsetAddNeeded();
    208   void setStatic();
    209   void setDynamic();
    210 
    211   AttributeProxy& assign(Attribute* pBase);
    212 
    213 private:
    214   AttributeSet &m_AttrPool;
    215   const Attribute *m_pBase;
    216   const AttrConstraint& m_Constraint;
    217 };
    218 
    219 
    220 // -----  comparisons  ----- //
    221 inline bool operator== (const Attribute& pLHS, const Attribute& pRHS)
    222 {
    223   return ((pLHS.isWholeArchive() == pRHS.isWholeArchive()) &&
    224     (pLHS.isAsNeeded() == pRHS.isAsNeeded()) &&
    225     (pLHS.isAddNeeded() == pRHS.isAddNeeded()) &&
    226     (pLHS.isStatic() == pRHS.isStatic()));
    227 }
    228 
    229 inline bool operator!= (const Attribute& pLHS, const Attribute& pRHS)
    230 {
    231   return !(pLHS == pRHS);
    232 }
    233 
    234 } // namespace of mcld
    235 
    236 #endif
    237 
    238