121fadadbSEugene Zelenko //===- DeclarationName.cpp - Declaration names implementation -------------===//
277324f38SDouglas Gregor //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
677324f38SDouglas Gregor //
777324f38SDouglas Gregor //===----------------------------------------------------------------------===//
877324f38SDouglas Gregor //
977324f38SDouglas Gregor // This file implements the DeclarationName and DeclarationNameTable
1077324f38SDouglas Gregor // classes.
1177324f38SDouglas Gregor //
1277324f38SDouglas Gregor //===----------------------------------------------------------------------===//
1321fadadbSEugene Zelenko 
149670f847SMehdi Amini #include "clang/AST/DeclarationName.h"
156aead3a0STed Kremenek #include "clang/AST/ASTContext.h"
1621fadadbSEugene Zelenko #include "clang/AST/Decl.h"
1721fadadbSEugene Zelenko #include "clang/AST/DeclBase.h"
18d5719084SArgyrios Kyrtzidis #include "clang/AST/DeclCXX.h"
1935845150SRichard Smith #include "clang/AST/DeclTemplate.h"
20befb4be3SJohannes Doerfert #include "clang/AST/OpenMPClause.h"
2121fadadbSEugene Zelenko #include "clang/AST/PrettyPrinter.h"
2292751d41SDouglas Gregor #include "clang/AST/Type.h"
23d6d2f189SAbramo Bagnara #include "clang/AST/TypeLoc.h"
24b082bab6SDouglas Gregor #include "clang/AST/TypeOrdering.h"
2577324f38SDouglas Gregor #include "clang/Basic/IdentifierTable.h"
2621fadadbSEugene Zelenko #include "clang/Basic/LLVM.h"
2721fadadbSEugene Zelenko #include "clang/Basic/LangOptions.h"
2821fadadbSEugene Zelenko #include "clang/Basic/OperatorKinds.h"
2921fadadbSEugene Zelenko #include "clang/Basic/SourceLocation.h"
3077324f38SDouglas Gregor #include "llvm/ADT/FoldingSet.h"
3121fadadbSEugene Zelenko #include "llvm/Support/Casting.h"
3221fadadbSEugene Zelenko #include "llvm/Support/Compiler.h"
332b59fbe7SChandler Carruth #include "llvm/Support/ErrorHandling.h"
3495c7c427SBenjamin Kramer #include "llvm/Support/raw_ostream.h"
3521fadadbSEugene Zelenko #include <algorithm>
3621fadadbSEugene Zelenko #include <cassert>
3721fadadbSEugene Zelenko #include <cstdint>
3821fadadbSEugene Zelenko #include <string>
3921fadadbSEugene Zelenko 
4077324f38SDouglas Gregor using namespace clang;
4177324f38SDouglas Gregor 
compareInt(unsigned A,unsigned B)42ef3057c4SJohn McCall static int compareInt(unsigned A, unsigned B) {
43ef3057c4SJohn McCall   return (A < B ? -1 : (A > B ? 1 : 0));
44ef3057c4SJohn McCall }
45ef3057c4SJohn McCall 
compare(DeclarationName LHS,DeclarationName RHS)46ef3057c4SJohn McCall int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
47b082bab6SDouglas Gregor   if (LHS.getNameKind() != RHS.getNameKind())
48ef3057c4SJohn McCall     return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
4977324f38SDouglas Gregor 
50b082bab6SDouglas Gregor   switch (LHS.getNameKind()) {
51ef3057c4SJohn McCall   case DeclarationName::Identifier: {
52366ba730SBruno Ricci     IdentifierInfo *LII = LHS.castAsIdentifierInfo();
53366ba730SBruno Ricci     IdentifierInfo *RII = RHS.castAsIdentifierInfo();
54366ba730SBruno Ricci     if (!LII)
55366ba730SBruno Ricci       return RII ? -1 : 0;
56366ba730SBruno Ricci     if (!RII)
57366ba730SBruno Ricci       return 1;
58ef3057c4SJohn McCall 
59ef3057c4SJohn McCall     return LII->getName().compare(RII->getName());
60ef3057c4SJohn McCall   }
61b082bab6SDouglas Gregor 
62b082bab6SDouglas Gregor   case DeclarationName::ObjCZeroArgSelector:
63b082bab6SDouglas Gregor   case DeclarationName::ObjCOneArgSelector:
64b082bab6SDouglas Gregor   case DeclarationName::ObjCMultiArgSelector: {
65b082bab6SDouglas Gregor     Selector LHSSelector = LHS.getObjCSelector();
66b082bab6SDouglas Gregor     Selector RHSSelector = RHS.getObjCSelector();
67b6665732SManman Ren     // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
68b6665732SManman Ren     if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
69b6665732SManman Ren         RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
70b6665732SManman Ren       return LHSSelector.getAsIdentifierInfo()->getName().compare(
71b6665732SManman Ren           RHSSelector.getAsIdentifierInfo()->getName());
72b6665732SManman Ren     }
73ef3057c4SJohn McCall     unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
74ef3057c4SJohn McCall     for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
75af2a6ae4SDouglas Gregor       switch (LHSSelector.getNameForSlot(I).compare(
76af2a6ae4SDouglas Gregor           RHSSelector.getNameForSlot(I))) {
77366ba730SBruno Ricci       case -1:
78366ba730SBruno Ricci         return -1;
79366ba730SBruno Ricci       case 1:
80366ba730SBruno Ricci         return 1;
81366ba730SBruno Ricci       default:
82366ba730SBruno Ricci         break;
83b082bab6SDouglas Gregor       }
84b082bab6SDouglas Gregor     }
85b082bab6SDouglas Gregor 
86ef3057c4SJohn McCall     return compareInt(LN, RN);
87b082bab6SDouglas Gregor   }
88b082bab6SDouglas Gregor 
89b082bab6SDouglas Gregor   case DeclarationName::CXXConstructorName:
90b082bab6SDouglas Gregor   case DeclarationName::CXXDestructorName:
91b082bab6SDouglas Gregor   case DeclarationName::CXXConversionFunctionName:
92ef3057c4SJohn McCall     if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
93ef3057c4SJohn McCall       return -1;
94ef3057c4SJohn McCall     if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
95ef3057c4SJohn McCall       return 1;
96ef3057c4SJohn McCall     return 0;
97b082bab6SDouglas Gregor 
9835845150SRichard Smith   case DeclarationName::CXXDeductionGuideName:
9935845150SRichard Smith     // We never want to compare deduction guide names for templates from
10035845150SRichard Smith     // different scopes, so just compare the template-name.
10135845150SRichard Smith     return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
10235845150SRichard Smith                    RHS.getCXXDeductionGuideTemplate()->getDeclName());
10335845150SRichard Smith 
104b082bab6SDouglas Gregor   case DeclarationName::CXXOperatorName:
105ef3057c4SJohn McCall     return compareInt(LHS.getCXXOverloadedOperator(),
106ef3057c4SJohn McCall                       RHS.getCXXOverloadedOperator());
107b082bab6SDouglas Gregor 
1083d221f2fSAlexis Hunt   case DeclarationName::CXXLiteralOperatorName:
109ef3057c4SJohn McCall     return LHS.getCXXLiteralIdentifier()->getName().compare(
110ef3057c4SJohn McCall         RHS.getCXXLiteralIdentifier()->getName());
1113d221f2fSAlexis Hunt 
112b082bab6SDouglas Gregor   case DeclarationName::CXXUsingDirective:
113ef3057c4SJohn McCall     return 0;
114b082bab6SDouglas Gregor   }
115b082bab6SDouglas Gregor 
116e4d798f0SDavid Blaikie   llvm_unreachable("Invalid DeclarationName Kind!");
11777324f38SDouglas Gregor }
11877324f38SDouglas Gregor 
printCXXConstructorDestructorName(QualType ClassType,raw_ostream & OS,PrintingPolicy Policy)119e91793c3SArgyrios Kyrtzidis static void printCXXConstructorDestructorName(QualType ClassType,
120e91793c3SArgyrios Kyrtzidis                                               raw_ostream &OS,
121301bc21fSRichard Smith                                               PrintingPolicy Policy) {
122301bc21fSRichard Smith   // We know we're printing C++ here. Ensure we print types properly.
123301bc21fSRichard Smith   Policy.adjustForCPlusPlus();
124301bc21fSRichard Smith 
125e91793c3SArgyrios Kyrtzidis   if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
126e91793c3SArgyrios Kyrtzidis     OS << *ClassRec->getDecl();
127e91793c3SArgyrios Kyrtzidis     return;
128e91793c3SArgyrios Kyrtzidis   }
129d5719084SArgyrios Kyrtzidis   if (Policy.SuppressTemplateArgsInCXXConstructors) {
130d5719084SArgyrios Kyrtzidis     if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
131d5719084SArgyrios Kyrtzidis       OS << *InjTy->getDecl();
132d5719084SArgyrios Kyrtzidis       return;
133d5719084SArgyrios Kyrtzidis     }
134d5719084SArgyrios Kyrtzidis   }
135e91793c3SArgyrios Kyrtzidis   ClassType.print(OS, Policy);
136e91793c3SArgyrios Kyrtzidis }
137e91793c3SArgyrios Kyrtzidis 
print(raw_ostream & OS,const PrintingPolicy & Policy) const138575e09d9SSam McCall void DeclarationName::print(raw_ostream &OS,
139575e09d9SSam McCall                             const PrintingPolicy &Policy) const {
140366ba730SBruno Ricci   switch (getNameKind()) {
141d4da8728SDavid Blaikie   case DeclarationName::Identifier:
142befb4be3SJohannes Doerfert     if (const IdentifierInfo *II = getAsIdentifierInfo()) {
143befb4be3SJohannes Doerfert       StringRef Name = II->getName();
144befb4be3SJohannes Doerfert       // If this is a mangled OpenMP variant name we strip off the mangling for
145befb4be3SJohannes Doerfert       // printing. It should not be visible to the user at all.
146befb4be3SJohannes Doerfert       if (II->isMangledOpenMPVariantName()) {
147befb4be3SJohannes Doerfert         std::pair<StringRef, StringRef> NameContextPair =
148befb4be3SJohannes Doerfert             Name.split(getOpenMPVariantManglingSeparatorStr());
149befb4be3SJohannes Doerfert         OS << NameContextPair.first << "["
150befb4be3SJohannes Doerfert            << OMPTraitInfo(NameContextPair.second) << "]";
151befb4be3SJohannes Doerfert       } else {
152befb4be3SJohannes Doerfert         OS << Name;
153befb4be3SJohannes Doerfert       }
154befb4be3SJohannes Doerfert     }
155e91793c3SArgyrios Kyrtzidis     return;
156d4da8728SDavid Blaikie 
157d4da8728SDavid Blaikie   case DeclarationName::ObjCZeroArgSelector:
158d4da8728SDavid Blaikie   case DeclarationName::ObjCOneArgSelector:
159d4da8728SDavid Blaikie   case DeclarationName::ObjCMultiArgSelector:
160366ba730SBruno Ricci     getObjCSelector().print(OS);
161e91793c3SArgyrios Kyrtzidis     return;
162d4da8728SDavid Blaikie 
163e91793c3SArgyrios Kyrtzidis   case DeclarationName::CXXConstructorName:
164366ba730SBruno Ricci     return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
165d4da8728SDavid Blaikie 
16621fadadbSEugene Zelenko   case DeclarationName::CXXDestructorName:
167d4da8728SDavid Blaikie     OS << '~';
168366ba730SBruno Ricci     return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
169d4da8728SDavid Blaikie 
17035845150SRichard Smith   case DeclarationName::CXXDeductionGuideName:
171f283fdcdSRichard Smith     OS << "<deduction guide for ";
172f283fdcdSRichard Smith     getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
173f283fdcdSRichard Smith     OS << '>';
174f283fdcdSRichard Smith     return;
17535845150SRichard Smith 
176d4da8728SDavid Blaikie   case DeclarationName::CXXOperatorName: {
1777fa2b74eSRichard Smith     const char *OpName = getOperatorSpelling(getCXXOverloadedOperator());
178d4da8728SDavid Blaikie     assert(OpName && "not an overloaded operator");
179d4da8728SDavid Blaikie 
180d4da8728SDavid Blaikie     OS << "operator";
181d4da8728SDavid Blaikie     if (OpName[0] >= 'a' && OpName[0] <= 'z')
182d4da8728SDavid Blaikie       OS << ' ';
183e91793c3SArgyrios Kyrtzidis     OS << OpName;
184e91793c3SArgyrios Kyrtzidis     return;
185d4da8728SDavid Blaikie   }
186d4da8728SDavid Blaikie 
187d4da8728SDavid Blaikie   case DeclarationName::CXXLiteralOperatorName:
188366ba730SBruno Ricci     OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
189e91793c3SArgyrios Kyrtzidis     return;
190d4da8728SDavid Blaikie 
191d4da8728SDavid Blaikie   case DeclarationName::CXXConversionFunctionName: {
192d4da8728SDavid Blaikie     OS << "operator ";
193366ba730SBruno Ricci     QualType Type = getCXXNameType();
194e91793c3SArgyrios Kyrtzidis     if (const RecordType *Rec = Type->getAs<RecordType>()) {
195e91793c3SArgyrios Kyrtzidis       OS << *Rec->getDecl();
196e91793c3SArgyrios Kyrtzidis       return;
197e91793c3SArgyrios Kyrtzidis     }
198301bc21fSRichard Smith     // We know we're printing C++ here, ensure we print 'bool' properly.
199301bc21fSRichard Smith     PrintingPolicy CXXPolicy = Policy;
200301bc21fSRichard Smith     CXXPolicy.adjustForCPlusPlus();
201301bc21fSRichard Smith     Type.print(OS, CXXPolicy);
202e91793c3SArgyrios Kyrtzidis     return;
203d4da8728SDavid Blaikie   }
204d4da8728SDavid Blaikie   case DeclarationName::CXXUsingDirective:
205e91793c3SArgyrios Kyrtzidis     OS << "<using-directive>";
206e91793c3SArgyrios Kyrtzidis     return;
207d4da8728SDavid Blaikie   }
208d4da8728SDavid Blaikie 
209d4da8728SDavid Blaikie   llvm_unreachable("Unexpected declaration name kind");
210d4da8728SDavid Blaikie }
211d4da8728SDavid Blaikie 
21221fadadbSEugene Zelenko namespace clang {
21321fadadbSEugene Zelenko 
operator <<(raw_ostream & OS,DeclarationName N)214e91793c3SArgyrios Kyrtzidis raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
215e91793c3SArgyrios Kyrtzidis   LangOptions LO;
216e91793c3SArgyrios Kyrtzidis   N.print(OS, PrintingPolicy(LO));
217e91793c3SArgyrios Kyrtzidis   return OS;
218e91793c3SArgyrios Kyrtzidis }
219e91793c3SArgyrios Kyrtzidis 
22021fadadbSEugene Zelenko } // namespace clang
22177324f38SDouglas Gregor 
isDependentName() const222ea0a0a9bSDouglas Gregor bool DeclarationName::isDependentName() const {
223ea0a0a9bSDouglas Gregor   QualType T = getCXXNameType();
22435845150SRichard Smith   if (!T.isNull() && T->isDependentType())
22535845150SRichard Smith     return true;
22635845150SRichard Smith 
22735845150SRichard Smith   // A class-scope deduction guide in a dependent context has a dependent name.
22835845150SRichard Smith   auto *TD = getCXXDeductionGuideTemplate();
22935845150SRichard Smith   if (TD && TD->getDeclContext()->isDependentContext())
23035845150SRichard Smith     return true;
23135845150SRichard Smith 
23235845150SRichard Smith   return false;
233ea0a0a9bSDouglas Gregor }
234ea0a0a9bSDouglas Gregor 
getAsString() const23592751d41SDouglas Gregor std::string DeclarationName::getAsString() const {
23695c7c427SBenjamin Kramer   std::string Result;
23795c7c427SBenjamin Kramer   llvm::raw_string_ostream OS(Result);
238d4da8728SDavid Blaikie   OS << *this;
239*ad17ea12SLogan Smith   return Result;
24095c7c427SBenjamin Kramer }
24195c7c427SBenjamin Kramer 
getFETokenInfoSlow() const242366ba730SBruno Ricci void *DeclarationName::getFETokenInfoSlow() const {
243ae2fbad3SDouglas Gregor   switch (getNameKind()) {
244ae2fbad3SDouglas Gregor   case Identifier:
245366ba730SBruno Ricci     llvm_unreachable("case Identifier already handled by getFETokenInfo!");
246ae2fbad3SDouglas Gregor   case CXXConstructorName:
247ae2fbad3SDouglas Gregor   case CXXDestructorName:
248ae2fbad3SDouglas Gregor   case CXXConversionFunctionName:
249366ba730SBruno Ricci     return castAsCXXSpecialNameExtra()->FETokenInfo;
250163c5850SDouglas Gregor   case CXXOperatorName:
251366ba730SBruno Ricci     return castAsCXXOperatorIdName()->FETokenInfo;
252366ba730SBruno Ricci   case CXXDeductionGuideName:
253366ba730SBruno Ricci     return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
2543d221f2fSAlexis Hunt   case CXXLiteralOperatorName:
255366ba730SBruno Ricci     return castAsCXXLiteralOperatorIdName()->FETokenInfo;
256ae2fbad3SDouglas Gregor   default:
257366ba730SBruno Ricci     llvm_unreachable("DeclarationName has no FETokenInfo!");
258ae2fbad3SDouglas Gregor   }
259ae2fbad3SDouglas Gregor }
260ae2fbad3SDouglas Gregor 
setFETokenInfoSlow(void * T)261366ba730SBruno Ricci void DeclarationName::setFETokenInfoSlow(void *T) {
262ae2fbad3SDouglas Gregor   switch (getNameKind()) {
263ae2fbad3SDouglas Gregor   case Identifier:
264366ba730SBruno Ricci     llvm_unreachable("case Identifier already handled by setFETokenInfo!");
265ae2fbad3SDouglas Gregor   case CXXConstructorName:
266ae2fbad3SDouglas Gregor   case CXXDestructorName:
267ae2fbad3SDouglas Gregor   case CXXConversionFunctionName:
268366ba730SBruno Ricci     castAsCXXSpecialNameExtra()->FETokenInfo = T;
269ae2fbad3SDouglas Gregor     break;
270163c5850SDouglas Gregor   case CXXOperatorName:
271366ba730SBruno Ricci     castAsCXXOperatorIdName()->FETokenInfo = T;
272163c5850SDouglas Gregor     break;
273366ba730SBruno Ricci   case CXXDeductionGuideName:
274366ba730SBruno Ricci     castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
275366ba730SBruno Ricci     break;
2763d221f2fSAlexis Hunt   case CXXLiteralOperatorName:
277366ba730SBruno Ricci     castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
2783d221f2fSAlexis Hunt     break;
279ae2fbad3SDouglas Gregor   default:
280366ba730SBruno Ricci     llvm_unreachable("DeclarationName has no FETokenInfo!");
281ae2fbad3SDouglas Gregor   }
282ae2fbad3SDouglas Gregor }
283ae2fbad3SDouglas Gregor 
dump() const284cdae941eSYaron Keren LLVM_DUMP_METHOD void DeclarationName::dump() const {
285d4da8728SDavid Blaikie   llvm::errs() << *this << '\n';
2861b69be2aSAnders Carlsson }
2871b69be2aSAnders Carlsson 
DeclarationNameTable(const ASTContext & C)28839c79807SJay Foad DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
289163c5850SDouglas Gregor   // Initialize the overloaded operator names.
290366ba730SBruno Ricci   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
291366ba730SBruno Ricci     CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
292d7d2b1feSBenjamin Kramer }
293d7d2b1feSBenjamin Kramer 
294d7d2b1feSBenjamin Kramer DeclarationName
getCXXDeductionGuideName(TemplateDecl * Template)29535845150SRichard Smith DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
29635845150SRichard Smith   Template = cast<TemplateDecl>(Template->getCanonicalDecl());
29735845150SRichard Smith 
29835845150SRichard Smith   llvm::FoldingSetNodeID ID;
29935845150SRichard Smith   ID.AddPointer(Template);
30035845150SRichard Smith 
30135845150SRichard Smith   void *InsertPos = nullptr;
302b619883cSBruno Ricci   if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
30335845150SRichard Smith     return DeclarationName(Name);
30435845150SRichard Smith 
305366ba730SBruno Ricci   auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
306b619883cSBruno Ricci   CXXDeductionGuideNames.InsertNode(Name, InsertPos);
30735845150SRichard Smith   return DeclarationName(Name);
30835845150SRichard Smith }
30935845150SRichard Smith 
getCXXConstructorName(CanQualType Ty)310366ba730SBruno Ricci DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
311366ba730SBruno Ricci   // The type of constructors is unqualified.
312366ba730SBruno Ricci   Ty = Ty.getUnqualifiedType();
313366ba730SBruno Ricci   // Do we already have this C++ constructor name ?
314366ba730SBruno Ricci   llvm::FoldingSetNodeID ID;
315366ba730SBruno Ricci   ID.AddPointer(Ty.getAsOpaquePtr());
316366ba730SBruno Ricci   void *InsertPos = nullptr;
317366ba730SBruno Ricci   if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
318366ba730SBruno Ricci     return {Name, DeclarationName::StoredCXXConstructorName};
319366ba730SBruno Ricci 
320366ba730SBruno Ricci   // We have to create it.
321366ba730SBruno Ricci   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
322366ba730SBruno Ricci   CXXConstructorNames.InsertNode(SpecialName, InsertPos);
323366ba730SBruno Ricci   return {SpecialName, DeclarationName::StoredCXXConstructorName};
324366ba730SBruno Ricci }
325366ba730SBruno Ricci 
getCXXDestructorName(CanQualType Ty)326366ba730SBruno Ricci DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
327366ba730SBruno Ricci   // The type of destructors is unqualified.
328366ba730SBruno Ricci   Ty = Ty.getUnqualifiedType();
329366ba730SBruno Ricci   // Do we already have this C++ destructor name ?
330366ba730SBruno Ricci   llvm::FoldingSetNodeID ID;
331366ba730SBruno Ricci   ID.AddPointer(Ty.getAsOpaquePtr());
332366ba730SBruno Ricci   void *InsertPos = nullptr;
333366ba730SBruno Ricci   if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
334366ba730SBruno Ricci     return {Name, DeclarationName::StoredCXXDestructorName};
335366ba730SBruno Ricci 
336366ba730SBruno Ricci   // We have to create it.
337366ba730SBruno Ricci   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
338366ba730SBruno Ricci   CXXDestructorNames.InsertNode(SpecialName, InsertPos);
339366ba730SBruno Ricci   return {SpecialName, DeclarationName::StoredCXXDestructorName};
340366ba730SBruno Ricci }
341366ba730SBruno Ricci 
34235845150SRichard Smith DeclarationName
getCXXConversionFunctionName(CanQualType Ty)343d7d2b1feSBenjamin Kramer DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
344366ba730SBruno Ricci   // Do we already have this C++ conversion function name ?
345366ba730SBruno Ricci   llvm::FoldingSetNodeID ID;
346366ba730SBruno Ricci   ID.AddPointer(Ty.getAsOpaquePtr());
347366ba730SBruno Ricci   void *InsertPos = nullptr;
348366ba730SBruno Ricci   if (auto *Name =
349366ba730SBruno Ricci           CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
350366ba730SBruno Ricci     return {Name, DeclarationName::StoredCXXConversionFunctionName};
351366ba730SBruno Ricci 
352366ba730SBruno Ricci   // We have to create it.
353366ba730SBruno Ricci   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
354366ba730SBruno Ricci   CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
355366ba730SBruno Ricci   return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
356d7d2b1feSBenjamin Kramer }
357d7d2b1feSBenjamin Kramer 
35877324f38SDouglas Gregor DeclarationName
getCXXSpecialName(DeclarationName::NameKind Kind,CanQualType Ty)35977324f38SDouglas Gregor DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
3602211d345SDouglas Gregor                                         CanQualType Ty) {
36177324f38SDouglas Gregor   switch (Kind) {
36277324f38SDouglas Gregor   case DeclarationName::CXXConstructorName:
363366ba730SBruno Ricci     return getCXXConstructorName(Ty);
36477324f38SDouglas Gregor   case DeclarationName::CXXDestructorName:
365366ba730SBruno Ricci     return getCXXDestructorName(Ty);
36677324f38SDouglas Gregor   case DeclarationName::CXXConversionFunctionName:
367366ba730SBruno Ricci     return getCXXConversionFunctionName(Ty);
36877324f38SDouglas Gregor   default:
369366ba730SBruno Ricci     llvm_unreachable("Invalid kind in getCXXSpecialName!");
37077324f38SDouglas Gregor   }
371163c5850SDouglas Gregor }
372163c5850SDouglas Gregor 
3733d221f2fSAlexis Hunt DeclarationName
getCXXLiteralOperatorName(IdentifierInfo * II)3743d221f2fSAlexis Hunt DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
375c88db065SAlexis Hunt   llvm::FoldingSetNodeID ID;
376c88db065SAlexis Hunt   ID.AddPointer(II);
377c88db065SAlexis Hunt 
37836250ad6SCraig Topper   void *InsertPos = nullptr;
379366ba730SBruno Ricci   if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
380c88db065SAlexis Hunt     return DeclarationName(Name);
381c88db065SAlexis Hunt 
382366ba730SBruno Ricci   auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
383b619883cSBruno Ricci   CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
3843d221f2fSAlexis Hunt   return DeclarationName(LiteralName);
3853d221f2fSAlexis Hunt }
3863d221f2fSAlexis Hunt 
DeclarationNameLoc(DeclarationName Name)387d6d2f189SAbramo Bagnara DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
388d6d2f189SAbramo Bagnara   switch (Name.getNameKind()) {
389d6d2f189SAbramo Bagnara   case DeclarationName::Identifier:
39035845150SRichard Smith   case DeclarationName::CXXDeductionGuideName:
391d6d2f189SAbramo Bagnara     break;
392d6d2f189SAbramo Bagnara   case DeclarationName::CXXConstructorName:
393d6d2f189SAbramo Bagnara   case DeclarationName::CXXDestructorName:
394d6d2f189SAbramo Bagnara   case DeclarationName::CXXConversionFunctionName:
39530d9ca1bSMikhail Maltsev     setNamedTypeLoc(nullptr);
396d6d2f189SAbramo Bagnara     break;
397d6d2f189SAbramo Bagnara   case DeclarationName::CXXOperatorName:
39830d9ca1bSMikhail Maltsev     setCXXOperatorNameRange(SourceRange());
399d6d2f189SAbramo Bagnara     break;
400d6d2f189SAbramo Bagnara   case DeclarationName::CXXLiteralOperatorName:
40130d9ca1bSMikhail Maltsev     setCXXLiteralOperatorNameLoc(SourceLocation());
402d6d2f189SAbramo Bagnara     break;
403d6d2f189SAbramo Bagnara   case DeclarationName::ObjCZeroArgSelector:
404d6d2f189SAbramo Bagnara   case DeclarationName::ObjCOneArgSelector:
405d6d2f189SAbramo Bagnara   case DeclarationName::ObjCMultiArgSelector:
406d6d2f189SAbramo Bagnara     // FIXME: ?
407d6d2f189SAbramo Bagnara     break;
408d6d2f189SAbramo Bagnara   case DeclarationName::CXXUsingDirective:
409d6d2f189SAbramo Bagnara     break;
410d6d2f189SAbramo Bagnara   }
411d6d2f189SAbramo Bagnara }
412d6d2f189SAbramo Bagnara 
containsUnexpandedParameterPack() const413a6e053e6SDouglas Gregor bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
414a6e053e6SDouglas Gregor   switch (Name.getNameKind()) {
415a6e053e6SDouglas Gregor   case DeclarationName::Identifier:
416a6e053e6SDouglas Gregor   case DeclarationName::ObjCZeroArgSelector:
417a6e053e6SDouglas Gregor   case DeclarationName::ObjCOneArgSelector:
418a6e053e6SDouglas Gregor   case DeclarationName::ObjCMultiArgSelector:
419a6e053e6SDouglas Gregor   case DeclarationName::CXXOperatorName:
420a6e053e6SDouglas Gregor   case DeclarationName::CXXLiteralOperatorName:
421a6e053e6SDouglas Gregor   case DeclarationName::CXXUsingDirective:
42235845150SRichard Smith   case DeclarationName::CXXDeductionGuideName:
423a6e053e6SDouglas Gregor     return false;
424a6e053e6SDouglas Gregor 
425a6e053e6SDouglas Gregor   case DeclarationName::CXXConstructorName:
426a6e053e6SDouglas Gregor   case DeclarationName::CXXDestructorName:
427a6e053e6SDouglas Gregor   case DeclarationName::CXXConversionFunctionName:
42830d9ca1bSMikhail Maltsev     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
429a6e053e6SDouglas Gregor       return TInfo->getType()->containsUnexpandedParameterPack();
430a6e053e6SDouglas Gregor 
431a6e053e6SDouglas Gregor     return Name.getCXXNameType()->containsUnexpandedParameterPack();
432a6e053e6SDouglas Gregor   }
4332b59fbe7SChandler Carruth   llvm_unreachable("All name kinds handled.");
434a6e053e6SDouglas Gregor }
435a6e053e6SDouglas Gregor 
isInstantiationDependent() const436678d76c0SDouglas Gregor bool DeclarationNameInfo::isInstantiationDependent() const {
437678d76c0SDouglas Gregor   switch (Name.getNameKind()) {
438678d76c0SDouglas Gregor   case DeclarationName::Identifier:
439678d76c0SDouglas Gregor   case DeclarationName::ObjCZeroArgSelector:
440678d76c0SDouglas Gregor   case DeclarationName::ObjCOneArgSelector:
441678d76c0SDouglas Gregor   case DeclarationName::ObjCMultiArgSelector:
442678d76c0SDouglas Gregor   case DeclarationName::CXXOperatorName:
443678d76c0SDouglas Gregor   case DeclarationName::CXXLiteralOperatorName:
444678d76c0SDouglas Gregor   case DeclarationName::CXXUsingDirective:
44535845150SRichard Smith   case DeclarationName::CXXDeductionGuideName:
446678d76c0SDouglas Gregor     return false;
447678d76c0SDouglas Gregor 
448678d76c0SDouglas Gregor   case DeclarationName::CXXConstructorName:
449678d76c0SDouglas Gregor   case DeclarationName::CXXDestructorName:
450678d76c0SDouglas Gregor   case DeclarationName::CXXConversionFunctionName:
45130d9ca1bSMikhail Maltsev     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
452678d76c0SDouglas Gregor       return TInfo->getType()->isInstantiationDependentType();
453678d76c0SDouglas Gregor 
454678d76c0SDouglas Gregor     return Name.getCXXNameType()->isInstantiationDependentType();
455678d76c0SDouglas Gregor   }
456678d76c0SDouglas Gregor   llvm_unreachable("All name kinds handled.");
457678d76c0SDouglas Gregor }
458678d76c0SDouglas Gregor 
getAsString() const459d6d2f189SAbramo Bagnara std::string DeclarationNameInfo::getAsString() const {
460d6d2f189SAbramo Bagnara   std::string Result;
461d6d2f189SAbramo Bagnara   llvm::raw_string_ostream OS(Result);
462575e09d9SSam McCall   OS << *this;
463*ad17ea12SLogan Smith   return Result;
464d6d2f189SAbramo Bagnara }
465d6d2f189SAbramo Bagnara 
operator <<(raw_ostream & OS,DeclarationNameInfo DNInfo)466575e09d9SSam McCall raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {
467575e09d9SSam McCall   LangOptions LO;
468575e09d9SSam McCall   DNInfo.printName(OS, PrintingPolicy(LangOptions()));
469575e09d9SSam McCall   return OS;
470575e09d9SSam McCall }
471575e09d9SSam McCall 
printName(raw_ostream & OS,PrintingPolicy Policy) const472575e09d9SSam McCall void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const {
473d6d2f189SAbramo Bagnara   switch (Name.getNameKind()) {
474d6d2f189SAbramo Bagnara   case DeclarationName::Identifier:
475d6d2f189SAbramo Bagnara   case DeclarationName::ObjCZeroArgSelector:
476d6d2f189SAbramo Bagnara   case DeclarationName::ObjCOneArgSelector:
477d6d2f189SAbramo Bagnara   case DeclarationName::ObjCMultiArgSelector:
478d6d2f189SAbramo Bagnara   case DeclarationName::CXXOperatorName:
479d6d2f189SAbramo Bagnara   case DeclarationName::CXXLiteralOperatorName:
480d6d2f189SAbramo Bagnara   case DeclarationName::CXXUsingDirective:
48135845150SRichard Smith   case DeclarationName::CXXDeductionGuideName:
482575e09d9SSam McCall     Name.print(OS, Policy);
483d6d2f189SAbramo Bagnara     return;
484d6d2f189SAbramo Bagnara 
485d6d2f189SAbramo Bagnara   case DeclarationName::CXXConstructorName:
486d6d2f189SAbramo Bagnara   case DeclarationName::CXXDestructorName:
487d6d2f189SAbramo Bagnara   case DeclarationName::CXXConversionFunctionName:
48830d9ca1bSMikhail Maltsev     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) {
489d6d2f189SAbramo Bagnara       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
490d6d2f189SAbramo Bagnara         OS << '~';
491d6d2f189SAbramo Bagnara       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
492d6d2f189SAbramo Bagnara         OS << "operator ";
493e81daee2SRichard Smith       LangOptions LO;
494575e09d9SSam McCall       Policy.adjustForCPlusPlus();
495575e09d9SSam McCall       Policy.SuppressScope = true;
496575e09d9SSam McCall       OS << TInfo->getType().getAsString(Policy);
497d4da8728SDavid Blaikie     } else
498575e09d9SSam McCall       Name.print(OS, Policy);
499d6d2f189SAbramo Bagnara     return;
500d6d2f189SAbramo Bagnara   }
50183d382b1SDavid Blaikie   llvm_unreachable("Unexpected declaration name kind");
502d6d2f189SAbramo Bagnara }
503d6d2f189SAbramo Bagnara 
getEndLocPrivate() const504f50288c2SStephen Kelly SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
505d6d2f189SAbramo Bagnara   switch (Name.getNameKind()) {
506d6d2f189SAbramo Bagnara   case DeclarationName::Identifier:
50735845150SRichard Smith   case DeclarationName::CXXDeductionGuideName:
508d6d2f189SAbramo Bagnara     return NameLoc;
509d6d2f189SAbramo Bagnara 
51030d9ca1bSMikhail Maltsev   case DeclarationName::CXXOperatorName:
51130d9ca1bSMikhail Maltsev     return LocInfo.getCXXOperatorNameEndLoc();
512d6d2f189SAbramo Bagnara 
51330d9ca1bSMikhail Maltsev   case DeclarationName::CXXLiteralOperatorName:
51430d9ca1bSMikhail Maltsev     return LocInfo.getCXXLiteralOperatorNameLoc();
515d6d2f189SAbramo Bagnara 
516d6d2f189SAbramo Bagnara   case DeclarationName::CXXConstructorName:
517d6d2f189SAbramo Bagnara   case DeclarationName::CXXDestructorName:
518d6d2f189SAbramo Bagnara   case DeclarationName::CXXConversionFunctionName:
51930d9ca1bSMikhail Maltsev     if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
520d6d2f189SAbramo Bagnara       return TInfo->getTypeLoc().getEndLoc();
521d6d2f189SAbramo Bagnara     else
522d6d2f189SAbramo Bagnara       return NameLoc;
523d6d2f189SAbramo Bagnara 
524d6d2f189SAbramo Bagnara     // DNInfo work in progress: FIXME.
525d6d2f189SAbramo Bagnara   case DeclarationName::ObjCZeroArgSelector:
526d6d2f189SAbramo Bagnara   case DeclarationName::ObjCOneArgSelector:
527d6d2f189SAbramo Bagnara   case DeclarationName::ObjCMultiArgSelector:
528d6d2f189SAbramo Bagnara   case DeclarationName::CXXUsingDirective:
529d6d2f189SAbramo Bagnara     return NameLoc;
530d6d2f189SAbramo Bagnara   }
53183d382b1SDavid Blaikie   llvm_unreachable("Unexpected declaration name kind");
532d6d2f189SAbramo Bagnara }
533