121fadadbSEugene Zelenko //===- NestedNameSpecifier.cpp - C++ nested name specifiers ---------------===//
25253768aSDouglas Gregor //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65253768aSDouglas Gregor //
75253768aSDouglas Gregor //===----------------------------------------------------------------------===//
85253768aSDouglas Gregor //
95253768aSDouglas Gregor // This file defines the NestedNameSpecifier class, which represents
105253768aSDouglas Gregor // a C++ nested-name-specifier.
115253768aSDouglas Gregor //
125253768aSDouglas Gregor //===----------------------------------------------------------------------===//
1321fadadbSEugene Zelenko
145253768aSDouglas Gregor #include "clang/AST/NestedNameSpecifier.h"
155253768aSDouglas Gregor #include "clang/AST/ASTContext.h"
165253768aSDouglas Gregor #include "clang/AST/Decl.h"
177b26ff91SDouglas Gregor #include "clang/AST/DeclCXX.h"
189d432e0dSClement Courbet #include "clang/AST/DeclTemplate.h"
1967d25914SHaojian Wu #include "clang/AST/DependenceFlags.h"
207de5966dSDouglas Gregor #include "clang/AST/PrettyPrinter.h"
2121fadadbSEugene Zelenko #include "clang/AST/TemplateName.h"
225253768aSDouglas Gregor #include "clang/AST/Type.h"
23869ad45fSDouglas Gregor #include "clang/AST/TypeLoc.h"
2421fadadbSEugene Zelenko #include "clang/Basic/LLVM.h"
2521fadadbSEugene Zelenko #include "clang/Basic/LangOptions.h"
2621fadadbSEugene Zelenko #include "clang/Basic/SourceLocation.h"
2721fadadbSEugene Zelenko #include "llvm/ADT/FoldingSet.h"
2821fadadbSEugene Zelenko #include "llvm/ADT/SmallVector.h"
2921fadadbSEugene Zelenko #include "llvm/Support/Casting.h"
3021fadadbSEugene Zelenko #include "llvm/Support/Compiler.h"
3121fadadbSEugene Zelenko #include "llvm/Support/ErrorHandling.h"
3218353910SDouglas Gregor #include "llvm/Support/raw_ostream.h"
3321fadadbSEugene Zelenko #include <algorithm>
34f21eb49aSDouglas Gregor #include <cassert>
3521fadadbSEugene Zelenko #include <cstdlib>
3621fadadbSEugene Zelenko #include <cstring>
3718353910SDouglas Gregor
385253768aSDouglas Gregor using namespace clang;
395253768aSDouglas Gregor
40f21eb49aSDouglas Gregor NestedNameSpecifier *
FindOrInsert(const ASTContext & Context,const NestedNameSpecifier & Mockup)4139c79807SJay Foad NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
42f21eb49aSDouglas Gregor const NestedNameSpecifier &Mockup) {
43f21eb49aSDouglas Gregor llvm::FoldingSetNodeID ID;
44f21eb49aSDouglas Gregor Mockup.Profile(ID);
455253768aSDouglas Gregor
4636250ad6SCraig Topper void *InsertPos = nullptr;
47f21eb49aSDouglas Gregor NestedNameSpecifier *NNS
48f21eb49aSDouglas Gregor = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
49f21eb49aSDouglas Gregor if (!NNS) {
50c3f89253SBenjamin Kramer NNS =
51c3f89253SBenjamin Kramer new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(Mockup);
52f21eb49aSDouglas Gregor Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
535253768aSDouglas Gregor }
5418353910SDouglas Gregor
55f21eb49aSDouglas Gregor return NNS;
56f21eb49aSDouglas Gregor }
57f21eb49aSDouglas Gregor
58f21eb49aSDouglas Gregor NestedNameSpecifier *
Create(const ASTContext & Context,NestedNameSpecifier * Prefix,IdentifierInfo * II)5939c79807SJay Foad NestedNameSpecifier::Create(const ASTContext &Context,
6039c79807SJay Foad NestedNameSpecifier *Prefix, IdentifierInfo *II) {
61f21eb49aSDouglas Gregor assert(II && "Identifier cannot be NULL");
62308047d3SDouglas Gregor assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
63f21eb49aSDouglas Gregor
64f21eb49aSDouglas Gregor NestedNameSpecifier Mockup;
65dce2b62bSDouglas Gregor Mockup.Prefix.setPointer(Prefix);
667b26ff91SDouglas Gregor Mockup.Prefix.setInt(StoredIdentifier);
67dce2b62bSDouglas Gregor Mockup.Specifier = II;
68f21eb49aSDouglas Gregor return FindOrInsert(Context, Mockup);
69f21eb49aSDouglas Gregor }
70f21eb49aSDouglas Gregor
71f21eb49aSDouglas Gregor NestedNameSpecifier *
Create(const ASTContext & Context,NestedNameSpecifier * Prefix,const NamespaceDecl * NS)7239c79807SJay Foad NestedNameSpecifier::Create(const ASTContext &Context,
73aeeca770SDmitri Gribenko NestedNameSpecifier *Prefix,
74aeeca770SDmitri Gribenko const NamespaceDecl *NS) {
75f21eb49aSDouglas Gregor assert(NS && "Namespace cannot be NULL");
76f21eb49aSDouglas Gregor assert((!Prefix ||
7736250ad6SCraig Topper (Prefix->getAsType() == nullptr &&
7836250ad6SCraig Topper Prefix->getAsIdentifier() == nullptr)) &&
79f21eb49aSDouglas Gregor "Broken nested name specifier");
80f21eb49aSDouglas Gregor NestedNameSpecifier Mockup;
81dce2b62bSDouglas Gregor Mockup.Prefix.setPointer(Prefix);
8267860249SNikola Smiljanic Mockup.Prefix.setInt(StoredDecl);
83aeeca770SDmitri Gribenko Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
84f21eb49aSDouglas Gregor return FindOrInsert(Context, Mockup);
85f21eb49aSDouglas Gregor }
86f21eb49aSDouglas Gregor
87f21eb49aSDouglas Gregor NestedNameSpecifier *
Create(const ASTContext & Context,NestedNameSpecifier * Prefix,NamespaceAliasDecl * Alias)8839c79807SJay Foad NestedNameSpecifier::Create(const ASTContext &Context,
8939c79807SJay Foad NestedNameSpecifier *Prefix,
907b26ff91SDouglas Gregor NamespaceAliasDecl *Alias) {
917b26ff91SDouglas Gregor assert(Alias && "Namespace alias cannot be NULL");
927b26ff91SDouglas Gregor assert((!Prefix ||
9336250ad6SCraig Topper (Prefix->getAsType() == nullptr &&
9436250ad6SCraig Topper Prefix->getAsIdentifier() == nullptr)) &&
957b26ff91SDouglas Gregor "Broken nested name specifier");
967b26ff91SDouglas Gregor NestedNameSpecifier Mockup;
977b26ff91SDouglas Gregor Mockup.Prefix.setPointer(Prefix);
9867860249SNikola Smiljanic Mockup.Prefix.setInt(StoredDecl);
997b26ff91SDouglas Gregor Mockup.Specifier = Alias;
1007b26ff91SDouglas Gregor return FindOrInsert(Context, Mockup);
1017b26ff91SDouglas Gregor }
1027b26ff91SDouglas Gregor
1037b26ff91SDouglas Gregor NestedNameSpecifier *
Create(const ASTContext & Context,NestedNameSpecifier * Prefix,bool Template,const Type * T)1047b26ff91SDouglas Gregor NestedNameSpecifier::Create(const ASTContext &Context,
1057b26ff91SDouglas Gregor NestedNameSpecifier *Prefix,
106424cec97SJohn McCall bool Template, const Type *T) {
107f21eb49aSDouglas Gregor assert(T && "Type cannot be NULL");
108f21eb49aSDouglas Gregor NestedNameSpecifier Mockup;
109dce2b62bSDouglas Gregor Mockup.Prefix.setPointer(Prefix);
1107b26ff91SDouglas Gregor Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
111424cec97SJohn McCall Mockup.Specifier = const_cast<Type*>(T);
112f21eb49aSDouglas Gregor return FindOrInsert(Context, Mockup);
113f21eb49aSDouglas Gregor }
114f21eb49aSDouglas Gregor
11564792e02SDouglas Gregor NestedNameSpecifier *
Create(const ASTContext & Context,IdentifierInfo * II)11639c79807SJay Foad NestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) {
11764792e02SDouglas Gregor assert(II && "Identifier cannot be NULL");
11864792e02SDouglas Gregor NestedNameSpecifier Mockup;
11936250ad6SCraig Topper Mockup.Prefix.setPointer(nullptr);
1207b26ff91SDouglas Gregor Mockup.Prefix.setInt(StoredIdentifier);
12164792e02SDouglas Gregor Mockup.Specifier = II;
12264792e02SDouglas Gregor return FindOrInsert(Context, Mockup);
12364792e02SDouglas Gregor }
12464792e02SDouglas Gregor
12539c79807SJay Foad NestedNameSpecifier *
GlobalSpecifier(const ASTContext & Context)12639c79807SJay Foad NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
127f21eb49aSDouglas Gregor if (!Context.GlobalNestedNameSpecifier)
128beb386abSRichard Smith Context.GlobalNestedNameSpecifier =
129c3f89253SBenjamin Kramer new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier();
130f21eb49aSDouglas Gregor return Context.GlobalNestedNameSpecifier;
131f21eb49aSDouglas Gregor }
132f21eb49aSDouglas Gregor
13367860249SNikola Smiljanic NestedNameSpecifier *
SuperSpecifier(const ASTContext & Context,CXXRecordDecl * RD)13467860249SNikola Smiljanic NestedNameSpecifier::SuperSpecifier(const ASTContext &Context,
13567860249SNikola Smiljanic CXXRecordDecl *RD) {
13667860249SNikola Smiljanic NestedNameSpecifier Mockup;
13767860249SNikola Smiljanic Mockup.Prefix.setPointer(nullptr);
13867860249SNikola Smiljanic Mockup.Prefix.setInt(StoredDecl);
13967860249SNikola Smiljanic Mockup.Specifier = RD;
14067860249SNikola Smiljanic return FindOrInsert(Context, Mockup);
14167860249SNikola Smiljanic }
14267860249SNikola Smiljanic
getKind() const1437b26ff91SDouglas Gregor NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
14436250ad6SCraig Topper if (!Specifier)
1457b26ff91SDouglas Gregor return Global;
1467b26ff91SDouglas Gregor
1477b26ff91SDouglas Gregor switch (Prefix.getInt()) {
1487b26ff91SDouglas Gregor case StoredIdentifier:
1497b26ff91SDouglas Gregor return Identifier;
1507b26ff91SDouglas Gregor
15167860249SNikola Smiljanic case StoredDecl: {
15267860249SNikola Smiljanic NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
15367860249SNikola Smiljanic if (isa<CXXRecordDecl>(ND))
15467860249SNikola Smiljanic return Super;
15567860249SNikola Smiljanic return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
15667860249SNikola Smiljanic }
1577b26ff91SDouglas Gregor
1587b26ff91SDouglas Gregor case StoredTypeSpec:
1597b26ff91SDouglas Gregor return TypeSpec;
1607b26ff91SDouglas Gregor
1617b26ff91SDouglas Gregor case StoredTypeSpecWithTemplate:
1627b26ff91SDouglas Gregor return TypeSpecWithTemplate;
1637b26ff91SDouglas Gregor }
1647b26ff91SDouglas Gregor
165e4d798f0SDavid Blaikie llvm_unreachable("Invalid NNS Kind!");
1667b26ff91SDouglas Gregor }
1677b26ff91SDouglas Gregor
1689fc8faf9SAdrian Prantl /// Retrieve the namespace stored in this nested name specifier.
getAsNamespace() const1697b26ff91SDouglas Gregor NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
17067860249SNikola Smiljanic if (Prefix.getInt() == StoredDecl)
1717b26ff91SDouglas Gregor return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
1727b26ff91SDouglas Gregor
17336250ad6SCraig Topper return nullptr;
1747b26ff91SDouglas Gregor }
1757b26ff91SDouglas Gregor
1769fc8faf9SAdrian Prantl /// Retrieve the namespace alias stored in this nested name specifier.
getAsNamespaceAlias() const1777b26ff91SDouglas Gregor NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
17867860249SNikola Smiljanic if (Prefix.getInt() == StoredDecl)
1797b26ff91SDouglas Gregor return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
1807b26ff91SDouglas Gregor
18136250ad6SCraig Topper return nullptr;
1827b26ff91SDouglas Gregor }
1837b26ff91SDouglas Gregor
1849fc8faf9SAdrian Prantl /// Retrieve the record declaration stored in this nested name specifier.
getAsRecordDecl() const18567860249SNikola Smiljanic CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const {
1865179eb78SRichard Smith switch (Prefix.getInt()) {
1875179eb78SRichard Smith case StoredIdentifier:
1885179eb78SRichard Smith return nullptr;
1895179eb78SRichard Smith
1905179eb78SRichard Smith case StoredDecl:
19167860249SNikola Smiljanic return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
19267860249SNikola Smiljanic
1935179eb78SRichard Smith case StoredTypeSpec:
1945179eb78SRichard Smith case StoredTypeSpecWithTemplate:
1955179eb78SRichard Smith return getAsType()->getAsCXXRecordDecl();
1965179eb78SRichard Smith }
1975179eb78SRichard Smith
1985179eb78SRichard Smith llvm_unreachable("Invalid NNS Kind!");
19967860249SNikola Smiljanic }
2007b26ff91SDouglas Gregor
getDependence() const201ec3060c7SIlya Biryukov NestedNameSpecifierDependence NestedNameSpecifier::getDependence() const {
202f21eb49aSDouglas Gregor switch (getKind()) {
203ec3060c7SIlya Biryukov case Identifier: {
204f21eb49aSDouglas Gregor // Identifier specifiers always represent dependent types
205ec3060c7SIlya Biryukov auto F = NestedNameSpecifierDependence::Dependent |
206ec3060c7SIlya Biryukov NestedNameSpecifierDependence::Instantiation;
207ec3060c7SIlya Biryukov // Prefix can contain unexpanded template parameters.
208ec3060c7SIlya Biryukov if (getPrefix())
209ec3060c7SIlya Biryukov return F | getPrefix()->getDependence();
210ec3060c7SIlya Biryukov return F;
211ec3060c7SIlya Biryukov }
212f21eb49aSDouglas Gregor
213f21eb49aSDouglas Gregor case Namespace:
2147b26ff91SDouglas Gregor case NamespaceAlias:
215f21eb49aSDouglas Gregor case Global:
216ec3060c7SIlya Biryukov return NestedNameSpecifierDependence::None;
217f21eb49aSDouglas Gregor
21867860249SNikola Smiljanic case Super: {
21967860249SNikola Smiljanic CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
22067860249SNikola Smiljanic for (const auto &Base : RD->bases())
22167860249SNikola Smiljanic if (Base.getType()->isDependentType())
222ec3060c7SIlya Biryukov // FIXME: must also be instantiation-dependent.
223ec3060c7SIlya Biryukov return NestedNameSpecifierDependence::Dependent;
224ec3060c7SIlya Biryukov return NestedNameSpecifierDependence::None;
22567860249SNikola Smiljanic }
22667860249SNikola Smiljanic
227f21eb49aSDouglas Gregor case TypeSpec:
228f21eb49aSDouglas Gregor case TypeSpecWithTemplate:
229ec3060c7SIlya Biryukov return toNestedNameSpecifierDependendence(getAsType()->getDependence());
230f21eb49aSDouglas Gregor }
231e4d798f0SDavid Blaikie llvm_unreachable("Invalid NNS Kind!");
232f21eb49aSDouglas Gregor }
233f21eb49aSDouglas Gregor
isDependent() const234ec3060c7SIlya Biryukov bool NestedNameSpecifier::isDependent() const {
235ec3060c7SIlya Biryukov return getDependence() & NestedNameSpecifierDependence::Dependent;
236ec3060c7SIlya Biryukov }
237ec3060c7SIlya Biryukov
isInstantiationDependent() const238678d76c0SDouglas Gregor bool NestedNameSpecifier::isInstantiationDependent() const {
239ec3060c7SIlya Biryukov return getDependence() & NestedNameSpecifierDependence::Instantiation;
240678d76c0SDouglas Gregor }
241678d76c0SDouglas Gregor
containsUnexpandedParameterPack() const242506bd564SDouglas Gregor bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
243ec3060c7SIlya Biryukov return getDependence() & NestedNameSpecifierDependence::UnexpandedPack;
244506bd564SDouglas Gregor }
245506bd564SDouglas Gregor
containsErrors() const246d285f293SHaojian Wu bool NestedNameSpecifier::containsErrors() const {
247d285f293SHaojian Wu return getDependence() & NestedNameSpecifierDependence::Error;
248d285f293SHaojian Wu }
249d285f293SHaojian Wu
2509fc8faf9SAdrian Prantl /// Print this nested name specifier to the given output
251f21eb49aSDouglas Gregor /// stream.
print(raw_ostream & OS,const PrintingPolicy & Policy,bool ResolveTemplateArguments) const2529d432e0dSClement Courbet void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
2539d432e0dSClement Courbet bool ResolveTemplateArguments) const {
254dce2b62bSDouglas Gregor if (getPrefix())
2557de5966dSDouglas Gregor getPrefix()->print(OS, Policy);
256f21eb49aSDouglas Gregor
257f21eb49aSDouglas Gregor switch (getKind()) {
258f21eb49aSDouglas Gregor case Identifier:
259f21eb49aSDouglas Gregor OS << getAsIdentifier()->getName();
260f21eb49aSDouglas Gregor break;
261f21eb49aSDouglas Gregor
262f21eb49aSDouglas Gregor case Namespace:
2632e10cf96SDouglas Gregor if (getAsNamespace()->isAnonymousNamespace())
2642e10cf96SDouglas Gregor return;
2652e10cf96SDouglas Gregor
2667b26ff91SDouglas Gregor OS << getAsNamespace()->getName();
2677b26ff91SDouglas Gregor break;
2687b26ff91SDouglas Gregor
2697b26ff91SDouglas Gregor case NamespaceAlias:
2707b26ff91SDouglas Gregor OS << getAsNamespaceAlias()->getName();
271f21eb49aSDouglas Gregor break;
272f21eb49aSDouglas Gregor
273f21eb49aSDouglas Gregor case Global:
274f21eb49aSDouglas Gregor break;
275f21eb49aSDouglas Gregor
27667860249SNikola Smiljanic case Super:
27767860249SNikola Smiljanic OS << "__super";
27867860249SNikola Smiljanic break;
27967860249SNikola Smiljanic
280f21eb49aSDouglas Gregor case TypeSpecWithTemplate:
281f21eb49aSDouglas Gregor OS << "template ";
282f21eb49aSDouglas Gregor // Fall through to print the type.
283f87496d1SGalina Kistanova LLVM_FALLTHROUGH;
284f21eb49aSDouglas Gregor
285f21eb49aSDouglas Gregor case TypeSpec: {
2869d432e0dSClement Courbet const auto *Record =
2879d432e0dSClement Courbet dyn_cast_or_null<ClassTemplateSpecializationDecl>(getAsRecordDecl());
2889d432e0dSClement Courbet if (ResolveTemplateArguments && Record) {
2899d432e0dSClement Courbet // Print the type trait with resolved template parameters.
2909d432e0dSClement Courbet Record->printName(OS);
29199d63ccfSPratyush Das printTemplateArgumentList(
29299d63ccfSPratyush Das OS, Record->getTemplateArgs().asArray(), Policy,
29399d63ccfSPratyush Das Record->getSpecializedTemplate()->getTemplateParameters());
2949d432e0dSClement Courbet break;
2959d432e0dSClement Courbet }
296424cec97SJohn McCall const Type *T = getAsType();
29718353910SDouglas Gregor
2987de5966dSDouglas Gregor PrintingPolicy InnerPolicy(Policy);
299b2e195a5SJohn McCall InnerPolicy.SuppressScope = true;
300053f691dSDouglas Gregor
301053f691dSDouglas Gregor // Nested-name-specifiers are intended to contain minimally-qualified
3026150c884SAbramo Bagnara // types. An actual ElaboratedType will not occur, since we'll store
303053f691dSDouglas Gregor // just the type that is referred to in the nested-name-specifier (e.g.,
304053f691dSDouglas Gregor // a TypedefType, TagType, etc.). However, when we are dealing with
305053f691dSDouglas Gregor // dependent template-id types (e.g., Outer<T>::template Inner<U>),
306053f691dSDouglas Gregor // the type requires its own nested-name-specifier for uniqueness, so we
307053f691dSDouglas Gregor // suppress that nested-name-specifier during printing.
3086150c884SAbramo Bagnara assert(!isa<ElaboratedType>(T) &&
3096150c884SAbramo Bagnara "Elaborated type in nested-name-specifier");
310053f691dSDouglas Gregor if (const TemplateSpecializationType *SpecType
311053f691dSDouglas Gregor = dyn_cast<TemplateSpecializationType>(T)) {
312053f691dSDouglas Gregor // Print the template name without its corresponding
313053f691dSDouglas Gregor // nested-name-specifier.
314*5fb3f437SDavid Blaikie SpecType->getTemplateName().print(OS, InnerPolicy,
315*5fb3f437SDavid Blaikie TemplateName::Qualified::None);
316053f691dSDouglas Gregor
317053f691dSDouglas Gregor // Print the template argument list.
31803e672ccSSerge Pavlov printTemplateArgumentList(OS, SpecType->template_arguments(),
31903e672ccSSerge Pavlov InnerPolicy);
3200642e5e7SMatthias Gehre } else if (const auto *DepSpecType =
3210642e5e7SMatthias Gehre dyn_cast<DependentTemplateSpecializationType>(T)) {
3220642e5e7SMatthias Gehre // Print the template name without its corresponding
3230642e5e7SMatthias Gehre // nested-name-specifier.
3240642e5e7SMatthias Gehre OS << DepSpecType->getIdentifier()->getName();
3250642e5e7SMatthias Gehre // Print the template argument list.
3260642e5e7SMatthias Gehre printTemplateArgumentList(OS, DepSpecType->template_arguments(),
3270642e5e7SMatthias Gehre InnerPolicy);
328053f691dSDouglas Gregor } else {
329053f691dSDouglas Gregor // Print the type normally
3309170e914SBenjamin Kramer QualType(T, 0).print(OS, InnerPolicy);
331053f691dSDouglas Gregor }
332f21eb49aSDouglas Gregor break;
333f21eb49aSDouglas Gregor }
334f21eb49aSDouglas Gregor }
33518353910SDouglas Gregor
33618353910SDouglas Gregor OS << "::";
33718353910SDouglas Gregor }
338f21eb49aSDouglas Gregor
dump(const LangOptions & LO) const33907dd5af6SStephen Kelly LLVM_DUMP_METHOD void NestedNameSpecifier::dump(const LangOptions &LO) const {
34007dd5af6SStephen Kelly dump(llvm::errs(), LO);
341015e6c8aSYaron Keren }
342015e6c8aSYaron Keren
dump() const34307dd5af6SStephen Kelly LLVM_DUMP_METHOD void NestedNameSpecifier::dump() const { dump(llvm::errs()); }
34407dd5af6SStephen Kelly
dump(llvm::raw_ostream & OS) const34507dd5af6SStephen Kelly LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS) const {
346015e6c8aSYaron Keren LangOptions LO;
34707dd5af6SStephen Kelly dump(OS, LO);
34807dd5af6SStephen Kelly }
34907dd5af6SStephen Kelly
dump(llvm::raw_ostream & OS,const LangOptions & LO) const35007dd5af6SStephen Kelly LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS,
35107dd5af6SStephen Kelly const LangOptions &LO) const {
35207dd5af6SStephen Kelly print(OS, PrintingPolicy(LO));
353333489bbSDouglas Gregor }
354869ad45fSDouglas Gregor
355869ad45fSDouglas Gregor unsigned
getLocalDataLength(NestedNameSpecifier * Qualifier)356869ad45fSDouglas Gregor NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
357869ad45fSDouglas Gregor assert(Qualifier && "Expected a non-NULL qualifier");
358869ad45fSDouglas Gregor
359869ad45fSDouglas Gregor // Location of the trailing '::'.
36021401a72SSimon Tatham unsigned Length = sizeof(SourceLocation::UIntTy);
361869ad45fSDouglas Gregor
362869ad45fSDouglas Gregor switch (Qualifier->getKind()) {
363869ad45fSDouglas Gregor case NestedNameSpecifier::Global:
364869ad45fSDouglas Gregor // Nothing more to add.
365869ad45fSDouglas Gregor break;
366869ad45fSDouglas Gregor
367869ad45fSDouglas Gregor case NestedNameSpecifier::Identifier:
368869ad45fSDouglas Gregor case NestedNameSpecifier::Namespace:
369869ad45fSDouglas Gregor case NestedNameSpecifier::NamespaceAlias:
37067860249SNikola Smiljanic case NestedNameSpecifier::Super:
371869ad45fSDouglas Gregor // The location of the identifier or namespace name.
37221401a72SSimon Tatham Length += sizeof(SourceLocation::UIntTy);
373869ad45fSDouglas Gregor break;
374869ad45fSDouglas Gregor
375869ad45fSDouglas Gregor case NestedNameSpecifier::TypeSpecWithTemplate:
376869ad45fSDouglas Gregor case NestedNameSpecifier::TypeSpec:
377869ad45fSDouglas Gregor // The "void*" that points at the TypeLoc data.
378869ad45fSDouglas Gregor // Note: the 'template' keyword is part of the TypeLoc.
379869ad45fSDouglas Gregor Length += sizeof(void *);
380869ad45fSDouglas Gregor break;
381869ad45fSDouglas Gregor }
382869ad45fSDouglas Gregor
383869ad45fSDouglas Gregor return Length;
384869ad45fSDouglas Gregor }
385869ad45fSDouglas Gregor
386869ad45fSDouglas Gregor unsigned
getDataLength(NestedNameSpecifier * Qualifier)387869ad45fSDouglas Gregor NestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) {
388869ad45fSDouglas Gregor unsigned Length = 0;
389869ad45fSDouglas Gregor for (; Qualifier; Qualifier = Qualifier->getPrefix())
390869ad45fSDouglas Gregor Length += getLocalDataLength(Qualifier);
391869ad45fSDouglas Gregor return Length;
392869ad45fSDouglas Gregor }
393869ad45fSDouglas Gregor
3949fc8faf9SAdrian Prantl /// Load a (possibly unaligned) source location from a given address
395869ad45fSDouglas Gregor /// and offset.
LoadSourceLocation(void * Data,unsigned Offset)39621fadadbSEugene Zelenko static SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
39721401a72SSimon Tatham SourceLocation::UIntTy Raw;
39821401a72SSimon Tatham memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(Raw));
399869ad45fSDouglas Gregor return SourceLocation::getFromRawEncoding(Raw);
400869ad45fSDouglas Gregor }
401869ad45fSDouglas Gregor
4029fc8faf9SAdrian Prantl /// Load a (possibly unaligned) pointer from a given address and
403869ad45fSDouglas Gregor /// offset.
LoadPointer(void * Data,unsigned Offset)40421fadadbSEugene Zelenko static void *LoadPointer(void *Data, unsigned Offset) {
405869ad45fSDouglas Gregor void *Result;
406869ad45fSDouglas Gregor memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
407869ad45fSDouglas Gregor return Result;
408869ad45fSDouglas Gregor }
409869ad45fSDouglas Gregor
getSourceRange() const410a9d87bc6SDouglas Gregor SourceRange NestedNameSpecifierLoc::getSourceRange() const {
41112441b3bSDouglas Gregor if (!Qualifier)
41212441b3bSDouglas Gregor return SourceRange();
41312441b3bSDouglas Gregor
414869ad45fSDouglas Gregor NestedNameSpecifierLoc First = *this;
415869ad45fSDouglas Gregor while (NestedNameSpecifierLoc Prefix = First.getPrefix())
416869ad45fSDouglas Gregor First = Prefix;
417869ad45fSDouglas Gregor
418869ad45fSDouglas Gregor return SourceRange(First.getLocalSourceRange().getBegin(),
419869ad45fSDouglas Gregor getLocalSourceRange().getEnd());
420869ad45fSDouglas Gregor }
421869ad45fSDouglas Gregor
getLocalSourceRange() const422a9d87bc6SDouglas Gregor SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
42312441b3bSDouglas Gregor if (!Qualifier)
42412441b3bSDouglas Gregor return SourceRange();
42512441b3bSDouglas Gregor
426869ad45fSDouglas Gregor unsigned Offset = getDataLength(Qualifier->getPrefix());
427869ad45fSDouglas Gregor switch (Qualifier->getKind()) {
428869ad45fSDouglas Gregor case NestedNameSpecifier::Global:
429869ad45fSDouglas Gregor return LoadSourceLocation(Data, Offset);
430869ad45fSDouglas Gregor
431869ad45fSDouglas Gregor case NestedNameSpecifier::Identifier:
432869ad45fSDouglas Gregor case NestedNameSpecifier::Namespace:
433869ad45fSDouglas Gregor case NestedNameSpecifier::NamespaceAlias:
43467860249SNikola Smiljanic case NestedNameSpecifier::Super:
43521401a72SSimon Tatham return SourceRange(
43621401a72SSimon Tatham LoadSourceLocation(Data, Offset),
43721401a72SSimon Tatham LoadSourceLocation(Data, Offset + sizeof(SourceLocation::UIntTy)));
438869ad45fSDouglas Gregor
439869ad45fSDouglas Gregor case NestedNameSpecifier::TypeSpecWithTemplate:
440869ad45fSDouglas Gregor case NestedNameSpecifier::TypeSpec: {
441869ad45fSDouglas Gregor // The "void*" that points at the TypeLoc data.
442869ad45fSDouglas Gregor // Note: the 'template' keyword is part of the TypeLoc.
443869ad45fSDouglas Gregor void *TypeData = LoadPointer(Data, Offset);
444869ad45fSDouglas Gregor TypeLoc TL(Qualifier->getAsType(), TypeData);
445869ad45fSDouglas Gregor return SourceRange(TL.getBeginLoc(),
446869ad45fSDouglas Gregor LoadSourceLocation(Data, Offset + sizeof(void*)));
447869ad45fSDouglas Gregor }
448869ad45fSDouglas Gregor }
449869ad45fSDouglas Gregor
450e4d798f0SDavid Blaikie llvm_unreachable("Invalid NNS Kind!");
451869ad45fSDouglas Gregor }
452a9d87bc6SDouglas Gregor
getTypeLoc() const453a9d87bc6SDouglas Gregor TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
45454272e5bSStephen Kelly if (Qualifier->getKind() != NestedNameSpecifier::TypeSpec &&
45554272e5bSStephen Kelly Qualifier->getKind() != NestedNameSpecifier::TypeSpecWithTemplate)
45654272e5bSStephen Kelly return TypeLoc();
457a9d87bc6SDouglas Gregor
458a9d87bc6SDouglas Gregor // The "void*" that points at the TypeLoc data.
459a9d87bc6SDouglas Gregor unsigned Offset = getDataLength(Qualifier->getPrefix());
460a9d87bc6SDouglas Gregor void *TypeData = LoadPointer(Data, Offset);
461a9d87bc6SDouglas Gregor return TypeLoc(Qualifier->getAsType(), TypeData);
462a9d87bc6SDouglas Gregor }
4639b27251eSDouglas Gregor
Append(char * Start,char * End,char * & Buffer,unsigned & BufferSize,unsigned & BufferCapacity)46421fadadbSEugene Zelenko static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
4659b27251eSDouglas Gregor unsigned &BufferCapacity) {
466b6708d8eSChandler Carruth if (Start == End)
467b6708d8eSChandler Carruth return;
468b6708d8eSChandler Carruth
4699b27251eSDouglas Gregor if (BufferSize + (End - Start) > BufferCapacity) {
4709b27251eSDouglas Gregor // Reallocate the buffer.
471b6708d8eSChandler Carruth unsigned NewCapacity = std::max(
472b6708d8eSChandler Carruth (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
4739b27251eSDouglas Gregor (unsigned)(BufferSize + (End - Start)));
474cc1c5165SBenjamin Kramer if (!BufferCapacity) {
47552525730SSerge Pavlov char *NewBuffer = static_cast<char *>(llvm::safe_malloc(NewCapacity));
476cc1c5165SBenjamin Kramer if (Buffer)
4779b27251eSDouglas Gregor memcpy(NewBuffer, Buffer, BufferSize);
4789b27251eSDouglas Gregor Buffer = NewBuffer;
479cc1c5165SBenjamin Kramer } else {
480cc1c5165SBenjamin Kramer Buffer = static_cast<char *>(llvm::safe_realloc(Buffer, NewCapacity));
481cc1c5165SBenjamin Kramer }
4829b27251eSDouglas Gregor BufferCapacity = NewCapacity;
4839b27251eSDouglas Gregor }
4847ec7a6e5SSimon Pilgrim assert(Buffer && Start && End && End > Start && "Illegal memory buffer copy");
4859b27251eSDouglas Gregor memcpy(Buffer + BufferSize, Start, End - Start);
4869b27251eSDouglas Gregor BufferSize += End - Start;
4879b27251eSDouglas Gregor }
4889b27251eSDouglas Gregor
4899fc8faf9SAdrian Prantl /// Save a source location to the given buffer.
SaveSourceLocation(SourceLocation Loc,char * & Buffer,unsigned & BufferSize,unsigned & BufferCapacity)49021fadadbSEugene Zelenko static void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
4919b27251eSDouglas Gregor unsigned &BufferSize, unsigned &BufferCapacity) {
49221401a72SSimon Tatham SourceLocation::UIntTy Raw = Loc.getRawEncoding();
4939b27251eSDouglas Gregor Append(reinterpret_cast<char *>(&Raw),
49421401a72SSimon Tatham reinterpret_cast<char *>(&Raw) + sizeof(Raw), Buffer, BufferSize,
49521401a72SSimon Tatham BufferCapacity);
4969b27251eSDouglas Gregor }
4979b27251eSDouglas Gregor
4989fc8faf9SAdrian Prantl /// Save a pointer to the given buffer.
SavePointer(void * Ptr,char * & Buffer,unsigned & BufferSize,unsigned & BufferCapacity)49921fadadbSEugene Zelenko static void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
5009b27251eSDouglas Gregor unsigned &BufferCapacity) {
5019b27251eSDouglas Gregor Append(reinterpret_cast<char *>(&Ptr),
5029b27251eSDouglas Gregor reinterpret_cast<char *>(&Ptr) + sizeof(void *),
5039b27251eSDouglas Gregor Buffer, BufferSize, BufferCapacity);
5049b27251eSDouglas Gregor }
5059b27251eSDouglas Gregor
5069b27251eSDouglas Gregor NestedNameSpecifierLocBuilder::
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder & Other)5079b27251eSDouglas Gregor NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other)
50821fadadbSEugene Zelenko : Representation(Other.Representation) {
5099b27251eSDouglas Gregor if (!Other.Buffer)
5109b27251eSDouglas Gregor return;
5119b27251eSDouglas Gregor
5129b27251eSDouglas Gregor if (Other.BufferCapacity == 0) {
5139b27251eSDouglas Gregor // Shallow copy is okay.
5149b27251eSDouglas Gregor Buffer = Other.Buffer;
5159b27251eSDouglas Gregor BufferSize = Other.BufferSize;
5169b27251eSDouglas Gregor return;
5179b27251eSDouglas Gregor }
5189b27251eSDouglas Gregor
5199b27251eSDouglas Gregor // Deep copy
5209f81d6a4SSerge Pavlov Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
5219f81d6a4SSerge Pavlov BufferCapacity);
5229b27251eSDouglas Gregor }
5239b27251eSDouglas Gregor
5249b27251eSDouglas Gregor NestedNameSpecifierLocBuilder &
5259b27251eSDouglas Gregor NestedNameSpecifierLocBuilder::
operator =(const NestedNameSpecifierLocBuilder & Other)5269b27251eSDouglas Gregor operator=(const NestedNameSpecifierLocBuilder &Other) {
5279b27251eSDouglas Gregor Representation = Other.Representation;
5289b27251eSDouglas Gregor
5299b27251eSDouglas Gregor if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
5309b27251eSDouglas Gregor // Re-use our storage.
5319b27251eSDouglas Gregor BufferSize = Other.BufferSize;
5329b27251eSDouglas Gregor memcpy(Buffer, Other.Buffer, BufferSize);
5339b27251eSDouglas Gregor return *this;
5349b27251eSDouglas Gregor }
5359b27251eSDouglas Gregor
5369b27251eSDouglas Gregor // Free our storage, if we have any.
5379b27251eSDouglas Gregor if (BufferCapacity) {
5389b27251eSDouglas Gregor free(Buffer);
5399b27251eSDouglas Gregor BufferCapacity = 0;
5409b27251eSDouglas Gregor }
5419b27251eSDouglas Gregor
5429b27251eSDouglas Gregor if (!Other.Buffer) {
5439b27251eSDouglas Gregor // Empty.
54436250ad6SCraig Topper Buffer = nullptr;
5459b27251eSDouglas Gregor BufferSize = 0;
5469b27251eSDouglas Gregor return *this;
5479b27251eSDouglas Gregor }
5489b27251eSDouglas Gregor
5499b27251eSDouglas Gregor if (Other.BufferCapacity == 0) {
5509b27251eSDouglas Gregor // Shallow copy is okay.
5519b27251eSDouglas Gregor Buffer = Other.Buffer;
5529b27251eSDouglas Gregor BufferSize = Other.BufferSize;
5539b27251eSDouglas Gregor return *this;
5549b27251eSDouglas Gregor }
5559b27251eSDouglas Gregor
5569b27251eSDouglas Gregor // Deep copy.
557c5871644SErik Pilkington BufferSize = 0;
5589f81d6a4SSerge Pavlov Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
5599f81d6a4SSerge Pavlov BufferCapacity);
5609b27251eSDouglas Gregor return *this;
5619b27251eSDouglas Gregor }
5629b27251eSDouglas Gregor
Extend(ASTContext & Context,SourceLocation TemplateKWLoc,TypeLoc TL,SourceLocation ColonColonLoc)5639b27251eSDouglas Gregor void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
5649b27251eSDouglas Gregor SourceLocation TemplateKWLoc,
5659b27251eSDouglas Gregor TypeLoc TL,
5669b27251eSDouglas Gregor SourceLocation ColonColonLoc) {
5679b27251eSDouglas Gregor Representation = NestedNameSpecifier::Create(Context, Representation,
5689b27251eSDouglas Gregor TemplateKWLoc.isValid(),
5699b27251eSDouglas Gregor TL.getTypePtr());
5709b27251eSDouglas Gregor
5719b27251eSDouglas Gregor // Push source-location info into the buffer.
5729b27251eSDouglas Gregor SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
5739b27251eSDouglas Gregor SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
5749b27251eSDouglas Gregor }
5759b27251eSDouglas Gregor
Extend(ASTContext & Context,IdentifierInfo * Identifier,SourceLocation IdentifierLoc,SourceLocation ColonColonLoc)5769b27251eSDouglas Gregor void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
5779b27251eSDouglas Gregor IdentifierInfo *Identifier,
5789b27251eSDouglas Gregor SourceLocation IdentifierLoc,
5799b27251eSDouglas Gregor SourceLocation ColonColonLoc) {
5809b27251eSDouglas Gregor Representation = NestedNameSpecifier::Create(Context, Representation,
5819b27251eSDouglas Gregor Identifier);
5829b27251eSDouglas Gregor
5839b27251eSDouglas Gregor // Push source-location info into the buffer.
5849b27251eSDouglas Gregor SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
5859b27251eSDouglas Gregor SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
5869b27251eSDouglas Gregor }
5879b27251eSDouglas Gregor
Extend(ASTContext & Context,NamespaceDecl * Namespace,SourceLocation NamespaceLoc,SourceLocation ColonColonLoc)5889b27251eSDouglas Gregor void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
5899b27251eSDouglas Gregor NamespaceDecl *Namespace,
5909b27251eSDouglas Gregor SourceLocation NamespaceLoc,
5919b27251eSDouglas Gregor SourceLocation ColonColonLoc) {
5929b27251eSDouglas Gregor Representation = NestedNameSpecifier::Create(Context, Representation,
5939b27251eSDouglas Gregor Namespace);
5949b27251eSDouglas Gregor
5959b27251eSDouglas Gregor // Push source-location info into the buffer.
5969b27251eSDouglas Gregor SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
5979b27251eSDouglas Gregor SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
5989b27251eSDouglas Gregor }
5999b27251eSDouglas Gregor
Extend(ASTContext & Context,NamespaceAliasDecl * Alias,SourceLocation AliasLoc,SourceLocation ColonColonLoc)6009b27251eSDouglas Gregor void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
6019b27251eSDouglas Gregor NamespaceAliasDecl *Alias,
6029b27251eSDouglas Gregor SourceLocation AliasLoc,
6039b27251eSDouglas Gregor SourceLocation ColonColonLoc) {
6049b27251eSDouglas Gregor Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
6059b27251eSDouglas Gregor
6069b27251eSDouglas Gregor // Push source-location info into the buffer.
6079b27251eSDouglas Gregor SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
6089b27251eSDouglas Gregor SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
6099b27251eSDouglas Gregor }
6109b27251eSDouglas Gregor
MakeGlobal(ASTContext & Context,SourceLocation ColonColonLoc)6119b27251eSDouglas Gregor void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context,
6129b27251eSDouglas Gregor SourceLocation ColonColonLoc) {
6139b27251eSDouglas Gregor assert(!Representation && "Already have a nested-name-specifier!?");
6149b27251eSDouglas Gregor Representation = NestedNameSpecifier::GlobalSpecifier(Context);
6159b27251eSDouglas Gregor
6169b27251eSDouglas Gregor // Push source-location info into the buffer.
6179b27251eSDouglas Gregor SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
6189b27251eSDouglas Gregor }
6199b27251eSDouglas Gregor
MakeSuper(ASTContext & Context,CXXRecordDecl * RD,SourceLocation SuperLoc,SourceLocation ColonColonLoc)62067860249SNikola Smiljanic void NestedNameSpecifierLocBuilder::MakeSuper(ASTContext &Context,
62167860249SNikola Smiljanic CXXRecordDecl *RD,
62267860249SNikola Smiljanic SourceLocation SuperLoc,
62367860249SNikola Smiljanic SourceLocation ColonColonLoc) {
62467860249SNikola Smiljanic Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
62567860249SNikola Smiljanic
62667860249SNikola Smiljanic // Push source-location info into the buffer.
62767860249SNikola Smiljanic SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
62867860249SNikola Smiljanic SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
62967860249SNikola Smiljanic }
63067860249SNikola Smiljanic
MakeTrivial(ASTContext & Context,NestedNameSpecifier * Qualifier,SourceRange R)6319b27251eSDouglas Gregor void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
6329b27251eSDouglas Gregor NestedNameSpecifier *Qualifier,
6339b27251eSDouglas Gregor SourceRange R) {
6349b27251eSDouglas Gregor Representation = Qualifier;
6359b27251eSDouglas Gregor
6369b27251eSDouglas Gregor // Construct bogus (but well-formed) source information for the
6379b27251eSDouglas Gregor // nested-name-specifier.
6389b27251eSDouglas Gregor BufferSize = 0;
6390e62c1ccSChris Lattner SmallVector<NestedNameSpecifier *, 4> Stack;
6409b27251eSDouglas Gregor for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
6419b27251eSDouglas Gregor Stack.push_back(NNS);
6429b27251eSDouglas Gregor while (!Stack.empty()) {
64325284cc9SRobert Wilhelm NestedNameSpecifier *NNS = Stack.pop_back_val();
6449b27251eSDouglas Gregor switch (NNS->getKind()) {
6459b27251eSDouglas Gregor case NestedNameSpecifier::Identifier:
6469b27251eSDouglas Gregor case NestedNameSpecifier::Namespace:
6479b27251eSDouglas Gregor case NestedNameSpecifier::NamespaceAlias:
6489b27251eSDouglas Gregor SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
6499b27251eSDouglas Gregor break;
6509b27251eSDouglas Gregor
6519b27251eSDouglas Gregor case NestedNameSpecifier::TypeSpec:
6529b27251eSDouglas Gregor case NestedNameSpecifier::TypeSpecWithTemplate: {
6539b27251eSDouglas Gregor TypeSourceInfo *TSInfo
6549b27251eSDouglas Gregor = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
6559b27251eSDouglas Gregor R.getBegin());
6569b27251eSDouglas Gregor SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
6579b27251eSDouglas Gregor BufferCapacity);
6589b27251eSDouglas Gregor break;
6599b27251eSDouglas Gregor }
6609b27251eSDouglas Gregor
6619b27251eSDouglas Gregor case NestedNameSpecifier::Global:
66267860249SNikola Smiljanic case NestedNameSpecifier::Super:
6639b27251eSDouglas Gregor break;
6649b27251eSDouglas Gregor }
6659b27251eSDouglas Gregor
6669b27251eSDouglas Gregor // Save the location of the '::'.
6679b27251eSDouglas Gregor SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
6689b27251eSDouglas Gregor Buffer, BufferSize, BufferCapacity);
6699b27251eSDouglas Gregor }
6709b27251eSDouglas Gregor }
6719b27251eSDouglas Gregor
Adopt(NestedNameSpecifierLoc Other)6729b27251eSDouglas Gregor void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) {
6739b27251eSDouglas Gregor if (BufferCapacity)
6749b27251eSDouglas Gregor free(Buffer);
6759b27251eSDouglas Gregor
6769b27251eSDouglas Gregor if (!Other) {
67736250ad6SCraig Topper Representation = nullptr;
6789b27251eSDouglas Gregor BufferSize = 0;
6799b27251eSDouglas Gregor return;
6809b27251eSDouglas Gregor }
6819b27251eSDouglas Gregor
6829b27251eSDouglas Gregor // Rather than copying the data (which is wasteful), "adopt" the
6839b27251eSDouglas Gregor // pointer (which points into the ASTContext) but set the capacity to zero to
6849b27251eSDouglas Gregor // indicate that we don't own it.
6859b27251eSDouglas Gregor Representation = Other.getNestedNameSpecifier();
6869b27251eSDouglas Gregor Buffer = static_cast<char *>(Other.getOpaqueData());
6879b27251eSDouglas Gregor BufferSize = Other.getDataLength();
6889b27251eSDouglas Gregor BufferCapacity = 0;
6899b27251eSDouglas Gregor }
6909b27251eSDouglas Gregor
6919b27251eSDouglas Gregor NestedNameSpecifierLoc
getWithLocInContext(ASTContext & Context) const6929b27251eSDouglas Gregor NestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const {
6939b27251eSDouglas Gregor if (!Representation)
6949b27251eSDouglas Gregor return NestedNameSpecifierLoc();
6959b27251eSDouglas Gregor
6969b27251eSDouglas Gregor // If we adopted our data pointer from elsewhere in the AST context, there's
6979b27251eSDouglas Gregor // no need to copy the memory.
6989b27251eSDouglas Gregor if (BufferCapacity == 0)
6999b27251eSDouglas Gregor return NestedNameSpecifierLoc(Representation, Buffer);
7009b27251eSDouglas Gregor
7019b27251eSDouglas Gregor // FIXME: After copying the source-location information, should we free
7029b27251eSDouglas Gregor // our (temporary) buffer and adopt the ASTContext-allocated memory?
7039b27251eSDouglas Gregor // Doing so would optimize repeated calls to getWithLocInContext().
704c3f89253SBenjamin Kramer void *Mem = Context.Allocate(BufferSize, alignof(void *));
7059b27251eSDouglas Gregor memcpy(Mem, Buffer, BufferSize);
7069b27251eSDouglas Gregor return NestedNameSpecifierLoc(Representation, Mem);
7079b27251eSDouglas Gregor }
708