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