DeclarationName.cpp 19 KB

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