1//===- Attribute.h --------------------------------------------------------===//
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#ifndef MCLD_MC_ATTRIBUTE_H
10#define MCLD_MC_ATTRIBUTE_H
11
12namespace mcld {
13
14class AttributeSet;
15
16/** \class AttributeBase
17 *  \brief AttributeBase provides the real storage for attributes of options.
18 *
19 *  Attributes are options affecting the link editing of input files.
20 *  Some options affects the input files mentioned on the command line after
21 *  them. For example, --whole-archive option affects archives mentioned on
22 *  the command line after the --whole-archve option. We call such options
23 *  "attributes of input files"
24 *
25 *  AttributeBase is the storage for attributes of input files. Each input
26 *  file (@see mcld::Input in MCLinker) has a pointer of an attribute. Since
27 *  most attributes of input files are identical, our design lets input files
28 *  which have identical attributes share common attribute. AttributeBase is
29 *  the shared storage for attribute.
30 */
31class AttributeBase
32{
33public:
34  AttributeBase()
35  : m_WholeArchive(false),
36    m_AsNeeded(false),
37    m_AddNeeded(true),
38    m_Static(false)
39  { }
40
41  AttributeBase(const AttributeBase& pBase)
42  : m_WholeArchive(pBase.m_WholeArchive),
43    m_AsNeeded(pBase.m_AsNeeded),
44    m_AddNeeded(pBase.m_AddNeeded),
45    m_Static(pBase.m_Static)
46  { }
47
48  virtual ~AttributeBase()
49  { }
50
51  // ----- observers  ----- //
52  // represent GNU ld --whole-archive/--no-whole-archive options
53  bool isWholeArchive() const
54  { return m_WholeArchive; }
55
56  // represent GNU ld --as-needed/--no-as-needed options
57  bool isAsNeeded() const
58  { return m_AsNeeded; }
59
60  // represent GNU ld --add-needed/--no-add-needed options
61  bool isAddNeeded() const
62  { return m_AddNeeded; }
63
64  // represent GNU ld -static option
65  bool isStatic() const
66  { return m_Static; }
67
68  // represent GNU ld -call_shared option
69  bool isDynamic() const
70  { return !m_Static; }
71
72public:
73  bool m_WholeArchive : 1;
74  bool m_AsNeeded : 1;
75  bool m_AddNeeded : 1;
76  bool m_Static : 1;
77};
78
79/** \class Attribute
80 *  \brief The base class of attributes. Providing the raw operations of an
81 *  attributes
82 *
83 *  For conventience and producing less bugs, we move the stoarges of attributes
84 *  onto AttributeBase, and modifiers remains with the class Attribute.
85 */
86class Attribute : public AttributeBase
87{
88public:
89  // -----  modifiers  ----- //
90  void setWholeArchive()
91  { m_WholeArchive = true; }
92
93  void unsetWholeArchive()
94  { m_WholeArchive = false; }
95
96  void setAsNeeded()
97  { m_AsNeeded = true; }
98
99  void unsetAsNeeded()
100  { m_AsNeeded = false; }
101
102  void setAddNeeded()
103  { m_AddNeeded = true; }
104
105  void unsetAddNeeded()
106  { m_AddNeeded = false; }
107
108  void setStatic()
109  { m_Static = true; }
110
111  void setDynamic()
112  { m_Static = false; }
113};
114
115/** \class AttrConstraint
116 *  \brief AttrConstarint is the constraint of a system.
117 *
118 *  Some systems can not enable certain attributes of a input file.
119 *  For example, systems which have no shared libraries can not enable
120 *  --call_shared options. We call the ability of enabling attributes
121 *  as the constraint of attributes of a system.
122 *
123 *  Systems enable attributes at the target implementation of SectLinker.
124 *
125 *  @see SectLinker
126 */
127class AttrConstraint : public AttributeBase
128{
129public:
130  void enableWholeArchive()
131  { m_WholeArchive = true; }
132
133  void disableWholeArchive()
134  { m_WholeArchive = false; }
135
136  void enableAsNeeded()
137  { m_AsNeeded = true; }
138
139  void disableAsNeeded()
140  { m_AsNeeded = false; }
141
142  void enableAddNeeded()
143  { m_AddNeeded = true; }
144
145  void disableAddNeeded()
146  { m_AddNeeded = false; }
147
148  void setSharedSystem()
149  { m_Static = false; }
150
151  void setStaticSystem()
152  { m_Static = true; }
153
154  bool isSharedSystem() const
155  { return !m_Static; }
156
157  bool isStaticSystem() const
158  { return m_Static; }
159
160  bool isLegal(const Attribute& pAttr) const;
161};
162
163/** \class AttributeProxy
164 *  \brief AttributeProxys is the illusion of private attribute of each
165 *  input file.
166 *
167 *  We designers want to hide the details of sharing common attributes
168 *  between input files. We want input files under the illusion that they
169 *  have their own private attributes to simplify the linking algorithms.
170 *
171 *  AttributeProxy hides the reality of sharing. An input file can change
172 *  its attribute without explicit searching of existing attributes
173 *  as it has a private ownership of the attribute. AttributeProxy does
174 *  the searching in the AttributeSet and changes the pointer of
175 *  the attribute of the input file. If the searching fails, AttributeProxy
176 *  requests a new attribute from the AttributeSet.
177 */
178class AttributeProxy
179{
180public:
181  AttributeProxy(AttributeSet& pParent,
182                 const Attribute& pBase,
183                 const AttrConstraint& pConstraint);
184
185  ~AttributeProxy();
186
187  // ----- observers  ----- //
188  bool isWholeArchive() const;
189
190  bool isAsNeeded() const;
191
192  bool isAddNeeded() const;
193
194  bool isStatic() const;
195
196  bool isDynamic() const;
197
198  const Attribute* attr() const
199  { return m_pBase; }
200
201  // -----  modifiers  ----- //
202  void setWholeArchive();
203  void unsetWholeArchive();
204  void setAsNeeded();
205  void unsetAsNeeded();
206  void setAddNeeded();
207  void unsetAddNeeded();
208  void setStatic();
209  void setDynamic();
210
211  AttributeProxy& assign(Attribute* pBase);
212
213private:
214  AttributeSet &m_AttrPool;
215  const Attribute *m_pBase;
216  const AttrConstraint& m_Constraint;
217};
218
219
220// -----  comparisons  ----- //
221inline bool operator== (const Attribute& pLHS, const Attribute& pRHS)
222{
223  return ((pLHS.isWholeArchive() == pRHS.isWholeArchive()) &&
224    (pLHS.isAsNeeded() == pRHS.isAsNeeded()) &&
225    (pLHS.isAddNeeded() == pRHS.isAddNeeded()) &&
226    (pLHS.isStatic() == pRHS.isStatic()));
227}
228
229inline bool operator!= (const Attribute& pLHS, const Attribute& pRHS)
230{
231  return !(pLHS == pRHS);
232}
233
234} // namespace of mcld
235
236#endif
237
238