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