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