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