| 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 | //===----------------------------------------------------------------------===// | 
 | 14 | #include "clang/AST/DeclarationName.h" | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 15 | #include "clang/AST/Type.h" | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame^] | 16 | #include "clang/AST/TypeOrdering.h" | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 17 | #include "clang/AST/Decl.h" | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 18 | #include "clang/Basic/IdentifierTable.h" | 
| Douglas Gregor | 370187c | 2009-04-22 21:45:53 +0000 | [diff] [blame] | 19 | #include "llvm/ADT/DenseMap.h" | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/FoldingSet.h" | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 21 | using namespace clang; | 
 | 22 |  | 
 | 23 | namespace clang { | 
 | 24 | /// CXXSpecialName - Records the type associated with one of the | 
 | 25 | /// "special" kinds of declaration names in C++, e.g., constructors, | 
 | 26 | /// destructors, and conversion functions. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 27 | class CXXSpecialName | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 28 |   : public DeclarationNameExtra, public llvm::FoldingSetNode { | 
 | 29 | public: | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 30 |   /// Type - The type associated with this declaration name. | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 31 |   QualType Type; | 
 | 32 |  | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 33 |   /// FETokenInfo - Extra information associated with this declaration | 
 | 34 |   /// name that can be used by the front end. | 
 | 35 |   void *FETokenInfo; | 
 | 36 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 37 |   void Profile(llvm::FoldingSetNodeID &ID) { | 
 | 38 |     ID.AddInteger(ExtraKindOrNumArgs); | 
 | 39 |     ID.AddPointer(Type.getAsOpaquePtr()); | 
 | 40 |   } | 
 | 41 | }; | 
 | 42 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 43 | /// CXXOperatorIdName - Contains extra information for the name of an | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 44 | /// overloaded operator in C++, such as "operator+. | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 45 | class CXXOperatorIdName : public DeclarationNameExtra { | 
 | 46 | public: | 
 | 47 |   /// FETokenInfo - Extra information associated with this operator | 
 | 48 |   /// name that can be used by the front end. | 
 | 49 |   void *FETokenInfo; | 
 | 50 | }; | 
 | 51 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 52 | bool operator<(DeclarationName LHS, DeclarationName RHS) { | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame^] | 53 |   if (LHS.getNameKind() != RHS.getNameKind()) | 
 | 54 |     return LHS.getNameKind() < RHS.getNameKind(); | 
 | 55 |    | 
 | 56 |   switch (LHS.getNameKind()) { | 
 | 57 |   case DeclarationName::Identifier: | 
 | 58 |     return LHS.getAsIdentifierInfo()->getName() <  | 
 | 59 |                                          RHS.getAsIdentifierInfo()->getName(); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 60 |  | 
| Douglas Gregor | d6b5f13 | 2009-11-04 22:24:30 +0000 | [diff] [blame^] | 61 |   case DeclarationName::ObjCZeroArgSelector: | 
 | 62 |   case DeclarationName::ObjCOneArgSelector: | 
 | 63 |   case DeclarationName::ObjCMultiArgSelector: { | 
 | 64 |     Selector LHSSelector = LHS.getObjCSelector(); | 
 | 65 |     Selector RHSSelector = RHS.getObjCSelector(); | 
 | 66 |     for (unsigned I = 0,  | 
 | 67 |                N = std::min(LHSSelector.getNumArgs(), RHSSelector.getNumArgs()); | 
 | 68 |          I != N; ++I) { | 
 | 69 |       IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I); | 
 | 70 |       IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I); | 
 | 71 |       if (!LHSId || !RHSId) | 
 | 72 |         return LHSId && !RHSId; | 
 | 73 |          | 
 | 74 |       switch (LHSId->getName().compare(RHSId->getName())) { | 
 | 75 |       case -1: return true; | 
 | 76 |       case 1: return false; | 
 | 77 |       default: break; | 
 | 78 |       } | 
 | 79 |     } | 
 | 80 |      | 
 | 81 |     return LHSSelector.getNumArgs() < RHSSelector.getNumArgs(); | 
 | 82 |   } | 
 | 83 |    | 
 | 84 |   case DeclarationName::CXXConstructorName: | 
 | 85 |   case DeclarationName::CXXDestructorName: | 
 | 86 |   case DeclarationName::CXXConversionFunctionName: | 
 | 87 |     return QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()); | 
 | 88 |                | 
 | 89 |   case DeclarationName::CXXOperatorName: | 
 | 90 |     return LHS.getCXXOverloadedOperator() < RHS.getCXXOverloadedOperator(); | 
 | 91 |                | 
 | 92 |   case DeclarationName::CXXUsingDirective: | 
 | 93 |     return false; | 
 | 94 |   } | 
 | 95 |                | 
 | 96 |   return false; | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 97 | } | 
 | 98 |  | 
 | 99 | } // end namespace clang | 
 | 100 |  | 
 | 101 | DeclarationName::DeclarationName(Selector Sel) { | 
| Douglas Gregor | 319ac89 | 2009-04-23 22:29:11 +0000 | [diff] [blame] | 102 |   if (!Sel.getAsOpaquePtr()) { | 
| Douglas Gregor | 813a97b | 2009-10-17 17:25:45 +0000 | [diff] [blame] | 103 |     Ptr = 0; | 
| Douglas Gregor | 319ac89 | 2009-04-23 22:29:11 +0000 | [diff] [blame] | 104 |     return; | 
 | 105 |   } | 
 | 106 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 107 |   switch (Sel.getNumArgs()) { | 
 | 108 |   case 0: | 
 | 109 |     Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); | 
| Ted Kremenek | 3eb8dd7 | 2009-03-14 00:27:40 +0000 | [diff] [blame] | 110 |     assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 111 |     Ptr |= StoredObjCZeroArgSelector; | 
 | 112 |     break; | 
 | 113 |  | 
 | 114 |   case 1: | 
 | 115 |     Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); | 
