clang API Documentation

DeclarationName.cpp
Go to the documentation of this file.
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 }