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 //===----------------------------------------------------------------------===//
isLegal(const Attribute & pAttr) const18 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 //===----------------------------------------------------------------------===//
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 }
60
isWholeArchive() const61 bool AttributeProxy::isWholeArchive() const
62 {
63 if (m_Constraint.isWholeArchive())
64 return m_pBase->isWholeArchive();
65 else
66 return false;
67 }
68
isAsNeeded() const69 bool AttributeProxy::isAsNeeded() const
70 {
71 if (m_Constraint.isAsNeeded())
72 return m_pBase->isAsNeeded();
73 else
74 return false;
75 }
76
isAddNeeded() const77 bool AttributeProxy::isAddNeeded() const
78 {
79 if (m_Constraint.isAddNeeded())
80 return m_pBase->isAddNeeded();
81 else
82 return false;
83 }
84
isStatic() const85 bool AttributeProxy::isStatic() const
86 {
87 if (m_Constraint.isSharedSystem())
88 return m_pBase->isStatic();
89 else
90 return true;
91 }
92
isDynamic() const93 bool AttributeProxy::isDynamic() const
94 {
95 if (m_Constraint.isSharedSystem())
96 return m_pBase->isDynamic();
97 else
98 return false;
99 }
100
ReplaceOrRecord(AttributeSet & pParent,const Attribute * & pBase,Attribute * & pCopy)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
setWholeArchive()116 void AttributeProxy::setWholeArchive()
117 {
118 Attribute *copy = new Attribute(*m_pBase);
119 copy->setWholeArchive();
120 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
121 }
122
unsetWholeArchive()123 void AttributeProxy::unsetWholeArchive()
124 {
125 Attribute *copy = new Attribute(*m_pBase);
126 copy->unsetWholeArchive();
127 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
128 }
129
setAsNeeded()130 void AttributeProxy::setAsNeeded()
131 {
132 Attribute *copy = new Attribute(*m_pBase);
133 copy->setAsNeeded();
134 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
135 }
136
unsetAsNeeded()137 void AttributeProxy::unsetAsNeeded()
138 {
139 Attribute *copy = new Attribute(*m_pBase);
140 copy->unsetAsNeeded();
141 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
142 }
143
setAddNeeded()144 void AttributeProxy::setAddNeeded()
145 {
146 Attribute *copy = new Attribute(*m_pBase);
147 copy->setAddNeeded();
148 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
149 }
150
unsetAddNeeded()151 void AttributeProxy::unsetAddNeeded()
152 {
153 Attribute *copy = new Attribute(*m_pBase);
154 copy->unsetAddNeeded();
155 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
156 }
157
setStatic()158 void AttributeProxy::setStatic()
159 {
160 Attribute *copy = new Attribute(*m_pBase);
161 copy->setStatic();
162 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
163 }
164
setDynamic()165 void AttributeProxy::setDynamic()
166 {
167 Attribute *copy = new Attribute(*m_pBase);
168 copy->setDynamic();
169 ReplaceOrRecord(m_AttrPool, m_pBase, copy);
170 }
171
assign(Attribute * pBase)172 AttributeProxy& AttributeProxy::assign(Attribute* pBase)
173 {
174 m_pBase = pBase;
175 return *this;
176 }
177
178