10b57cec5SDimitry Andric //===- DeclarationName.cpp - Declaration names implementation -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the DeclarationName and DeclarationNameTable
100b57cec5SDimitry Andric // classes.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "clang/AST/DeclarationName.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
160b57cec5SDimitry Andric #include "clang/AST/Decl.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
190b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
205ffd83dbSDimitry Andric #include "clang/AST/OpenMPClause.h"
210b57cec5SDimitry Andric #include "clang/AST/PrettyPrinter.h"
220b57cec5SDimitry Andric #include "clang/AST/Type.h"
230b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h"
240b57cec5SDimitry Andric #include "clang/AST/TypeOrdering.h"
250b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
260b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
270b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
280b57cec5SDimitry Andric #include "clang/Basic/OperatorKinds.h"
290b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
300b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h"
310b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
320b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
330b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
340b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
350b57cec5SDimitry Andric #include <algorithm>
360b57cec5SDimitry Andric #include <cassert>
370b57cec5SDimitry Andric #include <cstdint>
380b57cec5SDimitry Andric #include <string>
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric using namespace clang;
410b57cec5SDimitry Andric 
compareInt(unsigned A,unsigned B)420b57cec5SDimitry Andric static int compareInt(unsigned A, unsigned B) {
430b57cec5SDimitry Andric   return (A < B ? -1 : (A > B ? 1 : 0));
440b57cec5SDimitry Andric }
450b57cec5SDimitry Andric 
compare(DeclarationName LHS,DeclarationName RHS)460b57cec5SDimitry Andric int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
470b57cec5SDimitry Andric   if (LHS.getNameKind() != RHS.getNameKind())
480b57cec5SDimitry Andric     return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   switch (LHS.getNameKind()) {
510b57cec5SDimitry Andric   case DeclarationName::Identifier: {
520b57cec5SDimitry Andric     IdentifierInfo *LII = LHS.castAsIdentifierInfo();
530b57cec5SDimitry Andric     IdentifierInfo *RII = RHS.castAsIdentifierInfo();
540b57cec5SDimitry Andric     if (!LII)
550b57cec5SDimitry Andric       return RII ? -1 : 0;
560b57cec5SDimitry Andric     if (!RII)
570b57cec5SDimitry Andric       return 1;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric     return LII->getName().compare(RII->getName());
600b57cec5SDimitry Andric   }
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   case DeclarationName::ObjCZeroArgSelector:
630b57cec5SDimitry Andric   case DeclarationName::ObjCOneArgSelector:
640b57cec5SDimitry Andric   case DeclarationName::ObjCMultiArgSelector: {
650b57cec5SDimitry Andric     Selector LHSSelector = LHS.getObjCSelector();
660b57cec5SDimitry Andric     Selector RHSSelector = RHS.getObjCSelector();
670b57cec5SDimitry Andric     // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
680b57cec5SDimitry Andric     if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
690b57cec5SDimitry Andric         RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
700b57cec5SDimitry Andric       return LHSSelector.getAsIdentifierInfo()->getName().compare(
710b57cec5SDimitry Andric           RHSSelector.getAsIdentifierInfo()->getName());
720b57cec5SDimitry Andric     }
730b57cec5SDimitry Andric     unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
740b57cec5SDimitry Andric     for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
75bdd1243dSDimitry Andric       if (int Compare = LHSSelector.getNameForSlot(I).compare(
76bdd1243dSDimitry Andric               RHSSelector.getNameForSlot(I)))
77bdd1243dSDimitry Andric         return Compare;
780b57cec5SDimitry Andric     }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric     return compareInt(LN, RN);
810b57cec5SDimitry Andric   }
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   case DeclarationName::CXXConstructorName:
840b57cec5SDimitry Andric   case DeclarationName::CXXDestructorName:
850b57cec5SDimitry Andric   case DeclarationName::CXXConversionFunctionName:
860b57cec5SDimitry Andric     if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
870b57cec5SDimitry Andric       return -1;
880b57cec5SDimitry Andric     if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
890b57cec5SDimitry Andric       return 1;
900b57cec5SDimitry Andric     return 0;
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   case DeclarationName::CXXDeductionGuideName:
930b57cec5SDimitry Andric     // We never want to compare deduction guide names for templates from
940b57cec5SDimitry Andric     // different scopes, so just compare the template-name.
950b57cec5SDimitry Andric     return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
960b57cec5SDimitry Andric                    RHS.getCXXDeductionGuideTemplate()->getDeclName());
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   case DeclarationName::CXXOperatorName:
990b57cec5SDimitry Andric     return compareInt(LHS.getCXXOverloadedOperator(),
1000b57cec5SDimitry Andric                       RHS.getCXXOverloadedOperator());
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   case DeclarationName::CXXLiteralOperatorName:
1030b57cec5SDimitry Andric     return LHS.getCXXLiteralIdentifier()->getName().compare(
1040b57cec5SDimitry Andric         RHS.getCXXLiteralIdentifier()->getName());
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   case DeclarationName::CXXUsingDirective:
1070b57cec5SDimitry Andric     return 0;
1080b57cec5SDimitry Andric   }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   llvm_unreachable("Invalid DeclarationName Kind!");
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
printCXXConstructorDestructorName(QualType ClassType,raw_ostream & OS,PrintingPolicy Policy)1130b57cec5SDimitry Andric static void printCXXConstructorDestructorName(QualType ClassType,
1140b57cec5SDimitry Andric                                               raw_ostream &OS,
1150b57cec5SDimitry Andric                                               PrintingPolicy Policy) {
1160b57cec5SDimitry Andric   // We know we're printing C++ here. Ensure we print types properly.
1170b57cec5SDimitry Andric   Policy.adjustForCPlusPlus();
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric   if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
12006c3fb27SDimitry Andric     ClassRec->getDecl()->printName(OS, Policy);
1210b57cec5SDimitry Andric     return;
1220b57cec5SDimitry Andric   }
1230b57cec5SDimitry Andric   if (Policy.SuppressTemplateArgsInCXXConstructors) {
1240b57cec5SDimitry Andric     if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
12506c3fb27SDimitry Andric       InjTy->getDecl()->printName(OS, Policy);
1260b57cec5SDimitry Andric       return;
1270b57cec5SDimitry Andric     }
1280b57cec5SDimitry Andric   }
1290b57cec5SDimitry Andric   ClassType.print(OS, Policy);
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
print(raw_ostream & OS,const PrintingPolicy & Policy) const132480093f4SDimitry Andric void DeclarationName::print(raw_ostream &OS,
133480093f4SDimitry Andric                             const PrintingPolicy &Policy) const {
1340b57cec5SDimitry Andric   switch (getNameKind()) {
1350b57cec5SDimitry Andric   case DeclarationName::Identifier:
1365ffd83dbSDimitry Andric     if (const IdentifierInfo *II = getAsIdentifierInfo()) {
1375ffd83dbSDimitry Andric       StringRef Name = II->getName();
1385ffd83dbSDimitry Andric       // If this is a mangled OpenMP variant name we strip off the mangling for
1395ffd83dbSDimitry Andric       // printing. It should not be visible to the user at all.
1405ffd83dbSDimitry Andric       if (II->isMangledOpenMPVariantName()) {
1415ffd83dbSDimitry Andric         std::pair<StringRef, StringRef> NameContextPair =
1425ffd83dbSDimitry Andric             Name.split(getOpenMPVariantManglingSeparatorStr());
1435ffd83dbSDimitry Andric         OS << NameContextPair.first << "["
1445ffd83dbSDimitry Andric            << OMPTraitInfo(NameContextPair.second) << "]";
1455ffd83dbSDimitry Andric       } else {
1465ffd83dbSDimitry Andric         OS << Name;
1475ffd83dbSDimitry Andric       }
1485ffd83dbSDimitry Andric     }
1490b57cec5SDimitry Andric     return;
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   case DeclarationName::ObjCZeroArgSelector:
1520b57cec5SDimitry Andric   case DeclarationName::ObjCOneArgSelector:
1530b57cec5SDimitry Andric   case DeclarationName::ObjCMultiArgSelector:
1540b57cec5SDimitry Andric     getObjCSelector().print(OS);
1550b57cec5SDimitry Andric     return;
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric   case DeclarationName::CXXConstructorName:
1580b57cec5SDimitry Andric     return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   case DeclarationName::CXXDestructorName:
1610b57cec5SDimitry Andric     OS << '~';
1620b57cec5SDimitry Andric     return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric   case DeclarationName::CXXDeductionGuideName:
1650b57cec5SDimitry Andric     OS << "<deduction guide for ";
1660b57cec5SDimitry Andric     getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
1670b57cec5SDimitry Andric     OS << '>';
1680b57cec5SDimitry Andric     return;
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   case DeclarationName::CXXOperatorName: {
1710b57cec5SDimitry Andric     const char *OpName = getOperatorSpelling(getCXXOverloadedOperator());
1720b57cec5SDimitry Andric     assert(OpName && "not an overloaded operator");
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric     OS << "operator";
1750b57cec5SDimitry Andric     if (OpName[0] >= 'a' && OpName[0] <= 'z')
1760b57cec5SDimitry Andric       OS << ' ';
1770b57cec5SDimitry Andric     OS << OpName;
1780b57cec5SDimitry Andric     return;
1790b57cec5SDimitry Andric   }
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   case DeclarationName::CXXLiteralOperatorName:
1820b57cec5SDimitry Andric     OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
1830b57cec5SDimitry Andric     return;
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   case DeclarationName::CXXConversionFunctionName: {
1860b57cec5SDimitry Andric     OS << "operator ";
1870b57cec5SDimitry Andric     QualType Type = getCXXNameType();
1880b57cec5SDimitry Andric     if (const RecordType *Rec = Type->getAs<RecordType>()) {
1890b57cec5SDimitry Andric       OS << *Rec->getDecl();
1900b57cec5SDimitry Andric       return;
1910b57cec5SDimitry Andric     }
1920b57cec5SDimitry Andric     // We know we're printing C++ here, ensure we print 'bool' properly.
1930b57cec5SDimitry Andric     PrintingPolicy CXXPolicy = Policy;
1940b57cec5SDimitry Andric     CXXPolicy.adjustForCPlusPlus();
1950b57cec5SDimitry Andric     Type.print(OS, CXXPolicy);
1960b57cec5SDimitry Andric     return;
1970b57cec5SDimitry Andric   }
1980b57cec5SDimitry Andric   case DeclarationName::CXXUsingDirective:
1990b57cec5SDimitry Andric     OS << "<using-directive>";
2000b57cec5SDimitry Andric     return;
2010b57cec5SDimitry Andric   }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   llvm_unreachable("Unexpected declaration name kind");
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric namespace clang {
2070b57cec5SDimitry Andric 
operator <<(raw_ostream & OS,DeclarationName N)2080b57cec5SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
2090b57cec5SDimitry Andric   LangOptions LO;
2100b57cec5SDimitry Andric   N.print(OS, PrintingPolicy(LO));
2110b57cec5SDimitry Andric   return OS;
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric } // namespace clang
2150b57cec5SDimitry Andric 
isDependentName() const2160b57cec5SDimitry Andric bool DeclarationName::isDependentName() const {
2170b57cec5SDimitry Andric   QualType T = getCXXNameType();
2180b57cec5SDimitry Andric   if (!T.isNull() && T->isDependentType())
2190b57cec5SDimitry Andric     return true;
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   // A class-scope deduction guide in a dependent context has a dependent name.
2220b57cec5SDimitry Andric   auto *TD = getCXXDeductionGuideTemplate();
2230b57cec5SDimitry Andric   if (TD && TD->getDeclContext()->isDependentContext())
2240b57cec5SDimitry Andric     return true;
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   return false;
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric 
getAsString() const2290b57cec5SDimitry Andric std::string DeclarationName::getAsString() const {
2300b57cec5SDimitry Andric   std::string Result;
2310b57cec5SDimitry Andric   llvm::raw_string_ostream OS(Result);
2320b57cec5SDimitry Andric   OS << *this;
2330eae32dcSDimitry Andric   return Result;
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric 
getFETokenInfoSlow() const2360b57cec5SDimitry Andric void *DeclarationName::getFETokenInfoSlow() const {
2370b57cec5SDimitry Andric   switch (getNameKind()) {
2380b57cec5SDimitry Andric   case Identifier:
2390b57cec5SDimitry Andric     llvm_unreachable("case Identifier already handled by getFETokenInfo!");
2400b57cec5SDimitry Andric   case CXXConstructorName:
2410b57cec5SDimitry Andric   case CXXDestructorName:
2420b57cec5SDimitry Andric   case CXXConversionFunctionName:
2430b57cec5SDimitry Andric     return castAsCXXSpecialNameExtra()->FETokenInfo;
2440b57cec5SDimitry Andric   case CXXOperatorName:
2450b57cec5SDimitry Andric     return castAsCXXOperatorIdName()->FETokenInfo;
2460b57cec5SDimitry Andric   case CXXDeductionGuideName:
2470b57cec5SDimitry Andric     return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
2480b57cec5SDimitry Andric   case CXXLiteralOperatorName:
2490b57cec5SDimitry Andric     return castAsCXXLiteralOperatorIdName()->FETokenInfo;
2500b57cec5SDimitry Andric   default:
2510b57cec5SDimitry Andric     llvm_unreachable("DeclarationName has no FETokenInfo!");
2520b57cec5SDimitry Andric   }
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
setFETokenInfoSlow(void * T)2550b57cec5SDimitry Andric void DeclarationName::setFETokenInfoSlow(void *T) {
2560b57cec5SDimitry Andric   switch (getNameKind()) {
2570b57cec5SDimitry Andric   case Identifier:
2580b57cec5SDimitry Andric     llvm_unreachable("case Identifier already handled by setFETokenInfo!");
2590b57cec5SDimitry Andric   case CXXConstructorName:
2600b57cec5SDimitry Andric   case CXXDestructorName:
2610b57cec5SDimitry Andric   case CXXConversionFunctionName:
2620b57cec5SDimitry Andric     castAsCXXSpecialNameExtra()->FETokenInfo = T;
2630b57cec5SDimitry Andric     break;
2640b57cec5SDimitry Andric   case CXXOperatorName:
2650b57cec5SDimitry Andric     castAsCXXOperatorIdName()->FETokenInfo = T;
2660b57cec5SDimitry Andric     break;
2670b57cec5SDimitry Andric   case CXXDeductionGuideName:
2680b57cec5SDimitry Andric     castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
2690b57cec5SDimitry Andric     break;
2700b57cec5SDimitry Andric   case CXXLiteralOperatorName:
2710b57cec5SDimitry Andric     castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
2720b57cec5SDimitry Andric     break;
2730b57cec5SDimitry Andric   default:
2740b57cec5SDimitry Andric     llvm_unreachable("DeclarationName has no FETokenInfo!");
2750b57cec5SDimitry Andric   }
2760b57cec5SDimitry Andric }
2770b57cec5SDimitry Andric 
dump() const2780b57cec5SDimitry Andric LLVM_DUMP_METHOD void DeclarationName::dump() const {
2790b57cec5SDimitry Andric   llvm::errs() << *this << '\n';
2800b57cec5SDimitry Andric }
2810b57cec5SDimitry Andric 
DeclarationNameTable(const ASTContext & C)2820b57cec5SDimitry Andric DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
2830b57cec5SDimitry Andric   // Initialize the overloaded operator names.
2840b57cec5SDimitry Andric   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
2850b57cec5SDimitry Andric     CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric DeclarationName
getCXXDeductionGuideName(TemplateDecl * Template)2890b57cec5SDimitry Andric DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
2900b57cec5SDimitry Andric   Template = cast<TemplateDecl>(Template->getCanonicalDecl());
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric   llvm::FoldingSetNodeID ID;
2930b57cec5SDimitry Andric   ID.AddPointer(Template);
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric   void *InsertPos = nullptr;
2960b57cec5SDimitry Andric   if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
2970b57cec5SDimitry Andric     return DeclarationName(Name);
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
3000b57cec5SDimitry Andric   CXXDeductionGuideNames.InsertNode(Name, InsertPos);
3010b57cec5SDimitry Andric   return DeclarationName(Name);
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric 
getCXXConstructorName(CanQualType Ty)3040b57cec5SDimitry Andric DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
3050b57cec5SDimitry Andric   // The type of constructors is unqualified.
3060b57cec5SDimitry Andric   Ty = Ty.getUnqualifiedType();
3070b57cec5SDimitry Andric   // Do we already have this C++ constructor name ?
3080b57cec5SDimitry Andric   llvm::FoldingSetNodeID ID;
3090b57cec5SDimitry Andric   ID.AddPointer(Ty.getAsOpaquePtr());
3100b57cec5SDimitry Andric   void *InsertPos = nullptr;
3110b57cec5SDimitry Andric   if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
3120b57cec5SDimitry Andric     return {Name, DeclarationName::StoredCXXConstructorName};
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   // We have to create it.
3150b57cec5SDimitry Andric   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
3160b57cec5SDimitry Andric   CXXConstructorNames.InsertNode(SpecialName, InsertPos);
3170b57cec5SDimitry Andric   return {SpecialName, DeclarationName::StoredCXXConstructorName};
3180b57cec5SDimitry Andric }
3190b57cec5SDimitry Andric 
getCXXDestructorName(CanQualType Ty)3200b57cec5SDimitry Andric DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
3210b57cec5SDimitry Andric   // The type of destructors is unqualified.
3220b57cec5SDimitry Andric   Ty = Ty.getUnqualifiedType();
3230b57cec5SDimitry Andric   // Do we already have this C++ destructor name ?
3240b57cec5SDimitry Andric   llvm::FoldingSetNodeID ID;
3250b57cec5SDimitry Andric   ID.AddPointer(Ty.getAsOpaquePtr());
3260b57cec5SDimitry Andric   void *InsertPos = nullptr;
3270b57cec5SDimitry Andric   if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
3280b57cec5SDimitry Andric     return {Name, DeclarationName::StoredCXXDestructorName};
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   // We have to create it.
3310b57cec5SDimitry Andric   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
3320b57cec5SDimitry Andric   CXXDestructorNames.InsertNode(SpecialName, InsertPos);
3330b57cec5SDimitry Andric   return {SpecialName, DeclarationName::StoredCXXDestructorName};
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric DeclarationName
getCXXConversionFunctionName(CanQualType Ty)3370b57cec5SDimitry Andric DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
3380b57cec5SDimitry Andric   // Do we already have this C++ conversion function name ?
3390b57cec5SDimitry Andric   llvm::FoldingSetNodeID ID;
3400b57cec5SDimitry Andric   ID.AddPointer(Ty.getAsOpaquePtr());
3410b57cec5SDimitry Andric   void *InsertPos = nullptr;
3420b57cec5SDimitry Andric   if (auto *Name =
3430b57cec5SDimitry Andric           CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
3440b57cec5SDimitry Andric     return {Name, DeclarationName::StoredCXXConversionFunctionName};
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric   // We have to create it.
3470b57cec5SDimitry Andric   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
3480b57cec5SDimitry Andric   CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
3490b57cec5SDimitry Andric   return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric DeclarationName
getCXXSpecialName(DeclarationName::NameKind Kind,CanQualType Ty)3530b57cec5SDimitry Andric DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
3540b57cec5SDimitry Andric                                         CanQualType Ty) {
3550b57cec5SDimitry Andric   switch (Kind) {
3560b57cec5SDimitry Andric   case DeclarationName::CXXConstructorName:
3570b57cec5SDimitry Andric     return getCXXConstructorName(Ty);
3580b57cec5SDimitry Andric   case DeclarationName::CXXDestructorName:
3590b57cec5SDimitry Andric     return getCXXDestructorName(Ty);
3600b57cec5SDimitry Andric   case DeclarationName::CXXConversionFunctionName:
3610b57cec5SDimitry Andric     return getCXXConversionFunctionName(Ty);
3620b57cec5SDimitry Andric   default:
3630b57cec5SDimitry Andric     llvm_unreachable("Invalid kind in getCXXSpecialName!");
3640b57cec5SDimitry Andric   }
3650b57cec5SDimitry Andric }
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric DeclarationName
getCXXLiteralOperatorName(const IdentifierInfo * II)36806c3fb27SDimitry Andric DeclarationNameTable::getCXXLiteralOperatorName(const IdentifierInfo *II) {
3690b57cec5SDimitry Andric   llvm::FoldingSetNodeID ID;
3700b57cec5SDimitry Andric   ID.AddPointer(II);
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric   void *InsertPos = nullptr;
3730b57cec5SDimitry Andric   if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
3740b57cec5SDimitry Andric     return DeclarationName(Name);
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric   auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
3770b57cec5SDimitry Andric   CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
3780b57cec5SDimitry Andric   return DeclarationName(LiteralName);
3790b57cec5SDimitry Andric }
3800b57cec5SDimitry Andric 
DeclarationNameLoc(DeclarationName Name)3810b57cec5SDimitry Andric DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
3820b57cec5SDimitry Andric   switch (Name.getNameKind()) {
3830b57cec5SDimitry Andric   case DeclarationName::Identifier:
3840b57cec5SDimitry Andric   case DeclarationName::CXXDeductionGuideName:
3850b57cec5SDimitry Andric     break;
3860b57cec5SDimitry Andric   case DeclarationName::CXXConstructorName:
3870b57cec5SDimitry Andric   case DeclarationName::CXXDestructorName:
3880b57cec5SDimitry Andric   case DeclarationName::CXXConversionFunctionName:
389fe6060f1SDimitry Andric     setNamedTypeLoc(nullptr);
3900b57cec5SDimitry Andric     break;
3910b57cec5SDimitry Andric   case DeclarationName::CXXOperatorName:
392fe6060f1SDimitry Andric     setCXXOperatorNameRange(SourceRange());
3930b57cec5SDimitry Andric     break;
3940b57cec5SDimitry Andric   case DeclarationName::CXXLiteralOperatorName:
395fe6060f1SDimitry Andric     setCXXLiteralOperatorNameLoc(SourceLocation());
3960b57cec5SDimitry Andric     break;
3970b57cec5SDimitry Andric   case DeclarationName::ObjCZeroArgSelector:
3980b57cec5SDimitry Andric   case DeclarationName::ObjCOneArgSelector:
3990b57cec5SDimitry Andric   case DeclarationName::ObjCMultiArgSelector:
4000b57cec5SDimitry Andric     // FIXME: ?
4010b57cec5SDimitry Andric     break;
4020b57cec5SDimitry Andric   case DeclarationName::CXXUsingDirective:
4030b57cec5SDimitry Andric     break;
4040b57cec5SDimitry Andric   }
4050b57cec5SDimitry Andric }
4060b57cec5SDimitry Andric 
containsUnexpandedParameterPack() const4070b57cec5SDimitry Andric bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
4080b57cec5SDimitry Andric   switch (Name.getNameKind()) {
4090b57cec5SDimitry Andric   case DeclarationName::Identifier:
4100b57cec5SDimitry Andric   case DeclarationName::ObjCZeroArgSelector:
4110b57cec5SDimitry Andric   case DeclarationName::ObjCOneArgSelector:
4120b57cec5SDimitry Andric   case DeclarationName::ObjCMultiArgSelector:
4130b57cec5SDimitry Andric   case DeclarationName::CXXOperatorName:
4140b57cec5SDimitry Andric   case DeclarationName::CXXLiteralOperatorName:
4150b57cec5SDimitry Andric   case DeclarationName::CXXUsingDirective:
4160b57cec5SDimitry Andric   case DeclarationName::CXXDeductionGuideName:
4170b57cec5SDimitry Andric     return false;
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric   case DeclarationName::CXXConstructorName:
4200b57cec5SDimitry Andric   case DeclarationName::CXXDestructorName:
4210b57cec5SDimitry Andric   case DeclarationName::CXXConversionFunctionName:
422fe6060f1SDimitry Andric     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
4230b57cec5SDimitry Andric       return TInfo->getType()->containsUnexpandedParameterPack();
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric     return Name.getCXXNameType()->containsUnexpandedParameterPack();
4260b57cec5SDimitry Andric   }
4270b57cec5SDimitry Andric   llvm_unreachable("All name kinds handled.");
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric 
isInstantiationDependent() const4300b57cec5SDimitry Andric bool DeclarationNameInfo::isInstantiationDependent() const {
4310b57cec5SDimitry Andric   switch (Name.getNameKind()) {
4320b57cec5SDimitry Andric   case DeclarationName::Identifier:
4330b57cec5SDimitry Andric   case DeclarationName::ObjCZeroArgSelector:
4340b57cec5SDimitry Andric   case DeclarationName::ObjCOneArgSelector:
4350b57cec5SDimitry Andric   case DeclarationName::ObjCMultiArgSelector:
4360b57cec5SDimitry Andric   case DeclarationName::CXXOperatorName:
4370b57cec5SDimitry Andric   case DeclarationName::CXXLiteralOperatorName:
4380b57cec5SDimitry Andric   case DeclarationName::CXXUsingDirective:
4390b57cec5SDimitry Andric   case DeclarationName::CXXDeductionGuideName:
4400b57cec5SDimitry Andric     return false;
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   case DeclarationName::CXXConstructorName:
4430b57cec5SDimitry Andric   case DeclarationName::CXXDestructorName:
4440b57cec5SDimitry Andric   case DeclarationName::CXXConversionFunctionName:
445fe6060f1SDimitry Andric     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
4460b57cec5SDimitry Andric       return TInfo->getType()->isInstantiationDependentType();
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric     return Name.getCXXNameType()->isInstantiationDependentType();
4490b57cec5SDimitry Andric   }
4500b57cec5SDimitry Andric   llvm_unreachable("All name kinds handled.");
4510b57cec5SDimitry Andric }
4520b57cec5SDimitry Andric 
getAsString() const4530b57cec5SDimitry Andric std::string DeclarationNameInfo::getAsString() const {
4540b57cec5SDimitry Andric   std::string Result;
4550b57cec5SDimitry Andric   llvm::raw_string_ostream OS(Result);
456480093f4SDimitry Andric   OS << *this;
4570eae32dcSDimitry Andric   return Result;
4580b57cec5SDimitry Andric }
4590b57cec5SDimitry Andric 
operator <<(raw_ostream & OS,DeclarationNameInfo DNInfo)460480093f4SDimitry Andric raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {
461480093f4SDimitry Andric   LangOptions LO;
462480093f4SDimitry Andric   DNInfo.printName(OS, PrintingPolicy(LangOptions()));
463480093f4SDimitry Andric   return OS;
464480093f4SDimitry Andric }
465480093f4SDimitry Andric 
printName(raw_ostream & OS,PrintingPolicy Policy) const466480093f4SDimitry Andric void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const {
4670b57cec5SDimitry Andric   switch (Name.getNameKind()) {
4680b57cec5SDimitry Andric   case DeclarationName::Identifier:
4690b57cec5SDimitry Andric   case DeclarationName::ObjCZeroArgSelector:
4700b57cec5SDimitry Andric   case DeclarationName::ObjCOneArgSelector:
4710b57cec5SDimitry Andric   case DeclarationName::ObjCMultiArgSelector:
4720b57cec5SDimitry Andric   case DeclarationName::CXXOperatorName:
4730b57cec5SDimitry Andric   case DeclarationName::CXXLiteralOperatorName:
4740b57cec5SDimitry Andric   case DeclarationName::CXXUsingDirective:
4750b57cec5SDimitry Andric   case DeclarationName::CXXDeductionGuideName:
476480093f4SDimitry Andric     Name.print(OS, Policy);
4770b57cec5SDimitry Andric     return;
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric   case DeclarationName::CXXConstructorName:
4800b57cec5SDimitry Andric   case DeclarationName::CXXDestructorName:
4810b57cec5SDimitry Andric   case DeclarationName::CXXConversionFunctionName:
482fe6060f1SDimitry Andric     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) {
4830b57cec5SDimitry Andric       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
4840b57cec5SDimitry Andric         OS << '~';
4850b57cec5SDimitry Andric       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
4860b57cec5SDimitry Andric         OS << "operator ";
4870b57cec5SDimitry Andric       LangOptions LO;
488480093f4SDimitry Andric       Policy.adjustForCPlusPlus();
489480093f4SDimitry Andric       Policy.SuppressScope = true;
490480093f4SDimitry Andric       OS << TInfo->getType().getAsString(Policy);
4910b57cec5SDimitry Andric     } else
492480093f4SDimitry Andric       Name.print(OS, Policy);
4930b57cec5SDimitry Andric     return;
4940b57cec5SDimitry Andric   }
4950b57cec5SDimitry Andric   llvm_unreachable("Unexpected declaration name kind");
4960b57cec5SDimitry Andric }
4970b57cec5SDimitry Andric 
getEndLocPrivate() const4980b57cec5SDimitry Andric SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
4990b57cec5SDimitry Andric   switch (Name.getNameKind()) {
5000b57cec5SDimitry Andric   case DeclarationName::Identifier:
5010b57cec5SDimitry Andric   case DeclarationName::CXXDeductionGuideName:
5020b57cec5SDimitry Andric     return NameLoc;
5030b57cec5SDimitry Andric 
504fe6060f1SDimitry Andric   case DeclarationName::CXXOperatorName:
505fe6060f1SDimitry Andric     return LocInfo.getCXXOperatorNameEndLoc();
5060b57cec5SDimitry Andric 
507fe6060f1SDimitry Andric   case DeclarationName::CXXLiteralOperatorName:
508fe6060f1SDimitry Andric     return LocInfo.getCXXLiteralOperatorNameLoc();
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric   case DeclarationName::CXXConstructorName:
5110b57cec5SDimitry Andric   case DeclarationName::CXXDestructorName:
5120b57cec5SDimitry Andric   case DeclarationName::CXXConversionFunctionName:
513fe6060f1SDimitry Andric     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
5140b57cec5SDimitry Andric       return TInfo->getTypeLoc().getEndLoc();
5150b57cec5SDimitry Andric     else
5160b57cec5SDimitry Andric       return NameLoc;
5170b57cec5SDimitry Andric 
5180b57cec5SDimitry Andric     // DNInfo work in progress: FIXME.
5190b57cec5SDimitry Andric   case DeclarationName::ObjCZeroArgSelector:
5200b57cec5SDimitry Andric   case DeclarationName::ObjCOneArgSelector:
5210b57cec5SDimitry Andric   case DeclarationName::ObjCMultiArgSelector:
5220b57cec5SDimitry Andric   case DeclarationName::CXXUsingDirective:
5230b57cec5SDimitry Andric     return NameLoc;
5240b57cec5SDimitry Andric   }
5250b57cec5SDimitry Andric   llvm_unreachable("Unexpected declaration name kind");
5260b57cec5SDimitry Andric }
527