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
14 namespace mcld {
15
16 //===----------------------------------------------------------------------===//
17 // AttrConstraint
18 //===----------------------------------------------------------------------===//
isLegal(const Attribute & pAttr) const19 bool 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 //===----------------------------------------------------------------------===//
AttributeProxy(AttributeSet & pParent,const Attribute & pBase,const AttrConstraint & pConstraint)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
~AttributeProxy()57 AttributeProxy::~AttributeProxy() {
58 }
59
isWholeArchive() const60 bool AttributeProxy::isWholeArchive() const {
61 if (m_Constraint.isWholeArchive())
62 return m_pBase->isWholeArchive();
63 else
64 return false;
65 }
66
isAsNeeded() const67 bool AttributeProxy::isAsNeeded() const {
68 if (m_Constraint.isAsNeeded())
69 return m_pBase->isAsNeeded();
70 else
71 return false;
72 }
73
isAddNeeded() const74 bool AttributeProxy::isAddNeeded() const {
75 if (m_Constraint.isAddNeeded())
76 return m_pBase->isAddNeeded();
77 else
78 return false;
79 }
80
isStatic() const81 bool AttributeProxy::isStatic() const {
82 if (m_Constraint.isSharedSystem())
83 return m_pBase->isStatic();
84 else
85 return true;
86 }
87
isDynamic() const88 bool AttributeProxy::isDynamic() const {
89 if (m_Constraint.isSharedSystem())
90 return m_pBase->isDynamic();
91 else
92 return false;
93 }
94
ReplaceOrRecord(AttributeSet & pParent,const Attribute * & pBase,Attribute * & pCopy)95 static 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
setWholeArchive()108 void AttributeProxy::setWholeArchive() {
109 Attribute* copy = new Attribute(*m_pBase);
110 copy->setWholeArchive();
111 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
112 }
113
unsetWholeArchive()114 void AttributeProxy::unsetWholeArchive() {
115 Attribute* copy = new Attribute(*m_pBase);
116 copy->unsetWholeArchive();
117 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
118 }
119
setAsNeeded()120 void AttributeProxy::setAsNeeded() {
121 Attribute* copy = new Attribute(*m_pBase);
122 copy->setAsNeeded();
123 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
124 }
125
unsetAsNeeded()126 void AttributeProxy::unsetAsNeeded() {
127 Attribute* copy = new Attribute(*m_pBase);
128 copy->unsetAsNeeded();
129 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
130 }
131
setAddNeeded()132 void AttributeProxy::setAddNeeded() {
133 Attribute* copy = new Attribute(*m_pBase);
134 copy->setAddNeeded();
135 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
136 }
137
unsetAddNeeded()138 void AttributeProxy::unsetAddNeeded() {
139 Attribute* copy = new Attribute(*m_pBase);
140 copy->unsetAddNeeded();
141 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
142 }
143
setStatic()144 void AttributeProxy::setStatic() {
145 Attribute* copy = new Attribute(*m_pBase);
146 copy->setStatic();
147 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
148 }
149
setDynamic()150 void AttributeProxy::setDynamic() {
151 Attribute* copy = new Attribute(*m_pBase);
152 copy->setDynamic();
153 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
154 }
155
assign(Attribute * pBase)156 AttributeProxy& AttributeProxy::assign(Attribute* pBase) {
157 m_pBase = pBase;
158 return *this;
159 }
160
161 } // namespace mcld
162