| Ted Kremenek | 3eb8dd7 | 2009-03-14 00:27:40 +0000 | [diff] [blame] | 116 |     assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 117 |     Ptr |= StoredObjCOneArgSelector; | 
 | 118 |     break; | 
 | 119 |  | 
 | 120 |   default: | 
 | 121 |     Ptr = Sel.InfoPtr & ~Selector::ArgFlags; | 
| Ted Kremenek | 3eb8dd7 | 2009-03-14 00:27:40 +0000 | [diff] [blame] | 122 |     assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector"); | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 123 |     Ptr |= StoredDeclarationNameExtra; | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 124 |     break; | 
 | 125 |   } | 
 | 126 | } | 
 | 127 |  | 
 | 128 | DeclarationName::NameKind DeclarationName::getNameKind() const { | 
 | 129 |   switch (getStoredNameKind()) { | 
 | 130 |   case StoredIdentifier:          return Identifier; | 
 | 131 |   case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; | 
 | 132 |   case StoredObjCOneArgSelector:  return ObjCOneArgSelector; | 
 | 133 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 134 |   case StoredDeclarationNameExtra: | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 135 |     switch (getExtra()->ExtraKindOrNumArgs) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 136 |     case DeclarationNameExtra::CXXConstructor: | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 137 |       return CXXConstructorName; | 
 | 138 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 139 |     case DeclarationNameExtra::CXXDestructor: | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 140 |       return CXXDestructorName; | 
 | 141 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 142 |     case DeclarationNameExtra::CXXConversionFunction: | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 143 |       return CXXConversionFunctionName; | 
 | 144 |  | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 145 |     case DeclarationNameExtra::CXXUsingDirective: | 
 | 146 |       return CXXUsingDirective; | 
 | 147 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 148 |     default: | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 149 |       // Check if we have one of the CXXOperator* enumeration values. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 150 |       if (getExtra()->ExtraKindOrNumArgs < | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 151 |             DeclarationNameExtra::CXXUsingDirective) | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 152 |         return CXXOperatorName; | 
 | 153 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 154 |       return ObjCMultiArgSelector; | 
 | 155 |     } | 
 | 156 |     break; | 
 | 157 |   } | 
 | 158 |  | 
 | 159 |   // Can't actually get here. | 
