NestedNameSpecifier.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. //===--- NestedNameSpecifier.cpp - C++ nested name specifiers -----*- 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 defines the NestedNameSpecifier class, which represents
  11. // a C++ nested-name-specifier.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "clang/AST/NestedNameSpecifier.h"
  15. #include "clang/AST/ASTContext.h"
  16. #include "clang/AST/Decl.h"
  17. #include "clang/AST/DeclCXX.h"
  18. #include "clang/AST/PrettyPrinter.h"
  19. #include "clang/AST/Type.h"
  20. #include "clang/AST/TypeLoc.h"
  21. #include "llvm/Support/AlignOf.h"
  22. #include "llvm/Support/raw_ostream.h"
  23. #include <cassert>
  24. // //
  25. ///////////////////////////////////////////////////////////////////////////////
  26. using namespace clang;
  27. NestedNameSpecifier *
  28. NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
  29. const NestedNameSpecifier &Mockup) {
  30. llvm::FoldingSetNodeID ID;
  31. Mockup.Profile(ID);
  32. void *InsertPos = nullptr;
  33. NestedNameSpecifier *NNS
  34. = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
  35. if (!NNS) {
  36. NNS = new (Context, llvm::alignOf<NestedNameSpecifier>())
  37. NestedNameSpecifier(Mockup);
  38. Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
  39. }
  40. return NNS;
  41. }
  42. NestedNameSpecifier *
  43. NestedNameSpecifier::Create(const ASTContext &Context,
  44. NestedNameSpecifier *Prefix, IdentifierInfo *II) {
  45. assert(II && "Identifier cannot be NULL");
  46. assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
  47. NestedNameSpecifier Mockup;
  48. Mockup.Prefix.setPointer(Prefix);
  49. Mockup.Prefix.setInt(StoredIdentifier);
  50. Mockup.Specifier = II;
  51. return FindOrInsert(Context, Mockup);
  52. }
  53. NestedNameSpecifier *
  54. NestedNameSpecifier::Create(const ASTContext &Context,
  55. NestedNameSpecifier *Prefix,
  56. const NamespaceDecl *NS) {
  57. assert(NS && "Namespace cannot be NULL");
  58. assert((!Prefix ||
  59. (Prefix->getAsType() == nullptr &&
  60. Prefix->getAsIdentifier() == nullptr)) &&
  61. "Broken nested name specifier");
  62. NestedNameSpecifier Mockup;
  63. Mockup.Prefix.setPointer(Prefix);
  64. Mockup.Prefix.setInt(StoredDecl);
  65. Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
  66. return FindOrInsert(Context, Mockup);
  67. }
  68. NestedNameSpecifier *
  69. NestedNameSpecifier::Create(const ASTContext &Context,
  70. NestedNameSpecifier *Prefix,
  71. NamespaceAliasDecl *Alias) {
  72. assert(Alias && "Namespace alias cannot be NULL");
  73. assert((!Prefix ||
  74. (Prefix->getAsType() == nullptr &&
  75. Prefix->getAsIdentifier() == nullptr)) &&
  76. "Broken nested name specifier");
  77. NestedNameSpecifier Mockup;
  78. Mockup.Prefix.setPointer(Prefix);
  79. Mockup.Prefix.setInt(StoredDecl);
  80. Mockup.Specifier = Alias;
  81. return FindOrInsert(Context, Mockup);
  82. }
  83. NestedNameSpecifier *
  84. NestedNameSpecifier::Create(const ASTContext &Context,
  85. NestedNameSpecifier *Prefix,
  86. bool Template, const Type *T) {
  87. assert(T && "Type cannot be NULL");
  88. NestedNameSpecifier Mockup;
  89. Mockup.Prefix.setPointer(Prefix);
  90. Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
  91. Mockup.Specifier = const_cast<Type*>(T);
  92. return FindOrInsert(Context, Mockup);
  93. }
  94. NestedNameSpecifier *
  95. NestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) {
  96. assert(II && "Identifier cannot be NULL");
  97. NestedNameSpecifier Mockup;
  98. Mockup.Prefix.setPointer(nullptr);
  99. Mockup.Prefix.setInt(StoredIdentifier);
  100. Mockup.Specifier = II;
  101. return FindOrInsert(Context, Mockup);
  102. }
  103. NestedNameSpecifier *
  104. NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
  105. if (!Context.GlobalNestedNameSpecifier)
  106. Context.GlobalNestedNameSpecifier =
  107. new (Context, llvm::alignOf<NestedNameSpecifier>())
  108. NestedNameSpecifier();
  109. return Context.GlobalNestedNameSpecifier;
  110. }
  111. NestedNameSpecifier *
  112. NestedNameSpecifier::SuperSpecifier(const ASTContext &Context,
  113. CXXRecordDecl *RD) {
  114. NestedNameSpecifier Mockup;
  115. Mockup.Prefix.setPointer(nullptr);
  116. Mockup.Prefix.setInt(StoredDecl);
  117. Mockup.Specifier = RD;
  118. return FindOrInsert(Context, Mockup);
  119. }
  120. NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
  121. if (!Specifier)
  122. return Global;
  123. switch (Prefix.getInt()) {
  124. case StoredIdentifier:
  125. return Identifier;
  126. case StoredDecl: {
  127. NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
  128. if (isa<CXXRecordDecl>(ND))
  129. return Super;
  130. return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
  131. }
  132. case StoredTypeSpec:
  133. return TypeSpec;
  134. case StoredTypeSpecWithTemplate:
  135. return TypeSpecWithTemplate;
  136. }
  137. llvm_unreachable("Invalid NNS Kind!");
  138. }
  139. /// \brief Retrieve the namespace stored in this nested name specifier.
  140. NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
  141. if (Prefix.getInt() == StoredDecl)
  142. return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
  143. return nullptr;
  144. }
  145. /// \brief Retrieve the namespace alias stored in this nested name specifier.
  146. NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
  147. if (Prefix.getInt() == StoredDecl)
  148. return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
  149. return nullptr;
  150. }
  151. /// \brief Retrieve the record declaration stored in this nested name specifier.
  152. CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const {
  153. if (Prefix.getInt() == StoredDecl)
  154. return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
  155. return nullptr;
  156. }
  157. /// \brief Whether this nested name specifier refers to a dependent
  158. /// type or not.
  159. bool NestedNameSpecifier::isDependent() const {
  160. switch (getKind()) {
  161. case Identifier:
  162. // Identifier specifiers always represent dependent types
  163. return true;
  164. case Namespace:
  165. case NamespaceAlias:
  166. case Global:
  167. return false;
  168. case Super: {
  169. CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
  170. for (const auto &Base : RD->bases())
  171. if (Base.getType()->isDependentType())
  172. return true;
  173. return false;
  174. }
  175. case TypeSpec:
  176. case TypeSpecWithTemplate:
  177. return getAsType()->isDependentType();
  178. }
  179. llvm_unreachable("Invalid NNS Kind!");
  180. }
  181. /// \brief Whether this nested name specifier refers to a dependent
  182. /// type or not.
  183. bool NestedNameSpecifier::isInstantiationDependent() const {
  184. switch (getKind()) {
  185. case Identifier:
  186. // Identifier specifiers always represent dependent types
  187. return true;
  188. case Namespace:
  189. case NamespaceAlias:
  190. case Global:
  191. case Super:
  192. return false;
  193. case TypeSpec:
  194. case TypeSpecWithTemplate:
  195. return getAsType()->isInstantiationDependentType();
  196. }
  197. llvm_unreachable("Invalid NNS Kind!");
  198. }
  199. bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
  200. switch (getKind()) {
  201. case Identifier:
  202. return getPrefix() && getPrefix()->containsUnexpandedParameterPack();
  203. case Namespace:
  204. case NamespaceAlias:
  205. case Global:
  206. case Super:
  207. return false;
  208. case TypeSpec:
  209. case TypeSpecWithTemplate:
  210. return getAsType()->containsUnexpandedParameterPack();
  211. }
  212. llvm_unreachable("Invalid NNS Kind!");
  213. }
  214. /// \brief Print this nested name specifier to the given output
  215. /// stream.
  216. void
  217. NestedNameSpecifier::print(raw_ostream &OS,
  218. const PrintingPolicy &Policy) const {
  219. if (getPrefix())
  220. getPrefix()->print(OS, Policy);
  221. switch (getKind()) {
  222. case Identifier:
  223. OS << getAsIdentifier()->getName();
  224. break;
  225. case Namespace:
  226. if (getAsNamespace()->isAnonymousNamespace())
  227. return;
  228. OS << getAsNamespace()->getName();
  229. break;
  230. case NamespaceAlias:
  231. OS << getAsNamespaceAlias()->getName();
  232. break;
  233. case Global:
  234. break;
  235. case Super:
  236. OS << "__super";
  237. break;
  238. case TypeSpecWithTemplate:
  239. OS << "template ";
  240. // Fall through to print the type.
  241. case TypeSpec: {
  242. const Type *T = getAsType();
  243. PrintingPolicy InnerPolicy(Policy);
  244. InnerPolicy.SuppressScope = true;
  245. // Nested-name-specifiers are intended to contain minimally-qualified
  246. // types. An actual ElaboratedType will not occur, since we'll store
  247. // just the type that is referred to in the nested-name-specifier (e.g.,
  248. // a TypedefType, TagType, etc.). However, when we are dealing with
  249. // dependent template-id types (e.g., Outer<T>::template Inner<U>),
  250. // the type requires its own nested-name-specifier for uniqueness, so we
  251. // suppress that nested-name-specifier during printing.
  252. assert(!isa<ElaboratedType>(T) &&
  253. "Elaborated type in nested-name-specifier");
  254. if (const TemplateSpecializationType *SpecType
  255. = dyn_cast<TemplateSpecializationType>(T)) {
  256. // Print the template name without its corresponding
  257. // nested-name-specifier.
  258. SpecType->getTemplateName().print(OS, InnerPolicy, true);
  259. // Print the template argument list.
  260. TemplateSpecializationType::PrintTemplateArgumentList(
  261. OS, SpecType->getArgs(), SpecType->getNumArgs(), InnerPolicy);
  262. } else {
  263. // Print the type normally
  264. QualType(T, 0).print(OS, InnerPolicy);
  265. }
  266. break;
  267. }
  268. }
  269. OS << "::";
  270. }
  271. void NestedNameSpecifier::dump(const LangOptions &LO) {
  272. print(llvm::errs(), PrintingPolicy(LO));
  273. }
  274. unsigned
  275. NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
  276. assert(Qualifier && "Expected a non-NULL qualifier");
  277. // Location of the trailing '::'.
  278. unsigned Length = sizeof(unsigned);
  279. switch (Qualifier->getKind()) {
  280. case NestedNameSpecifier::Global:
  281. // Nothing more to add.
  282. break;
  283. case NestedNameSpecifier::Identifier:
  284. case NestedNameSpecifier::Namespace:
  285. case NestedNameSpecifier::NamespaceAlias:
  286. case NestedNameSpecifier::Super:
  287. // The location of the identifier or namespace name.
  288. Length += sizeof(unsigned);
  289. break;
  290. case NestedNameSpecifier::TypeSpecWithTemplate:
  291. case NestedNameSpecifier::TypeSpec:
  292. // The "void*" that points at the TypeLoc data.
  293. // Note: the 'template' keyword is part of the TypeLoc.
  294. Length += sizeof(void *);
  295. break;
  296. }
  297. return Length;
  298. }
  299. unsigned
  300. NestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) {
  301. unsigned Length = 0;
  302. for (; Qualifier; Qualifier = Qualifier->getPrefix())
  303. Length += getLocalDataLength(Qualifier);
  304. return Length;
  305. }
  306. namespace {
  307. /// \brief Load a (possibly unaligned) source location from a given address
  308. /// and offset.
  309. SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
  310. unsigned Raw;
  311. memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned));
  312. return SourceLocation::getFromRawEncoding(Raw);
  313. }
  314. /// \brief Load a (possibly unaligned) pointer from a given address and
  315. /// offset.
  316. void *LoadPointer(void *Data, unsigned Offset) {
  317. void *Result;
  318. memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
  319. return Result;
  320. }
  321. }
  322. SourceRange NestedNameSpecifierLoc::getSourceRange() const {
  323. if (!Qualifier)
  324. return SourceRange();
  325. NestedNameSpecifierLoc First = *this;
  326. while (NestedNameSpecifierLoc Prefix = First.getPrefix())
  327. First = Prefix;
  328. return SourceRange(First.getLocalSourceRange().getBegin(),
  329. getLocalSourceRange().getEnd());
  330. }
  331. SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
  332. if (!Qualifier)
  333. return SourceRange();
  334. unsigned Offset = getDataLength(Qualifier->getPrefix());
  335. switch (Qualifier->getKind()) {
  336. case NestedNameSpecifier::Global:
  337. return LoadSourceLocation(Data, Offset);
  338. case NestedNameSpecifier::Identifier:
  339. case NestedNameSpecifier::Namespace:
  340. case NestedNameSpecifier::NamespaceAlias:
  341. case NestedNameSpecifier::Super:
  342. return SourceRange(LoadSourceLocation(Data, Offset),
  343. LoadSourceLocation(Data, Offset + sizeof(unsigned)));
  344. case NestedNameSpecifier::TypeSpecWithTemplate:
  345. case NestedNameSpecifier::TypeSpec: {
  346. // The "void*" that points at the TypeLoc data.
  347. // Note: the 'template' keyword is part of the TypeLoc.
  348. void *TypeData = LoadPointer(Data, Offset);
  349. TypeLoc TL(Qualifier->getAsType(), TypeData);
  350. return SourceRange(TL.getBeginLoc(),
  351. LoadSourceLocation(Data, Offset + sizeof(void*)));
  352. }
  353. }
  354. llvm_unreachable("Invalid NNS Kind!");
  355. }
  356. TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
  357. assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec ||
  358. Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) &&
  359. "Nested-name-specifier location is not a type");
  360. // The "void*" that points at the TypeLoc data.
  361. unsigned Offset = getDataLength(Qualifier->getPrefix());
  362. void *TypeData = LoadPointer(Data, Offset);
  363. return TypeLoc(Qualifier->getAsType(), TypeData);
  364. }
  365. namespace {
  366. void Append(_In_reads_to_ptr_(End) char *Start, _In_reads_(0) char *End, _Outref_result_buffer_(BufferSize) char *&Buffer, unsigned &BufferSize,
  367. unsigned &BufferCapacity) {
  368. if (Start == End)
  369. return;
  370. if (BufferSize + (End - Start) > BufferCapacity) {
  371. // Reallocate the buffer.
  372. unsigned NewCapacity = std::max(
  373. (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
  374. (unsigned)(BufferSize + (End - Start)));
  375. char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
  376. if (BufferCapacity) {
  377. memcpy(NewBuffer, Buffer, BufferSize);
  378. free(Buffer);
  379. }
  380. Buffer = NewBuffer;
  381. BufferCapacity = NewCapacity;
  382. }
  383. memcpy(Buffer + BufferSize, Start, End - Start);
  384. BufferSize += End-Start;
  385. }
  386. /// \brief Save a source location to the given buffer.
  387. void SaveSourceLocation(SourceLocation Loc, _Outref_result_buffer_(BufferSize) char *&Buffer,
  388. unsigned &BufferSize, unsigned &BufferCapacity) {
  389. unsigned Raw = Loc.getRawEncoding();
  390. Append(reinterpret_cast<char *>(&Raw),
  391. reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
  392. Buffer, BufferSize, BufferCapacity);
  393. }
  394. /// \brief Save a pointer to the given buffer.
  395. void SavePointer(void *Ptr, _Outref_result_buffer_(BufferSize) char *&Buffer, unsigned &BufferSize,
  396. unsigned &BufferCapacity) {
  397. Append(reinterpret_cast<char *>(&Ptr),
  398. reinterpret_cast<char *>(&Ptr) + sizeof(void *),
  399. Buffer, BufferSize, BufferCapacity);
  400. }
  401. }
  402. NestedNameSpecifierLocBuilder::
  403. NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other)
  404. : Representation(Other.Representation), Buffer(nullptr),
  405. BufferSize(0), BufferCapacity(0)
  406. {
  407. if (!Other.Buffer)
  408. return;
  409. if (Other.BufferCapacity == 0) {
  410. // Shallow copy is okay.
  411. Buffer = Other.Buffer;
  412. BufferSize = Other.BufferSize;
  413. return;
  414. }
  415. // Deep copy
  416. Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
  417. BufferCapacity);
  418. }
  419. NestedNameSpecifierLocBuilder &
  420. NestedNameSpecifierLocBuilder::
  421. operator=(const NestedNameSpecifierLocBuilder &Other) {
  422. Representation = Other.Representation;
  423. if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
  424. // Re-use our storage.
  425. BufferSize = Other.BufferSize;
  426. memcpy(Buffer, Other.Buffer, BufferSize);
  427. return *this;
  428. }
  429. // Free our storage, if we have any.
  430. if (BufferCapacity) {
  431. free(Buffer);
  432. BufferCapacity = 0;
  433. }
  434. if (!Other.Buffer) {
  435. // Empty.
  436. Buffer = nullptr;
  437. BufferSize = 0;
  438. return *this;
  439. }
  440. if (Other.BufferCapacity == 0) {
  441. // Shallow copy is okay.
  442. Buffer = Other.Buffer;
  443. BufferSize = Other.BufferSize;
  444. return *this;
  445. }
  446. // Deep copy.
  447. Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
  448. BufferCapacity);
  449. return *this;
  450. }
  451. void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
  452. SourceLocation TemplateKWLoc,
  453. TypeLoc TL,
  454. SourceLocation ColonColonLoc) {
  455. Representation = NestedNameSpecifier::Create(Context, Representation,
  456. TemplateKWLoc.isValid(),
  457. TL.getTypePtr());
  458. // Push source-location info into the buffer.
  459. SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
  460. SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
  461. }
  462. void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
  463. IdentifierInfo *Identifier,
  464. SourceLocation IdentifierLoc,
  465. SourceLocation ColonColonLoc) {
  466. Representation = NestedNameSpecifier::Create(Context, Representation,
  467. Identifier);
  468. // Push source-location info into the buffer.
  469. SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
  470. SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
  471. }
  472. void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
  473. NamespaceDecl *Namespace,
  474. SourceLocation NamespaceLoc,
  475. SourceLocation ColonColonLoc) {
  476. Representation = NestedNameSpecifier::Create(Context, Representation,
  477. Namespace);
  478. // Push source-location info into the buffer.
  479. SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
  480. SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
  481. }
  482. void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
  483. NamespaceAliasDecl *Alias,
  484. SourceLocation AliasLoc,
  485. SourceLocation ColonColonLoc) {
  486. Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
  487. // Push source-location info into the buffer.
  488. SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
  489. SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
  490. }
  491. void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context,
  492. SourceLocation ColonColonLoc) {
  493. assert(!Representation && "Already have a nested-name-specifier!?");
  494. Representation = NestedNameSpecifier::GlobalSpecifier(Context);
  495. // Push source-location info into the buffer.
  496. SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
  497. }
  498. void NestedNameSpecifierLocBuilder::MakeSuper(ASTContext &Context,
  499. CXXRecordDecl *RD,
  500. SourceLocation SuperLoc,
  501. SourceLocation ColonColonLoc) {
  502. Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
  503. // Push source-location info into the buffer.
  504. SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
  505. SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
  506. }
  507. void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
  508. NestedNameSpecifier *Qualifier,
  509. SourceRange R) {
  510. Representation = Qualifier;
  511. // Construct bogus (but well-formed) source information for the
  512. // nested-name-specifier.
  513. BufferSize = 0;
  514. SmallVector<NestedNameSpecifier *, 4> Stack;
  515. for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
  516. Stack.push_back(NNS);
  517. while (!Stack.empty()) {
  518. NestedNameSpecifier *NNS = Stack.pop_back_val();
  519. switch (NNS->getKind()) {
  520. case NestedNameSpecifier::Identifier:
  521. case NestedNameSpecifier::Namespace:
  522. case NestedNameSpecifier::NamespaceAlias:
  523. SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
  524. break;
  525. case NestedNameSpecifier::TypeSpec:
  526. case NestedNameSpecifier::TypeSpecWithTemplate: {
  527. TypeSourceInfo *TSInfo
  528. = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
  529. R.getBegin());
  530. SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
  531. BufferCapacity);
  532. break;
  533. }
  534. case NestedNameSpecifier::Global:
  535. case NestedNameSpecifier::Super:
  536. break;
  537. }
  538. // Save the location of the '::'.
  539. SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
  540. Buffer, BufferSize, BufferCapacity);
  541. }
  542. }
  543. void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) {
  544. if (BufferCapacity)
  545. free(Buffer);
  546. if (!Other) {
  547. Representation = nullptr;
  548. BufferSize = 0;
  549. return;
  550. }
  551. // Rather than copying the data (which is wasteful), "adopt" the
  552. // pointer (which points into the ASTContext) but set the capacity to zero to
  553. // indicate that we don't own it.
  554. Representation = Other.getNestedNameSpecifier();
  555. Buffer = static_cast<char *>(Other.getOpaqueData());
  556. BufferSize = Other.getDataLength();
  557. BufferCapacity = 0;
  558. }
  559. NestedNameSpecifierLoc
  560. NestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const {
  561. if (!Representation)
  562. return NestedNameSpecifierLoc();
  563. // If we adopted our data pointer from elsewhere in the AST context, there's
  564. // no need to copy the memory.
  565. if (BufferCapacity == 0)
  566. return NestedNameSpecifierLoc(Representation, Buffer);
  567. // FIXME: After copying the source-location information, should we free
  568. // our (temporary) buffer and adopt the ASTContext-allocated memory?
  569. // Doing so would optimize repeated calls to getWithLocInContext().
  570. void *Mem = Context.Allocate(BufferSize, llvm::alignOf<void *>());
  571. memcpy(Mem, Buffer, BufferSize);
  572. return NestedNameSpecifierLoc(Representation, Mem);
  573. }