clang 20.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/Support/Compiler.h"
29#include "llvm/Support/ErrorHandling.h"
30#include "llvm/Support/raw_ostream.h"
31#include <algorithm>
32#include <cassert>
33#include <cstdlib>
34#include <cstring>
35
36using namespace clang;
37
39NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
40 const NestedNameSpecifier &Mockup) {
41 llvm::FoldingSetNodeID ID;
42 Mockup.Profile(ID);
43
44 void *InsertPos = nullptr;
46 = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
47 if (!NNS) {
48 NNS =
49 new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(Mockup);
50 Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
51 }
52
53 return NNS;
54}
55
57 NestedNameSpecifier *Prefix,
58 const IdentifierInfo *II) {
59 assert(II && "Identifier cannot be NULL");
60 assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
61
63 Mockup.Prefix.setPointer(Prefix);
64 Mockup.Prefix.setInt(StoredIdentifier);
65 Mockup.Specifier = const_cast<IdentifierInfo *>(II);
66 return FindOrInsert(Context, Mockup);
67}
68
71 NestedNameSpecifier *Prefix,
72 const NamespaceDecl *NS) {
73 assert(NS && "Namespace cannot be NULL");
74 assert((!Prefix ||
75 (Prefix->getAsType() == nullptr &&
76 Prefix->getAsIdentifier() == nullptr)) &&
77 "Broken nested name specifier");
79 Mockup.Prefix.setPointer(Prefix);
80 Mockup.Prefix.setInt(StoredDecl);
81 Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
82 return FindOrInsert(Context, Mockup);
83}
84
87 NestedNameSpecifier *Prefix,
88 const NamespaceAliasDecl *Alias) {
89 assert(Alias && "Namespace alias cannot be NULL");
90 assert((!Prefix ||
91 (Prefix->getAsType() == nullptr &&
92 Prefix->getAsIdentifier() == nullptr)) &&
93 "Broken nested name specifier");
95 Mockup.Prefix.setPointer(Prefix);
96 Mockup.Prefix.setInt(StoredDecl);
97 Mockup.Specifier = const_cast<NamespaceAliasDecl *>(Alias);
98 return FindOrInsert(Context, Mockup);
99}
100
103 NestedNameSpecifier *Prefix,
104 bool Template, const Type *T) {
105 assert(T && "Type cannot be NULL");
106 NestedNameSpecifier Mockup;
107 Mockup.Prefix.setPointer(Prefix);
108 Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
109 Mockup.Specifier = const_cast<Type*>(T);
110 return FindOrInsert(Context, Mockup);
111}
112
114 const IdentifierInfo *II) {
115 assert(II && "Identifier cannot be NULL");
116 NestedNameSpecifier Mockup;
117 Mockup.Prefix.setPointer(nullptr);
118 Mockup.Prefix.setInt(StoredIdentifier);
119 Mockup.Specifier = const_cast<IdentifierInfo *>(II);
120 return FindOrInsert(Context, Mockup);
121}
122
125 if (!Context.GlobalNestedNameSpecifier)
126 Context.GlobalNestedNameSpecifier =
127 new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier();
128 return Context.GlobalNestedNameSpecifier;
129}
130
133 CXXRecordDecl *RD) {
134 NestedNameSpecifier Mockup;
135 Mockup.Prefix.setPointer(nullptr);
136 Mockup.Prefix.setInt(StoredDecl);
137 Mockup.Specifier = RD;
138 return FindOrInsert(Context, Mockup);
139}
140
142 if (!Specifier)
143 return Global;
144
145 switch (Prefix.getInt()) {
146 case StoredIdentifier:
147 return Identifier;
148
149 case StoredDecl: {
150 NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
151 if (isa<CXXRecordDecl>(ND))
152 return Super;
153 return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
154 }
155
156 case StoredTypeSpec:
157 return TypeSpec;
158
159 case StoredTypeSpecWithTemplate:
161 }
162
163 llvm_unreachable("Invalid NNS Kind!");
164}
165
166/// Retrieve the namespace stored in this nested name specifier.
168 if (Prefix.getInt() == StoredDecl)
169 return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
170
171 return nullptr;
172}
173
174/// Retrieve the namespace alias stored in this nested name specifier.
176 if (Prefix.getInt() == StoredDecl)
177 return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
178
179 return nullptr;
180}
181
182/// Retrieve the record declaration stored in this nested name specifier.
184 switch (Prefix.getInt()) {
185 case StoredIdentifier:
186 return nullptr;
187
188 case StoredDecl:
189 return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
190
191 case StoredTypeSpec:
192 case StoredTypeSpecWithTemplate:
193 return getAsType()->getAsCXXRecordDecl();
194 }
195
196 llvm_unreachable("Invalid NNS Kind!");
197}
198
199NestedNameSpecifierDependence NestedNameSpecifier::getDependence() const {
200 switch (getKind()) {
201 case Identifier: {
202 // Identifier specifiers always represent dependent types
203 auto F = NestedNameSpecifierDependence::Dependent |
204 NestedNameSpecifierDependence::Instantiation;
205 // Prefix can contain unexpanded template parameters.
206 if (getPrefix())
207 return F | getPrefix()->getDependence();
208 return F;
209 }
210
211 case Namespace:
212 case NamespaceAlias:
213 case Global:
214 return NestedNameSpecifierDependence::None;
215
216 case Super: {
217 CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
218 for (const auto &Base : RD->bases())
219 if (Base.getType()->isDependentType())
220 // FIXME: must also be instantiation-dependent.
221 return NestedNameSpecifierDependence::Dependent;
222 return NestedNameSpecifierDependence::None;
223 }
224
225 case TypeSpec:
228 }
229 llvm_unreachable("Invalid NNS Kind!");
230}
231
233 return getDependence() & NestedNameSpecifierDependence::Dependent;
234}
235
237 return getDependence() & NestedNameSpecifierDependence::Instantiation;
238}
239
241 return getDependence() & NestedNameSpecifierDependence::UnexpandedPack;
242}
243
245 return getDependence() & NestedNameSpecifierDependence::Error;
246}
247
248/// Print this nested name specifier to the given output
249/// stream.
250void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
251 bool ResolveTemplateArguments) const {
252 if (getPrefix())
253 getPrefix()->print(OS, Policy);
254
255 switch (getKind()) {
256 case Identifier:
257 OS << getAsIdentifier()->getName();
258 break;
259
260 case Namespace:
261 if (getAsNamespace()->isAnonymousNamespace())
262 return;
263
264 OS << getAsNamespace()->getName();
265 break;
266
267 case NamespaceAlias:
268 OS << getAsNamespaceAlias()->getName();
269 break;
270
271 case Global:
272 break;
273
274 case Super:
275 OS << "__super";
276 break;
277
279 OS << "template ";
280 // Fall through to print the type.
281 [[fallthrough]];
282
283 case TypeSpec: {
284 const auto *Record =
285 dyn_cast_or_null<ClassTemplateSpecializationDecl>(getAsRecordDecl());
286 if (ResolveTemplateArguments && Record) {
287 // Print the type trait with resolved template parameters.
288 Record->printName(OS, Policy);
290 OS, Record->getTemplateArgs().asArray(), Policy,
291 Record->getSpecializedTemplate()->getTemplateParameters());
292 break;
293 }
294 const Type *T = getAsType();
295
296 PrintingPolicy InnerPolicy(Policy);
297 InnerPolicy.SuppressScope = true;
298
299 // Nested-name-specifiers are intended to contain minimally-qualified
300 // types. An actual ElaboratedType will not occur, since we'll store
301 // just the type that is referred to in the nested-name-specifier (e.g.,
302 // a TypedefType, TagType, etc.). However, when we are dealing with
303 // dependent template-id types (e.g., Outer<T>::template Inner<U>),
304 // the type requires its own nested-name-specifier for uniqueness, so we
305 // suppress that nested-name-specifier during printing.
306 assert(!isa<ElaboratedType>(T) &&
307 "Elaborated type in nested-name-specifier");
308 if (const TemplateSpecializationType *SpecType
309 = dyn_cast<TemplateSpecializationType>(T)) {
310 // Print the template name without its corresponding
311 // nested-name-specifier.
312 SpecType->getTemplateName().print(OS, InnerPolicy,
314
315 // Print the template argument list.
316 printTemplateArgumentList(OS, SpecType->template_arguments(),
317 InnerPolicy);
318 } else if (const auto *DepSpecType =
319 dyn_cast<DependentTemplateSpecializationType>(T)) {
320 // Print the template name without its corresponding
321 // nested-name-specifier.
322 OS << DepSpecType->getIdentifier()->getName();
323 // Print the template argument list.
324 printTemplateArgumentList(OS, DepSpecType->template_arguments(),
325 InnerPolicy);
326 } else {
327 // Print the type normally
328 QualType(T, 0).print(OS, InnerPolicy);
329 }
330 break;
331 }
332 }
333
334 OS << "::";
335}
336
337LLVM_DUMP_METHOD void NestedNameSpecifier::dump(const LangOptions &LO) const {
338 dump(llvm::errs(), LO);
339}
340
341LLVM_DUMP_METHOD void NestedNameSpecifier::dump() const { dump(llvm::errs()); }
342
343LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS) const {
344 LangOptions LO;
345 dump(OS, LO);
346}
347
348LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS,
349 const LangOptions &LO) const {
350 print(OS, PrintingPolicy(LO));
351}
352
353unsigned
354NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
355 assert(Qualifier && "Expected a non-NULL qualifier");
356
357 // Location of the trailing '::'.
358 unsigned Length = sizeof(SourceLocation::UIntTy);
359
360 switch (Qualifier->getKind()) {
362 // Nothing more to add.
363 break;
364
369 // The location of the identifier or namespace name.
370 Length += sizeof(SourceLocation::UIntTy);
371 break;
372
375 // The "void*" that points at the TypeLoc data.
376 // Note: the 'template' keyword is part of the TypeLoc.
377 Length += sizeof(void *);
378 break;
379 }
380
381 return Length;
382}
383
384unsigned
386 unsigned Length = 0;
387 for (; Qualifier; Qualifier = Qualifier->getPrefix())
388 Length += getLocalDataLength(Qualifier);
389 return Length;
390}
391
392/// Load a (possibly unaligned) source location from a given address
393/// and offset.
394static SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
396 memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(Raw));
398}
399
400/// Load a (possibly unaligned) pointer from a given address and
401/// offset.
402static void *LoadPointer(void *Data, unsigned Offset) {
403 void *Result;
404 memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
405 return Result;
406}
407
409 if (!Qualifier)
410 return SourceRange();
411
413 while (NestedNameSpecifierLoc Prefix = First.getPrefix())
414 First = Prefix;
415
416 return SourceRange(First.getLocalSourceRange().getBegin(),
417 getLocalSourceRange().getEnd());
418}
419
421 if (!Qualifier)
422 return SourceRange();
423
424 unsigned Offset = getDataLength(Qualifier->getPrefix());
425 switch (Qualifier->getKind()) {
427 return LoadSourceLocation(Data, Offset);
428
433 return SourceRange(
434 LoadSourceLocation(Data, Offset),
435 LoadSourceLocation(Data, Offset + sizeof(SourceLocation::UIntTy)));
436
439 // The "void*" that points at the TypeLoc data.
440 // Note: the 'template' keyword is part of the TypeLoc.
441 void *TypeData = LoadPointer(Data, Offset);
442 TypeLoc TL(Qualifier->getAsType(), TypeData);
443 return SourceRange(TL.getBeginLoc(),
444 LoadSourceLocation(Data, Offset + sizeof(void*)));
445 }
446 }
447
448 llvm_unreachable("Invalid NNS Kind!");
449}
450
452 if (Qualifier->getKind() != NestedNameSpecifier::TypeSpec &&
453 Qualifier->getKind() != NestedNameSpecifier::TypeSpecWithTemplate)
454 return TypeLoc();
455
456 // The "void*" that points at the TypeLoc data.
457 unsigned Offset = getDataLength(Qualifier->getPrefix());
458 void *TypeData = LoadPointer(Data, Offset);
459 return TypeLoc(Qualifier->getAsType(), TypeData);
460}
461
462static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
463 unsigned &BufferCapacity) {
464 if (Start == End)
465 return;
466
467 if (BufferSize + (End - Start) > BufferCapacity) {
468 // Reallocate the buffer.
469 unsigned NewCapacity = std::max(
470 (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
471 (unsigned)(BufferSize + (End - Start)));
472 if (!BufferCapacity) {
473 char *NewBuffer = static_cast<char *>(llvm::safe_malloc(NewCapacity));
474 if (Buffer)
475 memcpy(NewBuffer, Buffer, BufferSize);
476 Buffer = NewBuffer;
477 } else {
478 Buffer = static_cast<char *>(llvm::safe_realloc(Buffer, NewCapacity));
479 }
480 BufferCapacity = NewCapacity;
481 }
482 assert(Buffer && Start && End && End > Start && "Illegal memory buffer copy");
483 memcpy(Buffer + BufferSize, Start, End - Start);
484 BufferSize += End - Start;
485}
486
487/// Save a source location to the given buffer.
488static void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
489 unsigned &BufferSize, unsigned &BufferCapacity) {
491 Append(reinterpret_cast<char *>(&Raw),
492 reinterpret_cast<char *>(&Raw) + sizeof(Raw), Buffer, BufferSize,
493 BufferCapacity);
494}
495
496/// Save a pointer to the given buffer.
497static void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
498 unsigned &BufferCapacity) {
499 Append(reinterpret_cast<char *>(&Ptr),
500 reinterpret_cast<char *>(&Ptr) + sizeof(void *),
501 Buffer, BufferSize, BufferCapacity);
502}
503
506 : Representation(Other.Representation) {
507 if (!Other.Buffer)
508 return;
509
510 if (Other.BufferCapacity == 0) {
511 // Shallow copy is okay.
512 Buffer = Other.Buffer;
513 BufferSize = Other.BufferSize;
514 return;
515 }
516
517 // Deep copy
518 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
519 BufferCapacity);
520}
521
525 Representation = Other.Representation;
526
527 if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
528 // Re-use our storage.
529 BufferSize = Other.BufferSize;
530 memcpy(Buffer, Other.Buffer, BufferSize);
531 return *this;
532 }
533
534 // Free our storage, if we have any.
535 if (BufferCapacity) {
536 free(Buffer);
537 BufferCapacity = 0;
538 }
539
540 if (!Other.Buffer) {
541 // Empty.
542 Buffer = nullptr;
543 BufferSize = 0;
544 return *this;
545 }
546
547 if (Other.BufferCapacity == 0) {
548 // Shallow copy is okay.
549 Buffer = Other.Buffer;
550 BufferSize = Other.BufferSize;
551 return *this;
552 }
553
554 // Deep copy.
555 BufferSize = 0;
556 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
557 BufferCapacity);
558 return *this;
559}
560
562 SourceLocation TemplateKWLoc,
563 TypeLoc TL,
564 SourceLocation ColonColonLoc) {
565 Representation = NestedNameSpecifier::Create(Context, Representation,
566 TemplateKWLoc.isValid(),
567 TL.getTypePtr());
568
569 // Push source-location info into the buffer.
570 SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
571 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
572}
573
577 SourceLocation ColonColonLoc) {
578 Representation = NestedNameSpecifier::Create(Context, Representation,
579 Identifier);
580
581 // Push source-location info into the buffer.
582 SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
583 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
584}
585
587 NamespaceDecl *Namespace,
588 SourceLocation NamespaceLoc,
589 SourceLocation ColonColonLoc) {
590 Representation = NestedNameSpecifier::Create(Context, Representation,
591 Namespace);
592
593 // Push source-location info into the buffer.
594 SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
595 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
596}
597
599 NamespaceAliasDecl *Alias,
600 SourceLocation AliasLoc,
601 SourceLocation ColonColonLoc) {
602 Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
603
604 // Push source-location info into the buffer.
605 SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
606 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
607}
608
610 SourceLocation ColonColonLoc) {
611 assert(!Representation && "Already have a nested-name-specifier!?");
612 Representation = NestedNameSpecifier::GlobalSpecifier(Context);
613
614 // Push source-location info into the buffer.
615 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
616}
617
619 CXXRecordDecl *RD,
620 SourceLocation SuperLoc,
621 SourceLocation ColonColonLoc) {
622 Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
623
624 // Push source-location info into the buffer.
625 SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
626 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
627}
628
630 NestedNameSpecifier *Qualifier,
631 SourceRange R) {
632 Representation = Qualifier;
633
634 // Construct bogus (but well-formed) source information for the
635 // nested-name-specifier.
636 BufferSize = 0;
638 for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
639 Stack.push_back(NNS);
640 while (!Stack.empty()) {
641 NestedNameSpecifier *NNS = Stack.pop_back_val();
642 switch (NNS->getKind()) {
646 SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
647 break;
648
651 TypeSourceInfo *TSInfo
652 = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
653 R.getBegin());
654 SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
655 BufferCapacity);
656 break;
657 }
658
661 break;
662 }
663
664 // Save the location of the '::'.
665 SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
666 Buffer, BufferSize, BufferCapacity);
667 }
668}
669
671 if (BufferCapacity)
672 free(Buffer);
673
674 if (!Other) {
675 Representation = nullptr;
676 BufferSize = 0;
677 return;
678 }
679
680 // Rather than copying the data (which is wasteful), "adopt" the
681 // pointer (which points into the ASTContext) but set the capacity to zero to
682 // indicate that we don't own it.
683 Representation = Other.getNestedNameSpecifier();
684 Buffer = static_cast<char *>(Other.getOpaqueData());
685 BufferSize = Other.getDataLength();
686 BufferCapacity = 0;
687}
688
691 if (!Representation)
692 return NestedNameSpecifierLoc();
693
694 // If we adopted our data pointer from elsewhere in the AST context, there's
695 // no need to copy the memory.
696 if (BufferCapacity == 0)
697 return NestedNameSpecifierLoc(Representation, Buffer);
698
699 // FIXME: After copying the source-location information, should we free
700 // our (temporary) buffer and adopt the ASTContext-allocated memory?
701 // Doing so would optimize repeated calls to getWithLocInContext().
702 void *Mem = Context.Allocate(BufferSize, alignof(void *));
703 memcpy(Mem, Buffer, BufferSize);
704 return NestedNameSpecifierLoc(Representation, Mem);
705}
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:3040
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:31
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.
SourceLocation Loc
Definition: SemaObjC.cpp:759
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:188
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:754
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
base_class_range bases()
Definition: DeclCXX.h:620
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:499
This represents a decl that may have a name.
Definition: Decl.h:253
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:280
Represents a C++ namespace alias.
Definition: DeclCXX.h:3138
Represent a C++ namespace.
Definition: Decl.h:551
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.
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, const IdentifierInfo *II)
Builds a specifier combining a prefix and an identifier.
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.
A (possibly-)qualified type.
Definition: Type.h:929
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:6661
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:7902
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:1828
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1916
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
const FunctionProtoType * T
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:103
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned SuppressScope
Suppresses printing of scope specifiers.