Home | History | Annotate | Download | only in AST
      1 //===--- NestedNameSpecifier.cpp - C++ nested name specifiers -----*- C++ -*-=//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file defines the NestedNameSpecifier class, which represents
     11 //  a C++ nested-name-specifier.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 #include "clang/AST/NestedNameSpecifier.h"
     15 #include "clang/AST/ASTContext.h"
     16 #include "clang/AST/Decl.h"
     17 #include "clang/AST/DeclCXX.h"
     18 #include "clang/AST/PrettyPrinter.h"
     19 #include "clang/AST/Type.h"
     20 #include "clang/AST/TypeLoc.h"
     21 #include "llvm/Support/AlignOf.h"
     22 #include "llvm/Support/raw_ostream.h"
     23 #include <cassert>
     24 
     25 using namespace clang;
     26 
     27 NestedNameSpecifier *
     28 NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
     29                                   const NestedNameSpecifier &Mockup) {
     30   llvm::FoldingSetNodeID ID;
     31   Mockup.Profile(ID);
     32 
     33   void *InsertPos = nullptr;
     34   NestedNameSpecifier *NNS
     35     = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
     36   if (!NNS) {
     37     NNS = new (Context, llvm::alignOf<NestedNameSpecifier>())
     38         NestedNameSpecifier(Mockup);
     39     Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
     40   }
     41 
     42   return NNS;
     43 }
     44 
     45 NestedNameSpecifier *
     46 NestedNameSpecifier::Create(const ASTContext &Context,
     47                             NestedNameSpecifier *Prefix, IdentifierInfo *II) {
     48   assert(II && "Identifier cannot be NULL");
     49   assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
     50 
     51   NestedNameSpecifier Mockup;
     52   Mockup.Prefix.setPointer(Prefix);
     53   Mockup.Prefix.setInt(StoredIdentifier);
     54   Mockup.Specifier = II;
     55   return FindOrInsert(Context, Mockup);
     56 }
     57 
     58 NestedNameSpecifier *
     59 NestedNameSpecifier::Create(const ASTContext &Context,
     60                             NestedNameSpecifier *Prefix,
     61                             const NamespaceDecl *NS) {
     62   assert(NS && "Namespace cannot be NULL");
     63   assert((!Prefix ||
     64           (Prefix->getAsType() == nullptr &&
     65            Prefix->getAsIdentifier() == nullptr)) &&
     66          "Broken nested name specifier");
     67   NestedNameSpecifier Mockup;
     68   Mockup.Prefix.setPointer(Prefix);
     69   Mockup.Prefix.setInt(StoredDecl);
     70   Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
     71   return FindOrInsert(Context, Mockup);
     72 }
     73 
     74 NestedNameSpecifier *
     75 NestedNameSpecifier::Create(const ASTContext &Context,
     76                             NestedNameSpecifier *Prefix,
     77                             NamespaceAliasDecl *Alias) {
     78   assert(Alias && "Namespace alias cannot be NULL");
     79   assert((!Prefix ||
     80           (Prefix->getAsType() == nullptr &&
     81            Prefix->getAsIdentifier() == nullptr)) &&
     82          "Broken nested name specifier");
     83   NestedNameSpecifier Mockup;
     84   Mockup.Prefix.setPointer(Prefix);
     85   Mockup.Prefix.setInt(StoredDecl);
     86   Mockup.Specifier = Alias;
     87   return FindOrInsert(Context, Mockup);
     88 }
     89 
     90 NestedNameSpecifier *
     91 NestedNameSpecifier::Create(const ASTContext &Context,
     92                             NestedNameSpecifier *Prefix,
     93                             bool Template, const Type *T) {
     94   assert(T && "Type cannot be NULL");
     95   NestedNameSpecifier Mockup;
     96   Mockup.Prefix.setPointer(Prefix);
     97   Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
     98   Mockup.Specifier = const_cast<Type*>(T);
     99   return FindOrInsert(Context, Mockup);
    100 }
    101 
    102 NestedNameSpecifier *
    103 NestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) {
    104   assert(II && "Identifier cannot be NULL");
    105   NestedNameSpecifier Mockup;
    106   Mockup.Prefix.setPointer(nullptr);
    107   Mockup.Prefix.setInt(StoredIdentifier);
    108   Mockup.Specifier = II;
    109   return FindOrInsert(Context, Mockup);
    110 }
    111 
    112 NestedNameSpecifier *
    113 NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
    114   if (!Context.GlobalNestedNameSpecifier)
    115     Context.GlobalNestedNameSpecifier =
    116         new (Context, llvm::alignOf<NestedNameSpecifier>())
    117             NestedNameSpecifier();
    118   return Context.GlobalNestedNameSpecifier;
    119 }
    120 
    121 NestedNameSpecifier *
    122 NestedNameSpecifier::SuperSpecifier(const ASTContext &Context,
    123                                     CXXRecordDecl *RD) {
    124   NestedNameSpecifier Mockup;
    125   Mockup.Prefix.setPointer(nullptr);
    126   Mockup.Prefix.setInt(StoredDecl);
    127   Mockup.Specifier = RD;
    128   return FindOrInsert(Context, Mockup);
    129 }
    130 
    131 NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
    132   if (!Specifier)
    133     return Global;
    134 
    135   switch (Prefix.getInt()) {
    136   case StoredIdentifier:
    137     return Identifier;
    138 
    139   case StoredDecl: {
    140     NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
    141     if (isa<CXXRecordDecl>(ND))
    142       return Super;
    143     return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
    144   }
    145 
    146   case StoredTypeSpec:
    147     return TypeSpec;
    148 
    149   case StoredTypeSpecWithTemplate:
    150     return TypeSpecWithTemplate;
    151   }
    152 
    153   llvm_unreachable("Invalid NNS Kind!");
    154 }
    155 
    156 /// \brief Retrieve the namespace stored in this nested name specifier.
    157 NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
    158 	if (Prefix.getInt() == StoredDecl)
    159     return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
    160 
    161   return nullptr;
    162 }
    163 
    164 /// \brief Retrieve the namespace alias stored in this nested name specifier.
    165 NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
    166 	if (Prefix.getInt() == StoredDecl)
    167     return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
    168 
    169   return nullptr;
    170 }
    171 
    172 /// \brief Retrieve the record declaration stored in this nested name specifier.
    173 CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const {
    174   if (Prefix.getInt() == StoredDecl)
    175     return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
    176 
    177   return nullptr;
    178 }
    179 
    180 /// \brief Whether this nested name specifier refers to a dependent
    181 /// type or not.
    182 bool NestedNameSpecifier::isDependent() const {
    183   switch (getKind()) {
    184   case Identifier:
    185     // Identifier specifiers always represent dependent types
    186     return true;
    187 
    188   case Namespace:
    189   case NamespaceAlias:
    190   case Global:
    191     return false;
    192 
    193   case Super: {
    194     CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
    195     for (const auto &Base : RD->bases())
    196       if (Base.getType()->isDependentType())
    197         return true;
    198 
    199     return false;
    200   }
    201 
    202   case TypeSpec:
    203   case TypeSpecWithTemplate:
    204     return getAsType()->isDependentType();
    205   }
    206 
    207   llvm_unreachable("Invalid NNS Kind!");
    208 }
    209 
    210 /// \brief Whether this nested name specifier refers to a dependent
    211 /// type or not.
    212 bool NestedNameSpecifier::isInstantiationDependent() const {
    213   switch (getKind()) {
    214   case Identifier:
    215     // Identifier specifiers always represent dependent types
    216     return true;
    217 
    218   case Namespace:
    219   case NamespaceAlias:
    220   case Global:
    221   case Super:
    222     return false;
    223 
    224   case TypeSpec:
    225   case TypeSpecWithTemplate:
    226     return getAsType()->isInstantiationDependentType();
    227   }
    228 
    229   llvm_unreachable("Invalid NNS Kind!");
    230 }
    231 
    232 bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
    233   switch (getKind()) {
    234   case Identifier:
    235     return getPrefix() && getPrefix()->containsUnexpandedParameterPack();
    236 
    237   case Namespace:
    238   case NamespaceAlias:
    239   case Global:
    240   case Super:
    241     return false;
    242 
    243   case TypeSpec:
    244   case TypeSpecWithTemplate:
    245     return getAsType()->containsUnexpandedParameterPack();
    246   }
    247 
    248   llvm_unreachable("Invalid NNS Kind!");
    249 }
    250 
    251 /// \brief Print this nested name specifier to the given output
    252 /// stream.
    253 void
    254 NestedNameSpecifier::print(raw_ostream &OS,
    255                            const PrintingPolicy &Policy) const {
    256   if (getPrefix())
    257     getPrefix()->print(OS, Policy);
    258 
    259   switch (getKind()) {
    260   case Identifier:
    261     OS << getAsIdentifier()->getName();
    262     break;
    263 
    264   case Namespace:
    265     if (getAsNamespace()->isAnonymousNamespace())
    266       return;
    267 
    268     OS << getAsNamespace()->getName();
    269     break;
    270 
    271   case NamespaceAlias:
    272     OS << getAsNamespaceAlias()->getName();
    273     break;
    274 
    275   case Global:
    276     break;
    277 
    278   case Super:
    279     OS << "__super";
    280     break;
    281 
    282   case TypeSpecWithTemplate:
    283     OS << "template ";
    284     // Fall through to print the type.
    285 
    286   case TypeSpec: {
    287     const Type *T = getAsType();
    288 
    289     PrintingPolicy InnerPolicy(Policy);
    290     InnerPolicy.SuppressScope = true;
    291 
    292     // Nested-name-specifiers are intended to contain minimally-qualified
    293     // types. An actual ElaboratedType will not occur, since we'll store
    294     // just the type that is referred to in the nested-name-specifier (e.g.,
    295     // a TypedefType, TagType, etc.). However, when we are dealing with
    296     // dependent template-id types (e.g., Outer<T>::template Inner<U>),
    297     // the type requires its own nested-name-specifier for uniqueness, so we
    298     // suppress that nested-name-specifier during printing.
    299     assert(!isa<ElaboratedType>(T) &&
    300            "Elaborated type in nested-name-specifier");
    301     if (const TemplateSpecializationType *SpecType
    302           = dyn_cast<TemplateSpecializationType>(T)) {
    303       // Print the template name without its corresponding
    304       // nested-name-specifier.
    305       SpecType->getTemplateName().print(OS, InnerPolicy, true);
    306 
    307       // Print the template argument list.
    308       TemplateSpecializationType::PrintTemplateArgumentList(
    309           OS, SpecType->getArgs(), SpecType->getNumArgs(), InnerPolicy);
    310     } else {
    311       // Print the type normally
    312       QualType(T, 0).print(OS, InnerPolicy);
    313     }
    314     break;
    315   }
    316   }
    317 
    318   OS << "::";
    319 }
    320 
    321 void NestedNameSpecifier::dump(const LangOptions &LO) {
    322   print(llvm::errs(), PrintingPolicy(LO));
    323 }
    324 
    325 unsigned
    326 NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
    327   assert(Qualifier && "Expected a non-NULL qualifier");
    328 
    329   // Location of the trailing '::'.
    330   unsigned Length = sizeof(unsigned);
    331 
    332   switch (Qualifier->getKind()) {
    333   case NestedNameSpecifier::Global:
    334     // Nothing more to add.
    335     break;
    336 
    337   case NestedNameSpecifier::Identifier:
    338   case NestedNameSpecifier::Namespace:
    339   case NestedNameSpecifier::NamespaceAlias:
    340   case NestedNameSpecifier::Super:
    341     // The location of the identifier or namespace name.
    342     Length += sizeof(unsigned);
    343     break;
    344 
    345   case NestedNameSpecifier::TypeSpecWithTemplate:
    346   case NestedNameSpecifier::TypeSpec:
    347     // The "void*" that points at the TypeLoc data.
    348     // Note: the 'template' keyword is part of the TypeLoc.
    349     Length += sizeof(void *);
    350     break;
    351   }
    352 
    353   return Length;
    354 }
    355 
    356 unsigned
    357 NestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) {
    358   unsigned Length = 0;
    359   for (; Qualifier; Qualifier = Qualifier->getPrefix())
    360     Length += getLocalDataLength(Qualifier);
    361   return Length;
    362 }
    363 
    364 namespace {
    365   /// \brief Load a (possibly unaligned) source location from a given address
    366   /// and offset.
    367   SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
    368     unsigned Raw;
    369     memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned));
    370     return SourceLocation::getFromRawEncoding(Raw);
    371   }
    372 
    373   /// \brief Load a (possibly unaligned) pointer from a given address and
    374   /// offset.
    375   void *LoadPointer(void *Data, unsigned Offset) {
    376     void *Result;
    377     memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
    378     return Result;
    379   }
    380 }
    381 
    382 SourceRange NestedNameSpecifierLoc::getSourceRange() const {
    383   if (!Qualifier)
    384     return SourceRange();
    385 
    386   NestedNameSpecifierLoc First = *this;
    387   while (NestedNameSpecifierLoc Prefix = First.getPrefix())
    388     First = Prefix;
    389 
    390   return SourceRange(First.getLocalSourceRange().getBegin(),
    391                      getLocalSourceRange().getEnd());
    392 }
    393 
    394 SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
    395   if (!Qualifier)
    396     return SourceRange();
    397 
    398   unsigned Offset = getDataLength(Qualifier->getPrefix());
    399   switch (Qualifier->getKind()) {
    400   case NestedNameSpecifier::Global:
    401     return LoadSourceLocation(Data, Offset);
    402 
    403   case NestedNameSpecifier::Identifier:
    404   case NestedNameSpecifier::Namespace:
    405   case NestedNameSpecifier::NamespaceAlias:
    406   case NestedNameSpecifier::Super:
    407     return SourceRange(LoadSourceLocation(Data, Offset),
    408                        LoadSourceLocation(Data, Offset + sizeof(unsigned)));
    409 
    410   case NestedNameSpecifier::TypeSpecWithTemplate:
    411   case NestedNameSpecifier::TypeSpec: {
    412     // The "void*" that points at the TypeLoc data.
    413     // Note: the 'template' keyword is part of the TypeLoc.
    414     void *TypeData = LoadPointer(Data, Offset);
    415     TypeLoc TL(Qualifier->getAsType(), TypeData);
    416     return SourceRange(TL.getBeginLoc(),
    417                        LoadSourceLocation(Data, Offset + sizeof(void*)));
    418   }
    419   }
    420 
    421   llvm_unreachable("Invalid NNS Kind!");
    422 }
    423 
    424 TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
    425   assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec ||
    426           Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) &&
    427          "Nested-name-specifier location is not a type");
    428 
    429   // The "void*" that points at the TypeLoc data.
    430   unsigned Offset = getDataLength(Qualifier->getPrefix());
    431   void *TypeData = LoadPointer(Data, Offset);
    432   return TypeLoc(Qualifier->getAsType(), TypeData);
    433 }
    434 
    435 namespace {
    436   void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
    437               unsigned &BufferCapacity) {
    438     if (Start == End)
    439       return;
    440 
    441     if (BufferSize + (End - Start) > BufferCapacity) {
    442       // Reallocate the buffer.
    443       unsigned NewCapacity = std::max(
    444           (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
    445           (unsigned)(BufferSize + (End - Start)));
    446       char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
    447       if (BufferCapacity) {
    448         memcpy(NewBuffer, Buffer, BufferSize);
    449         free(Buffer);
    450       }
    451       Buffer = NewBuffer;
    452       BufferCapacity = NewCapacity;
    453     }
    454 
    455     memcpy(Buffer + BufferSize, Start, End - Start);
    456     BufferSize += End-Start;
    457   }
    458 
    459   /// \brief Save a source location to the given buffer.
    460   void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
    461                           unsigned &BufferSize, unsigned &BufferCapacity) {
    462     unsigned Raw = Loc.getRawEncoding();
    463     Append(reinterpret_cast<char *>(&Raw),
    464            reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
    465            Buffer, BufferSize, BufferCapacity);
    466   }
    467 
    468   /// \brief Save a pointer to the given buffer.
    469   void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
    470                    unsigned &BufferCapacity) {
    471     Append(reinterpret_cast<char *>(&Ptr),
    472            reinterpret_cast<char *>(&Ptr) + sizeof(void *),
    473            Buffer, BufferSize, BufferCapacity);
    474   }
    475 }
    476 
    477 NestedNameSpecifierLocBuilder::
    478 NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other)
    479   : Representation(Other.Representation), Buffer(nullptr),
    480     BufferSize(0), BufferCapacity(0)
    481 {
    482   if (!Other.Buffer)
    483     return;
    484 
    485   if (Other.BufferCapacity == 0) {
    486     // Shallow copy is okay.
    487     Buffer = Other.Buffer;
    488     BufferSize = Other.BufferSize;
    489     return;
    490   }
    491 
    492   // Deep copy
    493   Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
    494          BufferCapacity);
    495 }
    496 
    497 NestedNameSpecifierLocBuilder &
    498 NestedNameSpecifierLocBuilder::
    499 operator=(const NestedNameSpecifierLocBuilder &Other) {
    500   Representation = Other.Representation;
    501 
    502   if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
    503     // Re-use our storage.
    504     BufferSize = Other.BufferSize;
    505     memcpy(Buffer, Other.Buffer, BufferSize);
    506     return *this;
    507   }
    508 
    509   // Free our storage, if we have any.
    510   if (BufferCapacity) {
    511     free(Buffer);
    512     BufferCapacity = 0;
    513   }
    514 
    515   if (!Other.Buffer) {
    516     // Empty.
    517     Buffer = nullptr;
    518     BufferSize = 0;
    519     return *this;
    520   }
    521 
    522   if (Other.BufferCapacity == 0) {
    523     // Shallow copy is okay.
    524     Buffer = Other.Buffer;
    525     BufferSize = Other.BufferSize;
    526     return *this;
    527   }
    528 
    529   // Deep copy.
    530   Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
    531          BufferCapacity);
    532   return *this;
    533 }
    534 
    535 void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
    536                                            SourceLocation TemplateKWLoc,
    537                                            TypeLoc TL,
    538                                            SourceLocation ColonColonLoc) {
    539   Representation = NestedNameSpecifier::Create(Context, Representation,
    540                                                TemplateKWLoc.isValid(),
    541                                                TL.getTypePtr());
    542 
    543   // Push source-location info into the buffer.
    544   SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
    545   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
    546 }
    547 
    548 void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
    549                                            IdentifierInfo *Identifier,
    550                                            SourceLocation IdentifierLoc,
    551                                            SourceLocation ColonColonLoc) {
    552   Representation = NestedNameSpecifier::Create(Context, Representation,
    553                                                Identifier);
    554 
    555   // Push source-location info into the buffer.
    556   SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
    557   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
    558 }
    559 
    560 void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
    561                                            NamespaceDecl *Namespace,
    562                                            SourceLocation NamespaceLoc,
    563                                            SourceLocation ColonColonLoc) {
    564   Representation = NestedNameSpecifier::Create(Context, Representation,
    565                                                Namespace);
    566 
    567   // Push source-location info into the buffer.
    568   SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
    569   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
    570 }
    571 
    572 void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
    573                                            NamespaceAliasDecl *Alias,
    574                                            SourceLocation AliasLoc,
    575                                            SourceLocation ColonColonLoc) {
    576   Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
    577 
    578   // Push source-location info into the buffer.
    579   SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
    580   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
    581 }
    582 
    583 void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context,
    584                                                SourceLocation ColonColonLoc) {
    585   assert(!Representation && "Already have a nested-name-specifier!?");
    586   Representation = NestedNameSpecifier::GlobalSpecifier(Context);
    587 
    588   // Push source-location info into the buffer.
    589   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
    590 }
    591 
    592 void NestedNameSpecifierLocBuilder::MakeSuper(ASTContext &Context,
    593                                               CXXRecordDecl *RD,
    594                                               SourceLocation SuperLoc,
    595                                               SourceLocation ColonColonLoc) {
    596   Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
    597 
    598   // Push source-location info into the buffer.
    599   SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
    600   SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
    601 }
    602 
    603 void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
    604                                                 NestedNameSpecifier *Qualifier,
    605                                                 SourceRange R) {
    606   Representation = Qualifier;
    607 
    608   // Construct bogus (but well-formed) source information for the
    609   // nested-name-specifier.
    610   BufferSize = 0;
    611   SmallVector<NestedNameSpecifier *, 4> Stack;
    612   for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
    613     Stack.push_back(NNS);
    614   while (!Stack.empty()) {
    615     NestedNameSpecifier *NNS = Stack.pop_back_val();
    616     switch (NNS->getKind()) {
    617       case NestedNameSpecifier::Identifier:
    618       case NestedNameSpecifier::Namespace:
    619       case NestedNameSpecifier::NamespaceAlias:
    620         SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
    621         break;
    622 
    623       case NestedNameSpecifier::TypeSpec:
    624       case NestedNameSpecifier::TypeSpecWithTemplate: {
    625         TypeSourceInfo *TSInfo
    626         = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
    627                                            R.getBegin());
    628         SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
    629                     BufferCapacity);
    630         break;
    631       }
    632 
    633       case NestedNameSpecifier::Global:
    634       case NestedNameSpecifier::Super:
    635         break;
    636     }
    637 
    638     // Save the location of the '::'.
    639     SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
    640                        Buffer, BufferSize, BufferCapacity);
    641   }
    642 }
    643 
    644 void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) {
    645   if (BufferCapacity)
    646     free(Buffer);
    647 
    648   if (!Other) {
    649     Representation = nullptr;
    650     BufferSize = 0;
    651     return;
    652   }
    653 
    654   // Rather than copying the data (which is wasteful), "adopt" the
    655   // pointer (which points into the ASTContext) but set the capacity to zero to
    656   // indicate that we don't own it.
    657   Representation = Other.getNestedNameSpecifier();
    658   Buffer = static_cast<char *>(Other.getOpaqueData());
    659   BufferSize = Other.getDataLength();
    660   BufferCapacity = 0;
    661 }
    662 
    663 NestedNameSpecifierLoc
    664 NestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const {
    665   if (!Representation)
    666     return NestedNameSpecifierLoc();
    667 
    668   // If we adopted our data pointer from elsewhere in the AST context, there's
    669   // no need to copy the memory.
    670   if (BufferCapacity == 0)
    671     return NestedNameSpecifierLoc(Representation, Buffer);
    672 
    673   // FIXME: After copying the source-location information, should we free
    674   // our (temporary) buffer and adopt the ASTContext-allocated memory?
    675   // Doing so would optimize repeated calls to getWithLocInContext().
    676   void *Mem = Context.Allocate(BufferSize, llvm::alignOf<void *>());
    677   memcpy(Mem, Buffer, BufferSize);
    678   return NestedNameSpecifierLoc(Representation, Mem);
    679 }
    680