| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 1 | //===-- 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 | //===----------------------------------------------------------------------===// | 
| Ted Kremenek | ac9590e | 2010-05-10 20:40:08 +0000 | [diff] [blame^] | 14 | #include "clang/AST/ASTContext.h" | 
 | 15 | #include "clang/AST/Decl.h" | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 16 | #include "clang/AST/DeclarationName.h" | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 17 | #include "clang/AST/Type.h" | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame] | 18 | #include "clang/AST/TypeOrdering.h" | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 19 | #include "clang/Basic/IdentifierTable.h" | 
| Douglas Gregor | 370187c | 2009-04-22 21:45:53 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/DenseMap.h" | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 21 | #include "llvm/ADT/FoldingSet.h" | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 22 | #include "llvm/Support/raw_ostream.h" | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 23 | using namespace clang; | 
 | 24 |  | 
 | 25 | namespace clang { | 
 | 26 | /// CXXSpecialName - Records the type associated with one of the | 
 | 27 | /// "special" kinds of declaration names in C++, e.g., constructors, | 
 | 28 | /// destructors, and conversion functions. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 29 | class CXXSpecialName | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 30 |   : public DeclarationNameExtra, public llvm::FoldingSetNode { | 
 | 31 | public: | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 32 |   /// Type - The type associated with this declaration name. | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 33 |   QualType Type; | 
 | 34 |  | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 35 |   /// FETokenInfo - Extra information associated with this declaration | 
 | 36 |   /// name that can be used by the front end. | 
 | 37 |   void *FETokenInfo; | 
 | 38 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 39 |   void Profile(llvm::FoldingSetNodeID &ID) { | 
 | 40 |     ID.AddInteger(ExtraKindOrNumArgs); | 
 | 41 |     ID.AddPointer(Type.getAsOpaquePtr()); | 
 | 42 |   } | 
 | 43 | }; | 
 | 44 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 45 | /// CXXOperatorIdName - Contains extra information for the name of an | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 46 | /// overloaded operator in C++, such as "operator+. | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 47 | class CXXOperatorIdName : public DeclarationNameExtra { | 
 | 48 | public: | 
 | 49 |   /// FETokenInfo - Extra information associated with this operator | 
 | 50 |   /// name that can be used by the front end. | 
 | 51 |   void *FETokenInfo; | 
 | 52 | }; | 
 | 53 |  | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 54 | /// CXXLiberalOperatorName - Contains the actual identifier that makes up the | 
 | 55 | /// name. | 
 | 56 | /// | 
 | 57 | /// This identifier is stored here rather than directly in DeclarationName so as | 
 | 58 | /// to allow Objective-C selectors, which are about a million times more common, | 
 | 59 | /// to consume minimal memory. | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 60 | class CXXLiteralOperatorIdName | 
 | 61 |   : public DeclarationNameExtra, public llvm::FoldingSetNode { | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 62 | public: | 
 | 63 |   IdentifierInfo *ID; | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 64 |  | 
 | 65 |   void Profile(llvm::FoldingSetNodeID &FSID) { | 
 | 66 |     FSID.AddPointer(ID); | 
 | 67 |   } | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 68 | }; | 
 | 69 |  | 
| John McCall | 7fe0b9e | 2010-02-13 01:04:05 +0000 | [diff] [blame] | 70 | static int compareInt(unsigned A, unsigned B) { | 
 | 71 |   return (A < B ? -1 : (A > B ? 1 : 0)); | 
 | 72 | } | 
 | 73 |  | 
 | 74 | int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame] | 75 |   if (LHS.getNameKind() != RHS.getNameKind()) | 
