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