DeclarationName.cpp revision 203955
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/TypeOrdering.h" 17#include "clang/AST/Decl.h" 18#include "clang/Basic/IdentifierTable.h" 19#include "llvm/ADT/DenseMap.h" 20#include "llvm/ADT/FoldingSet.h" 21#include <cstdio> 22using namespace clang; 23 24namespace clang { 25/// CXXSpecialName - Records the type associated with one of the 26/// "special" kinds of declaration names in C++, e.g., constructors, 27/// destructors, and conversion functions. 28class CXXSpecialName 29 : public DeclarationNameExtra, public llvm::FoldingSetNode { 30public: 31 /// Type - The type associated with this declaration name. 32 QualType Type; 33 34 /// FETokenInfo - Extra information associated with this declaration 35 /// name that can be used by the front end. 36 void *FETokenInfo; 37 38 void Profile(llvm::FoldingSetNodeID &ID) { 39 ID.AddInteger(ExtraKindOrNumArgs); 40 ID.AddPointer(Type.getAsOpaquePtr()); 41 } 42}; 43 44/// CXXOperatorIdName - Contains extra information for the name of an 45/// overloaded operator in C++, such as "operator+. 46class CXXOperatorIdName : public DeclarationNameExtra { 47public: 48 /// FETokenInfo - Extra information associated with this operator 49 /// name that can be used by the front end. 50 void *FETokenInfo; 51}; 52 53/// CXXLiberalOperatorName - Contains the actual identifier that makes up the 54/// name. 55/// 56/// This identifier is stored here rather than directly in DeclarationName so as 57/// to allow Objective-C selectors, which are about a million times more common, 58/// to consume minimal memory. 59class CXXLiteralOperatorIdName 60 : public DeclarationNameExtra, public llvm::FoldingSetNode { 61public: 62 IdentifierInfo *ID; 63 64 void Profile(llvm::FoldingSetNodeID &FSID) { 65 FSID.AddPointer(ID); 66 } 67}; 68 69static int compareInt(unsigned A, unsigned B) { 70 return (A < B ? -1 : (A > B ? 1 : 0)); 71} 72 73int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { 74 if (LHS.getNameKind() != RHS.getNameKind()) 75 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1); 76 77 switch (LHS.getNameKind()) { 78 case DeclarationName::Identifier: { 79 IdentifierInfo *LII = LHS.getAsIdentifierInfo(); 80 IdentifierInfo *RII = RHS.getAsIdentifierInfo(); 81 if (!LII) return RII ? -1 : 0; 82 if (!RII) return 1; 83 84 return LII->getName().compare(RII->getName()); 85 } 86 87 case DeclarationName::ObjCZeroArgSelector: 88 case DeclarationName::ObjCOneArgSelector: 89 case DeclarationName::ObjCMultiArgSelector: { 90 Selector LHSSelector = LHS.getObjCSelector(); 91 Selector RHSSelector = RHS.getObjCSelector(); 92 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs(); 93 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) { 94 IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I); 95 IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I); 96 97 switch (LHSId->getName().compare(RHSId->getName())) { 98 case -1: return true; 99 case 1: return false; 100 default: break; 101 } 102 } 103 104 return compareInt(LN, RN); 105 } 106 107 case DeclarationName::CXXConstructorName: 108 case DeclarationName::CXXDestructorName: 109 case DeclarationName::CXXConversionFunctionName: 110 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType())) 111 return -1; 112 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType())) 113 return 1; 114 return 0; 115 116 case DeclarationName::CXXOperatorName: 117 return compareInt(LHS.getCXXOverloadedOperator(), 118 RHS.getCXXOverloadedOperator()); 119 120 case DeclarationName::CXXLiteralOperatorName: 121 return LHS.getCXXLiteralIdentifier()->getName().compare( 122 RHS.getCXXLiteralIdentifier()->getName()); 123 124 case DeclarationName::CXXUsingDirective: 125 return 0; 126 } 127 128 return 0; 129} 130 131} // end namespace clang 132 133DeclarationName::DeclarationName(Selector Sel) { 134 if (!Sel.getAsOpaquePtr()) { 135 Ptr = 0; 136 return; 137 } 138 139 switch (Sel.getNumArgs()) { 140 case 0: 141 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); 142 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); 143 Ptr |= StoredObjCZeroArgSelector; 144 break; 145 146 case 1: 147 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); 148 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); 149 Ptr |= StoredObjCOneArgSelector; 150 break; 151 152 default: 153 Ptr = Sel.InfoPtr & ~Selector::ArgFlags; 154 assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector"); 155 Ptr |= StoredDeclarationNameExtra; 156 break; 157 } 158} 159 160DeclarationName::NameKind DeclarationName::getNameKind() const { 161 switch (getStoredNameKind()) { 162 case StoredIdentifier: return Identifier; 163 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; 164 case StoredObjCOneArgSelector: return ObjCOneArgSelector; 165 166 case StoredDeclarationNameExtra: 167 switch (getExtra()->ExtraKindOrNumArgs) { 168 case DeclarationNameExtra::CXXConstructor: 169 return CXXConstructorName; 170 171 case DeclarationNameExtra::CXXDestructor: 172 return CXXDestructorName; 173 174 case DeclarationNameExtra::CXXConversionFunction: 175 return CXXConversionFunctionName; 176 177 case DeclarationNameExtra::CXXLiteralOperator: 178 return CXXLiteralOperatorName; 179 180 case DeclarationNameExtra::CXXUsingDirective: 181 return CXXUsingDirective; 182 183 default: 184 // Check if we have one of the CXXOperator* enumeration values. 185 if (getExtra()->ExtraKindOrNumArgs < 186 DeclarationNameExtra::CXXUsingDirective) 187 return CXXOperatorName; 188 189 return ObjCMultiArgSelector; 190 } 191 break; 192 } 193 194 // Can't actually get here. 195 assert(0 && "This should be unreachable!"); 196 return Identifier; 197} 198 199bool DeclarationName::isDependentName() const { 200 QualType T = getCXXNameType(); 201 return !T.isNull() && T->isDependentType(); 202} 203 204std::string DeclarationName::getAsString() const { 205 switch (getNameKind()) { 206 case Identifier: 207 if (const IdentifierInfo *II = getAsIdentifierInfo()) 208 return II->getName(); 209 return ""; 210 211 case ObjCZeroArgSelector: 212 case ObjCOneArgSelector: 213 case ObjCMultiArgSelector: 214 return getObjCSelector().getAsString(); 215 216 case CXXConstructorName: { 217 QualType ClassType = getCXXNameType(); 218 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) 219 return ClassRec->getDecl()->getNameAsString(); 220 return ClassType.getAsString(); 221 } 222 223 case CXXDestructorName: { 224 std::string Result = "~"; 225 QualType Type = getCXXNameType(); 226 if (const RecordType *Rec = Type->getAs<RecordType>()) 227 Result += Rec->getDecl()->getNameAsString(); 228 else 229 Result += Type.getAsString(); 230 return Result; 231 } 232 233 case CXXOperatorName: { 234 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = { 235 0, 236#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 237 Spelling, 238#include "clang/Basic/OperatorKinds.def" 239 }; 240 const char *OpName = OperatorNames[getCXXOverloadedOperator()]; 241 assert(OpName && "not an overloaded operator"); 242 243 std::string Result = "operator"; 244 if (OpName[0] >= 'a' && OpName[0] <= 'z') 245 Result += ' '; 246 Result += OpName; 247 return Result; 248 } 249 250 case CXXLiteralOperatorName: { 251 return "operator \"\" " + std::string(getCXXLiteralIdentifier()->getName()); 252 } 253 254 case CXXConversionFunctionName: { 255 std::string Result = "operator "; 256 QualType Type = getCXXNameType(); 257 if (const RecordType *Rec = Type->getAs<RecordType>()) 258 Result += Rec->getDecl()->getNameAsString(); 259 else 260 Result += Type.getAsString(); 261 return Result; 262 } 263 case CXXUsingDirective: 264 return "<using-directive>"; 265 } 266 267 assert(false && "Unexpected declaration name kind"); 268 return ""; 269} 270 271QualType DeclarationName::getCXXNameType() const { 272 if (CXXSpecialName *CXXName = getAsCXXSpecialName()) 273 return CXXName->Type; 274 else 275 return QualType(); 276} 277 278OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { 279 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { 280 unsigned value 281 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; 282 return static_cast<OverloadedOperatorKind>(value); 283 } else { 284 return OO_None; 285 } 286} 287 288IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const { 289 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName()) 290 return CXXLit->ID; 291 else 292 return 0; 293} 294 295Selector DeclarationName::getObjCSelector() const { 296 switch (getNameKind()) { 297 case ObjCZeroArgSelector: 298 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0); 299 300 case ObjCOneArgSelector: 301 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1); 302 303 case ObjCMultiArgSelector: 304 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask)); 305 306 default: 307 break; 308 } 309 310 return Selector(); 311} 312 313void *DeclarationName::getFETokenInfoAsVoid() const { 314 switch (getNameKind()) { 315 case Identifier: 316 return getAsIdentifierInfo()->getFETokenInfo<void>(); 317 318 case CXXConstructorName: 319 case CXXDestructorName: 320 case CXXConversionFunctionName: 321 return getAsCXXSpecialName()->FETokenInfo; 322 323 case CXXOperatorName: 324 return getAsCXXOperatorIdName()->FETokenInfo; 325 326 case CXXLiteralOperatorName: 327 return getCXXLiteralIdentifier()->getFETokenInfo<void>(); 328 329 default: 330 assert(false && "Declaration name has no FETokenInfo"); 331 } 332 return 0; 333} 334 335void DeclarationName::setFETokenInfo(void *T) { 336 switch (getNameKind()) { 337 case Identifier: 338 getAsIdentifierInfo()->setFETokenInfo(T); 339 break; 340 341 case CXXConstructorName: 342 case CXXDestructorName: 343 case CXXConversionFunctionName: 344 getAsCXXSpecialName()->FETokenInfo = T; 345 break; 346 347 case CXXOperatorName: 348 getAsCXXOperatorIdName()->FETokenInfo = T; 349 break; 350 351 case CXXLiteralOperatorName: 352 getCXXLiteralIdentifier()->setFETokenInfo(T); 353 break; 354 355 default: 356 assert(false && "Declaration name has no FETokenInfo"); 357 } 358} 359 360DeclarationName DeclarationName::getUsingDirectiveName() { 361 // Single instance of DeclarationNameExtra for using-directive 362 static const DeclarationNameExtra UDirExtra = 363 { DeclarationNameExtra::CXXUsingDirective }; 364 365 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); 366 Ptr |= StoredDeclarationNameExtra; 367 368 return DeclarationName(Ptr); 369} 370 371void DeclarationName::dump() const { 372 fprintf(stderr, "%s\n", getAsString().c_str()); 373} 374 375DeclarationNameTable::DeclarationNameTable() { 376 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; 377 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; 378 379 // Initialize the overloaded operator names. 380 CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; 381 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { 382 CXXOperatorNames[Op].ExtraKindOrNumArgs 383 = Op + DeclarationNameExtra::CXXConversionFunction; 384 CXXOperatorNames[Op].FETokenInfo = 0; 385 } 386} 387 388DeclarationNameTable::~DeclarationNameTable() { 389 llvm::FoldingSet<CXXSpecialName> *SpecialNames = 390 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 391 llvm::FoldingSetIterator<CXXSpecialName> 392 SI = SpecialNames->begin(), SE = SpecialNames->end(); 393 394 while (SI != SE) { 395 CXXSpecialName *n = &*SI++; 396 delete n; 397 } 398 399 400 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames 401 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> 402 (CXXLiteralOperatorNames); 403 llvm::FoldingSetIterator<CXXLiteralOperatorIdName> 404 LI = LiteralNames->begin(), LE = LiteralNames->end(); 405 406 while (LI != LE) { 407 CXXLiteralOperatorIdName *n = &*LI++; 408 delete n; 409 } 410 411 delete SpecialNames; 412 delete LiteralNames; 413 delete [] CXXOperatorNames; 414} 415 416DeclarationName 417DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 418 CanQualType Ty) { 419 assert(Kind >= DeclarationName::CXXConstructorName && 420 Kind <= DeclarationName::CXXConversionFunctionName && 421 "Kind must be a C++ special name kind"); 422 llvm::FoldingSet<CXXSpecialName> *SpecialNames 423 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 424 425 DeclarationNameExtra::ExtraKind EKind; 426 switch (Kind) { 427 case DeclarationName::CXXConstructorName: 428 EKind = DeclarationNameExtra::CXXConstructor; 429 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); 430 break; 431 case DeclarationName::CXXDestructorName: 432 EKind = DeclarationNameExtra::CXXDestructor; 433 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); 434 break; 435 case DeclarationName::CXXConversionFunctionName: 436 EKind = DeclarationNameExtra::CXXConversionFunction; 437 break; 438 default: 439 return DeclarationName(); 440 } 441 442 // Unique selector, to guarantee there is one per name. 443 llvm::FoldingSetNodeID ID; 444 ID.AddInteger(EKind); 445 ID.AddPointer(Ty.getAsOpaquePtr()); 446 447 void *InsertPos = 0; 448 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) 449 return DeclarationName(Name); 450 451 CXXSpecialName *SpecialName = new CXXSpecialName; 452 SpecialName->ExtraKindOrNumArgs = EKind; 453 SpecialName->Type = Ty; 454 SpecialName->FETokenInfo = 0; 455 456 SpecialNames->InsertNode(SpecialName, InsertPos); 457 return DeclarationName(SpecialName); 458} 459 460DeclarationName 461DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { 462 return DeclarationName(&CXXOperatorNames[(unsigned)Op]); 463} 464 465DeclarationName 466DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { 467 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames 468 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> 469 (CXXLiteralOperatorNames); 470 471 llvm::FoldingSetNodeID ID; 472 ID.AddPointer(II); 473 474 void *InsertPos = 0; 475 if (CXXLiteralOperatorIdName *Name = 476 LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) 477 return DeclarationName (Name); 478 479 CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName; 480 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; 481 LiteralName->ID = II; 482 483 LiteralNames->InsertNode(LiteralName, InsertPos); 484 return DeclarationName(LiteralName); 485} 486 487unsigned 488llvm::DenseMapInfo<clang::DeclarationName>:: 489getHashValue(clang::DeclarationName N) { 490 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr()); 491} 492 493