| John McCall | 7fe0b9e | 2010-02-13 01:04:05 +0000 | [diff] [blame] | 76 |     return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1); | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame] | 77 |    | 
 | 78 |   switch (LHS.getNameKind()) { | 
| John McCall | 7fe0b9e | 2010-02-13 01:04:05 +0000 | [diff] [blame] | 79 |   case DeclarationName::Identifier: { | 
 | 80 |     IdentifierInfo *LII = LHS.getAsIdentifierInfo(); | 
 | 81 |     IdentifierInfo *RII = RHS.getAsIdentifierInfo(); | 
 | 82 |     if (!LII) return RII ? -1 : 0; | 
 | 83 |     if (!RII) return 1; | 
 | 84 |      | 
 | 85 |     return LII->getName().compare(RII->getName()); | 
 | 86 |   } | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 87 |  | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame] | 88 |   case DeclarationName::ObjCZeroArgSelector: | 
 | 89 |   case DeclarationName::ObjCOneArgSelector: | 
 | 90 |   case DeclarationName::ObjCMultiArgSelector: { | 
 | 91 |     Selector LHSSelector = LHS.getObjCSelector(); | 
 | 92 |     Selector RHSSelector = RHS.getObjCSelector(); | 
| John McCall | 7fe0b9e | 2010-02-13 01:04:05 +0000 | [diff] [blame] | 93 |     unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs(); | 
 | 94 |     for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) { | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame] | 95 |       IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I); | 
 | 96 |       IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I); | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame] | 97 |          | 
 | 98 |       switch (LHSId->getName().compare(RHSId->getName())) { | 
 | 99 |       case -1: return true; | 
 | 100 |       case 1: return false; | 
 | 101 |       default: break; | 
 | 102 |       } | 
 | 103 |     } | 
| John McCall | 7fe0b9e | 2010-02-13 01:04:05 +0000 | [diff] [blame] | 104 |  | 
 | 105 |     return compareInt(LN, RN); | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame] | 106 |   } | 
 | 107 |    | 
 | 108 |   case DeclarationName::CXXConstructorName: | 
 | 109 |   case DeclarationName::CXXDestructorName: | 
 | 110 |   case DeclarationName::CXXConversionFunctionName: | 
| John McCall | 7fe0b9e | 2010-02-13 01:04:05 +0000 | [diff] [blame] | 111 |     if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType())) | 
 | 112 |       return -1; | 
 | 113 |     if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType())) | 
 | 114 |       return 1; | 
 | 115 |     return 0; | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame] | 116 |                | 
 | 117 |   case DeclarationName::CXXOperatorName: | 
| John McCall | 7fe0b9e | 2010-02-13 01:04:05 +0000 | [diff] [blame] | 118 |     return compareInt(LHS.getCXXOverloadedOperator(), | 
 | 119 |                       RHS.getCXXOverloadedOperator()); | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 120 |  | 
 | 121 |   case DeclarationName::CXXLiteralOperatorName: | 
| John McCall | 7fe0b9e | 2010-02-13 01:04:05 +0000 | [diff] [blame] | 122 |     return LHS.getCXXLiteralIdentifier()->getName().compare( | 
 | 123 |                                    RHS.getCXXLiteralIdentifier()->getName()); | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame] | 124 |                | 
 | 125 |   case DeclarationName::CXXUsingDirective: | 
| John McCall | 7fe0b9e | 2010-02-13 01:04:05 +0000 | [diff] [blame] | 126 |     return 0; | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame] | 127 |   } | 
 | 128 |                | 
| John McCall | 7fe0b9e | 2010-02-13 01:04:05 +0000 | [diff] [blame] | 129 |   return 0; | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 130 | } | 
 | 131 |  | 
 | 132 | } // end namespace clang | 
 | 133 |  | 
 | 134 | DeclarationName::DeclarationName(Selector Sel) { | 
| Douglas Gregor | 319ac89 | 2009-04-23 22:29:11 +0000 | [diff] [blame] | 135 |   if (!Sel.getAsOpaquePtr()) { | 
| Douglas Gregor | 813a97b | 2009-10-17 17:25:45 +0000 | [diff] [blame] | 136 |     Ptr = 0; | 
| Douglas Gregor | 319ac89 | 2009-04-23 22:29:11 +0000 | [diff] [blame] | 137 |     return; | 
 | 138 |   } | 
 | 139 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 140 |   switch (Sel.getNumArgs()) { | 
 | 141 |   case 0: | 
 | 142 |     Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); | 
| Ted Kremenek | 3eb8dd7 | 2009-03-14 00:27:40 +0000 | [diff] [blame] | 143 |     assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 144 |     Ptr |= StoredObjCZeroArgSelector; | 
 | 145 |     break; | 
 | 146 |  | 
 | 147 |   case 1: | 
 | 148 |     Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); | 
| Ted Kremenek | 3eb8dd7 | 2009-03-14 00:27:40 +0000 | [diff] [blame] | 149 |     assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 150 |     Ptr |= StoredObjCOneArgSelector; | 
 | 151 |     break; | 
 | 152 |  | 
 | 153 |   default: | 
 | 154 |     Ptr = Sel.InfoPtr & ~Selector::ArgFlags; | 
