Home | History | Annotate | Line # | Download | only in AST
      1 //===- DeclarationName.cpp - Declaration names implementation -------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file implements the DeclarationName and DeclarationNameTable
     10 // classes.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "clang/AST/DeclarationName.h"
     15 #include "clang/AST/ASTContext.h"
     16 #include "clang/AST/Decl.h"
     17 #include "clang/AST/DeclBase.h"
     18 #include "clang/AST/DeclCXX.h"
     19 #include "clang/AST/DeclTemplate.h"
     20 #include "clang/AST/OpenMPClause.h"
     21 #include "clang/AST/PrettyPrinter.h"
     22 #include "clang/AST/Type.h"
     23 #include "clang/AST/TypeLoc.h"
     24 #include "clang/AST/TypeOrdering.h"
     25 #include "clang/Basic/IdentifierTable.h"
     26 #include "clang/Basic/LLVM.h"
     27 #include "clang/Basic/LangOptions.h"
     28 #include "clang/Basic/OperatorKinds.h"
     29 #include "clang/Basic/SourceLocation.h"
     30 #include "llvm/ADT/FoldingSet.h"
     31 #include "llvm/Support/Casting.h"
     32 #include "llvm/Support/Compiler.h"
     33 #include "llvm/Support/ErrorHandling.h"
     34 #include "llvm/Support/raw_ostream.h"
     35 #include <algorithm>
     36 #include <cassert>
     37 #include <cstdint>
     38 #include <string>
     39 
     40 using namespace clang;
     41 
     42 static int compareInt(unsigned A, unsigned B) {
     43   return (A < B ? -1 : (A > B ? 1 : 0));
     44 }
     45 
     46 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
     47   if (LHS.getNameKind() != RHS.getNameKind())
     48     return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
     49 
     50   switch (LHS.getNameKind()) {
     51   case DeclarationName::Identifier: {
     52     IdentifierInfo *LII = LHS.castAsIdentifierInfo();
     53     IdentifierInfo *RII = RHS.castAsIdentifierInfo();
     54     if (!LII)
     55       return RII ? -1 : 0;
     56     if (!RII)
     57       return 1;
     58 
     59     return LII->getName().compare(RII->getName());
     60   }
     61 
     62   case DeclarationName::ObjCZeroArgSelector:
     63   case DeclarationName::ObjCOneArgSelector:
     64   case DeclarationName::ObjCMultiArgSelector: {
     65     Selector LHSSelector = LHS.getObjCSelector();
     66     Selector RHSSelector = RHS.getObjCSelector();
     67     // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
     68     if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
     69         RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
     70       return LHSSelector.getAsIdentifierInfo()->getName().compare(
     71           RHSSelector.getAsIdentifierInfo()->getName());
     72     }
     73     unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
     74     for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
     75       switch (LHSSelector.getNameForSlot(I).compare(
     76           RHSSelector.getNameForSlot(I))) {
     77       case -1:
     78         return -1;
     79       case 1:
     80         return 1;
     81       default:
     82         break;
     83       }
     84     }
     85 
     86     return compareInt(LN, RN);
     87   }
     88 
     89   case DeclarationName::CXXConstructorName:
     90   case DeclarationName::CXXDestructorName:
     91   case DeclarationName::CXXConversionFunctionName:
     92     if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
     93       return -1;
     94     if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
     95       return 1;
     96     return 0;
     97 
     98   case DeclarationName::CXXDeductionGuideName:
     99     // We never want to compare deduction guide names for templates from
    100     // different scopes, so just compare the template-name.
    101     return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
    102                    RHS.getCXXDeductionGuideTemplate()->getDeclName());
    103 
    104   case DeclarationName::CXXOperatorName:
    105     return compareInt(LHS.getCXXOverloadedOperator(),
    106                       RHS.getCXXOverloadedOperator());
    107 
    108   case DeclarationName::CXXLiteralOperatorName:
    109     return LHS.getCXXLiteralIdentifier()->getName().compare(
    110         RHS.getCXXLiteralIdentifier()->getName());
    111 
    112   case DeclarationName::CXXUsingDirective:
    113     return 0;
    114   }
    115 
    116   llvm_unreachable("Invalid DeclarationName Kind!");
    117 }
    118 
    119 static void printCXXConstructorDestructorName(QualType ClassType,
    120                                               raw_ostream &OS,
    121                                               PrintingPolicy Policy) {
    122   // We know we're printing C++ here. Ensure we print types properly.
    123   Policy.adjustForCPlusPlus();
    124 
    125   if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
    126     OS << *ClassRec->getDecl();
    127     return;
    128   }
    129   if (Policy.SuppressTemplateArgsInCXXConstructors) {
    130     if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
    131       OS << *InjTy->getDecl();
    132       return;
    133     }
    134   }
    135   ClassType.print(OS, Policy);
    136 }
    137 
    138 void DeclarationName::print(raw_ostream &OS,
    139                             const PrintingPolicy &Policy) const {
    140   switch (getNameKind()) {
    141   case DeclarationName::Identifier:
    142     if (const IdentifierInfo *II = getAsIdentifierInfo()) {
    143       StringRef Name = II->getName();
    144       // If this is a mangled OpenMP variant name we strip off the mangling for
    145       // printing. It should not be visible to the user at all.
    146       if (II->isMangledOpenMPVariantName()) {
    147         std::pair<StringRef, StringRef> NameContextPair =
    148             Name.split(getOpenMPVariantManglingSeparatorStr());
    149         OS << NameContextPair.first << "["
    150            << OMPTraitInfo(NameContextPair.second) << "]";
    151       } else {
    152         OS << Name;
    153       }
    154     }
    155     return;
    156 
    157   case DeclarationName::ObjCZeroArgSelector:
    158   case DeclarationName::ObjCOneArgSelector:
    159   case DeclarationName::ObjCMultiArgSelector:
    160     getObjCSelector().print(OS);
    161     return;
    162 
    163   case DeclarationName::CXXConstructorName:
    164     return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
    165 
    166   case DeclarationName::CXXDestructorName:
    167     OS << '~';
    168     return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
    169 
    170   case DeclarationName::CXXDeductionGuideName:
    171     OS << "<deduction guide for ";
    172     getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
    173     OS << '>';
    174     return;
    175 
    176   case DeclarationName::CXXOperatorName: {
    177     const char *OpName = getOperatorSpelling(getCXXOverloadedOperator());
    178     assert(OpName && "not an overloaded operator");
    179 
    180     OS << "operator";
    181     if (OpName[0] >= 'a' && OpName[0] <= 'z')
    182       OS << ' ';
    183     OS << OpName;
    184     return;
    185   }
    186 
    187   case DeclarationName::CXXLiteralOperatorName:
    188     OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
    189     return;
    190 
    191   case DeclarationName::CXXConversionFunctionName: {
    192     OS << "operator ";
    193     QualType Type = getCXXNameType();
    194     if (const RecordType *Rec = Type->getAs<RecordType>()) {
    195       OS << *Rec->getDecl();
    196       return;
    197     }
    198     // We know we're printing C++ here, ensure we print 'bool' properly.
    199     PrintingPolicy CXXPolicy = Policy;
    200     CXXPolicy.adjustForCPlusPlus();
    201     Type.print(OS, CXXPolicy);
    202     return;
    203   }
    204   case DeclarationName::CXXUsingDirective:
    205     OS << "<using-directive>";
    206     return;
    207   }
    208 
    209   llvm_unreachable("Unexpected declaration name kind");
    210 }
    211 
    212 namespace clang {
    213 
    214 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
    215   LangOptions LO;
    216   N.print(OS, PrintingPolicy(LO));
    217   return OS;
    218 }
    219 
    220 } // namespace clang
    221 
    222 bool DeclarationName::isDependentName() const {
    223   QualType T = getCXXNameType();
    224   if (!T.isNull() && T->isDependentType())
    225     return true;
    226 
    227   // A class-scope deduction guide in a dependent context has a dependent name.
    228   auto *TD = getCXXDeductionGuideTemplate();
    229   if (TD && TD->getDeclContext()->isDependentContext())
    230     return true;
    231 
    232   return false;
    233 }
    234 
    235 std::string DeclarationName::getAsString() const {
    236   std::string Result;
    237   llvm::raw_string_ostream OS(Result);
    238   OS << *this;
    239   return OS.str();
    240 }
    241 
    242 void *DeclarationName::getFETokenInfoSlow() const {
    243   switch (getNameKind()) {
    244   case Identifier:
    245     llvm_unreachable("case Identifier already handled by getFETokenInfo!");
    246   case CXXConstructorName:
    247   case CXXDestructorName:
    248   case CXXConversionFunctionName:
    249     return castAsCXXSpecialNameExtra()->FETokenInfo;
    250   case CXXOperatorName:
    251     return castAsCXXOperatorIdName()->FETokenInfo;
    252   case CXXDeductionGuideName:
    253     return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
    254   case CXXLiteralOperatorName:
    255     return castAsCXXLiteralOperatorIdName()->FETokenInfo;
    256   default:
    257     llvm_unreachable("DeclarationName has no FETokenInfo!");
    258   }
    259 }
    260 
    261 void DeclarationName::setFETokenInfoSlow(void *T) {
    262   switch (getNameKind()) {
    263   case Identifier:
    264     llvm_unreachable("case Identifier already handled by setFETokenInfo!");
    265   case CXXConstructorName:
    266   case CXXDestructorName:
    267   case CXXConversionFunctionName:
    268     castAsCXXSpecialNameExtra()->FETokenInfo = T;
    269     break;
    270   case CXXOperatorName:
    271     castAsCXXOperatorIdName()->FETokenInfo = T;
    272     break;
    273   case CXXDeductionGuideName:
    274     castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
    275     break;
    276   case CXXLiteralOperatorName:
    277     castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
    278     break;
    279   default:
    280     llvm_unreachable("DeclarationName has no FETokenInfo!");
    281   }
    282 }
    283 
    284 LLVM_DUMP_METHOD void DeclarationName::dump() const {
    285   llvm::errs() << *this << '\n';
    286 }
    287 
    288 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
    289   // Initialize the overloaded operator names.
    290   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
    291     CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
    292 }
    293 
    294 DeclarationName
    295 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
    296   Template = cast<TemplateDecl>(Template->getCanonicalDecl());
    297 
    298   llvm::FoldingSetNodeID ID;
    299   ID.AddPointer(Template);
    300 
    301   void *InsertPos = nullptr;
    302   if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
    303     return DeclarationName(Name);
    304 
    305   auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
    306   CXXDeductionGuideNames.InsertNode(Name, InsertPos);
    307   return DeclarationName(Name);
    308 }
    309 
    310 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
    311   // The type of constructors is unqualified.
    312   Ty = Ty.getUnqualifiedType();
    313   // Do we already have this C++ constructor name ?
    314   llvm::FoldingSetNodeID ID;
    315   ID.AddPointer(Ty.getAsOpaquePtr());
    316   void *InsertPos = nullptr;
    317   if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
    318     return {Name, DeclarationName::StoredCXXConstructorName};
    319 
    320   // We have to create it.
    321   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
    322   CXXConstructorNames.InsertNode(SpecialName, InsertPos);
    323   return {SpecialName, DeclarationName::StoredCXXConstructorName};
    324 }
    325 
    326 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
    327   // The type of destructors is unqualified.
    328   Ty = Ty.getUnqualifiedType();
    329   // Do we already have this C++ destructor name ?
    330   llvm::FoldingSetNodeID ID;
    331   ID.AddPointer(Ty.getAsOpaquePtr());
    332   void *InsertPos = nullptr;
    333   if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
    334     return {Name, DeclarationName::StoredCXXDestructorName};
    335 
    336   // We have to create it.
    337   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
    338   CXXDestructorNames.InsertNode(SpecialName, InsertPos);
    339   return {SpecialName, DeclarationName::StoredCXXDestructorName};
    340 }
    341 
    342 DeclarationName
    343 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
    344   // Do we already have this C++ conversion function name ?
    345   llvm::FoldingSetNodeID ID;
    346   ID.AddPointer(Ty.getAsOpaquePtr());
    347   void *InsertPos = nullptr;
    348   if (auto *Name =
    349           CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
    350     return {Name, DeclarationName::StoredCXXConversionFunctionName};
    351 
    352   // We have to create it.
    353   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
    354   CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
    355   return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
    356 }
    357 
    358 DeclarationName
    359 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
    360                                         CanQualType Ty) {
    361   switch (Kind) {
    362   case DeclarationName::CXXConstructorName:
    363     return getCXXConstructorName(Ty);
    364   case DeclarationName::CXXDestructorName:
    365     return getCXXDestructorName(Ty);
    366   case DeclarationName::CXXConversionFunctionName:
    367     return getCXXConversionFunctionName(Ty);
    368   default:
    369     llvm_unreachable("Invalid kind in getCXXSpecialName!");
    370   }
    371 }
    372 
    373 DeclarationName
    374 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
    375   llvm::FoldingSetNodeID ID;
    376   ID.AddPointer(II);
    377 
    378   void *InsertPos = nullptr;
    379   if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
    380     return DeclarationName(Name);
    381 
    382   auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
    383   CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
    384   return DeclarationName(LiteralName);
    385 }
    386 
    387 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
    388   switch (Name.getNameKind()) {
    389   case DeclarationName::Identifier:
    390   case DeclarationName::CXXDeductionGuideName:
    391     break;
    392   case DeclarationName::CXXConstructorName:
    393   case DeclarationName::CXXDestructorName:
    394   case DeclarationName::CXXConversionFunctionName:
    395     setNamedTypeLoc(nullptr);
    396     break;
    397   case DeclarationName::CXXOperatorName:
    398     setCXXOperatorNameRange(SourceRange());
    399     break;
    400   case DeclarationName::CXXLiteralOperatorName:
    401     setCXXLiteralOperatorNameLoc(SourceLocation());
    402     break;
    403   case DeclarationName::ObjCZeroArgSelector:
    404   case DeclarationName::ObjCOneArgSelector:
    405   case DeclarationName::ObjCMultiArgSelector:
    406     // FIXME: ?
    407     break;
    408   case DeclarationName::CXXUsingDirective:
    409     break;
    410   }
    411 }
    412 
    413 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
    414   switch (Name.getNameKind()) {
    415   case DeclarationName::Identifier:
    416   case DeclarationName::ObjCZeroArgSelector:
    417   case DeclarationName::ObjCOneArgSelector:
    418   case DeclarationName::ObjCMultiArgSelector:
    419   case DeclarationName::CXXOperatorName:
    420   case DeclarationName::CXXLiteralOperatorName:
    421   case DeclarationName::CXXUsingDirective:
    422   case DeclarationName::CXXDeductionGuideName:
    423     return false;
    424 
    425   case DeclarationName::CXXConstructorName:
    426   case DeclarationName::CXXDestructorName:
    427   case DeclarationName::CXXConversionFunctionName:
    428     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
    429       return TInfo->getType()->containsUnexpandedParameterPack();
    430 
    431     return Name.getCXXNameType()->containsUnexpandedParameterPack();
    432   }
    433   llvm_unreachable("All name kinds handled.");
    434 }
    435 
    436 bool DeclarationNameInfo::isInstantiationDependent() const {
    437   switch (Name.getNameKind()) {
    438   case DeclarationName::Identifier:
    439   case DeclarationName::ObjCZeroArgSelector:
    440   case DeclarationName::ObjCOneArgSelector:
    441   case DeclarationName::ObjCMultiArgSelector:
    442   case DeclarationName::CXXOperatorName:
    443   case DeclarationName::CXXLiteralOperatorName:
    444   case DeclarationName::CXXUsingDirective:
    445   case DeclarationName::CXXDeductionGuideName:
    446     return false;
    447 
    448   case DeclarationName::CXXConstructorName:
    449   case DeclarationName::CXXDestructorName:
    450   case DeclarationName::CXXConversionFunctionName:
    451     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
    452       return TInfo->getType()->isInstantiationDependentType();
    453 
    454     return Name.getCXXNameType()->isInstantiationDependentType();
    455   }
    456   llvm_unreachable("All name kinds handled.");
    457 }
    458 
    459 std::string DeclarationNameInfo::getAsString() const {
    460   std::string Result;
    461   llvm::raw_string_ostream OS(Result);
    462   OS << *this;
    463   return OS.str();
    464 }
    465 
    466 raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {
    467   LangOptions LO;
    468   DNInfo.printName(OS, PrintingPolicy(LangOptions()));
    469   return OS;
    470 }
    471 
    472 void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const {
    473   switch (Name.getNameKind()) {
    474   case DeclarationName::Identifier:
    475   case DeclarationName::ObjCZeroArgSelector:
    476   case DeclarationName::ObjCOneArgSelector:
    477   case DeclarationName::ObjCMultiArgSelector:
    478   case DeclarationName::CXXOperatorName:
    479   case DeclarationName::CXXLiteralOperatorName:
    480   case DeclarationName::CXXUsingDirective:
    481   case DeclarationName::CXXDeductionGuideName:
    482     Name.print(OS, Policy);
    483     return;
    484 
    485   case DeclarationName::CXXConstructorName:
    486   case DeclarationName::CXXDestructorName:
    487   case DeclarationName::CXXConversionFunctionName:
    488     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) {
    489       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
    490         OS << '~';
    491       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
    492         OS << "operator ";
    493       LangOptions LO;
    494       Policy.adjustForCPlusPlus();
    495       Policy.SuppressScope = true;
    496       OS << TInfo->getType().getAsString(Policy);
    497     } else
    498       Name.print(OS, Policy);
    499     return;
    500   }
    501   llvm_unreachable("Unexpected declaration name kind");
    502 }
    503 
    504 SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
    505   switch (Name.getNameKind()) {
    506   case DeclarationName::Identifier:
    507   case DeclarationName::CXXDeductionGuideName:
    508     return NameLoc;
    509 
    510   case DeclarationName::CXXOperatorName:
    511     return LocInfo.getCXXOperatorNameEndLoc();
    512 
    513   case DeclarationName::CXXLiteralOperatorName:
    514     return LocInfo.getCXXLiteralOperatorNameLoc();
    515 
    516   case DeclarationName::CXXConstructorName:
    517   case DeclarationName::CXXDestructorName:
    518   case DeclarationName::CXXConversionFunctionName:
    519     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
    520       return TInfo->getTypeLoc().getEndLoc();
    521     else
    522       return NameLoc;
    523 
    524     // DNInfo work in progress: FIXME.
    525   case DeclarationName::ObjCZeroArgSelector:
    526   case DeclarationName::ObjCOneArgSelector:
    527   case DeclarationName::ObjCMultiArgSelector:
    528   case DeclarationName::CXXUsingDirective:
    529     return NameLoc;
    530   }
    531   llvm_unreachable("Unexpected declaration name kind");
    532 }
    533