NestedNameSpecifier.cpp revision 314564
1193326Sed//===--- NestedNameSpecifier.cpp - C++ nested name specifiers -----*- C++ -*-=// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines the NestedNameSpecifier class, which represents 11193326Sed// a C++ nested-name-specifier. 12193326Sed// 13193326Sed//===----------------------------------------------------------------------===// 14193326Sed#include "clang/AST/NestedNameSpecifier.h" 15193326Sed#include "clang/AST/ASTContext.h" 16193326Sed#include "clang/AST/Decl.h" 17219077Sdim#include "clang/AST/DeclCXX.h" 18193326Sed#include "clang/AST/PrettyPrinter.h" 19193326Sed#include "clang/AST/Type.h" 20219077Sdim#include "clang/AST/TypeLoc.h" 21239462Sdim#include "llvm/Support/AlignOf.h" 22193326Sed#include "llvm/Support/raw_ostream.h" 23193326Sed#include <cassert> 24193326Sed 25193326Sedusing namespace clang; 26193326Sed 27193326SedNestedNameSpecifier * 28218893SdimNestedNameSpecifier::FindOrInsert(const ASTContext &Context, 29193326Sed const NestedNameSpecifier &Mockup) { 30193326Sed llvm::FoldingSetNodeID ID; 31193326Sed Mockup.Profile(ID); 32193326Sed 33276479Sdim void *InsertPos = nullptr; 34198092Srdivacky NestedNameSpecifier *NNS 35193326Sed = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos); 36193326Sed if (!NNS) { 37314564Sdim NNS = 38314564Sdim new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(Mockup); 39193326Sed Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos); 40193326Sed } 41193326Sed 42193326Sed return NNS; 43193326Sed} 44193326Sed 45193326SedNestedNameSpecifier * 46218893SdimNestedNameSpecifier::Create(const ASTContext &Context, 47218893Sdim NestedNameSpecifier *Prefix, IdentifierInfo *II) { 48193326Sed assert(II && "Identifier cannot be NULL"); 49198092Srdivacky assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent"); 50193326Sed 51193326Sed NestedNameSpecifier Mockup; 52193326Sed Mockup.Prefix.setPointer(Prefix); 53219077Sdim Mockup.Prefix.setInt(StoredIdentifier); 54193326Sed Mockup.Specifier = II; 55193326Sed return FindOrInsert(Context, Mockup); 56193326Sed} 57193326Sed 58193326SedNestedNameSpecifier * 59218893SdimNestedNameSpecifier::Create(const ASTContext &Context, 60249423Sdim NestedNameSpecifier *Prefix, 61249423Sdim const NamespaceDecl *NS) { 62193326Sed assert(NS && "Namespace cannot be NULL"); 63198092Srdivacky assert((!Prefix || 64276479Sdim (Prefix->getAsType() == nullptr && 65276479Sdim Prefix->getAsIdentifier() == nullptr)) && 66193326Sed "Broken nested name specifier"); 67193326Sed NestedNameSpecifier Mockup; 68193326Sed Mockup.Prefix.setPointer(Prefix); 69280031Sdim Mockup.Prefix.setInt(StoredDecl); 70249423Sdim Mockup.Specifier = const_cast<NamespaceDecl *>(NS); 71193326Sed return FindOrInsert(Context, Mockup); 72193326Sed} 73193326Sed 74193326SedNestedNameSpecifier * 75218893SdimNestedNameSpecifier::Create(const ASTContext &Context, 76219077Sdim NestedNameSpecifier *Prefix, 77219077Sdim NamespaceAliasDecl *Alias) { 78219077Sdim assert(Alias && "Namespace alias cannot be NULL"); 79219077Sdim assert((!Prefix || 80276479Sdim (Prefix->getAsType() == nullptr && 81276479Sdim Prefix->getAsIdentifier() == nullptr)) && 82219077Sdim "Broken nested name specifier"); 83219077Sdim NestedNameSpecifier Mockup; 84219077Sdim Mockup.Prefix.setPointer(Prefix); 85280031Sdim Mockup.Prefix.setInt(StoredDecl); 86219077Sdim Mockup.Specifier = Alias; 87219077Sdim return FindOrInsert(Context, Mockup); 88219077Sdim} 89219077Sdim 90219077SdimNestedNameSpecifier * 91219077SdimNestedNameSpecifier::Create(const ASTContext &Context, 92218893Sdim NestedNameSpecifier *Prefix, 93218893Sdim bool Template, const Type *T) { 94193326Sed assert(T && "Type cannot be NULL"); 95193326Sed NestedNameSpecifier Mockup; 96193326Sed Mockup.Prefix.setPointer(Prefix); 97219077Sdim Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec); 98218893Sdim Mockup.Specifier = const_cast<Type*>(T); 99193326Sed return FindOrInsert(Context, Mockup); 100193326Sed} 101198092Srdivacky 102198092SrdivackyNestedNameSpecifier * 103218893SdimNestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) { 104198092Srdivacky assert(II && "Identifier cannot be NULL"); 105198092Srdivacky NestedNameSpecifier Mockup; 106276479Sdim Mockup.Prefix.setPointer(nullptr); 107219077Sdim Mockup.Prefix.setInt(StoredIdentifier); 108198092Srdivacky Mockup.Specifier = II; 109198092Srdivacky return FindOrInsert(Context, Mockup); 110198092Srdivacky} 111198092Srdivacky 112218893SdimNestedNameSpecifier * 113218893SdimNestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) { 114193326Sed if (!Context.GlobalNestedNameSpecifier) 115239462Sdim Context.GlobalNestedNameSpecifier = 116314564Sdim new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(); 117193326Sed return Context.GlobalNestedNameSpecifier; 118193326Sed} 119193326Sed 120280031SdimNestedNameSpecifier * 121280031SdimNestedNameSpecifier::SuperSpecifier(const ASTContext &Context, 122280031Sdim CXXRecordDecl *RD) { 123280031Sdim NestedNameSpecifier Mockup; 124280031Sdim Mockup.Prefix.setPointer(nullptr); 125280031Sdim Mockup.Prefix.setInt(StoredDecl); 126280031Sdim Mockup.Specifier = RD; 127280031Sdim return FindOrInsert(Context, Mockup); 128280031Sdim} 129280031Sdim 130219077SdimNestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const { 131276479Sdim if (!Specifier) 132219077Sdim return Global; 133219077Sdim 134219077Sdim switch (Prefix.getInt()) { 135219077Sdim case StoredIdentifier: 136219077Sdim return Identifier; 137219077Sdim 138280031Sdim case StoredDecl: { 139280031Sdim NamedDecl *ND = static_cast<NamedDecl *>(Specifier); 140280031Sdim if (isa<CXXRecordDecl>(ND)) 141280031Sdim return Super; 142280031Sdim return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias; 143280031Sdim } 144219077Sdim 145219077Sdim case StoredTypeSpec: 146219077Sdim return TypeSpec; 147219077Sdim 148219077Sdim case StoredTypeSpecWithTemplate: 149219077Sdim return TypeSpecWithTemplate; 150219077Sdim } 151219077Sdim 152234353Sdim llvm_unreachable("Invalid NNS Kind!"); 153219077Sdim} 154219077Sdim 155280031Sdim/// \brief Retrieve the namespace stored in this nested name specifier. 156219077SdimNamespaceDecl *NestedNameSpecifier::getAsNamespace() const { 157314564Sdim if (Prefix.getInt() == StoredDecl) 158219077Sdim return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier)); 159219077Sdim 160276479Sdim return nullptr; 161219077Sdim} 162219077Sdim 163280031Sdim/// \brief Retrieve the namespace alias stored in this nested name specifier. 164219077SdimNamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const { 165314564Sdim if (Prefix.getInt() == StoredDecl) 166219077Sdim return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier)); 167219077Sdim 168276479Sdim return nullptr; 169219077Sdim} 170219077Sdim 171280031Sdim/// \brief Retrieve the record declaration stored in this nested name specifier. 172280031SdimCXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const { 173309124Sdim switch (Prefix.getInt()) { 174309124Sdim case StoredIdentifier: 175309124Sdim return nullptr; 176309124Sdim 177309124Sdim case StoredDecl: 178280031Sdim return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier)); 179219077Sdim 180309124Sdim case StoredTypeSpec: 181309124Sdim case StoredTypeSpecWithTemplate: 182309124Sdim return getAsType()->getAsCXXRecordDecl(); 183309124Sdim } 184309124Sdim 185309124Sdim llvm_unreachable("Invalid NNS Kind!"); 186280031Sdim} 187280031Sdim 188193326Sed/// \brief Whether this nested name specifier refers to a dependent 189193326Sed/// type or not. 190193326Sedbool NestedNameSpecifier::isDependent() const { 191193326Sed switch (getKind()) { 192193326Sed case Identifier: 193193326Sed // Identifier specifiers always represent dependent types 194193326Sed return true; 195193326Sed 196193326Sed case Namespace: 197219077Sdim case NamespaceAlias: 198193326Sed case Global: 199193326Sed return false; 200193326Sed 201280031Sdim case Super: { 202280031Sdim CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier); 203280031Sdim for (const auto &Base : RD->bases()) 204280031Sdim if (Base.getType()->isDependentType()) 205280031Sdim return true; 206280031Sdim 207280031Sdim return false; 208280031Sdim } 209280031Sdim 210193326Sed case TypeSpec: 211193326Sed case TypeSpecWithTemplate: 212193326Sed return getAsType()->isDependentType(); 213193326Sed } 214193326Sed 215234353Sdim llvm_unreachable("Invalid NNS Kind!"); 216193326Sed} 217193326Sed 218224145Sdim/// \brief Whether this nested name specifier refers to a dependent 219224145Sdim/// type or not. 220224145Sdimbool NestedNameSpecifier::isInstantiationDependent() const { 221224145Sdim switch (getKind()) { 222224145Sdim case Identifier: 223224145Sdim // Identifier specifiers always represent dependent types 224224145Sdim return true; 225224145Sdim 226224145Sdim case Namespace: 227224145Sdim case NamespaceAlias: 228224145Sdim case Global: 229280031Sdim case Super: 230224145Sdim return false; 231280031Sdim 232224145Sdim case TypeSpec: 233224145Sdim case TypeSpecWithTemplate: 234224145Sdim return getAsType()->isInstantiationDependentType(); 235224145Sdim } 236234353Sdim 237234353Sdim llvm_unreachable("Invalid NNS Kind!"); 238224145Sdim} 239224145Sdim 240218893Sdimbool NestedNameSpecifier::containsUnexpandedParameterPack() const { 241218893Sdim switch (getKind()) { 242218893Sdim case Identifier: 243218893Sdim return getPrefix() && getPrefix()->containsUnexpandedParameterPack(); 244218893Sdim 245218893Sdim case Namespace: 246219077Sdim case NamespaceAlias: 247218893Sdim case Global: 248280031Sdim case Super: 249218893Sdim return false; 250218893Sdim 251218893Sdim case TypeSpec: 252218893Sdim case TypeSpecWithTemplate: 253218893Sdim return getAsType()->containsUnexpandedParameterPack(); 254218893Sdim } 255218893Sdim 256234353Sdim llvm_unreachable("Invalid NNS Kind!"); 257218893Sdim} 258218893Sdim 259193326Sed/// \brief Print this nested name specifier to the given output 260193326Sed/// stream. 261198092Srdivackyvoid 262226633SdimNestedNameSpecifier::print(raw_ostream &OS, 263193326Sed const PrintingPolicy &Policy) const { 264193326Sed if (getPrefix()) 265193326Sed getPrefix()->print(OS, Policy); 266193326Sed 267193326Sed switch (getKind()) { 268193326Sed case Identifier: 269193326Sed OS << getAsIdentifier()->getName(); 270193326Sed break; 271193326Sed 272193326Sed case Namespace: 273234353Sdim if (getAsNamespace()->isAnonymousNamespace()) 274234353Sdim return; 275234353Sdim 276219077Sdim OS << getAsNamespace()->getName(); 277193326Sed break; 278193326Sed 279219077Sdim case NamespaceAlias: 280219077Sdim OS << getAsNamespaceAlias()->getName(); 281219077Sdim break; 282219077Sdim 283193326Sed case Global: 284193326Sed break; 285193326Sed 286280031Sdim case Super: 287280031Sdim OS << "__super"; 288280031Sdim break; 289280031Sdim 290193326Sed case TypeSpecWithTemplate: 291193326Sed OS << "template "; 292193326Sed // Fall through to print the type. 293193326Sed 294193326Sed case TypeSpec: { 295218893Sdim const Type *T = getAsType(); 296193326Sed 297193326Sed PrintingPolicy InnerPolicy(Policy); 298198092Srdivacky InnerPolicy.SuppressScope = true; 299198092Srdivacky 300198092Srdivacky // Nested-name-specifiers are intended to contain minimally-qualified 301208600Srdivacky // types. An actual ElaboratedType will not occur, since we'll store 302198092Srdivacky // just the type that is referred to in the nested-name-specifier (e.g., 303198092Srdivacky // a TypedefType, TagType, etc.). However, when we are dealing with 304198092Srdivacky // dependent template-id types (e.g., Outer<T>::template Inner<U>), 305198092Srdivacky // the type requires its own nested-name-specifier for uniqueness, so we 306198092Srdivacky // suppress that nested-name-specifier during printing. 307208600Srdivacky assert(!isa<ElaboratedType>(T) && 308208600Srdivacky "Elaborated type in nested-name-specifier"); 309198092Srdivacky if (const TemplateSpecializationType *SpecType 310198092Srdivacky = dyn_cast<TemplateSpecializationType>(T)) { 311198092Srdivacky // Print the template name without its corresponding 312198092Srdivacky // nested-name-specifier. 313198092Srdivacky SpecType->getTemplateName().print(OS, InnerPolicy, true); 314198092Srdivacky 315198092Srdivacky // Print the template argument list. 316249423Sdim TemplateSpecializationType::PrintTemplateArgumentList( 317309124Sdim OS, SpecType->template_arguments(), InnerPolicy); 318198092Srdivacky } else { 319198092Srdivacky // Print the type normally 320249423Sdim QualType(T, 0).print(OS, InnerPolicy); 321198092Srdivacky } 322193326Sed break; 323193326Sed } 324193326Sed } 325193326Sed 326193326Sed OS << "::"; 327193326Sed} 328193326Sed 329296417Sdimvoid NestedNameSpecifier::dump(const LangOptions &LO) const { 330195341Sed print(llvm::errs(), PrintingPolicy(LO)); 331193326Sed} 332219077Sdim 333309124SdimLLVM_DUMP_METHOD void NestedNameSpecifier::dump() const { 334296417Sdim LangOptions LO; 335296417Sdim print(llvm::errs(), PrintingPolicy(LO)); 336296417Sdim} 337296417Sdim 338219077Sdimunsigned 339219077SdimNestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) { 340219077Sdim assert(Qualifier && "Expected a non-NULL qualifier"); 341219077Sdim 342219077Sdim // Location of the trailing '::'. 343219077Sdim unsigned Length = sizeof(unsigned); 344219077Sdim 345219077Sdim switch (Qualifier->getKind()) { 346219077Sdim case NestedNameSpecifier::Global: 347219077Sdim // Nothing more to add. 348219077Sdim break; 349219077Sdim 350219077Sdim case NestedNameSpecifier::Identifier: 351219077Sdim case NestedNameSpecifier::Namespace: 352219077Sdim case NestedNameSpecifier::NamespaceAlias: 353280031Sdim case NestedNameSpecifier::Super: 354219077Sdim // The location of the identifier or namespace name. 355219077Sdim Length += sizeof(unsigned); 356219077Sdim break; 357219077Sdim 358219077Sdim case NestedNameSpecifier::TypeSpecWithTemplate: 359219077Sdim case NestedNameSpecifier::TypeSpec: 360219077Sdim // The "void*" that points at the TypeLoc data. 361219077Sdim // Note: the 'template' keyword is part of the TypeLoc. 362219077Sdim Length += sizeof(void *); 363219077Sdim break; 364219077Sdim } 365219077Sdim 366219077Sdim return Length; 367219077Sdim} 368219077Sdim 369219077Sdimunsigned 370219077SdimNestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) { 371219077Sdim unsigned Length = 0; 372219077Sdim for (; Qualifier; Qualifier = Qualifier->getPrefix()) 373219077Sdim Length += getLocalDataLength(Qualifier); 374219077Sdim return Length; 375219077Sdim} 376219077Sdim 377219077Sdimnamespace { 378219077Sdim /// \brief Load a (possibly unaligned) source location from a given address 379219077Sdim /// and offset. 380219077Sdim SourceLocation LoadSourceLocation(void *Data, unsigned Offset) { 381219077Sdim unsigned Raw; 382219077Sdim memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned)); 383219077Sdim return SourceLocation::getFromRawEncoding(Raw); 384219077Sdim } 385219077Sdim 386219077Sdim /// \brief Load a (possibly unaligned) pointer from a given address and 387219077Sdim /// offset. 388219077Sdim void *LoadPointer(void *Data, unsigned Offset) { 389219077Sdim void *Result; 390219077Sdim memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*)); 391219077Sdim return Result; 392219077Sdim } 393219077Sdim} 394219077Sdim 395219077SdimSourceRange NestedNameSpecifierLoc::getSourceRange() const { 396219077Sdim if (!Qualifier) 397219077Sdim return SourceRange(); 398219077Sdim 399219077Sdim NestedNameSpecifierLoc First = *this; 400219077Sdim while (NestedNameSpecifierLoc Prefix = First.getPrefix()) 401219077Sdim First = Prefix; 402219077Sdim 403219077Sdim return SourceRange(First.getLocalSourceRange().getBegin(), 404219077Sdim getLocalSourceRange().getEnd()); 405219077Sdim} 406219077Sdim 407219077SdimSourceRange NestedNameSpecifierLoc::getLocalSourceRange() const { 408219077Sdim if (!Qualifier) 409219077Sdim return SourceRange(); 410219077Sdim 411219077Sdim unsigned Offset = getDataLength(Qualifier->getPrefix()); 412219077Sdim switch (Qualifier->getKind()) { 413219077Sdim case NestedNameSpecifier::Global: 414219077Sdim return LoadSourceLocation(Data, Offset); 415219077Sdim 416219077Sdim case NestedNameSpecifier::Identifier: 417219077Sdim case NestedNameSpecifier::Namespace: 418219077Sdim case NestedNameSpecifier::NamespaceAlias: 419280031Sdim case NestedNameSpecifier::Super: 420219077Sdim return SourceRange(LoadSourceLocation(Data, Offset), 421219077Sdim LoadSourceLocation(Data, Offset + sizeof(unsigned))); 422219077Sdim 423219077Sdim case NestedNameSpecifier::TypeSpecWithTemplate: 424219077Sdim case NestedNameSpecifier::TypeSpec: { 425219077Sdim // The "void*" that points at the TypeLoc data. 426219077Sdim // Note: the 'template' keyword is part of the TypeLoc. 427219077Sdim void *TypeData = LoadPointer(Data, Offset); 428219077Sdim TypeLoc TL(Qualifier->getAsType(), TypeData); 429219077Sdim return SourceRange(TL.getBeginLoc(), 430219077Sdim LoadSourceLocation(Data, Offset + sizeof(void*))); 431219077Sdim } 432219077Sdim } 433234353Sdim 434234353Sdim llvm_unreachable("Invalid NNS Kind!"); 435219077Sdim} 436219077Sdim 437219077SdimTypeLoc NestedNameSpecifierLoc::getTypeLoc() const { 438219077Sdim assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec || 439219077Sdim Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) && 440219077Sdim "Nested-name-specifier location is not a type"); 441219077Sdim 442219077Sdim // The "void*" that points at the TypeLoc data. 443219077Sdim unsigned Offset = getDataLength(Qualifier->getPrefix()); 444219077Sdim void *TypeData = LoadPointer(Data, Offset); 445219077Sdim return TypeLoc(Qualifier->getAsType(), TypeData); 446219077Sdim} 447221345Sdim 448221345Sdimnamespace { 449221345Sdim void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize, 450221345Sdim unsigned &BufferCapacity) { 451288943Sdim if (Start == End) 452288943Sdim return; 453288943Sdim 454221345Sdim if (BufferSize + (End - Start) > BufferCapacity) { 455221345Sdim // Reallocate the buffer. 456288943Sdim unsigned NewCapacity = std::max( 457288943Sdim (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2), 458288943Sdim (unsigned)(BufferSize + (End - Start))); 459221345Sdim char *NewBuffer = static_cast<char *>(malloc(NewCapacity)); 460288943Sdim if (BufferCapacity) { 461288943Sdim memcpy(NewBuffer, Buffer, BufferSize); 462221345Sdim free(Buffer); 463288943Sdim } 464221345Sdim Buffer = NewBuffer; 465221345Sdim BufferCapacity = NewCapacity; 466221345Sdim } 467221345Sdim 468221345Sdim memcpy(Buffer + BufferSize, Start, End - Start); 469221345Sdim BufferSize += End-Start; 470221345Sdim } 471221345Sdim 472221345Sdim /// \brief Save a source location to the given buffer. 473221345Sdim void SaveSourceLocation(SourceLocation Loc, char *&Buffer, 474221345Sdim unsigned &BufferSize, unsigned &BufferCapacity) { 475221345Sdim unsigned Raw = Loc.getRawEncoding(); 476221345Sdim Append(reinterpret_cast<char *>(&Raw), 477221345Sdim reinterpret_cast<char *>(&Raw) + sizeof(unsigned), 478221345Sdim Buffer, BufferSize, BufferCapacity); 479221345Sdim } 480221345Sdim 481221345Sdim /// \brief Save a pointer to the given buffer. 482221345Sdim void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize, 483221345Sdim unsigned &BufferCapacity) { 484221345Sdim Append(reinterpret_cast<char *>(&Ptr), 485221345Sdim reinterpret_cast<char *>(&Ptr) + sizeof(void *), 486221345Sdim Buffer, BufferSize, BufferCapacity); 487221345Sdim } 488221345Sdim} 489221345Sdim 490221345SdimNestedNameSpecifierLocBuilder:: 491221345SdimNestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other) 492276479Sdim : Representation(Other.Representation), Buffer(nullptr), 493221345Sdim BufferSize(0), BufferCapacity(0) 494221345Sdim{ 495221345Sdim if (!Other.Buffer) 496221345Sdim return; 497221345Sdim 498221345Sdim if (Other.BufferCapacity == 0) { 499221345Sdim // Shallow copy is okay. 500221345Sdim Buffer = Other.Buffer; 501221345Sdim BufferSize = Other.BufferSize; 502221345Sdim return; 503221345Sdim } 504221345Sdim 505221345Sdim // Deep copy 506276479Sdim Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize, 507276479Sdim BufferCapacity); 508221345Sdim} 509221345Sdim 510221345SdimNestedNameSpecifierLocBuilder & 511221345SdimNestedNameSpecifierLocBuilder:: 512221345Sdimoperator=(const NestedNameSpecifierLocBuilder &Other) { 513221345Sdim Representation = Other.Representation; 514221345Sdim 515221345Sdim if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) { 516221345Sdim // Re-use our storage. 517221345Sdim BufferSize = Other.BufferSize; 518221345Sdim memcpy(Buffer, Other.Buffer, BufferSize); 519221345Sdim return *this; 520221345Sdim } 521221345Sdim 522221345Sdim // Free our storage, if we have any. 523221345Sdim if (BufferCapacity) { 524221345Sdim free(Buffer); 525221345Sdim BufferCapacity = 0; 526221345Sdim } 527221345Sdim 528221345Sdim if (!Other.Buffer) { 529221345Sdim // Empty. 530276479Sdim Buffer = nullptr; 531221345Sdim BufferSize = 0; 532221345Sdim return *this; 533221345Sdim } 534221345Sdim 535221345Sdim if (Other.BufferCapacity == 0) { 536221345Sdim // Shallow copy is okay. 537221345Sdim Buffer = Other.Buffer; 538221345Sdim BufferSize = Other.BufferSize; 539221345Sdim return *this; 540221345Sdim } 541221345Sdim 542221345Sdim // Deep copy. 543276479Sdim Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize, 544276479Sdim BufferCapacity); 545221345Sdim return *this; 546221345Sdim} 547221345Sdim 548221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 549221345Sdim SourceLocation TemplateKWLoc, 550221345Sdim TypeLoc TL, 551221345Sdim SourceLocation ColonColonLoc) { 552221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, 553221345Sdim TemplateKWLoc.isValid(), 554221345Sdim TL.getTypePtr()); 555221345Sdim 556221345Sdim // Push source-location info into the buffer. 557221345Sdim SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity); 558221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 559221345Sdim} 560221345Sdim 561221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 562221345Sdim IdentifierInfo *Identifier, 563221345Sdim SourceLocation IdentifierLoc, 564221345Sdim SourceLocation ColonColonLoc) { 565221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, 566221345Sdim Identifier); 567221345Sdim 568221345Sdim // Push source-location info into the buffer. 569221345Sdim SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity); 570221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 571221345Sdim} 572221345Sdim 573221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 574221345Sdim NamespaceDecl *Namespace, 575221345Sdim SourceLocation NamespaceLoc, 576221345Sdim SourceLocation ColonColonLoc) { 577221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, 578221345Sdim Namespace); 579221345Sdim 580221345Sdim // Push source-location info into the buffer. 581221345Sdim SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity); 582221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 583221345Sdim} 584221345Sdim 585221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 586221345Sdim NamespaceAliasDecl *Alias, 587221345Sdim SourceLocation AliasLoc, 588221345Sdim SourceLocation ColonColonLoc) { 589221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, Alias); 590221345Sdim 591221345Sdim // Push source-location info into the buffer. 592221345Sdim SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity); 593221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 594221345Sdim} 595221345Sdim 596221345Sdimvoid NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context, 597221345Sdim SourceLocation ColonColonLoc) { 598221345Sdim assert(!Representation && "Already have a nested-name-specifier!?"); 599221345Sdim Representation = NestedNameSpecifier::GlobalSpecifier(Context); 600221345Sdim 601221345Sdim // Push source-location info into the buffer. 602221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 603221345Sdim} 604221345Sdim 605280031Sdimvoid NestedNameSpecifierLocBuilder::MakeSuper(ASTContext &Context, 606280031Sdim CXXRecordDecl *RD, 607280031Sdim SourceLocation SuperLoc, 608280031Sdim SourceLocation ColonColonLoc) { 609280031Sdim Representation = NestedNameSpecifier::SuperSpecifier(Context, RD); 610280031Sdim 611280031Sdim // Push source-location info into the buffer. 612280031Sdim SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity); 613280031Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 614280031Sdim} 615280031Sdim 616221345Sdimvoid NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context, 617221345Sdim NestedNameSpecifier *Qualifier, 618221345Sdim SourceRange R) { 619221345Sdim Representation = Qualifier; 620221345Sdim 621221345Sdim // Construct bogus (but well-formed) source information for the 622221345Sdim // nested-name-specifier. 623221345Sdim BufferSize = 0; 624226633Sdim SmallVector<NestedNameSpecifier *, 4> Stack; 625221345Sdim for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix()) 626221345Sdim Stack.push_back(NNS); 627221345Sdim while (!Stack.empty()) { 628261991Sdim NestedNameSpecifier *NNS = Stack.pop_back_val(); 629221345Sdim switch (NNS->getKind()) { 630221345Sdim case NestedNameSpecifier::Identifier: 631221345Sdim case NestedNameSpecifier::Namespace: 632221345Sdim case NestedNameSpecifier::NamespaceAlias: 633221345Sdim SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity); 634221345Sdim break; 635221345Sdim 636221345Sdim case NestedNameSpecifier::TypeSpec: 637221345Sdim case NestedNameSpecifier::TypeSpecWithTemplate: { 638221345Sdim TypeSourceInfo *TSInfo 639221345Sdim = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0), 640221345Sdim R.getBegin()); 641221345Sdim SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize, 642221345Sdim BufferCapacity); 643221345Sdim break; 644221345Sdim } 645221345Sdim 646221345Sdim case NestedNameSpecifier::Global: 647280031Sdim case NestedNameSpecifier::Super: 648221345Sdim break; 649221345Sdim } 650221345Sdim 651221345Sdim // Save the location of the '::'. 652221345Sdim SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(), 653221345Sdim Buffer, BufferSize, BufferCapacity); 654221345Sdim } 655221345Sdim} 656221345Sdim 657221345Sdimvoid NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) { 658221345Sdim if (BufferCapacity) 659221345Sdim free(Buffer); 660221345Sdim 661221345Sdim if (!Other) { 662276479Sdim Representation = nullptr; 663221345Sdim BufferSize = 0; 664221345Sdim return; 665221345Sdim } 666221345Sdim 667221345Sdim // Rather than copying the data (which is wasteful), "adopt" the 668221345Sdim // pointer (which points into the ASTContext) but set the capacity to zero to 669221345Sdim // indicate that we don't own it. 670221345Sdim Representation = Other.getNestedNameSpecifier(); 671221345Sdim Buffer = static_cast<char *>(Other.getOpaqueData()); 672221345Sdim BufferSize = Other.getDataLength(); 673221345Sdim BufferCapacity = 0; 674221345Sdim} 675221345Sdim 676221345SdimNestedNameSpecifierLoc 677221345SdimNestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const { 678221345Sdim if (!Representation) 679221345Sdim return NestedNameSpecifierLoc(); 680221345Sdim 681221345Sdim // If we adopted our data pointer from elsewhere in the AST context, there's 682221345Sdim // no need to copy the memory. 683221345Sdim if (BufferCapacity == 0) 684221345Sdim return NestedNameSpecifierLoc(Representation, Buffer); 685221345Sdim 686221345Sdim // FIXME: After copying the source-location information, should we free 687221345Sdim // our (temporary) buffer and adopt the ASTContext-allocated memory? 688221345Sdim // Doing so would optimize repeated calls to getWithLocInContext(). 689314564Sdim void *Mem = Context.Allocate(BufferSize, alignof(void *)); 690221345Sdim memcpy(Mem, Buffer, BufferSize); 691221345Sdim return NestedNameSpecifierLoc(Representation, Mem); 692221345Sdim} 693