1193326Sed//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file defines the NestedNameSpecifier class, which represents
11193326Sed//  a C++ nested-name-specifier.
12193326Sed//
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
15193326Sed#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
16193326Sed
17198092Srdivacky#include "clang/Basic/Diagnostic.h"
18193326Sed#include "llvm/ADT/FoldingSet.h"
19193326Sed#include "llvm/ADT/PointerIntPair.h"
20234353Sdim#include "llvm/Support/Compiler.h"
21193326Sed
22193326Sednamespace clang {
23193326Sed
24193326Sedclass ASTContext;
25219077Sdimclass NamespaceAliasDecl;
26193326Sedclass NamespaceDecl;
27193326Sedclass IdentifierInfo;
28198092Srdivackystruct PrintingPolicy;
29193326Sedclass Type;
30219077Sdimclass TypeLoc;
31195341Sedclass LangOptions;
32193326Sed
33193326Sed/// \brief Represents a C++ nested name specifier, such as
34239462Sdim/// "\::std::vector<int>::".
35193326Sed///
36193326Sed/// C++ nested name specifiers are the prefixes to qualified
37193326Sed/// namespaces. For example, "foo::" in "foo::x" is a nested name
38193326Sed/// specifier. Nested name specifiers are made up of a sequence of
39193326Sed/// specifiers, each of which can be a namespace, type, identifier
40234353Sdim/// (for dependent names), decltype specifier, or the global specifier ('::').
41234353Sdim/// The last two specifiers can only appear at the start of a
42234353Sdim/// nested-namespace-specifier.
43193326Sedclass NestedNameSpecifier : public llvm::FoldingSetNode {
44219077Sdim
45219077Sdim  /// \brief Enumeration describing
46219077Sdim  enum StoredSpecifierKind {
47219077Sdim    StoredIdentifier = 0,
48219077Sdim    StoredNamespaceOrAlias = 1,
49219077Sdim    StoredTypeSpec = 2,
50219077Sdim    StoredTypeSpecWithTemplate = 3
51219077Sdim  };
52219077Sdim
53193326Sed  /// \brief The nested name specifier that precedes this nested name
54193326Sed  /// specifier.
55193326Sed  ///
56193326Sed  /// The pointer is the nested-name-specifier that precedes this
57193326Sed  /// one. The integer stores one of the first four values of type
58193326Sed  /// SpecifierKind.
59219077Sdim  llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
60193326Sed
61193326Sed  /// \brief The last component in the nested name specifier, which
62193326Sed  /// can be an identifier, a declaration, or a type.
63193326Sed  ///
64193326Sed  /// When the pointer is NULL, this specifier represents the global
65193326Sed  /// specifier '::'. Otherwise, the pointer is one of
66193326Sed  /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
67193326Sed  /// specifier as encoded within the prefix.
68193326Sed  void* Specifier;
69193326Sed
70193326Sedpublic:
71193326Sed  /// \brief The kind of specifier that completes this nested name
72193326Sed  /// specifier.
73193326Sed  enum SpecifierKind {
74193326Sed    /// \brief An identifier, stored as an IdentifierInfo*.
75219077Sdim    Identifier,
76219077Sdim    /// \brief A namespace, stored as a NamespaceDecl*.
77219077Sdim    Namespace,
78219077Sdim    /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
79219077Sdim    NamespaceAlias,
80193326Sed    /// \brief A type, stored as a Type*.
81219077Sdim    TypeSpec,
82193326Sed    /// \brief A type that was preceded by the 'template' keyword,
83193326Sed    /// stored as a Type*.
84219077Sdim    TypeSpecWithTemplate,
85193326Sed    /// \brief The global specifier '::'. There is no stored value.
86219077Sdim    Global
87193326Sed  };
88193326Sed
89193326Sedprivate:
90193326Sed  /// \brief Builds the global specifier.
91219077Sdim  NestedNameSpecifier() : Prefix(0, StoredIdentifier), Specifier(0) { }
92193326Sed
93193326Sed  /// \brief Copy constructor used internally to clone nested name
94193326Sed  /// specifiers.
95198092Srdivacky  NestedNameSpecifier(const NestedNameSpecifier &Other)
96198092Srdivacky    : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
97193326Sed      Specifier(Other.Specifier) {
98193326Sed  }
99193326Sed
100243830Sdim  void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION;
101193326Sed
102193326Sed  /// \brief Either find or insert the given nested name specifier
103193326Sed  /// mockup in the given context.
104218893Sdim  static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
105193326Sed                                           const NestedNameSpecifier &Mockup);
106193326Sed
107193326Sedpublic:
108193326Sed  /// \brief Builds a specifier combining a prefix and an identifier.
109193326Sed  ///
110193326Sed  /// The prefix must be dependent, since nested name specifiers
111193326Sed  /// referencing an identifier are only permitted when the identifier
112193326Sed  /// cannot be resolved.
113218893Sdim  static NestedNameSpecifier *Create(const ASTContext &Context,
114198092Srdivacky                                     NestedNameSpecifier *Prefix,
115193326Sed                                     IdentifierInfo *II);
116193326Sed
117193326Sed  /// \brief Builds a nested name specifier that names a namespace.
118218893Sdim  static NestedNameSpecifier *Create(const ASTContext &Context,
119198092Srdivacky                                     NestedNameSpecifier *Prefix,
120249423Sdim                                     const NamespaceDecl *NS);
121193326Sed
122219077Sdim  /// \brief Builds a nested name specifier that names a namespace alias.
123219077Sdim  static NestedNameSpecifier *Create(const ASTContext &Context,
124219077Sdim                                     NestedNameSpecifier *Prefix,
125219077Sdim                                     NamespaceAliasDecl *Alias);
126219077Sdim
127193326Sed  /// \brief Builds a nested name specifier that names a type.
128218893Sdim  static NestedNameSpecifier *Create(const ASTContext &Context,
129198092Srdivacky                                     NestedNameSpecifier *Prefix,
130218893Sdim                                     bool Template, const Type *T);
131193326Sed
132198092Srdivacky  /// \brief Builds a specifier that consists of just an identifier.
133198092Srdivacky  ///
134198092Srdivacky  /// The nested-name-specifier is assumed to be dependent, but has no
135198092Srdivacky  /// prefix because the prefix is implied by something outside of the
136198092Srdivacky  /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
137198092Srdivacky  /// type.
138218893Sdim  static NestedNameSpecifier *Create(const ASTContext &Context,
139218893Sdim                                     IdentifierInfo *II);
140198092Srdivacky
141193326Sed  /// \brief Returns the nested name specifier representing the global
142193326Sed  /// scope.
143218893Sdim  static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
144193326Sed
145193326Sed  /// \brief Return the prefix of this nested name specifier.
146193326Sed  ///
147193326Sed  /// The prefix contains all of the parts of the nested name
148193326Sed  /// specifier that preced this current specifier. For example, for a
149193326Sed  /// nested name specifier that represents "foo::bar::", the current
150193326Sed  /// specifier will contain "bar::" and the prefix will contain
151193326Sed  /// "foo::".
152193326Sed  NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
153193326Sed
154193326Sed  /// \brief Determine what kind of nested name specifier is stored.
155219077Sdim  SpecifierKind getKind() const;
156193326Sed
157193326Sed  /// \brief Retrieve the identifier stored in this nested name
158193326Sed  /// specifier.
159193326Sed  IdentifierInfo *getAsIdentifier() const {
160219077Sdim    if (Prefix.getInt() == StoredIdentifier)
161193326Sed      return (IdentifierInfo *)Specifier;
162193326Sed
163193326Sed    return 0;
164193326Sed  }
165198092Srdivacky
166193326Sed  /// \brief Retrieve the namespace stored in this nested name
167193326Sed  /// specifier.
168219077Sdim  NamespaceDecl *getAsNamespace() const;
169193326Sed
170219077Sdim  /// \brief Retrieve the namespace alias stored in this nested name
171219077Sdim  /// specifier.
172219077Sdim  NamespaceAliasDecl *getAsNamespaceAlias() const;
173193326Sed
174193326Sed  /// \brief Retrieve the type stored in this nested name specifier.
175218893Sdim  const Type *getAsType() const {
176219077Sdim    if (Prefix.getInt() == StoredTypeSpec ||
177219077Sdim        Prefix.getInt() == StoredTypeSpecWithTemplate)
178218893Sdim      return (const Type *)Specifier;
179193326Sed
180193326Sed    return 0;
181193326Sed  }
182193326Sed
183193326Sed  /// \brief Whether this nested name specifier refers to a dependent
184193326Sed  /// type or not.
185193326Sed  bool isDependent() const;
186193326Sed
187224145Sdim  /// \brief Whether this nested name specifier involves a template
188224145Sdim  /// parameter.
189224145Sdim  bool isInstantiationDependent() const;
190224145Sdim
191218893Sdim  /// \brief Whether this nested-name-specifier contains an unexpanded
192239462Sdim  /// parameter pack (for C++11 variadic templates).
193218893Sdim  bool containsUnexpandedParameterPack() const;
194218893Sdim
195193326Sed  /// \brief Print this nested name specifier to the given output
196193326Sed  /// stream.
197226633Sdim  void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
198193326Sed
199193326Sed  void Profile(llvm::FoldingSetNodeID &ID) const {
200193326Sed    ID.AddPointer(Prefix.getOpaqueValue());
201193326Sed    ID.AddPointer(Specifier);
202193326Sed  }
203193326Sed
204193326Sed  /// \brief Dump the nested name specifier to standard output to aid
205193326Sed  /// in debugging.
206195341Sed  void dump(const LangOptions &LO);
207193326Sed};
208193326Sed
209219077Sdim/// \brief A C++ nested-name-specifier augmented with source location
210219077Sdim/// information.
211219077Sdimclass NestedNameSpecifierLoc {
212219077Sdim  NestedNameSpecifier *Qualifier;
213219077Sdim  void *Data;
214219077Sdim
215219077Sdim  /// \brief Determines the data length for the last component in the
216219077Sdim  /// given nested-name-specifier.
217219077Sdim  static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
218219077Sdim
219219077Sdim  /// \brief Determines the data length for the entire
220219077Sdim  /// nested-name-specifier.
221219077Sdim  static unsigned getDataLength(NestedNameSpecifier *Qualifier);
222219077Sdim
223219077Sdimpublic:
224219077Sdim  /// \brief Construct an empty nested-name-specifier.
225219077Sdim  NestedNameSpecifierLoc() : Qualifier(0), Data(0) { }
226234353Sdim
227219077Sdim  /// \brief Construct a nested-name-specifier with source location information
228234353Sdim  /// from
229219077Sdim  NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
230219077Sdim    : Qualifier(Qualifier), Data(Data) { }
231234353Sdim
232219077Sdim  /// \brief Evalutes true when this nested-name-specifier location is
233219077Sdim  /// non-empty.
234263508Sdim  LLVM_EXPLICIT operator bool() const { return Qualifier; }
235219077Sdim
236263508Sdim  /// \brief Evalutes true when this nested-name-specifier location is
237263508Sdim  /// empty.
238263508Sdim  bool hasQualifier() const { return Qualifier; }
239263508Sdim
240219077Sdim  /// \brief Retrieve the nested-name-specifier to which this instance
241219077Sdim  /// refers.
242219077Sdim  NestedNameSpecifier *getNestedNameSpecifier() const {
243219077Sdim    return Qualifier;
244219077Sdim  }
245219077Sdim
246219077Sdim  /// \brief Retrieve the opaque pointer that refers to source-location data.
247219077Sdim  void *getOpaqueData() const { return Data; }
248234353Sdim
249219077Sdim  /// \brief Retrieve the source range covering the entirety of this
250219077Sdim  /// nested-name-specifier.
251219077Sdim  ///
252219077Sdim  /// For example, if this instance refers to a nested-name-specifier
253239462Sdim  /// \c \::std::vector<int>::, the returned source range would cover
254219077Sdim  /// from the initial '::' to the last '::'.
255234353Sdim  SourceRange getSourceRange() const LLVM_READONLY;
256219077Sdim
257219077Sdim  /// \brief Retrieve the source range covering just the last part of
258219077Sdim  /// this nested-name-specifier, not including the prefix.
259219077Sdim  ///
260219077Sdim  /// For example, if this instance refers to a nested-name-specifier
261239462Sdim  /// \c \::std::vector<int>::, the returned source range would cover
262219077Sdim  /// from "vector" to the last '::'.
263219077Sdim  SourceRange getLocalSourceRange() const;
264219077Sdim
265219077Sdim  /// \brief Retrieve the location of the beginning of this
266219077Sdim  /// nested-name-specifier.
267234353Sdim  SourceLocation getBeginLoc() const {
268219077Sdim    return getSourceRange().getBegin();
269219077Sdim  }
270219077Sdim
271219077Sdim  /// \brief Retrieve the location of the end of this
272219077Sdim  /// nested-name-specifier.
273234353Sdim  SourceLocation getEndLoc() const {
274219077Sdim    return getSourceRange().getEnd();
275219077Sdim  }
276219077Sdim
277219077Sdim  /// \brief Retrieve the location of the beginning of this
278219077Sdim  /// component of the nested-name-specifier.
279234353Sdim  SourceLocation getLocalBeginLoc() const {
280219077Sdim    return getLocalSourceRange().getBegin();
281219077Sdim  }
282234353Sdim
283219077Sdim  /// \brief Retrieve the location of the end of this component of the
284219077Sdim  /// nested-name-specifier.
285234353Sdim  SourceLocation getLocalEndLoc() const {
286219077Sdim    return getLocalSourceRange().getEnd();
287219077Sdim  }
288219077Sdim
289219077Sdim  /// \brief Return the prefix of this nested-name-specifier.
290219077Sdim  ///
291219077Sdim  /// For example, if this instance refers to a nested-name-specifier
292239462Sdim  /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
293219077Sdim  /// returned prefix may be empty, if this is the first component of
294219077Sdim  /// the nested-name-specifier.
295219077Sdim  NestedNameSpecifierLoc getPrefix() const {
296219077Sdim    if (!Qualifier)
297219077Sdim      return *this;
298219077Sdim
299219077Sdim    return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
300219077Sdim  }
301219077Sdim
302219077Sdim  /// \brief For a nested-name-specifier that refers to a type,
303219077Sdim  /// retrieve the type with source-location information.
304219077Sdim  TypeLoc getTypeLoc() const;
305219077Sdim
306219077Sdim  /// \brief Determines the data length for the entire
307219077Sdim  /// nested-name-specifier.
308219077Sdim  unsigned getDataLength() const { return getDataLength(Qualifier); }
309234353Sdim
310234353Sdim  friend bool operator==(NestedNameSpecifierLoc X,
311219077Sdim                         NestedNameSpecifierLoc Y) {
312219077Sdim    return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
313219077Sdim  }
314219077Sdim
315234353Sdim  friend bool operator!=(NestedNameSpecifierLoc X,
316219077Sdim                         NestedNameSpecifierLoc Y) {
317219077Sdim    return !(X == Y);
318219077Sdim  }
319219077Sdim};
320219077Sdim
321221345Sdim/// \brief Class that aids in the construction of nested-name-specifiers along
322221345Sdim/// with source-location information for all of the components of the
323221345Sdim/// nested-name-specifier.
324221345Sdimclass NestedNameSpecifierLocBuilder {
325234353Sdim  /// \brief The current representation of the nested-name-specifier we're
326221345Sdim  /// building.
327221345Sdim  NestedNameSpecifier *Representation;
328234353Sdim
329221345Sdim  /// \brief Buffer used to store source-location information for the
330221345Sdim  /// nested-name-specifier.
331221345Sdim  ///
332234353Sdim  /// Note that we explicitly manage the buffer (rather than using a
333221345Sdim  /// SmallVector) because \c Declarator expects it to be possible to memcpy()
334221345Sdim  /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
335221345Sdim  char *Buffer;
336234353Sdim
337221345Sdim  /// \brief The size of the buffer used to store source-location information
338221345Sdim  /// for the nested-name-specifier.
339221345Sdim  unsigned BufferSize;
340234353Sdim
341234353Sdim  /// \brief The capacity of the buffer used to store source-location
342221345Sdim  /// information for the nested-name-specifier.
343221345Sdim  unsigned BufferCapacity;
344221345Sdim
345221345Sdimpublic:
346234353Sdim  NestedNameSpecifierLocBuilder()
347234353Sdim    : Representation(0), Buffer(0), BufferSize(0), BufferCapacity(0) { }
348234353Sdim
349221345Sdim  NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
350234353Sdim
351221345Sdim  NestedNameSpecifierLocBuilder &
352221345Sdim  operator=(const NestedNameSpecifierLocBuilder &Other);
353234353Sdim
354234353Sdim  ~NestedNameSpecifierLocBuilder() {
355234353Sdim    if (BufferCapacity)
356234353Sdim      free(Buffer);
357234353Sdim  }
358234353Sdim
359221345Sdim  /// \brief Retrieve the representation of the nested-name-specifier.
360221345Sdim  NestedNameSpecifier *getRepresentation() const { return Representation; }
361234353Sdim
362221345Sdim  /// \brief Extend the current nested-name-specifier by another
363221345Sdim  /// nested-name-specifier component of the form 'type::'.
364221345Sdim  ///
365221345Sdim  /// \param Context The AST context in which this nested-name-specifier
366221345Sdim  /// resides.
367221345Sdim  ///
368221345Sdim  /// \param TemplateKWLoc The location of the 'template' keyword, if present.
369221345Sdim  ///
370221345Sdim  /// \param TL The TypeLoc that describes the type preceding the '::'.
371221345Sdim  ///
372221345Sdim  /// \param ColonColonLoc The location of the trailing '::'.
373221345Sdim  void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
374221345Sdim              SourceLocation ColonColonLoc);
375234353Sdim
376234353Sdim  /// \brief Extend the current nested-name-specifier by another
377221345Sdim  /// nested-name-specifier component of the form 'identifier::'.
378221345Sdim  ///
379221345Sdim  /// \param Context The AST context in which this nested-name-specifier
380221345Sdim  /// resides.
381221345Sdim  ///
382221345Sdim  /// \param Identifier The identifier.
383221345Sdim  ///
384221345Sdim  /// \param IdentifierLoc The location of the identifier.
385221345Sdim  ///
386221345Sdim  /// \param ColonColonLoc The location of the trailing '::'.
387221345Sdim  void Extend(ASTContext &Context, IdentifierInfo *Identifier,
388221345Sdim              SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
389234353Sdim
390234353Sdim  /// \brief Extend the current nested-name-specifier by another
391221345Sdim  /// nested-name-specifier component of the form 'namespace::'.
392221345Sdim  ///
393221345Sdim  /// \param Context The AST context in which this nested-name-specifier
394221345Sdim  /// resides.
395221345Sdim  ///
396221345Sdim  /// \param Namespace The namespace.
397221345Sdim  ///
398221345Sdim  /// \param NamespaceLoc The location of the namespace name.
399221345Sdim  ///
400221345Sdim  /// \param ColonColonLoc The location of the trailing '::'.
401221345Sdim  void Extend(ASTContext &Context, NamespaceDecl *Namespace,
402221345Sdim              SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
403234353Sdim
404234353Sdim  /// \brief Extend the current nested-name-specifier by another
405221345Sdim  /// nested-name-specifier component of the form 'namespace-alias::'.
406221345Sdim  ///
407221345Sdim  /// \param Context The AST context in which this nested-name-specifier
408221345Sdim  /// resides.
409221345Sdim  ///
410221345Sdim  /// \param Alias The namespace alias.
411221345Sdim  ///
412234353Sdim  /// \param AliasLoc The location of the namespace alias
413221345Sdim  /// name.
414221345Sdim  ///
415221345Sdim  /// \param ColonColonLoc The location of the trailing '::'.
416221345Sdim  void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
417221345Sdim              SourceLocation AliasLoc, SourceLocation ColonColonLoc);
418234353Sdim
419221345Sdim  /// \brief Turn this (empty) nested-name-specifier into the global
420221345Sdim  /// nested-name-specifier '::'.
421221345Sdim  void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
422234353Sdim
423221345Sdim  /// \brief Make a new nested-name-specifier from incomplete source-location
424221345Sdim  /// information.
425221345Sdim  ///
426221345Sdim  /// This routine should be used very, very rarely, in cases where we
427221345Sdim  /// need to synthesize a nested-name-specifier. Most code should instead use
428221345Sdim  /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
429234353Sdim  void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
430221345Sdim                   SourceRange R);
431234353Sdim
432234353Sdim  /// \brief Adopt an existing nested-name-specifier (with source-range
433221345Sdim  /// information).
434221345Sdim  void Adopt(NestedNameSpecifierLoc Other);
435234353Sdim
436221345Sdim  /// \brief Retrieve the source range covered by this nested-name-specifier.
437234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
438221345Sdim    return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
439221345Sdim  }
440234353Sdim
441221345Sdim  /// \brief Retrieve a nested-name-specifier with location information,
442221345Sdim  /// copied into the given AST context.
443221345Sdim  ///
444221345Sdim  /// \param Context The context into which this nested-name-specifier will be
445221345Sdim  /// copied.
446221345Sdim  NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
447221345Sdim
448224145Sdim  /// \brief Retrieve a nested-name-specifier with location
449239462Sdim  /// information based on the information in this builder.
450239462Sdim  ///
451239462Sdim  /// This loc will contain references to the builder's internal data and may
452224145Sdim  /// be invalidated by any change to the builder.
453224145Sdim  NestedNameSpecifierLoc getTemporary() const {
454224145Sdim    return NestedNameSpecifierLoc(Representation, Buffer);
455224145Sdim  }
456224145Sdim
457221345Sdim  /// \brief Clear out this builder, and prepare it to build another
458221345Sdim  /// nested-name-specifier with source-location information.
459221345Sdim  void Clear() {
460221345Sdim    Representation = 0;
461221345Sdim    BufferSize = 0;
462221345Sdim  }
463234353Sdim
464221345Sdim  /// \brief Retrieve the underlying buffer.
465221345Sdim  ///
466221345Sdim  /// \returns A pair containing a pointer to the buffer of source-location
467221345Sdim  /// data and the size of the source-location data that resides in that
468221345Sdim  /// buffer.
469221345Sdim  std::pair<char *, unsigned> getBuffer() const {
470221345Sdim    return std::make_pair(Buffer, BufferSize);
471221345Sdim  }
472221345Sdim};
473234353Sdim
474234353Sdim/// Insertion operator for diagnostics.  This allows sending
475234353Sdim/// NestedNameSpecifiers into a diagnostic with <<.
476198092Srdivackyinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
477198092Srdivacky                                           NestedNameSpecifier *NNS) {
478198092Srdivacky  DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
479226633Sdim                  DiagnosticsEngine::ak_nestednamespec);
480198092Srdivacky  return DB;
481193326Sed}
482193326Sed
483198092Srdivacky}
484198092Srdivacky
485193326Sed#endif
486