| Ted Kremenek | 3eb8dd7 | 2009-03-14 00:27:40 +0000 | [diff] [blame] | 155 |     assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector"); | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 156 |     Ptr |= StoredDeclarationNameExtra; | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 157 |     break; | 
 | 158 |   } | 
 | 159 | } | 
 | 160 |  | 
 | 161 | DeclarationName::NameKind DeclarationName::getNameKind() const { | 
 | 162 |   switch (getStoredNameKind()) { | 
 | 163 |   case StoredIdentifier:          return Identifier; | 
 | 164 |   case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; | 
 | 165 |   case StoredObjCOneArgSelector:  return ObjCOneArgSelector; | 
 | 166 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 167 |   case StoredDeclarationNameExtra: | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 168 |     switch (getExtra()->ExtraKindOrNumArgs) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 169 |     case DeclarationNameExtra::CXXConstructor: | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 170 |       return CXXConstructorName; | 
 | 171 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 172 |     case DeclarationNameExtra::CXXDestructor: | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 173 |       return CXXDestructorName; | 
 | 174 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 175 |     case DeclarationNameExtra::CXXConversionFunction: | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 176 |       return CXXConversionFunctionName; | 
 | 177 |  | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 178 |     case DeclarationNameExtra::CXXLiteralOperator: | 
 | 179 |       return CXXLiteralOperatorName; | 
 | 180 |  | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 181 |     case DeclarationNameExtra::CXXUsingDirective: | 
 | 182 |       return CXXUsingDirective; | 
 | 183 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 184 |     default: | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 185 |       // Check if we have one of the CXXOperator* enumeration values. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 186 |       if (getExtra()->ExtraKindOrNumArgs < | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 187 |             DeclarationNameExtra::CXXUsingDirective) | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 188 |         return CXXOperatorName; | 
 | 189 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 190 |       return ObjCMultiArgSelector; | 
 | 191 |     } | 
 | 192 |     break; | 
 | 193 |   } | 
 | 194 |  | 
 | 195 |   // Can't actually get here. | 
| Chris Lattner | ac8d75f | 2009-03-21 06:40:50 +0000 | [diff] [blame] | 196 |   assert(0 && "This should be unreachable!"); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 197 |   return Identifier; | 
 | 198 | } | 
 | 199 |  | 
