DeclarationName.cpp revision 200583
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 : public DeclarationNameExtra { 60public: 61 IdentifierInfo *ID; 62}; 63 64bool operator<(DeclarationName LHS, DeclarationName RHS) { 65 if (LHS.getNameKind() != RHS.getNameKind()) 66 return LHS.getNameKind() < RHS.getNameKind(); 67 68 switch (LHS.getNameKind()) { 69 case DeclarationName::Identifier: 70 return LHS.getAsIdentifierInfo()->getName() < 71 RHS.getAsIdentifierInfo()->getName(); 72 73 case DeclarationName::ObjCZeroArgSelector: 74 case DeclarationName::ObjCOneArgSelector: 75 case DeclarationName::ObjCMultiArgSelector: { 76 Selector LHSSelector = LHS.getObjCSelector(); 77 Selector RHSSelector = RHS.getObjCSelector(); 78 for (unsigned I = 0, 79 N = std::min(LHSSelector.getNumArgs(), RHSSelector.getNumArgs()); 80 I != N; ++I) { 81 IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I); 82 IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I); 83 if (!LHSId || !RHSId) 84 return LHSId && !RHSId; 85 86 switch (LHSId->getName().compare(RHSId->getName())) { 87 case -1: return true; 88 case 1: return false; 89 default: break; 90 } 91 } 92 93 return LHSSelector.getNumArgs() < RHSSelector.getNumArgs(); 94 } 95 96 case DeclarationName::CXXConstructorName: 97 case DeclarationName::CXXDestructorName: 98 case DeclarationName::CXXConversionFunctionName: 99 return QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()); 100 101 case DeclarationName::CXXOperatorName: 102 return LHS.getCXXOverloadedOperator() < RHS.getCXXOverloadedOperator(); 103 104 case DeclarationName::CXXLiteralOperatorName: 105 return LHS.getCXXLiteralIdentifier()->getName() < 106 RHS.getCXXLiteralIdentifier()->getName(); 107 108 case DeclarationName::CXXUsingDirective: 109 return false; 110 } 111 112 return false; 113} 114 115} // end namespace clang 116 117DeclarationName::DeclarationName(Selector Sel) { 118 if (!Sel.getAsOpaquePtr()) { 119 Ptr = 0; 120 return; 121 } 122 123 switch (Sel.getNumArgs()) { 124 case 0: 125 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); 126 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); 127 Ptr |= StoredObjCZeroArgSelector; 128 break; 129 130 case 1: 131 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); 132 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); 133 Ptr |= StoredObjCOneArgSelector; 134 break; 135 136 default: 137 Ptr = Sel.InfoPtr & ~Selector::ArgFlags; 138 assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector"); 139 Ptr |= StoredDeclarationNameExtra; 140 break; 141 } 142} 143 144DeclarationName::NameKind DeclarationName::getNameKind() const { 145 switch (getStoredNameKind()) { 146 case StoredIdentifier: return Identifier; 147 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; 148 case StoredObjCOneArgSelector: return ObjCOneArgSelector; 149 150 case StoredDeclarationNameExtra: 151 switch (getExtra()->ExtraKindOrNumArgs) { 152 case DeclarationNameExtra::CXXConstructor: 153 return CXXConstructorName; 154 155 case DeclarationNameExtra::CXXDestructor: 156 return CXXDestructorName; 157 158 case DeclarationNameExtra::CXXConversionFunction: 159 return CXXConversionFunctionName; 160 161 case DeclarationNameExtra::CXXLiteralOperator: 162 return CXXLiteralOperatorName; 163 164 case DeclarationNameExtra::CXXUsingDirective: 165 return CXXUsingDirective; 166 167 default: 168 // Check if we have one of the CXXOperator* enumeration values. 169 if (getExtra()->ExtraKindOrNumArgs < 170 DeclarationNameExtra::CXXUsingDirective) 171 return CXXOperatorName; 172 173 return ObjCMultiArgSelector; 174 } 175 break; 176 } 177 178 // Can't actually get here. 179 assert(0 && "This should be unreachable!"); 180 return Identifier; 181} 182 183std::string DeclarationName::getAsString() const { 184 switch (getNameKind()) { 185 case Identifier: 186 if (const IdentifierInfo *II = getAsIdentifierInfo()) 187 return II->getName(); 188 return ""; 189 190 case ObjCZeroArgSelector: 191 case ObjCOneArgSelector: 192 case ObjCMultiArgSelector: 193 return getObjCSelector().getAsString(); 194 195 case CXXConstructorName: { 196 QualType ClassType = getCXXNameType(); 197 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) 198 return ClassRec->getDecl()->getNameAsString(); 199 return ClassType.getAsString(); 200 } 201 202 case CXXDestructorName: { 203 std::string Result = "~"; 204 QualType Type = getCXXNameType(); 205 if (const RecordType *Rec = Type->getAs<RecordType>()) 206 Result += Rec->getDecl()->getNameAsString(); 207 else 208 Result += Type.getAsString(); 209 return Result; 210 } 211 212 case CXXOperatorName: { 213 static const char *OperatorNames[NUM_OVERLOADED_OPERATORS] = { 214 0, 215#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 216 Spelling, 217#include "clang/Basic/OperatorKinds.def" 218 }; 219 const char *OpName = OperatorNames[getCXXOverloadedOperator()]; 220 assert(OpName && "not an overloaded operator"); 221 222 std::string Result = "operator"; 223 if (OpName[0] >= 'a' && OpName[0] <= 'z') 224 Result += ' '; 225 Result += OpName; 226 return Result; 227 } 228 229 case CXXLiteralOperatorName: { 230 return "operator \"\" " + std::string(getCXXLiteralIdentifier()->getName()); 231 } 232 233 case CXXConversionFunctionName: { 234 std::string Result = "operator "; 235 QualType Type = getCXXNameType(); 236 if (const RecordType *Rec = Type->getAs<RecordType>()) 237 Result += Rec->getDecl()->getNameAsString(); 238 else 239 Result += Type.getAsString(); 240 return Result; 241 } 242 case CXXUsingDirective: 243 return "<using-directive>"; 244 } 245 246 assert(false && "Unexpected declaration name kind"); 247 return ""; 248} 249 250QualType DeclarationName::getCXXNameType() const { 251 if (CXXSpecialName *CXXName = getAsCXXSpecialName()) 252 return CXXName->Type; 253 else 254 return QualType(); 255} 256 257OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { 258 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { 259 unsigned value 260 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; 261 return static_cast<OverloadedOperatorKind>(value); 262 } else { 263 return OO_None; 264 } 265} 266 267IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const { 268 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName()) 269 return CXXLit->ID; 270 else 271 return 0; 272} 273 274Selector DeclarationName::getObjCSelector() const { 275 switch (getNameKind()) { 276 case ObjCZeroArgSelector: 277 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0); 278 279 case ObjCOneArgSelector: 280 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1); 281 282 case ObjCMultiArgSelector: 283 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask)); 284 285 default: 286 break; 287 } 288 289 return Selector(); 290} 291 292void *DeclarationName::getFETokenInfoAsVoid() const { 293 switch (getNameKind()) { 294 case Identifier: 295 return getAsIdentifierInfo()->getFETokenInfo<void>(); 296 297 case CXXConstructorName: 298 case CXXDestructorName: 299 case CXXConversionFunctionName: 300 return getAsCXXSpecialName()->FETokenInfo; 301 302 case CXXOperatorName: 303 return getAsCXXOperatorIdName()->FETokenInfo; 304 305 case CXXLiteralOperatorName: 306 return getCXXLiteralIdentifier()->getFETokenInfo<void>(); 307 308 default: 309 assert(false && "Declaration name has no FETokenInfo"); 310 } 311 return 0; 312} 313 314void DeclarationName::setFETokenInfo(void *T) { 315 switch (getNameKind()) { 316 case Identifier: 317 getAsIdentifierInfo()->setFETokenInfo(T); 318 break; 319 320 case CXXConstructorName: 321 case CXXDestructorName: 322 case CXXConversionFunctionName: 323 getAsCXXSpecialName()->FETokenInfo = T; 324 break; 325 326 case CXXOperatorName: 327 getAsCXXOperatorIdName()->FETokenInfo = T; 328 break; 329 330 case CXXLiteralOperatorName: 331 getCXXLiteralIdentifier()->setFETokenInfo(T); 332 break; 333 334 default: 335 assert(false && "Declaration name has no FETokenInfo"); 336 } 337} 338 339DeclarationName DeclarationName::getUsingDirectiveName() { 340 // Single instance of DeclarationNameExtra for using-directive 341 static const DeclarationNameExtra UDirExtra = 342 { DeclarationNameExtra::CXXUsingDirective }; 343 344 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); 345 Ptr |= StoredDeclarationNameExtra; 346 347 return DeclarationName(Ptr); 348} 349 350void DeclarationName::dump() const { 351 fprintf(stderr, "%s\n", getAsString().c_str()); 352} 353 354DeclarationNameTable::DeclarationNameTable() { 355 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; 356 357 // Initialize the overloaded operator names. 358 CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; 359 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { 360 CXXOperatorNames[Op].ExtraKindOrNumArgs 361 = Op + DeclarationNameExtra::CXXConversionFunction; 362 CXXOperatorNames[Op].FETokenInfo = 0; 363 } 364} 365 366DeclarationNameTable::~DeclarationNameTable() { 367 llvm::FoldingSet<CXXSpecialName> *set = 368 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 369 llvm::FoldingSetIterator<CXXSpecialName> I = set->begin(), E = set->end(); 370 371 while (I != E) { 372 CXXSpecialName *n = &*I++; 373 delete n; 374 } 375 376 delete set; 377 delete [] CXXOperatorNames; 378} 379 380DeclarationName 381DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 382 CanQualType Ty) { 383 assert(Kind >= DeclarationName::CXXConstructorName && 384 Kind <= DeclarationName::CXXConversionFunctionName && 385 "Kind must be a C++ special name kind"); 386 llvm::FoldingSet<CXXSpecialName> *SpecialNames 387 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 388 389 DeclarationNameExtra::ExtraKind EKind; 390 switch (Kind) { 391 case DeclarationName::CXXConstructorName: 392 EKind = DeclarationNameExtra::CXXConstructor; 393 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); 394 break; 395 case DeclarationName::CXXDestructorName: 396 EKind = DeclarationNameExtra::CXXDestructor; 397 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); 398 break; 399 case DeclarationName::CXXConversionFunctionName: 400 EKind = DeclarationNameExtra::CXXConversionFunction; 401 break; 402 default: 403 return DeclarationName(); 404 } 405 406 // Unique selector, to guarantee there is one per name. 407 llvm::FoldingSetNodeID ID; 408 ID.AddInteger(EKind); 409 ID.AddPointer(Ty.getAsOpaquePtr()); 410 411 void *InsertPos = 0; 412 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) 413 return DeclarationName(Name); 414 415 CXXSpecialName *SpecialName = new CXXSpecialName; 416 SpecialName->ExtraKindOrNumArgs = EKind; 417 SpecialName->Type = Ty; 418 SpecialName->FETokenInfo = 0; 419 420 SpecialNames->InsertNode(SpecialName, InsertPos); 421 return DeclarationName(SpecialName); 422} 423 424DeclarationName 425DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { 426 return DeclarationName(&CXXOperatorNames[(unsigned)Op]); 427} 428 429DeclarationName 430DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { 431 CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName; 432 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; 433 LiteralName->ID = II; 434 return DeclarationName(LiteralName); 435} 436 437unsigned 438llvm::DenseMapInfo<clang::DeclarationName>:: 439getHashValue(clang::DeclarationName N) { 440 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr()); 441} 442 443