| Chris Lattner | ac8d75f | 2009-03-21 06:40:50 +0000 | [diff] [blame] | 160 |   assert(0 && "This should be unreachable!"); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 161 |   return Identifier; | 
 | 162 | } | 
 | 163 |  | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 164 | std::string DeclarationName::getAsString() const { | 
 | 165 |   switch (getNameKind()) { | 
 | 166 |   case Identifier: | 
 | 167 |     if (const IdentifierInfo *II = getAsIdentifierInfo()) | 
 | 168 |       return II->getName(); | 
 | 169 |     return ""; | 
 | 170 |  | 
 | 171 |   case ObjCZeroArgSelector: | 
 | 172 |   case ObjCOneArgSelector: | 
 | 173 |   case ObjCMultiArgSelector: | 
| Chris Lattner | 077bf5e | 2008-11-24 03:33:13 +0000 | [diff] [blame] | 174 |     return getObjCSelector().getAsString(); | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 175 |  | 
 | 176 |   case CXXConstructorName: { | 
 | 177 |     QualType ClassType = getCXXNameType(); | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 178 |     if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) | 
| Chris Lattner | 39f34e9 | 2008-11-24 04:00:27 +0000 | [diff] [blame] | 179 |       return ClassRec->getDecl()->getNameAsString(); | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 180 |     return ClassType.getAsString(); | 
 | 181 |   } | 
 | 182 |  | 
 | 183 |   case CXXDestructorName: { | 
 | 184 |     std::string Result = "~"; | 
 | 185 |     QualType Type = getCXXNameType(); | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 186 |     if (const RecordType *Rec = Type->getAs<RecordType>()) | 
| Chris Lattner | 39f34e9 | 2008-11-24 04:00:27 +0000 | [diff] [blame] | 187 |       Result += Rec->getDecl()->getNameAsString(); | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 188 |     else | 
 | 189 |       Result += Type.getAsString(); | 
 | 190 |     return Result; | 
 | 191 |   } | 
 | 192 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 193 |   case CXXOperatorName: { | 
 | 194 |     static const char *OperatorNames[NUM_OVERLOADED_OPERATORS] = { | 
 | 195 |       0, | 
 | 196 | #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ | 
 | 197 |       Spelling, | 
 | 198 | #include "clang/Basic/OperatorKinds.def" | 
 | 199 |     }; | 
 | 200 |     const char *OpName = OperatorNames[getCXXOverloadedOperator()]; | 
 | 201 |     assert(OpName && "not an overloaded operator"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 202 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 203 |     std::string Result = "operator"; | 
 | 204 |     if (OpName[0] >= 'a' && OpName[0] <= 'z') | 
 | 205 |       Result += ' '; | 
 | 206 |     Result += OpName; | 
 | 207 |     return Result; | 
 | 208 |   } | 
 | 209 |  | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 210 |   case CXXConversionFunctionName: { | 
 | 211 |     std::string Result = "operator "; | 
 | 212 |     QualType Type = getCXXNameType(); | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 213 |     if (const RecordType *Rec = Type->getAs<RecordType>()) | 
| Chris Lattner | 39f34e9 | 2008-11-24 04:00:27 +0000 | [diff] [blame] | 214 |       Result += Rec->getDecl()->getNameAsString(); | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 215 |     else | 
 | 216 |       Result += Type.getAsString(); | 
 | 217 |     return Result; | 
 | 218 |   } | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 219 |   case CXXUsingDirective: | 
 | 220 |     return "<using-directive>"; | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 221 |   } | 
 | 222 |  | 
 | 223 |   assert(false && "Unexpected declaration name kind"); | 
 | 224 |   return ""; | 
 | 225 | } | 
 | 226 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 227 | QualType DeclarationName::getCXXNameType() const { | 
 | 228 |   if (CXXSpecialName *CXXName = getAsCXXSpecialName()) | 
 | 229 |     return CXXName->Type; | 
 | 230 |   else | 
 | 231 |     return QualType(); | 
 | 232 | } | 
 | 233 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 234 | OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { | 
 | 235 |   if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 236 |     unsigned value | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 237 |       = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; | 
 | 238 |     return static_cast<OverloadedOperatorKind>(value); | 
 | 239 |   } else { | 
 | 240 |     return OO_None; | 
 | 241 |   } | 
 | 242 | } | 
 | 243 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 244 | Selector DeclarationName::getObjCSelector() const { | 
 | 245 |   switch (getNameKind()) { | 
 | 246 |   case ObjCZeroArgSelector: | 
 | 247 |     return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0); | 
 | 248 |  | 
 | 249 |   case ObjCOneArgSelector: | 
 | 250 |     return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1); | 
 | 251 |  | 
 | 252 |   case ObjCMultiArgSelector: | 
 | 253 |     return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask)); | 
 | 254 |  | 
 | 255 |   default: | 
 | 256 |     break; | 
 | 257 |   } | 
 | 258 |  | 
 | 259 |   return Selector(); | 
 | 260 | } | 
 | 261 |  | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 262 | void *DeclarationName::getFETokenInfoAsVoid() const { | 
 | 263 |   switch (getNameKind()) { | 
 | 264 |   case Identifier: | 
 | 265 |     return getAsIdentifierInfo()->getFETokenInfo<void>(); | 
 | 266 |  | 
 | 267 |   case CXXConstructorName: | 
 | 268 |   case CXXDestructorName: | 
 | 269 |   case CXXConversionFunctionName: | 
 | 270 |     return getAsCXXSpecialName()->FETokenInfo; | 
 | 271 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 272 |   case CXXOperatorName: | 
 | 273 |     return getAsCXXOperatorIdName()->FETokenInfo; | 
 | 274 |  | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 275 |   default: | 
 | 276 |     assert(false && "Declaration name has no FETokenInfo"); | 
 | 277 |   } | 
 | 278 |   return 0; | 
 | 279 | } | 
 | 280 |  | 
 | 281 | void DeclarationName::setFETokenInfo(void *T) { | 
 | 282 |   switch (getNameKind()) { | 
 | 283 |   case Identifier: | 
 | 284 |     getAsIdentifierInfo()->setFETokenInfo(T); | 
 | 285 |     break; | 
 | 286 |  | 
 | 287 |   case CXXConstructorName: | 
 | 288 |   case CXXDestructorName: | 
 | 289 |   case CXXConversionFunctionName: | 
 | 290 |     getAsCXXSpecialName()->FETokenInfo = T; | 
 | 291 |     break; | 
 | 292 |  | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 293 |   case CXXOperatorName: | 
 | 294 |     getAsCXXOperatorIdName()->FETokenInfo = T; | 
 | 295 |     break; | 
 | 296 |  | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 297 |   default: | 
 | 298 |     assert(false && "Declaration name has no FETokenInfo"); | 
 | 299 |   } | 
 | 300 | } | 
 | 301 |  | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 302 | DeclarationName DeclarationName::getUsingDirectiveName() { | 
 | 303 |   // Single instance of DeclarationNameExtra for using-directive | 
 | 304 |   static DeclarationNameExtra UDirExtra = | 
 | 305 |     { DeclarationNameExtra::CXXUsingDirective }; | 
 | 306 |  | 
 | 307 |   uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); | 
 | 308 |   Ptr |= StoredDeclarationNameExtra; | 
 | 309 |  | 
 | 310 |   return DeclarationName(Ptr); | 
 | 311 | } | 
 | 312 |  | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 313 | DeclarationNameTable::DeclarationNameTable() { | 
 | 314 |   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 315 |  | 
 | 316 |   // Initialize the overloaded operator names. | 
 | 317 |   CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; | 
 | 318 |   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 319 |     CXXOperatorNames[Op].ExtraKindOrNumArgs | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 320 |       = Op + DeclarationNameExtra::CXXConversionFunction; | 
 | 321 |     CXXOperatorNames[Op].FETokenInfo = 0; | 
 | 322 |   } | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 323 | } | 
 | 324 |  | 
 | 325 | DeclarationNameTable::~DeclarationNameTable() { | 
| Nuno Lopes | 6d34ae5 | 2008-12-14 17:27:25 +0000 | [diff] [blame] | 326 |   llvm::FoldingSet<CXXSpecialName> *set = | 
 | 327 |     static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); | 
