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