clang API Documentation
00001 //===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the DeclarationName and DeclarationNameTable 00011 // classes. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 #include "clang/AST/ASTContext.h" 00015 #include "clang/AST/Decl.h" 00016 #include "clang/AST/DeclarationName.h" 00017 #include "clang/AST/Type.h" 00018 #include "clang/AST/TypeLoc.h" 00019 #include "clang/AST/TypeOrdering.h" 00020 #include "clang/Basic/IdentifierTable.h" 00021 #include "llvm/ADT/DenseMap.h" 00022 #include "llvm/ADT/FoldingSet.h" 00023 #include "llvm/Support/ErrorHandling.h" 00024 #include "llvm/Support/raw_ostream.h" 00025 using namespace clang; 00026 00027 namespace clang { 00028 /// CXXSpecialName - Records the type associated with one of the 00029 /// "special" kinds of declaration names in C++, e.g., constructors, 00030 /// destructors, and conversion functions. 00031 class CXXSpecialName 00032 : public DeclarationNameExtra, public llvm::FoldingSetNode { 00033 public: 00034 /// Type - The type associated with this declaration name. 00035 QualType Type; 00036 00037 /// FETokenInfo - Extra information associated with this declaration 00038 /// name that can be used by the front end. 00039 void *FETokenInfo; 00040 00041 void Profile(llvm::FoldingSetNodeID &ID) { 00042 ID.AddInteger(ExtraKindOrNumArgs); 00043 ID.AddPointer(Type.getAsOpaquePtr()); 00044 } 00045 }; 00046 00047 /// CXXOperatorIdName - Contains extra information for the name of an 00048 /// overloaded operator in C++, such as "operator+. 00049 class CXXOperatorIdName : public DeclarationNameExtra { 00050 public: 00051 /// FETokenInfo - Extra information associated with this operator 00052 /// name that can be used by the front end. 00053 void *FETokenInfo; 00054 }; 00055 00056 /// CXXLiteralOperatorName - Contains the actual identifier that makes up the 00057 /// name. 00058 /// 00059 /// This identifier is stored here rather than directly in DeclarationName so as 00060 /// to allow Objective-C selectors, which are about a million times more common, 00061 /// to consume minimal memory. 00062 class CXXLiteralOperatorIdName 00063 : public DeclarationNameExtra, public llvm::FoldingSetNode { 00064 public: 00065 IdentifierInfo *ID; 00066 00067 /// FETokenInfo - Extra information associated with this operator 00068 /// name that can be used by the front end. 00069 void *FETokenInfo; 00070 00071 void Profile(llvm::FoldingSetNodeID &FSID) { 00072 FSID.AddPointer(ID); 00073 } 00074 }; 00075 00076 static int compareInt(unsigned A, unsigned B) { 00077 return (A < B ? -1 : (A > B ? 1 : 0)); 00078 } 00079 00080 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { 00081 if (LHS.getNameKind() != RHS.getNameKind()) 00082 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1); 00083 00084 switch (LHS.getNameKind()) { 00085 case DeclarationName::Identifier: { 00086 IdentifierInfo *LII = LHS.getAsIdentifierInfo(); 00087 IdentifierInfo *RII = RHS.getAsIdentifierInfo(); 00088 if (!LII) return RII ? -1 : 0; 00089 if (!RII) return 1; 00090 00091 return LII->getName().compare(RII->getName()); 00092 } 00093 00094 case DeclarationName::ObjCZeroArgSelector: 00095 case DeclarationName::ObjCOneArgSelector: 00096 case DeclarationName::ObjCMultiArgSelector: { 00097 Selector LHSSelector = LHS.getObjCSelector(); 00098 Selector RHSSelector = RHS.getObjCSelector(); 00099 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs(); 00100 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) { 00101 switch (LHSSelector.getNameForSlot(I).compare( 00102 RHSSelector.getNameForSlot(I))) { 00103 case -1: return true; 00104 case 1: return false; 00105 default: break; 00106 } 00107 } 00108 00109 return compareInt(LN, RN); 00110 } 00111 00112 case DeclarationName::CXXConstructorName: 00113 case DeclarationName::CXXDestructorName: 00114 case DeclarationName::CXXConversionFunctionName: 00115 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType())) 00116 return -1; 00117 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType())) 00118 return 1; 00119 return 0; 00120 00121 case DeclarationName::CXXOperatorName: 00122 return compareInt(LHS.getCXXOverloadedOperator(), 00123 RHS.getCXXOverloadedOperator()); 00124 00125 case DeclarationName::CXXLiteralOperatorName: 00126 return LHS.getCXXLiteralIdentifier()->getName().compare( 00127 RHS.getCXXLiteralIdentifier()->getName()); 00128 00129 case DeclarationName::CXXUsingDirective: 00130 return 0; 00131 } 00132 00133 llvm_unreachable("Invalid DeclarationName Kind!"); 00134 } 00135 00136 } // end namespace clang 00137 00138 DeclarationName::NameKind DeclarationName::getNameKind() const { 00139 switch (getStoredNameKind()) { 00140 case StoredIdentifier: return Identifier; 00141 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; 00142 case StoredObjCOneArgSelector: return ObjCOneArgSelector; 00143 00144 case StoredDeclarationNameExtra: 00145 switch (getExtra()->ExtraKindOrNumArgs) { 00146 case DeclarationNameExtra::CXXConstructor: 00147 return CXXConstructorName; 00148 00149 case DeclarationNameExtra::CXXDestructor: 00150 return CXXDestructorName; 00151 00152 case DeclarationNameExtra::CXXConversionFunction: 00153 return CXXConversionFunctionName; 00154 00155 case DeclarationNameExtra::CXXLiteralOperator: 00156 return CXXLiteralOperatorName; 00157 00158 case DeclarationNameExtra::CXXUsingDirective: 00159 return CXXUsingDirective; 00160 00161 default: 00162 // Check if we have one of the CXXOperator* enumeration values. 00163 if (getExtra()->ExtraKindOrNumArgs < 00164 DeclarationNameExtra::CXXUsingDirective) 00165 return CXXOperatorName; 00166 00167 return ObjCMultiArgSelector; 00168 } 00169 } 00170 00171 // Can't actually get here. 00172 llvm_unreachable("This should be unreachable!"); 00173 } 00174 00175 bool DeclarationName::isDependentName() const { 00176 QualType T = getCXXNameType(); 00177 return !T.isNull() && T->isDependentType(); 00178 } 00179 00180 std::string DeclarationName::getAsString() const { 00181 std::string Result; 00182 llvm::raw_string_ostream OS(Result); 00183 printName(OS); 00184 return OS.str(); 00185 } 00186 00187 void DeclarationName::printName(raw_ostream &OS) const { 00188 switch (getNameKind()) { 00189 case Identifier: 00190 if (const IdentifierInfo *II = getAsIdentifierInfo()) 00191 OS << II->getName(); 00192 return; 00193 00194 case ObjCZeroArgSelector: 00195 case ObjCOneArgSelector: 00196 case ObjCMultiArgSelector: 00197 OS << getObjCSelector().getAsString(); 00198 return; 00199 00200 case CXXConstructorName: { 00201 QualType ClassType = getCXXNameType(); 00202 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) 00203 OS << *ClassRec->getDecl(); 00204 else 00205 OS << ClassType.getAsString(); 00206 return; 00207 } 00208 00209 case CXXDestructorName: { 00210 OS << '~'; 00211 QualType Type = getCXXNameType(); 00212 if (const RecordType *Rec = Type->getAs<RecordType>()) 00213 OS << *Rec->getDecl(); 00214 else 00215 OS << Type.getAsString(); 00216 return; 00217 } 00218 00219 case CXXOperatorName: { 00220 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = { 00221 0, 00222 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 00223 Spelling, 00224 #include "clang/Basic/OperatorKinds.def" 00225 }; 00226 const char *OpName = OperatorNames[getCXXOverloadedOperator()]; 00227 assert(OpName && "not an overloaded operator"); 00228 00229 OS << "operator"; 00230 if (OpName[0] >= 'a' && OpName[0] <= 'z') 00231 OS << ' '; 00232 OS << OpName; 00233 return; 00234 } 00235 00236 case CXXLiteralOperatorName: 00237 OS << "operator \"\" " << getCXXLiteralIdentifier()->getName(); 00238 return; 00239 00240 case CXXConversionFunctionName: { 00241 OS << "operator "; 00242 QualType Type = getCXXNameType(); 00243 if (const RecordType *Rec = Type->getAs<RecordType>()) 00244 OS << *Rec->getDecl(); 00245 else 00246 OS << Type.getAsString(); 00247 return; 00248 } 00249 case CXXUsingDirective: 00250 OS << "<using-directive>"; 00251 return; 00252 } 00253 00254 llvm_unreachable("Unexpected declaration name kind"); 00255 } 00256 00257 QualType DeclarationName::getCXXNameType() const { 00258 if (CXXSpecialName *CXXName = getAsCXXSpecialName()) 00259 return CXXName->Type; 00260 else 00261 return QualType(); 00262 } 00263 00264 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { 00265 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { 00266 unsigned value 00267 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; 00268 return static_cast<OverloadedOperatorKind>(value); 00269 } else { 00270 return OO_None; 00271 } 00272 } 00273 00274 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const { 00275 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName()) 00276 return CXXLit->ID; 00277 else 00278 return 0; 00279 } 00280 00281 void *DeclarationName::getFETokenInfoAsVoidSlow() const { 00282 switch (getNameKind()) { 00283 case Identifier: 00284 llvm_unreachable("Handled by getFETokenInfo()"); 00285 00286 case CXXConstructorName: 00287 case CXXDestructorName: 00288 case CXXConversionFunctionName: 00289 return getAsCXXSpecialName()->FETokenInfo; 00290 00291 case CXXOperatorName: 00292 return getAsCXXOperatorIdName()->FETokenInfo; 00293 00294 case CXXLiteralOperatorName: 00295 return getAsCXXLiteralOperatorIdName()->FETokenInfo; 00296 00297 default: 00298 llvm_unreachable("Declaration name has no FETokenInfo"); 00299 } 00300 } 00301 00302 void DeclarationName::setFETokenInfo(void *T) { 00303 switch (getNameKind()) { 00304 case Identifier: 00305 getAsIdentifierInfo()->setFETokenInfo(T); 00306 break; 00307 00308 case CXXConstructorName: 00309 case CXXDestructorName: 00310 case CXXConversionFunctionName: 00311 getAsCXXSpecialName()->FETokenInfo = T; 00312 break; 00313 00314 case CXXOperatorName: 00315 getAsCXXOperatorIdName()->FETokenInfo = T; 00316 break; 00317 00318 case CXXLiteralOperatorName: 00319 getAsCXXLiteralOperatorIdName()->FETokenInfo = T; 00320 break; 00321 00322 default: 00323 llvm_unreachable("Declaration name has no FETokenInfo"); 00324 } 00325 } 00326 00327 DeclarationName DeclarationName::getUsingDirectiveName() { 00328 // Single instance of DeclarationNameExtra for using-directive 00329 static const DeclarationNameExtra UDirExtra = 00330 { DeclarationNameExtra::CXXUsingDirective }; 00331 00332 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); 00333 Ptr |= StoredDeclarationNameExtra; 00334 00335 return DeclarationName(Ptr); 00336 } 00337 00338 void DeclarationName::dump() const { 00339 printName(llvm::errs()); 00340 llvm::errs() << '\n'; 00341 } 00342 00343 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { 00344 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; 00345 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; 00346 00347 // Initialize the overloaded operator names. 00348 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; 00349 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { 00350 CXXOperatorNames[Op].ExtraKindOrNumArgs 00351 = Op + DeclarationNameExtra::CXXConversionFunction; 00352 CXXOperatorNames[Op].FETokenInfo = 0; 00353 } 00354 } 00355 00356 DeclarationNameTable::~DeclarationNameTable() { 00357 llvm::FoldingSet<CXXSpecialName> *SpecialNames = 00358 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 00359 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames 00360 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> 00361 (CXXLiteralOperatorNames); 00362 00363 delete SpecialNames; 00364 delete LiteralNames; 00365 } 00366 00367 DeclarationName 00368 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 00369 CanQualType Ty) { 00370 assert(Kind >= DeclarationName::CXXConstructorName && 00371 Kind <= DeclarationName::CXXConversionFunctionName && 00372 "Kind must be a C++ special name kind"); 00373 llvm::FoldingSet<CXXSpecialName> *SpecialNames 00374 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 00375 00376 DeclarationNameExtra::ExtraKind EKind; 00377 switch (Kind) { 00378 case DeclarationName::CXXConstructorName: 00379 EKind = DeclarationNameExtra::CXXConstructor; 00380 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); 00381 break; 00382 case DeclarationName::CXXDestructorName: 00383 EKind = DeclarationNameExtra::CXXDestructor; 00384 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); 00385 break; 00386 case DeclarationName::CXXConversionFunctionName: 00387 EKind = DeclarationNameExtra::CXXConversionFunction; 00388 break; 00389 default: 00390 return DeclarationName(); 00391 } 00392 00393 // Unique selector, to guarantee there is one per name. 00394 llvm::FoldingSetNodeID ID; 00395 ID.AddInteger(EKind); 00396 ID.AddPointer(Ty.getAsOpaquePtr()); 00397 00398 void *InsertPos = 0; 00399 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) 00400 return DeclarationName(Name); 00401 00402 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName; 00403 SpecialName->ExtraKindOrNumArgs = EKind; 00404 SpecialName->Type = Ty; 00405 SpecialName->FETokenInfo = 0; 00406 00407 SpecialNames->InsertNode(SpecialName, InsertPos); 00408 return DeclarationName(SpecialName); 00409 } 00410 00411 DeclarationName 00412 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { 00413 return DeclarationName(&CXXOperatorNames[(unsigned)Op]); 00414 } 00415 00416 DeclarationName 00417 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { 00418 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames 00419 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> 00420 (CXXLiteralOperatorNames); 00421 00422 llvm::FoldingSetNodeID ID; 00423 ID.AddPointer(II); 00424 00425 void *InsertPos = 0; 00426 if (CXXLiteralOperatorIdName *Name = 00427 LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) 00428 return DeclarationName (Name); 00429 00430 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName; 00431 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; 00432 LiteralName->ID = II; 00433 LiteralName->FETokenInfo = 0; 00434 00435 LiteralNames->InsertNode(LiteralName, InsertPos); 00436 return DeclarationName(LiteralName); 00437 } 00438 00439 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { 00440 switch (Name.getNameKind()) { 00441 case DeclarationName::Identifier: 00442 break; 00443 case DeclarationName::CXXConstructorName: 00444 case DeclarationName::CXXDestructorName: 00445 case DeclarationName::CXXConversionFunctionName: 00446 NamedType.TInfo = 0; 00447 break; 00448 case DeclarationName::CXXOperatorName: 00449 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); 00450 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); 00451 break; 00452 case DeclarationName::CXXLiteralOperatorName: 00453 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding(); 00454 break; 00455 case DeclarationName::ObjCZeroArgSelector: 00456 case DeclarationName::ObjCOneArgSelector: 00457 case DeclarationName::ObjCMultiArgSelector: 00458 // FIXME: ? 00459 break; 00460 case DeclarationName::CXXUsingDirective: 00461 break; 00462 } 00463 } 00464 00465 bool DeclarationNameInfo::containsUnexpandedParameterPack() const { 00466 switch (Name.getNameKind()) { 00467 case DeclarationName::Identifier: 00468 case DeclarationName::ObjCZeroArgSelector: 00469 case DeclarationName::ObjCOneArgSelector: 00470 case DeclarationName::ObjCMultiArgSelector: 00471 case DeclarationName::CXXOperatorName: 00472 case DeclarationName::CXXLiteralOperatorName: 00473 case DeclarationName::CXXUsingDirective: 00474 return false; 00475 00476 case DeclarationName::CXXConstructorName: 00477 case DeclarationName::CXXDestructorName: 00478 case DeclarationName::CXXConversionFunctionName: 00479 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 00480 return TInfo->getType()->containsUnexpandedParameterPack(); 00481 00482 return Name.getCXXNameType()->containsUnexpandedParameterPack(); 00483 } 00484 llvm_unreachable("All name kinds handled."); 00485 } 00486 00487 bool DeclarationNameInfo::isInstantiationDependent() const { 00488 switch (Name.getNameKind()) { 00489 case DeclarationName::Identifier: 00490 case DeclarationName::ObjCZeroArgSelector: 00491 case DeclarationName::ObjCOneArgSelector: 00492 case DeclarationName::ObjCMultiArgSelector: 00493 case DeclarationName::CXXOperatorName: 00494 case DeclarationName::CXXLiteralOperatorName: 00495 case DeclarationName::CXXUsingDirective: 00496 return false; 00497 00498 case DeclarationName::CXXConstructorName: 00499 case DeclarationName::CXXDestructorName: 00500 case DeclarationName::CXXConversionFunctionName: 00501 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 00502 return TInfo->getType()->isInstantiationDependentType(); 00503 00504 return Name.getCXXNameType()->isInstantiationDependentType(); 00505 } 00506 llvm_unreachable("All name kinds handled."); 00507 } 00508 00509 std::string DeclarationNameInfo::getAsString() const { 00510 std::string Result; 00511 llvm::raw_string_ostream OS(Result); 00512 printName(OS); 00513 return OS.str(); 00514 } 00515 00516 void DeclarationNameInfo::printName(raw_ostream &OS) const { 00517 switch (Name.getNameKind()) { 00518 case DeclarationName::Identifier: 00519 case DeclarationName::ObjCZeroArgSelector: 00520 case DeclarationName::ObjCOneArgSelector: 00521 case DeclarationName::ObjCMultiArgSelector: 00522 case DeclarationName::CXXOperatorName: 00523 case DeclarationName::CXXLiteralOperatorName: 00524 case DeclarationName::CXXUsingDirective: 00525 Name.printName(OS); 00526 return; 00527 00528 case DeclarationName::CXXConstructorName: 00529 case DeclarationName::CXXDestructorName: 00530 case DeclarationName::CXXConversionFunctionName: 00531 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) { 00532 if (Name.getNameKind() == DeclarationName::CXXDestructorName) 00533 OS << '~'; 00534 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) 00535 OS << "operator "; 00536 OS << TInfo->getType().getAsString(); 00537 } 00538 else 00539 Name.printName(OS); 00540 return; 00541 } 00542 llvm_unreachable("Unexpected declaration name kind"); 00543 } 00544 00545 SourceLocation DeclarationNameInfo::getEndLoc() const { 00546 switch (Name.getNameKind()) { 00547 case DeclarationName::Identifier: 00548 return NameLoc; 00549 00550 case DeclarationName::CXXOperatorName: { 00551 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc; 00552 return SourceLocation::getFromRawEncoding(raw); 00553 } 00554 00555 case DeclarationName::CXXLiteralOperatorName: { 00556 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc; 00557 return SourceLocation::getFromRawEncoding(raw); 00558 } 00559 00560 case DeclarationName::CXXConstructorName: 00561 case DeclarationName::CXXDestructorName: 00562 case DeclarationName::CXXConversionFunctionName: 00563 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 00564 return TInfo->getTypeLoc().getEndLoc(); 00565 else 00566 return NameLoc; 00567 00568 // DNInfo work in progress: FIXME. 00569 case DeclarationName::ObjCZeroArgSelector: 00570 case DeclarationName::ObjCOneArgSelector: 00571 case DeclarationName::ObjCMultiArgSelector: 00572 case DeclarationName::CXXUsingDirective: 00573 return NameLoc; 00574 } 00575 llvm_unreachable("Unexpected declaration name kind"); 00576 }