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