blob: 1fa2010786413cb3ec6afba0b703d067bf4e33c0 [file] [log] [blame]
Douglas Gregor2e1cd422008-11-17 14:58:09 +00001//===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the DeclarationName and DeclarationNameTable
11// classes.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/AST/DeclarationName.h"
Douglas Gregor10bd3682008-11-17 22:58:34 +000015#include "clang/AST/Type.h"
Douglas Gregord6b5f132009-11-04 22:24:30 +000016#include "clang/AST/TypeOrdering.h"
Douglas Gregor10bd3682008-11-17 22:58:34 +000017#include "clang/AST/Decl.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000018#include "clang/Basic/IdentifierTable.h"
Douglas Gregor370187c2009-04-22 21:45:53 +000019#include "llvm/ADT/DenseMap.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000020#include "llvm/ADT/FoldingSet.h"
Chandler Carruth894993f2009-11-15 23:10:57 +000021#include <cstdio>
Douglas Gregor2e1cd422008-11-17 14:58:09 +000022using namespace clang;
23
24namespace clang {
25/// CXXSpecialName - Records the type associated with one of the
26/// "special" kinds of declaration names in C++, e.g., constructors,
27/// destructors, and conversion functions.
Mike Stump1eb44332009-09-09 15:08:12 +000028class CXXSpecialName
Douglas Gregor2e1cd422008-11-17 14:58:09 +000029 : public DeclarationNameExtra, public llvm::FoldingSetNode {
30public:
Douglas Gregor2def4832008-11-17 20:34:05 +000031 /// Type - The type associated with this declaration name.
Douglas Gregor2e1cd422008-11-17 14:58:09 +000032 QualType Type;
33
Douglas Gregor2def4832008-11-17 20:34:05 +000034 /// FETokenInfo - Extra information associated with this declaration
35 /// name that can be used by the front end.
36 void *FETokenInfo;
37
Douglas Gregor2e1cd422008-11-17 14:58:09 +000038 void Profile(llvm::FoldingSetNodeID &ID) {
39 ID.AddInteger(ExtraKindOrNumArgs);
40 ID.AddPointer(Type.getAsOpaquePtr());
41 }
42};
43
Douglas Gregore94ca9e42008-11-18 14:39:36 +000044/// CXXOperatorIdName - Contains extra information for the name of an
Mike Stump1eb44332009-09-09 15:08:12 +000045/// overloaded operator in C++, such as "operator+.
Douglas Gregore94ca9e42008-11-18 14:39:36 +000046class CXXOperatorIdName : public DeclarationNameExtra {
47public:
48 /// FETokenInfo - Extra information associated with this operator
49 /// name that can be used by the front end.
50 void *FETokenInfo;
51};
52
Sean Hunt3e518bd2009-11-29 07:34:05 +000053/// CXXLiberalOperatorName - Contains the actual identifier that makes up the
54/// name.
55///
56/// This identifier is stored here rather than directly in DeclarationName so as
57/// to allow Objective-C selectors, which are about a million times more common,
58/// to consume minimal memory.
59class CXXLiteralOperatorIdName : public DeclarationNameExtra {
60public:
61 IdentifierInfo *ID;
62};
63
Douglas Gregor2e1cd422008-11-17 14:58:09 +000064bool operator<(DeclarationName LHS, DeclarationName RHS) {
Douglas Gregord6b5f132009-11-04 22:24:30 +000065 if (LHS.getNameKind() != RHS.getNameKind())
66 return LHS.getNameKind() < RHS.getNameKind();
67
68 switch (LHS.getNameKind()) {
69 case DeclarationName::Identifier:
70 return LHS.getAsIdentifierInfo()->getName() <
71 RHS.getAsIdentifierInfo()->getName();
Douglas Gregor2e1cd422008-11-17 14:58:09 +000072
Douglas Gregord6b5f132009-11-04 22:24:30 +000073 case DeclarationName::ObjCZeroArgSelector:
74 case DeclarationName::ObjCOneArgSelector:
75 case DeclarationName::ObjCMultiArgSelector: {
76 Selector LHSSelector = LHS.getObjCSelector();
77 Selector RHSSelector = RHS.getObjCSelector();
78 for (unsigned I = 0,
79 N = std::min(LHSSelector.getNumArgs(), RHSSelector.getNumArgs());
80 I != N; ++I) {
81 IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
82 IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
83 if (!LHSId || !RHSId)
84 return LHSId && !RHSId;
85
86 switch (LHSId->getName().compare(RHSId->getName())) {
87 case -1: return true;
88 case 1: return false;
89 default: break;
90 }
91 }
92
93 return LHSSelector.getNumArgs() < RHSSelector.getNumArgs();
94 }
95
96 case DeclarationName::CXXConstructorName:
97 case DeclarationName::CXXDestructorName:
98 case DeclarationName::CXXConversionFunctionName:
99 return QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType());
100
101 case DeclarationName::CXXOperatorName:
102 return LHS.getCXXOverloadedOperator() < RHS.getCXXOverloadedOperator();
Sean Hunt3e518bd2009-11-29 07:34:05 +0000103
104 case DeclarationName::CXXLiteralOperatorName:
105 return LHS.getCXXLiteralIdentifier()->getName() <
106 RHS.getCXXLiteralIdentifier()->getName();
Douglas Gregord6b5f132009-11-04 22:24:30 +0000107
108 case DeclarationName::CXXUsingDirective:
109 return false;
110 }
111
112 return false;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000113}
114
115} // end namespace clang
116
117DeclarationName::DeclarationName(Selector Sel) {
Douglas Gregor319ac892009-04-23 22:29:11 +0000118 if (!Sel.getAsOpaquePtr()) {
Douglas Gregor813a97b2009-10-17 17:25:45 +0000119 Ptr = 0;
Douglas Gregor319ac892009-04-23 22:29:11 +0000120 return;
121 }
122
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000123 switch (Sel.getNumArgs()) {
124 case 0:
125 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000126 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000127 Ptr |= StoredObjCZeroArgSelector;
128 break;
129
130 case 1:
131 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000132 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000133 Ptr |= StoredObjCOneArgSelector;
134 break;
135
136 default:
137 Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000138 assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000139 Ptr |= StoredDeclarationNameExtra;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000140 break;
141 }
142}
143
144DeclarationName::NameKind DeclarationName::getNameKind() const {
145 switch (getStoredNameKind()) {
146 case StoredIdentifier: return Identifier;
147 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
148 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
149
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000150 case StoredDeclarationNameExtra:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000151 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump1eb44332009-09-09 15:08:12 +0000152 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000153 return CXXConstructorName;
154
Mike Stump1eb44332009-09-09 15:08:12 +0000155 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000156 return CXXDestructorName;
157
Mike Stump1eb44332009-09-09 15:08:12 +0000158 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000159 return CXXConversionFunctionName;
160
Sean Hunt3e518bd2009-11-29 07:34:05 +0000161 case DeclarationNameExtra::CXXLiteralOperator:
162 return CXXLiteralOperatorName;
163
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000164 case DeclarationNameExtra::CXXUsingDirective:
165 return CXXUsingDirective;
166
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000167 default:
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000168 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump1eb44332009-09-09 15:08:12 +0000169 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000170 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000171 return CXXOperatorName;
172
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000173 return ObjCMultiArgSelector;
174 }
175 break;
176 }
177
178 // Can't actually get here.
Chris Lattnerac8d75f2009-03-21 06:40:50 +0000179 assert(0 && "This should be unreachable!");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000180 return Identifier;
181}
182
Douglas Gregor48026d22010-01-11 18:40:55 +0000183bool DeclarationName::isDependentName() const {
184 QualType T = getCXXNameType();
185 return !T.isNull() && T->isDependentType();
186}
187
Douglas Gregor10bd3682008-11-17 22:58:34 +0000188std::string DeclarationName::getAsString() const {
189 switch (getNameKind()) {
190 case Identifier:
191 if (const IdentifierInfo *II = getAsIdentifierInfo())
192 return II->getName();
193 return "";
194
195 case ObjCZeroArgSelector:
196 case ObjCOneArgSelector:
197 case ObjCMultiArgSelector:
Chris Lattner077bf5e2008-11-24 03:33:13 +0000198 return getObjCSelector().getAsString();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000199
200 case CXXConstructorName: {
201 QualType ClassType = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000202 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
Chris Lattner39f34e92008-11-24 04:00:27 +0000203 return ClassRec->getDecl()->getNameAsString();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000204 return ClassType.getAsString();
205 }
206
207 case CXXDestructorName: {
208 std::string Result = "~";
209 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000210 if (const RecordType *Rec = Type->getAs<RecordType>())
Chris Lattner39f34e92008-11-24 04:00:27 +0000211 Result += Rec->getDecl()->getNameAsString();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000212 else
213 Result += Type.getAsString();
214 return Result;
215 }
216
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000217 case CXXOperatorName: {
Nuno Lopes2550d702009-12-23 17:49:57 +0000218 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000219 0,
220#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
221 Spelling,
222#include "clang/Basic/OperatorKinds.def"
223 };
224 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
225 assert(OpName && "not an overloaded operator");
Mike Stump1eb44332009-09-09 15:08:12 +0000226
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000227 std::string Result = "operator";
228 if (OpName[0] >= 'a' && OpName[0] <= 'z')
229 Result += ' ';
230 Result += OpName;
231 return Result;
232 }
233
Sean Hunt3e518bd2009-11-29 07:34:05 +0000234 case CXXLiteralOperatorName: {
235 return "operator \"\" " + std::string(getCXXLiteralIdentifier()->getName());
236 }
237
Douglas Gregor10bd3682008-11-17 22:58:34 +0000238 case CXXConversionFunctionName: {
239 std::string Result = "operator ";
240 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000241 if (const RecordType *Rec = Type->getAs<RecordType>())
Chris Lattner39f34e92008-11-24 04:00:27 +0000242 Result += Rec->getDecl()->getNameAsString();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000243 else
244 Result += Type.getAsString();
245 return Result;
246 }
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000247 case CXXUsingDirective:
248 return "<using-directive>";
Douglas Gregor10bd3682008-11-17 22:58:34 +0000249 }
250
251 assert(false && "Unexpected declaration name kind");
252 return "";
253}
254
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000255QualType DeclarationName::getCXXNameType() const {
256 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
257 return CXXName->Type;
258 else
259 return QualType();
260}
261
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000262OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
263 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump1eb44332009-09-09 15:08:12 +0000264 unsigned value
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000265 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
266 return static_cast<OverloadedOperatorKind>(value);
267 } else {
268 return OO_None;
269 }
270}
271
Sean Hunt3e518bd2009-11-29 07:34:05 +0000272IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
273 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
274 return CXXLit->ID;
275 else
276 return 0;
277}
278
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000279Selector DeclarationName::getObjCSelector() const {
280 switch (getNameKind()) {
281 case ObjCZeroArgSelector:
282 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
283
284 case ObjCOneArgSelector:
285 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
286
287 case ObjCMultiArgSelector:
288 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
289
290 default:
291 break;
292 }
293
294 return Selector();
295}
296
Douglas Gregor2def4832008-11-17 20:34:05 +0000297void *DeclarationName::getFETokenInfoAsVoid() const {
298 switch (getNameKind()) {
299 case Identifier:
300 return getAsIdentifierInfo()->getFETokenInfo<void>();
301
302 case CXXConstructorName:
303 case CXXDestructorName:
304 case CXXConversionFunctionName:
305 return getAsCXXSpecialName()->FETokenInfo;
306
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000307 case CXXOperatorName:
308 return getAsCXXOperatorIdName()->FETokenInfo;
309
Sean Hunt3e518bd2009-11-29 07:34:05 +0000310 case CXXLiteralOperatorName:
311 return getCXXLiteralIdentifier()->getFETokenInfo<void>();
312
Douglas Gregor2def4832008-11-17 20:34:05 +0000313 default:
314 assert(false && "Declaration name has no FETokenInfo");
315 }
316 return 0;
317}
318
319void DeclarationName::setFETokenInfo(void *T) {
320 switch (getNameKind()) {
321 case Identifier:
322 getAsIdentifierInfo()->setFETokenInfo(T);
323 break;
324
325 case CXXConstructorName:
326 case CXXDestructorName:
327 case CXXConversionFunctionName:
328 getAsCXXSpecialName()->FETokenInfo = T;
329 break;
330
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000331 case CXXOperatorName:
332 getAsCXXOperatorIdName()->FETokenInfo = T;
333 break;
334
Sean Hunt3e518bd2009-11-29 07:34:05 +0000335 case CXXLiteralOperatorName:
336 getCXXLiteralIdentifier()->setFETokenInfo(T);
337 break;
338
Douglas Gregor2def4832008-11-17 20:34:05 +0000339 default:
340 assert(false && "Declaration name has no FETokenInfo");
341 }
342}
343
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000344DeclarationName DeclarationName::getUsingDirectiveName() {
345 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes68f7a242009-12-10 00:07:02 +0000346 static const DeclarationNameExtra UDirExtra =
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000347 { DeclarationNameExtra::CXXUsingDirective };
348
349 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
350 Ptr |= StoredDeclarationNameExtra;
351
352 return DeclarationName(Ptr);
353}
354
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000355void DeclarationName::dump() const {
356 fprintf(stderr, "%s\n", getAsString().c_str());
357}
358
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000359DeclarationNameTable::DeclarationNameTable() {
360 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000361
362 // Initialize the overloaded operator names.
363 CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
364 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump1eb44332009-09-09 15:08:12 +0000365 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000366 = Op + DeclarationNameExtra::CXXConversionFunction;
367 CXXOperatorNames[Op].FETokenInfo = 0;
368 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000369}
370
371DeclarationNameTable::~DeclarationNameTable() {
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000372 llvm::FoldingSet<CXXSpecialName> *set =
373 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Nuno Lopesf9d1e4b2008-12-14 21:53:25 +0000374 llvm::FoldingSetIterator<CXXSpecialName> I = set->begin(), E = set->end();
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000375
Nuno Lopesf9d1e4b2008-12-14 21:53:25 +0000376 while (I != E) {
377 CXXSpecialName *n = &*I++;
378 delete n;
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000379 }
380
381 delete set;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000382 delete [] CXXOperatorNames;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000383}
384
Mike Stump1eb44332009-09-09 15:08:12 +0000385DeclarationName
386DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor50d62d12009-08-05 05:36:45 +0000387 CanQualType Ty) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000388 assert(Kind >= DeclarationName::CXXConstructorName &&
389 Kind <= DeclarationName::CXXConversionFunctionName &&
390 "Kind must be a C++ special name kind");
Mike Stump1eb44332009-09-09 15:08:12 +0000391 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000392 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
393
394 DeclarationNameExtra::ExtraKind EKind;
395 switch (Kind) {
Mike Stump1eb44332009-09-09 15:08:12 +0000396 case DeclarationName::CXXConstructorName:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000397 EKind = DeclarationNameExtra::CXXConstructor;
John McCall0953e762009-09-24 19:53:00 +0000398 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000399 break;
400 case DeclarationName::CXXDestructorName:
401 EKind = DeclarationNameExtra::CXXDestructor;
John McCall0953e762009-09-24 19:53:00 +0000402 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000403 break;
404 case DeclarationName::CXXConversionFunctionName:
405 EKind = DeclarationNameExtra::CXXConversionFunction;
406 break;
407 default:
408 return DeclarationName();
409 }
410
411 // Unique selector, to guarantee there is one per name.
412 llvm::FoldingSetNodeID ID;
413 ID.AddInteger(EKind);
414 ID.AddPointer(Ty.getAsOpaquePtr());
415
416 void *InsertPos = 0;
417 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
418 return DeclarationName(Name);
419
420 CXXSpecialName *SpecialName = new CXXSpecialName;
421 SpecialName->ExtraKindOrNumArgs = EKind;
422 SpecialName->Type = Ty;
Douglas Gregor2def4832008-11-17 20:34:05 +0000423 SpecialName->FETokenInfo = 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000424
425 SpecialNames->InsertNode(SpecialName, InsertPos);
426 return DeclarationName(SpecialName);
427}
428
Mike Stump1eb44332009-09-09 15:08:12 +0000429DeclarationName
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000430DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
431 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
432}
433
Sean Hunt3e518bd2009-11-29 07:34:05 +0000434DeclarationName
435DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
436 CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
437 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
438 LiteralName->ID = II;
439 return DeclarationName(LiteralName);
440}
441
Mike Stump1eb44332009-09-09 15:08:12 +0000442unsigned
Douglas Gregor44b43212008-12-11 16:49:14 +0000443llvm::DenseMapInfo<clang::DeclarationName>::
444getHashValue(clang::DeclarationName N) {
445 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
446}
447