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;
2514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregorclass NamespaceAliasDecl;
26ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorclass NamespaceDecl;
27ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorclass IdentifierInfo;
283b4ea54acf01f72f6eb74d96689dda86d950228fDaniel Dunbarstruct PrintingPolicy;
29e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorclass Type;
30dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregorclass TypeLoc;
31e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnerclass LangOptions;
32e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
33ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// \brief Represents a C++ nested name specifier, such as
349c849b03a62fd1864d62c382c916cf9dc17be335James Dennett/// "\::std::vector<int>::".
35e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor///
36ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// C++ nested name specifiers are the prefixes to qualified
37ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// namespaces. For example, "foo::" in "foo::x" is a nested name
38ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// specifier. Nested name specifiers are made up of a sequence of
39ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// specifiers, each of which can be a namespace, type, identifier
4042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie/// (for dependent names), decltype specifier, or the global specifier ('::').
4142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie/// The last two specifiers can only appear at the start of a
4242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie/// nested-namespace-specifier.
43ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorclass NestedNameSpecifier : public llvm::FoldingSetNode {
4414aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
4514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Enumeration describing
4614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  enum StoredSpecifierKind {
4714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredIdentifier = 0,
4814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredNamespaceOrAlias = 1,
4914aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredTypeSpec = 2,
5014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredTypeSpecWithTemplate = 3
5114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  };
5214aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
53ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The nested name specifier that precedes this nested name
54ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
551734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  ///
561734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// The pointer is the nested-name-specifier that precedes this
571734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// one. The integer stores one of the first four values of type
581734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// SpecifierKind.
5914aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
60ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
61ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The last component in the nested name specifier, which
62ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// can be an identifier, a declaration, or a type.
63ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  ///
64ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// When the pointer is NULL, this specifier represents the global
65ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier '::'. Otherwise, the pointer is one of
66ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
671734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// specifier as encoded within the prefix.
681734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  void* Specifier;
69e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
70e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorpublic:
71ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The kind of specifier that completes this nested name
72ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
73ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  enum SpecifierKind {
74ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief An identifier, stored as an IdentifierInfo*.
7514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    Identifier,
7614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    /// \brief A namespace, stored as a NamespaceDecl*.
7714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    Namespace,
7814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
7914aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    NamespaceAlias,
80ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief A type, stored as a Type*.
8114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    TypeSpec,
82ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief A type that was preceded by the 'template' keyword,
83ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// stored as a Type*.
8414aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    TypeSpecWithTemplate,
85ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief The global specifier '::'. There is no stored value.
8614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    Global
87ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  };
88ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
89ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorprivate:
90ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds the global specifier.
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  NestedNameSpecifier()
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
93ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
94ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Copy constructor used internally to clone nested name
95ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifiers.
961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  NestedNameSpecifier(const NestedNameSpecifier &Other)
971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
98ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor      Specifier(Other.Specifier) {
99e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
100e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
101be2fa7ebf01259b63dc52fe46c8d101c18e72269Craig Topper  void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION;
102e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
103ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Either find or insert the given nested name specifier
104ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// mockup in the given context.
1054ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
1061734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor                                           const NestedNameSpecifier &Mockup);
107e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
108ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorpublic:
109ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a specifier combining a prefix and an identifier.
110e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  ///
111ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// The prefix must be dependent, since nested name specifiers
112ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// referencing an identifier are only permitted when the identifier
113ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// cannot be resolved.
1144ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
116ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     IdentifierInfo *II);
117ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
118ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a nested name specifier that names a namespace.
1194ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
1218441fffda14c5d9ac704f24173fcb117d4999a8eDmitri Gribenko                                     const NamespaceDecl *NS);
122ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
12314aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Builds a nested name specifier that names a namespace alias.
12414aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  static NestedNameSpecifier *Create(const ASTContext &Context,
12514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor                                     NestedNameSpecifier *Prefix,
12614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor                                     NamespaceAliasDecl *Alias);
12714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
128ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a nested name specifier that names a type.
1294ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
131f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall                                     bool Template, const Type *T);
132ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
1332700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// \brief Builds a specifier that consists of just an identifier.
1342700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  ///
1352700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// The nested-name-specifier is assumed to be dependent, but has no
1362700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// prefix because the prefix is implied by something outside of the
1372700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
1382700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// type.
1394ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1404ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad                                     IdentifierInfo *II);
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
142ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Returns the nested name specifier representing the global
143ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// scope.
1444ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
145ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
146ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Return the prefix of this nested name specifier.
147e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  ///
148ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// The prefix contains all of the parts of the nested name
149ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier that preced this current specifier. For example, for a
150ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// nested name specifier that represents "foo::bar::", the current
151ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier will contain "bar::" and the prefix will contain
152ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// "foo::".
1531734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
154ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
155ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Determine what kind of nested name specifier is stored.
15614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  SpecifierKind getKind() const;
157e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
158ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the identifier stored in this nested name
159ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
160ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  IdentifierInfo *getAsIdentifier() const {
16114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    if (Prefix.getInt() == StoredIdentifier)
1621734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      return (IdentifierInfo *)Specifier;
163e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
1646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
165e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
167ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the namespace stored in this nested name
168ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
16914aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  NamespaceDecl *getAsNamespace() const;
170e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
17114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Retrieve the namespace alias stored in this nested name
17214aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// specifier.
17314aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  NamespaceAliasDecl *getAsNamespaceAlias() const;
174e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
175ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the type stored in this nested name specifier.
176f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const Type *getAsType() const {
17714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    if (Prefix.getInt() == StoredTypeSpec ||
17814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor        Prefix.getInt() == StoredTypeSpecWithTemplate)
179f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall      return (const Type *)Specifier;
180ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
182ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
183ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
184ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Whether this nested name specifier refers to a dependent
185ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// type or not.
186ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  bool isDependent() const;
187ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
188561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// \brief Whether this nested name specifier involves a template
189561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// parameter.
190561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  bool isInstantiationDependent() const;
191561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
192d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \brief Whether this nested-name-specifier contains an unexpanded
1939c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// parameter pack (for C++11 variadic templates).
194d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  bool containsUnexpandedParameterPack() const;
195d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
196ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Print this nested name specifier to the given output
197ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// stream.
1988cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner  void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
199e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
200ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
2011734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Prefix.getOpaqueValue());
2021734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Specifier);
203e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
204bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor
205d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// \brief Dump the nested name specifier to standard output to aid
206d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// in debugging.
207e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void dump(const LangOptions &LO);
208e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor};
209e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
210c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor/// \brief A C++ nested-name-specifier augmented with source location
211c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor/// information.
212c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregorclass NestedNameSpecifierLoc {
213c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifier *Qualifier;
214c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  void *Data;
215c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
216c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the last component in the
217c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// given nested-name-specifier.
218c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
219c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
220c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the entire
221c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
222c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  static unsigned getDataLength(NestedNameSpecifier *Qualifier);
223c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
224c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregorpublic:
225c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Construct an empty nested-name-specifier.
2266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
227ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
228c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Construct a nested-name-specifier with source location information
229ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// from
230c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
231c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    : Qualifier(Qualifier), Data(Data) { }
232ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
233c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Evalutes true when this nested-name-specifier location is
234c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// non-empty.
2357247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie  LLVM_EXPLICIT operator bool() const { return Qualifier; }
2367247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie
2377247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie  /// \brief Evalutes true when this nested-name-specifier location is
2387247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie  /// empty.
2397247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie  bool hasQualifier() const { return Qualifier; }
240c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
241c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the nested-name-specifier to which this instance
242c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// refers.
243c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifier *getNestedNameSpecifier() const {
244c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    return Qualifier;
245c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  }
246c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
247c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the opaque pointer that refers to source-location data.
248c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  void *getOpaqueData() const { return Data; }
249ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
250c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the source range covering the entirety of this
251c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
252c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
253c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
2549c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// \c \::std::vector<int>::, the returned source range would cover
255c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// from the initial '::' to the last '::'.
256aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY;
257c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
258c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the source range covering just the last part of
259c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// this nested-name-specifier, not including the prefix.
260c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
261c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
2629c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// \c \::std::vector<int>::, the returned source range would cover
263c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// from "vector" to the last '::'.
264dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  SourceRange getLocalSourceRange() const;
265dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
266dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief Retrieve the location of the beginning of this
267dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// nested-name-specifier.
268ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getBeginLoc() const {
269dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    return getSourceRange().getBegin();
270dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
271dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
272dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief Retrieve the location of the end of this
273dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// nested-name-specifier.
274ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getEndLoc() const {
275dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    return getSourceRange().getEnd();
276dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
277c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
278c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// \brief Retrieve the location of the beginning of this
279c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// component of the nested-name-specifier.
280ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getLocalBeginLoc() const {
281c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    return getLocalSourceRange().getBegin();
282c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  }
283ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
284c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// \brief Retrieve the location of the end of this component of the
285c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// nested-name-specifier.
286ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getLocalEndLoc() const {
287c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    return getLocalSourceRange().getEnd();
288c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  }
289c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor
290c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Return the prefix of this nested-name-specifier.
291c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
292c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
2939c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
294c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// returned prefix may be empty, if this is the first component of
295c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// the nested-name-specifier.
296c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifierLoc getPrefix() const {
297c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    if (!Qualifier)
298c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor      return *this;
299c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
300c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
301c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  }
302dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
303dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief For a nested-name-specifier that refers to a type,
304dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// retrieve the type with source-location information.
305dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  TypeLoc getTypeLoc() const;
306dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
307c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the entire
308c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
309c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  unsigned getDataLength() const { return getDataLength(Qualifier); }
310ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
311ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  friend bool operator==(NestedNameSpecifierLoc X,
31200cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor                         NestedNameSpecifierLoc Y) {
31300cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor    return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
31400cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  }
31500cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor
316ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  friend bool operator!=(NestedNameSpecifierLoc X,
31700cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor                         NestedNameSpecifierLoc Y) {
31800cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor    return !(X == Y);
31900cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  }
320c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor};
321c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
3225f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// \brief Class that aids in the construction of nested-name-specifiers along
3235f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// with source-location information for all of the components of the
3245f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// nested-name-specifier.
3255f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregorclass NestedNameSpecifierLocBuilder {
326ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief The current representation of the nested-name-specifier we're
3275f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// building.
3285f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifier *Representation;
329ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3305f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Buffer used to store source-location information for the
3315f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier.
3325f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
333ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// Note that we explicitly manage the buffer (rather than using a
3345f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// SmallVector) because \c Declarator expects it to be possible to memcpy()
3355f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
3365f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  char *Buffer;
337ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3385f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief The size of the buffer used to store source-location information
3395f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// for the nested-name-specifier.
3405f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  unsigned BufferSize;
341ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
342ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief The capacity of the buffer used to store source-location
3435f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information for the nested-name-specifier.
3445f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  unsigned BufferCapacity;
3455f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3465f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregorpublic:
34742f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar  NestedNameSpecifierLocBuilder()
3486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : Representation(nullptr), Buffer(nullptr), BufferSize(0),
3496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      BufferCapacity(0) {}
350ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3515f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
352ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3535f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLocBuilder &
3545f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  operator=(const NestedNameSpecifierLocBuilder &Other);
355ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
35642f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar  ~NestedNameSpecifierLocBuilder() {
35742f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar    if (BufferCapacity)
35842f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar      free(Buffer);
35942f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar  }
360ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3615f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the representation of the nested-name-specifier.
3625f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifier *getRepresentation() const { return Representation; }
363ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3645f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Extend the current nested-name-specifier by another
3655f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'type::'.
3665f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3675f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3685f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3695f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3705f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param TemplateKWLoc The location of the 'template' keyword, if present.
3715f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3725f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param TL The TypeLoc that describes the type preceding the '::'.
3735f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3745f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
3755f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
3765f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation ColonColonLoc);
377ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
378ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Extend the current nested-name-specifier by another
3795f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'identifier::'.
3805f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3815f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3825f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3835f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3845f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Identifier The identifier.
3855f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3865f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param IdentifierLoc The location of the identifier.
3875f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3885f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
3895f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, IdentifierInfo *Identifier,
3905f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
391ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
392ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Extend the current nested-name-specifier by another
3935f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'namespace::'.
3945f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3955f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3965f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3975f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3985f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Namespace The namespace.
3995f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4005f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param NamespaceLoc The location of the namespace name.
4015f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4025f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
4035f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, NamespaceDecl *Namespace,
4045f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation NamespaceLoc, 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-alias::'.
4085f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4095f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
4105f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
4115f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4125f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Alias The namespace alias.
4135f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
414ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \param AliasLoc The location of the namespace alias
4155f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// name.
4165f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4175f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
4185f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
4195f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation AliasLoc, SourceLocation ColonColonLoc);
420ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4215f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Turn this (empty) nested-name-specifier into the global
4225f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier '::'.
4235f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
424ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4255f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Make a new nested-name-specifier from incomplete source-location
4265f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information.
4275f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4285f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// This routine should be used very, very rarely, in cases where we
4295f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// need to synthesize a nested-name-specifier. Most code should instead use
4305f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
431ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
4325f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor                   SourceRange R);
433ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
434ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Adopt an existing nested-name-specifier (with source-range
4355f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information).
4365f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Adopt(NestedNameSpecifierLoc Other);
437ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4385f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the source range covered by this nested-name-specifier.
439aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY {
4405f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
4415f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
442ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4435f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve a nested-name-specifier with location information,
4445f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// copied into the given AST context.
4455f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4465f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The context into which this nested-name-specifier will be
4475f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// copied.
4485f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
4495f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
4509dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  /// \brief Retrieve a nested-name-specifier with location
4519c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// information based on the information in this builder.
4529c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  ///
4539c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// This loc will contain references to the builder's internal data and may
4549dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  /// be invalidated by any change to the builder.
4559dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  NestedNameSpecifierLoc getTemporary() const {
4569dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall    return NestedNameSpecifierLoc(Representation, Buffer);
4579dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  }
4589dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall
4595f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Clear out this builder, and prepare it to build another
4605f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier with source-location information.
4615f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Clear() {
4626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Representation = nullptr;
4635f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    BufferSize = 0;
4645f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
465ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4665f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the underlying buffer.
4675f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4685f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \returns A pair containing a pointer to the buffer of source-location
4695f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// data and the size of the source-location data that resides in that
4705f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// buffer.
4715f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  std::pair<char *, unsigned> getBuffer() const {
4725f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    return std::make_pair(Buffer, BufferSize);
4735f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
4745f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor};
475ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
476ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// Insertion operator for diagnostics.  This allows sending
477ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// NestedNameSpecifiers into a diagnostic with <<.
478d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramerinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
479d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer                                           NestedNameSpecifier *NNS) {
480d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer  DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
481d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer                  DiagnosticsEngine::ak_nestednamespec);
482d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer  return DB;
483d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer}
4841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
485e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor}
486e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
487e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#endif
488