Attribute.cpp revision 37b74a387bb3993387029859c2d9d051c41c724e
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 11#include "mcld/MC/AttributeSet.h" 12#include "mcld/Support/MsgHandling.h" 13 14namespace mcld { 15 16//===----------------------------------------------------------------------===// 17// AttrConstraint 18//===----------------------------------------------------------------------===// 19bool AttrConstraint::isLegal(const Attribute& pAttr) const { 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//===----------------------------------------------------------------------===// 51AttributeProxy::AttributeProxy(AttributeSet& pParent, 52 const Attribute& pBase, 53 const AttrConstraint& pConstraint) 54 : m_AttrPool(pParent), m_pBase(&pBase), m_Constraint(pConstraint) { 55} 56 57AttributeProxy::~AttributeProxy() { 58} 59 60bool AttributeProxy::isWholeArchive() const { 61 if (m_Constraint.isWholeArchive()) 62 return m_pBase->isWholeArchive(); 63 else 64 return false; 65} 66 67bool AttributeProxy::isAsNeeded() const { 68 if (m_Constraint.isAsNeeded()) 69 return m_pBase->isAsNeeded(); 70 else 71 return false; 72} 73 74bool AttributeProxy::isAddNeeded() const { 75 if (m_Constraint.isAddNeeded()) 76 return m_pBase->isAddNeeded(); 77 else 78 return false; 79} 80 81bool AttributeProxy::isStatic() const { 82 if (m_Constraint.isSharedSystem()) 83 return m_pBase->isStatic(); 84 else 85 return true; 86} 87 88bool AttributeProxy::isDynamic() const { 89 if (m_Constraint.isSharedSystem()) 90 return m_pBase->isDynamic(); 91 else 92 return false; 93} 94 95static inline void ReplaceOrRecord(AttributeSet& pParent, 96 const Attribute*& pBase, 97 Attribute*& pCopy) { 98 Attribute* result = pParent.exists(*pCopy); 99 if (result == NULL) { // can not find 100 pParent.record(*pCopy); 101 pBase = pCopy; 102 } else { // find 103 delete pCopy; 104 pBase = result; 105 } 106} 107 108void AttributeProxy::setWholeArchive() { 109 Attribute* copy = new Attribute(*m_pBase); 110 copy->setWholeArchive(); 111 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 112} 113 114void AttributeProxy::unsetWholeArchive() { 115 Attribute* copy = new Attribute(*m_pBase); 116 copy->unsetWholeArchive(); 117 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 118} 119 120void AttributeProxy::setAsNeeded() { 121 Attribute* copy = new Attribute(*m_pBase); 122 copy->setAsNeeded(); 123 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 124} 125 126void AttributeProxy::unsetAsNeeded() { 127 Attribute* copy = new Attribute(*m_pBase); 128 copy->unsetAsNeeded(); 129 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 130} 131 132void AttributeProxy::setAddNeeded() { 133 Attribute* copy = new Attribute(*m_pBase); 134 copy->setAddNeeded(); 135 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 136} 137 138void AttributeProxy::unsetAddNeeded() { 139 Attribute* copy = new Attribute(*m_pBase); 140 copy->unsetAddNeeded(); 141 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 142} 143 144void AttributeProxy::setStatic() { 145 Attribute* copy = new Attribute(*m_pBase); 146 copy->setStatic(); 147 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 148} 149 150void AttributeProxy::setDynamic() { 151 Attribute* copy = new Attribute(*m_pBase); 152 copy->setDynamic(); 153 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 154} 155 156AttributeProxy& AttributeProxy::assign(Attribute* pBase) { 157 m_pBase = pBase; 158 return *this; 159} 160 161} // namespace mcld 162