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