clang API Documentation
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