1 //===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the DeclarationName and DeclarationNameTable
13 //===----------------------------------------------------------------------===//
14 #include "clang/AST/DeclarationName.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/Type.h"
18 #include "clang/AST/TypeLoc.h"
19 #include "clang/AST/TypeOrdering.h"
20 #include "clang/Basic/IdentifierTable.h"
21 #include "llvm/ADT/FoldingSet.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/raw_ostream.h"
24 using namespace clang;
27 /// CXXSpecialName - Records the type associated with one of the
28 /// "special" kinds of declaration names in C++, e.g., constructors,
29 /// destructors, and conversion functions.
31 : public DeclarationNameExtra, public llvm::FoldingSetNode {
33 /// Type - The type associated with this declaration name.
36 /// FETokenInfo - Extra information associated with this declaration
37 /// name that can be used by the front end.
40 void Profile(llvm::FoldingSetNodeID &ID) {
41 ID.AddInteger(ExtraKindOrNumArgs);
42 ID.AddPointer(Type.getAsOpaquePtr());
46 /// CXXOperatorIdName - Contains extra information for the name of an
47 /// overloaded operator in C++, such as "operator+.
48 class CXXOperatorIdName : public DeclarationNameExtra {
50 /// FETokenInfo - Extra information associated with this operator
51 /// name that can be used by the front end.
55 /// CXXLiteralOperatorName - Contains the actual identifier that makes up the
58 /// This identifier is stored here rather than directly in DeclarationName so as
59 /// to allow Objective-C selectors, which are about a million times more common,
60 /// to consume minimal memory.
61 class CXXLiteralOperatorIdName
62 : public DeclarationNameExtra, public llvm::FoldingSetNode {
66 /// FETokenInfo - Extra information associated with this operator
67 /// name that can be used by the front end.
70 void Profile(llvm::FoldingSetNodeID &FSID) {
75 static int compareInt(unsigned A, unsigned B) {
76 return (A < B ? -1 : (A > B ? 1 : 0));
79 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
80 if (LHS.getNameKind() != RHS.getNameKind())
81 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
83 switch (LHS.getNameKind()) {
84 case DeclarationName::Identifier: {
85 IdentifierInfo *LII = LHS.getAsIdentifierInfo();
86 IdentifierInfo *RII = RHS.getAsIdentifierInfo();
87 if (!LII) return RII ? -1 : 0;
90 return LII->getName().compare(RII->getName());
93 case DeclarationName::ObjCZeroArgSelector:
94 case DeclarationName::ObjCOneArgSelector:
95 case DeclarationName::ObjCMultiArgSelector: {
96 Selector LHSSelector = LHS.getObjCSelector();
97 Selector RHSSelector = RHS.getObjCSelector();
98 // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
99 if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
100 RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
101 return LHSSelector.getAsIdentifierInfo()->getName().compare(
102 RHSSelector.getAsIdentifierInfo()->getName());
104 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
105 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
106 switch (LHSSelector.getNameForSlot(I).compare(
107 RHSSelector.getNameForSlot(I))) {
114 return compareInt(LN, RN);
117 case DeclarationName::CXXConstructorName:
118 case DeclarationName::CXXDestructorName:
119 case DeclarationName::CXXConversionFunctionName:
120 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
122 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
126 case DeclarationName::CXXOperatorName:
127 return compareInt(LHS.getCXXOverloadedOperator(),
128 RHS.getCXXOverloadedOperator());
130 case DeclarationName::CXXLiteralOperatorName:
131 return LHS.getCXXLiteralIdentifier()->getName().compare(
132 RHS.getCXXLiteralIdentifier()->getName());
134 case DeclarationName::CXXUsingDirective:
138 llvm_unreachable("Invalid DeclarationName Kind!");
141 static void printCXXConstructorDestructorName(QualType ClassType,
143 PrintingPolicy Policy) {
144 // We know we're printing C++ here. Ensure we print types properly.
145 Policy.adjustForCPlusPlus();
147 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
148 OS << *ClassRec->getDecl();
151 if (Policy.SuppressTemplateArgsInCXXConstructors) {
152 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
153 OS << *InjTy->getDecl();
157 ClassType.print(OS, Policy);
160 void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
161 DeclarationName &N = *this;
162 switch (N.getNameKind()) {
163 case DeclarationName::Identifier:
164 if (const IdentifierInfo *II = N.getAsIdentifierInfo())
168 case DeclarationName::ObjCZeroArgSelector:
169 case DeclarationName::ObjCOneArgSelector:
170 case DeclarationName::ObjCMultiArgSelector:
171 N.getObjCSelector().print(OS);
174 case DeclarationName::CXXConstructorName:
175 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
177 case DeclarationName::CXXDestructorName: {
179 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
182 case DeclarationName::CXXOperatorName: {
183 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
185 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
187 #include "clang/Basic/OperatorKinds.def"
189 const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
190 assert(OpName && "not an overloaded operator");
193 if (OpName[0] >= 'a' && OpName[0] <= 'z')
199 case DeclarationName::CXXLiteralOperatorName:
200 OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
203 case DeclarationName::CXXConversionFunctionName: {
205 QualType Type = N.getCXXNameType();
206 if (const RecordType *Rec = Type->getAs<RecordType>()) {
207 OS << *Rec->getDecl();
210 // We know we're printing C++ here, ensure we print 'bool' properly.
211 PrintingPolicy CXXPolicy = Policy;
212 CXXPolicy.adjustForCPlusPlus();
213 Type.print(OS, CXXPolicy);
216 case DeclarationName::CXXUsingDirective:
217 OS << "<using-directive>";
221 llvm_unreachable("Unexpected declaration name kind");
224 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
226 N.print(OS, PrintingPolicy(LO));
230 } // end namespace clang
232 DeclarationName::NameKind DeclarationName::getNameKind() const {
233 switch (getStoredNameKind()) {
234 case StoredIdentifier: return Identifier;
235 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
236 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
238 case StoredDeclarationNameExtra:
239 switch (getExtra()->ExtraKindOrNumArgs) {
240 case DeclarationNameExtra::CXXConstructor:
241 return CXXConstructorName;
243 case DeclarationNameExtra::CXXDestructor:
244 return CXXDestructorName;
246 case DeclarationNameExtra::CXXConversionFunction:
247 return CXXConversionFunctionName;
249 case DeclarationNameExtra::CXXLiteralOperator:
250 return CXXLiteralOperatorName;
252 case DeclarationNameExtra::CXXUsingDirective:
253 return CXXUsingDirective;
256 // Check if we have one of the CXXOperator* enumeration values.
257 if (getExtra()->ExtraKindOrNumArgs <
258 DeclarationNameExtra::CXXUsingDirective)
259 return CXXOperatorName;
261 return ObjCMultiArgSelector;
265 // Can't actually get here.
266 llvm_unreachable("This should be unreachable!");
269 bool DeclarationName::isDependentName() const {
270 QualType T = getCXXNameType();
271 return !T.isNull() && T->isDependentType();
274 std::string DeclarationName::getAsString() const {
276 llvm::raw_string_ostream OS(Result);
281 QualType DeclarationName::getCXXNameType() const {
282 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
283 return CXXName->Type;
288 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
289 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
291 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
292 return static_cast<OverloadedOperatorKind>(value);
298 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
299 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
305 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
306 switch (getNameKind()) {
308 llvm_unreachable("Handled by getFETokenInfo()");
310 case CXXConstructorName:
311 case CXXDestructorName:
312 case CXXConversionFunctionName:
313 return getAsCXXSpecialName()->FETokenInfo;
315 case CXXOperatorName:
316 return getAsCXXOperatorIdName()->FETokenInfo;
318 case CXXLiteralOperatorName:
319 return getAsCXXLiteralOperatorIdName()->FETokenInfo;
322 llvm_unreachable("Declaration name has no FETokenInfo");
326 void DeclarationName::setFETokenInfo(void *T) {
327 switch (getNameKind()) {
329 getAsIdentifierInfo()->setFETokenInfo(T);
332 case CXXConstructorName:
333 case CXXDestructorName:
334 case CXXConversionFunctionName:
335 getAsCXXSpecialName()->FETokenInfo = T;
338 case CXXOperatorName:
339 getAsCXXOperatorIdName()->FETokenInfo = T;
342 case CXXLiteralOperatorName:
343 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
347 llvm_unreachable("Declaration name has no FETokenInfo");
351 DeclarationName DeclarationName::getUsingDirectiveName() {
352 // Single instance of DeclarationNameExtra for using-directive
353 static const DeclarationNameExtra UDirExtra =
354 { DeclarationNameExtra::CXXUsingDirective };
356 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
357 Ptr |= StoredDeclarationNameExtra;
359 return DeclarationName(Ptr);
362 LLVM_DUMP_METHOD void DeclarationName::dump() const {
363 llvm::errs() << *this << '\n';
366 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
367 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
368 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
370 // Initialize the overloaded operator names.
371 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
372 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
373 CXXOperatorNames[Op].ExtraKindOrNumArgs
374 = Op + DeclarationNameExtra::CXXConversionFunction;
375 CXXOperatorNames[Op].FETokenInfo = nullptr;
379 DeclarationNameTable::~DeclarationNameTable() {
380 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
381 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
382 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
383 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
384 (CXXLiteralOperatorNames);
390 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
391 return getCXXSpecialName(DeclarationName::CXXConstructorName,
392 Ty.getUnqualifiedType());
395 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
396 return getCXXSpecialName(DeclarationName::CXXDestructorName,
397 Ty.getUnqualifiedType());
401 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
402 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
406 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
408 assert(Kind >= DeclarationName::CXXConstructorName &&
409 Kind <= DeclarationName::CXXConversionFunctionName &&
410 "Kind must be a C++ special name kind");
411 llvm::FoldingSet<CXXSpecialName> *SpecialNames
412 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
414 DeclarationNameExtra::ExtraKind EKind;
416 case DeclarationName::CXXConstructorName:
417 EKind = DeclarationNameExtra::CXXConstructor;
418 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
420 case DeclarationName::CXXDestructorName:
421 EKind = DeclarationNameExtra::CXXDestructor;
422 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
424 case DeclarationName::CXXConversionFunctionName:
425 EKind = DeclarationNameExtra::CXXConversionFunction;
428 return DeclarationName();
431 // Unique selector, to guarantee there is one per name.
432 llvm::FoldingSetNodeID ID;
433 ID.AddInteger(EKind);
434 ID.AddPointer(Ty.getAsOpaquePtr());
436 void *InsertPos = nullptr;
437 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
438 return DeclarationName(Name);
440 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
441 SpecialName->ExtraKindOrNumArgs = EKind;
442 SpecialName->Type = Ty;
443 SpecialName->FETokenInfo = nullptr;
445 SpecialNames->InsertNode(SpecialName, InsertPos);
446 return DeclarationName(SpecialName);
450 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
451 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
455 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
456 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
457 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
458 (CXXLiteralOperatorNames);
460 llvm::FoldingSetNodeID ID;
463 void *InsertPos = nullptr;
464 if (CXXLiteralOperatorIdName *Name =
465 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
466 return DeclarationName (Name);
468 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
469 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
470 LiteralName->ID = II;
471 LiteralName->FETokenInfo = nullptr;
473 LiteralNames->InsertNode(LiteralName, InsertPos);
474 return DeclarationName(LiteralName);
477 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
478 switch (Name.getNameKind()) {
479 case DeclarationName::Identifier:
481 case DeclarationName::CXXConstructorName:
482 case DeclarationName::CXXDestructorName:
483 case DeclarationName::CXXConversionFunctionName:
484 NamedType.TInfo = nullptr;
486 case DeclarationName::CXXOperatorName:
487 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
488 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
490 case DeclarationName::CXXLiteralOperatorName:
491 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
493 case DeclarationName::ObjCZeroArgSelector:
494 case DeclarationName::ObjCOneArgSelector:
495 case DeclarationName::ObjCMultiArgSelector:
498 case DeclarationName::CXXUsingDirective:
503 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
504 switch (Name.getNameKind()) {
505 case DeclarationName::Identifier:
506 case DeclarationName::ObjCZeroArgSelector:
507 case DeclarationName::ObjCOneArgSelector:
508 case DeclarationName::ObjCMultiArgSelector:
509 case DeclarationName::CXXOperatorName:
510 case DeclarationName::CXXLiteralOperatorName:
511 case DeclarationName::CXXUsingDirective:
514 case DeclarationName::CXXConstructorName:
515 case DeclarationName::CXXDestructorName:
516 case DeclarationName::CXXConversionFunctionName:
517 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
518 return TInfo->getType()->containsUnexpandedParameterPack();
520 return Name.getCXXNameType()->containsUnexpandedParameterPack();
522 llvm_unreachable("All name kinds handled.");
525 bool DeclarationNameInfo::isInstantiationDependent() const {
526 switch (Name.getNameKind()) {
527 case DeclarationName::Identifier:
528 case DeclarationName::ObjCZeroArgSelector:
529 case DeclarationName::ObjCOneArgSelector:
530 case DeclarationName::ObjCMultiArgSelector:
531 case DeclarationName::CXXOperatorName:
532 case DeclarationName::CXXLiteralOperatorName:
533 case DeclarationName::CXXUsingDirective:
536 case DeclarationName::CXXConstructorName:
537 case DeclarationName::CXXDestructorName:
538 case DeclarationName::CXXConversionFunctionName:
539 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
540 return TInfo->getType()->isInstantiationDependentType();
542 return Name.getCXXNameType()->isInstantiationDependentType();
544 llvm_unreachable("All name kinds handled.");
547 std::string DeclarationNameInfo::getAsString() const {
549 llvm::raw_string_ostream OS(Result);
554 void DeclarationNameInfo::printName(raw_ostream &OS) const {
555 switch (Name.getNameKind()) {
556 case DeclarationName::Identifier:
557 case DeclarationName::ObjCZeroArgSelector:
558 case DeclarationName::ObjCOneArgSelector:
559 case DeclarationName::ObjCMultiArgSelector:
560 case DeclarationName::CXXOperatorName:
561 case DeclarationName::CXXLiteralOperatorName:
562 case DeclarationName::CXXUsingDirective:
566 case DeclarationName::CXXConstructorName:
567 case DeclarationName::CXXDestructorName:
568 case DeclarationName::CXXConversionFunctionName:
569 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
570 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
572 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
577 OS << TInfo->getType().getAsString(PrintingPolicy(LO));
582 llvm_unreachable("Unexpected declaration name kind");
585 SourceLocation DeclarationNameInfo::getEndLoc() const {
586 switch (Name.getNameKind()) {
587 case DeclarationName::Identifier:
590 case DeclarationName::CXXOperatorName: {
591 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
592 return SourceLocation::getFromRawEncoding(raw);
595 case DeclarationName::CXXLiteralOperatorName: {
596 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
597 return SourceLocation::getFromRawEncoding(raw);
600 case DeclarationName::CXXConstructorName:
601 case DeclarationName::CXXDestructorName:
602 case DeclarationName::CXXConversionFunctionName:
603 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
604 return TInfo->getTypeLoc().getEndLoc();
608 // DNInfo work in progress: FIXME.
609 case DeclarationName::ObjCZeroArgSelector:
610 case DeclarationName::ObjCOneArgSelector:
611 case DeclarationName::ObjCMultiArgSelector:
612 case DeclarationName::CXXUsingDirective:
615 llvm_unreachable("Unexpected declaration name kind");