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