xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/AST/DeclarationName.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===- DeclarationName.cpp - Declaration names implementation -------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements the DeclarationName and DeclarationNameTable
107330f729Sjoerg // classes.
117330f729Sjoerg //
127330f729Sjoerg //===----------------------------------------------------------------------===//
137330f729Sjoerg 
147330f729Sjoerg #include "clang/AST/DeclarationName.h"
157330f729Sjoerg #include "clang/AST/ASTContext.h"
167330f729Sjoerg #include "clang/AST/Decl.h"
177330f729Sjoerg #include "clang/AST/DeclBase.h"
187330f729Sjoerg #include "clang/AST/DeclCXX.h"
197330f729Sjoerg #include "clang/AST/DeclTemplate.h"
20*e038c9c4Sjoerg #include "clang/AST/OpenMPClause.h"
217330f729Sjoerg #include "clang/AST/PrettyPrinter.h"
227330f729Sjoerg #include "clang/AST/Type.h"
237330f729Sjoerg #include "clang/AST/TypeLoc.h"
247330f729Sjoerg #include "clang/AST/TypeOrdering.h"
257330f729Sjoerg #include "clang/Basic/IdentifierTable.h"
267330f729Sjoerg #include "clang/Basic/LLVM.h"
277330f729Sjoerg #include "clang/Basic/LangOptions.h"
287330f729Sjoerg #include "clang/Basic/OperatorKinds.h"
297330f729Sjoerg #include "clang/Basic/SourceLocation.h"
307330f729Sjoerg #include "llvm/ADT/FoldingSet.h"
317330f729Sjoerg #include "llvm/Support/Casting.h"
327330f729Sjoerg #include "llvm/Support/Compiler.h"
337330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
347330f729Sjoerg #include "llvm/Support/raw_ostream.h"
357330f729Sjoerg #include <algorithm>
367330f729Sjoerg #include <cassert>
377330f729Sjoerg #include <cstdint>
387330f729Sjoerg #include <string>
397330f729Sjoerg 
407330f729Sjoerg using namespace clang;
417330f729Sjoerg 
compareInt(unsigned A,unsigned B)427330f729Sjoerg static int compareInt(unsigned A, unsigned B) {
437330f729Sjoerg   return (A < B ? -1 : (A > B ? 1 : 0));
447330f729Sjoerg }
457330f729Sjoerg 
compare(DeclarationName LHS,DeclarationName RHS)467330f729Sjoerg int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
477330f729Sjoerg   if (LHS.getNameKind() != RHS.getNameKind())
487330f729Sjoerg     return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
497330f729Sjoerg 
507330f729Sjoerg   switch (LHS.getNameKind()) {
517330f729Sjoerg   case DeclarationName::Identifier: {
527330f729Sjoerg     IdentifierInfo *LII = LHS.castAsIdentifierInfo();
537330f729Sjoerg     IdentifierInfo *RII = RHS.castAsIdentifierInfo();
547330f729Sjoerg     if (!LII)
557330f729Sjoerg       return RII ? -1 : 0;
567330f729Sjoerg     if (!RII)
577330f729Sjoerg       return 1;
587330f729Sjoerg 
597330f729Sjoerg     return LII->getName().compare(RII->getName());
607330f729Sjoerg   }
617330f729Sjoerg 
627330f729Sjoerg   case DeclarationName::ObjCZeroArgSelector:
637330f729Sjoerg   case DeclarationName::ObjCOneArgSelector:
647330f729Sjoerg   case DeclarationName::ObjCMultiArgSelector: {
657330f729Sjoerg     Selector LHSSelector = LHS.getObjCSelector();
667330f729Sjoerg     Selector RHSSelector = RHS.getObjCSelector();
677330f729Sjoerg     // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
687330f729Sjoerg     if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
697330f729Sjoerg         RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
707330f729Sjoerg       return LHSSelector.getAsIdentifierInfo()->getName().compare(
717330f729Sjoerg           RHSSelector.getAsIdentifierInfo()->getName());
727330f729Sjoerg     }
737330f729Sjoerg     unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
747330f729Sjoerg     for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
757330f729Sjoerg       switch (LHSSelector.getNameForSlot(I).compare(
767330f729Sjoerg           RHSSelector.getNameForSlot(I))) {
777330f729Sjoerg       case -1:
787330f729Sjoerg         return -1;
797330f729Sjoerg       case 1:
807330f729Sjoerg         return 1;
817330f729Sjoerg       default:
827330f729Sjoerg         break;
837330f729Sjoerg       }
847330f729Sjoerg     }
857330f729Sjoerg 
867330f729Sjoerg     return compareInt(LN, RN);
877330f729Sjoerg   }
887330f729Sjoerg 
897330f729Sjoerg   case DeclarationName::CXXConstructorName:
907330f729Sjoerg   case DeclarationName::CXXDestructorName:
917330f729Sjoerg   case DeclarationName::CXXConversionFunctionName:
927330f729Sjoerg     if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
937330f729Sjoerg       return -1;
947330f729Sjoerg     if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
957330f729Sjoerg       return 1;
967330f729Sjoerg     return 0;
977330f729Sjoerg 
987330f729Sjoerg   case DeclarationName::CXXDeductionGuideName:
997330f729Sjoerg     // We never want to compare deduction guide names for templates from
1007330f729Sjoerg     // different scopes, so just compare the template-name.
1017330f729Sjoerg     return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
1027330f729Sjoerg                    RHS.getCXXDeductionGuideTemplate()->getDeclName());
1037330f729Sjoerg 
1047330f729Sjoerg   case DeclarationName::CXXOperatorName:
1057330f729Sjoerg     return compareInt(LHS.getCXXOverloadedOperator(),
1067330f729Sjoerg                       RHS.getCXXOverloadedOperator());
1077330f729Sjoerg 
1087330f729Sjoerg   case DeclarationName::CXXLiteralOperatorName:
1097330f729Sjoerg     return LHS.getCXXLiteralIdentifier()->getName().compare(
1107330f729Sjoerg         RHS.getCXXLiteralIdentifier()->getName());
1117330f729Sjoerg 
1127330f729Sjoerg   case DeclarationName::CXXUsingDirective:
1137330f729Sjoerg     return 0;
1147330f729Sjoerg   }
1157330f729Sjoerg 
1167330f729Sjoerg   llvm_unreachable("Invalid DeclarationName Kind!");
1177330f729Sjoerg }
1187330f729Sjoerg 
printCXXConstructorDestructorName(QualType ClassType,raw_ostream & OS,PrintingPolicy Policy)1197330f729Sjoerg static void printCXXConstructorDestructorName(QualType ClassType,
1207330f729Sjoerg                                               raw_ostream &OS,
1217330f729Sjoerg                                               PrintingPolicy Policy) {
1227330f729Sjoerg   // We know we're printing C++ here. Ensure we print types properly.
1237330f729Sjoerg   Policy.adjustForCPlusPlus();
1247330f729Sjoerg 
1257330f729Sjoerg   if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
1267330f729Sjoerg     OS << *ClassRec->getDecl();
1277330f729Sjoerg     return;
1287330f729Sjoerg   }
1297330f729Sjoerg   if (Policy.SuppressTemplateArgsInCXXConstructors) {
1307330f729Sjoerg     if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
1317330f729Sjoerg       OS << *InjTy->getDecl();
1327330f729Sjoerg       return;
1337330f729Sjoerg     }
1347330f729Sjoerg   }
1357330f729Sjoerg   ClassType.print(OS, Policy);
1367330f729Sjoerg }
1377330f729Sjoerg 
print(raw_ostream & OS,const PrintingPolicy & Policy) const138*e038c9c4Sjoerg void DeclarationName::print(raw_ostream &OS,
139*e038c9c4Sjoerg                             const PrintingPolicy &Policy) const {
1407330f729Sjoerg   switch (getNameKind()) {
1417330f729Sjoerg   case DeclarationName::Identifier:
142*e038c9c4Sjoerg     if (const IdentifierInfo *II = getAsIdentifierInfo()) {
143*e038c9c4Sjoerg       StringRef Name = II->getName();
144*e038c9c4Sjoerg       // If this is a mangled OpenMP variant name we strip off the mangling for
145*e038c9c4Sjoerg       // printing. It should not be visible to the user at all.
146*e038c9c4Sjoerg       if (II->isMangledOpenMPVariantName()) {
147*e038c9c4Sjoerg         std::pair<StringRef, StringRef> NameContextPair =
148*e038c9c4Sjoerg             Name.split(getOpenMPVariantManglingSeparatorStr());
149*e038c9c4Sjoerg         OS << NameContextPair.first << "["
150*e038c9c4Sjoerg            << OMPTraitInfo(NameContextPair.second) << "]";
151*e038c9c4Sjoerg       } else {
152*e038c9c4Sjoerg         OS << Name;
153*e038c9c4Sjoerg       }
154*e038c9c4Sjoerg     }
1557330f729Sjoerg     return;
1567330f729Sjoerg 
1577330f729Sjoerg   case DeclarationName::ObjCZeroArgSelector:
1587330f729Sjoerg   case DeclarationName::ObjCOneArgSelector:
1597330f729Sjoerg   case DeclarationName::ObjCMultiArgSelector:
1607330f729Sjoerg     getObjCSelector().print(OS);
1617330f729Sjoerg     return;
1627330f729Sjoerg 
1637330f729Sjoerg   case DeclarationName::CXXConstructorName:
1647330f729Sjoerg     return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
1657330f729Sjoerg 
1667330f729Sjoerg   case DeclarationName::CXXDestructorName:
1677330f729Sjoerg     OS << '~';
1687330f729Sjoerg     return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
1697330f729Sjoerg 
1707330f729Sjoerg   case DeclarationName::CXXDeductionGuideName:
1717330f729Sjoerg     OS << "<deduction guide for ";
1727330f729Sjoerg     getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
1737330f729Sjoerg     OS << '>';
1747330f729Sjoerg     return;
1757330f729Sjoerg 
1767330f729Sjoerg   case DeclarationName::CXXOperatorName: {
1777330f729Sjoerg     const char *OpName = getOperatorSpelling(getCXXOverloadedOperator());
1787330f729Sjoerg     assert(OpName && "not an overloaded operator");
1797330f729Sjoerg 
1807330f729Sjoerg     OS << "operator";
1817330f729Sjoerg     if (OpName[0] >= 'a' && OpName[0] <= 'z')
1827330f729Sjoerg       OS << ' ';
1837330f729Sjoerg     OS << OpName;
1847330f729Sjoerg     return;
1857330f729Sjoerg   }
1867330f729Sjoerg 
1877330f729Sjoerg   case DeclarationName::CXXLiteralOperatorName:
1887330f729Sjoerg     OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
1897330f729Sjoerg     return;
1907330f729Sjoerg 
1917330f729Sjoerg   case DeclarationName::CXXConversionFunctionName: {
1927330f729Sjoerg     OS << "operator ";
1937330f729Sjoerg     QualType Type = getCXXNameType();
1947330f729Sjoerg     if (const RecordType *Rec = Type->getAs<RecordType>()) {
1957330f729Sjoerg       OS << *Rec->getDecl();
1967330f729Sjoerg       return;
1977330f729Sjoerg     }
1987330f729Sjoerg     // We know we're printing C++ here, ensure we print 'bool' properly.
1997330f729Sjoerg     PrintingPolicy CXXPolicy = Policy;
2007330f729Sjoerg     CXXPolicy.adjustForCPlusPlus();
2017330f729Sjoerg     Type.print(OS, CXXPolicy);
2027330f729Sjoerg     return;
2037330f729Sjoerg   }
2047330f729Sjoerg   case DeclarationName::CXXUsingDirective:
2057330f729Sjoerg     OS << "<using-directive>";
2067330f729Sjoerg     return;
2077330f729Sjoerg   }
2087330f729Sjoerg 
2097330f729Sjoerg   llvm_unreachable("Unexpected declaration name kind");
2107330f729Sjoerg }
2117330f729Sjoerg 
2127330f729Sjoerg namespace clang {
2137330f729Sjoerg 
operator <<(raw_ostream & OS,DeclarationName N)2147330f729Sjoerg raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
2157330f729Sjoerg   LangOptions LO;
2167330f729Sjoerg   N.print(OS, PrintingPolicy(LO));
2177330f729Sjoerg   return OS;
2187330f729Sjoerg }
2197330f729Sjoerg 
2207330f729Sjoerg } // namespace clang
2217330f729Sjoerg 
isDependentName() const2227330f729Sjoerg bool DeclarationName::isDependentName() const {
2237330f729Sjoerg   QualType T = getCXXNameType();
2247330f729Sjoerg   if (!T.isNull() && T->isDependentType())
2257330f729Sjoerg     return true;
2267330f729Sjoerg 
2277330f729Sjoerg   // A class-scope deduction guide in a dependent context has a dependent name.
2287330f729Sjoerg   auto *TD = getCXXDeductionGuideTemplate();
2297330f729Sjoerg   if (TD && TD->getDeclContext()->isDependentContext())
2307330f729Sjoerg     return true;
2317330f729Sjoerg 
2327330f729Sjoerg   return false;
2337330f729Sjoerg }
2347330f729Sjoerg 
getAsString() const2357330f729Sjoerg std::string DeclarationName::getAsString() const {
2367330f729Sjoerg   std::string Result;
2377330f729Sjoerg   llvm::raw_string_ostream OS(Result);
2387330f729Sjoerg   OS << *this;
2397330f729Sjoerg   return OS.str();
2407330f729Sjoerg }
2417330f729Sjoerg 
getFETokenInfoSlow() const2427330f729Sjoerg void *DeclarationName::getFETokenInfoSlow() const {
2437330f729Sjoerg   switch (getNameKind()) {
2447330f729Sjoerg   case Identifier:
2457330f729Sjoerg     llvm_unreachable("case Identifier already handled by getFETokenInfo!");
2467330f729Sjoerg   case CXXConstructorName:
2477330f729Sjoerg   case CXXDestructorName:
2487330f729Sjoerg   case CXXConversionFunctionName:
2497330f729Sjoerg     return castAsCXXSpecialNameExtra()->FETokenInfo;
2507330f729Sjoerg   case CXXOperatorName:
2517330f729Sjoerg     return castAsCXXOperatorIdName()->FETokenInfo;
2527330f729Sjoerg   case CXXDeductionGuideName:
2537330f729Sjoerg     return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
2547330f729Sjoerg   case CXXLiteralOperatorName:
2557330f729Sjoerg     return castAsCXXLiteralOperatorIdName()->FETokenInfo;
2567330f729Sjoerg   default:
2577330f729Sjoerg     llvm_unreachable("DeclarationName has no FETokenInfo!");
2587330f729Sjoerg   }
2597330f729Sjoerg }
2607330f729Sjoerg 
setFETokenInfoSlow(void * T)2617330f729Sjoerg void DeclarationName::setFETokenInfoSlow(void *T) {
2627330f729Sjoerg   switch (getNameKind()) {
2637330f729Sjoerg   case Identifier:
2647330f729Sjoerg     llvm_unreachable("case Identifier already handled by setFETokenInfo!");
2657330f729Sjoerg   case CXXConstructorName:
2667330f729Sjoerg   case CXXDestructorName:
2677330f729Sjoerg   case CXXConversionFunctionName:
2687330f729Sjoerg     castAsCXXSpecialNameExtra()->FETokenInfo = T;
2697330f729Sjoerg     break;
2707330f729Sjoerg   case CXXOperatorName:
2717330f729Sjoerg     castAsCXXOperatorIdName()->FETokenInfo = T;
2727330f729Sjoerg     break;
2737330f729Sjoerg   case CXXDeductionGuideName:
2747330f729Sjoerg     castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
2757330f729Sjoerg     break;
2767330f729Sjoerg   case CXXLiteralOperatorName:
2777330f729Sjoerg     castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
2787330f729Sjoerg     break;
2797330f729Sjoerg   default:
2807330f729Sjoerg     llvm_unreachable("DeclarationName has no FETokenInfo!");
2817330f729Sjoerg   }
2827330f729Sjoerg }
2837330f729Sjoerg 
dump() const2847330f729Sjoerg LLVM_DUMP_METHOD void DeclarationName::dump() const {
2857330f729Sjoerg   llvm::errs() << *this << '\n';
2867330f729Sjoerg }
2877330f729Sjoerg 
DeclarationNameTable(const ASTContext & C)2887330f729Sjoerg DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
2897330f729Sjoerg   // Initialize the overloaded operator names.
2907330f729Sjoerg   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
2917330f729Sjoerg     CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
2927330f729Sjoerg }
2937330f729Sjoerg 
2947330f729Sjoerg DeclarationName
getCXXDeductionGuideName(TemplateDecl * Template)2957330f729Sjoerg DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
2967330f729Sjoerg   Template = cast<TemplateDecl>(Template->getCanonicalDecl());
2977330f729Sjoerg 
2987330f729Sjoerg   llvm::FoldingSetNodeID ID;
2997330f729Sjoerg   ID.AddPointer(Template);
3007330f729Sjoerg 
3017330f729Sjoerg   void *InsertPos = nullptr;
3027330f729Sjoerg   if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
3037330f729Sjoerg     return DeclarationName(Name);
3047330f729Sjoerg 
3057330f729Sjoerg   auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
3067330f729Sjoerg   CXXDeductionGuideNames.InsertNode(Name, InsertPos);
3077330f729Sjoerg   return DeclarationName(Name);
3087330f729Sjoerg }
3097330f729Sjoerg 
getCXXConstructorName(CanQualType Ty)3107330f729Sjoerg DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
3117330f729Sjoerg   // The type of constructors is unqualified.
3127330f729Sjoerg   Ty = Ty.getUnqualifiedType();
3137330f729Sjoerg   // Do we already have this C++ constructor name ?
3147330f729Sjoerg   llvm::FoldingSetNodeID ID;
3157330f729Sjoerg   ID.AddPointer(Ty.getAsOpaquePtr());
3167330f729Sjoerg   void *InsertPos = nullptr;
3177330f729Sjoerg   if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
3187330f729Sjoerg     return {Name, DeclarationName::StoredCXXConstructorName};
3197330f729Sjoerg 
3207330f729Sjoerg   // We have to create it.
3217330f729Sjoerg   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
3227330f729Sjoerg   CXXConstructorNames.InsertNode(SpecialName, InsertPos);
3237330f729Sjoerg   return {SpecialName, DeclarationName::StoredCXXConstructorName};
3247330f729Sjoerg }
3257330f729Sjoerg 
getCXXDestructorName(CanQualType Ty)3267330f729Sjoerg DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
3277330f729Sjoerg   // The type of destructors is unqualified.
3287330f729Sjoerg   Ty = Ty.getUnqualifiedType();
3297330f729Sjoerg   // Do we already have this C++ destructor name ?
3307330f729Sjoerg   llvm::FoldingSetNodeID ID;
3317330f729Sjoerg   ID.AddPointer(Ty.getAsOpaquePtr());
3327330f729Sjoerg   void *InsertPos = nullptr;
3337330f729Sjoerg   if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
3347330f729Sjoerg     return {Name, DeclarationName::StoredCXXDestructorName};
3357330f729Sjoerg 
3367330f729Sjoerg   // We have to create it.
3377330f729Sjoerg   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
3387330f729Sjoerg   CXXDestructorNames.InsertNode(SpecialName, InsertPos);
3397330f729Sjoerg   return {SpecialName, DeclarationName::StoredCXXDestructorName};
3407330f729Sjoerg }
3417330f729Sjoerg 
3427330f729Sjoerg DeclarationName
getCXXConversionFunctionName(CanQualType Ty)3437330f729Sjoerg DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
3447330f729Sjoerg   // Do we already have this C++ conversion function name ?
3457330f729Sjoerg   llvm::FoldingSetNodeID ID;
3467330f729Sjoerg   ID.AddPointer(Ty.getAsOpaquePtr());
3477330f729Sjoerg   void *InsertPos = nullptr;
3487330f729Sjoerg   if (auto *Name =
3497330f729Sjoerg           CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
3507330f729Sjoerg     return {Name, DeclarationName::StoredCXXConversionFunctionName};
3517330f729Sjoerg 
3527330f729Sjoerg   // We have to create it.
3537330f729Sjoerg   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
3547330f729Sjoerg   CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
3557330f729Sjoerg   return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
3567330f729Sjoerg }
3577330f729Sjoerg 
3587330f729Sjoerg DeclarationName
getCXXSpecialName(DeclarationName::NameKind Kind,CanQualType Ty)3597330f729Sjoerg DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
3607330f729Sjoerg                                         CanQualType Ty) {
3617330f729Sjoerg   switch (Kind) {
3627330f729Sjoerg   case DeclarationName::CXXConstructorName:
3637330f729Sjoerg     return getCXXConstructorName(Ty);
3647330f729Sjoerg   case DeclarationName::CXXDestructorName:
3657330f729Sjoerg     return getCXXDestructorName(Ty);
3667330f729Sjoerg   case DeclarationName::CXXConversionFunctionName:
3677330f729Sjoerg     return getCXXConversionFunctionName(Ty);
3687330f729Sjoerg   default:
3697330f729Sjoerg     llvm_unreachable("Invalid kind in getCXXSpecialName!");
3707330f729Sjoerg   }
3717330f729Sjoerg }
3727330f729Sjoerg 
3737330f729Sjoerg DeclarationName
getCXXLiteralOperatorName(IdentifierInfo * II)3747330f729Sjoerg DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
3757330f729Sjoerg   llvm::FoldingSetNodeID ID;
3767330f729Sjoerg   ID.AddPointer(II);
3777330f729Sjoerg 
3787330f729Sjoerg   void *InsertPos = nullptr;
3797330f729Sjoerg   if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
3807330f729Sjoerg     return DeclarationName(Name);
3817330f729Sjoerg 
3827330f729Sjoerg   auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
3837330f729Sjoerg   CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
3847330f729Sjoerg   return DeclarationName(LiteralName);
3857330f729Sjoerg }
3867330f729Sjoerg 
DeclarationNameLoc(DeclarationName Name)3877330f729Sjoerg DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
3887330f729Sjoerg   switch (Name.getNameKind()) {
3897330f729Sjoerg   case DeclarationName::Identifier:
3907330f729Sjoerg   case DeclarationName::CXXDeductionGuideName:
3917330f729Sjoerg     break;
3927330f729Sjoerg   case DeclarationName::CXXConstructorName:
3937330f729Sjoerg   case DeclarationName::CXXDestructorName:
3947330f729Sjoerg   case DeclarationName::CXXConversionFunctionName:
395*e038c9c4Sjoerg     setNamedTypeLoc(nullptr);
3967330f729Sjoerg     break;
3977330f729Sjoerg   case DeclarationName::CXXOperatorName:
398*e038c9c4Sjoerg     setCXXOperatorNameRange(SourceRange());
3997330f729Sjoerg     break;
4007330f729Sjoerg   case DeclarationName::CXXLiteralOperatorName:
401*e038c9c4Sjoerg     setCXXLiteralOperatorNameLoc(SourceLocation());
4027330f729Sjoerg     break;
4037330f729Sjoerg   case DeclarationName::ObjCZeroArgSelector:
4047330f729Sjoerg   case DeclarationName::ObjCOneArgSelector:
4057330f729Sjoerg   case DeclarationName::ObjCMultiArgSelector:
4067330f729Sjoerg     // FIXME: ?
4077330f729Sjoerg     break;
4087330f729Sjoerg   case DeclarationName::CXXUsingDirective:
4097330f729Sjoerg     break;
4107330f729Sjoerg   }
4117330f729Sjoerg }
4127330f729Sjoerg 
containsUnexpandedParameterPack() const4137330f729Sjoerg bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
4147330f729Sjoerg   switch (Name.getNameKind()) {
4157330f729Sjoerg   case DeclarationName::Identifier:
4167330f729Sjoerg   case DeclarationName::ObjCZeroArgSelector:
4177330f729Sjoerg   case DeclarationName::ObjCOneArgSelector:
4187330f729Sjoerg   case DeclarationName::ObjCMultiArgSelector:
4197330f729Sjoerg   case DeclarationName::CXXOperatorName:
4207330f729Sjoerg   case DeclarationName::CXXLiteralOperatorName:
4217330f729Sjoerg   case DeclarationName::CXXUsingDirective:
4227330f729Sjoerg   case DeclarationName::CXXDeductionGuideName:
4237330f729Sjoerg     return false;
4247330f729Sjoerg 
4257330f729Sjoerg   case DeclarationName::CXXConstructorName:
4267330f729Sjoerg   case DeclarationName::CXXDestructorName:
4277330f729Sjoerg   case DeclarationName::CXXConversionFunctionName:
428*e038c9c4Sjoerg     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
4297330f729Sjoerg       return TInfo->getType()->containsUnexpandedParameterPack();
4307330f729Sjoerg 
4317330f729Sjoerg     return Name.getCXXNameType()->containsUnexpandedParameterPack();
4327330f729Sjoerg   }
4337330f729Sjoerg   llvm_unreachable("All name kinds handled.");
4347330f729Sjoerg }
4357330f729Sjoerg 
isInstantiationDependent() const4367330f729Sjoerg bool DeclarationNameInfo::isInstantiationDependent() const {
4377330f729Sjoerg   switch (Name.getNameKind()) {
4387330f729Sjoerg   case DeclarationName::Identifier:
4397330f729Sjoerg   case DeclarationName::ObjCZeroArgSelector:
4407330f729Sjoerg   case DeclarationName::ObjCOneArgSelector:
4417330f729Sjoerg   case DeclarationName::ObjCMultiArgSelector:
4427330f729Sjoerg   case DeclarationName::CXXOperatorName:
4437330f729Sjoerg   case DeclarationName::CXXLiteralOperatorName:
4447330f729Sjoerg   case DeclarationName::CXXUsingDirective:
4457330f729Sjoerg   case DeclarationName::CXXDeductionGuideName:
4467330f729Sjoerg     return false;
4477330f729Sjoerg 
4487330f729Sjoerg   case DeclarationName::CXXConstructorName:
4497330f729Sjoerg   case DeclarationName::CXXDestructorName:
4507330f729Sjoerg   case DeclarationName::CXXConversionFunctionName:
451*e038c9c4Sjoerg     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
4527330f729Sjoerg       return TInfo->getType()->isInstantiationDependentType();
4537330f729Sjoerg 
4547330f729Sjoerg     return Name.getCXXNameType()->isInstantiationDependentType();
4557330f729Sjoerg   }
4567330f729Sjoerg   llvm_unreachable("All name kinds handled.");
4577330f729Sjoerg }
4587330f729Sjoerg 
getAsString() const4597330f729Sjoerg std::string DeclarationNameInfo::getAsString() const {
4607330f729Sjoerg   std::string Result;
4617330f729Sjoerg   llvm::raw_string_ostream OS(Result);
462*e038c9c4Sjoerg   OS << *this;
4637330f729Sjoerg   return OS.str();
4647330f729Sjoerg }
4657330f729Sjoerg 
operator <<(raw_ostream & OS,DeclarationNameInfo DNInfo)466*e038c9c4Sjoerg raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {
467*e038c9c4Sjoerg   LangOptions LO;
468*e038c9c4Sjoerg   DNInfo.printName(OS, PrintingPolicy(LangOptions()));
469*e038c9c4Sjoerg   return OS;
470*e038c9c4Sjoerg }
471*e038c9c4Sjoerg 
printName(raw_ostream & OS,PrintingPolicy Policy) const472*e038c9c4Sjoerg void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const {
4737330f729Sjoerg   switch (Name.getNameKind()) {
4747330f729Sjoerg   case DeclarationName::Identifier:
4757330f729Sjoerg   case DeclarationName::ObjCZeroArgSelector:
4767330f729Sjoerg   case DeclarationName::ObjCOneArgSelector:
4777330f729Sjoerg   case DeclarationName::ObjCMultiArgSelector:
4787330f729Sjoerg   case DeclarationName::CXXOperatorName:
4797330f729Sjoerg   case DeclarationName::CXXLiteralOperatorName:
4807330f729Sjoerg   case DeclarationName::CXXUsingDirective:
4817330f729Sjoerg   case DeclarationName::CXXDeductionGuideName:
482*e038c9c4Sjoerg     Name.print(OS, Policy);
4837330f729Sjoerg     return;
4847330f729Sjoerg 
4857330f729Sjoerg   case DeclarationName::CXXConstructorName:
4867330f729Sjoerg   case DeclarationName::CXXDestructorName:
4877330f729Sjoerg   case DeclarationName::CXXConversionFunctionName:
488*e038c9c4Sjoerg     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) {
4897330f729Sjoerg       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
4907330f729Sjoerg         OS << '~';
4917330f729Sjoerg       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
4927330f729Sjoerg         OS << "operator ";
4937330f729Sjoerg       LangOptions LO;
494*e038c9c4Sjoerg       Policy.adjustForCPlusPlus();
495*e038c9c4Sjoerg       Policy.SuppressScope = true;
496*e038c9c4Sjoerg       OS << TInfo->getType().getAsString(Policy);
4977330f729Sjoerg     } else
498*e038c9c4Sjoerg       Name.print(OS, Policy);
4997330f729Sjoerg     return;
5007330f729Sjoerg   }
5017330f729Sjoerg   llvm_unreachable("Unexpected declaration name kind");
5027330f729Sjoerg }
5037330f729Sjoerg 
getEndLocPrivate() const5047330f729Sjoerg SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
5057330f729Sjoerg   switch (Name.getNameKind()) {
5067330f729Sjoerg   case DeclarationName::Identifier:
5077330f729Sjoerg   case DeclarationName::CXXDeductionGuideName:
5087330f729Sjoerg     return NameLoc;
5097330f729Sjoerg 
510*e038c9c4Sjoerg   case DeclarationName::CXXOperatorName:
511*e038c9c4Sjoerg     return LocInfo.getCXXOperatorNameEndLoc();
5127330f729Sjoerg 
513*e038c9c4Sjoerg   case DeclarationName::CXXLiteralOperatorName:
514*e038c9c4Sjoerg     return LocInfo.getCXXLiteralOperatorNameLoc();
5157330f729Sjoerg 
5167330f729Sjoerg   case DeclarationName::CXXConstructorName:
5177330f729Sjoerg   case DeclarationName::CXXDestructorName:
5187330f729Sjoerg   case DeclarationName::CXXConversionFunctionName:
519*e038c9c4Sjoerg     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
5207330f729Sjoerg       return TInfo->getTypeLoc().getEndLoc();
5217330f729Sjoerg     else
5227330f729Sjoerg       return NameLoc;
5237330f729Sjoerg 
5247330f729Sjoerg     // DNInfo work in progress: FIXME.
5257330f729Sjoerg   case DeclarationName::ObjCZeroArgSelector:
5267330f729Sjoerg   case DeclarationName::ObjCOneArgSelector:
5277330f729Sjoerg   case DeclarationName::ObjCMultiArgSelector:
5287330f729Sjoerg   case DeclarationName::CXXUsingDirective:
5297330f729Sjoerg     return NameLoc;
5307330f729Sjoerg   }
5317330f729Sjoerg   llvm_unreachable("Unexpected declaration name kind");
5327330f729Sjoerg }
533