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_ATTRIBUTE_H 10 #define MCLD_ATTRIBUTE_H 11 #ifdef ENABLE_UNITTEST 12 #include <gtest.h> 13 #endif 14 15 namespace mcld { 16 17 class 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 */ 34 class AttributeBase 35 { 36 public: 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 75 public: 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 */ 89 class Attribute : public AttributeBase 90 { 91 public: 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 */ 130 class AttrConstraint : public AttributeBase 131 { 132 public: 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 */ 181 class AttributeProxy 182 { 183 public: 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 216 private: 217 AttributeSet &m_AttrPool; 218 const Attribute *m_pBase; 219 const AttrConstraint& m_Constraint; 220 }; 221 222 223 // ----- comparisons ----- // 224 inline 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 232 inline bool operator!= (const Attribute& pLHS, const Attribute& pRHS) 233 { 234 return !(pLHS == pRHS); 235 } 236 237 } // namespace of mcld 238 239 #endif 240 241