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