| Douglas Gregor | 48026d2 | 2010-01-11 18:40:55 +0000 | [diff] [blame] | 200 | bool DeclarationName::isDependentName() const { | 
 | 201 |   QualType T = getCXXNameType(); | 
 | 202 |   return !T.isNull() && T->isDependentType(); | 
 | 203 | } | 
 | 204 |  | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 205 | std::string DeclarationName::getAsString() const { | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 206 |   std::string Result; | 
 | 207 |   llvm::raw_string_ostream OS(Result); | 
 | 208 |   printName(OS); | 
 | 209 |   return OS.str(); | 
 | 210 | } | 
 | 211 |  | 
 | 212 | void DeclarationName::printName(llvm::raw_ostream &OS) const { | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 213 |   switch (getNameKind()) { | 
 | 214 |   case Identifier: | 
 | 215 |     if (const IdentifierInfo *II = getAsIdentifierInfo()) | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 216 |       OS << II->getName(); | 
 | 217 |     return; | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 218 |  | 
 | 219 |   case ObjCZeroArgSelector: | 
 | 220 |   case ObjCOneArgSelector: | 
 | 221 |   case ObjCMultiArgSelector: | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 222 |     OS << getObjCSelector().getAsString(); | 
 | 223 |     return; | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 224 |  | 
 | 225 |   case CXXConstructorName: { | 
 | 226 |     QualType ClassType = getCXXNameType(); | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 227 |     if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 228 |       OS << ClassRec->getDecl(); | 
 | 229 |     else | 
 | 230 |       OS << ClassType.getAsString(); | 
 | 231 |     return; | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 232 |   } | 
 | 233 |  | 
 | 234 |   case CXXDestructorName: { | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 235 |     OS << '~'; | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 236 |     QualType Type = getCXXNameType(); | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 237 |     if (const RecordType *Rec = Type->getAs<RecordType>()) | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 238 |       OS << Rec->getDecl(); | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 239 |     else | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 240 |       OS << Type.getAsString(); | 
 | 241 |     return; | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 242 |   } | 
 | 243 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 244 |   case CXXOperatorName: { | 
| Nuno Lopes | 2550d70 | 2009-12-23 17:49:57 +0000 | [diff] [blame] | 245 |     static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = { | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 246 |       0, | 
 | 247 | #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ | 
 | 248 |       Spelling, | 
 | 249 | #include "clang/Basic/OperatorKinds.def" | 
 | 250 |     }; | 
 | 251 |     const char *OpName = OperatorNames[getCXXOverloadedOperator()]; | 
 | 252 |     assert(OpName && "not an overloaded operator"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 253 |  | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 254 |     OS << "operator"; | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 255 |     if (OpName[0] >= 'a' && OpName[0] <= 'z') | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 256 |       OS << ' '; | 
 | 257 |     OS << OpName; | 
 | 258 |     return; | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 259 |   } | 
 | 260 |  | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 261 |   case CXXLiteralOperatorName: | 
 | 262 |     OS << "operator \"\" " << getCXXLiteralIdentifier()->getName(); | 
 | 263 |     return; | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 264 |  | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 265 |   case CXXConversionFunctionName: { | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 266 |     OS << "operator "; | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 267 |     QualType Type = getCXXNameType(); | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 268 |     if (const RecordType *Rec = Type->getAs<RecordType>()) | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 269 |       OS << Rec->getDecl(); | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 270 |     else | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 271 |       OS << Type.getAsString(); | 
 | 272 |     return; | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 273 |   } | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 274 |   case CXXUsingDirective: | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 275 |     OS << "<using-directive>"; | 
 | 276 |     return; | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 277 |   } | 
 | 278 |  | 
 | 279 |   assert(false && "Unexpected declaration name kind"); | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 280 | } | 
 | 281 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 282 | QualType DeclarationName::getCXXNameType() const { | 
 | 283 |   if (CXXSpecialName *CXXName = getAsCXXSpecialName()) | 
 | 284 |     return CXXName->Type; | 
 | 285 |   else | 
 | 286 |     return QualType(); | 
 | 287 | } | 
 | 288 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 289 | OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { | 
 | 290 |   if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 291 |     unsigned value | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 292 |       = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; | 
 | 293 |     return static_cast<OverloadedOperatorKind>(value); | 
 | 294 |   } else { | 
 | 295 |     return OO_None; | 
 | 296 |   } | 
 | 297 | } | 
 | 298 |  | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 299 | IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const { | 
 | 300 |   if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName()) | 
 | 301 |     return CXXLit->ID; | 
 | 302 |   else | 
 | 303 |     return 0; | 
 | 304 | } | 
 | 305 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 306 | Selector DeclarationName::getObjCSelector() const { | 
 | 307 |   switch (getNameKind()) { | 
 | 308 |   case ObjCZeroArgSelector: | 
 | 309 |     return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0); | 
 | 310 |  | 
 | 311 |   case ObjCOneArgSelector: | 
 | 312 |     return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1); | 
 | 313 |  | 
 | 314 |   case ObjCMultiArgSelector: | 
 | 315 |     return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask)); | 
 | 316 |  | 
 | 317 |   default: | 
 | 318 |     break; | 
 | 319 |   } | 
 | 320 |  | 
 | 321 |   return Selector(); | 
 | 322 | } | 
 | 323 |  | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 324 | void *DeclarationName::getFETokenInfoAsVoid() const { | 
 | 325 |   switch (getNameKind()) { | 
 | 326 |   case Identifier: | 
 | 327 |     return getAsIdentifierInfo()->getFETokenInfo<void>(); | 
 | 328 |  | 
 | 329 |   case CXXConstructorName: | 
 | 330 |   case CXXDestructorName: | 
 | 331 |   case CXXConversionFunctionName: | 
 | 332 |     return getAsCXXSpecialName()->FETokenInfo; | 
 | 333 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 334 |   case CXXOperatorName: | 
 | 335 |     return getAsCXXOperatorIdName()->FETokenInfo; | 
 | 336 |  | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 337 |   case CXXLiteralOperatorName: | 
 | 338 |     return getCXXLiteralIdentifier()->getFETokenInfo<void>(); | 
 | 339 |  | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 340 |   default: | 
 | 341 |     assert(false && "Declaration name has no FETokenInfo"); | 
 | 342 |   } | 
 | 343 |   return 0; | 
 | 344 | } | 
 | 345 |  | 
 | 346 | void DeclarationName::setFETokenInfo(void *T) { | 
 | 347 |   switch (getNameKind()) { | 
 | 348 |   case Identifier: | 
 | 349 |     getAsIdentifierInfo()->setFETokenInfo(T); | 
 | 350 |     break; | 
 | 351 |  | 
 | 352 |   case CXXConstructorName: | 
 | 353 |   case CXXDestructorName: | 
 | 354 |   case CXXConversionFunctionName: | 
 | 355 |     getAsCXXSpecialName()->FETokenInfo = T; | 
 | 356 |     break; | 
 | 357 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 358 |   case CXXOperatorName: | 
 | 359 |     getAsCXXOperatorIdName()->FETokenInfo = T; | 
 | 360 |     break; | 
 | 361 |  | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 362 |   case CXXLiteralOperatorName: | 
 | 363 |     getCXXLiteralIdentifier()->setFETokenInfo(T); | 
 | 364 |     break; | 
 | 365 |  | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 366 |   default: | 
 | 367 |     assert(false && "Declaration name has no FETokenInfo"); | 
 | 368 |   } | 
 | 369 | } | 
 | 370 |  | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 371 | DeclarationName DeclarationName::getUsingDirectiveName() { | 
 | 372 |   // Single instance of DeclarationNameExtra for using-directive | 
| Nuno Lopes | 68f7a24 | 2009-12-10 00:07:02 +0000 | [diff] [blame] | 373 |   static const DeclarationNameExtra UDirExtra = | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 374 |     { DeclarationNameExtra::CXXUsingDirective }; | 
 | 375 |  | 
 | 376 |   uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); | 
 | 377 |   Ptr |= StoredDeclarationNameExtra; | 
 | 378 |  | 
 | 379 |   return DeclarationName(Ptr); | 
 | 380 | } | 
 | 381 |  | 
