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 public:
33  AttributeBase()
34      : m_WholeArchive(false),
35        m_AsNeeded(false),
36        m_AddNeeded(true),
37        m_Static(false) {}
38
39  AttributeBase(const AttributeBase& pBase)
40      : m_WholeArchive(pBase.m_WholeArchive),
41        m_AsNeeded(pBase.m_AsNeeded),
42        m_AddNeeded(pBase.m_AddNeeded),
43        m_Static(pBase.m_Static) {}
44
45  virtual ~AttributeBase() {}
46
47  // ----- observers  ----- //
48  // represent GNU ld --whole-archive/--no-whole-archive options
49  bool isWholeArchive() const { return m_WholeArchive; }
50
51  // represent GNU ld --as-needed/--no-as-needed options
52  bool isAsNeeded() const { return m_AsNeeded; }
53
54  // represent GNU ld --add-needed/--no-add-needed options
55  bool isAddNeeded() const { return m_AddNeeded; }
56
57  // represent GNU ld -static option
58  bool isStatic() const { return m_Static; }
59
60  // represent GNU ld -call_shared option
61  bool isDynamic() const { return !m_Static; }
62
63 public:
64  bool m_WholeArchive : 1;
65  bool m_AsNeeded : 1;
66  bool m_AddNeeded : 1;
67  bool m_Static : 1;
68};
69
70/** \class Attribute
71 *  \brief The base class of attributes. Providing the raw operations of an
72 *  attributes
73 *
74 *  For conventience and producing less bugs, we move the stoarges of attributes
75 *  onto AttributeBase, and modifiers remains with the class Attribute.
76 */
77class Attribute : public AttributeBase {
78 public:
79  // -----  modifiers  ----- //
80  void setWholeArchive() { m_WholeArchive = true; }
81
82  void unsetWholeArchive() { m_WholeArchive = false; }
83
84  void setAsNeeded() { m_AsNeeded = true; }
85
86  void unsetAsNeeded() { m_AsNeeded = false; }
87
88  void setAddNeeded() { m_AddNeeded = true; }
89
90  void unsetAddNeeded() { m_AddNeeded = false; }
91
92  void setStatic() { m_Static = true; }
93
94  void setDynamic() { m_Static = false; }
95};
96
97/** \class AttrConstraint
98 *  \brief AttrConstarint is the constraint of a system.
99 *
100 *  Some systems can not enable certain attributes of a input file.
101 *  For example, systems which have no shared libraries can not enable
102 *  --call_shared options. We call the ability of enabling attributes
103 *  as the constraint of attributes of a system.
104 *
105 *  Systems enable attributes at the target implementation of SectLinker.
106 *
107 *  @see SectLinker
108 */
109class AttrConstraint : public AttributeBase {
110 public:
111  void enableWholeArchive() { m_WholeArchive = true; }
112
113  void disableWholeArchive() { m_WholeArchive = false; }
114
115  void enableAsNeeded() { m_AsNeeded = true; }
116
117  void disableAsNeeded() { m_AsNeeded = false; }
118
119  void enableAddNeeded() { m_AddNeeded = true; }
120
121  void disableAddNeeded() { m_AddNeeded = false; }
122
123  void setSharedSystem() { m_Static = false; }
124
125  void setStaticSystem() { m_Static = true; }
126
127  bool isSharedSystem() const { return !m_Static; }
128
129  bool isStaticSystem() const { return m_Static; }
130
131  bool isLegal(const Attribute& pAttr) const;
132};
133
134/** \class AttributeProxy
135 *  \brief AttributeProxys is the illusion of private attribute of each
136 *  input file.
137 *
138 *  We designers want to hide the details of sharing common attributes
139 *  between input files. We want input files under the illusion that they
140 *  have their own private attributes to simplify the linking algorithms.
141 *
142 *  AttributeProxy hides the reality of sharing. An input file can change
143 *  its attribute without explicit searching of existing attributes
144 *  as it has a private ownership of the attribute. AttributeProxy does
145 *  the searching in the AttributeSet and changes the pointer of
146 *  the attribute of the input file. If the searching fails, AttributeProxy
147 *  requests a new attribute from the AttributeSet.
148 */
149class AttributeProxy {
150 public:
151  AttributeProxy(AttributeSet& pParent,
152                 const Attribute& pBase,
153                 const AttrConstraint& pConstraint);
154
155  ~AttributeProxy();
156
157  // ----- observers  ----- //
158  bool isWholeArchive() const;
159
160  bool isAsNeeded() const;
161
162  bool isAddNeeded() const;
163
164  bool isStatic() const;
165
166  bool isDynamic() const;
167
168  const Attribute* attr() const { return m_pBase; }
169
170  // -----  modifiers  ----- //
171  void setWholeArchive();
172  void unsetWholeArchive();
173  void setAsNeeded();
174  void unsetAsNeeded();
175  void setAddNeeded();
176  void unsetAddNeeded();
177  void setStatic();
178  void setDynamic();
179
180  AttributeProxy& assign(Attribute* pBase);
181
182 private:
183  AttributeSet& m_AttrPool;
184  const Attribute* m_pBase;
185  const AttrConstraint& m_Constraint;
186};
187
188// -----  comparisons  ----- //
189inline bool operator==(const Attribute& pLHS, const Attribute& pRHS) {
190  return ((pLHS.isWholeArchive() == pRHS.isWholeArchive()) &&
191          (pLHS.isAsNeeded() == pRHS.isAsNeeded()) &&
192          (pLHS.isAddNeeded() == pRHS.isAddNeeded()) &&
193          (pLHS.isStatic() == pRHS.isStatic()));
194}
195
196inline bool operator!=(const Attribute& pLHS, const Attribute& pRHS) {
197  return !(pLHS == pRHS);
198}
199
200}  // namespace mcld
201
202#endif  // MCLD_MC_ATTRIBUTE_H_
203