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