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 12 namespace mcld { 13 14 class 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 */ 31 class 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 */ 77 class 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 */ 109 class 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 */ 149 class 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 ----- // 189 inline 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 196 inline 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