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