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 DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
    368   return getCXXSpecialName(DeclarationName::CXXConstructorName,
    369                            Ty.getUnqualifiedType());
    370 }
    371 
    372 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
    373   return getCXXSpecialName(DeclarationName::CXXDestructorName,
    374                            Ty.getUnqualifiedType());
    375 }
    376 
    377 DeclarationName
    378 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
    379   return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
    380 }
    381 
    382 DeclarationName
    383 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
    384                                         CanQualType Ty) {
    385   assert(Kind >= DeclarationName::CXXConstructorName &&
    386          Kind <= DeclarationName::CXXConversionFunctionName &&
    387          "Kind must be a C++ special name kind");
    388   llvm::FoldingSet<CXXSpecialName> *SpecialNames
    389     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
    390 
    391   DeclarationNameExtra::ExtraKind EKind;
    392   switch (Kind) {
    393   case DeclarationName::CXXConstructorName:
    394     EKind = DeclarationNameExtra::CXXConstructor;
    395     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
    396     break;
    397   case DeclarationName::CXXDestructorName:
    398     EKind = DeclarationNameExtra::CXXDestructor;
    399     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
    400     break;
    401   case DeclarationName::CXXConversionFunctionName:
    402     EKind = DeclarationNameExtra::CXXConversionFunction;
    403     break;
    404   default:
    405     return DeclarationName();
    406   }
    407 
    408   // Unique selector, to guarantee there is one per name.
    409   llvm::FoldingSetNodeID ID;
    410   ID.AddInteger(EKind);
    411   ID.AddPointer(Ty.getAsOpaquePtr());
    412 
    413   void *InsertPos = 0;
    414   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
    415     return DeclarationName(Name);
    416 
    417   CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
    418   SpecialName->ExtraKindOrNumArgs = EKind;
    419   SpecialName->Type = Ty;
    420   SpecialName->FETokenInfo = 0;
    421 
    422   SpecialNames->InsertNode(SpecialName, InsertPos);
    423   return DeclarationName(SpecialName);
    424 }
    425 
    426 DeclarationName
    427 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
    428   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
    429 }
    430 
    431 DeclarationName
    432 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
    433   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
    434     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
    435                                                       (CXXLiteralOperatorNames);
    436 
    437   llvm::FoldingSetNodeID ID;
    438   ID.AddPointer(II);
    439 
    440   void *InsertPos = 0;
    441   if (CXXLiteralOperatorIdName *Name =
    442                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
    443     return DeclarationName (Name);
    444 
    445   CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
    446   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
    447   LiteralName->ID = II;
    448   LiteralName->FETokenInfo = 0;
    449 
    450   LiteralNames->InsertNode(LiteralName, InsertPos);
    451   return DeclarationName(LiteralName);
    452 }
    453 
    454 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
    455   switch (Name.getNameKind()) {
    456   case DeclarationName::Identifier:
    457     break;
    458   case DeclarationName::CXXConstructorName:
    459   case DeclarationName::CXXDestructorName:
    460   case DeclarationName::CXXConversionFunctionName:
    461     NamedType.TInfo = 0;
    462     break;
    463   case DeclarationName::CXXOperatorName:
    464     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
    465     CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
    466     break;
    467   case DeclarationName::CXXLiteralOperatorName:
    468     CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
    469     break;
    470   case DeclarationName::ObjCZeroArgSelector:
    471   case DeclarationName::ObjCOneArgSelector:
    472   case DeclarationName::ObjCMultiArgSelector:
    473     // FIXME: ?
    474     break;
    475   case DeclarationName::CXXUsingDirective:
    476     break;
    477   }
    478 }
    479 
    480 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
    481   switch (Name.getNameKind()) {
    482   case DeclarationName::Identifier:
    483   case DeclarationName::ObjCZeroArgSelector:
    484   case DeclarationName::ObjCOneArgSelector:
    485   case DeclarationName::ObjCMultiArgSelector:
    486   case DeclarationName::CXXOperatorName:
    487   case DeclarationName::CXXLiteralOperatorName:
    488   case DeclarationName::CXXUsingDirective:
    489     return false;
    490 
    491   case DeclarationName::CXXConstructorName:
    492   case DeclarationName::CXXDestructorName:
    493   case DeclarationName::CXXConversionFunctionName:
    494     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
    495       return TInfo->getType()->containsUnexpandedParameterPack();
    496 
    497     return Name.getCXXNameType()->containsUnexpandedParameterPack();
    498   }
    499   llvm_unreachable("All name kinds handled.");
    500 }
    501 
    502 bool DeclarationNameInfo::isInstantiationDependent() const {
    503   switch (Name.getNameKind()) {
    504   case DeclarationName::Identifier:
    505   case DeclarationName::ObjCZeroArgSelector:
    506   case DeclarationName::ObjCOneArgSelector:
    507   case DeclarationName::ObjCMultiArgSelector:
    508   case DeclarationName::CXXOperatorName:
    509   case DeclarationName::CXXLiteralOperatorName:
    510   case DeclarationName::CXXUsingDirective:
    511     return false;
    512 
    513   case DeclarationName::CXXConstructorName:
    514   case DeclarationName::CXXDestructorName:
    515   case DeclarationName::CXXConversionFunctionName:
    516     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
    517       return TInfo->getType()->isInstantiationDependentType();
    518 
    519     return Name.getCXXNameType()->isInstantiationDependentType();
    520   }
    521   llvm_unreachable("All name kinds handled.");
    522 }
    523 
    524 std::string DeclarationNameInfo::getAsString() const {
    525   std::string Result;
    526   llvm::raw_string_ostream OS(Result);
    527   printName(OS);
    528   return OS.str();
    529 }
    530 
    531 void DeclarationNameInfo::printName(raw_ostream &OS) const {
    532   switch (Name.getNameKind()) {
    533   case DeclarationName::Identifier:
    534   case DeclarationName::ObjCZeroArgSelector:
    535   case DeclarationName::ObjCOneArgSelector:
    536   case DeclarationName::ObjCMultiArgSelector:
    537   case DeclarationName::CXXOperatorName:
    538   case DeclarationName::CXXLiteralOperatorName:
    539   case DeclarationName::CXXUsingDirective:
    540     Name.printName(OS);
    541     return;
    542 
    543   case DeclarationName::CXXConstructorName:
    544   case DeclarationName::CXXDestructorName:
    545   case DeclarationName::CXXConversionFunctionName:
    546     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
    547       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
    548         OS << '~';
    549       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
    550         OS << "operator ";
    551       OS << TInfo->getType().getAsString();
    552     }
    553     else
    554       Name.printName(OS);
    555     return;
    556   }
    557   llvm_unreachable("Unexpected declaration name kind");
    558 }
    559 
    560 SourceLocation DeclarationNameInfo::getEndLoc() const {
    561   switch (Name.getNameKind()) {
    562   case DeclarationName::Identifier:
    563     return NameLoc;
    564 
    565   case DeclarationName::CXXOperatorName: {
    566     unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
    567     return SourceLocation::getFromRawEncoding(raw);
    568   }
    569 
    570   case DeclarationName::CXXLiteralOperatorName: {
    571     unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
    572     return SourceLocation::getFromRawEncoding(raw);
    573   }
    574 
    575   case DeclarationName::CXXConstructorName:
    576   case DeclarationName::CXXDestructorName:
    577   case DeclarationName::CXXConversionFunctionName:
    578     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
    579       return TInfo->getTypeLoc().getEndLoc();
    580     else
    581       return NameLoc;
    582 
    583     // DNInfo work in progress: FIXME.
    584   case DeclarationName::ObjCZeroArgSelector:
    585   case DeclarationName::ObjCOneArgSelector:
    586   case DeclarationName::ObjCMultiArgSelector:
    587   case DeclarationName::CXXUsingDirective:
    588     return NameLoc;
    589   }
    590   llvm_unreachable("Unexpected declaration name kind");
    591 }
    592