clang API Documentation

NestedNameSpecifier.cpp
Go to the documentation of this file.
00001 //===--- NestedNameSpecifier.cpp - C++ nested name specifiers -----*- C++ -*-=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines the NestedNameSpecifier class, which represents
00011 //  a C++ nested-name-specifier.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 #include "clang/AST/NestedNameSpecifier.h"
00015 #include "clang/AST/ASTContext.h"
00016 #include "clang/AST/Decl.h"
00017 #include "clang/AST/DeclCXX.h"
00018 #include "clang/AST/PrettyPrinter.h"
00019 #include "clang/AST/Type.h"
00020 #include "clang/AST/TypeLoc.h"
00021 #include "llvm/Support/AlignOf.h"
00022 #include "llvm/Support/raw_ostream.h"
00023 #include <cassert>
00024 
00025 using namespace clang;
00026 
00027 NestedNameSpecifier *
00028 NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
00029                                   const NestedNameSpecifier &Mockup) {
00030   llvm::FoldingSetNodeID ID;
00031   Mockup.Profile(ID);
00032 
00033   void *InsertPos = nullptr;
00034   NestedNameSpecifier *NNS
00035     = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
00036   if (!NNS) {
00037     NNS = new (Context, llvm::alignOf<NestedNameSpecifier>())
00038         NestedNameSpecifier(Mockup);
00039     Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
00040   }
00041 
00042   return NNS;
00043 }
00044 
00045 NestedNameSpecifier *
00046 NestedNameSpecifier::Create(const ASTContext &Context,
00047                             NestedNameSpecifier *Prefix, IdentifierInfo *II) {
00048   assert(II && "Identifier cannot be NULL");
00049   assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
00050 
00051   NestedNameSpecifier Mockup;
00052   Mockup.Prefix.setPointer(Prefix);
00053   Mockup.Prefix.setInt(StoredIdentifier);
00054   Mockup.Specifier = II;
00055   return FindOrInsert(Context, Mockup);
00056 }
00057 
00058 NestedNameSpecifier *
00059 NestedNameSpecifier::Create(const ASTContext &Context,
00060                             NestedNameSpecifier *Prefix,
00061                             const NamespaceDecl *NS) {
00062   assert(NS && "Namespace cannot be NULL");
00063   assert((!Prefix ||
00064           (Prefix->getAsType() == nullptr &&
00065            Prefix->getAsIdentifier() == nullptr)) &&
00066          "Broken nested name specifier");
00067   NestedNameSpecifier Mockup;
00068   Mockup.Prefix.setPointer(Prefix);
00069   Mockup.Prefix.setInt(StoredDecl);
00070   Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
00071   return FindOrInsert(Context, Mockup);
00072 }
00073 
00074 NestedNameSpecifier *
00075 NestedNameSpecifier::Create(const ASTContext &Context,
00076                             NestedNameSpecifier *Prefix, 
00077                             NamespaceAliasDecl *Alias) {
00078   assert(Alias && "Namespace alias cannot be NULL");
00079   assert((!Prefix ||
00080           (Prefix->getAsType() == nullptr &&
00081            Prefix->getAsIdentifier() == nullptr)) &&
00082          "Broken nested name specifier");
00083   NestedNameSpecifier Mockup;
00084   Mockup.Prefix.setPointer(Prefix);
00085   Mockup.Prefix.setInt(StoredDecl);
00086   Mockup.Specifier = Alias;
00087   return FindOrInsert(Context, Mockup);
00088 }
00089 
00090 NestedNameSpecifier *
00091 NestedNameSpecifier::Create(const ASTContext &Context,
00092                             NestedNameSpecifier *Prefix,
00093                             bool Template, const Type *T) {
00094   assert(T && "Type cannot be NULL");
00095   NestedNameSpecifier Mockup;
00096   Mockup.Prefix.setPointer(Prefix);
00097   Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
00098   Mockup.Specifier = const_cast<Type*>(T);
00099   return FindOrInsert(Context, Mockup);
00100 }
00101 
00102 NestedNameSpecifier *
00103 NestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) {
00104   assert(II && "Identifier cannot be NULL");
00105   NestedNameSpecifier Mockup;
00106   Mockup.Prefix.setPointer(nullptr);
00107   Mockup.Prefix.setInt(StoredIdentifier);
00108   Mockup.Specifier = II;
00109   return FindOrInsert(Context, Mockup);
00110 }
00111 
00112 NestedNameSpecifier *
00113 NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
00114   if (!Context.GlobalNestedNameSpecifier)
00115     Context.GlobalNestedNameSpecifier =
00116         new (Context, llvm::alignOf<NestedNameSpecifier>())
00117             NestedNameSpecifier();
00118   return Context.GlobalNestedNameSpecifier;
00119 }
00120 
00121 NestedNameSpecifier *
00122 NestedNameSpecifier::SuperSpecifier(const ASTContext &Context,
00123                                     CXXRecordDecl *RD) {
00124   NestedNameSpecifier Mockup;
00125   Mockup.Prefix.setPointer(nullptr);
00126   Mockup.Prefix.setInt(StoredDecl);
00127   Mockup.Specifier = RD;
00128   return FindOrInsert(Context, Mockup);
00129 }
00130 
00131 NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
00132   if (!Specifier)
00133     return Global;
00134 
00135   switch (Prefix.getInt()) {
00136   case StoredIdentifier:
00137     return Identifier;
00138 
00139   case StoredDecl: {
00140     NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
00141     if (isa<CXXRecordDecl>(ND))
00142       return Super;
00143     return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
00144   }
00145 
00146   case StoredTypeSpec:
00147     return TypeSpec;
00148 
00149   case StoredTypeSpecWithTemplate:
00150     return TypeSpecWithTemplate;
00151   }
00152 
00153   llvm_unreachable("Invalid NNS Kind!");
00154 }
00155 
00156 /// \brief Retrieve the namespace stored in this nested name specifier.
00157 NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
00158   if (Prefix.getInt() == StoredDecl)
00159     return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
00160 
00161   return nullptr;
00162 }
00163 
00164 /// \brief Retrieve the namespace alias stored in this nested name specifier.
00165 NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
00166   if (Prefix.getInt() == StoredDecl)
00167     return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
00168 
00169   return nullptr;
00170 }
00171 
00172 /// \brief Retrieve the record declaration stored in this nested name specifier.
00173 CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const {
00174   if (Prefix.getInt() == StoredDecl)
00175     return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
00176 
00177   return nullptr;
00178 }
00179 
00180 /// \brief Whether this nested name specifier refers to a dependent
00181 /// type or not.
00182 bool NestedNameSpecifier::isDependent() const {
00183   switch (getKind()) {
00184   case Identifier:
00185     // Identifier specifiers always represent dependent types
00186     return true;
00187 
00188   case Namespace:
00189   case NamespaceAlias:
00190   case Global:
00191     return false;
00192 
00193   case Super: {
00194     CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
00195     for (const auto &Base : RD->bases())
00196       if (Base.getType()->isDependentType())
00197         return true;
00198 
00199     return false;
00200   }
00201 
00202   case TypeSpec:
00203   case TypeSpecWithTemplate:
00204     return getAsType()->isDependentType();
00205   }
00206 
00207   llvm_unreachable("Invalid NNS Kind!");
00208 }
00209 
00210 /// \brief Whether this nested name specifier refers to a dependent
00211 /// type or not.
00212 bool NestedNameSpecifier::isInstantiationDependent() const {
00213   switch (getKind()) {
00214   case Identifier:
00215     // Identifier specifiers always represent dependent types
00216     return true;
00217     
00218   case Namespace:
00219   case NamespaceAlias:
00220   case Global:
00221   case Super:
00222     return false;
00223 
00224   case TypeSpec:
00225   case TypeSpecWithTemplate:
00226     return getAsType()->isInstantiationDependentType();
00227   }
00228 
00229   llvm_unreachable("Invalid NNS Kind!");
00230 }
00231 
00232 bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
00233   switch (getKind()) {
00234   case Identifier:
00235     return getPrefix() && getPrefix()->containsUnexpandedParameterPack();
00236 
00237   case Namespace:
00238   case NamespaceAlias:
00239   case Global:
00240   case Super:
00241     return false;
00242 
00243   case TypeSpec:
00244   case TypeSpecWithTemplate:
00245     return getAsType()->containsUnexpandedParameterPack();
00246   }
00247 
00248   llvm_unreachable("Invalid NNS Kind!");
00249 }
00250 
00251 /// \brief Print this nested name specifier to the given output
00252 /// stream.
00253 void
00254 NestedNameSpecifier::print(raw_ostream &OS,
00255                            const PrintingPolicy &Policy) const {
00256   if (getPrefix())
00257     getPrefix()->print(OS, Policy);
00258 
00259   switch (getKind()) {
00260   case Identifier:
00261     OS << getAsIdentifier()->getName();
00262     break;
00263 
00264   case Namespace:
00265     if (getAsNamespace()->isAnonymousNamespace())
00266       return;
00267       
00268     OS << getAsNamespace()->getName();
00269     break;
00270 
00271   case NamespaceAlias:
00272     OS << getAsNamespaceAlias()->getName();
00273     break;
00274 
00275   case Global:
00276     break;
00277 
00278   case Super:
00279     OS << "__super";
00280     break;
00281 
00282   case TypeSpecWithTemplate:
00283     OS << "template ";
00284     // Fall through to print the type.
00285 
00286   case TypeSpec: {
00287     const Type *T = getAsType();
00288 
00289     PrintingPolicy InnerPolicy(Policy);
00290     InnerPolicy.SuppressScope = true;
00291 
00292     // Nested-name-specifiers are intended to contain minimally-qualified
00293     // types. An actual ElaboratedType will not occur, since we'll store
00294     // just the type that is referred to in the nested-name-specifier (e.g.,
00295     // a TypedefType, TagType, etc.). However, when we are dealing with
00296     // dependent template-id types (e.g., Outer<T>::template Inner<U>),
00297     // the type requires its own nested-name-specifier for uniqueness, so we
00298     // suppress that nested-name-specifier during printing.
00299     assert(!isa<ElaboratedType>(T) &&
00300            "Elaborated type in nested-name-specifier");
00301     if (const TemplateSpecializationType *SpecType
00302           = dyn_cast<TemplateSpecializationType>(T)) {
00303       // Print the template name without its corresponding
00304       // nested-name-specifier.
00305       SpecType->getTemplateName().print(OS, InnerPolicy, true);
00306 
00307       // Print the template argument list.
00308       TemplateSpecializationType::PrintTemplateArgumentList(
00309           OS, SpecType->getArgs(), SpecType->getNumArgs(), InnerPolicy);
00310     } else {
00311       // Print the type normally
00312       QualType(T, 0).print(OS, InnerPolicy);
00313     }
00314     break;
00315   }
00316   }
00317 
00318   OS << "::";
00319 }
00320 
00321 void NestedNameSpecifier::dump(const LangOptions &LO) {
00322   print(llvm::errs(), PrintingPolicy(LO));
00323 }
00324 
00325 unsigned 
00326 NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
00327   assert(Qualifier && "Expected a non-NULL qualifier");
00328 
00329   // Location of the trailing '::'.
00330   unsigned Length = sizeof(unsigned);
00331 
00332   switch (Qualifier->getKind()) {
00333   case NestedNameSpecifier::Global:
00334     // Nothing more to add.
00335     break;
00336 
00337   case NestedNameSpecifier::Identifier:
00338   case NestedNameSpecifier::Namespace:
00339   case NestedNameSpecifier::NamespaceAlias:
00340   case NestedNameSpecifier::Super:
00341     // The location of the identifier or namespace name.
00342     Length += sizeof(unsigned);
00343     break;
00344 
00345   case NestedNameSpecifier::TypeSpecWithTemplate:
00346   case NestedNameSpecifier::TypeSpec:
00347     // The "void*" that points at the TypeLoc data.
00348     // Note: the 'template' keyword is part of the TypeLoc.
00349     Length += sizeof(void *);
00350     break;
00351   }
00352 
00353   return Length;
00354 }
00355 
00356 unsigned 
00357 NestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) {
00358   unsigned Length = 0;
00359   for (; Qualifier; Qualifier = Qualifier->getPrefix())
00360     Length += getLocalDataLength(Qualifier);
00361   return Length;
00362 }
00363 
00364 namespace {
00365   /// \brief Load a (possibly unaligned) source location from a given address
00366   /// and offset.
00367   SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
00368     unsigned Raw;
00369     memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned));
00370     return SourceLocation::getFromRawEncoding(Raw);
00371   }
00372   
00373   /// \brief Load a (possibly unaligned) pointer from a given address and
00374   /// offset.
00375   void *LoadPointer(void *Data, unsigned Offset) {
00376     void *Result;
00377     memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
00378     return Result;
00379   }
00380 }
00381 
00382 SourceRange NestedNameSpecifierLoc::getSourceRange() const {
00383   if (!Qualifier)
00384     return SourceRange();
00385   
00386   NestedNameSpecifierLoc First = *this;
00387   while (NestedNameSpecifierLoc Prefix = First.getPrefix())
00388     First = Prefix;
00389   
00390   return SourceRange(First.getLocalSourceRange().getBegin(), 
00391                      getLocalSourceRange().getEnd());
00392 }
00393 
00394 SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
00395   if (!Qualifier)
00396     return SourceRange();
00397   
00398   unsigned Offset = getDataLength(Qualifier->getPrefix());
00399   switch (Qualifier->getKind()) {
00400   case NestedNameSpecifier::Global:
00401     return LoadSourceLocation(Data, Offset);
00402 
00403   case NestedNameSpecifier::Identifier:
00404   case NestedNameSpecifier::Namespace:
00405   case NestedNameSpecifier::NamespaceAlias:
00406   case NestedNameSpecifier::Super:
00407     return SourceRange(LoadSourceLocation(Data, Offset),
00408                        LoadSourceLocation(Data, Offset + sizeof(unsigned)));
00409 
00410   case NestedNameSpecifier::TypeSpecWithTemplate:
00411   case NestedNameSpecifier::TypeSpec: {
00412     // The "void*" that points at the TypeLoc data.
00413     // Note: the 'template' keyword is part of the TypeLoc.
00414     void *TypeData = LoadPointer(Data, Offset);
00415     TypeLoc TL(Qualifier->getAsType(), TypeData);
00416     return SourceRange(TL.getBeginLoc(),
00417                        LoadSourceLocation(Data, Offset + sizeof(void*)));
00418   }
00419   }
00420 
00421   llvm_unreachable("Invalid NNS Kind!");
00422 }
00423 
00424 TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
00425   assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec ||
00426           Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) &&
00427          "Nested-name-specifier location is not a type");
00428 
00429   // The "void*" that points at the TypeLoc data.
00430   unsigned Offset = getDataLength(Qualifier->getPrefix());
00431   void *TypeData = LoadPointer(Data, Offset);
00432   return TypeLoc(Qualifier->getAsType(), TypeData);
00433 }
00434 
00435 namespace {
00436   void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
00437               unsigned &BufferCapacity) {
00438     if (BufferSize + (End - Start) > BufferCapacity) {
00439       // Reallocate the buffer.
00440       unsigned NewCapacity 
00441       = std::max((unsigned)(BufferCapacity? BufferCapacity * 2 
00442                             : sizeof(void*) * 2),
00443                  (unsigned)(BufferSize + (End - Start)));
00444       char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
00445       memcpy(NewBuffer, Buffer, BufferSize);
00446       
00447       if (BufferCapacity)
00448         free(Buffer);
00449       Buffer = NewBuffer;
00450       BufferCapacity = NewCapacity;
00451     }
00452     
00453     memcpy(Buffer + BufferSize, Start, End - Start);
00454     BufferSize += End-Start;
00455   }
00456   
00457   /// \brief Save a source location to the given buffer.
00458   void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
00459                           unsigned &BufferSize, unsigned &BufferCapacity) {
00460     unsigned Raw = Loc.getRawEncoding();
00461     Append(reinterpret_cast<char *>(&Raw),
00462            reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
00463            Buffer, BufferSize, BufferCapacity);
00464   }
00465   
00466   /// \brief Save a pointer to the given buffer.
00467   void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
00468                    unsigned &BufferCapacity) {
00469     Append(reinterpret_cast<char *>(&Ptr),
00470            reinterpret_cast<char *>(&Ptr) + sizeof(void *),
00471            Buffer, BufferSize, BufferCapacity);
00472   }
00473 }
00474 
00475 NestedNameSpecifierLocBuilder::
00476 NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other) 
00477   : Representation(Other.Representation), Buffer(nullptr),
00478     BufferSize(0), BufferCapacity(0)
00479 {
00480   if (!Other.Buffer)
00481     return;
00482   
00483   if (Other.BufferCapacity == 0) {
00484     // Shallow copy is okay.
00485     Buffer = Other.Buffer;
00486     BufferSize = Other.BufferSize;
00487     return;
00488   }
00489   
00490   // Deep copy
00491   Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
00492          BufferCapacity);
00493 }
00494 
00495 NestedNameSpecifierLocBuilder &
00496 NestedNameSpecifierLocBuilder::
00497 operator=(const NestedNameSpecifierLocBuilder &Other) {
00498   Representation = Other.Representation;
00499   
00500   if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
00501     // Re-use our storage.
00502     BufferSize = Other.BufferSize;
00503     memcpy(Buffer, Other.Buffer, BufferSize);
00504     return *this;
00505   }
00506   
00507   // Free our storage, if we have any.
00508   if (BufferCapacity) {
00509     free(Buffer);
00510     BufferCapacity = 0;
00511   }
00512   
00513   if (!Other.Buffer) {
00514     // Empty.
00515     Buffer = nullptr;
00516     BufferSize = 0;
00517     return *this;
00518   }
00519   
00520   if (Other.BufferCapacity == 0) {
00521     // Shallow copy is okay.
00522     Buffer = Other.Buffer;
00523     BufferSize = Other.BufferSize;
00524     return *this;
00525   }
00526   
00527   // Deep copy.
00528   Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
00529          BufferCapacity);
00530   return *this;
00531 }
00532 
00533 void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 
00534                                            SourceLocation TemplateKWLoc, 
00535                                            TypeLoc TL, 
00536                                            SourceLocation ColonColonLoc) {
00537   Representation = NestedNameSpecifier::Create(Context, Representation, 
00538                                                TemplateKWLoc.isValid(), 
00539                                                TL.getTypePtr());
00540   
00541   // Push source-location info into the buffer.
00542   SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
00543   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
00544 }
00545 
00546 void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 
00547                                            IdentifierInfo *Identifier,
00548                                            SourceLocation IdentifierLoc, 
00549                                            SourceLocation ColonColonLoc) {
00550   Representation = NestedNameSpecifier::Create(Context, Representation, 
00551                                                Identifier);
00552   
00553   // Push source-location info into the buffer.
00554   SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
00555   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
00556 }
00557 
00558 void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, 
00559                                            NamespaceDecl *Namespace,
00560                                            SourceLocation NamespaceLoc, 
00561                                            SourceLocation ColonColonLoc) {
00562   Representation = NestedNameSpecifier::Create(Context, Representation, 
00563                                                Namespace);
00564   
00565   // Push source-location info into the buffer.
00566   SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
00567   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
00568 }
00569 
00570 void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
00571                                            NamespaceAliasDecl *Alias,
00572                                            SourceLocation AliasLoc, 
00573                                            SourceLocation ColonColonLoc) {
00574   Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
00575   
00576   // Push source-location info into the buffer.
00577   SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
00578   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
00579 }
00580 
00581 void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context, 
00582                                                SourceLocation ColonColonLoc) {
00583   assert(!Representation && "Already have a nested-name-specifier!?");
00584   Representation = NestedNameSpecifier::GlobalSpecifier(Context);
00585   
00586   // Push source-location info into the buffer.
00587   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
00588 }
00589 
00590 void NestedNameSpecifierLocBuilder::MakeSuper(ASTContext &Context,
00591                                               CXXRecordDecl *RD,
00592                                               SourceLocation SuperLoc,
00593                                               SourceLocation ColonColonLoc) {
00594   Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
00595 
00596   // Push source-location info into the buffer.
00597   SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
00598   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
00599 }
00600 
00601 void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context, 
00602                                                 NestedNameSpecifier *Qualifier, 
00603                                                 SourceRange R) {
00604   Representation = Qualifier;
00605   
00606   // Construct bogus (but well-formed) source information for the 
00607   // nested-name-specifier.
00608   BufferSize = 0;
00609   SmallVector<NestedNameSpecifier *, 4> Stack;
00610   for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
00611     Stack.push_back(NNS);
00612   while (!Stack.empty()) {
00613     NestedNameSpecifier *NNS = Stack.pop_back_val();
00614     switch (NNS->getKind()) {
00615       case NestedNameSpecifier::Identifier:
00616       case NestedNameSpecifier::Namespace:
00617       case NestedNameSpecifier::NamespaceAlias:
00618         SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
00619         break;
00620         
00621       case NestedNameSpecifier::TypeSpec:
00622       case NestedNameSpecifier::TypeSpecWithTemplate: {
00623         TypeSourceInfo *TSInfo
00624         = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
00625                                            R.getBegin());
00626         SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize, 
00627                     BufferCapacity);
00628         break;
00629       }
00630         
00631       case NestedNameSpecifier::Global:
00632       case NestedNameSpecifier::Super:
00633         break;
00634     }
00635     
00636     // Save the location of the '::'.
00637     SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(), 
00638                        Buffer, BufferSize, BufferCapacity);
00639   }
00640 }
00641 
00642 void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) {
00643   if (BufferCapacity)
00644     free(Buffer);
00645 
00646   if (!Other) {
00647     Representation = nullptr;
00648     BufferSize = 0;
00649     return;
00650   }
00651   
00652   // Rather than copying the data (which is wasteful), "adopt" the 
00653   // pointer (which points into the ASTContext) but set the capacity to zero to
00654   // indicate that we don't own it.
00655   Representation = Other.getNestedNameSpecifier();
00656   Buffer = static_cast<char *>(Other.getOpaqueData());
00657   BufferSize = Other.getDataLength();
00658   BufferCapacity = 0;
00659 }
00660 
00661 NestedNameSpecifierLoc 
00662 NestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const {
00663   if (!Representation)
00664     return NestedNameSpecifierLoc();
00665   
00666   // If we adopted our data pointer from elsewhere in the AST context, there's
00667   // no need to copy the memory.
00668   if (BufferCapacity == 0)
00669     return NestedNameSpecifierLoc(Representation, Buffer);
00670   
00671   // FIXME: After copying the source-location information, should we free
00672   // our (temporary) buffer and adopt the ASTContext-allocated memory?
00673   // Doing so would optimize repeated calls to getWithLocInContext().
00674   void *Mem = Context.Allocate(BufferSize, llvm::alignOf<void *>());
00675   memcpy(Mem, Buffer, BufferSize);
00676   return NestedNameSpecifierLoc(Representation, Mem);
00677 }