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 } // end namespace clang
    137 
    138 DeclarationName::NameKind DeclarationName::getNameKind() const {
    139   switch (getStoredNameKind()) {
    140   case StoredIdentifier:          return Identifier;
    141   case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
    142   case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
    143 
    144   case StoredDeclarationNameExtra:
    145     switch (getExtra()->ExtraKindOrNumArgs) {
    146     case DeclarationNameExtra::CXXConstructor:
    147       return CXXConstructorName;
    148 
    149     case DeclarationNameExtra::CXXDestructor:
    150       return CXXDestructorName;
    151 
    152     case DeclarationNameExtra::CXXConversionFunction:
    153       return CXXConversionFunctionName;
    154 
    155     case DeclarationNameExtra::CXXLiteralOperator:
    156       return CXXLiteralOperatorName;
    157 
    158     case DeclarationNameExtra::CXXUsingDirective:
    159       return CXXUsingDirective;
    160 
    161     default:
    162       // Check if we have one of the CXXOperator* enumeration values.
    163       if (getExtra()->ExtraKindOrNumArgs <
    164             DeclarationNameExtra::CXXUsingDirective)
    165         return CXXOperatorName;
    166 
    167       return ObjCMultiArgSelector;
    168     }
    169   }
    170 
    171   // Can't actually get here.
    172   llvm_unreachable("This should be unreachable!");
    173 }
    174 
    175 bool DeclarationName::isDependentName() const {
    176   QualType T = getCXXNameType();
    177   return !T.isNull() && T->isDependentType();
    178 }
    179 
    180 std::string DeclarationName::getAsString() const {
    181   std::string Result;
    182   llvm::raw_string_ostream OS(Result);
    183   printName(OS);
    184   return OS.str();
    185 }
    186 
    187 void DeclarationName::printName(raw_ostream &OS) const {
    188   switch (getNameKind()) {
    189   case Identifier:
    190     if (const IdentifierInfo *II = getAsIdentifierInfo())
    191       OS << II->getName();
    192     return;
    193 
    194   case ObjCZeroArgSelector:
    195   case ObjCOneArgSelector:
    196   case ObjCMultiArgSelector:
    197     OS << getObjCSelector().getAsString();
    198     return;
    199 
    200   case CXXConstructorName: {
    201     QualType ClassType = getCXXNameType();
    202     if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
    203       OS << *ClassRec->getDecl();
    204     else
    205       OS << ClassType.getAsString();
    206     return;
    207   }
    208 
    209   case CXXDestructorName: {
    210     OS << '~';
    211     QualType Type = getCXXNameType();
    212     if (const RecordType *Rec = Type->getAs<RecordType>())
    213       OS << *Rec->getDecl();
    214     else
    215       OS << Type.getAsString();
    216     return;
    217   }
    218 
    219   case CXXOperatorName: {
    220     static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
    221       0,
    222 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
    223       Spelling,
    224 #include "clang/Basic/OperatorKinds.def"
    225     };
    226     const char *OpName = OperatorNames[getCXXOverloadedOperator()];
    227     assert(OpName && "not an overloaded operator");
    228 
    229     OS << "operator";
    230     if (OpName[0] >= 'a' && OpName[0] <= 'z')
    231       OS << ' ';
    232     OS << OpName;
    233     return;
    234   }
    235 
    236   case CXXLiteralOperatorName:
    237     OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
    238     return;
    239 
    240   case CXXConversionFunctionName: {
    241     OS << "operator ";
    242     QualType Type = getCXXNameType();
    243     if (const RecordType *Rec = Type->getAs<RecordType>())
    244       OS << *Rec->getDecl();
    245     else
    246       OS << Type.getAsString();
    247     return;
    248   }
    249   case CXXUsingDirective:
    250     OS << "<using-directive>";
    251     return;
    252   }
    253 
    254   llvm_unreachable("Unexpected declaration name kind");
    255 }
    256 
    257 QualType DeclarationName::getCXXNameType() const {
    258   if (CXXSpecialName *CXXName = getAsCXXSpecialName())
    259     return CXXName->Type;
    260   else
    261     return QualType();
    262 }
    263 
    264 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
    265   if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
    266     unsigned value
    267       = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
    268     return static_cast<OverloadedOperatorKind>(value);
    269   } else {
    270     return OO_None;
    271   }
    272 }
    273 
    274 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
    275   if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
    276     return CXXLit->ID;
    277   else
    278     return 0;
    279 }
    280 
    281 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
    282   switch (getNameKind()) {
    283   case Identifier:
    284     llvm_unreachable("Handled by getFETokenInfo()");
    285 
    286   case CXXConstructorName:
    287   case CXXDestructorName:
    288   case CXXConversionFunctionName:
    289     return getAsCXXSpecialName()->FETokenInfo;
    290 
    291   case CXXOperatorName:
    292     return getAsCXXOperatorIdName()->FETokenInfo;
    293 
    294   case CXXLiteralOperatorName:
    295     return getAsCXXLiteralOperatorIdName()->FETokenInfo;
    296 
    297   default:
    298     llvm_unreachable("Declaration name has no FETokenInfo");
    299   }
    300 }
    301 
    302 void DeclarationName::setFETokenInfo(void *T) {
    303   switch (getNameKind()) {
    304   case Identifier:
    305     getAsIdentifierInfo()->setFETokenInfo(T);
    306     break;
    307 
    308   case CXXConstructorName:
    309   case CXXDestructorName:
    310   case CXXConversionFunctionName:
    311     getAsCXXSpecialName()->FETokenInfo = T;
    312     break;
    313 
    314   case CXXOperatorName:
    315     getAsCXXOperatorIdName()->FETokenInfo = T;
    316     break;
    317 
    318   case CXXLiteralOperatorName:
    319     getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
    320     break;
    321 
    322   default:
    323     llvm_unreachable("Declaration name has no FETokenInfo");
    324   }
    325 }
    326 
    327 DeclarationName DeclarationName::getUsingDirectiveName() {
    328   // Single instance of DeclarationNameExtra for using-directive
    329   static const DeclarationNameExtra UDirExtra =
    330     { DeclarationNameExtra::CXXUsingDirective };
    331 
    332   uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
    333   Ptr |= StoredDeclarationNameExtra;
    334 
    335   return DeclarationName(Ptr);
    336 }
    337 
    338 void DeclarationName::dump() const {
    339   printName(llvm::errs());
    340   llvm::errs() << '\n';
    341 }
    342 
    343 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
    344   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
    345   CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
    346 
    347   // Initialize the overloaded operator names.
    348   CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
    349   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
    350     CXXOperatorNames[Op].ExtraKindOrNumArgs
    351       = Op + DeclarationNameExtra::CXXConversionFunction;
    352     CXXOperatorNames[Op].FETokenInfo = 0;
    353   }
    354 }
    355 
    356 DeclarationNameTable::~DeclarationNameTable() {
    357   llvm::FoldingSet<CXXSpecialName> *SpecialNames =
    358     static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
    359   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
    360     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
    361         (CXXLiteralOperatorNames);
    362 
    363   delete SpecialNames;
    364   delete LiteralNames;
    365 }
    366 
    367 DeclarationName
    368 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
    369                                         CanQualType Ty) {
    370   assert(Kind >= DeclarationName::CXXConstructorName &&
    371          Kind <= DeclarationName::CXXConversionFunctionName &&
    372          "Kind must be a C++ special name kind");
    373   llvm::FoldingSet<CXXSpecialName> *SpecialNames
    374     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
    375 
    376   DeclarationNameExtra::ExtraKind EKind;
    377   switch (Kind) {
    378   case DeclarationName::CXXConstructorName:
    379     EKind = DeclarationNameExtra::CXXConstructor;
    380     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
    381     break;
    382   case DeclarationName::CXXDestructorName:
    383     EKind = DeclarationNameExtra::CXXDestructor;
    384     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
    385     break;
    386   case DeclarationName::CXXConversionFunctionName:
    387     EKind = DeclarationNameExtra::CXXConversionFunction;
    388     break;
    389   default:
    390     return DeclarationName();
    391   }
    392 
    393   // Unique selector, to guarantee there is one per name.
    394   llvm::FoldingSetNodeID ID;
    395   ID.AddInteger(EKind);
    396   ID.AddPointer(Ty.getAsOpaquePtr());
    397 
    398   void *InsertPos = 0;
    399   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
    400     return DeclarationName(Name);
    401 
    402   CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
    403   SpecialName->ExtraKindOrNumArgs = EKind;
    404   SpecialName->Type = Ty;
    405   SpecialName->FETokenInfo = 0;
    406 
    407   SpecialNames->InsertNode(SpecialName, InsertPos);
    408   return DeclarationName(SpecialName);
    409 }
    410 
    411 DeclarationName
    412 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
    413   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
    414 }
    415 
    416 DeclarationName
    417 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
    418   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
    419     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
    420                                                       (CXXLiteralOperatorNames);
    421 
    422   llvm::FoldingSetNodeID ID;
    423   ID.AddPointer(II);
    424 
    425   void *InsertPos = 0;
    426   if (CXXLiteralOperatorIdName *Name =
    427                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
    428     return DeclarationName (Name);
    429 
    430   CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
    431   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
    432   LiteralName->ID = II;
    433   LiteralName->FETokenInfo = 0;
    434 
    435   LiteralNames->InsertNode(LiteralName, InsertPos);
    436   return DeclarationName(LiteralName);
    437 }
    438 
    439 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
    440   switch (Name.getNameKind()) {
    441   case DeclarationName::Identifier:
    442     break;
    443   case DeclarationName::CXXConstructorName:
    444   case DeclarationName::CXXDestructorName:
    445   case DeclarationName::CXXConversionFunctionName:
    446     NamedType.TInfo = 0;
    447     break;
    448   case DeclarationName::CXXOperatorName:
    449     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
    450     CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
    451     break;
    452   case DeclarationName::CXXLiteralOperatorName:
    453     CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
    454     break;
    455   case DeclarationName::ObjCZeroArgSelector:
    456   case DeclarationName::ObjCOneArgSelector:
    457   case DeclarationName::ObjCMultiArgSelector:
    458     // FIXME: ?
    459     break;
    460   case DeclarationName::CXXUsingDirective:
    461     break;
    462   }
    463 }
    464 
    465 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
    466   switch (Name.getNameKind()) {
    467   case DeclarationName::Identifier:
    468   case DeclarationName::ObjCZeroArgSelector:
    469   case DeclarationName::ObjCOneArgSelector:
    470   case DeclarationName::ObjCMultiArgSelector:
    471   case DeclarationName::CXXOperatorName:
    472   case DeclarationName::CXXLiteralOperatorName:
    473   case DeclarationName::CXXUsingDirective:
    474     return false;
    475 
    476   case DeclarationName::CXXConstructorName:
    477   case DeclarationName::CXXDestructorName:
    478   case DeclarationName::CXXConversionFunctionName:
    479     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
    480       return TInfo->getType()->containsUnexpandedParameterPack();
    481 
    482     return Name.getCXXNameType()->containsUnexpandedParameterPack();
    483   }
    484   llvm_unreachable("All name kinds handled.");
    485 }
    486 
    487 bool DeclarationNameInfo::isInstantiationDependent() const {
    488   switch (Name.getNameKind()) {
    489   case DeclarationName::Identifier:
    490   case DeclarationName::ObjCZeroArgSelector:
    491   case DeclarationName::ObjCOneArgSelector:
    492   case DeclarationName::ObjCMultiArgSelector:
    493   case DeclarationName::CXXOperatorName:
    494   case DeclarationName::CXXLiteralOperatorName:
    495   case DeclarationName::CXXUsingDirective:
    496     return false;
    497 
    498   case DeclarationName::CXXConstructorName:
    499   case DeclarationName::CXXDestructorName:
    500   case DeclarationName::CXXConversionFunctionName:
    501     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
    502       return TInfo->getType()->isInstantiationDependentType();
    503 
    504     return Name.getCXXNameType()->isInstantiationDependentType();
    505   }
    506   llvm_unreachable("All name kinds handled.");
    507 }
    508 
    509 std::string DeclarationNameInfo::getAsString() const {
    510   std::string Result;
    511   llvm::raw_string_ostream OS(Result);
    512   printName(OS);
    513   return OS.str();
    514 }
    515 
    516 void DeclarationNameInfo::printName(raw_ostream &OS) const {
    517   switch (Name.getNameKind()) {
    518   case DeclarationName::Identifier:
    519   case DeclarationName::ObjCZeroArgSelector:
    520   case DeclarationName::ObjCOneArgSelector:
    521   case DeclarationName::ObjCMultiArgSelector:
    522   case DeclarationName::CXXOperatorName:
    523   case DeclarationName::CXXLiteralOperatorName:
    524   case DeclarationName::CXXUsingDirective:
    525     Name.printName(OS);
    526     return;
    527 
    528   case DeclarationName::CXXConstructorName:
    529   case DeclarationName::CXXDestructorName:
    530   case DeclarationName::CXXConversionFunctionName:
    531     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
    532       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
    533         OS << '~';
    534       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
    535         OS << "operator ";
    536       OS << TInfo->getType().getAsString();
    537     }
    538     else
    539       Name.printName(OS);
    540     return;
    541   }
    542   llvm_unreachable("Unexpected declaration name kind");
    543 }
    544 
    545 SourceLocation DeclarationNameInfo::getEndLoc() const {
    546   switch (Name.getNameKind()) {
    547   case DeclarationName::Identifier:
    548     return NameLoc;
    549 
    550   case DeclarationName::CXXOperatorName: {
    551     unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
    552     return SourceLocation::getFromRawEncoding(raw);
    553   }
    554 
    555   case DeclarationName::CXXLiteralOperatorName: {
    556     unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
    557     return SourceLocation::getFromRawEncoding(raw);
    558   }
    559 
    560   case DeclarationName::CXXConstructorName:
    561   case DeclarationName::CXXDestructorName:
    562   case DeclarationName::CXXConversionFunctionName:
    563     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
    564       return TInfo->getTypeLoc().getEndLoc();
    565     else
    566       return NameLoc;
    567 
    568     // DNInfo work in progress: FIXME.
    569   case DeclarationName::ObjCZeroArgSelector:
    570   case DeclarationName::ObjCOneArgSelector:
    571   case DeclarationName::ObjCMultiArgSelector:
    572   case DeclarationName::CXXUsingDirective:
    573     return NameLoc;
    574   }
    575   llvm_unreachable("Unexpected declaration name kind");
    576 }
    577