NestedNameSpecifier.h revision 9dc71d2fddcd283e07d45f3894c8559e2f7dd9a7
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
17dacd434c49658286c380c7b4c357d76d53cb4aa1Douglas Gregor#include "clang/Basic/Diagnostic.h"
18ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor#include "llvm/ADT/FoldingSet.h"
19ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor#include "llvm/ADT/PointerIntPair.h"
20e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
21bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregornamespace llvm {
22bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor  class raw_ostream;
23bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor}
24bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor
25e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregornamespace clang {
26e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
27e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorclass ASTContext;
2814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregorclass NamespaceAliasDecl;
29ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorclass NamespaceDecl;
30ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorclass IdentifierInfo;
313b4ea54acf01f72f6eb74d96689dda86d950228fDaniel Dunbarstruct PrintingPolicy;
32e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorclass Type;
33dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregorclass TypeLoc;
34e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnerclass LangOptions;
35e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
36ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// \brief Represents a C++ nested name specifier, such as
37ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// "::std::vector<int>::".
38e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor///
39ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// C++ nested name specifiers are the prefixes to qualified
40ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// namespaces. For example, "foo::" in "foo::x" is a nested name
41ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// specifier. Nested name specifiers are made up of a sequence of
42ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// specifiers, each of which can be a namespace, type, identifier
43ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// (for dependent names), or the global specifier ('::', must be the
44ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// first specifier).
45ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorclass NestedNameSpecifier : public llvm::FoldingSetNode {
4614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
4714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Enumeration describing
4814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  enum StoredSpecifierKind {
4914aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredIdentifier = 0,
5014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredNamespaceOrAlias = 1,
5114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredTypeSpec = 2,
5214aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    StoredTypeSpecWithTemplate = 3
5314aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  };
5414aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
55ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The nested name specifier that precedes this nested name
56ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
571734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  ///
581734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// The pointer is the nested-name-specifier that precedes this
591734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// one. The integer stores one of the first four values of type
601734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// SpecifierKind.
6114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
62ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
63ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The last component in the nested name specifier, which
64ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// can be an identifier, a declaration, or a type.
65ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  ///
66ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// When the pointer is NULL, this specifier represents the global
67ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier '::'. Otherwise, the pointer is one of
68ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
691734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// specifier as encoded within the prefix.
701734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  void* Specifier;
71e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
72e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorpublic:
73ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The kind of specifier that completes this nested name
74ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
75ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  enum SpecifierKind {
76ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief An identifier, stored as an IdentifierInfo*.
7714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    Identifier,
7814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    /// \brief A namespace, stored as a NamespaceDecl*.
7914aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    Namespace,
8014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
8114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    NamespaceAlias,
82ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief A type, stored as a Type*.
8314aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    TypeSpec,
84ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief A type that was preceded by the 'template' keyword,
85ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// stored as a Type*.
8614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    TypeSpecWithTemplate,
87ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief The global specifier '::'. There is no stored value.
8814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    Global
89ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  };
90ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
91ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorprivate:
92ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds the global specifier.
9314aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  NestedNameSpecifier() : Prefix(0, StoredIdentifier), Specifier(0) { }
94ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
95ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Copy constructor used internally to clone nested name
96ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifiers.
971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  NestedNameSpecifier(const NestedNameSpecifier &Other)
981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
99ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor      Specifier(Other.Specifier) {
100e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
101e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
102ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  NestedNameSpecifier &operator=(const NestedNameSpecifier &); // do not implement
103e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
104ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Either find or insert the given nested name specifier
105ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// mockup in the given context.
1064ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
1071734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor                                           const NestedNameSpecifier &Mockup);
108e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
109ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorpublic:
110ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a specifier combining a prefix and an identifier.
111e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  ///
112ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// The prefix must be dependent, since nested name specifiers
113ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// referencing an identifier are only permitted when the identifier
114ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// cannot be resolved.
1154ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
117ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     IdentifierInfo *II);
118ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
119ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a nested name specifier that names a namespace.
1204ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
122ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     NamespaceDecl *NS);
123ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
12414aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Builds a nested name specifier that names a namespace alias.
12514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  static NestedNameSpecifier *Create(const ASTContext &Context,
12614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor                                     NestedNameSpecifier *Prefix,
12714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor                                     NamespaceAliasDecl *Alias);
12814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
129ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a nested name specifier that names a type.
1304ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
132f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall                                     bool Template, const Type *T);
133ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
1342700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// \brief Builds a specifier that consists of just an identifier.
1352700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  ///
1362700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// The nested-name-specifier is assumed to be dependent, but has no
1372700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// prefix because the prefix is implied by something outside of the
1382700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
1392700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// type.
1404ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1414ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad                                     IdentifierInfo *II);
1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
143ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Returns the nested name specifier representing the global
144ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// scope.
1454ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
146ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
147ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Return the prefix of this nested name specifier.
148e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  ///
149ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// The prefix contains all of the parts of the nested name
150ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier that preced this current specifier. For example, for a
151ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// nested name specifier that represents "foo::bar::", the current
152ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier will contain "bar::" and the prefix will contain
153ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// "foo::".
1541734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
155ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
156ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Determine what kind of nested name specifier is stored.
15714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  SpecifierKind getKind() const;
158e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
159ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the identifier stored in this nested name
160ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
161ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  IdentifierInfo *getAsIdentifier() const {
16214aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    if (Prefix.getInt() == StoredIdentifier)
1631734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      return (IdentifierInfo *)Specifier;
164e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
165e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor    return 0;
166e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
168ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the namespace stored in this nested name
169ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
17014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  NamespaceDecl *getAsNamespace() const;
171e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
17214aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Retrieve the namespace alias stored in this nested name
17314aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// specifier.
17414aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  NamespaceAliasDecl *getAsNamespaceAlias() const;
175e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
176ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the type stored in this nested name specifier.
177f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const Type *getAsType() const {
17814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    if (Prefix.getInt() == StoredTypeSpec ||
17914aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor        Prefix.getInt() == StoredTypeSpecWithTemplate)
180f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall      return (const Type *)Specifier;
181ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
182ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    return 0;
183ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
184ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
185ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Whether this nested name specifier refers to a dependent
186ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// type or not.
187ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  bool isDependent() const;
188ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
189561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// \brief Whether this nested name specifier involves a template
190561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// parameter.
191561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  bool isInstantiationDependent() const;
192561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
193d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \brief Whether this nested-name-specifier contains an unexpanded
194d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// parameter pack (for C++0x variadic templates).
195d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  bool containsUnexpandedParameterPack() const;
196d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
197ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Print this nested name specifier to the given output
198ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// stream.
199d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
200e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
201ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
2021734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Prefix.getOpaqueValue());
2031734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Specifier);
204e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
205bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor
206d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// \brief Dump the nested name specifier to standard output to aid
207d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// in debugging.
208e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void dump(const LangOptions &LO);
209e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor};
210e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
211c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor/// \brief A C++ nested-name-specifier augmented with source location
212c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor/// information.
213c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregorclass NestedNameSpecifierLoc {
214c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifier *Qualifier;
215c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  void *Data;
216c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
217c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the last component in the
218c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// given nested-name-specifier.
219c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
220c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
221c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the entire
222c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
223c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  static unsigned getDataLength(NestedNameSpecifier *Qualifier);
224c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
225c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregorpublic:
226c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Construct an empty nested-name-specifier.
227c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifierLoc() : Qualifier(0), Data(0) { }
228c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
229c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Construct a nested-name-specifier with source location information
230c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// from
231c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
232c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    : Qualifier(Qualifier), Data(Data) { }
233c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
234c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Evalutes true when this nested-name-specifier location is
235c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// non-empty.
236c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  operator bool() const { return Qualifier; }
237c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
238c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the nested-name-specifier to which this instance
239c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// refers.
240c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifier *getNestedNameSpecifier() const {
241c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    return Qualifier;
242c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  }
243c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
244c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the opaque pointer that refers to source-location data.
245c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  void *getOpaqueData() const { return Data; }
246c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
247c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the source range covering the entirety of this
248c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
249c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
250c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
251c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \c ::std::vector<int>::, the returned source range would cover
252c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// from the initial '::' to the last '::'.
253dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  SourceRange getSourceRange() const;
254c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
255c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the source range covering just the last part of
256c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// this nested-name-specifier, not including the prefix.
257c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
258c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
259c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \c ::std::vector<int>::, the returned source range would cover
260c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// from "vector" to the last '::'.
261dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  SourceRange getLocalSourceRange() const;
262dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
263dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief Retrieve the location of the beginning of this
264dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// nested-name-specifier.
265dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  SourceLocation getBeginLoc() const {
266dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    return getSourceRange().getBegin();
267dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
268dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
269dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief Retrieve the location of the end of this
270dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// nested-name-specifier.
271dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  SourceLocation getEndLoc() const {
272dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    return getSourceRange().getEnd();
273dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
274c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
275c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// \brief Retrieve the location of the beginning of this
276c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// component of the nested-name-specifier.
277c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  SourceLocation getLocalBeginLoc() const {
278c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    return getLocalSourceRange().getBegin();
279c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  }
280c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor
281c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// \brief Retrieve the location of the end of this component of the
282c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// nested-name-specifier.
283c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  SourceLocation getLocalEndLoc() const {
284c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    return getLocalSourceRange().getEnd();
285c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  }
286c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor
287c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Return the prefix of this nested-name-specifier.
288c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
289c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
290c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \c ::std::vector<int>::, the prefix is \c ::std::. Note that the
291c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// returned prefix may be empty, if this is the first component of
292c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// the nested-name-specifier.
293c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifierLoc getPrefix() const {
294c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    if (!Qualifier)
295c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor      return *this;
296c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
297c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
298c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  }
299dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
300dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief For a nested-name-specifier that refers to a type,
301dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// retrieve the type with source-location information.
302dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  TypeLoc getTypeLoc() const;
303dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
304c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the entire
305c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
306c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  unsigned getDataLength() const { return getDataLength(Qualifier); }
30700cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor
30800cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  friend bool operator==(NestedNameSpecifierLoc X,
30900cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor                         NestedNameSpecifierLoc Y) {
31000cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor    return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
31100cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  }
31200cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor
31300cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  friend bool operator!=(NestedNameSpecifierLoc X,
31400cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor                         NestedNameSpecifierLoc Y) {
31500cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor    return !(X == Y);
31600cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  }
317c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor};
318c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
3195f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// \brief Class that aids in the construction of nested-name-specifiers along
3205f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// with source-location information for all of the components of the
3215f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// nested-name-specifier.
3225f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregorclass NestedNameSpecifierLocBuilder {
3235f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief The current representation of the nested-name-specifier we're
3245f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// building.
3255f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifier *Representation;
3265f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3275f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Buffer used to store source-location information for the
3285f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier.
3295f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3305f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// Note that we explicitly manage the buffer (rather than using a
3315f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// SmallVector) because \c Declarator expects it to be possible to memcpy()
3325f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
3335f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  char *Buffer;
3345f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3355f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief The size of the buffer used to store source-location information
3365f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// for the nested-name-specifier.
3375f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  unsigned BufferSize;
3385f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3395f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief The capacity of the buffer used to store source-location
3405f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information for the nested-name-specifier.
3415f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  unsigned BufferCapacity;
3425f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3435f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregorpublic:
3445f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLocBuilder();
3455f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3465f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
3475f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3485f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLocBuilder &
3495f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  operator=(const NestedNameSpecifierLocBuilder &Other);
3505f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3515f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ~NestedNameSpecifierLocBuilder();
3525f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3535f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the representation of the nested-name-specifier.
3545f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifier *getRepresentation() const { return Representation; }
3555f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3565f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Extend the current nested-name-specifier by another
3575f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'type::'.
3585f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3595f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3605f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3615f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3625f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param TemplateKWLoc The location of the 'template' keyword, if present.
3635f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3645f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param TL The TypeLoc that describes the type preceding the '::'.
3655f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3665f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
3675f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
3685f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation ColonColonLoc);
3695f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3705f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Extend the current nested-name-specifier by another
3715f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'identifier::'.
3725f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3735f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3745f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3755f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3765f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Identifier The identifier.
3775f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3785f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param IdentifierLoc The location of the identifier.
3795f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3805f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
3815f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, IdentifierInfo *Identifier,
3825f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
3835f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3845f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Extend the current nested-name-specifier by another
3855f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'namespace::'.
3865f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3875f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3885f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3895f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3905f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Namespace The namespace.
3915f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3925f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param NamespaceLoc The location of the namespace name.
3935f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3945f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
3955f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, NamespaceDecl *Namespace,
3965f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
3975f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3985f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Extend the current nested-name-specifier by another
3995f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'namespace-alias::'.
4005f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4015f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
4025f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
4035f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4045f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Alias The namespace alias.
4055f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4065f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param AliasLoc The location of the namespace alias
4075f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// name.
4085f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4095f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
4105f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
4115f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation AliasLoc, SourceLocation ColonColonLoc);
4125f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
4135f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Turn this (empty) nested-name-specifier into the global
4145f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier '::'.
4155f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
4165f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
4175f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Make a new nested-name-specifier from incomplete source-location
4185f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information.
4195f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4205f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// This routine should be used very, very rarely, in cases where we
4215f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// need to synthesize a nested-name-specifier. Most code should instead use
4225f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
4235f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
4245f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor                   SourceRange R);
4255f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
4265f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Adopt an existing nested-name-specifier (with source-range
4275f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information).
4285f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Adopt(NestedNameSpecifierLoc Other);
4295f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
4305f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the source range covered by this nested-name-specifier.
4315f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  SourceRange getSourceRange() const {
4325f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
4335f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
4345f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
4355f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve a nested-name-specifier with location information,
4365f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// copied into the given AST context.
4375f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4385f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The context into which this nested-name-specifier will be
4395f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// copied.
4405f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
4415f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
4429dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  /// \brief Retrieve a nested-name-specifier with location
4439dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  /// information based on the information in this builder.  This loc
4449dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  /// will contain references to the builder's internal data and may
4459dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  /// be invalidated by any change to the builder.
4469dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  NestedNameSpecifierLoc getTemporary() const {
4479dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall    return NestedNameSpecifierLoc(Representation, Buffer);
4489dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  }
4499dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall
4505f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Clear out this builder, and prepare it to build another
4515f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier with source-location information.
4525f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Clear() {
4535f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    Representation = 0;
4545f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    BufferSize = 0;
4555f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
4565f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
4575f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the underlying buffer.
4585f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4595f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \returns A pair containing a pointer to the buffer of source-location
4605f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// data and the size of the source-location data that resides in that
4615f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// buffer.
4625f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  std::pair<char *, unsigned> getBuffer() const {
4635f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    return std::make_pair(Buffer, BufferSize);
4645f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
4655f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor};
4665f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
467dacd434c49658286c380c7b4c357d76d53cb4aa1Douglas Gregor/// Insertion operator for diagnostics.  This allows sending NestedNameSpecifiers
468dacd434c49658286c380c7b4c357d76d53cb4aa1Douglas Gregor/// into a diagnostic with <<.
469dacd434c49658286c380c7b4c357d76d53cb4aa1Douglas Gregorinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
470dacd434c49658286c380c7b4c357d76d53cb4aa1Douglas Gregor                                           NestedNameSpecifier *NNS) {
4711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
472dacd434c49658286c380c7b4c357d76d53cb4aa1Douglas Gregor                  Diagnostic::ak_nestednamespec);
473dacd434c49658286c380c7b4c357d76d53cb4aa1Douglas Gregor  return DB;
474dacd434c49658286c380c7b4c357d76d53cb4aa1Douglas Gregor}
4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
476e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor}
477e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
478e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#endif
479