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