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