1e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===//
2e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//
3e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//                     The LLVM Compiler Infrastructure
4e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//
5e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor// This file is distributed under the University of Illinois Open Source
6e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor// License. See LICENSE.TXT for details.
7e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//
8e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//===----------------------------------------------------------------------===//
9e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//
10e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//  This file defines the NestedNameSpecifier class, which represents
11e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//  a C++ nested-name-specifier.
12e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//
13e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//===----------------------------------------------------------------------===//
14e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
15e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
16e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
17d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer#include "clang/Basic/Diagnostic.h"
18ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor#include "llvm/ADT/FoldingSet.h"
19ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor#include "llvm/ADT/PointerIntPair.h"
20aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar#include "llvm/Support/Compiler.h"
21e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
22e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregornamespace clang {
23e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
24e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorclass ASTContext;
25176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass CXXRecordDecl;
2614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregorclass NamespaceAliasDecl;
27ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorclass NamespaceDecl;
28ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorclass IdentifierInfo;
293b4ea54acf01f72f6eb74d96689dda86d950228fDaniel Dunbarstruct PrintingPolicy;
30e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorclass Type;
31dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregorclass TypeLoc;
32e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnerclass LangOptions;
33e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
34ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// \brief Represents a C++ nested name specifier, such as
359c849b03a62fd1864d62c382c916cf9dc17be335James Dennett/// "\::std::vector<int>::".
36e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor///
37ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// C++ nested name specifiers are the prefixes to qualified
38ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// namespaces. For example, "foo::" in "foo::x" is a nested name
39ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// specifier. Nested name specifiers are made up of a sequence of
40ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// specifiers, each of which can be a namespace, type, identifier
4142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie/// (for dependent names), decltype specifier, or the global specifier ('::').
4242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie/// The last two specifiers can only appear at the start of a
4342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie/// nested-namespace-specifier.
44ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorclass NestedNameSpecifier : public llvm::FoldingSetNode {
4514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
4614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Enumeration describing
4714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  enum StoredSpecifierKind {
4814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredIdentifier = 0,
49176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    StoredDecl = 1,
5014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredTypeSpec = 2,
5114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredTypeSpecWithTemplate = 3
5214aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  };
5314aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
54ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The nested name specifier that precedes this nested name
55ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
561734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  ///
571734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// The pointer is the nested-name-specifier that precedes this
581734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// one. The integer stores one of the first four values of type
591734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// SpecifierKind.
6014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
61ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
62ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The last component in the nested name specifier, which
63ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// can be an identifier, a declaration, or a type.
64ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  ///
65ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// When the pointer is NULL, this specifier represents the global
66ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier '::'. Otherwise, the pointer is one of
67ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
681734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// specifier as encoded within the prefix.
691734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  void* Specifier;
70e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
71e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorpublic:
72ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The kind of specifier that completes this nested name
73ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
74ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  enum SpecifierKind {
75ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief An identifier, stored as an IdentifierInfo*.
7614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    Identifier,
7714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    /// \brief A namespace, stored as a NamespaceDecl*.
7814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    Namespace,
7914aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
8014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    NamespaceAlias,
81ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief A type, stored as a Type*.
8214aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    TypeSpec,
83ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief A type that was preceded by the 'template' keyword,
84ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// stored as a Type*.
8514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    TypeSpecWithTemplate,
86ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief The global specifier '::'. There is no stored value.
87176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Global,
88176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    /// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
89176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    /// the class it appeared in.
90176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Super
91ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  };
92ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
93ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorprivate:
94ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds the global specifier.
956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  NestedNameSpecifier()
966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
97ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
98ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Copy constructor used internally to clone nested name
99ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifiers.
1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  NestedNameSpecifier(const NestedNameSpecifier &Other)
1011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
102ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor      Specifier(Other.Specifier) {
103e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
104e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void operator=(const NestedNameSpecifier &) = delete;
106e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
107ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Either find or insert the given nested name specifier
108ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// mockup in the given context.
1094ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
1101734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor                                           const NestedNameSpecifier &Mockup);
111e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
112ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorpublic:
113ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a specifier combining a prefix and an identifier.
114e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  ///
115ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// The prefix must be dependent, since nested name specifiers
116ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// referencing an identifier are only permitted when the identifier
117ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// cannot be resolved.
1184ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
120ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     IdentifierInfo *II);
121ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
122ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a nested name specifier that names a namespace.
1234ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
1258441fffda14c5d9ac704f24173fcb117d4999a8eDmitri Gribenko                                     const NamespaceDecl *NS);
126ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
12714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Builds a nested name specifier that names a namespace alias.
12814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  static NestedNameSpecifier *Create(const ASTContext &Context,
12914aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor                                     NestedNameSpecifier *Prefix,
13014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor                                     NamespaceAliasDecl *Alias);
13114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
132ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a nested name specifier that names a type.
1334ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
135f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall                                     bool Template, const Type *T);
136ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
1372700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// \brief Builds a specifier that consists of just an identifier.
1382700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  ///
1392700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// The nested-name-specifier is assumed to be dependent, but has no
1402700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// prefix because the prefix is implied by something outside of the
1412700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
1422700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// type.
1434ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1444ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad                                     IdentifierInfo *II);
1451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
146ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Returns the nested name specifier representing the global
147ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// scope.
1484ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
149ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
150176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \brief Returns the nested name specifier representing the __super scope
151176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// for the given CXXRecordDecl.
152176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
153176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                             CXXRecordDecl *RD);
154176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
155ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Return the prefix of this nested name specifier.
156e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  ///
157ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// The prefix contains all of the parts of the nested name
158ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier that preced this current specifier. For example, for a
159ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// nested name specifier that represents "foo::bar::", the current
160ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier will contain "bar::" and the prefix will contain
161ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// "foo::".
1621734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
163ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
164ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Determine what kind of nested name specifier is stored.
16514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  SpecifierKind getKind() const;
166e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
167ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the identifier stored in this nested name
168ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
169ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  IdentifierInfo *getAsIdentifier() const {
17014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    if (Prefix.getInt() == StoredIdentifier)
1711734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      return (IdentifierInfo *)Specifier;
172e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
174e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
176ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the namespace stored in this nested name
177ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
17814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  NamespaceDecl *getAsNamespace() const;
179e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
18014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Retrieve the namespace alias stored in this nested name
18114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// specifier.
18214aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  NamespaceAliasDecl *getAsNamespaceAlias() const;
183e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
184176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \brief Retrieve the record declaration stored in this nested name
185176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// specifier.
186176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CXXRecordDecl *getAsRecordDecl() const;
187176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
188ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the type stored in this nested name specifier.
189f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const Type *getAsType() const {
19014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    if (Prefix.getInt() == StoredTypeSpec ||
19114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor        Prefix.getInt() == StoredTypeSpecWithTemplate)
192f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall      return (const Type *)Specifier;
193ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
1946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
195ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
196ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
197ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Whether this nested name specifier refers to a dependent
198ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// type or not.
199ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  bool isDependent() const;
200ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
201561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// \brief Whether this nested name specifier involves a template
202561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// parameter.
203561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  bool isInstantiationDependent() const;
204561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
205d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \brief Whether this nested-name-specifier contains an unexpanded
2069c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// parameter pack (for C++11 variadic templates).
207d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  bool containsUnexpandedParameterPack() const;
208d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
209ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Print this nested name specifier to the given output
210ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// stream.
2118cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner  void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
212e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
213ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
2141734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Prefix.getOpaqueValue());
2151734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Specifier);
216e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
217bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor
218d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// \brief Dump the nested name specifier to standard output to aid
219d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// in debugging.
2204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void dump(const LangOptions &LO) const;
2214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void dump() const;
222e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor};
223e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
224c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor/// \brief A C++ nested-name-specifier augmented with source location
225c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor/// information.
226c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregorclass NestedNameSpecifierLoc {
227c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifier *Qualifier;
228c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  void *Data;
229c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
230c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the last component in the
231c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// given nested-name-specifier.
232c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
233c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
234c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the entire
235c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
236c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  static unsigned getDataLength(NestedNameSpecifier *Qualifier);
237c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
238c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregorpublic:
239c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Construct an empty nested-name-specifier.
2406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
241ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
242c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Construct a nested-name-specifier with source location information
243ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// from
244c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
245c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    : Qualifier(Qualifier), Data(Data) { }
246ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
247c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Evalutes true when this nested-name-specifier location is
248c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// non-empty.
2490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  explicit operator bool() const { return Qualifier; }
2507247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie
2517247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie  /// \brief Evalutes true when this nested-name-specifier location is
2527247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie  /// empty.
2537247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie  bool hasQualifier() const { return Qualifier; }
254c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
255c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the nested-name-specifier to which this instance
256c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// refers.
257c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifier *getNestedNameSpecifier() const {
258c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    return Qualifier;
259c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  }
260c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
261c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the opaque pointer that refers to source-location data.
262c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  void *getOpaqueData() const { return Data; }
263ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
264c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the source range covering the entirety of this
265c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
266c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
267c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
2689c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// \c \::std::vector<int>::, the returned source range would cover
269c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// from the initial '::' to the last '::'.
270aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY;
271c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
272c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the source range covering just the last part of
273c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// this nested-name-specifier, not including the prefix.
274c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
275c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
2769c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// \c \::std::vector<int>::, the returned source range would cover
277c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// from "vector" to the last '::'.
278dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  SourceRange getLocalSourceRange() const;
279dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
280dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief Retrieve the location of the beginning of this
281dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// nested-name-specifier.
282ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getBeginLoc() const {
283dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    return getSourceRange().getBegin();
284dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
285dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
286dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief Retrieve the location of the end of this
287dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// nested-name-specifier.
288ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getEndLoc() const {
289dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    return getSourceRange().getEnd();
290dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
291c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
292c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// \brief Retrieve the location of the beginning of this
293c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// component of the nested-name-specifier.
294ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getLocalBeginLoc() const {
295c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    return getLocalSourceRange().getBegin();
296c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  }
297ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
298c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// \brief Retrieve the location of the end of this component of the
299c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// nested-name-specifier.
300ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getLocalEndLoc() const {
301c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    return getLocalSourceRange().getEnd();
302c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  }
303c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor
304c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Return the prefix of this nested-name-specifier.
305c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
306c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
3079c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
308c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// returned prefix may be empty, if this is the first component of
309c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// the nested-name-specifier.
310c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifierLoc getPrefix() const {
311c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    if (!Qualifier)
312c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor      return *this;
313c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
314c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
315c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  }
316dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
317dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief For a nested-name-specifier that refers to a type,
318dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// retrieve the type with source-location information.
319dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  TypeLoc getTypeLoc() const;
320dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
321c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the entire
322c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
323c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  unsigned getDataLength() const { return getDataLength(Qualifier); }
324ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
325ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  friend bool operator==(NestedNameSpecifierLoc X,
32600cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor                         NestedNameSpecifierLoc Y) {
32700cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor    return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
32800cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  }
32900cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor
330ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  friend bool operator!=(NestedNameSpecifierLoc X,
33100cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor                         NestedNameSpecifierLoc Y) {
33200cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor    return !(X == Y);
33300cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  }
334c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor};
335c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
3365f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// \brief Class that aids in the construction of nested-name-specifiers along
3375f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// with source-location information for all of the components of the
3385f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// nested-name-specifier.
3395f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregorclass NestedNameSpecifierLocBuilder {
340ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief The current representation of the nested-name-specifier we're
3415f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// building.
3425f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifier *Representation;
343ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3445f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Buffer used to store source-location information for the
3455f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier.
3465f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
347ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// Note that we explicitly manage the buffer (rather than using a
3485f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// SmallVector) because \c Declarator expects it to be possible to memcpy()
3495f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
3505f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  char *Buffer;
351ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3525f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief The size of the buffer used to store source-location information
3535f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// for the nested-name-specifier.
3545f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  unsigned BufferSize;
355ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
356ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief The capacity of the buffer used to store source-location
3575f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information for the nested-name-specifier.
3585f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  unsigned BufferCapacity;
3595f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3605f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregorpublic:
36142f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar  NestedNameSpecifierLocBuilder()
3626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : Representation(nullptr), Buffer(nullptr), BufferSize(0),
3636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      BufferCapacity(0) {}
364ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3655f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
366ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3675f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLocBuilder &
3685f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  operator=(const NestedNameSpecifierLocBuilder &Other);
369ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
37042f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar  ~NestedNameSpecifierLocBuilder() {
37142f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar    if (BufferCapacity)
37242f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar      free(Buffer);
37342f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar  }
374ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3755f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the representation of the nested-name-specifier.
3765f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifier *getRepresentation() const { return Representation; }
377ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3785f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Extend the current nested-name-specifier by another
3795f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'type::'.
3805f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3815f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3825f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3835f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3845f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param TemplateKWLoc The location of the 'template' keyword, if present.
3855f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3865f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param TL The TypeLoc that describes the type preceding the '::'.
3875f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3885f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
3895f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
3905f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation ColonColonLoc);
391ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
392ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Extend the current nested-name-specifier by another
3935f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'identifier::'.
3945f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3955f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3965f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3975f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3985f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Identifier The identifier.
3995f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4005f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param IdentifierLoc The location of the identifier.
4015f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4025f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
4035f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, IdentifierInfo *Identifier,
4045f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
405ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
406ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Extend the current nested-name-specifier by another
4075f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'namespace::'.
4085f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4095f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
4105f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
4115f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4125f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Namespace The namespace.
4135f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4145f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param NamespaceLoc The location of the namespace name.
4155f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4165f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
4175f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, NamespaceDecl *Namespace,
4185f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
419ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
420ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Extend the current nested-name-specifier by another
4215f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'namespace-alias::'.
4225f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4235f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
4245f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
4255f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4265f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Alias The namespace alias.
4275f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
428ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \param AliasLoc The location of the namespace alias
4295f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// name.
4305f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4315f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
4325f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
4335f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation AliasLoc, SourceLocation ColonColonLoc);
434ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4355f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Turn this (empty) nested-name-specifier into the global
4365f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier '::'.
4375f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
438176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
439176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \brief Turns this (empty) nested-name-specifier into '__super'
440176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// nested-name-specifier.
441176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ///
442176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \param Context The AST context in which this nested-name-specifier
443176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// resides.
444176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ///
445176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \param RD The declaration of the class in which nested-name-specifier
446176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// appeared.
447176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ///
448176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \param SuperLoc The location of the '__super' keyword.
449176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// name.
450176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ///
451176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \param ColonColonLoc The location of the trailing '::'.
452176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
453176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                 SourceLocation SuperLoc, SourceLocation ColonColonLoc);
4545f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Make a new nested-name-specifier from incomplete source-location
4555f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information.
4565f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4575f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// This routine should be used very, very rarely, in cases where we
4585f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// need to synthesize a nested-name-specifier. Most code should instead use
4595f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
460ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
4615f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor                   SourceRange R);
462ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
463ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Adopt an existing nested-name-specifier (with source-range
4645f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information).
4655f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Adopt(NestedNameSpecifierLoc Other);
466ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4675f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the source range covered by this nested-name-specifier.
468aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY {
4695f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
4705f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
471ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4725f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve a nested-name-specifier with location information,
4735f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// copied into the given AST context.
4745f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4755f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The context into which this nested-name-specifier will be
4765f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// copied.
4775f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
4785f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
4799dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  /// \brief Retrieve a nested-name-specifier with location
4809c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// information based on the information in this builder.
4819c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  ///
4829c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// This loc will contain references to the builder's internal data and may
4839dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  /// be invalidated by any change to the builder.
4849dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  NestedNameSpecifierLoc getTemporary() const {
4859dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall    return NestedNameSpecifierLoc(Representation, Buffer);
4869dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  }
4879dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall
4885f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Clear out this builder, and prepare it to build another
4895f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier with source-location information.
4905f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Clear() {
4916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Representation = nullptr;
4925f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    BufferSize = 0;
4935f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
494ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4955f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the underlying buffer.
4965f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4975f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \returns A pair containing a pointer to the buffer of source-location
4985f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// data and the size of the source-location data that resides in that
4995f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// buffer.
5005f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  std::pair<char *, unsigned> getBuffer() const {
5015f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    return std::make_pair(Buffer, BufferSize);
5025f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
5035f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor};
504ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
505ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// Insertion operator for diagnostics.  This allows sending
506ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// NestedNameSpecifiers into a diagnostic with <<.
507d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramerinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
508d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer                                           NestedNameSpecifier *NNS) {
509d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer  DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
510d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer                  DiagnosticsEngine::ak_nestednamespec);
511d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer  return DB;
512d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer}
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
514e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor}
515e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
516e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#endif
517