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  public:
     33   AttributeBase()
     34       : m_WholeArchive(false),
     35         m_AsNeeded(false),
     36         m_AddNeeded(true),
     37         m_Static(false) {}
     38 
     39   AttributeBase(const AttributeBase& pBase)
     40       : m_WholeArchive(pBase.m_WholeArchive),
     41         m_AsNeeded(pBase.m_AsNeeded),
     42         m_AddNeeded(pBase.m_AddNeeded),
     43         m_Static(pBase.m_Static) {}
     44 
     45   virtual ~AttributeBase() {}
     46 
     47   // ----- observers  ----- //
     48   // represent GNU ld --whole-archive/--no-whole-archive options
     49   bool isWholeArchive() const { return m_WholeArchive; }
     50 
     51   // represent GNU ld --as-needed/--no-as-needed options
     52   bool isAsNeeded() const { return m_AsNeeded; }
     53 
     54   // represent GNU ld --add-needed/--no-add-needed options
     55   bool isAddNeeded() const { return m_AddNeeded; }
     56 
     57   // represent GNU ld -static option
     58   bool isStatic() const { return m_Static; }
     59 
     60   // represent GNU ld -call_shared option
     61   bool isDynamic() const { return !m_Static; }
     62 
     63  public:
     64   bool m_WholeArchive : 1;
     65   bool m_AsNeeded : 1;
     66   bool m_AddNeeded : 1;
     67   bool m_Static : 1;
     68 };
     69 
     70 /** \class Attribute
     71  *  \brief The base class of attributes. Providing the raw operations of an
     72  *  attributes
     73  *
     74  *  For conventience and producing less bugs, we move the stoarges of attributes
     75  *  onto AttributeBase, and modifiers remains with the class Attribute.
     76  */
     77 class Attribute : public AttributeBase {
     78  public:
     79   // -----  modifiers  ----- //
     80   void setWholeArchive() { m_WholeArchive = true; }
     81 
     82   void unsetWholeArchive() { m_WholeArchive = false; }
     83 
     84   void setAsNeeded() { m_AsNeeded = true; }
     85 
     86   void unsetAsNeeded() { m_AsNeeded = false; }
     87 
     88   void setAddNeeded() { m_AddNeeded = true; }
     89 
     90   void unsetAddNeeded() { m_AddNeeded = false; }
     91 
     92   void setStatic() { m_Static = true; }
     93 
     94   void setDynamic() { m_Static = false; }
     95 };
     96 
     97 /** \class AttrConstraint
     98  *  \brief AttrConstarint is the constraint of a system.
     99  *
    100  *  Some systems can not enable certain attributes of a input file.
    101  *  For example, systems which have no shared libraries can not enable
    102  *  --call_shared options. We call the ability of enabling attributes
    103  *  as the constraint of attributes of a system.
    104  *
    105  *  Systems enable attributes at the target implementation of SectLinker.
    106  *
    107  *  @see SectLinker
    108  */
    109 class AttrConstraint : public AttributeBase {
    110  public:
    111   void enableWholeArchive() { m_WholeArchive = true; }
    112 
    113   void disableWholeArchive() { m_WholeArchive = false; }
    114 
    115   void enableAsNeeded() { m_AsNeeded = true; }
    116 
    117   void disableAsNeeded() { m_AsNeeded = false; }
    118 
    119   void enableAddNeeded() { m_AddNeeded = true; }
    120 
    121   void disableAddNeeded() { m_AddNeeded = false; }
    122 
    123   void setSharedSystem() { m_Static = false; }
    124 
    125   void setStaticSystem() { m_Static = true; }
    126 
    127   bool isSharedSystem() const { return !m_Static; }
    128 
    129   bool isStaticSystem() const { return m_Static; }
    130 
    131   bool isLegal(const Attribute& pAttr) const;
    132 };
    133 
    134 /** \class AttributeProxy
    135  *  \brief AttributeProxys is the illusion of private attribute of each
    136  *  input file.
    137  *
    138  *  We designers want to hide the details of sharing common attributes
    139  *  between input files. We want input files under the illusion that they
    140  *  have their own private attributes to simplify the linking algorithms.
    141  *
    142  *  AttributeProxy hides the reality of sharing. An input file can change
    143  *  its attribute without explicit searching of existing attributes
    144  *  as it has a private ownership of the attribute. AttributeProxy does
    145  *  the searching in the AttributeSet and changes the pointer of
    146  *  the attribute of the input file. If the searching fails, AttributeProxy
    147  *  requests a new attribute from the AttributeSet.
    148  */
    149 class AttributeProxy {
    150  public:
    151   AttributeProxy(AttributeSet& pParent,
    152                  const Attribute& pBase,
    153                  const AttrConstraint& pConstraint);
    154 
    155   ~AttributeProxy();
    156 
    157   // ----- observers  ----- //
    158   bool isWholeArchive() const;
    159 
    160   bool isAsNeeded() const;
    161 
    162   bool isAddNeeded() const;
    163 
    164   bool isStatic() const;
    165 
    166   bool isDynamic() const;
    167 
    168   const Attribute* attr() const { return m_pBase; }
    169 
    170   // -----  modifiers  ----- //
    171   void setWholeArchive();
    172   void unsetWholeArchive();
    173   void setAsNeeded();
    174   void unsetAsNeeded();
    175   void setAddNeeded();
    176   void unsetAddNeeded();
    177   void setStatic();
    178   void setDynamic();
    179 
    180   AttributeProxy& assign(Attribute* pBase);
    181 
    182  private:
    183   AttributeSet& m_AttrPool;
    184   const Attribute* m_pBase;
    185   const AttrConstraint& m_Constraint;
    186 };
    187 
    188 // -----  comparisons  ----- //
    189 inline bool operator==(const Attribute& pLHS, const Attribute& pRHS) {
    190   return ((pLHS.isWholeArchive() == pRHS.isWholeArchive()) &&
    191           (pLHS.isAsNeeded() == pRHS.isAsNeeded()) &&
    192           (pLHS.isAddNeeded() == pRHS.isAddNeeded()) &&
    193           (pLHS.isStatic() == pRHS.isStatic()));
    194 }
    195 
    196 inline bool operator!=(const Attribute& pLHS, const Attribute& pRHS) {
    197   return !(pLHS == pRHS);
    198 }
    199 
    200 }  // namespace mcld
    201 
    202 #endif  // MCLD_MC_ATTRIBUTE_H_
    203