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