NestedNameSpecifier.cpp 23 KB

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