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