1f4a2713aSLionel Sambuc //===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the DeclarationName and DeclarationNameTable
11f4a2713aSLionel Sambuc // classes.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
15f4a2713aSLionel Sambuc #include "clang/AST/Decl.h"
16f4a2713aSLionel Sambuc #include "clang/AST/DeclarationName.h"
17f4a2713aSLionel Sambuc #include "clang/AST/Type.h"
18f4a2713aSLionel Sambuc #include "clang/AST/TypeLoc.h"
19f4a2713aSLionel Sambuc #include "clang/AST/TypeOrdering.h"
20f4a2713aSLionel Sambuc #include "clang/Basic/IdentifierTable.h"
21f4a2713aSLionel Sambuc #include "llvm/ADT/DenseMap.h"
22f4a2713aSLionel Sambuc #include "llvm/ADT/FoldingSet.h"
23f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
24f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
25f4a2713aSLionel Sambuc using namespace clang;
26f4a2713aSLionel Sambuc
27f4a2713aSLionel Sambuc namespace clang {
28f4a2713aSLionel Sambuc /// CXXSpecialName - Records the type associated with one of the
29f4a2713aSLionel Sambuc /// "special" kinds of declaration names in C++, e.g., constructors,
30f4a2713aSLionel Sambuc /// destructors, and conversion functions.
31f4a2713aSLionel Sambuc class CXXSpecialName
32f4a2713aSLionel Sambuc : public DeclarationNameExtra, public llvm::FoldingSetNode {
33f4a2713aSLionel Sambuc public:
34f4a2713aSLionel Sambuc /// Type - The type associated with this declaration name.
35f4a2713aSLionel Sambuc QualType Type;
36f4a2713aSLionel Sambuc
37f4a2713aSLionel Sambuc /// FETokenInfo - Extra information associated with this declaration
38f4a2713aSLionel Sambuc /// name that can be used by the front end.
39f4a2713aSLionel Sambuc void *FETokenInfo;
40f4a2713aSLionel Sambuc
Profile(llvm::FoldingSetNodeID & ID)41f4a2713aSLionel Sambuc void Profile(llvm::FoldingSetNodeID &ID) {
42f4a2713aSLionel Sambuc ID.AddInteger(ExtraKindOrNumArgs);
43f4a2713aSLionel Sambuc ID.AddPointer(Type.getAsOpaquePtr());
44f4a2713aSLionel Sambuc }
45f4a2713aSLionel Sambuc };
46f4a2713aSLionel Sambuc
47f4a2713aSLionel Sambuc /// CXXOperatorIdName - Contains extra information for the name of an
48f4a2713aSLionel Sambuc /// overloaded operator in C++, such as "operator+.
49f4a2713aSLionel Sambuc class CXXOperatorIdName : public DeclarationNameExtra {
50f4a2713aSLionel Sambuc public:
51f4a2713aSLionel Sambuc /// FETokenInfo - Extra information associated with this operator
52f4a2713aSLionel Sambuc /// name that can be used by the front end.
53f4a2713aSLionel Sambuc void *FETokenInfo;
54f4a2713aSLionel Sambuc };
55f4a2713aSLionel Sambuc
56f4a2713aSLionel Sambuc /// CXXLiteralOperatorName - Contains the actual identifier that makes up the
57f4a2713aSLionel Sambuc /// name.
58f4a2713aSLionel Sambuc ///
59f4a2713aSLionel Sambuc /// This identifier is stored here rather than directly in DeclarationName so as
60f4a2713aSLionel Sambuc /// to allow Objective-C selectors, which are about a million times more common,
61f4a2713aSLionel Sambuc /// to consume minimal memory.
62f4a2713aSLionel Sambuc class CXXLiteralOperatorIdName
63f4a2713aSLionel Sambuc : public DeclarationNameExtra, public llvm::FoldingSetNode {
64f4a2713aSLionel Sambuc public:
65f4a2713aSLionel Sambuc IdentifierInfo *ID;
66f4a2713aSLionel Sambuc
67f4a2713aSLionel Sambuc /// FETokenInfo - Extra information associated with this operator
68f4a2713aSLionel Sambuc /// name that can be used by the front end.
69f4a2713aSLionel Sambuc void *FETokenInfo;
70f4a2713aSLionel Sambuc
Profile(llvm::FoldingSetNodeID & FSID)71f4a2713aSLionel Sambuc void Profile(llvm::FoldingSetNodeID &FSID) {
72f4a2713aSLionel Sambuc FSID.AddPointer(ID);
73f4a2713aSLionel Sambuc }
74f4a2713aSLionel Sambuc };
75f4a2713aSLionel Sambuc
compareInt(unsigned A,unsigned B)76f4a2713aSLionel Sambuc static int compareInt(unsigned A, unsigned B) {
77f4a2713aSLionel Sambuc return (A < B ? -1 : (A > B ? 1 : 0));
78f4a2713aSLionel Sambuc }
79f4a2713aSLionel Sambuc
compare(DeclarationName LHS,DeclarationName RHS)80f4a2713aSLionel Sambuc int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
81f4a2713aSLionel Sambuc if (LHS.getNameKind() != RHS.getNameKind())
82f4a2713aSLionel Sambuc return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
83f4a2713aSLionel Sambuc
84f4a2713aSLionel Sambuc switch (LHS.getNameKind()) {
85f4a2713aSLionel Sambuc case DeclarationName::Identifier: {
86f4a2713aSLionel Sambuc IdentifierInfo *LII = LHS.getAsIdentifierInfo();
87f4a2713aSLionel Sambuc IdentifierInfo *RII = RHS.getAsIdentifierInfo();
88f4a2713aSLionel Sambuc if (!LII) return RII ? -1 : 0;
89f4a2713aSLionel Sambuc if (!RII) return 1;
90f4a2713aSLionel Sambuc
91f4a2713aSLionel Sambuc return LII->getName().compare(RII->getName());
92f4a2713aSLionel Sambuc }
93f4a2713aSLionel Sambuc
94f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
95f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
96f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector: {
97f4a2713aSLionel Sambuc Selector LHSSelector = LHS.getObjCSelector();
98f4a2713aSLionel Sambuc Selector RHSSelector = RHS.getObjCSelector();
99f4a2713aSLionel Sambuc unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
100f4a2713aSLionel Sambuc for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
101f4a2713aSLionel Sambuc switch (LHSSelector.getNameForSlot(I).compare(
102f4a2713aSLionel Sambuc RHSSelector.getNameForSlot(I))) {
103f4a2713aSLionel Sambuc case -1: return true;
104f4a2713aSLionel Sambuc case 1: return false;
105f4a2713aSLionel Sambuc default: break;
106f4a2713aSLionel Sambuc }
107f4a2713aSLionel Sambuc }
108f4a2713aSLionel Sambuc
109f4a2713aSLionel Sambuc return compareInt(LN, RN);
110f4a2713aSLionel Sambuc }
111f4a2713aSLionel Sambuc
112f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
113f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
114f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
115f4a2713aSLionel Sambuc if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
116f4a2713aSLionel Sambuc return -1;
117f4a2713aSLionel Sambuc if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
118f4a2713aSLionel Sambuc return 1;
119f4a2713aSLionel Sambuc return 0;
120f4a2713aSLionel Sambuc
121f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
122f4a2713aSLionel Sambuc return compareInt(LHS.getCXXOverloadedOperator(),
123f4a2713aSLionel Sambuc RHS.getCXXOverloadedOperator());
124f4a2713aSLionel Sambuc
125f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
126f4a2713aSLionel Sambuc return LHS.getCXXLiteralIdentifier()->getName().compare(
127f4a2713aSLionel Sambuc RHS.getCXXLiteralIdentifier()->getName());
128f4a2713aSLionel Sambuc
129f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
130f4a2713aSLionel Sambuc return 0;
131f4a2713aSLionel Sambuc }
132f4a2713aSLionel Sambuc
133f4a2713aSLionel Sambuc llvm_unreachable("Invalid DeclarationName Kind!");
134f4a2713aSLionel Sambuc }
135f4a2713aSLionel Sambuc
operator <<(raw_ostream & OS,DeclarationName N)136f4a2713aSLionel Sambuc raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
137f4a2713aSLionel Sambuc switch (N.getNameKind()) {
138f4a2713aSLionel Sambuc case DeclarationName::Identifier:
139f4a2713aSLionel Sambuc if (const IdentifierInfo *II = N.getAsIdentifierInfo())
140f4a2713aSLionel Sambuc OS << II->getName();
141f4a2713aSLionel Sambuc return OS;
142f4a2713aSLionel Sambuc
143f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
144f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
145f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
146*0a6a1f1dSLionel Sambuc N.getObjCSelector().print(OS);
147*0a6a1f1dSLionel Sambuc return OS;
148f4a2713aSLionel Sambuc
149f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName: {
150f4a2713aSLionel Sambuc QualType ClassType = N.getCXXNameType();
151f4a2713aSLionel Sambuc if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
152f4a2713aSLionel Sambuc return OS << *ClassRec->getDecl();
153*0a6a1f1dSLionel Sambuc LangOptions LO;
154*0a6a1f1dSLionel Sambuc LO.CPlusPlus = true;
155*0a6a1f1dSLionel Sambuc return OS << ClassType.getAsString(PrintingPolicy(LO));
156f4a2713aSLionel Sambuc }
157f4a2713aSLionel Sambuc
158f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName: {
159f4a2713aSLionel Sambuc OS << '~';
160f4a2713aSLionel Sambuc QualType Type = N.getCXXNameType();
161f4a2713aSLionel Sambuc if (const RecordType *Rec = Type->getAs<RecordType>())
162f4a2713aSLionel Sambuc return OS << *Rec->getDecl();
163*0a6a1f1dSLionel Sambuc LangOptions LO;
164*0a6a1f1dSLionel Sambuc LO.CPlusPlus = true;
165*0a6a1f1dSLionel Sambuc return OS << Type.getAsString(PrintingPolicy(LO));
166f4a2713aSLionel Sambuc }
167f4a2713aSLionel Sambuc
168f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName: {
169f4a2713aSLionel Sambuc static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
170*0a6a1f1dSLionel Sambuc nullptr,
171f4a2713aSLionel Sambuc #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
172f4a2713aSLionel Sambuc Spelling,
173f4a2713aSLionel Sambuc #include "clang/Basic/OperatorKinds.def"
174f4a2713aSLionel Sambuc };
175f4a2713aSLionel Sambuc const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
176f4a2713aSLionel Sambuc assert(OpName && "not an overloaded operator");
177f4a2713aSLionel Sambuc
178f4a2713aSLionel Sambuc OS << "operator";
179f4a2713aSLionel Sambuc if (OpName[0] >= 'a' && OpName[0] <= 'z')
180f4a2713aSLionel Sambuc OS << ' ';
181f4a2713aSLionel Sambuc return OS << OpName;
182f4a2713aSLionel Sambuc }
183f4a2713aSLionel Sambuc
184f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
185f4a2713aSLionel Sambuc return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
186f4a2713aSLionel Sambuc
187f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName: {
188f4a2713aSLionel Sambuc OS << "operator ";
189f4a2713aSLionel Sambuc QualType Type = N.getCXXNameType();
190f4a2713aSLionel Sambuc if (const RecordType *Rec = Type->getAs<RecordType>())
191f4a2713aSLionel Sambuc return OS << *Rec->getDecl();
192*0a6a1f1dSLionel Sambuc LangOptions LO;
193*0a6a1f1dSLionel Sambuc LO.CPlusPlus = true;
194*0a6a1f1dSLionel Sambuc LO.Bool = true;
195*0a6a1f1dSLionel Sambuc return OS << Type.getAsString(PrintingPolicy(LO));
196f4a2713aSLionel Sambuc }
197f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
198f4a2713aSLionel Sambuc return OS << "<using-directive>";
199f4a2713aSLionel Sambuc }
200f4a2713aSLionel Sambuc
201f4a2713aSLionel Sambuc llvm_unreachable("Unexpected declaration name kind");
202f4a2713aSLionel Sambuc }
203f4a2713aSLionel Sambuc
204f4a2713aSLionel Sambuc } // end namespace clang
205f4a2713aSLionel Sambuc
getNameKind() const206f4a2713aSLionel Sambuc DeclarationName::NameKind DeclarationName::getNameKind() const {
207f4a2713aSLionel Sambuc switch (getStoredNameKind()) {
208f4a2713aSLionel Sambuc case StoredIdentifier: return Identifier;
209f4a2713aSLionel Sambuc case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
210f4a2713aSLionel Sambuc case StoredObjCOneArgSelector: return ObjCOneArgSelector;
211f4a2713aSLionel Sambuc
212f4a2713aSLionel Sambuc case StoredDeclarationNameExtra:
213f4a2713aSLionel Sambuc switch (getExtra()->ExtraKindOrNumArgs) {
214f4a2713aSLionel Sambuc case DeclarationNameExtra::CXXConstructor:
215f4a2713aSLionel Sambuc return CXXConstructorName;
216f4a2713aSLionel Sambuc
217f4a2713aSLionel Sambuc case DeclarationNameExtra::CXXDestructor:
218f4a2713aSLionel Sambuc return CXXDestructorName;
219f4a2713aSLionel Sambuc
220f4a2713aSLionel Sambuc case DeclarationNameExtra::CXXConversionFunction:
221f4a2713aSLionel Sambuc return CXXConversionFunctionName;
222f4a2713aSLionel Sambuc
223f4a2713aSLionel Sambuc case DeclarationNameExtra::CXXLiteralOperator:
224f4a2713aSLionel Sambuc return CXXLiteralOperatorName;
225f4a2713aSLionel Sambuc
226f4a2713aSLionel Sambuc case DeclarationNameExtra::CXXUsingDirective:
227f4a2713aSLionel Sambuc return CXXUsingDirective;
228f4a2713aSLionel Sambuc
229f4a2713aSLionel Sambuc default:
230f4a2713aSLionel Sambuc // Check if we have one of the CXXOperator* enumeration values.
231f4a2713aSLionel Sambuc if (getExtra()->ExtraKindOrNumArgs <
232f4a2713aSLionel Sambuc DeclarationNameExtra::CXXUsingDirective)
233f4a2713aSLionel Sambuc return CXXOperatorName;
234f4a2713aSLionel Sambuc
235f4a2713aSLionel Sambuc return ObjCMultiArgSelector;
236f4a2713aSLionel Sambuc }
237f4a2713aSLionel Sambuc }
238f4a2713aSLionel Sambuc
239f4a2713aSLionel Sambuc // Can't actually get here.
240f4a2713aSLionel Sambuc llvm_unreachable("This should be unreachable!");
241f4a2713aSLionel Sambuc }
242f4a2713aSLionel Sambuc
isDependentName() const243f4a2713aSLionel Sambuc bool DeclarationName::isDependentName() const {
244f4a2713aSLionel Sambuc QualType T = getCXXNameType();
245f4a2713aSLionel Sambuc return !T.isNull() && T->isDependentType();
246f4a2713aSLionel Sambuc }
247f4a2713aSLionel Sambuc
getAsString() const248f4a2713aSLionel Sambuc std::string DeclarationName::getAsString() const {
249f4a2713aSLionel Sambuc std::string Result;
250f4a2713aSLionel Sambuc llvm::raw_string_ostream OS(Result);
251f4a2713aSLionel Sambuc OS << *this;
252f4a2713aSLionel Sambuc return OS.str();
253f4a2713aSLionel Sambuc }
254f4a2713aSLionel Sambuc
getCXXNameType() const255f4a2713aSLionel Sambuc QualType DeclarationName::getCXXNameType() const {
256f4a2713aSLionel Sambuc if (CXXSpecialName *CXXName = getAsCXXSpecialName())
257f4a2713aSLionel Sambuc return CXXName->Type;
258f4a2713aSLionel Sambuc else
259f4a2713aSLionel Sambuc return QualType();
260f4a2713aSLionel Sambuc }
261f4a2713aSLionel Sambuc
getCXXOverloadedOperator() const262f4a2713aSLionel Sambuc OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
263f4a2713aSLionel Sambuc if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
264f4a2713aSLionel Sambuc unsigned value
265f4a2713aSLionel Sambuc = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
266f4a2713aSLionel Sambuc return static_cast<OverloadedOperatorKind>(value);
267f4a2713aSLionel Sambuc } else {
268f4a2713aSLionel Sambuc return OO_None;
269f4a2713aSLionel Sambuc }
270f4a2713aSLionel Sambuc }
271f4a2713aSLionel Sambuc
getCXXLiteralIdentifier() const272f4a2713aSLionel Sambuc IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
273f4a2713aSLionel Sambuc if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
274f4a2713aSLionel Sambuc return CXXLit->ID;
275f4a2713aSLionel Sambuc else
276*0a6a1f1dSLionel Sambuc return nullptr;
277f4a2713aSLionel Sambuc }
278f4a2713aSLionel Sambuc
getFETokenInfoAsVoidSlow() const279f4a2713aSLionel Sambuc void *DeclarationName::getFETokenInfoAsVoidSlow() const {
280f4a2713aSLionel Sambuc switch (getNameKind()) {
281f4a2713aSLionel Sambuc case Identifier:
282f4a2713aSLionel Sambuc llvm_unreachable("Handled by getFETokenInfo()");
283f4a2713aSLionel Sambuc
284f4a2713aSLionel Sambuc case CXXConstructorName:
285f4a2713aSLionel Sambuc case CXXDestructorName:
286f4a2713aSLionel Sambuc case CXXConversionFunctionName:
287f4a2713aSLionel Sambuc return getAsCXXSpecialName()->FETokenInfo;
288f4a2713aSLionel Sambuc
289f4a2713aSLionel Sambuc case CXXOperatorName:
290f4a2713aSLionel Sambuc return getAsCXXOperatorIdName()->FETokenInfo;
291f4a2713aSLionel Sambuc
292f4a2713aSLionel Sambuc case CXXLiteralOperatorName:
293f4a2713aSLionel Sambuc return getAsCXXLiteralOperatorIdName()->FETokenInfo;
294f4a2713aSLionel Sambuc
295f4a2713aSLionel Sambuc default:
296f4a2713aSLionel Sambuc llvm_unreachable("Declaration name has no FETokenInfo");
297f4a2713aSLionel Sambuc }
298f4a2713aSLionel Sambuc }
299f4a2713aSLionel Sambuc
setFETokenInfo(void * T)300f4a2713aSLionel Sambuc void DeclarationName::setFETokenInfo(void *T) {
301f4a2713aSLionel Sambuc switch (getNameKind()) {
302f4a2713aSLionel Sambuc case Identifier:
303f4a2713aSLionel Sambuc getAsIdentifierInfo()->setFETokenInfo(T);
304f4a2713aSLionel Sambuc break;
305f4a2713aSLionel Sambuc
306f4a2713aSLionel Sambuc case CXXConstructorName:
307f4a2713aSLionel Sambuc case CXXDestructorName:
308f4a2713aSLionel Sambuc case CXXConversionFunctionName:
309f4a2713aSLionel Sambuc getAsCXXSpecialName()->FETokenInfo = T;
310f4a2713aSLionel Sambuc break;
311f4a2713aSLionel Sambuc
312f4a2713aSLionel Sambuc case CXXOperatorName:
313f4a2713aSLionel Sambuc getAsCXXOperatorIdName()->FETokenInfo = T;
314f4a2713aSLionel Sambuc break;
315f4a2713aSLionel Sambuc
316f4a2713aSLionel Sambuc case CXXLiteralOperatorName:
317f4a2713aSLionel Sambuc getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
318f4a2713aSLionel Sambuc break;
319f4a2713aSLionel Sambuc
320f4a2713aSLionel Sambuc default:
321f4a2713aSLionel Sambuc llvm_unreachable("Declaration name has no FETokenInfo");
322f4a2713aSLionel Sambuc }
323f4a2713aSLionel Sambuc }
324f4a2713aSLionel Sambuc
getUsingDirectiveName()325f4a2713aSLionel Sambuc DeclarationName DeclarationName::getUsingDirectiveName() {
326f4a2713aSLionel Sambuc // Single instance of DeclarationNameExtra for using-directive
327f4a2713aSLionel Sambuc static const DeclarationNameExtra UDirExtra =
328f4a2713aSLionel Sambuc { DeclarationNameExtra::CXXUsingDirective };
329f4a2713aSLionel Sambuc
330f4a2713aSLionel Sambuc uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
331f4a2713aSLionel Sambuc Ptr |= StoredDeclarationNameExtra;
332f4a2713aSLionel Sambuc
333f4a2713aSLionel Sambuc return DeclarationName(Ptr);
334f4a2713aSLionel Sambuc }
335f4a2713aSLionel Sambuc
dump() const336f4a2713aSLionel Sambuc void DeclarationName::dump() const {
337f4a2713aSLionel Sambuc llvm::errs() << *this << '\n';
338f4a2713aSLionel Sambuc }
339f4a2713aSLionel Sambuc
DeclarationNameTable(const ASTContext & C)340f4a2713aSLionel Sambuc DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
341f4a2713aSLionel Sambuc CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
342f4a2713aSLionel Sambuc CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
343f4a2713aSLionel Sambuc
344f4a2713aSLionel Sambuc // Initialize the overloaded operator names.
345f4a2713aSLionel Sambuc CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
346f4a2713aSLionel Sambuc for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
347f4a2713aSLionel Sambuc CXXOperatorNames[Op].ExtraKindOrNumArgs
348f4a2713aSLionel Sambuc = Op + DeclarationNameExtra::CXXConversionFunction;
349*0a6a1f1dSLionel Sambuc CXXOperatorNames[Op].FETokenInfo = nullptr;
350f4a2713aSLionel Sambuc }
351f4a2713aSLionel Sambuc }
352f4a2713aSLionel Sambuc
~DeclarationNameTable()353f4a2713aSLionel Sambuc DeclarationNameTable::~DeclarationNameTable() {
354f4a2713aSLionel Sambuc llvm::FoldingSet<CXXSpecialName> *SpecialNames =
355f4a2713aSLionel Sambuc static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
356f4a2713aSLionel Sambuc llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
357f4a2713aSLionel Sambuc = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
358f4a2713aSLionel Sambuc (CXXLiteralOperatorNames);
359f4a2713aSLionel Sambuc
360f4a2713aSLionel Sambuc delete SpecialNames;
361f4a2713aSLionel Sambuc delete LiteralNames;
362f4a2713aSLionel Sambuc }
363f4a2713aSLionel Sambuc
getCXXConstructorName(CanQualType Ty)364f4a2713aSLionel Sambuc DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
365f4a2713aSLionel Sambuc return getCXXSpecialName(DeclarationName::CXXConstructorName,
366f4a2713aSLionel Sambuc Ty.getUnqualifiedType());
367f4a2713aSLionel Sambuc }
368f4a2713aSLionel Sambuc
getCXXDestructorName(CanQualType Ty)369f4a2713aSLionel Sambuc DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
370f4a2713aSLionel Sambuc return getCXXSpecialName(DeclarationName::CXXDestructorName,
371f4a2713aSLionel Sambuc Ty.getUnqualifiedType());
372f4a2713aSLionel Sambuc }
373f4a2713aSLionel Sambuc
374f4a2713aSLionel Sambuc DeclarationName
getCXXConversionFunctionName(CanQualType Ty)375f4a2713aSLionel Sambuc DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
376f4a2713aSLionel Sambuc return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
377f4a2713aSLionel Sambuc }
378f4a2713aSLionel Sambuc
379f4a2713aSLionel Sambuc DeclarationName
getCXXSpecialName(DeclarationName::NameKind Kind,CanQualType Ty)380f4a2713aSLionel Sambuc DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
381f4a2713aSLionel Sambuc CanQualType Ty) {
382f4a2713aSLionel Sambuc assert(Kind >= DeclarationName::CXXConstructorName &&
383f4a2713aSLionel Sambuc Kind <= DeclarationName::CXXConversionFunctionName &&
384f4a2713aSLionel Sambuc "Kind must be a C++ special name kind");
385f4a2713aSLionel Sambuc llvm::FoldingSet<CXXSpecialName> *SpecialNames
386f4a2713aSLionel Sambuc = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
387f4a2713aSLionel Sambuc
388f4a2713aSLionel Sambuc DeclarationNameExtra::ExtraKind EKind;
389f4a2713aSLionel Sambuc switch (Kind) {
390f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
391f4a2713aSLionel Sambuc EKind = DeclarationNameExtra::CXXConstructor;
392f4a2713aSLionel Sambuc assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
393f4a2713aSLionel Sambuc break;
394f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
395f4a2713aSLionel Sambuc EKind = DeclarationNameExtra::CXXDestructor;
396f4a2713aSLionel Sambuc assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
397f4a2713aSLionel Sambuc break;
398f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
399f4a2713aSLionel Sambuc EKind = DeclarationNameExtra::CXXConversionFunction;
400f4a2713aSLionel Sambuc break;
401f4a2713aSLionel Sambuc default:
402f4a2713aSLionel Sambuc return DeclarationName();
403f4a2713aSLionel Sambuc }
404f4a2713aSLionel Sambuc
405f4a2713aSLionel Sambuc // Unique selector, to guarantee there is one per name.
406f4a2713aSLionel Sambuc llvm::FoldingSetNodeID ID;
407f4a2713aSLionel Sambuc ID.AddInteger(EKind);
408f4a2713aSLionel Sambuc ID.AddPointer(Ty.getAsOpaquePtr());
409f4a2713aSLionel Sambuc
410*0a6a1f1dSLionel Sambuc void *InsertPos = nullptr;
411f4a2713aSLionel Sambuc if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
412f4a2713aSLionel Sambuc return DeclarationName(Name);
413f4a2713aSLionel Sambuc
414f4a2713aSLionel Sambuc CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
415f4a2713aSLionel Sambuc SpecialName->ExtraKindOrNumArgs = EKind;
416f4a2713aSLionel Sambuc SpecialName->Type = Ty;
417*0a6a1f1dSLionel Sambuc SpecialName->FETokenInfo = nullptr;
418f4a2713aSLionel Sambuc
419f4a2713aSLionel Sambuc SpecialNames->InsertNode(SpecialName, InsertPos);
420f4a2713aSLionel Sambuc return DeclarationName(SpecialName);
421f4a2713aSLionel Sambuc }
422f4a2713aSLionel Sambuc
423f4a2713aSLionel Sambuc DeclarationName
getCXXOperatorName(OverloadedOperatorKind Op)424f4a2713aSLionel Sambuc DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
425f4a2713aSLionel Sambuc return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
426f4a2713aSLionel Sambuc }
427f4a2713aSLionel Sambuc
428f4a2713aSLionel Sambuc DeclarationName
getCXXLiteralOperatorName(IdentifierInfo * II)429f4a2713aSLionel Sambuc DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
430f4a2713aSLionel Sambuc llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
431f4a2713aSLionel Sambuc = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
432f4a2713aSLionel Sambuc (CXXLiteralOperatorNames);
433f4a2713aSLionel Sambuc
434f4a2713aSLionel Sambuc llvm::FoldingSetNodeID ID;
435f4a2713aSLionel Sambuc ID.AddPointer(II);
436f4a2713aSLionel Sambuc
437*0a6a1f1dSLionel Sambuc void *InsertPos = nullptr;
438f4a2713aSLionel Sambuc if (CXXLiteralOperatorIdName *Name =
439f4a2713aSLionel Sambuc LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
440f4a2713aSLionel Sambuc return DeclarationName (Name);
441f4a2713aSLionel Sambuc
442f4a2713aSLionel Sambuc CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
443f4a2713aSLionel Sambuc LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
444f4a2713aSLionel Sambuc LiteralName->ID = II;
445*0a6a1f1dSLionel Sambuc LiteralName->FETokenInfo = nullptr;
446f4a2713aSLionel Sambuc
447f4a2713aSLionel Sambuc LiteralNames->InsertNode(LiteralName, InsertPos);
448f4a2713aSLionel Sambuc return DeclarationName(LiteralName);
449f4a2713aSLionel Sambuc }
450f4a2713aSLionel Sambuc
DeclarationNameLoc(DeclarationName Name)451f4a2713aSLionel Sambuc DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
452f4a2713aSLionel Sambuc switch (Name.getNameKind()) {
453f4a2713aSLionel Sambuc case DeclarationName::Identifier:
454f4a2713aSLionel Sambuc break;
455f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
456f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
457f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
458*0a6a1f1dSLionel Sambuc NamedType.TInfo = nullptr;
459f4a2713aSLionel Sambuc break;
460f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
461f4a2713aSLionel Sambuc CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
462f4a2713aSLionel Sambuc CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
463f4a2713aSLionel Sambuc break;
464f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
465f4a2713aSLionel Sambuc CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
466f4a2713aSLionel Sambuc break;
467f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
468f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
469f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
470f4a2713aSLionel Sambuc // FIXME: ?
471f4a2713aSLionel Sambuc break;
472f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
473f4a2713aSLionel Sambuc break;
474f4a2713aSLionel Sambuc }
475f4a2713aSLionel Sambuc }
476f4a2713aSLionel Sambuc
containsUnexpandedParameterPack() const477f4a2713aSLionel Sambuc bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
478f4a2713aSLionel Sambuc switch (Name.getNameKind()) {
479f4a2713aSLionel Sambuc case DeclarationName::Identifier:
480f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
481f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
482f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
483f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
484f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
485f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
486f4a2713aSLionel Sambuc return false;
487f4a2713aSLionel Sambuc
488f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
489f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
490f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
491f4a2713aSLionel Sambuc if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
492f4a2713aSLionel Sambuc return TInfo->getType()->containsUnexpandedParameterPack();
493f4a2713aSLionel Sambuc
494f4a2713aSLionel Sambuc return Name.getCXXNameType()->containsUnexpandedParameterPack();
495f4a2713aSLionel Sambuc }
496f4a2713aSLionel Sambuc llvm_unreachable("All name kinds handled.");
497f4a2713aSLionel Sambuc }
498f4a2713aSLionel Sambuc
isInstantiationDependent() const499f4a2713aSLionel Sambuc bool DeclarationNameInfo::isInstantiationDependent() const {
500f4a2713aSLionel Sambuc switch (Name.getNameKind()) {
501f4a2713aSLionel Sambuc case DeclarationName::Identifier:
502f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
503f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
504f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
505f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
506f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
507f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
508f4a2713aSLionel Sambuc return false;
509f4a2713aSLionel Sambuc
510f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
511f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
512f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
513f4a2713aSLionel Sambuc if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
514f4a2713aSLionel Sambuc return TInfo->getType()->isInstantiationDependentType();
515f4a2713aSLionel Sambuc
516f4a2713aSLionel Sambuc return Name.getCXXNameType()->isInstantiationDependentType();
517f4a2713aSLionel Sambuc }
518f4a2713aSLionel Sambuc llvm_unreachable("All name kinds handled.");
519f4a2713aSLionel Sambuc }
520f4a2713aSLionel Sambuc
getAsString() const521f4a2713aSLionel Sambuc std::string DeclarationNameInfo::getAsString() const {
522f4a2713aSLionel Sambuc std::string Result;
523f4a2713aSLionel Sambuc llvm::raw_string_ostream OS(Result);
524f4a2713aSLionel Sambuc printName(OS);
525f4a2713aSLionel Sambuc return OS.str();
526f4a2713aSLionel Sambuc }
527f4a2713aSLionel Sambuc
printName(raw_ostream & OS) const528f4a2713aSLionel Sambuc void DeclarationNameInfo::printName(raw_ostream &OS) const {
529f4a2713aSLionel Sambuc switch (Name.getNameKind()) {
530f4a2713aSLionel Sambuc case DeclarationName::Identifier:
531f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
532f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
533f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
534f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
535f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName:
536f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
537f4a2713aSLionel Sambuc OS << Name;
538f4a2713aSLionel Sambuc return;
539f4a2713aSLionel Sambuc
540f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
541f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
542f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
543f4a2713aSLionel Sambuc if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
544f4a2713aSLionel Sambuc if (Name.getNameKind() == DeclarationName::CXXDestructorName)
545f4a2713aSLionel Sambuc OS << '~';
546f4a2713aSLionel Sambuc else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
547f4a2713aSLionel Sambuc OS << "operator ";
548*0a6a1f1dSLionel Sambuc LangOptions LO;
549*0a6a1f1dSLionel Sambuc LO.CPlusPlus = true;
550*0a6a1f1dSLionel Sambuc LO.Bool = true;
551*0a6a1f1dSLionel Sambuc OS << TInfo->getType().getAsString(PrintingPolicy(LO));
552f4a2713aSLionel Sambuc } else
553f4a2713aSLionel Sambuc OS << Name;
554f4a2713aSLionel Sambuc return;
555f4a2713aSLionel Sambuc }
556f4a2713aSLionel Sambuc llvm_unreachable("Unexpected declaration name kind");
557f4a2713aSLionel Sambuc }
558f4a2713aSLionel Sambuc
getEndLoc() const559f4a2713aSLionel Sambuc SourceLocation DeclarationNameInfo::getEndLoc() const {
560f4a2713aSLionel Sambuc switch (Name.getNameKind()) {
561f4a2713aSLionel Sambuc case DeclarationName::Identifier:
562f4a2713aSLionel Sambuc return NameLoc;
563f4a2713aSLionel Sambuc
564f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName: {
565f4a2713aSLionel Sambuc unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
566f4a2713aSLionel Sambuc return SourceLocation::getFromRawEncoding(raw);
567f4a2713aSLionel Sambuc }
568f4a2713aSLionel Sambuc
569f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName: {
570f4a2713aSLionel Sambuc unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
571f4a2713aSLionel Sambuc return SourceLocation::getFromRawEncoding(raw);
572f4a2713aSLionel Sambuc }
573f4a2713aSLionel Sambuc
574f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
575f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
576f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
577f4a2713aSLionel Sambuc if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
578f4a2713aSLionel Sambuc return TInfo->getTypeLoc().getEndLoc();
579f4a2713aSLionel Sambuc else
580f4a2713aSLionel Sambuc return NameLoc;
581f4a2713aSLionel Sambuc
582f4a2713aSLionel Sambuc // DNInfo work in progress: FIXME.
583f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
584f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
585f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
586f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
587f4a2713aSLionel Sambuc return NameLoc;
588f4a2713aSLionel Sambuc }
589f4a2713aSLionel Sambuc llvm_unreachable("Unexpected declaration name kind");
590f4a2713aSLionel Sambuc }
591