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: 39 AttributeBase() 40 : m_WholeArchive(false), 41 m_AsNeeded(false), 42 m_AddNeeded(true), 43 m_Static(false) 44 { } 45 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 53 virtual ~AttributeBase() 54 { } 55 56 // ----- observers ----- // 57 // represent GNU ld --whole-archive/--no-whole-archive options 58 bool isWholeArchive() const 59 { return m_WholeArchive; } 60 61 // represent GNU ld --as-needed/--no-as-needed options 62 bool isAsNeeded() const 63 { return m_AsNeeded; } 64 65 // represent GNU ld --add-needed/--no-add-needed options 66 bool isAddNeeded() const 67 { return m_AddNeeded; } 68 69 // represent GNU ld -static option 70 bool isStatic() const 71 { return m_Static; } 72 73 // represent GNU ld -call_shared option 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 ----- // 94 void setWholeArchive() 95 { m_WholeArchive = true; } 96 97 void unsetWholeArchive() 98 { m_WholeArchive = false; } 99 100 void setAsNeeded() 101 { m_AsNeeded = true; } 102 103 void unsetAsNeeded() 104 { m_AsNeeded = false; } 105 106 void setAddNeeded() 107 { m_AddNeeded = true; } 108 109 void unsetAddNeeded() 110 { m_AddNeeded = false; } 111 112 void setStatic() 113 { m_Static = true; } 114 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: 134 void enableWholeArchive() 135 { m_WholeArchive = true; } 136 137 void disableWholeArchive() 138 { m_WholeArchive = false; } 139 140 void enableAsNeeded() 141 { m_AsNeeded = true; } 142 143 void disableAsNeeded() 144 { m_AsNeeded = false; } 145 146 void enableAddNeeded() 147 { m_AddNeeded = true; } 148 149 void disableAddNeeded() 150 { m_AddNeeded = false; } 151 152 void setSharedSystem() 153 { m_Static = false; } 154 155 void setStaticSystem() 156 { m_Static = true; } 157 158 bool isSharedSystem() const 159 { return !m_Static; } 160 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 202 Attribute* attr() 203 { return m_pBase; } 204 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 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