clang 19.0.0git
NestedNameSpecifier.cpp
Go to the documentation of this file.
1//===- NestedNameSpecifier.cpp - C++ nested name specifiers ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the NestedNameSpecifier class, which represents
10// a C++ nested-name-specifier.
11//
12//===----------------------------------------------------------------------===//
13
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclCXX.h"
22#include "clang/AST/Type.h"
23#include "clang/AST/TypeLoc.h"
24#include "clang/Basic/LLVM.h"
27#include "llvm/ADT/FoldingSet.h"
28#include "llvm/ADT/SmallVector.h"
29#include "llvm/Support/Casting.h"
30#include "llvm/Support/Compiler.h"
31#include "llvm/Support/ErrorHandling.h"
32#include "llvm/Support/raw_ostream.h"
33#include <algorithm>
34#include <cassert>
35#include <cstdlib>
36#include <cstring>
37
38using namespace clang;
39
41NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
42 const NestedNameSpecifier &Mockup) {
43 llvm::FoldingSetNodeID ID;
44 Mockup.Profile(ID);
45
46 void *InsertPos = nullptr;
48 = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
49 if (!NNS) {
50 NNS =
51 new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(Mockup);
52 Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
53 }
54
55 return NNS;
56}
57
61 assert(II && "Identifier cannot be NULL");
62 assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
63
65 Mockup.Prefix.setPointer(Prefix);
66 Mockup.Prefix.setInt(StoredIdentifier);
67 Mockup.Specifier = II;
68 return FindOrInsert(Context, Mockup);
69}
70
73 NestedNameSpecifier *Prefix,
74 const NamespaceDecl *NS) {
75 assert(NS && "Namespace cannot be NULL");
76 assert((!Prefix ||
77 (Prefix->getAsType() == nullptr &&
78 Prefix->getAsIdentifier() == nullptr)) &&
79 "Broken nested name specifier");
81 Mockup.Prefix.setPointer(Prefix);
82 Mockup.Prefix.setInt(StoredDecl);
83 Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
84 return FindOrInsert(Context, Mockup);
85}
86
89 NestedNameSpecifier *Prefix,
90 NamespaceAliasDecl *Alias) {
91 assert(Alias && "Namespace alias cannot be NULL");
92 assert((!Prefix ||
93 (Prefix->getAsType() == nullptr &&
94 Prefix->getAsIdentifier() == nullptr)) &&
95 "Broken nested name specifier");
97 Mockup.Prefix.setPointer(Prefix);
98 Mockup.Prefix.setInt(StoredDecl);
99 Mockup.Specifier = Alias;
100 return FindOrInsert(Context, Mockup);
101}
102
105 NestedNameSpecifier *Prefix,
106 bool Template, const Type *T) {
107 assert(T && "Type cannot be NULL");
108 NestedNameSpecifier Mockup;
109 Mockup.Prefix.setPointer(Prefix);
110 Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
111 Mockup.Specifier = const_cast<Type*>(T);
112 return FindOrInsert(Context, Mockup);
113}
114
117 assert(II && "Identifier cannot be NULL");
118 NestedNameSpecifier Mockup;
119 Mockup.Prefix.setPointer(nullptr);
120 Mockup.Prefix.setInt(StoredIdentifier);
121 Mockup.Specifier = II;
122 return FindOrInsert(Context, Mockup);
123}
124
127 if (!Context.GlobalNestedNameSpecifier)
128 Context.GlobalNestedNameSpecifier =
129 new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier();
130 return Context.GlobalNestedNameSpecifier;
131}
132
135 CXXRecordDecl *RD) {
136 NestedNameSpecifier Mockup;
137 Mockup.Prefix.setPointer(nullptr);
138 Mockup.Prefix.setInt(StoredDecl);
139 Mockup.Specifier = RD;
140 return FindOrInsert(Context, Mockup);
141}
142
144 if (!Specifier)
145 return Global;
146
147 switch (Prefix.getInt()) {
148 case StoredIdentifier:
149 return Identifier;
150
151 case StoredDecl: {
152 NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
153 if (isa<CXXRecordDecl>(ND))
154 return Super;
155 return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
156 }
157
158 case StoredTypeSpec:
159 return TypeSpec;
160
161 case StoredTypeSpecWithTemplate:
163 }
164
165 llvm_unreachable("Invalid NNS Kind!");
166}
167
168/// Retrieve the namespace stored in this nested name specifier.
170 if (Prefix.getInt() == StoredDecl)
171 return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
172
173 return nullptr;
174}
175
176/// Retrieve the namespace alias stored in this nested name specifier.
178 if (Prefix.getInt() == StoredDecl)
179 return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
180
181 return nullptr;
182}
183
184/// Retrieve the record declaration stored in this nested name specifier.
186 switch (Prefix.getInt()) {
187 case StoredIdentifier:
188 return nullptr;
189
190 case StoredDecl:
191 return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
192
193 case StoredTypeSpec:
194 case StoredTypeSpecWithTemplate:
195 return getAsType()->getAsCXXRecordDecl();
196 }
197
198 llvm_unreachable("Invalid NNS Kind!");
199}
200
201NestedNameSpecifierDependence NestedNameSpecifier::getDependence() const {
202 switch (getKind()) {
203 case Identifier: {
204 // Identifier specifiers always represent dependent types
205 auto F = NestedNameSpecifierDependence::Dependent |
206 NestedNameSpecifierDependence::Instantiation;
207 // Prefix can contain unexpanded template parameters.
208 if (getPrefix())
209 return F | getPrefix()->getDependence();
210 return F;
211 }
212
213 case Namespace:
214 case NamespaceAlias:
215 case Global:
216 return NestedNameSpecifierDependence::None;
217
218 case Super: {
219 CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
220 for (const auto &Base : RD->bases())
221 if (Base.getType()->isDependentType())
222 // FIXME: must also be instantiation-dependent.
223 return NestedNameSpecifierDependence::Dependent;
224 return NestedNameSpecifierDependence::None;
225 }
226
227 case TypeSpec:
230 }
231 llvm_unreachable("Invalid NNS Kind!");
232}
233
235 return getDependence() & NestedNameSpecifierDependence::Dependent;
236}
237
239 return getDependence() & NestedNameSpecifierDependence::Instantiation;
240}
241
243 return getDependence() & NestedNameSpecifierDependence::UnexpandedPack;
244}
245
247 return getDependence() & NestedNameSpecifierDependence::Error;
248}
249
250/// Print this nested name specifier to the given output
251/// stream.
252void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
253 bool ResolveTemplateArguments) const {
254 if (getPrefix())
255 getPrefix()->print(OS, Policy);
256
257 switch (getKind()) {
258 case Identifier:
259 OS << getAsIdentifier()->getName();
260 break;
261
262 case Namespace:
263 if (getAsNamespace()->isAnonymousNamespace())
264 return;
265
266 OS << getAsNamespace()->getName();
267 break;
268
269 case NamespaceAlias:
270 OS << getAsNamespaceAlias()->getName();
271 break;
272
273 case Global:
274 break;
275
276 case Super:
277 OS << "__super";
278 break;
279
281 OS << "template ";
282 // Fall through to print the type.
283 [[fallthrough]];
284
285 case TypeSpec: {
286 const auto *Record =
287 dyn_cast_or_null<ClassTemplateSpecializationDecl>(getAsRecordDecl());
288 if (ResolveTemplateArguments && Record) {
289 // Print the type trait with resolved template parameters.
290 Record->printName(OS, Policy);
292 OS, Record->getTemplateArgs().asArray(), Policy,
293 Record->getSpecializedTemplate()->getTemplateParameters());
294 break;
295 }
296 const Type *T = getAsType();
297
298 PrintingPolicy InnerPolicy(Policy);
299 InnerPolicy.SuppressScope = true;
300
301 // Nested-name-specifiers are intended to contain minimally-qualified
302 // types. An actual ElaboratedType will not occur, since we'll store
303 // just the type that is referred to in the nested-name-specifier (e.g.,
304 // a TypedefType, TagType, etc.). However, when we are dealing with
305 // dependent template-id types (e.g., Outer<T>::template Inner<U>),
306 // the type requires its own nested-name-specifier for uniqueness, so we
307 // suppress that nested-name-specifier during printing.
308 assert(!isa<ElaboratedType>(T) &&
309 "Elaborated type in nested-name-specifier");
310 if (const TemplateSpecializationType *SpecType
311 = dyn_cast<TemplateSpecializationType>(T)) {
312 // Print the template name without its corresponding
313 // nested-name-specifier.
314 SpecType->getTemplateName().print(OS, InnerPolicy,
316
317 // Print the template argument list.
318 printTemplateArgumentList(OS, SpecType->template_arguments(),
319 InnerPolicy);
320 } else if (const auto *DepSpecType =
321 dyn_cast<DependentTemplateSpecializationType>(T)) {
322 // Print the template name without its corresponding
323 // nested-name-specifier.
324 OS << DepSpecType->getIdentifier()->getName();
325 // Print the template argument list.
326 printTemplateArgumentList(OS, DepSpecType->template_arguments(),
327 InnerPolicy);
328 } else {
329 // Print the type normally
330 QualType(T, 0).print(OS, InnerPolicy);
331 }
332 break;
333 }
334 }
335
336 OS << "::";
337}
338
339LLVM_DUMP_METHOD void NestedNameSpecifier::dump(const LangOptions &LO) const {
340 dump(llvm::errs(), LO);
341}
342
343LLVM_DUMP_METHOD void NestedNameSpecifier::dump() const { dump(llvm::errs()); }
344
345LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS) const {
346 LangOptions LO;
347 dump(OS, LO);
348}
349
350LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS,
351 const LangOptions &LO) const {
352 print(OS, PrintingPolicy(LO));
353}
354
355unsigned
356NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
357 assert(Qualifier && "Expected a non-NULL qualifier");
358
359 // Location of the trailing '::'.
360 unsigned Length = sizeof(SourceLocation::UIntTy);
361
362 switch (Qualifier->getKind()) {
364 // Nothing more to add.
365 break;
366
371 // The location of the identifier or namespace name.
372 Length += sizeof(SourceLocation::UIntTy);
373 break;
374
377 // The "void*" that points at the TypeLoc data.
378 // Note: the 'template' keyword is part of the TypeLoc.
379 Length += sizeof(void *);
380 break;
381 }
382
383 return Length;
384}
385
386unsigned
388 unsigned Length = 0;
389 for (; Qualifier; Qualifier = Qualifier->getPrefix())
390 Length += getLocalDataLength(Qualifier);
391 return Length;
392}
393
394/// Load a (possibly unaligned) source location from a given address
395/// and offset.
396static SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
398 memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(Raw));
400}
401
402/// Load a (possibly unaligned) pointer from a given address and
403/// offset.
404static void *LoadPointer(void *Data, unsigned Offset) {
405 void *Result;
406 memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
407 return Result;
408}
409
411 if (!Qualifier)
412 return SourceRange();
413
415 while (NestedNameSpecifierLoc Prefix = First.getPrefix())
416 First = Prefix;
417
418 return SourceRange(First.getLocalSourceRange().getBegin(),
419 getLocalSourceRange().getEnd());
420}
421
423 if (!Qualifier)
424 return SourceRange();
425
426 unsigned Offset = getDataLength(Qualifier->getPrefix());
427 switch (Qualifier->getKind()) {
429 return LoadSourceLocation(Data, Offset);
430
435 return SourceRange(
436 LoadSourceLocation(Data, Offset),
437 LoadSourceLocation(Data, Offset + sizeof(SourceLocation::UIntTy)));
438
441 // The "void*" that points at the TypeLoc data.
442 // Note: the 'template' keyword is part of the TypeLoc.
443 void *TypeData = LoadPointer(Data, Offset);
444 TypeLoc TL(Qualifier->getAsType(), TypeData);
445 return SourceRange(TL.getBeginLoc(),
446 LoadSourceLocation(Data, Offset + sizeof(void*)));
447 }
448 }
449
450 llvm_unreachable("Invalid NNS Kind!");
451}
452
454 if (Qualifier->getKind() != NestedNameSpecifier::TypeSpec &&
455 Qualifier->getKind() != NestedNameSpecifier::TypeSpecWithTemplate)
456 return TypeLoc();
457
458 // The "void*" that points at the TypeLoc data.
459 unsigned Offset = getDataLength(Qualifier->getPrefix());
460 void *TypeData = LoadPointer(Data, Offset);
461 return TypeLoc(Qualifier->getAsType(), TypeData);
462}
463
464static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
465 unsigned &BufferCapacity) {
466 if (Start == End)
467 return;
468
469 if (BufferSize + (End - Start) > BufferCapacity) {
470 // Reallocate the buffer.
471 unsigned NewCapacity = std::max(
472 (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
473 (unsigned)(BufferSize + (End - Start)));
474 if (!BufferCapacity) {
475 char *NewBuffer = static_cast<char *>(llvm::safe_malloc(NewCapacity));
476 if (Buffer)
477 memcpy(NewBuffer, Buffer, BufferSize);
478 Buffer = NewBuffer;
479 } else {
480 Buffer = static_cast<char *>(llvm::safe_realloc(Buffer, NewCapacity));
481 }
482 BufferCapacity = NewCapacity;
483 }
484 assert(Buffer && Start && End && End > Start && "Illegal memory buffer copy");
485 memcpy(Buffer + BufferSize, Start, End - Start);
486 BufferSize += End - Start;
487}
488
489/// Save a source location to the given buffer.
490static void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
491 unsigned &BufferSize, unsigned &BufferCapacity) {
493 Append(reinterpret_cast<char *>(&Raw),
494 reinterpret_cast<char *>(&Raw) + sizeof(Raw), Buffer, BufferSize,
495 BufferCapacity);
496}
497
498/// Save a pointer to the given buffer.
499static void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
500 unsigned &BufferCapacity) {
501 Append(reinterpret_cast<char *>(&Ptr),
502 reinterpret_cast<char *>(&Ptr) + sizeof(void *),
503 Buffer, BufferSize, BufferCapacity);
504}
505
508 : Representation(Other.Representation) {
509 if (!Other.Buffer)
510 return;
511
512 if (Other.BufferCapacity == 0) {
513 // Shallow copy is okay.
514 Buffer = Other.Buffer;
515 BufferSize = Other.BufferSize;
516 return;
517 }
518
519 // Deep copy
520 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
521 BufferCapacity);
522}
523
527 Representation = Other.Representation;
528
529 if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
530 // Re-use our storage.
531 BufferSize = Other.BufferSize;
532 memcpy(Buffer, Other.Buffer, BufferSize);
533 return *this;
534 }
535
536 // Free our storage, if we have any.
537 if (BufferCapacity) {
538 free(Buffer);
539 BufferCapacity = 0;
540 }
541
542 if (!Other.Buffer) {
543 // Empty.
544 Buffer = nullptr;
545 BufferSize = 0;
546 return *this;
547 }
548
549 if (Other.BufferCapacity == 0) {
550 // Shallow copy is okay.
551 Buffer = Other.Buffer;
552 BufferSize = Other.BufferSize;
553 return *this;
554 }
555
556 // Deep copy.
557 BufferSize = 0;
558 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
559 BufferCapacity);
560 return *this;
561}
562
564 SourceLocation TemplateKWLoc,
565 TypeLoc TL,
566 SourceLocation ColonColonLoc) {
567 Representation = NestedNameSpecifier::Create(Context, Representation,
568 TemplateKWLoc.isValid(),
569 TL.getTypePtr());
570
571 // Push source-location info into the buffer.
572 SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
573 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
574}
575
579 SourceLocation ColonColonLoc) {
580 Representation = NestedNameSpecifier::Create(Context, Representation,
581 Identifier);
582
583 // Push source-location info into the buffer.
584 SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
585 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
586}
587
589 NamespaceDecl *Namespace,
590 SourceLocation NamespaceLoc,
591 SourceLocation ColonColonLoc) {
592 Representation = NestedNameSpecifier::Create(Context, Representation,
593 Namespace);
594
595 // Push source-location info into the buffer.
596 SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
597 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
598}
599
601 NamespaceAliasDecl *Alias,
602 SourceLocation AliasLoc,
603 SourceLocation ColonColonLoc) {
604 Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
605
606 // Push source-location info into the buffer.
607 SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
608 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
609}
610
612 SourceLocation ColonColonLoc) {
613 assert(!Representation && "Already have a nested-name-specifier!?");
614 Representation = NestedNameSpecifier::GlobalSpecifier(Context);
615
616 // Push source-location info into the buffer.
617 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
618}
619
621 CXXRecordDecl *RD,
622 SourceLocation SuperLoc,
623 SourceLocation ColonColonLoc) {
624 Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
625
626 // Push source-location info into the buffer.
627 SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
628 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
629}
630
632 NestedNameSpecifier *Qualifier,
633 SourceRange R) {
634 Representation = Qualifier;
635
636 // Construct bogus (but well-formed) source information for the
637 // nested-name-specifier.
638 BufferSize = 0;
640 for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
641 Stack.push_back(NNS);
642 while (!Stack.empty()) {
643 NestedNameSpecifier *NNS = Stack.pop_back_val();
644 switch (NNS->getKind()) {
648 SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
649 break;
650
653 TypeSourceInfo *TSInfo
654 = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
655 R.getBegin());
656 SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
657 BufferCapacity);
658 break;
659 }
660
663 break;
664 }
665
666 // Save the location of the '::'.
667 SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
668 Buffer, BufferSize, BufferCapacity);
669 }
670}
671
673 if (BufferCapacity)
674 free(Buffer);
675
676 if (!Other) {
677 Representation = nullptr;
678 BufferSize = 0;
679 return;
680 }
681
682 // Rather than copying the data (which is wasteful), "adopt" the
683 // pointer (which points into the ASTContext) but set the capacity to zero to
684 // indicate that we don't own it.
685 Representation = Other.getNestedNameSpecifier();
686 Buffer = static_cast<char *>(Other.getOpaqueData());
687 BufferSize = Other.getDataLength();
688 BufferCapacity = 0;
689}
690
693 if (!Representation)
694 return NestedNameSpecifierLoc();
695
696 // If we adopted our data pointer from elsewhere in the AST context, there's
697 // no need to copy the memory.
698 if (BufferCapacity == 0)
699 return NestedNameSpecifierLoc(Representation, Buffer);
700
701 // FIXME: After copying the source-location information, should we free
702 // our (temporary) buffer and adopt the ASTContext-allocated memory?
703 // Doing so would optimize repeated calls to getWithLocInContext().
704 void *Mem = Context.Allocate(BufferSize, alignof(void *));
705 memcpy(Mem, Buffer, BufferSize);
706 return NestedNameSpecifierLoc(Representation, Mem);
707}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
StringRef Identifier
Definition: Format.cpp:2960
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
llvm::MachO::Record Record
Definition: MachO.h:28
static void * LoadPointer(void *Data, unsigned Offset)
Load a (possibly unaligned) pointer from a given address and offset.
static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize, unsigned &BufferCapacity)
static void SaveSourceLocation(SourceLocation Loc, char *&Buffer, unsigned &BufferSize, unsigned &BufferCapacity)
Save a source location to the given buffer.
static void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize, unsigned &BufferCapacity)
Save a pointer to the given buffer.
static SourceLocation LoadSourceLocation(void *Data, unsigned Offset)
Load a (possibly unaligned) source location from a given address and offset.
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:713
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
base_class_range bases()
Definition: DeclCXX.h:618
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:418
This represents a decl that may have a name.
Definition: Decl.h:249
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
Represents a C++ namespace alias.
Definition: DeclCXX.h:3113
Represent a C++ namespace.
Definition: Decl.h:547
Class that aids in the construction of nested-name-specifiers along with source-location information ...
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
NestedNameSpecifierLocBuilder & operator=(const NestedNameSpecifierLocBuilder &Other)
void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, SourceRange R)
Make a new nested-name-specifier from incomplete source-location information.
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, SourceLocation SuperLoc, SourceLocation ColonColonLoc)
Turns this (empty) nested-name-specifier into '__super' nested-name-specifier.
void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, SourceLocation ColonColonLoc)
Extend the current nested-name-specifier by another nested-name-specifier component of the form 'type...
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc)
Turn this (empty) nested-name-specifier into the global nested-name-specifier '::'.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
A C++ nested-name-specifier augmented with source location information.
TypeLoc getTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
SourceRange getLocalSourceRange() const
Retrieve the source range covering just the last part of this nested-name-specifier,...
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
unsigned getDataLength() const
Determines the data length for the entire nested-name-specifier.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
bool containsErrors() const
Whether this nested name specifier contains an error.
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
void Profile(llvm::FoldingSetNodeID &ID) const
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.
bool isInstantiationDependent() const
Whether this nested name specifier involves a template parameter.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
SpecifierKind
The kind of specifier that completes this nested name specifier.
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
@ TypeSpec
A type, stored as a Type*.
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Identifier
An identifier, stored as an IdentifierInfo*.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace, stored as a NamespaceDecl*.
NestedNameSpecifierDependence getDependence() const
bool containsUnexpandedParameterPack() const
Whether this nested-name-specifier contains an unexpanded parameter pack (for C++11 variadic template...
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
static NestedNameSpecifier * SuperSpecifier(const ASTContext &Context, CXXRecordDecl *RD)
Returns the nested name specifier representing the __super scope for the given CXXRecordDecl.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, IdentifierInfo *II)
Builds a specifier combining a prefix and an identifier.
A (possibly-)qualified type.
Definition: Type.h:737
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Encodes a location in the source.
static SourceLocation getFromRawEncoding(UIntTy Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:5632
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:59
void * getOpaqueData() const
Get the pointer where source information is stored.
Definition: TypeLoc.h:142
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:192
const Type * getTypePtr() const
Definition: TypeLoc.h:137
A container of type source information.
Definition: Type.h:6873
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:256
The base class of the type hierarchy.
Definition: Type.h:1606
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1819
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
NestedNameSpecifierDependence toNestedNameSpecifierDependendence(TypeDependence D)
@ Other
Other implicit parameter.
Wraps an identifier and optional source location for the identifier.
Definition: ParsedAttr.h:100
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned SuppressScope
Suppresses printing of scope specifiers.