clang: lib/AST/NestedNameSpecifier.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
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
32#include
33#include
34#include
35
36using namespace clang;
37
39NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
41 llvm::FoldingSetNodeID ID;
43
44 void *InsertPos = nullptr;
46 = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
47 if (!NNS) {
48 NNS =
50 Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
51 }
52
53 return NNS;
54}
55
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);
66 return FindOrInsert(Context, Mockup);
67}
68
73 assert(NS && "Namespace cannot be NULL");
74 assert((!Prefix ||
75 (Prefix->getAsType() == 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
89 assert(Alias && "Namespace alias cannot be NULL");
90 assert((!Prefix ||
91 (Prefix->getAsType() == nullptr &&
93 "Broken nested name specifier");
95 Mockup.Prefix.setPointer(Prefix);
96 Mockup.Prefix.setInt(StoredDecl);
98 return FindOrInsert(Context, Mockup);
99}
100
104 bool Template, const Type *T) {
105 assert(T && "Type cannot be NULL");
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
115 assert(II && "Identifier cannot be NULL");
117 Mockup.Prefix.setPointer(nullptr);
118 Mockup.Prefix.setInt(StoredIdentifier);
120 return FindOrInsert(Context, Mockup);
121}
122
125 if (!Context.GlobalNestedNameSpecifier)
126 Context.GlobalNestedNameSpecifier =
128 return Context.GlobalNestedNameSpecifier;
129}
130
135 Mockup.Prefix.setPointer(nullptr);
136 Mockup.Prefix.setInt(StoredDecl);
137 Mockup.Specifier = RD;
138 return FindOrInsert(Context, Mockup);
139}
140
142 if (!Specifier)
144
145 switch (Prefix.getInt()) {
146 case StoredIdentifier:
148
149 case StoredDecl: {
151 if (isa(ND))
154 }
155
156 case StoredTypeSpec:
158
159 case StoredTypeSpecWithTemplate:
161 }
162
163 llvm_unreachable("Invalid NNS Kind!");
164}
165
166
168 if (Prefix.getInt() == StoredDecl)
169 return dyn_cast(static_cast<NamedDecl *>(Specifier));
170
171 return nullptr;
172}
173
174
176 if (Prefix.getInt() == StoredDecl)
177 return dyn_cast(static_cast<NamedDecl *>(Specifier));
178
179 return nullptr;
180}
181
182
184 switch (Prefix.getInt()) {
185 case StoredIdentifier:
186 return nullptr;
187
188 case StoredDecl:
189 return dyn_cast(static_cast<NamedDecl *>(Specifier));
190
191 case StoredTypeSpec:
192 case StoredTypeSpecWithTemplate:
194 }
195
196 llvm_unreachable("Invalid NNS Kind!");
197}
198
202
203 auto F = NestedNameSpecifierDependence::Dependent |
204 NestedNameSpecifierDependence::Instantiation;
205
208 return F;
209 }
210
214 return NestedNameSpecifierDependence::None;
215
218 for (const auto &Base : RD->bases())
219 if (Base.getType()->isDependentType())
220
221 return NestedNameSpecifierDependence::Dependent;
222 return NestedNameSpecifierDependence::None;
223 }
224
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
249
251 bool ResolveTemplateArguments) const {
254
258 break;
259
262 return;
263
265 break;
266
269 break;
270
272 break;
273
275 OS << "__super";
276 break;
277
279 OS << "template ";
280
281 [[fallthrough]];
282
285 dyn_cast_or_null(getAsRecordDecl());
286 if (ResolveTemplateArguments && Record) {
287
288 Record->printName(OS, Policy);
290 OS, Record->getTemplateArgs().asArray(), Policy,
291 Record->getSpecializedTemplate()->getTemplateParameters());
292 break;
293 }
295
298
299
300
301
302
303
304
305
306 assert(!isa(T) &&
307 "Elaborated type in nested-name-specifier");
309 = dyn_cast(T)) {
310
311
312 SpecType->getTemplateName().print(OS, InnerPolicy,
314
315
317 InnerPolicy);
318 } else if (const auto *DepSpecType =
319 dyn_cast(T)) {
320
321
322 OS << DepSpecType->getIdentifier()->getName();
323
325 InnerPolicy);
326 } else {
327
329 }
330 break;
331 }
332 }
333
334 OS << "::";
335}
336
338 dump(llvm::errs(), LO);
339}
340
342
345 dump(OS, LO);
346}
347
351}
352
353unsigned
354NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
355 assert(Qualifier && "Expected a non-NULL qualifier");
356
357
359
360 switch (Qualifier->getKind()) {
362
363 break;
364
369
371 break;
372
375
376
377 Length += sizeof(void *);
378 break;
379 }
380
381 return Length;
382}
383
384unsigned
386 unsigned Length = 0;
388 Length += getLocalDataLength(Qualifier);
389 return Length;
390}
391
392
393
396 memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(Raw));
398}
399
400
401
404 memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
406}
407
409 if (!Qualifier)
411
415
418}
419
421 if (!Qualifier)
423
424 unsigned Offset = getDataLength(Qualifier->getPrefix());
425 switch (Qualifier->getKind()) {
428
436
439
440
441 void *TypeData = LoadPointer(Data, Offset);
442 TypeLoc TL(Qualifier->getAsType(), TypeData);
445 }
446 }
447
448 llvm_unreachable("Invalid NNS Kind!");
449}
450
455
456
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
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
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
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 (.Buffer)
508 return;
509
510 if (Other.BufferCapacity == 0) {
511
512 Buffer = Other.Buffer;
513 BufferSize = Other.BufferSize;
514 return;
515 }
516
517
519 BufferCapacity);
520}
521
525 Representation = Other.Representation;
526
527 if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
528
529 BufferSize = Other.BufferSize;
530 memcpy(Buffer, Other.Buffer, BufferSize);
531 return *this;
532 }
533
534
535 if (BufferCapacity) {
536 free(Buffer);
537 BufferCapacity = 0;
538 }
539
540 if (.Buffer) {
541
542 Buffer = nullptr;
543 BufferSize = 0;
544 return *this;
545 }
546
547 if (Other.BufferCapacity == 0) {
548
549 Buffer = Other.Buffer;
550 BufferSize = Other.BufferSize;
551 return *this;
552 }
553
554
555 BufferSize = 0;
557 BufferCapacity);
558 return *this;
559}
560
568
569
571 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
572}
573
580
581
583 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
584}
585
591 Namespace);
592
593
594 SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
595 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
596}
597
603
604
606 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
607}
608
611 assert(!Representation && "Already have a nested-name-specifier!?");
613
614
615 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
616}
617
623
624
626 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
627}
628
632 Representation = Qualifier;
633
634
635
636 BufferSize = 0;
639 Stack.push_back(NNS);
640 while (!Stack.empty()) {
642 switch (NNS->getKind()) {
647 break;
648
655 BufferCapacity);
656 break;
657 }
658
661 break;
662 }
663
664
666 Buffer, BufferSize, BufferCapacity);
667 }
668}
669
671 if (BufferCapacity)
672 free(Buffer);
673
675 Representation = nullptr;
676 BufferSize = 0;
677 return;
678 }
679
680
681
682
683 Representation = Other.getNestedNameSpecifier();
684 Buffer = static_cast<char *>(Other.getOpaqueData());
685 BufferSize = Other.getDataLength();
686 BufferCapacity = 0;
687}
688
691 if (!Representation)
693
694
695
696 if (BufferCapacity == 0)
698
699
700
701
702 void *Mem = Context.Allocate(BufferSize, alignof(void *));
703 memcpy(Mem, Buffer, BufferSize);
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.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
llvm::MachO::Record Record
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 ...
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
Represents a C++ struct/union/class.
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...
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represents a C++ namespace alias.
Represent a C++ namespace.
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.
NestedNameSpecifierLocBuilder()=default
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::".
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.
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...
Base wrapper for a particular "section" of type source info.
void * getOpaqueData() const
Get the pointer where source information is stored.
SourceLocation getBeginLoc() const
Get the begin source location.
const Type * getTypePtr() const
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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.
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressScope
Suppresses printing of scope specifiers.