Warning: That file was not part of the compilation database. It may have many parsing errors.

1//===- NestedNameSpecifier.h - C++ nested name specifiers -------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the NestedNameSpecifier class, which represents
11// a C++ nested-name-specifier.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
16#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
17
18#include "clang/Basic/Diagnostic.h"
19#include "clang/Basic/SourceLocation.h"
20#include "llvm/ADT/FoldingSet.h"
21#include "llvm/ADT/PointerIntPair.h"
22#include "llvm/Support/Compiler.h"
23#include <cstdint>
24#include <cstdlib>
25#include <utility>
26
27namespace clang {
28
29class ASTContext;
30class CXXRecordDecl;
31class IdentifierInfo;
32class LangOptions;
33class NamespaceAliasDecl;
34class NamespaceDecl;
35struct PrintingPolicy;
36class Type;
37class TypeLoc;
38
39/// Represents a C++ nested name specifier, such as
40/// "\::std::vector<int>::".
41///
42/// C++ nested name specifiers are the prefixes to qualified
43/// names. For example, "foo::" in "foo::x" is a nested name
44/// specifier. Nested name specifiers are made up of a sequence of
45/// specifiers, each of which can be a namespace, type, identifier
46/// (for dependent names), decltype specifier, or the global specifier ('::').
47/// The last two specifiers can only appear at the start of a
48/// nested-namespace-specifier.
49class NestedNameSpecifier : public llvm::FoldingSetNode {
50 /// Enumeration describing
51 enum StoredSpecifierKind {
52 StoredIdentifier = 0,
53 StoredDecl = 1,
54 StoredTypeSpec = 2,
55 StoredTypeSpecWithTemplate = 3
56 };
57
58 /// The nested name specifier that precedes this nested name
59 /// specifier.
60 ///
61 /// The pointer is the nested-name-specifier that precedes this
62 /// one. The integer stores one of the first four values of type
63 /// SpecifierKind.
64 llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
65
66 /// The last component in the nested name specifier, which
67 /// can be an identifier, a declaration, or a type.
68 ///
69 /// When the pointer is NULL, this specifier represents the global
70 /// specifier '::'. Otherwise, the pointer is one of
71 /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
72 /// specifier as encoded within the prefix.
73 void* Specifier = nullptr;
74
75public:
76 /// The kind of specifier that completes this nested name
77 /// specifier.
78 enum SpecifierKind {
79 /// An identifier, stored as an IdentifierInfo*.
80 Identifier,
81
82 /// A namespace, stored as a NamespaceDecl*.
83 Namespace,
84
85 /// A namespace alias, stored as a NamespaceAliasDecl*.
86 NamespaceAlias,
87
88 /// A type, stored as a Type*.
89 TypeSpec,
90
91 /// A type that was preceded by the 'template' keyword,
92 /// stored as a Type*.
93 TypeSpecWithTemplate,
94
95 /// The global specifier '::'. There is no stored value.
96 Global,
97
98 /// Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
99 /// the class it appeared in.
100 Super
101 };
102
103private:
104 /// Builds the global specifier.
105 NestedNameSpecifier() : Prefix(nullptr, StoredIdentifier) {}
106
107 /// Copy constructor used internally to clone nested name
108 /// specifiers.
109 NestedNameSpecifier(const NestedNameSpecifier &Other) = default;
110
111 /// Either find or insert the given nested name specifier
112 /// mockup in the given context.
113 static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
114 const NestedNameSpecifier &Mockup);
115
116public:
117 NestedNameSpecifier &operator=(const NestedNameSpecifier &) = delete;
118
119 /// Builds a specifier combining a prefix and an identifier.
120 ///
121 /// The prefix must be dependent, since nested name specifiers
122 /// referencing an identifier are only permitted when the identifier
123 /// cannot be resolved.
124 static NestedNameSpecifier *Create(const ASTContext &Context,
125 NestedNameSpecifier *Prefix,
126 IdentifierInfo *II);
127
128 /// Builds a nested name specifier that names a namespace.
129 static NestedNameSpecifier *Create(const ASTContext &Context,
130 NestedNameSpecifier *Prefix,
131 const NamespaceDecl *NS);
132
133 /// Builds a nested name specifier that names a namespace alias.
134 static NestedNameSpecifier *Create(const ASTContext &Context,
135 NestedNameSpecifier *Prefix,
136 NamespaceAliasDecl *Alias);
137
138 /// Builds a nested name specifier that names a type.
139 static NestedNameSpecifier *Create(const ASTContext &Context,
140 NestedNameSpecifier *Prefix,
141 bool Template, const Type *T);
142
143 /// Builds a specifier that consists of just an identifier.
144 ///
145 /// The nested-name-specifier is assumed to be dependent, but has no
146 /// prefix because the prefix is implied by something outside of the
147 /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
148 /// type.
149 static NestedNameSpecifier *Create(const ASTContext &Context,
150 IdentifierInfo *II);
151
152 /// Returns the nested name specifier representing the global
153 /// scope.
154 static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
155
156 /// Returns the nested name specifier representing the __super scope
157 /// for the given CXXRecordDecl.
158 static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
159 CXXRecordDecl *RD);
160
161 /// Return the prefix of this nested name specifier.
162 ///
163 /// The prefix contains all of the parts of the nested name
164 /// specifier that preced this current specifier. For example, for a
165 /// nested name specifier that represents "foo::bar::", the current
166 /// specifier will contain "bar::" and the prefix will contain
167 /// "foo::".
168 NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
169
170 /// Determine what kind of nested name specifier is stored.
171 SpecifierKind getKind() const;
172
173 /// Retrieve the identifier stored in this nested name
174 /// specifier.
175 IdentifierInfo *getAsIdentifier() const {
176 if (Prefix.getInt() == StoredIdentifier)
177 return (IdentifierInfo *)Specifier;
178
179 return nullptr;
180 }
181
182 /// Retrieve the namespace stored in this nested name
183 /// specifier.
184 NamespaceDecl *getAsNamespace() const;
185
186 /// Retrieve the namespace alias stored in this nested name
187 /// specifier.
188 NamespaceAliasDecl *getAsNamespaceAlias() const;
189
190 /// Retrieve the record declaration stored in this nested name
191 /// specifier.
192 CXXRecordDecl *getAsRecordDecl() const;
193
194 /// Retrieve the type stored in this nested name specifier.
195 const Type *getAsType() const {
196 if (Prefix.getInt() == StoredTypeSpec ||
197 Prefix.getInt() == StoredTypeSpecWithTemplate)
198 return (const Type *)Specifier;
199
200 return nullptr;
201 }
202
203 /// Whether this nested name specifier refers to a dependent
204 /// type or not.
205 bool isDependent() const;
206
207 /// Whether this nested name specifier involves a template
208 /// parameter.
209 bool isInstantiationDependent() const;
210
211 /// Whether this nested-name-specifier contains an unexpanded
212 /// parameter pack (for C++11 variadic templates).
213 bool containsUnexpandedParameterPack() const;
214
215 /// Print this nested name specifier to the given output
216 /// stream.
217 void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
218
219 void Profile(llvm::FoldingSetNodeID &ID) const {
220 ID.AddPointer(Prefix.getOpaqueValue());
221 ID.AddPointer(Specifier);
222 }
223
224 /// Dump the nested name specifier to standard output to aid
225 /// in debugging.
226 void dump(const LangOptions &LO) const;
227 void dump() const;
228};
229
230/// A C++ nested-name-specifier augmented with source location
231/// information.
232class NestedNameSpecifierLoc {
233 NestedNameSpecifier *Qualifier = nullptr;
234 void *Data = nullptr;
235
236 /// Determines the data length for the last component in the
237 /// given nested-name-specifier.
238 static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
239
240 /// Determines the data length for the entire
241 /// nested-name-specifier.
242 static unsigned getDataLength(NestedNameSpecifier *Qualifier);
243
244public:
245 /// Construct an empty nested-name-specifier.
246 NestedNameSpecifierLoc() = default;
247
248 /// Construct a nested-name-specifier with source location information
249 /// from
250 NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
251 : Qualifier(Qualifier), Data(Data) {}
252
253 /// Evaluates true when this nested-name-specifier location is
254 /// non-empty.
255 explicit operator bool() const { return Qualifier; }
256
257 /// Evaluates true when this nested-name-specifier location is
258 /// empty.
259 bool hasQualifier() const { return Qualifier; }
260
261 /// Retrieve the nested-name-specifier to which this instance
262 /// refers.
263 NestedNameSpecifier *getNestedNameSpecifier() const {
264 return Qualifier;
265 }
266
267 /// Retrieve the opaque pointer that refers to source-location data.
268 void *getOpaqueData() const { return Data; }
269
270 /// Retrieve the source range covering the entirety of this
271 /// nested-name-specifier.
272 ///
273 /// For example, if this instance refers to a nested-name-specifier
274 /// \c \::std::vector<int>::, the returned source range would cover
275 /// from the initial '::' to the last '::'.
276 SourceRange getSourceRange() const LLVM_READONLY;
277
278 /// Retrieve the source range covering just the last part of
279 /// this nested-name-specifier, not including the prefix.
280 ///
281 /// For example, if this instance refers to a nested-name-specifier
282 /// \c \::std::vector<int>::, the returned source range would cover
283 /// from "vector" to the last '::'.
284 SourceRange getLocalSourceRange() const;
285
286 /// Retrieve the location of the beginning of this
287 /// nested-name-specifier.
288 SourceLocation getBeginLoc() const {
289 return getSourceRange().getBegin();
290 }
291
292 /// Retrieve the location of the end of this
293 /// nested-name-specifier.
294 SourceLocation getEndLoc() const {
295 return getSourceRange().getEnd();
296 }
297
298 /// Retrieve the location of the beginning of this
299 /// component of the nested-name-specifier.
300 SourceLocation getLocalBeginLoc() const {
301 return getLocalSourceRange().getBegin();
302 }
303
304 /// Retrieve the location of the end of this component of the
305 /// nested-name-specifier.
306 SourceLocation getLocalEndLoc() const {
307 return getLocalSourceRange().getEnd();
308 }
309
310 /// Return the prefix of this nested-name-specifier.
311 ///
312 /// For example, if this instance refers to a nested-name-specifier
313 /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
314 /// returned prefix may be empty, if this is the first component of
315 /// the nested-name-specifier.
316 NestedNameSpecifierLoc getPrefix() const {
317 if (!Qualifier)
318 return *this;
319
320 return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
321 }
322
323 /// For a nested-name-specifier that refers to a type,
324 /// retrieve the type with source-location information.
325 TypeLoc getTypeLoc() const;
326
327 /// Determines the data length for the entire
328 /// nested-name-specifier.
329 unsigned getDataLength() const { return getDataLength(Qualifier); }
330
331 friend bool operator==(NestedNameSpecifierLoc X,
332 NestedNameSpecifierLoc Y) {
333 return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
334 }
335
336 friend bool operator!=(NestedNameSpecifierLoc X,
337 NestedNameSpecifierLoc Y) {
338 return !(X == Y);
339 }
340};
341
342/// Class that aids in the construction of nested-name-specifiers along
343/// with source-location information for all of the components of the
344/// nested-name-specifier.
345class NestedNameSpecifierLocBuilder {
346 /// The current representation of the nested-name-specifier we're
347 /// building.
348 NestedNameSpecifier *Representation = nullptr;
349
350 /// Buffer used to store source-location information for the
351 /// nested-name-specifier.
352 ///
353 /// Note that we explicitly manage the buffer (rather than using a
354 /// SmallVector) because \c Declarator expects it to be possible to memcpy()
355 /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
356 char *Buffer = nullptr;
357
358 /// The size of the buffer used to store source-location information
359 /// for the nested-name-specifier.
360 unsigned BufferSize = 0;
361
362 /// The capacity of the buffer used to store source-location
363 /// information for the nested-name-specifier.
364 unsigned BufferCapacity = 0;
365
366public:
367 NestedNameSpecifierLocBuilder() = default;
368 NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
369
370 NestedNameSpecifierLocBuilder &
371 operator=(const NestedNameSpecifierLocBuilder &Other);
372
373 ~NestedNameSpecifierLocBuilder() {
374 if (BufferCapacity)
375 free(Buffer);
376 }
377
378 /// Retrieve the representation of the nested-name-specifier.
379 NestedNameSpecifier *getRepresentation() const { return Representation; }
380
381 /// Extend the current nested-name-specifier by another
382 /// nested-name-specifier component of the form 'type::'.
383 ///
384 /// \param Context The AST context in which this nested-name-specifier
385 /// resides.
386 ///
387 /// \param TemplateKWLoc The location of the 'template' keyword, if present.
388 ///
389 /// \param TL The TypeLoc that describes the type preceding the '::'.
390 ///
391 /// \param ColonColonLoc The location of the trailing '::'.
392 void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
393 SourceLocation ColonColonLoc);
394
395 /// Extend the current nested-name-specifier by another
396 /// nested-name-specifier component of the form 'identifier::'.
397 ///
398 /// \param Context The AST context in which this nested-name-specifier
399 /// resides.
400 ///
401 /// \param Identifier The identifier.
402 ///
403 /// \param IdentifierLoc The location of the identifier.
404 ///
405 /// \param ColonColonLoc The location of the trailing '::'.
406 void Extend(ASTContext &Context, IdentifierInfo *Identifier,
407 SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
408
409 /// Extend the current nested-name-specifier by another
410 /// nested-name-specifier component of the form 'namespace::'.
411 ///
412 /// \param Context The AST context in which this nested-name-specifier
413 /// resides.
414 ///
415 /// \param Namespace The namespace.
416 ///
417 /// \param NamespaceLoc The location of the namespace name.
418 ///
419 /// \param ColonColonLoc The location of the trailing '::'.
420 void Extend(ASTContext &Context, NamespaceDecl *Namespace,
421 SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
422
423 /// Extend the current nested-name-specifier by another
424 /// nested-name-specifier component of the form 'namespace-alias::'.
425 ///
426 /// \param Context The AST context in which this nested-name-specifier
427 /// resides.
428 ///
429 /// \param Alias The namespace alias.
430 ///
431 /// \param AliasLoc The location of the namespace alias
432 /// name.
433 ///
434 /// \param ColonColonLoc The location of the trailing '::'.
435 void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
436 SourceLocation AliasLoc, SourceLocation ColonColonLoc);
437
438 /// Turn this (empty) nested-name-specifier into the global
439 /// nested-name-specifier '::'.
440 void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
441
442 /// Turns this (empty) nested-name-specifier into '__super'
443 /// nested-name-specifier.
444 ///
445 /// \param Context The AST context in which this nested-name-specifier
446 /// resides.
447 ///
448 /// \param RD The declaration of the class in which nested-name-specifier
449 /// appeared.
450 ///
451 /// \param SuperLoc The location of the '__super' keyword.
452 /// name.
453 ///
454 /// \param ColonColonLoc The location of the trailing '::'.
455 void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
456 SourceLocation SuperLoc, SourceLocation ColonColonLoc);
457
458 /// Make a new nested-name-specifier from incomplete source-location
459 /// information.
460 ///
461 /// This routine should be used very, very rarely, in cases where we
462 /// need to synthesize a nested-name-specifier. Most code should instead use
463 /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
464 void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
465 SourceRange R);
466
467 /// Adopt an existing nested-name-specifier (with source-range
468 /// information).
469 void Adopt(NestedNameSpecifierLoc Other);
470
471 /// Retrieve the source range covered by this nested-name-specifier.
472 SourceRange getSourceRange() const LLVM_READONLY {
473 return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
474 }
475
476 /// Retrieve a nested-name-specifier with location information,
477 /// copied into the given AST context.
478 ///
479 /// \param Context The context into which this nested-name-specifier will be
480 /// copied.
481 NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
482
483 /// Retrieve a nested-name-specifier with location
484 /// information based on the information in this builder.
485 ///
486 /// This loc will contain references to the builder's internal data and may
487 /// be invalidated by any change to the builder.
488 NestedNameSpecifierLoc getTemporary() const {
489 return NestedNameSpecifierLoc(Representation, Buffer);
490 }
491
492 /// Clear out this builder, and prepare it to build another
493 /// nested-name-specifier with source-location information.
494 void Clear() {
495 Representation = nullptr;
496 BufferSize = 0;
497 }
498
499 /// Retrieve the underlying buffer.
500 ///
501 /// \returns A pair containing a pointer to the buffer of source-location
502 /// data and the size of the source-location data that resides in that
503 /// buffer.
504 std::pair<char *, unsigned> getBuffer() const {
505 return std::make_pair(Buffer, BufferSize);
506 }
507};
508
509/// Insertion operator for diagnostics. This allows sending
510/// NestedNameSpecifiers into a diagnostic with <<.
511inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
512 NestedNameSpecifier *NNS) {
513 DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
514 DiagnosticsEngine::ak_nestednamespec);
515 return DB;
516}
517
518} // namespace clang
519
520#endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
521

Warning: That file was not part of the compilation database. It may have many parsing errors.