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