Home | History | Annotate | Download | only in MC
      1 //===- MCLDAttribute.cpp --------------------------------------------------===//
      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 #include <mcld/MC/Attribute.h>
     10 #include <mcld/MC/AttributeSet.h>
     11 #include <mcld/Support/MsgHandling.h>
     12 
     13 using namespace mcld;
     14 
     15 //===----------------------------------------------------------------------===//
     16 // AttrConstraint
     17 //===----------------------------------------------------------------------===//
     18 bool AttrConstraint::isLegal(const Attribute& pAttr) const
     19 {
     20   if (!isWholeArchive() && pAttr.isWholeArchive()) {
     21     error(diag::err_unsupported_whole_archive);
     22     return false;
     23   }
     24   if (!isAsNeeded() && pAttr.isAsNeeded()) {
     25     error(diag::err_unsupported_as_needed);
     26     return false;
     27   }
     28   if (!isAddNeeded() && pAttr.isAddNeeded()) {
     29     error(diag::err_unsupported_add_needed);
     30     return false;
     31   }
     32   if (isStaticSystem() && pAttr.isDynamic()) {
     33     error(diag::err_unsupported_Bdynamic);
     34     return false;
     35   }
     36   if (isStaticSystem() && pAttr.isAsNeeded()) {
     37     warning(diag::err_enable_as_needed_on_static_system);
     38     return true;
     39   }
     40   // FIXME: may be it's legal, but ignored by GNU ld.
     41   if (pAttr.isAsNeeded() && pAttr.isStatic()) {
     42     warning(diag::err_mix_static_as_needed);
     43     return true;
     44   }
     45   return true;
     46 }
     47 
     48 //===----------------------------------------------------------------------===//
     49 // AttributeProxy
     50 //===----------------------------------------------------------------------===//
     51 AttributeProxy::AttributeProxy(AttributeSet& pParent,
     52                                const Attribute& pBase,
     53                                const AttrConstraint& pConstraint)
     54   : m_AttrPool(pParent), m_pBase(&pBase), m_Constraint(pConstraint) {
     55 }
     56 
     57 AttributeProxy::~AttributeProxy()
     58 {
     59 }
     60 
     61 bool AttributeProxy::isWholeArchive() const
     62 {
     63   if (m_Constraint.isWholeArchive())
     64     return m_pBase->isWholeArchive();
     65   else
     66     return false;
     67 }
     68 
     69 bool AttributeProxy::isAsNeeded() const
     70 {
     71   if (m_Constraint.isAsNeeded())
     72     return m_pBase->isAsNeeded();
     73   else
     74     return false;
     75 }
     76 
     77 bool AttributeProxy::isAddNeeded() const
     78 {
     79   if (m_Constraint.isAddNeeded())
     80     return m_pBase->isAddNeeded();
     81   else
     82     return false;
     83 }
     84 
     85 bool AttributeProxy::isStatic() const
     86 {
     87   if (m_Constraint.isSharedSystem())
     88     return m_pBase->isStatic();
     89   else
     90     return true;
     91 }
     92 
     93 bool AttributeProxy::isDynamic() const
     94 {
     95   if (m_Constraint.isSharedSystem())
     96     return m_pBase->isDynamic();
     97   else
     98     return false;
     99 }
    100 
    101 static inline void ReplaceOrRecord(AttributeSet& pParent,
    102                                    const Attribute *&pBase,
    103                                    Attribute *&pCopy)
    104 {
    105   Attribute *result = pParent.exists(*pCopy);
    106   if (NULL == result) { // can not find
    107     pParent.record(*pCopy);
    108     pBase = pCopy;
    109   }
    110   else { // find
    111     delete pCopy;
    112     pBase = result;
    113   }
    114 }
    115 
    116 void AttributeProxy::setWholeArchive()
    117 {
    118   Attribute *copy = new Attribute(*m_pBase);
    119   copy->setWholeArchive();
    120   ReplaceOrRecord(m_AttrPool, m_pBase, copy);
    121 }
    122 
    123 void AttributeProxy::unsetWholeArchive()
    124 {
    125   Attribute *copy = new Attribute(*m_pBase);
    126   copy->unsetWholeArchive();
    127   ReplaceOrRecord(m_AttrPool, m_pBase, copy);
    128 }
    129 
    130 void AttributeProxy::setAsNeeded()
    131 {
    132   Attribute *copy = new Attribute(*m_pBase);
    133   copy->setAsNeeded();
    134   ReplaceOrRecord(m_AttrPool, m_pBase, copy);
    135 }
    136 
    137 void AttributeProxy::unsetAsNeeded()
    138 {
    139   Attribute *copy = new Attribute(*m_pBase);
    140   copy->unsetAsNeeded();
    141   ReplaceOrRecord(m_AttrPool, m_pBase, copy);
    142 }
    143 
    144 void AttributeProxy::setAddNeeded()
    145 {
    146   Attribute *copy = new Attribute(*m_pBase);
    147   copy->setAddNeeded();
    148   ReplaceOrRecord(m_AttrPool, m_pBase, copy);
    149 }
    150 
    151 void AttributeProxy::unsetAddNeeded()
    152 {
    153   Attribute *copy = new Attribute(*m_pBase);
    154   copy->unsetAddNeeded();
    155   ReplaceOrRecord(m_AttrPool, m_pBase, copy);
    156 }
    157 
    158 void AttributeProxy::setStatic()
    159 {
    160   Attribute *copy = new Attribute(*m_pBase);
    161   copy->setStatic();
    162   ReplaceOrRecord(m_AttrPool, m_pBase, copy);
    163 }
    164 
    165 void AttributeProxy::setDynamic()
    166 {
    167   Attribute *copy = new Attribute(*m_pBase);
    168   copy->setDynamic();
    169   ReplaceOrRecord(m_AttrPool, m_pBase, copy);
    170 }
    171 
    172 AttributeProxy& AttributeProxy::assign(Attribute* pBase)
    173 {
    174   m_pBase = pBase;
    175   return *this;
    176 }
    177 
    178