| Anders Carlsson | 70f5bc7 | 2009-11-15 22:30:43 +0000 | [diff] [blame] | 382 | void DeclarationName::dump() const { | 
| Benjamin Kramer | f6cde77 | 2010-04-17 09:56:45 +0000 | [diff] [blame] | 383 |   printName(llvm::errs()); | 
 | 384 |   llvm::errs() << '\n'; | 
| Anders Carlsson | 70f5bc7 | 2009-11-15 22:30:43 +0000 | [diff] [blame] | 385 | } | 
 | 386 |  | 
| Ted Kremenek | ac9590e | 2010-05-10 20:40:08 +0000 | [diff] [blame^] | 387 | DeclarationNameTable::DeclarationNameTable(ASTContext &C) { | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 388 |   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 389 |   CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 390 |  | 
 | 391 |   // Initialize the overloaded operator names. | 
| Ted Kremenek | ac9590e | 2010-05-10 20:40:08 +0000 | [diff] [blame^] | 392 |   CXXOperatorNames = new (C) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 393 |   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 394 |     CXXOperatorNames[Op].ExtraKindOrNumArgs | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 395 |       = Op + DeclarationNameExtra::CXXConversionFunction; | 
 | 396 |     CXXOperatorNames[Op].FETokenInfo = 0; | 
 | 397 |   } | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 398 | } | 
 | 399 |  | 
 | 400 | DeclarationNameTable::~DeclarationNameTable() { | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 401 |   llvm::FoldingSet<CXXSpecialName> *SpecialNames = | 
| Nuno Lopes | 6d34ae5 | 2008-12-14 17:27:25 +0000 | [diff] [blame] | 402 |     static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 403 |   llvm::FoldingSetIterator<CXXSpecialName> | 
 | 404 |                            SI = SpecialNames->begin(), SE = SpecialNames->end(); | 
| Nuno Lopes | 6d34ae5 | 2008-12-14 17:27:25 +0000 | [diff] [blame] | 405 |  | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 406 |   while (SI != SE) { | 
 | 407 |     CXXSpecialName *n = &*SI++; | 
| Nuno Lopes | f9d1e4b | 2008-12-14 21:53:25 +0000 | [diff] [blame] | 408 |     delete n; | 
| Nuno Lopes | 6d34ae5 | 2008-12-14 17:27:25 +0000 | [diff] [blame] | 409 |   } | 
 | 410 |  | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 411 |  | 
 | 412 |   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames | 
 | 413 |     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> | 
 | 414 |                                                       (CXXLiteralOperatorNames); | 
 | 415 |   llvm::FoldingSetIterator<CXXLiteralOperatorIdName> | 
 | 416 |                            LI = LiteralNames->begin(), LE = LiteralNames->end(); | 
 | 417 |  | 
 | 418 |   while (LI != LE) { | 
 | 419 |     CXXLiteralOperatorIdName *n = &*LI++; | 
 | 420 |     delete n; | 
 | 421 |   } | 
 | 422 |  | 
 | 423 |   delete SpecialNames; | 
 | 424 |   delete LiteralNames; | 
| Ted Kremenek | ac9590e | 2010-05-10 20:40:08 +0000 | [diff] [blame^] | 425 | } | 
 | 426 |  | 
 | 427 | void DeclarationNameTable::DoDestroy(ASTContext &C) { | 
 | 428 |   if (C.FreeMemory) { | 
 | 429 |     C.Deallocate(CXXOperatorNames); | 
 | 430 |   } | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 431 | } | 
 | 432 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 433 | DeclarationName | 
 | 434 | DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, | 
