NestedNameSpecifier.cpp revision 327952
1327952Sdim//===- NestedNameSpecifier.cpp - C++ nested name specifiers ---------------===// 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//===----------------------------------------------------------------------===// 14327952Sdim 15193326Sed#include "clang/AST/NestedNameSpecifier.h" 16193326Sed#include "clang/AST/ASTContext.h" 17193326Sed#include "clang/AST/Decl.h" 18219077Sdim#include "clang/AST/DeclCXX.h" 19193326Sed#include "clang/AST/PrettyPrinter.h" 20327952Sdim#include "clang/AST/TemplateName.h" 21193326Sed#include "clang/AST/Type.h" 22219077Sdim#include "clang/AST/TypeLoc.h" 23327952Sdim#include "clang/Basic/LLVM.h" 24327952Sdim#include "clang/Basic/LangOptions.h" 25327952Sdim#include "clang/Basic/SourceLocation.h" 26327952Sdim#include "llvm/ADT/FoldingSet.h" 27327952Sdim#include "llvm/ADT/SmallVector.h" 28327952Sdim#include "llvm/Support/Casting.h" 29327952Sdim#include "llvm/Support/Compiler.h" 30327952Sdim#include "llvm/Support/ErrorHandling.h" 31193326Sed#include "llvm/Support/raw_ostream.h" 32327952Sdim#include <algorithm> 33193326Sed#include <cassert> 34327952Sdim#include <cstdlib> 35327952Sdim#include <cstring> 36193326Sed 37193326Sedusing namespace clang; 38193326Sed 39193326SedNestedNameSpecifier * 40218893SdimNestedNameSpecifier::FindOrInsert(const ASTContext &Context, 41193326Sed const NestedNameSpecifier &Mockup) { 42193326Sed llvm::FoldingSetNodeID ID; 43193326Sed Mockup.Profile(ID); 44193326Sed 45276479Sdim void *InsertPos = nullptr; 46198092Srdivacky NestedNameSpecifier *NNS 47193326Sed = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos); 48193326Sed if (!NNS) { 49314564Sdim NNS = 50314564Sdim new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(Mockup); 51193326Sed Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos); 52193326Sed } 53193326Sed 54193326Sed return NNS; 55193326Sed} 56193326Sed 57193326SedNestedNameSpecifier * 58218893SdimNestedNameSpecifier::Create(const ASTContext &Context, 59218893Sdim NestedNameSpecifier *Prefix, IdentifierInfo *II) { 60193326Sed assert(II && "Identifier cannot be NULL"); 61198092Srdivacky assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent"); 62193326Sed 63193326Sed NestedNameSpecifier Mockup; 64193326Sed Mockup.Prefix.setPointer(Prefix); 65219077Sdim Mockup.Prefix.setInt(StoredIdentifier); 66193326Sed Mockup.Specifier = II; 67193326Sed return FindOrInsert(Context, Mockup); 68193326Sed} 69193326Sed 70193326SedNestedNameSpecifier * 71218893SdimNestedNameSpecifier::Create(const ASTContext &Context, 72249423Sdim NestedNameSpecifier *Prefix, 73249423Sdim const NamespaceDecl *NS) { 74193326Sed assert(NS && "Namespace cannot be NULL"); 75198092Srdivacky assert((!Prefix || 76276479Sdim (Prefix->getAsType() == nullptr && 77276479Sdim Prefix->getAsIdentifier() == nullptr)) && 78193326Sed "Broken nested name specifier"); 79193326Sed NestedNameSpecifier Mockup; 80193326Sed Mockup.Prefix.setPointer(Prefix); 81280031Sdim Mockup.Prefix.setInt(StoredDecl); 82249423Sdim Mockup.Specifier = const_cast<NamespaceDecl *>(NS); 83193326Sed return FindOrInsert(Context, Mockup); 84193326Sed} 85193326Sed 86193326SedNestedNameSpecifier * 87218893SdimNestedNameSpecifier::Create(const ASTContext &Context, 88219077Sdim NestedNameSpecifier *Prefix, 89219077Sdim NamespaceAliasDecl *Alias) { 90219077Sdim assert(Alias && "Namespace alias cannot be NULL"); 91219077Sdim assert((!Prefix || 92276479Sdim (Prefix->getAsType() == nullptr && 93276479Sdim Prefix->getAsIdentifier() == nullptr)) && 94219077Sdim "Broken nested name specifier"); 95219077Sdim NestedNameSpecifier Mockup; 96219077Sdim Mockup.Prefix.setPointer(Prefix); 97280031Sdim Mockup.Prefix.setInt(StoredDecl); 98219077Sdim Mockup.Specifier = Alias; 99219077Sdim return FindOrInsert(Context, Mockup); 100219077Sdim} 101219077Sdim 102219077SdimNestedNameSpecifier * 103219077SdimNestedNameSpecifier::Create(const ASTContext &Context, 104218893Sdim NestedNameSpecifier *Prefix, 105218893Sdim bool Template, const Type *T) { 106193326Sed assert(T && "Type cannot be NULL"); 107193326Sed NestedNameSpecifier Mockup; 108193326Sed Mockup.Prefix.setPointer(Prefix); 109219077Sdim Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec); 110218893Sdim Mockup.Specifier = const_cast<Type*>(T); 111193326Sed return FindOrInsert(Context, Mockup); 112193326Sed} 113198092Srdivacky 114198092SrdivackyNestedNameSpecifier * 115218893SdimNestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) { 116198092Srdivacky assert(II && "Identifier cannot be NULL"); 117198092Srdivacky NestedNameSpecifier Mockup; 118276479Sdim Mockup.Prefix.setPointer(nullptr); 119219077Sdim Mockup.Prefix.setInt(StoredIdentifier); 120198092Srdivacky Mockup.Specifier = II; 121198092Srdivacky return FindOrInsert(Context, Mockup); 122198092Srdivacky} 123198092Srdivacky 124218893SdimNestedNameSpecifier * 125218893SdimNestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) { 126193326Sed if (!Context.GlobalNestedNameSpecifier) 127239462Sdim Context.GlobalNestedNameSpecifier = 128314564Sdim new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(); 129193326Sed return Context.GlobalNestedNameSpecifier; 130193326Sed} 131193326Sed 132280031SdimNestedNameSpecifier * 133280031SdimNestedNameSpecifier::SuperSpecifier(const ASTContext &Context, 134280031Sdim CXXRecordDecl *RD) { 135280031Sdim NestedNameSpecifier Mockup; 136280031Sdim Mockup.Prefix.setPointer(nullptr); 137280031Sdim Mockup.Prefix.setInt(StoredDecl); 138280031Sdim Mockup.Specifier = RD; 139280031Sdim return FindOrInsert(Context, Mockup); 140280031Sdim} 141280031Sdim 142219077SdimNestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const { 143276479Sdim if (!Specifier) 144219077Sdim return Global; 145219077Sdim 146219077Sdim switch (Prefix.getInt()) { 147219077Sdim case StoredIdentifier: 148219077Sdim return Identifier; 149219077Sdim 150280031Sdim case StoredDecl: { 151280031Sdim NamedDecl *ND = static_cast<NamedDecl *>(Specifier); 152280031Sdim if (isa<CXXRecordDecl>(ND)) 153280031Sdim return Super; 154280031Sdim return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias; 155280031Sdim } 156219077Sdim 157219077Sdim case StoredTypeSpec: 158219077Sdim return TypeSpec; 159219077Sdim 160219077Sdim case StoredTypeSpecWithTemplate: 161219077Sdim return TypeSpecWithTemplate; 162219077Sdim } 163219077Sdim 164234353Sdim llvm_unreachable("Invalid NNS Kind!"); 165219077Sdim} 166219077Sdim 167280031Sdim/// \brief Retrieve the namespace stored in this nested name specifier. 168219077SdimNamespaceDecl *NestedNameSpecifier::getAsNamespace() const { 169314564Sdim if (Prefix.getInt() == StoredDecl) 170219077Sdim return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier)); 171219077Sdim 172276479Sdim return nullptr; 173219077Sdim} 174219077Sdim 175280031Sdim/// \brief Retrieve the namespace alias stored in this nested name specifier. 176219077SdimNamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const { 177314564Sdim if (Prefix.getInt() == StoredDecl) 178219077Sdim return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier)); 179219077Sdim 180276479Sdim return nullptr; 181219077Sdim} 182219077Sdim 183280031Sdim/// \brief Retrieve the record declaration stored in this nested name specifier. 184280031SdimCXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const { 185309124Sdim switch (Prefix.getInt()) { 186309124Sdim case StoredIdentifier: 187309124Sdim return nullptr; 188309124Sdim 189309124Sdim case StoredDecl: 190280031Sdim return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier)); 191219077Sdim 192309124Sdim case StoredTypeSpec: 193309124Sdim case StoredTypeSpecWithTemplate: 194309124Sdim return getAsType()->getAsCXXRecordDecl(); 195309124Sdim } 196309124Sdim 197309124Sdim llvm_unreachable("Invalid NNS Kind!"); 198280031Sdim} 199280031Sdim 200193326Sed/// \brief Whether this nested name specifier refers to a dependent 201193326Sed/// type or not. 202193326Sedbool NestedNameSpecifier::isDependent() const { 203193326Sed switch (getKind()) { 204193326Sed case Identifier: 205193326Sed // Identifier specifiers always represent dependent types 206193326Sed return true; 207193326Sed 208193326Sed case Namespace: 209219077Sdim case NamespaceAlias: 210193326Sed case Global: 211193326Sed return false; 212193326Sed 213280031Sdim case Super: { 214280031Sdim CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier); 215280031Sdim for (const auto &Base : RD->bases()) 216280031Sdim if (Base.getType()->isDependentType()) 217280031Sdim return true; 218280031Sdim 219280031Sdim return false; 220280031Sdim } 221280031Sdim 222193326Sed case TypeSpec: 223193326Sed case TypeSpecWithTemplate: 224193326Sed return getAsType()->isDependentType(); 225193326Sed } 226193326Sed 227234353Sdim llvm_unreachable("Invalid NNS Kind!"); 228193326Sed} 229193326Sed 230224145Sdim/// \brief Whether this nested name specifier refers to a dependent 231224145Sdim/// type or not. 232224145Sdimbool NestedNameSpecifier::isInstantiationDependent() const { 233224145Sdim switch (getKind()) { 234224145Sdim case Identifier: 235224145Sdim // Identifier specifiers always represent dependent types 236224145Sdim return true; 237224145Sdim 238224145Sdim case Namespace: 239224145Sdim case NamespaceAlias: 240224145Sdim case Global: 241280031Sdim case Super: 242224145Sdim return false; 243280031Sdim 244224145Sdim case TypeSpec: 245224145Sdim case TypeSpecWithTemplate: 246224145Sdim return getAsType()->isInstantiationDependentType(); 247224145Sdim } 248234353Sdim 249234353Sdim llvm_unreachable("Invalid NNS Kind!"); 250224145Sdim} 251224145Sdim 252218893Sdimbool NestedNameSpecifier::containsUnexpandedParameterPack() const { 253218893Sdim switch (getKind()) { 254218893Sdim case Identifier: 255218893Sdim return getPrefix() && getPrefix()->containsUnexpandedParameterPack(); 256218893Sdim 257218893Sdim case Namespace: 258219077Sdim case NamespaceAlias: 259218893Sdim case Global: 260280031Sdim case Super: 261218893Sdim return false; 262218893Sdim 263218893Sdim case TypeSpec: 264218893Sdim case TypeSpecWithTemplate: 265218893Sdim return getAsType()->containsUnexpandedParameterPack(); 266218893Sdim } 267218893Sdim 268234353Sdim llvm_unreachable("Invalid NNS Kind!"); 269218893Sdim} 270218893Sdim 271193326Sed/// \brief Print this nested name specifier to the given output 272193326Sed/// stream. 273198092Srdivackyvoid 274226633SdimNestedNameSpecifier::print(raw_ostream &OS, 275193326Sed const PrintingPolicy &Policy) const { 276193326Sed if (getPrefix()) 277193326Sed getPrefix()->print(OS, Policy); 278193326Sed 279193326Sed switch (getKind()) { 280193326Sed case Identifier: 281193326Sed OS << getAsIdentifier()->getName(); 282193326Sed break; 283193326Sed 284193326Sed case Namespace: 285234353Sdim if (getAsNamespace()->isAnonymousNamespace()) 286234353Sdim return; 287234353Sdim 288219077Sdim OS << getAsNamespace()->getName(); 289193326Sed break; 290193326Sed 291219077Sdim case NamespaceAlias: 292219077Sdim OS << getAsNamespaceAlias()->getName(); 293219077Sdim break; 294219077Sdim 295193326Sed case Global: 296193326Sed break; 297193326Sed 298280031Sdim case Super: 299280031Sdim OS << "__super"; 300280031Sdim break; 301280031Sdim 302193326Sed case TypeSpecWithTemplate: 303193326Sed OS << "template "; 304193326Sed // Fall through to print the type. 305321369Sdim LLVM_FALLTHROUGH; 306193326Sed 307193326Sed case TypeSpec: { 308218893Sdim const Type *T = getAsType(); 309193326Sed 310193326Sed PrintingPolicy InnerPolicy(Policy); 311198092Srdivacky InnerPolicy.SuppressScope = true; 312198092Srdivacky 313198092Srdivacky // Nested-name-specifiers are intended to contain minimally-qualified 314208600Srdivacky // types. An actual ElaboratedType will not occur, since we'll store 315198092Srdivacky // just the type that is referred to in the nested-name-specifier (e.g., 316198092Srdivacky // a TypedefType, TagType, etc.). However, when we are dealing with 317198092Srdivacky // dependent template-id types (e.g., Outer<T>::template Inner<U>), 318198092Srdivacky // the type requires its own nested-name-specifier for uniqueness, so we 319198092Srdivacky // suppress that nested-name-specifier during printing. 320208600Srdivacky assert(!isa<ElaboratedType>(T) && 321208600Srdivacky "Elaborated type in nested-name-specifier"); 322198092Srdivacky if (const TemplateSpecializationType *SpecType 323198092Srdivacky = dyn_cast<TemplateSpecializationType>(T)) { 324198092Srdivacky // Print the template name without its corresponding 325198092Srdivacky // nested-name-specifier. 326198092Srdivacky SpecType->getTemplateName().print(OS, InnerPolicy, true); 327198092Srdivacky 328198092Srdivacky // Print the template argument list. 329327952Sdim printTemplateArgumentList(OS, SpecType->template_arguments(), 330327952Sdim InnerPolicy); 331198092Srdivacky } else { 332198092Srdivacky // Print the type normally 333249423Sdim QualType(T, 0).print(OS, InnerPolicy); 334198092Srdivacky } 335193326Sed break; 336193326Sed } 337193326Sed } 338193326Sed 339193326Sed OS << "::"; 340193326Sed} 341193326Sed 342296417Sdimvoid NestedNameSpecifier::dump(const LangOptions &LO) const { 343195341Sed print(llvm::errs(), PrintingPolicy(LO)); 344193326Sed} 345219077Sdim 346309124SdimLLVM_DUMP_METHOD void NestedNameSpecifier::dump() const { 347296417Sdim LangOptions LO; 348296417Sdim print(llvm::errs(), PrintingPolicy(LO)); 349296417Sdim} 350296417Sdim 351219077Sdimunsigned 352219077SdimNestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) { 353219077Sdim assert(Qualifier && "Expected a non-NULL qualifier"); 354219077Sdim 355219077Sdim // Location of the trailing '::'. 356219077Sdim unsigned Length = sizeof(unsigned); 357219077Sdim 358219077Sdim switch (Qualifier->getKind()) { 359219077Sdim case NestedNameSpecifier::Global: 360219077Sdim // Nothing more to add. 361219077Sdim break; 362219077Sdim 363219077Sdim case NestedNameSpecifier::Identifier: 364219077Sdim case NestedNameSpecifier::Namespace: 365219077Sdim case NestedNameSpecifier::NamespaceAlias: 366280031Sdim case NestedNameSpecifier::Super: 367219077Sdim // The location of the identifier or namespace name. 368219077Sdim Length += sizeof(unsigned); 369219077Sdim break; 370219077Sdim 371219077Sdim case NestedNameSpecifier::TypeSpecWithTemplate: 372219077Sdim case NestedNameSpecifier::TypeSpec: 373219077Sdim // The "void*" that points at the TypeLoc data. 374219077Sdim // Note: the 'template' keyword is part of the TypeLoc. 375219077Sdim Length += sizeof(void *); 376219077Sdim break; 377219077Sdim } 378219077Sdim 379219077Sdim return Length; 380219077Sdim} 381219077Sdim 382219077Sdimunsigned 383219077SdimNestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) { 384219077Sdim unsigned Length = 0; 385219077Sdim for (; Qualifier; Qualifier = Qualifier->getPrefix()) 386219077Sdim Length += getLocalDataLength(Qualifier); 387219077Sdim return Length; 388219077Sdim} 389219077Sdim 390327952Sdim/// \brief Load a (possibly unaligned) source location from a given address 391327952Sdim/// and offset. 392327952Sdimstatic SourceLocation LoadSourceLocation(void *Data, unsigned Offset) { 393327952Sdim unsigned Raw; 394327952Sdim memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned)); 395327952Sdim return SourceLocation::getFromRawEncoding(Raw); 396327952Sdim} 397219077Sdim 398327952Sdim/// \brief Load a (possibly unaligned) pointer from a given address and 399327952Sdim/// offset. 400327952Sdimstatic void *LoadPointer(void *Data, unsigned Offset) { 401327952Sdim void *Result; 402327952Sdim memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*)); 403327952Sdim return Result; 404219077Sdim} 405219077Sdim 406219077SdimSourceRange NestedNameSpecifierLoc::getSourceRange() const { 407219077Sdim if (!Qualifier) 408219077Sdim return SourceRange(); 409219077Sdim 410219077Sdim NestedNameSpecifierLoc First = *this; 411219077Sdim while (NestedNameSpecifierLoc Prefix = First.getPrefix()) 412219077Sdim First = Prefix; 413219077Sdim 414219077Sdim return SourceRange(First.getLocalSourceRange().getBegin(), 415219077Sdim getLocalSourceRange().getEnd()); 416219077Sdim} 417219077Sdim 418219077SdimSourceRange NestedNameSpecifierLoc::getLocalSourceRange() const { 419219077Sdim if (!Qualifier) 420219077Sdim return SourceRange(); 421219077Sdim 422219077Sdim unsigned Offset = getDataLength(Qualifier->getPrefix()); 423219077Sdim switch (Qualifier->getKind()) { 424219077Sdim case NestedNameSpecifier::Global: 425219077Sdim return LoadSourceLocation(Data, Offset); 426219077Sdim 427219077Sdim case NestedNameSpecifier::Identifier: 428219077Sdim case NestedNameSpecifier::Namespace: 429219077Sdim case NestedNameSpecifier::NamespaceAlias: 430280031Sdim case NestedNameSpecifier::Super: 431219077Sdim return SourceRange(LoadSourceLocation(Data, Offset), 432219077Sdim LoadSourceLocation(Data, Offset + sizeof(unsigned))); 433219077Sdim 434219077Sdim case NestedNameSpecifier::TypeSpecWithTemplate: 435219077Sdim case NestedNameSpecifier::TypeSpec: { 436219077Sdim // The "void*" that points at the TypeLoc data. 437219077Sdim // Note: the 'template' keyword is part of the TypeLoc. 438219077Sdim void *TypeData = LoadPointer(Data, Offset); 439219077Sdim TypeLoc TL(Qualifier->getAsType(), TypeData); 440219077Sdim return SourceRange(TL.getBeginLoc(), 441219077Sdim LoadSourceLocation(Data, Offset + sizeof(void*))); 442219077Sdim } 443219077Sdim } 444234353Sdim 445234353Sdim llvm_unreachable("Invalid NNS Kind!"); 446219077Sdim} 447219077Sdim 448219077SdimTypeLoc NestedNameSpecifierLoc::getTypeLoc() const { 449219077Sdim assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec || 450219077Sdim Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) && 451219077Sdim "Nested-name-specifier location is not a type"); 452219077Sdim 453219077Sdim // The "void*" that points at the TypeLoc data. 454219077Sdim unsigned Offset = getDataLength(Qualifier->getPrefix()); 455219077Sdim void *TypeData = LoadPointer(Data, Offset); 456219077Sdim return TypeLoc(Qualifier->getAsType(), TypeData); 457219077Sdim} 458221345Sdim 459327952Sdimstatic void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize, 460221345Sdim unsigned &BufferCapacity) { 461327952Sdim if (Start == End) 462327952Sdim return; 463288943Sdim 464327952Sdim if (BufferSize + (End - Start) > BufferCapacity) { 465327952Sdim // Reallocate the buffer. 466327952Sdim unsigned NewCapacity = std::max( 467327952Sdim (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2), 468327952Sdim (unsigned)(BufferSize + (End - Start))); 469327952Sdim char *NewBuffer = static_cast<char *>(malloc(NewCapacity)); 470327952Sdim if (BufferCapacity) { 471327952Sdim memcpy(NewBuffer, Buffer, BufferSize); 472327952Sdim free(Buffer); 473221345Sdim } 474327952Sdim Buffer = NewBuffer; 475327952Sdim BufferCapacity = NewCapacity; 476221345Sdim } 477327952Sdim 478327952Sdim memcpy(Buffer + BufferSize, Start, End - Start); 479327952Sdim BufferSize += End-Start; 480327952Sdim} 481221345Sdim 482327952Sdim/// \brief Save a source location to the given buffer. 483327952Sdimstatic void SaveSourceLocation(SourceLocation Loc, char *&Buffer, 484327952Sdim unsigned &BufferSize, unsigned &BufferCapacity) { 485327952Sdim unsigned Raw = Loc.getRawEncoding(); 486327952Sdim Append(reinterpret_cast<char *>(&Raw), 487327952Sdim reinterpret_cast<char *>(&Raw) + sizeof(unsigned), 488327952Sdim Buffer, BufferSize, BufferCapacity); 489327952Sdim} 490221345Sdim 491327952Sdim/// \brief Save a pointer to the given buffer. 492327952Sdimstatic void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize, 493327952Sdim unsigned &BufferCapacity) { 494327952Sdim Append(reinterpret_cast<char *>(&Ptr), 495327952Sdim reinterpret_cast<char *>(&Ptr) + sizeof(void *), 496327952Sdim Buffer, BufferSize, BufferCapacity); 497221345Sdim} 498221345Sdim 499221345SdimNestedNameSpecifierLocBuilder:: 500221345SdimNestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other) 501327952Sdim : Representation(Other.Representation) { 502221345Sdim if (!Other.Buffer) 503221345Sdim return; 504221345Sdim 505221345Sdim if (Other.BufferCapacity == 0) { 506221345Sdim // Shallow copy is okay. 507221345Sdim Buffer = Other.Buffer; 508221345Sdim BufferSize = Other.BufferSize; 509221345Sdim return; 510221345Sdim } 511221345Sdim 512221345Sdim // Deep copy 513276479Sdim Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize, 514276479Sdim BufferCapacity); 515221345Sdim} 516221345Sdim 517221345SdimNestedNameSpecifierLocBuilder & 518221345SdimNestedNameSpecifierLocBuilder:: 519221345Sdimoperator=(const NestedNameSpecifierLocBuilder &Other) { 520221345Sdim Representation = Other.Representation; 521221345Sdim 522221345Sdim if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) { 523221345Sdim // Re-use our storage. 524221345Sdim BufferSize = Other.BufferSize; 525221345Sdim memcpy(Buffer, Other.Buffer, BufferSize); 526221345Sdim return *this; 527221345Sdim } 528221345Sdim 529221345Sdim // Free our storage, if we have any. 530221345Sdim if (BufferCapacity) { 531221345Sdim free(Buffer); 532221345Sdim BufferCapacity = 0; 533221345Sdim } 534221345Sdim 535221345Sdim if (!Other.Buffer) { 536221345Sdim // Empty. 537276479Sdim Buffer = nullptr; 538221345Sdim BufferSize = 0; 539221345Sdim return *this; 540221345Sdim } 541221345Sdim 542221345Sdim if (Other.BufferCapacity == 0) { 543221345Sdim // Shallow copy is okay. 544221345Sdim Buffer = Other.Buffer; 545221345Sdim BufferSize = Other.BufferSize; 546221345Sdim return *this; 547221345Sdim } 548221345Sdim 549221345Sdim // Deep copy. 550276479Sdim Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize, 551276479Sdim BufferCapacity); 552221345Sdim return *this; 553221345Sdim} 554221345Sdim 555221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 556221345Sdim SourceLocation TemplateKWLoc, 557221345Sdim TypeLoc TL, 558221345Sdim SourceLocation ColonColonLoc) { 559221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, 560221345Sdim TemplateKWLoc.isValid(), 561221345Sdim TL.getTypePtr()); 562221345Sdim 563221345Sdim // Push source-location info into the buffer. 564221345Sdim SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity); 565221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 566221345Sdim} 567221345Sdim 568221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 569221345Sdim IdentifierInfo *Identifier, 570221345Sdim SourceLocation IdentifierLoc, 571221345Sdim SourceLocation ColonColonLoc) { 572221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, 573221345Sdim Identifier); 574221345Sdim 575221345Sdim // Push source-location info into the buffer. 576221345Sdim SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity); 577221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 578221345Sdim} 579221345Sdim 580221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 581221345Sdim NamespaceDecl *Namespace, 582221345Sdim SourceLocation NamespaceLoc, 583221345Sdim SourceLocation ColonColonLoc) { 584221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, 585221345Sdim Namespace); 586221345Sdim 587221345Sdim // Push source-location info into the buffer. 588221345Sdim SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity); 589221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 590221345Sdim} 591221345Sdim 592221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 593221345Sdim NamespaceAliasDecl *Alias, 594221345Sdim SourceLocation AliasLoc, 595221345Sdim SourceLocation ColonColonLoc) { 596221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, Alias); 597221345Sdim 598221345Sdim // Push source-location info into the buffer. 599221345Sdim SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity); 600221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 601221345Sdim} 602221345Sdim 603221345Sdimvoid NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context, 604221345Sdim SourceLocation ColonColonLoc) { 605221345Sdim assert(!Representation && "Already have a nested-name-specifier!?"); 606221345Sdim Representation = NestedNameSpecifier::GlobalSpecifier(Context); 607221345Sdim 608221345Sdim // Push source-location info into the buffer. 609221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 610221345Sdim} 611221345Sdim 612280031Sdimvoid NestedNameSpecifierLocBuilder::MakeSuper(ASTContext &Context, 613280031Sdim CXXRecordDecl *RD, 614280031Sdim SourceLocation SuperLoc, 615280031Sdim SourceLocation ColonColonLoc) { 616280031Sdim Representation = NestedNameSpecifier::SuperSpecifier(Context, RD); 617280031Sdim 618280031Sdim // Push source-location info into the buffer. 619280031Sdim SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity); 620280031Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 621280031Sdim} 622280031Sdim 623221345Sdimvoid NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context, 624221345Sdim NestedNameSpecifier *Qualifier, 625221345Sdim SourceRange R) { 626221345Sdim Representation = Qualifier; 627221345Sdim 628221345Sdim // Construct bogus (but well-formed) source information for the 629221345Sdim // nested-name-specifier. 630221345Sdim BufferSize = 0; 631226633Sdim SmallVector<NestedNameSpecifier *, 4> Stack; 632221345Sdim for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix()) 633221345Sdim Stack.push_back(NNS); 634221345Sdim while (!Stack.empty()) { 635261991Sdim NestedNameSpecifier *NNS = Stack.pop_back_val(); 636221345Sdim switch (NNS->getKind()) { 637221345Sdim case NestedNameSpecifier::Identifier: 638221345Sdim case NestedNameSpecifier::Namespace: 639221345Sdim case NestedNameSpecifier::NamespaceAlias: 640221345Sdim SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity); 641221345Sdim break; 642221345Sdim 643221345Sdim case NestedNameSpecifier::TypeSpec: 644221345Sdim case NestedNameSpecifier::TypeSpecWithTemplate: { 645221345Sdim TypeSourceInfo *TSInfo 646221345Sdim = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0), 647221345Sdim R.getBegin()); 648221345Sdim SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize, 649221345Sdim BufferCapacity); 650221345Sdim break; 651221345Sdim } 652221345Sdim 653221345Sdim case NestedNameSpecifier::Global: 654280031Sdim case NestedNameSpecifier::Super: 655221345Sdim break; 656221345Sdim } 657221345Sdim 658221345Sdim // Save the location of the '::'. 659221345Sdim SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(), 660221345Sdim Buffer, BufferSize, BufferCapacity); 661221345Sdim } 662221345Sdim} 663221345Sdim 664221345Sdimvoid NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) { 665221345Sdim if (BufferCapacity) 666221345Sdim free(Buffer); 667221345Sdim 668221345Sdim if (!Other) { 669276479Sdim Representation = nullptr; 670221345Sdim BufferSize = 0; 671221345Sdim return; 672221345Sdim } 673221345Sdim 674221345Sdim // Rather than copying the data (which is wasteful), "adopt" the 675221345Sdim // pointer (which points into the ASTContext) but set the capacity to zero to 676221345Sdim // indicate that we don't own it. 677221345Sdim Representation = Other.getNestedNameSpecifier(); 678221345Sdim Buffer = static_cast<char *>(Other.getOpaqueData()); 679221345Sdim BufferSize = Other.getDataLength(); 680221345Sdim BufferCapacity = 0; 681221345Sdim} 682221345Sdim 683221345SdimNestedNameSpecifierLoc 684221345SdimNestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const { 685221345Sdim if (!Representation) 686221345Sdim return NestedNameSpecifierLoc(); 687221345Sdim 688221345Sdim // If we adopted our data pointer from elsewhere in the AST context, there's 689221345Sdim // no need to copy the memory. 690221345Sdim if (BufferCapacity == 0) 691221345Sdim return NestedNameSpecifierLoc(Representation, Buffer); 692221345Sdim 693221345Sdim // FIXME: After copying the source-location information, should we free 694221345Sdim // our (temporary) buffer and adopt the ASTContext-allocated memory? 695221345Sdim // Doing so would optimize repeated calls to getWithLocInContext(). 696314564Sdim void *Mem = Context.Allocate(BufferSize, alignof(void *)); 697221345Sdim memcpy(Mem, Buffer, BufferSize); 698221345Sdim return NestedNameSpecifierLoc(Representation, Mem); 699221345Sdim} 700