• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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