DeclarationName.cpp 19 KB

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