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