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