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" 21245431Sdim#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 33193326Sed void *InsertPos = 0; 34198092Srdivacky NestedNameSpecifier *NNS 35193326Sed = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos); 36193326Sed if (!NNS) { 37245431Sdim NNS = new (Context, llvm::alignOf<NestedNameSpecifier>()) 38245431Sdim 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, 60252723Sdim NestedNameSpecifier *Prefix, 61252723Sdim const NamespaceDecl *NS) { 62193326Sed assert(NS && "Namespace cannot be NULL"); 63198092Srdivacky assert((!Prefix || 64193326Sed (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) && 65193326Sed "Broken nested name specifier"); 66193326Sed NestedNameSpecifier Mockup; 67193326Sed Mockup.Prefix.setPointer(Prefix); 68219077Sdim Mockup.Prefix.setInt(StoredNamespaceOrAlias); 69252723Sdim Mockup.Specifier = const_cast<NamespaceDecl *>(NS); 70193326Sed return FindOrInsert(Context, Mockup); 71193326Sed} 72193326Sed 73193326SedNestedNameSpecifier * 74218893SdimNestedNameSpecifier::Create(const ASTContext &Context, 75219077Sdim NestedNameSpecifier *Prefix, 76219077Sdim NamespaceAliasDecl *Alias) { 77219077Sdim assert(Alias && "Namespace alias cannot be NULL"); 78219077Sdim assert((!Prefix || 79219077Sdim (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) && 80219077Sdim "Broken nested name specifier"); 81219077Sdim NestedNameSpecifier Mockup; 82219077Sdim Mockup.Prefix.setPointer(Prefix); 83219077Sdim Mockup.Prefix.setInt(StoredNamespaceOrAlias); 84219077Sdim Mockup.Specifier = Alias; 85219077Sdim return FindOrInsert(Context, Mockup); 86219077Sdim} 87219077Sdim 88219077SdimNestedNameSpecifier * 89219077SdimNestedNameSpecifier::Create(const ASTContext &Context, 90218893Sdim NestedNameSpecifier *Prefix, 91218893Sdim bool Template, const Type *T) { 92193326Sed assert(T && "Type cannot be NULL"); 93193326Sed NestedNameSpecifier Mockup; 94193326Sed Mockup.Prefix.setPointer(Prefix); 95219077Sdim Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec); 96218893Sdim Mockup.Specifier = const_cast<Type*>(T); 97193326Sed return FindOrInsert(Context, Mockup); 98193326Sed} 99198092Srdivacky 100198092SrdivackyNestedNameSpecifier * 101218893SdimNestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) { 102198092Srdivacky assert(II && "Identifier cannot be NULL"); 103198092Srdivacky NestedNameSpecifier Mockup; 104198092Srdivacky Mockup.Prefix.setPointer(0); 105219077Sdim Mockup.Prefix.setInt(StoredIdentifier); 106198092Srdivacky Mockup.Specifier = II; 107198092Srdivacky return FindOrInsert(Context, Mockup); 108198092Srdivacky} 109198092Srdivacky 110218893SdimNestedNameSpecifier * 111218893SdimNestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) { 112193326Sed if (!Context.GlobalNestedNameSpecifier) 113245431Sdim Context.GlobalNestedNameSpecifier = 114245431Sdim new (Context, llvm::alignOf<NestedNameSpecifier>()) 115245431Sdim NestedNameSpecifier(); 116193326Sed return Context.GlobalNestedNameSpecifier; 117193326Sed} 118193326Sed 119219077SdimNestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const { 120219077Sdim if (Specifier == 0) 121219077Sdim return Global; 122219077Sdim 123219077Sdim switch (Prefix.getInt()) { 124219077Sdim case StoredIdentifier: 125219077Sdim return Identifier; 126219077Sdim 127219077Sdim case StoredNamespaceOrAlias: 128219077Sdim return isa<NamespaceDecl>(static_cast<NamedDecl *>(Specifier))? Namespace 129219077Sdim : NamespaceAlias; 130219077Sdim 131219077Sdim case StoredTypeSpec: 132219077Sdim return TypeSpec; 133219077Sdim 134219077Sdim case StoredTypeSpecWithTemplate: 135219077Sdim return TypeSpecWithTemplate; 136219077Sdim } 137219077Sdim 138235633Sdim llvm_unreachable("Invalid NNS Kind!"); 139219077Sdim} 140219077Sdim 141219077Sdim/// \brief Retrieve the namespace stored in this nested name 142219077Sdim/// specifier. 143219077SdimNamespaceDecl *NestedNameSpecifier::getAsNamespace() const { 144219077Sdim if (Prefix.getInt() == StoredNamespaceOrAlias) 145219077Sdim return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier)); 146219077Sdim 147219077Sdim return 0; 148219077Sdim} 149219077Sdim 150219077Sdim/// \brief Retrieve the namespace alias stored in this nested name 151219077Sdim/// specifier. 152219077SdimNamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const { 153219077Sdim if (Prefix.getInt() == StoredNamespaceOrAlias) 154219077Sdim return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier)); 155219077Sdim 156219077Sdim return 0; 157219077Sdim} 158219077Sdim 159219077Sdim 160193326Sed/// \brief Whether this nested name specifier refers to a dependent 161193326Sed/// type or not. 162193326Sedbool NestedNameSpecifier::isDependent() const { 163193326Sed switch (getKind()) { 164193326Sed case Identifier: 165193326Sed // Identifier specifiers always represent dependent types 166193326Sed return true; 167193326Sed 168193326Sed case Namespace: 169219077Sdim case NamespaceAlias: 170193326Sed case Global: 171193326Sed return false; 172193326Sed 173193326Sed case TypeSpec: 174193326Sed case TypeSpecWithTemplate: 175193326Sed return getAsType()->isDependentType(); 176193326Sed } 177193326Sed 178235633Sdim llvm_unreachable("Invalid NNS Kind!"); 179193326Sed} 180193326Sed 181224145Sdim/// \brief Whether this nested name specifier refers to a dependent 182224145Sdim/// type or not. 183224145Sdimbool NestedNameSpecifier::isInstantiationDependent() const { 184224145Sdim switch (getKind()) { 185224145Sdim case Identifier: 186224145Sdim // Identifier specifiers always represent dependent types 187224145Sdim return true; 188224145Sdim 189224145Sdim case Namespace: 190224145Sdim case NamespaceAlias: 191224145Sdim case Global: 192224145Sdim return false; 193224145Sdim 194224145Sdim case TypeSpec: 195224145Sdim case TypeSpecWithTemplate: 196224145Sdim return getAsType()->isInstantiationDependentType(); 197224145Sdim } 198235633Sdim 199235633Sdim llvm_unreachable("Invalid NNS Kind!"); 200224145Sdim} 201224145Sdim 202218893Sdimbool NestedNameSpecifier::containsUnexpandedParameterPack() const { 203218893Sdim switch (getKind()) { 204218893Sdim case Identifier: 205218893Sdim return getPrefix() && getPrefix()->containsUnexpandedParameterPack(); 206218893Sdim 207218893Sdim case Namespace: 208219077Sdim case NamespaceAlias: 209218893Sdim case Global: 210218893Sdim return false; 211218893Sdim 212218893Sdim case TypeSpec: 213218893Sdim case TypeSpecWithTemplate: 214218893Sdim return getAsType()->containsUnexpandedParameterPack(); 215218893Sdim } 216218893Sdim 217235633Sdim llvm_unreachable("Invalid NNS Kind!"); 218218893Sdim} 219218893Sdim 220193326Sed/// \brief Print this nested name specifier to the given output 221193326Sed/// stream. 222198092Srdivackyvoid 223226890SdimNestedNameSpecifier::print(raw_ostream &OS, 224193326Sed const PrintingPolicy &Policy) const { 225193326Sed if (getPrefix()) 226193326Sed getPrefix()->print(OS, Policy); 227193326Sed 228193326Sed switch (getKind()) { 229193326Sed case Identifier: 230193326Sed OS << getAsIdentifier()->getName(); 231193326Sed break; 232193326Sed 233193326Sed case Namespace: 234235633Sdim if (getAsNamespace()->isAnonymousNamespace()) 235235633Sdim return; 236235633Sdim 237219077Sdim OS << getAsNamespace()->getName(); 238193326Sed break; 239193326Sed 240219077Sdim case NamespaceAlias: 241219077Sdim OS << getAsNamespaceAlias()->getName(); 242219077Sdim break; 243219077Sdim 244193326Sed case Global: 245193326Sed break; 246193326Sed 247193326Sed case TypeSpecWithTemplate: 248193326Sed OS << "template "; 249193326Sed // Fall through to print the type. 250193326Sed 251193326Sed case TypeSpec: { 252218893Sdim const Type *T = getAsType(); 253193326Sed 254193326Sed PrintingPolicy InnerPolicy(Policy); 255198092Srdivacky InnerPolicy.SuppressScope = true; 256198092Srdivacky 257198092Srdivacky // Nested-name-specifiers are intended to contain minimally-qualified 258208600Srdivacky // types. An actual ElaboratedType will not occur, since we'll store 259198092Srdivacky // just the type that is referred to in the nested-name-specifier (e.g., 260198092Srdivacky // a TypedefType, TagType, etc.). However, when we are dealing with 261198092Srdivacky // dependent template-id types (e.g., Outer<T>::template Inner<U>), 262198092Srdivacky // the type requires its own nested-name-specifier for uniqueness, so we 263198092Srdivacky // suppress that nested-name-specifier during printing. 264208600Srdivacky assert(!isa<ElaboratedType>(T) && 265208600Srdivacky "Elaborated type in nested-name-specifier"); 266198092Srdivacky if (const TemplateSpecializationType *SpecType 267198092Srdivacky = dyn_cast<TemplateSpecializationType>(T)) { 268198092Srdivacky // Print the template name without its corresponding 269198092Srdivacky // nested-name-specifier. 270198092Srdivacky SpecType->getTemplateName().print(OS, InnerPolicy, true); 271198092Srdivacky 272198092Srdivacky // Print the template argument list. 273252723Sdim TemplateSpecializationType::PrintTemplateArgumentList( 274252723Sdim OS, SpecType->getArgs(), SpecType->getNumArgs(), InnerPolicy); 275198092Srdivacky } else { 276198092Srdivacky // Print the type normally 277252723Sdim QualType(T, 0).print(OS, InnerPolicy); 278198092Srdivacky } 279193326Sed break; 280193326Sed } 281193326Sed } 282193326Sed 283193326Sed OS << "::"; 284193326Sed} 285193326Sed 286195341Sedvoid NestedNameSpecifier::dump(const LangOptions &LO) { 287195341Sed print(llvm::errs(), PrintingPolicy(LO)); 288193326Sed} 289219077Sdim 290219077Sdimunsigned 291219077SdimNestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) { 292219077Sdim assert(Qualifier && "Expected a non-NULL qualifier"); 293219077Sdim 294219077Sdim // Location of the trailing '::'. 295219077Sdim unsigned Length = sizeof(unsigned); 296219077Sdim 297219077Sdim switch (Qualifier->getKind()) { 298219077Sdim case NestedNameSpecifier::Global: 299219077Sdim // Nothing more to add. 300219077Sdim break; 301219077Sdim 302219077Sdim case NestedNameSpecifier::Identifier: 303219077Sdim case NestedNameSpecifier::Namespace: 304219077Sdim case NestedNameSpecifier::NamespaceAlias: 305219077Sdim // The location of the identifier or namespace name. 306219077Sdim Length += sizeof(unsigned); 307219077Sdim break; 308219077Sdim 309219077Sdim case NestedNameSpecifier::TypeSpecWithTemplate: 310219077Sdim case NestedNameSpecifier::TypeSpec: 311219077Sdim // The "void*" that points at the TypeLoc data. 312219077Sdim // Note: the 'template' keyword is part of the TypeLoc. 313219077Sdim Length += sizeof(void *); 314219077Sdim break; 315219077Sdim } 316219077Sdim 317219077Sdim return Length; 318219077Sdim} 319219077Sdim 320219077Sdimunsigned 321219077SdimNestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) { 322219077Sdim unsigned Length = 0; 323219077Sdim for (; Qualifier; Qualifier = Qualifier->getPrefix()) 324219077Sdim Length += getLocalDataLength(Qualifier); 325219077Sdim return Length; 326219077Sdim} 327219077Sdim 328219077Sdimnamespace { 329219077Sdim /// \brief Load a (possibly unaligned) source location from a given address 330219077Sdim /// and offset. 331219077Sdim SourceLocation LoadSourceLocation(void *Data, unsigned Offset) { 332219077Sdim unsigned Raw; 333219077Sdim memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned)); 334219077Sdim return SourceLocation::getFromRawEncoding(Raw); 335219077Sdim } 336219077Sdim 337219077Sdim /// \brief Load a (possibly unaligned) pointer from a given address and 338219077Sdim /// offset. 339219077Sdim void *LoadPointer(void *Data, unsigned Offset) { 340219077Sdim void *Result; 341219077Sdim memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*)); 342219077Sdim return Result; 343219077Sdim } 344219077Sdim} 345219077Sdim 346219077SdimSourceRange NestedNameSpecifierLoc::getSourceRange() const { 347219077Sdim if (!Qualifier) 348219077Sdim return SourceRange(); 349219077Sdim 350219077Sdim NestedNameSpecifierLoc First = *this; 351219077Sdim while (NestedNameSpecifierLoc Prefix = First.getPrefix()) 352219077Sdim First = Prefix; 353219077Sdim 354219077Sdim return SourceRange(First.getLocalSourceRange().getBegin(), 355219077Sdim getLocalSourceRange().getEnd()); 356219077Sdim} 357219077Sdim 358219077SdimSourceRange NestedNameSpecifierLoc::getLocalSourceRange() const { 359219077Sdim if (!Qualifier) 360219077Sdim return SourceRange(); 361219077Sdim 362219077Sdim unsigned Offset = getDataLength(Qualifier->getPrefix()); 363219077Sdim switch (Qualifier->getKind()) { 364219077Sdim case NestedNameSpecifier::Global: 365219077Sdim return LoadSourceLocation(Data, Offset); 366219077Sdim 367219077Sdim case NestedNameSpecifier::Identifier: 368219077Sdim case NestedNameSpecifier::Namespace: 369219077Sdim case NestedNameSpecifier::NamespaceAlias: 370219077Sdim return SourceRange(LoadSourceLocation(Data, Offset), 371219077Sdim LoadSourceLocation(Data, Offset + sizeof(unsigned))); 372219077Sdim 373219077Sdim case NestedNameSpecifier::TypeSpecWithTemplate: 374219077Sdim case NestedNameSpecifier::TypeSpec: { 375219077Sdim // The "void*" that points at the TypeLoc data. 376219077Sdim // Note: the 'template' keyword is part of the TypeLoc. 377219077Sdim void *TypeData = LoadPointer(Data, Offset); 378219077Sdim TypeLoc TL(Qualifier->getAsType(), TypeData); 379219077Sdim return SourceRange(TL.getBeginLoc(), 380219077Sdim LoadSourceLocation(Data, Offset + sizeof(void*))); 381219077Sdim } 382219077Sdim } 383235633Sdim 384235633Sdim llvm_unreachable("Invalid NNS Kind!"); 385219077Sdim} 386219077Sdim 387219077SdimTypeLoc NestedNameSpecifierLoc::getTypeLoc() const { 388219077Sdim assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec || 389219077Sdim Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) && 390219077Sdim "Nested-name-specifier location is not a type"); 391219077Sdim 392219077Sdim // The "void*" that points at the TypeLoc data. 393219077Sdim unsigned Offset = getDataLength(Qualifier->getPrefix()); 394219077Sdim void *TypeData = LoadPointer(Data, Offset); 395219077Sdim return TypeLoc(Qualifier->getAsType(), TypeData); 396219077Sdim} 397221345Sdim 398221345Sdimnamespace { 399221345Sdim void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize, 400221345Sdim unsigned &BufferCapacity) { 401221345Sdim if (BufferSize + (End - Start) > BufferCapacity) { 402221345Sdim // Reallocate the buffer. 403221345Sdim unsigned NewCapacity 404221345Sdim = std::max((unsigned)(BufferCapacity? BufferCapacity * 2 405221345Sdim : sizeof(void*) * 2), 406221345Sdim (unsigned)(BufferSize + (End - Start))); 407221345Sdim char *NewBuffer = static_cast<char *>(malloc(NewCapacity)); 408221345Sdim memcpy(NewBuffer, Buffer, BufferSize); 409221345Sdim 410221345Sdim if (BufferCapacity) 411221345Sdim free(Buffer); 412221345Sdim Buffer = NewBuffer; 413221345Sdim BufferCapacity = NewCapacity; 414221345Sdim } 415221345Sdim 416221345Sdim memcpy(Buffer + BufferSize, Start, End - Start); 417221345Sdim BufferSize += End-Start; 418221345Sdim } 419221345Sdim 420221345Sdim /// \brief Save a source location to the given buffer. 421221345Sdim void SaveSourceLocation(SourceLocation Loc, char *&Buffer, 422221345Sdim unsigned &BufferSize, unsigned &BufferCapacity) { 423221345Sdim unsigned Raw = Loc.getRawEncoding(); 424221345Sdim Append(reinterpret_cast<char *>(&Raw), 425221345Sdim reinterpret_cast<char *>(&Raw) + sizeof(unsigned), 426221345Sdim Buffer, BufferSize, BufferCapacity); 427221345Sdim } 428221345Sdim 429221345Sdim /// \brief Save a pointer to the given buffer. 430221345Sdim void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize, 431221345Sdim unsigned &BufferCapacity) { 432221345Sdim Append(reinterpret_cast<char *>(&Ptr), 433221345Sdim reinterpret_cast<char *>(&Ptr) + sizeof(void *), 434221345Sdim Buffer, BufferSize, BufferCapacity); 435221345Sdim } 436221345Sdim} 437221345Sdim 438221345SdimNestedNameSpecifierLocBuilder:: 439221345SdimNestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other) 440221345Sdim : Representation(Other.Representation), Buffer(0), 441221345Sdim BufferSize(0), BufferCapacity(0) 442221345Sdim{ 443221345Sdim if (!Other.Buffer) 444221345Sdim return; 445221345Sdim 446221345Sdim if (Other.BufferCapacity == 0) { 447221345Sdim // Shallow copy is okay. 448221345Sdim Buffer = Other.Buffer; 449221345Sdim BufferSize = Other.BufferSize; 450221345Sdim return; 451221345Sdim } 452221345Sdim 453221345Sdim // Deep copy 454221345Sdim BufferSize = Other.BufferSize; 455221345Sdim BufferCapacity = Other.BufferSize; 456221345Sdim Buffer = static_cast<char *>(malloc(BufferCapacity)); 457221345Sdim memcpy(Buffer, Other.Buffer, BufferSize); 458221345Sdim} 459221345Sdim 460221345SdimNestedNameSpecifierLocBuilder & 461221345SdimNestedNameSpecifierLocBuilder:: 462221345Sdimoperator=(const NestedNameSpecifierLocBuilder &Other) { 463221345Sdim Representation = Other.Representation; 464221345Sdim 465221345Sdim if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) { 466221345Sdim // Re-use our storage. 467221345Sdim BufferSize = Other.BufferSize; 468221345Sdim memcpy(Buffer, Other.Buffer, BufferSize); 469221345Sdim return *this; 470221345Sdim } 471221345Sdim 472221345Sdim // Free our storage, if we have any. 473221345Sdim if (BufferCapacity) { 474221345Sdim free(Buffer); 475221345Sdim BufferCapacity = 0; 476221345Sdim } 477221345Sdim 478221345Sdim if (!Other.Buffer) { 479221345Sdim // Empty. 480221345Sdim Buffer = 0; 481221345Sdim BufferSize = 0; 482221345Sdim return *this; 483221345Sdim } 484221345Sdim 485221345Sdim if (Other.BufferCapacity == 0) { 486221345Sdim // Shallow copy is okay. 487221345Sdim Buffer = Other.Buffer; 488221345Sdim BufferSize = Other.BufferSize; 489221345Sdim return *this; 490221345Sdim } 491221345Sdim 492221345Sdim // Deep copy. 493221345Sdim BufferSize = Other.BufferSize; 494221345Sdim BufferCapacity = BufferSize; 495221345Sdim Buffer = static_cast<char *>(malloc(BufferSize)); 496221345Sdim memcpy(Buffer, Other.Buffer, BufferSize); 497221345Sdim return *this; 498221345Sdim} 499221345Sdim 500221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 501221345Sdim SourceLocation TemplateKWLoc, 502221345Sdim TypeLoc TL, 503221345Sdim SourceLocation ColonColonLoc) { 504221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, 505221345Sdim TemplateKWLoc.isValid(), 506221345Sdim TL.getTypePtr()); 507221345Sdim 508221345Sdim // Push source-location info into the buffer. 509221345Sdim SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity); 510221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 511221345Sdim} 512221345Sdim 513221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 514221345Sdim IdentifierInfo *Identifier, 515221345Sdim SourceLocation IdentifierLoc, 516221345Sdim SourceLocation ColonColonLoc) { 517221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, 518221345Sdim Identifier); 519221345Sdim 520221345Sdim // Push source-location info into the buffer. 521221345Sdim SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity); 522221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 523221345Sdim} 524221345Sdim 525221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 526221345Sdim NamespaceDecl *Namespace, 527221345Sdim SourceLocation NamespaceLoc, 528221345Sdim SourceLocation ColonColonLoc) { 529221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, 530221345Sdim Namespace); 531221345Sdim 532221345Sdim // Push source-location info into the buffer. 533221345Sdim SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity); 534221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 535221345Sdim} 536221345Sdim 537221345Sdimvoid NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 538221345Sdim NamespaceAliasDecl *Alias, 539221345Sdim SourceLocation AliasLoc, 540221345Sdim SourceLocation ColonColonLoc) { 541221345Sdim Representation = NestedNameSpecifier::Create(Context, Representation, Alias); 542221345Sdim 543221345Sdim // Push source-location info into the buffer. 544221345Sdim SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity); 545221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 546221345Sdim} 547221345Sdim 548221345Sdimvoid NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context, 549221345Sdim SourceLocation ColonColonLoc) { 550221345Sdim assert(!Representation && "Already have a nested-name-specifier!?"); 551221345Sdim Representation = NestedNameSpecifier::GlobalSpecifier(Context); 552221345Sdim 553221345Sdim // Push source-location info into the buffer. 554221345Sdim SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity); 555221345Sdim} 556221345Sdim 557221345Sdimvoid NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context, 558221345Sdim NestedNameSpecifier *Qualifier, 559221345Sdim SourceRange R) { 560221345Sdim Representation = Qualifier; 561221345Sdim 562221345Sdim // Construct bogus (but well-formed) source information for the 563221345Sdim // nested-name-specifier. 564221345Sdim BufferSize = 0; 565226890Sdim SmallVector<NestedNameSpecifier *, 4> Stack; 566221345Sdim for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix()) 567221345Sdim Stack.push_back(NNS); 568221345Sdim while (!Stack.empty()) { 569263509Sdim NestedNameSpecifier *NNS = Stack.pop_back_val(); 570221345Sdim switch (NNS->getKind()) { 571221345Sdim case NestedNameSpecifier::Identifier: 572221345Sdim case NestedNameSpecifier::Namespace: 573221345Sdim case NestedNameSpecifier::NamespaceAlias: 574221345Sdim SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity); 575221345Sdim break; 576221345Sdim 577221345Sdim case NestedNameSpecifier::TypeSpec: 578221345Sdim case NestedNameSpecifier::TypeSpecWithTemplate: { 579221345Sdim TypeSourceInfo *TSInfo 580221345Sdim = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0), 581221345Sdim R.getBegin()); 582221345Sdim SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize, 583221345Sdim BufferCapacity); 584221345Sdim break; 585221345Sdim } 586221345Sdim 587221345Sdim case NestedNameSpecifier::Global: 588221345Sdim break; 589221345Sdim } 590221345Sdim 591221345Sdim // Save the location of the '::'. 592221345Sdim SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(), 593221345Sdim Buffer, BufferSize, BufferCapacity); 594221345Sdim } 595221345Sdim} 596221345Sdim 597221345Sdimvoid NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) { 598221345Sdim if (BufferCapacity) 599221345Sdim free(Buffer); 600221345Sdim 601221345Sdim if (!Other) { 602221345Sdim Representation = 0; 603221345Sdim BufferSize = 0; 604221345Sdim return; 605221345Sdim } 606221345Sdim 607221345Sdim // Rather than copying the data (which is wasteful), "adopt" the 608221345Sdim // pointer (which points into the ASTContext) but set the capacity to zero to 609221345Sdim // indicate that we don't own it. 610221345Sdim Representation = Other.getNestedNameSpecifier(); 611221345Sdim Buffer = static_cast<char *>(Other.getOpaqueData()); 612221345Sdim BufferSize = Other.getDataLength(); 613221345Sdim BufferCapacity = 0; 614221345Sdim} 615221345Sdim 616221345SdimNestedNameSpecifierLoc 617221345SdimNestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const { 618221345Sdim if (!Representation) 619221345Sdim return NestedNameSpecifierLoc(); 620221345Sdim 621221345Sdim // If we adopted our data pointer from elsewhere in the AST context, there's 622221345Sdim // no need to copy the memory. 623221345Sdim if (BufferCapacity == 0) 624221345Sdim return NestedNameSpecifierLoc(Representation, Buffer); 625221345Sdim 626221345Sdim // FIXME: After copying the source-location information, should we free 627221345Sdim // our (temporary) buffer and adopt the ASTContext-allocated memory? 628221345Sdim // Doing so would optimize repeated calls to getWithLocInContext(). 629221345Sdim void *Mem = Context.Allocate(BufferSize, llvm::alignOf<void *>()); 630221345Sdim memcpy(Mem, Buffer, BufferSize); 631221345Sdim return NestedNameSpecifierLoc(Representation, Mem); 632221345Sdim} 633