| Douglas Gregor | 50d62d1 | 2009-08-05 05:36:45 +0000 | [diff] [blame] | 435 |                                         CanQualType Ty) { | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 436 |   assert(Kind >= DeclarationName::CXXConstructorName && | 
 | 437 |          Kind <= DeclarationName::CXXConversionFunctionName && | 
 | 438 |          "Kind must be a C++ special name kind"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 439 |   llvm::FoldingSet<CXXSpecialName> *SpecialNames | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 440 |     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); | 
 | 441 |  | 
 | 442 |   DeclarationNameExtra::ExtraKind EKind; | 
 | 443 |   switch (Kind) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 444 |   case DeclarationName::CXXConstructorName: | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 445 |     EKind = DeclarationNameExtra::CXXConstructor; | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 446 |     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 447 |     break; | 
 | 448 |   case DeclarationName::CXXDestructorName: | 
 | 449 |     EKind = DeclarationNameExtra::CXXDestructor; | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 450 |     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 451 |     break; | 
 | 452 |   case DeclarationName::CXXConversionFunctionName: | 
 | 453 |     EKind = DeclarationNameExtra::CXXConversionFunction; | 
 | 454 |     break; | 
 | 455 |   default: | 
 | 456 |     return DeclarationName(); | 
 | 457 |   } | 
 | 458 |  | 
 | 459 |   // Unique selector, to guarantee there is one per name. | 
 | 460 |   llvm::FoldingSetNodeID ID; | 
 | 461 |   ID.AddInteger(EKind); | 
 | 462 |   ID.AddPointer(Ty.getAsOpaquePtr()); | 
 | 463 |  | 
 | 464 |   void *InsertPos = 0; | 
 | 465 |   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) | 
 | 466 |     return DeclarationName(Name); | 
 | 467 |  | 
 | 468 |   CXXSpecialName *SpecialName = new CXXSpecialName; | 
 | 469 |   SpecialName->ExtraKindOrNumArgs = EKind; | 
 | 470 |   SpecialName->Type = Ty; | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 471 |   SpecialName->FETokenInfo = 0; | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 472 |  | 
 | 473 |   SpecialNames->InsertNode(SpecialName, InsertPos); | 
 | 474 |   return DeclarationName(SpecialName); | 
 | 475 | } | 
 | 476 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 477 | DeclarationName | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 478 | DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { | 
 | 479 |   return DeclarationName(&CXXOperatorNames[(unsigned)Op]); | 
 | 480 | } | 
 | 481 |  | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 482 | DeclarationName | 
 | 483 | DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 484 |   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames | 
 | 485 |     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> | 
 | 486 |                                                       (CXXLiteralOperatorNames); | 
 | 487 |  | 
 | 488 |   llvm::FoldingSetNodeID ID; | 
 | 489 |   ID.AddPointer(II); | 
 | 490 |  | 
 | 491 |   void *InsertPos = 0; | 
 | 492 |   if (CXXLiteralOperatorIdName *Name = | 
 | 493 |                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) | 
 | 494 |     return DeclarationName (Name); | 
 | 495 |    | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 496 |   CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName; | 
 | 497 |   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; | 
 | 498 |   LiteralName->ID = II; | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 499 |  | 
 | 500 |   LiteralNames->InsertNode(LiteralName, InsertPos); | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 501 |   return DeclarationName(LiteralName); | 
 | 502 | } | 
 | 503 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 504 | unsigned | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 505 | llvm::DenseMapInfo<clang::DeclarationName>:: | 
 | 506 | getHashValue(clang::DeclarationName N) { | 
 | 507 |   return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr()); | 
 | 508 | } | 
 | 509 |  |