10b57cec5SDimitry Andric //===- NestedNameSpecifier.cpp - C++ nested name specifiers ---------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines the NestedNameSpecifier class, which represents 100b57cec5SDimitry Andric // a C++ nested-name-specifier. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "clang/AST/NestedNameSpecifier.h" 150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 160b57cec5SDimitry Andric #include "clang/AST/Decl.h" 170b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 180b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h" 195ffd83dbSDimitry Andric #include "clang/AST/DependenceFlags.h" 200b57cec5SDimitry Andric #include "clang/AST/PrettyPrinter.h" 210b57cec5SDimitry Andric #include "clang/AST/TemplateName.h" 220b57cec5SDimitry Andric #include "clang/AST/Type.h" 230b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h" 240b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 250b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h" 260b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h" 270b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h" 280b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 290b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 300b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 310b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 320b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 330b57cec5SDimitry Andric #include <algorithm> 340b57cec5SDimitry Andric #include <cassert> 350b57cec5SDimitry Andric #include <cstdlib> 360b57cec5SDimitry Andric #include <cstring> 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric using namespace clang; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric NestedNameSpecifier * 410b57cec5SDimitry Andric NestedNameSpecifier::FindOrInsert(const ASTContext &Context, 420b57cec5SDimitry Andric const NestedNameSpecifier &Mockup) { 430b57cec5SDimitry Andric llvm::FoldingSetNodeID ID; 440b57cec5SDimitry Andric Mockup.Profile(ID); 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric void *InsertPos = nullptr; 470b57cec5SDimitry Andric NestedNameSpecifier *NNS 480b57cec5SDimitry Andric = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos); 490b57cec5SDimitry Andric if (!NNS) { 500b57cec5SDimitry Andric NNS = 510b57cec5SDimitry Andric new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(Mockup); 520b57cec5SDimitry Andric Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos); 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric return NNS; 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric 58*0fca6ea1SDimitry Andric NestedNameSpecifier *NestedNameSpecifier::Create(const ASTContext &Context, 59*0fca6ea1SDimitry Andric NestedNameSpecifier *Prefix, 60*0fca6ea1SDimitry Andric const IdentifierInfo *II) { 610b57cec5SDimitry Andric assert(II && "Identifier cannot be NULL"); 620b57cec5SDimitry Andric assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent"); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric NestedNameSpecifier Mockup; 650b57cec5SDimitry Andric Mockup.Prefix.setPointer(Prefix); 660b57cec5SDimitry Andric Mockup.Prefix.setInt(StoredIdentifier); 67*0fca6ea1SDimitry Andric Mockup.Specifier = const_cast<IdentifierInfo *>(II); 680b57cec5SDimitry Andric return FindOrInsert(Context, Mockup); 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric NestedNameSpecifier * 720b57cec5SDimitry Andric NestedNameSpecifier::Create(const ASTContext &Context, 730b57cec5SDimitry Andric NestedNameSpecifier *Prefix, 740b57cec5SDimitry Andric const NamespaceDecl *NS) { 750b57cec5SDimitry Andric assert(NS && "Namespace cannot be NULL"); 760b57cec5SDimitry Andric assert((!Prefix || 770b57cec5SDimitry Andric (Prefix->getAsType() == nullptr && 780b57cec5SDimitry Andric Prefix->getAsIdentifier() == nullptr)) && 790b57cec5SDimitry Andric "Broken nested name specifier"); 800b57cec5SDimitry Andric NestedNameSpecifier Mockup; 810b57cec5SDimitry Andric Mockup.Prefix.setPointer(Prefix); 820b57cec5SDimitry Andric Mockup.Prefix.setInt(StoredDecl); 830b57cec5SDimitry Andric Mockup.Specifier = const_cast<NamespaceDecl *>(NS); 840b57cec5SDimitry Andric return FindOrInsert(Context, Mockup); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric NestedNameSpecifier * 880b57cec5SDimitry Andric NestedNameSpecifier::Create(const ASTContext &Context, 890b57cec5SDimitry Andric NestedNameSpecifier *Prefix, 90*0fca6ea1SDimitry Andric const NamespaceAliasDecl *Alias) { 910b57cec5SDimitry Andric assert(Alias && "Namespace alias cannot be NULL"); 920b57cec5SDimitry Andric assert((!Prefix || 930b57cec5SDimitry Andric (Prefix->getAsType() == nullptr && 940b57cec5SDimitry Andric Prefix->getAsIdentifier() == nullptr)) && 950b57cec5SDimitry Andric "Broken nested name specifier"); 960b57cec5SDimitry Andric NestedNameSpecifier Mockup; 970b57cec5SDimitry Andric Mockup.Prefix.setPointer(Prefix); 980b57cec5SDimitry Andric Mockup.Prefix.setInt(StoredDecl); 99*0fca6ea1SDimitry Andric Mockup.Specifier = const_cast<NamespaceAliasDecl *>(Alias); 1000b57cec5SDimitry Andric return FindOrInsert(Context, Mockup); 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric NestedNameSpecifier * 1040b57cec5SDimitry Andric NestedNameSpecifier::Create(const ASTContext &Context, 1050b57cec5SDimitry Andric NestedNameSpecifier *Prefix, 1060b57cec5SDimitry Andric bool Template, const Type *T) { 1070b57cec5SDimitry Andric assert(T && "Type cannot be NULL"); 1080b57cec5SDimitry Andric NestedNameSpecifier Mockup; 1090b57cec5SDimitry Andric Mockup.Prefix.setPointer(Prefix); 1100b57cec5SDimitry Andric Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec); 1110b57cec5SDimitry Andric Mockup.Specifier = const_cast<Type*>(T); 1120b57cec5SDimitry Andric return FindOrInsert(Context, Mockup); 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric 115*0fca6ea1SDimitry Andric NestedNameSpecifier *NestedNameSpecifier::Create(const ASTContext &Context, 116*0fca6ea1SDimitry Andric const IdentifierInfo *II) { 1170b57cec5SDimitry Andric assert(II && "Identifier cannot be NULL"); 1180b57cec5SDimitry Andric NestedNameSpecifier Mockup; 1190b57cec5SDimitry Andric Mockup.Prefix.setPointer(nullptr); 1200b57cec5SDimitry Andric Mockup.Prefix.setInt(StoredIdentifier); 121*0fca6ea1SDimitry Andric Mockup.Specifier = const_cast<IdentifierInfo *>(II); 1220b57cec5SDimitry Andric return FindOrInsert(Context, Mockup); 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric NestedNameSpecifier * 1260b57cec5SDimitry Andric NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) { 1270b57cec5SDimitry Andric if (!Context.GlobalNestedNameSpecifier) 1280b57cec5SDimitry Andric Context.GlobalNestedNameSpecifier = 1290b57cec5SDimitry Andric new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(); 1300b57cec5SDimitry Andric return Context.GlobalNestedNameSpecifier; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric NestedNameSpecifier * 1340b57cec5SDimitry Andric NestedNameSpecifier::SuperSpecifier(const ASTContext &Context, 1350b57cec5SDimitry Andric CXXRecordDecl *RD) { 1360b57cec5SDimitry Andric NestedNameSpecifier Mockup; 1370b57cec5SDimitry Andric Mockup.Prefix.setPointer(nullptr); 1380b57cec5SDimitry Andric Mockup.Prefix.setInt(StoredDecl); 1390b57cec5SDimitry Andric Mockup.Specifier = RD; 1400b57cec5SDimitry Andric return FindOrInsert(Context, Mockup); 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const { 1440b57cec5SDimitry Andric if (!Specifier) 1450b57cec5SDimitry Andric return Global; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric switch (Prefix.getInt()) { 1480b57cec5SDimitry Andric case StoredIdentifier: 1490b57cec5SDimitry Andric return Identifier; 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric case StoredDecl: { 1520b57cec5SDimitry Andric NamedDecl *ND = static_cast<NamedDecl *>(Specifier); 1530b57cec5SDimitry Andric if (isa<CXXRecordDecl>(ND)) 1540b57cec5SDimitry Andric return Super; 1550b57cec5SDimitry Andric return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric case StoredTypeSpec: 1590b57cec5SDimitry Andric return TypeSpec; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric case StoredTypeSpecWithTemplate: 1620b57cec5SDimitry Andric return TypeSpecWithTemplate; 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric llvm_unreachable("Invalid NNS Kind!"); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric /// Retrieve the namespace stored in this nested name specifier. 1690b57cec5SDimitry Andric NamespaceDecl *NestedNameSpecifier::getAsNamespace() const { 1700b57cec5SDimitry Andric if (Prefix.getInt() == StoredDecl) 1710b57cec5SDimitry Andric return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier)); 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric return nullptr; 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric /// Retrieve the namespace alias stored in this nested name specifier. 1770b57cec5SDimitry Andric NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const { 1780b57cec5SDimitry Andric if (Prefix.getInt() == StoredDecl) 1790b57cec5SDimitry Andric return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier)); 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric return nullptr; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric /// Retrieve the record declaration stored in this nested name specifier. 1850b57cec5SDimitry Andric CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const { 1860b57cec5SDimitry Andric switch (Prefix.getInt()) { 1870b57cec5SDimitry Andric case StoredIdentifier: 1880b57cec5SDimitry Andric return nullptr; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric case StoredDecl: 1910b57cec5SDimitry Andric return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier)); 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric case StoredTypeSpec: 1940b57cec5SDimitry Andric case StoredTypeSpecWithTemplate: 1950b57cec5SDimitry Andric return getAsType()->getAsCXXRecordDecl(); 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric llvm_unreachable("Invalid NNS Kind!"); 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2015ffd83dbSDimitry Andric NestedNameSpecifierDependence NestedNameSpecifier::getDependence() const { 2020b57cec5SDimitry Andric switch (getKind()) { 2035ffd83dbSDimitry Andric case Identifier: { 2040b57cec5SDimitry Andric // Identifier specifiers always represent dependent types 2055ffd83dbSDimitry Andric auto F = NestedNameSpecifierDependence::Dependent | 2065ffd83dbSDimitry Andric NestedNameSpecifierDependence::Instantiation; 2075ffd83dbSDimitry Andric // Prefix can contain unexpanded template parameters. 2085ffd83dbSDimitry Andric if (getPrefix()) 2095ffd83dbSDimitry Andric return F | getPrefix()->getDependence(); 2105ffd83dbSDimitry Andric return F; 2115ffd83dbSDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric case Namespace: 2140b57cec5SDimitry Andric case NamespaceAlias: 2150b57cec5SDimitry Andric case Global: 2165ffd83dbSDimitry Andric return NestedNameSpecifierDependence::None; 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric case Super: { 2190b57cec5SDimitry Andric CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier); 2200b57cec5SDimitry Andric for (const auto &Base : RD->bases()) 2210b57cec5SDimitry Andric if (Base.getType()->isDependentType()) 2225ffd83dbSDimitry Andric // FIXME: must also be instantiation-dependent. 2235ffd83dbSDimitry Andric return NestedNameSpecifierDependence::Dependent; 2245ffd83dbSDimitry Andric return NestedNameSpecifierDependence::None; 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric case TypeSpec: 2280b57cec5SDimitry Andric case TypeSpecWithTemplate: 2295ffd83dbSDimitry Andric return toNestedNameSpecifierDependendence(getAsType()->getDependence()); 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric llvm_unreachable("Invalid NNS Kind!"); 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2345ffd83dbSDimitry Andric bool NestedNameSpecifier::isDependent() const { 2355ffd83dbSDimitry Andric return getDependence() & NestedNameSpecifierDependence::Dependent; 2365ffd83dbSDimitry Andric } 2375ffd83dbSDimitry Andric 2380b57cec5SDimitry Andric bool NestedNameSpecifier::isInstantiationDependent() const { 2395ffd83dbSDimitry Andric return getDependence() & NestedNameSpecifierDependence::Instantiation; 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric bool NestedNameSpecifier::containsUnexpandedParameterPack() const { 2435ffd83dbSDimitry Andric return getDependence() & NestedNameSpecifierDependence::UnexpandedPack; 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 2465ffd83dbSDimitry Andric bool NestedNameSpecifier::containsErrors() const { 2475ffd83dbSDimitry Andric return getDependence() & NestedNameSpecifierDependence::Error; 2480b57cec5SDimitry Andric } 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric /// Print this nested name specifier to the given output 2510b57cec5SDimitry Andric /// stream. 2520b57cec5SDimitry Andric void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy, 2530b57cec5SDimitry Andric bool ResolveTemplateArguments) const { 2540b57cec5SDimitry Andric if (getPrefix()) 2550b57cec5SDimitry Andric getPrefix()->print(OS, Policy); 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric switch (getKind()) { 2580b57cec5SDimitry Andric case Identifier: 2590b57cec5SDimitry Andric OS << getAsIdentifier()->getName(); 2600b57cec5SDimitry Andric break; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric case Namespace: 2630b57cec5SDimitry Andric if (getAsNamespace()->isAnonymousNamespace()) 2640b57cec5SDimitry Andric return; 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric OS << getAsNamespace()->getName(); 2670b57cec5SDimitry Andric break; 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric case NamespaceAlias: 2700b57cec5SDimitry Andric OS << getAsNamespaceAlias()->getName(); 2710b57cec5SDimitry Andric break; 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric case Global: 2740b57cec5SDimitry Andric break; 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric case Super: 2770b57cec5SDimitry Andric OS << "__super"; 2780b57cec5SDimitry Andric break; 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric case TypeSpecWithTemplate: 2810b57cec5SDimitry Andric OS << "template "; 2820b57cec5SDimitry Andric // Fall through to print the type. 283bdd1243dSDimitry Andric [[fallthrough]]; 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric case TypeSpec: { 2860b57cec5SDimitry Andric const auto *Record = 2870b57cec5SDimitry Andric dyn_cast_or_null<ClassTemplateSpecializationDecl>(getAsRecordDecl()); 2880b57cec5SDimitry Andric if (ResolveTemplateArguments && Record) { 2890b57cec5SDimitry Andric // Print the type trait with resolved template parameters. 290bdd1243dSDimitry Andric Record->printName(OS, Policy); 291fe6060f1SDimitry Andric printTemplateArgumentList( 292fe6060f1SDimitry Andric OS, Record->getTemplateArgs().asArray(), Policy, 293fe6060f1SDimitry Andric Record->getSpecializedTemplate()->getTemplateParameters()); 2940b57cec5SDimitry Andric break; 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric const Type *T = getAsType(); 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric PrintingPolicy InnerPolicy(Policy); 2990b57cec5SDimitry Andric InnerPolicy.SuppressScope = true; 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric // Nested-name-specifiers are intended to contain minimally-qualified 3020b57cec5SDimitry Andric // types. An actual ElaboratedType will not occur, since we'll store 3030b57cec5SDimitry Andric // just the type that is referred to in the nested-name-specifier (e.g., 3040b57cec5SDimitry Andric // a TypedefType, TagType, etc.). However, when we are dealing with 3050b57cec5SDimitry Andric // dependent template-id types (e.g., Outer<T>::template Inner<U>), 3060b57cec5SDimitry Andric // the type requires its own nested-name-specifier for uniqueness, so we 3070b57cec5SDimitry Andric // suppress that nested-name-specifier during printing. 3080b57cec5SDimitry Andric assert(!isa<ElaboratedType>(T) && 3090b57cec5SDimitry Andric "Elaborated type in nested-name-specifier"); 3100b57cec5SDimitry Andric if (const TemplateSpecializationType *SpecType 3110b57cec5SDimitry Andric = dyn_cast<TemplateSpecializationType>(T)) { 3120b57cec5SDimitry Andric // Print the template name without its corresponding 3130b57cec5SDimitry Andric // nested-name-specifier. 314349cc55cSDimitry Andric SpecType->getTemplateName().print(OS, InnerPolicy, 315349cc55cSDimitry Andric TemplateName::Qualified::None); 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric // Print the template argument list. 3180b57cec5SDimitry Andric printTemplateArgumentList(OS, SpecType->template_arguments(), 3190b57cec5SDimitry Andric InnerPolicy); 3205ffd83dbSDimitry Andric } else if (const auto *DepSpecType = 3215ffd83dbSDimitry Andric dyn_cast<DependentTemplateSpecializationType>(T)) { 3225ffd83dbSDimitry Andric // Print the template name without its corresponding 3235ffd83dbSDimitry Andric // nested-name-specifier. 3245ffd83dbSDimitry Andric OS << DepSpecType->getIdentifier()->getName(); 3255ffd83dbSDimitry Andric // Print the template argument list. 3265ffd83dbSDimitry Andric printTemplateArgumentList(OS, DepSpecType->template_arguments(), 3275ffd83dbSDimitry Andric InnerPolicy); 3280b57cec5SDimitry Andric } else { 3290b57cec5SDimitry Andric // Print the type normally 3300b57cec5SDimitry Andric QualType(T, 0).print(OS, InnerPolicy); 3310b57cec5SDimitry Andric } 3320b57cec5SDimitry Andric break; 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric OS << "::"; 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric LLVM_DUMP_METHOD void NestedNameSpecifier::dump(const LangOptions &LO) const { 3400b57cec5SDimitry Andric dump(llvm::errs(), LO); 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric LLVM_DUMP_METHOD void NestedNameSpecifier::dump() const { dump(llvm::errs()); } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS) const { 3460b57cec5SDimitry Andric LangOptions LO; 3470b57cec5SDimitry Andric dump(OS, LO); 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS, 3510b57cec5SDimitry Andric const LangOptions &LO) const { 3520b57cec5SDimitry Andric print(OS, PrintingPolicy(LO)); 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric unsigned 3560b57cec5SDimitry Andric NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) { 3570b57cec5SDimitry Andric assert(Qualifier && "Expected a non-NULL qualifier"); 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric // Location of the trailing '::'. 360fe6060f1SDimitry Andric unsigned Length = sizeof(SourceLocation::UIntTy); 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric switch (Qualifier->getKind()) { 3630b57cec5SDimitry Andric case NestedNameSpecifier::Global: 3640b57cec5SDimitry Andric // Nothing more to add. 3650b57cec5SDimitry Andric break; 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric case NestedNameSpecifier::Identifier: 3680b57cec5SDimitry Andric case NestedNameSpecifier::Namespace: 3690b57cec5SDimitry Andric case NestedNameSpecifier::NamespaceAlias: 3700b57cec5SDimitry Andric case NestedNameSpecifier::Super: 3710b57cec5SDimitry Andric // The location of the identifier or namespace name. 372fe6060f1SDimitry Andric Length += sizeof(SourceLocation::UIntTy); 3730b57cec5SDimitry Andric break; 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric case NestedNameSpecifier::TypeSpecWithTemplate: 3760b57cec5SDimitry Andric case NestedNameSpecifier::TypeSpec: 3770b57cec5SDimitry Andric // The "void*" that points at the TypeLoc data. 3780b57cec5SDimitry Andric // Note: the 'template' keyword is part of the TypeLoc. 3790b57cec5SDimitry Andric Length += sizeof(void *); 3800b57cec5SDimitry Andric break; 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric return Length; 3840b57cec5SDimitry Andric } 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric unsigned 3870b57cec5SDimitry Andric NestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) { 3880b57cec5SDimitry Andric unsigned Length = 0; 3890b57cec5SDimitry Andric for (; Qualifier; Qualifier = Qualifier->getPrefix()) 3900b57cec5SDimitry Andric Length += getLocalDataLength(Qualifier); 3910b57cec5SDimitry Andric return Length; 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric /// Load a (possibly unaligned) source location from a given address 3950b57cec5SDimitry Andric /// and offset. 3960b57cec5SDimitry Andric static SourceLocation LoadSourceLocation(void *Data, unsigned Offset) { 397fe6060f1SDimitry Andric SourceLocation::UIntTy Raw; 398fe6060f1SDimitry Andric memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(Raw)); 3990b57cec5SDimitry Andric return SourceLocation::getFromRawEncoding(Raw); 4000b57cec5SDimitry Andric } 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric /// Load a (possibly unaligned) pointer from a given address and 4030b57cec5SDimitry Andric /// offset. 4040b57cec5SDimitry Andric static void *LoadPointer(void *Data, unsigned Offset) { 4050b57cec5SDimitry Andric void *Result; 4060b57cec5SDimitry Andric memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*)); 4070b57cec5SDimitry Andric return Result; 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric SourceRange NestedNameSpecifierLoc::getSourceRange() const { 4110b57cec5SDimitry Andric if (!Qualifier) 4120b57cec5SDimitry Andric return SourceRange(); 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric NestedNameSpecifierLoc First = *this; 4150b57cec5SDimitry Andric while (NestedNameSpecifierLoc Prefix = First.getPrefix()) 4160b57cec5SDimitry Andric First = Prefix; 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric return SourceRange(First.getLocalSourceRange().getBegin(), 4190b57cec5SDimitry Andric getLocalSourceRange().getEnd()); 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const { 4230b57cec5SDimitry Andric if (!Qualifier) 4240b57cec5SDimitry Andric return SourceRange(); 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric unsigned Offset = getDataLength(Qualifier->getPrefix()); 4270b57cec5SDimitry Andric switch (Qualifier->getKind()) { 4280b57cec5SDimitry Andric case NestedNameSpecifier::Global: 4290b57cec5SDimitry Andric return LoadSourceLocation(Data, Offset); 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric case NestedNameSpecifier::Identifier: 4320b57cec5SDimitry Andric case NestedNameSpecifier::Namespace: 4330b57cec5SDimitry Andric case NestedNameSpecifier::NamespaceAlias: 4340b57cec5SDimitry Andric case NestedNameSpecifier::Super: 435fe6060f1SDimitry Andric return SourceRange( 436fe6060f1SDimitry Andric LoadSourceLocation(Data, Offset), 437fe6060f1SDimitry Andric LoadSourceLocation(Data, Offset + sizeof(SourceLocation::UIntTy))); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric case NestedNameSpecifier::TypeSpecWithTemplate: 4400b57cec5SDimitry Andric case NestedNameSpecifier::TypeSpec: { 4410b57cec5SDimitry Andric // The "void*" that points at the TypeLoc data. 4420b57cec5SDimitry Andric // Note: the 'template' keyword is part of the TypeLoc. 4430b57cec5SDimitry Andric void *TypeData = LoadPointer(Data, Offset); 4440b57cec5SDimitry Andric TypeLoc TL(Qualifier->getAsType(), TypeData); 4450b57cec5SDimitry Andric return SourceRange(TL.getBeginLoc(), 4460b57cec5SDimitry Andric LoadSourceLocation(Data, Offset + sizeof(void*))); 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric } 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric llvm_unreachable("Invalid NNS Kind!"); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric TypeLoc NestedNameSpecifierLoc::getTypeLoc() const { 4540b57cec5SDimitry Andric if (Qualifier->getKind() != NestedNameSpecifier::TypeSpec && 4550b57cec5SDimitry Andric Qualifier->getKind() != NestedNameSpecifier::TypeSpecWithTemplate) 4560b57cec5SDimitry Andric return TypeLoc(); 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric // The "void*" that points at the TypeLoc data. 4590b57cec5SDimitry Andric unsigned Offset = getDataLength(Qualifier->getPrefix()); 4600b57cec5SDimitry Andric void *TypeData = LoadPointer(Data, Offset); 4610b57cec5SDimitry Andric return TypeLoc(Qualifier->getAsType(), TypeData); 4620b57cec5SDimitry Andric } 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize, 4650b57cec5SDimitry Andric unsigned &BufferCapacity) { 4660b57cec5SDimitry Andric if (Start == End) 4670b57cec5SDimitry Andric return; 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric if (BufferSize + (End - Start) > BufferCapacity) { 4700b57cec5SDimitry Andric // Reallocate the buffer. 4710b57cec5SDimitry Andric unsigned NewCapacity = std::max( 4720b57cec5SDimitry Andric (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2), 4730b57cec5SDimitry Andric (unsigned)(BufferSize + (End - Start))); 4745ffd83dbSDimitry Andric if (!BufferCapacity) { 4750b57cec5SDimitry Andric char *NewBuffer = static_cast<char *>(llvm::safe_malloc(NewCapacity)); 4765ffd83dbSDimitry Andric if (Buffer) 4770b57cec5SDimitry Andric memcpy(NewBuffer, Buffer, BufferSize); 4780b57cec5SDimitry Andric Buffer = NewBuffer; 4795ffd83dbSDimitry Andric } else { 4805ffd83dbSDimitry Andric Buffer = static_cast<char *>(llvm::safe_realloc(Buffer, NewCapacity)); 4815ffd83dbSDimitry Andric } 4820b57cec5SDimitry Andric BufferCapacity = NewCapacity; 4830b57cec5SDimitry Andric } 484480093f4SDimitry Andric assert(Buffer && Start && End && End > Start && "Illegal memory buffer copy"); 4850b57cec5SDimitry Andric memcpy(Buffer + BufferSize, Start, End - Start); 4860b57cec5SDimitry Andric BufferSize += End - Start; 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric /// Save a source location to the given buffer. 4900b57cec5SDimitry Andric static void SaveSourceLocation(SourceLocation Loc, char *&Buffer, 4910b57cec5SDimitry Andric unsigned &BufferSize, unsigned &BufferCapacity) { 492fe6060f1SDimitry Andric SourceLocation::UIntTy Raw = Loc.getRawEncoding(); 4930b57cec5SDimitry Andric Append(reinterpret_cast<char *>(&Raw), 494fe6060f1SDimitry Andric reinterpret_cast<char *>(&Raw) + sizeof(Raw), Buffer, BufferSize, 495fe6060f1SDimitry Andric BufferCapacity); 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric /// Save a pointer to the given buffer. 4990b57cec5SDimitry Andric static void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize, 5000b57cec5SDimitry Andric unsigned &BufferCapacity) { 5010b57cec5SDimitry Andric Append(reinterpret_cast<char *>(&Ptr), 5020b57cec5SDimitry Andric reinterpret_cast<char *>(&Ptr) + sizeof(void *), 5030b57cec5SDimitry Andric Buffer, BufferSize, BufferCapacity); 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric NestedNameSpecifierLocBuilder:: 5070b57cec5SDimitry Andric NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other) 5080b57cec5SDimitry Andric : Representation(Other.Representation) { 5090b57cec5SDimitry Andric if (!Other.Buffer) 5100b57cec5SDimitry Andric return; 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric if (Other.BufferCapacity == 0) { 5130b57cec5SDimitry Andric // Shallow copy is okay. 5140b57cec5SDimitry Andric Buffer = Other.Buffer; 5150b57cec5SDimitry Andric BufferSize = Other.BufferSize; 5160b57cec5SDimitry Andric return; 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric // Deep copy 5200b57cec5SDimitry Andric Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize, 5210b57cec5SDimitry Andric BufferCapacity); 5220b57cec5SDimitry Andric } 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric NestedNameSpecifierLocBuilder & 5250b57cec5SDimitry Andric NestedNameSpecifierLocBuilder:: 5260b57cec5SDimitry Andric operator=(const NestedNameSpecifierLocBuilder &Other) { 5270b57cec5SDimitry Andric Representation = Other.Representation; 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) { 5300b57cec5SDimitry Andric // Re-use our storage. 5310b57cec5SDimitry Andric BufferSize = Other.BufferSize; 5320b57cec5SDimitry Andric memcpy(Buffer, Other.Buffer, BufferSize); 5330b57cec5SDimitry Andric return *this; 5340b57cec5SDimitry Andric } 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric // Free our storage, if we have any. 5370b57cec5SDimitry Andric if (BufferCapacity) { 5380b57cec5SDimitry Andric free(Buffer); 5390b57cec5SDimitry Andric BufferCapacity = 0; 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric if (!Other.Buffer) { 5430b57cec5SDimitry Andric // Empty. 5440b57cec5SDimitry Andric Buffer = nullptr; 5450b57cec5SDimitry Andric BufferSize = 0; 5460b57cec5SDimitry Andric return *this; 5470b57cec5SDimitry Andric } 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric if (Other.BufferCapacity == 0) { 5500b57cec5SDimitry Andric // Shallow copy is okay. 5510b57cec5SDimitry Andric Buffer = Other.Buffer; 5520b57cec5SDimitry Andric BufferSize = Other.BufferSize; 5530b57cec5SDimitry Andric return *this; 5540b57cec5SDimitry Andric } 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric // Deep copy. 5570b57cec5SDimitry Andric BufferSize = 0; 5580b57cec5SDimitry Andric Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize, 5590b57cec5SDimitry Andric BufferCapacity); 5600b57cec5SDimitry Andric return *this; 5610b57cec5SDimitry Andric } 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 5640b57cec5SDimitry Andric SourceLocation TemplateKWLoc, 5650b57cec5SDimitry Andric TypeLoc TL, 5660b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 5670b57cec5SDimitry Andric Representation = NestedNameSpecifier::Create(Context, Representation, 5680b57cec5SDimitry Andric TemplateKWLoc.isValid(), 5690b57cec5SDimitry Andric TL.getTypePtr()); 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric // Push source-location info into the buffer. 5720b57cec5SDimitry Andric SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity); 5730b57cec5SDimitry Andric SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 5740b57cec5SDimitry Andric } 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andric void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 5770b57cec5SDimitry Andric IdentifierInfo *Identifier, 5780b57cec5SDimitry Andric SourceLocation IdentifierLoc, 5790b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 5800b57cec5SDimitry Andric Representation = NestedNameSpecifier::Create(Context, Representation, 5810b57cec5SDimitry Andric Identifier); 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric // Push source-location info into the buffer. 5840b57cec5SDimitry Andric SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity); 5850b57cec5SDimitry Andric SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 5890b57cec5SDimitry Andric NamespaceDecl *Namespace, 5900b57cec5SDimitry Andric SourceLocation NamespaceLoc, 5910b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 5920b57cec5SDimitry Andric Representation = NestedNameSpecifier::Create(Context, Representation, 5930b57cec5SDimitry Andric Namespace); 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric // Push source-location info into the buffer. 5960b57cec5SDimitry Andric SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity); 5970b57cec5SDimitry Andric SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 6010b57cec5SDimitry Andric NamespaceAliasDecl *Alias, 6020b57cec5SDimitry Andric SourceLocation AliasLoc, 6030b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 6040b57cec5SDimitry Andric Representation = NestedNameSpecifier::Create(Context, Representation, Alias); 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric // Push source-location info into the buffer. 6070b57cec5SDimitry Andric SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity); 6080b57cec5SDimitry Andric SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context, 6120b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 6130b57cec5SDimitry Andric assert(!Representation && "Already have a nested-name-specifier!?"); 6140b57cec5SDimitry Andric Representation = NestedNameSpecifier::GlobalSpecifier(Context); 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric // Push source-location info into the buffer. 6170b57cec5SDimitry Andric SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 6180b57cec5SDimitry Andric } 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric void NestedNameSpecifierLocBuilder::MakeSuper(ASTContext &Context, 6210b57cec5SDimitry Andric CXXRecordDecl *RD, 6220b57cec5SDimitry Andric SourceLocation SuperLoc, 6230b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 6240b57cec5SDimitry Andric Representation = NestedNameSpecifier::SuperSpecifier(Context, RD); 6250b57cec5SDimitry Andric 6260b57cec5SDimitry Andric // Push source-location info into the buffer. 6270b57cec5SDimitry Andric SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity); 6280b57cec5SDimitry Andric SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 6290b57cec5SDimitry Andric } 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context, 6320b57cec5SDimitry Andric NestedNameSpecifier *Qualifier, 6330b57cec5SDimitry Andric SourceRange R) { 6340b57cec5SDimitry Andric Representation = Qualifier; 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric // Construct bogus (but well-formed) source information for the 6370b57cec5SDimitry Andric // nested-name-specifier. 6380b57cec5SDimitry Andric BufferSize = 0; 6390b57cec5SDimitry Andric SmallVector<NestedNameSpecifier *, 4> Stack; 6400b57cec5SDimitry Andric for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix()) 6410b57cec5SDimitry Andric Stack.push_back(NNS); 6420b57cec5SDimitry Andric while (!Stack.empty()) { 6430b57cec5SDimitry Andric NestedNameSpecifier *NNS = Stack.pop_back_val(); 6440b57cec5SDimitry Andric switch (NNS->getKind()) { 6450b57cec5SDimitry Andric case NestedNameSpecifier::Identifier: 6460b57cec5SDimitry Andric case NestedNameSpecifier::Namespace: 6470b57cec5SDimitry Andric case NestedNameSpecifier::NamespaceAlias: 6480b57cec5SDimitry Andric SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity); 6490b57cec5SDimitry Andric break; 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric case NestedNameSpecifier::TypeSpec: 6520b57cec5SDimitry Andric case NestedNameSpecifier::TypeSpecWithTemplate: { 6530b57cec5SDimitry Andric TypeSourceInfo *TSInfo 6540b57cec5SDimitry Andric = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0), 6550b57cec5SDimitry Andric R.getBegin()); 6560b57cec5SDimitry Andric SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize, 6570b57cec5SDimitry Andric BufferCapacity); 6580b57cec5SDimitry Andric break; 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric case NestedNameSpecifier::Global: 6620b57cec5SDimitry Andric case NestedNameSpecifier::Super: 6630b57cec5SDimitry Andric break; 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric // Save the location of the '::'. 6670b57cec5SDimitry Andric SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(), 6680b57cec5SDimitry Andric Buffer, BufferSize, BufferCapacity); 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric } 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) { 6730b57cec5SDimitry Andric if (BufferCapacity) 6740b57cec5SDimitry Andric free(Buffer); 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric if (!Other) { 6770b57cec5SDimitry Andric Representation = nullptr; 6780b57cec5SDimitry Andric BufferSize = 0; 6790b57cec5SDimitry Andric return; 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric // Rather than copying the data (which is wasteful), "adopt" the 6830b57cec5SDimitry Andric // pointer (which points into the ASTContext) but set the capacity to zero to 6840b57cec5SDimitry Andric // indicate that we don't own it. 6850b57cec5SDimitry Andric Representation = Other.getNestedNameSpecifier(); 6860b57cec5SDimitry Andric Buffer = static_cast<char *>(Other.getOpaqueData()); 6870b57cec5SDimitry Andric BufferSize = Other.getDataLength(); 6880b57cec5SDimitry Andric BufferCapacity = 0; 6890b57cec5SDimitry Andric } 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric NestedNameSpecifierLoc 6920b57cec5SDimitry Andric NestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const { 6930b57cec5SDimitry Andric if (!Representation) 6940b57cec5SDimitry Andric return NestedNameSpecifierLoc(); 6950b57cec5SDimitry Andric 6960b57cec5SDimitry Andric // If we adopted our data pointer from elsewhere in the AST context, there's 6970b57cec5SDimitry Andric // no need to copy the memory. 6980b57cec5SDimitry Andric if (BufferCapacity == 0) 6990b57cec5SDimitry Andric return NestedNameSpecifierLoc(Representation, Buffer); 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andric // FIXME: After copying the source-location information, should we free 7020b57cec5SDimitry Andric // our (temporary) buffer and adopt the ASTContext-allocated memory? 7030b57cec5SDimitry Andric // Doing so would optimize repeated calls to getWithLocInContext(). 7040b57cec5SDimitry Andric void *Mem = Context.Allocate(BufferSize, alignof(void *)); 7050b57cec5SDimitry Andric memcpy(Mem, Buffer, BufferSize); 7060b57cec5SDimitry Andric return NestedNameSpecifierLoc(Representation, Mem); 7070b57cec5SDimitry Andric } 708