NestedNameSpecifier.cpp 23 KB

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