1 //===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the DeclarationName and DeclarationNameTable 11 // classes. 12 // 13 //===----------------------------------------------------------------------===// 14 #include "clang/AST/DeclarationName.h" 15 #include "clang/AST/Type.h" 16 #include "clang/AST/Decl.h" 17 #include "clang/Basic/IdentifierTable.h" 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/ADT/FoldingSet.h" 20 using namespace clang; 21 22 namespace clang { 23 /// CXXSpecialName - Records the type associated with one of the 24 /// "special" kinds of declaration names in C++, e.g., constructors, 25 /// destructors, and conversion functions. 26 class CXXSpecialName 27 : public DeclarationNameExtra, public llvm::FoldingSetNode { 28 public: 29 /// Type - The type associated with this declaration name. 30 QualType Type; 31 32 /// FETokenInfo - Extra information associated with this declaration 33 /// name that can be used by the front end. 34 void *FETokenInfo; 35 36 void Profile(llvm::FoldingSetNodeID &ID) { 37 ID.AddInteger(ExtraKindOrNumArgs); 38 ID.AddPointer(Type.getAsOpaquePtr()); 39 } 40 }; 41 42 /// CXXOperatorIdName - Contains extra information for the name of an 43 /// overloaded operator in C++, such as "operator+. 44 class CXXOperatorIdName : public DeclarationNameExtra { 45 public: 46 /// FETokenInfo - Extra information associated with this operator 47 /// name that can be used by the front end. 48 void *FETokenInfo; 49 }; 50 51 bool operator<(DeclarationName LHS, DeclarationName RHS) { 52 if (IdentifierInfo *LhsId = LHS.getAsIdentifierInfo()) 53 if (IdentifierInfo *RhsId = RHS.getAsIdentifierInfo()) 54 return strcmp(LhsId->getName(), RhsId->getName()) < 0; 55 56 return LHS.getAsOpaqueInteger() < RHS.getAsOpaqueInteger(); 57 } 58 59 } // end namespace clang 60 61 DeclarationName::DeclarationName(Selector Sel) { 62 if (!Sel.getAsOpaquePtr()) { 63 Ptr = StoredObjCZeroArgSelector; 64 return; 65 } 66 67 switch (Sel.getNumArgs()) { 68 case 0: 69 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); 70 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); 71 Ptr |= StoredObjCZeroArgSelector; 72 break; 73 74 case 1: 75 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); 76 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); 77 Ptr |= StoredObjCOneArgSelector; 78 break; 79 80 default: 81 Ptr = Sel.InfoPtr & ~Selector::ArgFlags; 82 assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector"); 83 Ptr |= StoredDeclarationNameExtra; 84 break; 85 } 86 } 87 88 DeclarationName::NameKind DeclarationName::getNameKind() const { 89 switch (getStoredNameKind()) { 90 case StoredIdentifier: return Identifier; 91 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; 92 case StoredObjCOneArgSelector: return ObjCOneArgSelector; 93 94 case StoredDeclarationNameExtra: 95 switch (getExtra()->ExtraKindOrNumArgs) { 96 case DeclarationNameExtra::CXXConstructor: 97 return CXXConstructorName; 98 99 case DeclarationNameExtra::CXXDestructor: 100 return CXXDestructorName; 101 102 case DeclarationNameExtra::CXXConversionFunction: 103 return CXXConversionFunctionName; 104 105 case DeclarationNameExtra::CXXUsingDirective: 106 return CXXUsingDirective; 107 108 default: 109 // Check if we have one of the CXXOperator* enumeration values. 110 if (getExtra()->ExtraKindOrNumArgs < 111 DeclarationNameExtra::CXXUsingDirective) 112 return CXXOperatorName; 113 114 return ObjCMultiArgSelector; 115 } 116 break; 117 } 118 119 // Can't actually get here. 120 assert(0 && "This should be unreachable!"); 121 return Identifier; 122 } 123 124 std::string DeclarationName::getAsString() const { 125 switch (getNameKind()) { 126 case Identifier: 127 if (const IdentifierInfo *II = getAsIdentifierInfo()) 128 return II->getName(); 129 return ""; 130 131 case ObjCZeroArgSelector: 132 case ObjCOneArgSelector: 133 case ObjCMultiArgSelector: 134 return getObjCSelector().getAsString(); 135 136 case CXXConstructorName: { 137 QualType ClassType = getCXXNameType(); 138 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) 139 return ClassRec->getDecl()->getNameAsString(); 140 return ClassType.getAsString(); 141 } 142 143 case CXXDestructorName: { 144 std::string Result = "~"; 145 QualType Type = getCXXNameType(); 146 if (const RecordType *Rec = Type->getAs<RecordType>()) 147 Result += Rec->getDecl()->getNameAsString(); 148 else 149 Result += Type.getAsString(); 150 return Result; 151 } 152 153 case CXXOperatorName: { 154 static const char *OperatorNames[NUM_OVERLOADED_OPERATORS] = { 155 0, 156 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 157 Spelling, 158 #include "clang/Basic/OperatorKinds.def" 159 }; 160 const char *OpName = OperatorNames[getCXXOverloadedOperator()]; 161 assert(OpName && "not an overloaded operator"); 162 163 std::string Result = "operator"; 164 if (OpName[0] >= 'a' && OpName[0] <= 'z') 165 Result += ' '; 166 Result += OpName; 167 return Result; 168 } 169 170 case CXXConversionFunctionName: { 171 std::string Result = "operator "; 172 QualType Type = getCXXNameType(); 173 if (const RecordType *Rec = Type->getAs<RecordType>()) 174 Result += Rec->getDecl()->getNameAsString(); 175 else 176 Result += Type.getAsString(); 177 return Result; 178 } 179 case CXXUsingDirective: 180 return "<using-directive>"; 181 } 182 183 assert(false && "Unexpected declaration name kind"); 184 return ""; 185 } 186 187 QualType DeclarationName::getCXXNameType() const { 188 if (CXXSpecialName *CXXName = getAsCXXSpecialName()) 189 return CXXName->Type; 190 else 191 return QualType(); 192 } 193 194 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { 195 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { 196 unsigned value 197 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; 198 return static_cast<OverloadedOperatorKind>(value); 199 } else { 200 return OO_None; 201 } 202 } 203 204 Selector DeclarationName::getObjCSelector() const { 205 switch (getNameKind()) { 206 case ObjCZeroArgSelector: 207 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0); 208 209 case ObjCOneArgSelector: 210 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1); 211 212 case ObjCMultiArgSelector: 213 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask)); 214 215 default: 216 break; 217 } 218 219 return Selector(); 220 } 221 222 void *DeclarationName::getFETokenInfoAsVoid() const { 223 switch (getNameKind()) { 224 case Identifier: 225 return getAsIdentifierInfo()->getFETokenInfo<void>(); 226 227 case CXXConstructorName: 228 case CXXDestructorName: 229 case CXXConversionFunctionName: 230 return getAsCXXSpecialName()->FETokenInfo; 231 232 case CXXOperatorName: 233 return getAsCXXOperatorIdName()->FETokenInfo; 234 235 default: 236 assert(false && "Declaration name has no FETokenInfo"); 237 } 238 return 0; 239 } 240 241 void DeclarationName::setFETokenInfo(void *T) { 242 switch (getNameKind()) { 243 case Identifier: 244 getAsIdentifierInfo()->setFETokenInfo(T); 245 break; 246 247 case CXXConstructorName: 248 case CXXDestructorName: 249 case CXXConversionFunctionName: 250 getAsCXXSpecialName()->FETokenInfo = T; 251 break; 252 253 case CXXOperatorName: 254 getAsCXXOperatorIdName()->FETokenInfo = T; 255 break; 256 257 default: 258 assert(false && "Declaration name has no FETokenInfo"); 259 } 260 } 261 262 DeclarationName DeclarationName::getUsingDirectiveName() { 263 // Single instance of DeclarationNameExtra for using-directive 264 static DeclarationNameExtra UDirExtra = 265 { DeclarationNameExtra::CXXUsingDirective }; 266 267 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); 268 Ptr |= StoredDeclarationNameExtra; 269 270 return DeclarationName(Ptr); 271 } 272 273 DeclarationNameTable::DeclarationNameTable() { 274 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; 275 276 // Initialize the overloaded operator names. 277 CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; 278 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { 279 CXXOperatorNames[Op].ExtraKindOrNumArgs 280 = Op + DeclarationNameExtra::CXXConversionFunction; 281 CXXOperatorNames[Op].FETokenInfo = 0; 282 } 283 } 284 285 DeclarationNameTable::~DeclarationNameTable() { 286 llvm::FoldingSet<CXXSpecialName> *set = 287 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 288 llvm::FoldingSetIterator<CXXSpecialName> I = set->begin(), E = set->end(); 289 290 while (I != E) { 291 CXXSpecialName *n = &*I++; 292 delete n; 293 } 294 295 delete set; 296 delete [] CXXOperatorNames; 297 } 298 299 DeclarationName 300 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 301 QualType Ty) { 302 assert(Kind >= DeclarationName::CXXConstructorName && 303 Kind <= DeclarationName::CXXConversionFunctionName && 304 "Kind must be a C++ special name kind"); 305 assert(Ty->isCanonical() && 306 "Can only build C++ special names from canonical types"); 307 llvm::FoldingSet<CXXSpecialName> *SpecialNames 308 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 309 310 DeclarationNameExtra::ExtraKind EKind; 311 switch (Kind) { 312 case DeclarationName::CXXConstructorName: 313 EKind = DeclarationNameExtra::CXXConstructor; 314 assert(Ty.getCVRQualifiers() == 0 &&"Constructor type must be unqualified"); 315 break; 316 case DeclarationName::CXXDestructorName: 317 EKind = DeclarationNameExtra::CXXDestructor; 318 assert(Ty.getCVRQualifiers() == 0 && "Destructor type must be unqualified"); 319 break; 320 case DeclarationName::CXXConversionFunctionName: 321 EKind = DeclarationNameExtra::CXXConversionFunction; 322 break; 323 default: 324 return DeclarationName(); 325 } 326 327 // Unique selector, to guarantee there is one per name. 328 llvm::FoldingSetNodeID ID; 329 ID.AddInteger(EKind); 330 ID.AddPointer(Ty.getAsOpaquePtr()); 331 332 void *InsertPos = 0; 333 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) 334 return DeclarationName(Name); 335 336 CXXSpecialName *SpecialName = new CXXSpecialName; 337 SpecialName->ExtraKindOrNumArgs = EKind; 338 SpecialName->Type = Ty; 339 SpecialName->FETokenInfo = 0; 340 341 SpecialNames->InsertNode(SpecialName, InsertPos); 342 return DeclarationName(SpecialName); 343 } 344 345 DeclarationName 346 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { 347 return DeclarationName(&CXXOperatorNames[(unsigned)Op]); 348 } 349 350 unsigned 351 llvm::DenseMapInfo<clang::DeclarationName>:: 352 getHashValue(clang::DeclarationName N) { 353 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr()); 354 } 355 356