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.
9114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  NestedNameSpecifier() : Prefix(0, StoredIdentifier), Specifier(0) { }
92ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
93ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Copy constructor used internally to clone nested name
94ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifiers.
951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  NestedNameSpecifier(const NestedNameSpecifier &Other)
961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
97ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor      Specifier(Other.Specifier) {
98e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
99e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
100be2fa7ebf01259b63dc52fe46c8d101c18e72269Craig Topper  void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION;
101e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
102ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Either find or insert the given nested name specifier
103ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// mockup in the given context.
1044ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
1051734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor                                           const NestedNameSpecifier &Mockup);
106e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
107ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorpublic:
108ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a specifier combining a prefix and an identifier.
109e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  ///
110ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// The prefix must be dependent, since nested name specifiers
111ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// referencing an identifier are only permitted when the identifier
112ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// cannot be resolved.
1134ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
115ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     IdentifierInfo *II);
116ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
117ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a nested name specifier that names a namespace.
1184ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
1208441fffda14c5d9ac704f24173fcb117d4999a8eDmitri Gribenko                                     const NamespaceDecl *NS);
121ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
12214aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Builds a nested name specifier that names a namespace alias.
12314aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  static NestedNameSpecifier *Create(const ASTContext &Context,
12414aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor                                     NestedNameSpecifier *Prefix,
12514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor                                     NamespaceAliasDecl *Alias);
12614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
127ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a nested name specifier that names a type.
1284ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     NestedNameSpecifier *Prefix,
130f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall                                     bool Template, const Type *T);
131ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
1322700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// \brief Builds a specifier that consists of just an identifier.
1332700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  ///
1342700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// The nested-name-specifier is assumed to be dependent, but has no
1352700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// prefix because the prefix is implied by something outside of the
1362700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
1372700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  /// type.
1384ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *Create(const ASTContext &Context,
1394ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad                                     IdentifierInfo *II);
1401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
141ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Returns the nested name specifier representing the global
142ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// scope.
1434ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
144ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
145ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Return the prefix of this nested name specifier.
146e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  ///
147ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// The prefix contains all of the parts of the nested name
148ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier that preced this current specifier. For example, for a
149ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// nested name specifier that represents "foo::bar::", the current
150ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier will contain "bar::" and the prefix will contain
151ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// "foo::".
1521734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
153ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
154ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Determine what kind of nested name specifier is stored.
15514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  SpecifierKind getKind() const;
156e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
157ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the identifier stored in this nested name
158ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
159ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  IdentifierInfo *getAsIdentifier() const {
16014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    if (Prefix.getInt() == StoredIdentifier)
1611734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      return (IdentifierInfo *)Specifier;
162e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
163e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor    return 0;
164e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
166ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the namespace stored in this nested name
167ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
16814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  NamespaceDecl *getAsNamespace() const;
169e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
17014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// \brief Retrieve the namespace alias stored in this nested name
17114aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  /// specifier.
17214aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  NamespaceAliasDecl *getAsNamespaceAlias() const;
173e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
174ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the type stored in this nested name specifier.
175f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const Type *getAsType() const {
17614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    if (Prefix.getInt() == StoredTypeSpec ||
17714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor        Prefix.getInt() == StoredTypeSpecWithTemplate)
178f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall      return (const Type *)Specifier;
179ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
180ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    return 0;
181ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
182ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
183ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Whether this nested name specifier refers to a dependent
184ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// type or not.
185ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  bool isDependent() const;
186ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
187561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// \brief Whether this nested name specifier involves a template
188561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// parameter.
189561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  bool isInstantiationDependent() const;
190561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
191d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \brief Whether this nested-name-specifier contains an unexpanded
1929c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// parameter pack (for C++11 variadic templates).
193d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  bool containsUnexpandedParameterPack() const;
194d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
195ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Print this nested name specifier to the given output
196ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// stream.
1978cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner  void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
198e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
199ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
2001734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Prefix.getOpaqueValue());
2011734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Specifier);
202e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
203bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor
204d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// \brief Dump the nested name specifier to standard output to aid
205d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// in debugging.
206e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void dump(const LangOptions &LO);
207e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor};
208e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
209c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor/// \brief A C++ nested-name-specifier augmented with source location
210c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor/// information.
211c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregorclass NestedNameSpecifierLoc {
212c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifier *Qualifier;
213c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  void *Data;
214c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
215c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the last component in the
216c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// given nested-name-specifier.
217c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
218c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
219c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the entire
220c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
221c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  static unsigned getDataLength(NestedNameSpecifier *Qualifier);
222c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
223c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregorpublic:
224c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Construct an empty nested-name-specifier.
225c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifierLoc() : Qualifier(0), Data(0) { }
226ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
227c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Construct a nested-name-specifier with source location information
228ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// from
229c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
230c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    : Qualifier(Qualifier), Data(Data) { }
231ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
232c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Evalutes true when this nested-name-specifier location is
233c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// non-empty.
234c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  operator bool() const { return Qualifier; }
235c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
236c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the nested-name-specifier to which this instance
237c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// refers.
238c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifier *getNestedNameSpecifier() const {
239c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    return Qualifier;
240c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  }
241c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
242c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the opaque pointer that refers to source-location data.
243c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  void *getOpaqueData() const { return Data; }
244ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
245c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the source range covering the entirety of this
246c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
247c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
248c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
2499c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// \c \::std::vector<int>::, the returned source range would cover
250c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// from the initial '::' to the last '::'.
251aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY;
252c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
253c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Retrieve the source range covering just the last part of
254c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// this nested-name-specifier, not including the prefix.
255c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
256c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
2579c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// \c \::std::vector<int>::, the returned source range would cover
258c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// from "vector" to the last '::'.
259dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  SourceRange getLocalSourceRange() const;
260dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
261dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief Retrieve the location of the beginning of this
262dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// nested-name-specifier.
263ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getBeginLoc() const {
264dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    return getSourceRange().getBegin();
265dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
266dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
267dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief Retrieve the location of the end of this
268dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// nested-name-specifier.
269ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getEndLoc() const {
270dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    return getSourceRange().getEnd();
271dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
272c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
273c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// \brief Retrieve the location of the beginning of this
274c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// component of the nested-name-specifier.
275ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getLocalBeginLoc() const {
276c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    return getLocalSourceRange().getBegin();
277c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  }
278ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
279c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// \brief Retrieve the location of the end of this component of the
280c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  /// nested-name-specifier.
281ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getLocalEndLoc() const {
282c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    return getLocalSourceRange().getEnd();
283c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  }
284c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor
285c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Return the prefix of this nested-name-specifier.
286c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  ///
287c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// For example, if this instance refers to a nested-name-specifier
2889c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
289c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// returned prefix may be empty, if this is the first component of
290c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// the nested-name-specifier.
291c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  NestedNameSpecifierLoc getPrefix() const {
292c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    if (!Qualifier)
293c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor      return *this;
294c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
295c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor    return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
296c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  }
297dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
298dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief For a nested-name-specifier that refers to a type,
299dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// retrieve the type with source-location information.
300dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  TypeLoc getTypeLoc() const;
301dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
302c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// \brief Determines the data length for the entire
303c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  /// nested-name-specifier.
304c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor  unsigned getDataLength() const { return getDataLength(Qualifier); }
305ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
306ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  friend bool operator==(NestedNameSpecifierLoc X,
30700cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor                         NestedNameSpecifierLoc Y) {
30800cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor    return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
30900cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  }
31000cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor
311ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  friend bool operator!=(NestedNameSpecifierLoc X,
31200cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor                         NestedNameSpecifierLoc Y) {
31300cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor    return !(X == Y);
31400cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  }
315c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor};
316c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor
3175f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// \brief Class that aids in the construction of nested-name-specifiers along
3185f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// with source-location information for all of the components of the
3195f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor/// nested-name-specifier.
3205f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregorclass NestedNameSpecifierLocBuilder {
321ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief The current representation of the nested-name-specifier we're
3225f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// building.
3235f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifier *Representation;
324ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3255f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Buffer used to store source-location information for the
3265f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier.
3275f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
328ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// Note that we explicitly manage the buffer (rather than using a
3295f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// SmallVector) because \c Declarator expects it to be possible to memcpy()
3305f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
3315f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  char *Buffer;
332ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3335f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief The size of the buffer used to store source-location information
3345f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// for the nested-name-specifier.
3355f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  unsigned BufferSize;
336ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
337ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief The capacity of the buffer used to store source-location
3385f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information for the nested-name-specifier.
3395f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  unsigned BufferCapacity;
3405f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
3415f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregorpublic:
34242f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar  NestedNameSpecifierLocBuilder()
34342f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar    : Representation(0), Buffer(0), BufferSize(0), BufferCapacity(0) { }
344ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3455f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
346ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3475f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLocBuilder &
3485f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  operator=(const NestedNameSpecifierLocBuilder &Other);
349ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
35042f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar  ~NestedNameSpecifierLocBuilder() {
35142f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar    if (BufferCapacity)
35242f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar      free(Buffer);
35342f42c8c58fd1b70ed1e84b426312581e656620bDaniel Dunbar  }
354ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3555f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the representation of the nested-name-specifier.
3565f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifier *getRepresentation() const { return Representation; }
357ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3585f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Extend the current nested-name-specifier by another
3595f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'type::'.
3605f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3615f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3625f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3635f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3645f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param TemplateKWLoc The location of the 'template' keyword, if present.
3655f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3665f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param TL The TypeLoc that describes the type preceding the '::'.
3675f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3685f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
3695f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
3705f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation ColonColonLoc);
371ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
372ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Extend the current nested-name-specifier by another
3735f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'identifier::'.
3745f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3755f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3765f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3775f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3785f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Identifier The identifier.
3795f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3805f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param IdentifierLoc The location of the identifier.
3815f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3825f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
3835f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, IdentifierInfo *Identifier,
3845f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
385ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
386ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Extend the current nested-name-specifier by another
3875f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'namespace::'.
3885f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3895f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
3905f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
3915f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3925f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Namespace The namespace.
3935f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3945f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param NamespaceLoc The location of the namespace name.
3955f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
3965f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
3975f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, NamespaceDecl *Namespace,
3985f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
399ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
400ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Extend the current nested-name-specifier by another
4015f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier component of the form 'namespace-alias::'.
4025f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4035f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The AST context in which this nested-name-specifier
4045f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// resides.
4055f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4065f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Alias The namespace alias.
4075f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
408ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \param AliasLoc The location of the namespace alias
4095f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// name.
4105f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4115f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param ColonColonLoc The location of the trailing '::'.
4125f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
4135f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor              SourceLocation AliasLoc, SourceLocation ColonColonLoc);
414ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4155f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Turn this (empty) nested-name-specifier into the global
4165f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier '::'.
4175f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
418ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4195f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Make a new nested-name-specifier from incomplete source-location
4205f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information.
4215f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4225f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// This routine should be used very, very rarely, in cases where we
4235f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// need to synthesize a nested-name-specifier. Most code should instead use
4245f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
425ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
4265f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor                   SourceRange R);
427ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
428ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Adopt an existing nested-name-specifier (with source-range
4295f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// information).
4305f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Adopt(NestedNameSpecifierLoc Other);
431ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4325f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the source range covered by this nested-name-specifier.
433aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY {
4345f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
4355f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
436ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4375f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve a nested-name-specifier with location information,
4385f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// copied into the given AST context.
4395f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4405f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \param Context The context into which this nested-name-specifier will be
4415f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// copied.
4425f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
4435f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor
4449dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  /// \brief Retrieve a nested-name-specifier with location
4459c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// information based on the information in this builder.
4469c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  ///
4479c849b03a62fd1864d62c382c916cf9dc17be335James Dennett  /// This loc will contain references to the builder's internal data and may
4489dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  /// be invalidated by any change to the builder.
4499dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  NestedNameSpecifierLoc getTemporary() const {
4509dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall    return NestedNameSpecifierLoc(Representation, Buffer);
4519dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall  }
4529dc71d2fddcd283e07d45f3894c8559e2f7dd9a7John McCall
4535f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Clear out this builder, and prepare it to build another
4545f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// nested-name-specifier with source-location information.
4555f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  void Clear() {
4565f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    Representation = 0;
4575f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    BufferSize = 0;
4585f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
459ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4605f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \brief Retrieve the underlying buffer.
4615f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  ///
4625f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// \returns A pair containing a pointer to the buffer of source-location
4635f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// data and the size of the source-location data that resides in that
4645f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  /// buffer.
4655f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  std::pair<char *, unsigned> getBuffer() const {
4665f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor    return std::make_pair(Buffer, BufferSize);
4675f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor  }
4685f791bb44417ecc201ed57a85d0fe02001d8a615Douglas Gregor};
469ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
470ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// Insertion operator for diagnostics.  This allows sending
471ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// NestedNameSpecifiers into a diagnostic with <<.
472d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramerinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
473d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer                                           NestedNameSpecifier *NNS) {
474d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer  DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
475d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer                  DiagnosticsEngine::ak_nestednamespec);
476d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer  return DB;
477d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer}
4781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
479e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor}
480e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
481e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#endif
482