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