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