| Nuno Lopes | f9d1e4b | 2008-12-14 21:53:25 +0000 | [diff] [blame] | 328 |   llvm::FoldingSetIterator<CXXSpecialName> I = set->begin(), E = set->end(); | 
| Nuno Lopes | 6d34ae5 | 2008-12-14 17:27:25 +0000 | [diff] [blame] | 329 |  | 
| Nuno Lopes | f9d1e4b | 2008-12-14 21:53:25 +0000 | [diff] [blame] | 330 |   while (I != E) { | 
 | 331 |     CXXSpecialName *n = &*I++; | 
 | 332 |     delete n; | 
| Nuno Lopes | 6d34ae5 | 2008-12-14 17:27:25 +0000 | [diff] [blame] | 333 |   } | 
 | 334 |  | 
 | 335 |   delete set; | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 336 |   delete [] CXXOperatorNames; | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 337 | } | 
 | 338 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 339 | DeclarationName | 
 | 340 | DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, | 
| Douglas Gregor | 50d62d1 | 2009-08-05 05:36:45 +0000 | [diff] [blame] | 341 |                                         CanQualType Ty) { | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 342 |   assert(Kind >= DeclarationName::CXXConstructorName && | 
 | 343 |          Kind <= DeclarationName::CXXConversionFunctionName && | 
 | 344 |          "Kind must be a C++ special name kind"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 345 |   llvm::FoldingSet<CXXSpecialName> *SpecialNames | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 346 |     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); | 
 | 347 |  | 
 | 348 |   DeclarationNameExtra::ExtraKind EKind; | 
 | 349 |   switch (Kind) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 350 |   case DeclarationName::CXXConstructorName: | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 351 |     EKind = DeclarationNameExtra::CXXConstructor; | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 352 |     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 353 |     break; | 
 | 354 |   case DeclarationName::CXXDestructorName: | 
 | 355 |     EKind = DeclarationNameExtra::CXXDestructor; | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 356 |     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 357 |     break; | 
 | 358 |   case DeclarationName::CXXConversionFunctionName: | 
 | 359 |     EKind = DeclarationNameExtra::CXXConversionFunction; | 
 | 360 |     break; | 
 | 361 |   default: | 
 | 362 |     return DeclarationName(); | 
 | 363 |   } | 
 | 364 |  | 
 | 365 |   // Unique selector, to guarantee there is one per name. | 
 | 366 |   llvm::FoldingSetNodeID ID; | 
 | 367 |   ID.AddInteger(EKind); | 
 | 368 |   ID.AddPointer(Ty.getAsOpaquePtr()); | 
 | 369 |  | 
 | 370 |   void *InsertPos = 0; | 
 | 371 |   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) | 
 | 372 |     return DeclarationName(Name); | 
 | 373 |  | 
 | 374 |   CXXSpecialName *SpecialName = new CXXSpecialName; | 
 | 375 |   SpecialName->ExtraKindOrNumArgs = EKind; | 
 | 376 |   SpecialName->Type = Ty; | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 377 |   SpecialName->FETokenInfo = 0; | 
| Douglas Gregor | 2e1cd42 | 2008-11-17 14:58:09 +0000 | [diff] [blame] | 378 |  | 
 | 379 |   SpecialNames->InsertNode(SpecialName, InsertPos); | 
 | 380 |   return DeclarationName(SpecialName); | 
 | 381 | } | 
 | 382 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 383 | DeclarationName | 
| Douglas Gregor | e94ca9e4 | 2008-11-18 14:39:36 +0000 | [diff] [blame] | 384 | DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { | 
 | 385 |   return DeclarationName(&CXXOperatorNames[(unsigned)Op]); | 
 | 386 | } | 
 | 387 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 388 | unsigned | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 389 | llvm::DenseMapInfo<clang::DeclarationName>:: | 
 | 390 | getHashValue(clang::DeclarationName N) { | 
 | 391 |   return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr()); | 
 | 392 | } | 
 | 393 |  |