DeclCXX.h revision 207619
1193326Sed//===-- DeclCXX.h - Classes for representing C++ declarations -*- 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//
10205219Srdivacky//  This file defines the C++ Decl subclasses, other than those for
11205219Srdivacky//  templates (in DeclTemplate.h) and friends (in DeclFriend.h).
12193326Sed//
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15193326Sed#ifndef LLVM_CLANG_AST_DECLCXX_H
16193326Sed#define LLVM_CLANG_AST_DECLCXX_H
17193326Sed
18198092Srdivacky#include "clang/AST/Expr.h"
19193326Sed#include "clang/AST/Decl.h"
20202879Srdivacky#include "clang/AST/UnresolvedSet.h"
21193326Sed#include "llvm/ADT/SmallVector.h"
22198092Srdivacky#include "llvm/ADT/SmallPtrSet.h"
23193326Sed
24193326Sednamespace clang {
25193326Sed
26193326Sedclass ClassTemplateDecl;
27198092Srdivackyclass ClassTemplateSpecializationDecl;
28198092Srdivackyclass CXXBasePath;
29198092Srdivackyclass CXXBasePaths;
30193326Sedclass CXXConstructorDecl;
31198092Srdivackyclass CXXConversionDecl;
32193326Sedclass CXXDestructorDecl;
33193326Sedclass CXXMethodDecl;
34198092Srdivackyclass CXXRecordDecl;
35198092Srdivackyclass CXXMemberLookupCriteria;
36206084Srdivackyclass CXXFinalOverriderMap;
37205219Srdivackyclass FriendDecl;
38198092Srdivacky
39198092Srdivacky/// \brief Represents any kind of function declaration, whether it is a
40195099Sed/// concrete function or a function template.
41195099Sedclass AnyFunctionDecl {
42195099Sed  NamedDecl *Function;
43198092Srdivacky
44195341Sed  AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
45198092Srdivacky
46195099Sedpublic:
47195099Sed  AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
48195099Sed  AnyFunctionDecl(FunctionTemplateDecl *FTD);
49198092Srdivacky
50198092Srdivacky  /// \brief Implicily converts any function or function template into a
51195099Sed  /// named declaration.
52195099Sed  operator NamedDecl *() const { return Function; }
53198092Srdivacky
54195099Sed  /// \brief Retrieve the underlying function or function template.
55195099Sed  NamedDecl *get() const { return Function; }
56198092Srdivacky
57198092Srdivacky  static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
58195341Sed    return AnyFunctionDecl(ND);
59195341Sed  }
60195099Sed};
61198092Srdivacky
62195099Sed} // end namespace clang
63195099Sed
64195099Sednamespace llvm {
65198092Srdivacky  /// Implement simplify_type for AnyFunctionDecl, so that we can dyn_cast from
66195099Sed  /// AnyFunctionDecl to any function or function template declaration.
67195099Sed  template<> struct simplify_type<const ::clang::AnyFunctionDecl> {
68195099Sed    typedef ::clang::NamedDecl* SimpleType;
69195099Sed    static SimpleType getSimplifiedValue(const ::clang::AnyFunctionDecl &Val) {
70195099Sed      return Val;
71195099Sed    }
72195099Sed  };
73195099Sed  template<> struct simplify_type< ::clang::AnyFunctionDecl>
74195099Sed  : public simplify_type<const ::clang::AnyFunctionDecl> {};
75198092Srdivacky
76195341Sed  // Provide PointerLikeTypeTraits for non-cvr pointers.
77195341Sed  template<>
78195341Sed  class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
79195341Sed  public:
80195341Sed    static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
81198092Srdivacky      return F.get();
82195341Sed    }
83195341Sed    static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
84195341Sed      return ::clang::AnyFunctionDecl::getFromNamedDecl(
85195341Sed                                      static_cast< ::clang::NamedDecl*>(P));
86195341Sed    }
87198092Srdivacky
88195341Sed    enum { NumLowBitsAvailable = 2 };
89195341Sed  };
90198092Srdivacky
91195099Sed} // end namespace llvm
92195099Sed
93195099Sednamespace clang {
94198092Srdivacky
95193326Sed/// CXXBaseSpecifier - A base class of a C++ class.
96193326Sed///
97193326Sed/// Each CXXBaseSpecifier represents a single, direct base class (or
98193326Sed/// struct) of a C++ class (or struct). It specifies the type of that
99193326Sed/// base class, whether it is a virtual or non-virtual base, and what
100193326Sed/// level of access (public, protected, private) is used for the
101193326Sed/// derivation. For example:
102193326Sed///
103193326Sed/// @code
104193326Sed///   class A { };
105193326Sed///   class B { };
106193326Sed///   class C : public virtual A, protected B { };
107193326Sed/// @endcode
108193326Sed///
109193326Sed/// In this code, C will have two CXXBaseSpecifiers, one for "public
110193326Sed/// virtual A" and the other for "protected B".
111193326Sedclass CXXBaseSpecifier {
112193326Sed  /// Range - The source code range that covers the full base
113193326Sed  /// specifier, including the "virtual" (if present) and access
114193326Sed  /// specifier (if present).
115200583Srdivacky  // FIXME: Move over to a TypeLoc!
116193326Sed  SourceRange Range;
117193326Sed
118193326Sed  /// Virtual - Whether this is a virtual base class or not.
119193326Sed  bool Virtual : 1;
120193326Sed
121193326Sed  /// BaseOfClass - Whether this is the base of a class (true) or of a
122193326Sed  /// struct (false). This determines the mapping from the access
123193326Sed  /// specifier as written in the source code to the access specifier
124193326Sed  /// used for semantic analysis.
125198092Srdivacky  bool BaseOfClass : 1;
126193326Sed
127193326Sed  /// Access - Access specifier as written in the source code (which
128193326Sed  /// may be AS_none). The actual type of data stored here is an
129193326Sed  /// AccessSpecifier, but we use "unsigned" here to work around a
130193326Sed  /// VC++ bug.
131193326Sed  unsigned Access : 2;
132193326Sed
133193326Sed  /// BaseType - The type of the base class. This will be a class or
134193326Sed  /// struct (or a typedef of such).
135193326Sed  QualType BaseType;
136198092Srdivacky
137193326Sedpublic:
138193326Sed  CXXBaseSpecifier() { }
139193326Sed
140193326Sed  CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, QualType T)
141193326Sed    : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseType(T) { }
142193326Sed
143193326Sed  /// getSourceRange - Retrieves the source range that contains the
144193326Sed  /// entire base specifier.
145193326Sed  SourceRange getSourceRange() const { return Range; }
146198092Srdivacky
147193326Sed  /// isVirtual - Determines whether the base class is a virtual base
148193326Sed  /// class (or not).
149193326Sed  bool isVirtual() const { return Virtual; }
150193326Sed
151203955Srdivacky  /// \brief Determine whether this base class if a base of a class declared
152203955Srdivacky  /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
153203955Srdivacky  bool isBaseOfClass() const { return BaseOfClass; }
154203955Srdivacky
155193326Sed  /// getAccessSpecifier - Returns the access specifier for this base
156193326Sed  /// specifier. This is the actual base specifier as used for
157193326Sed  /// semantic analysis, so the result can never be AS_none. To
158193326Sed  /// retrieve the access specifier as written in the source code, use
159193326Sed  /// getAccessSpecifierAsWritten().
160198092Srdivacky  AccessSpecifier getAccessSpecifier() const {
161193326Sed    if ((AccessSpecifier)Access == AS_none)
162193326Sed      return BaseOfClass? AS_private : AS_public;
163193326Sed    else
164198092Srdivacky      return (AccessSpecifier)Access;
165193326Sed  }
166193326Sed
167193326Sed  /// getAccessSpecifierAsWritten - Retrieves the access specifier as
168193326Sed  /// written in the source code (which may mean that no access
169193326Sed  /// specifier was explicitly written). Use getAccessSpecifier() to
170193326Sed  /// retrieve the access specifier for use in semantic analysis.
171193326Sed  AccessSpecifier getAccessSpecifierAsWritten() const {
172193326Sed    return (AccessSpecifier)Access;
173193326Sed  }
174193326Sed
175193326Sed  /// getType - Retrieves the type of the base class. This type will
176193326Sed  /// always be an unqualified class type.
177193326Sed  QualType getType() const { return BaseType; }
178193326Sed};
179193326Sed
180193326Sed/// CXXRecordDecl - Represents a C++ struct/union/class.
181193326Sed/// FIXME: This class will disappear once we've properly taught RecordDecl
182193326Sed/// to deal with C++-specific things.
183193326Sedclass CXXRecordDecl : public RecordDecl {
184193326Sed
185203955Srdivacky  friend void TagDecl::startDefinition();
186193326Sed
187203955Srdivacky  struct DefinitionData {
188203955Srdivacky    DefinitionData(CXXRecordDecl *D);
189193326Sed
190203955Srdivacky    /// UserDeclaredConstructor - True when this class has a
191203955Srdivacky    /// user-declared constructor.
192203955Srdivacky    bool UserDeclaredConstructor : 1;
193193326Sed
194203955Srdivacky    /// UserDeclaredCopyConstructor - True when this class has a
195203955Srdivacky    /// user-declared copy constructor.
196203955Srdivacky    bool UserDeclaredCopyConstructor : 1;
197193326Sed
198203955Srdivacky    /// UserDeclaredCopyAssignment - True when this class has a
199203955Srdivacky    /// user-declared copy assignment operator.
200203955Srdivacky    bool UserDeclaredCopyAssignment : 1;
201193326Sed
202203955Srdivacky    /// UserDeclaredDestructor - True when this class has a
203203955Srdivacky    /// user-declared destructor.
204203955Srdivacky    bool UserDeclaredDestructor : 1;
205198092Srdivacky
206203955Srdivacky    /// Aggregate - True when this class is an aggregate.
207203955Srdivacky    bool Aggregate : 1;
208193326Sed
209203955Srdivacky    /// PlainOldData - True when this class is a POD-type.
210203955Srdivacky    bool PlainOldData : 1;
211198092Srdivacky
212203955Srdivacky    /// Empty - true when this class is empty for traits purposes,
213203955Srdivacky    /// i.e. has no data members other than 0-width bit-fields, has no
214203955Srdivacky    /// virtual function/base, and doesn't inherit from a non-empty
215203955Srdivacky    /// class. Doesn't take union-ness into account.
216203955Srdivacky    bool Empty : 1;
217198092Srdivacky
218203955Srdivacky    /// Polymorphic - True when this class is polymorphic, i.e. has at
219203955Srdivacky    /// least one virtual member or derives from a polymorphic class.
220203955Srdivacky    bool Polymorphic : 1;
221198092Srdivacky
222203955Srdivacky    /// Abstract - True when this class is abstract, i.e. has at least
223203955Srdivacky    /// one pure virtual function, (that can come from a base class).
224203955Srdivacky    bool Abstract : 1;
225198092Srdivacky
226203955Srdivacky    /// HasTrivialConstructor - True when this class has a trivial constructor.
227203955Srdivacky    ///
228203955Srdivacky    /// C++ [class.ctor]p5.  A constructor is trivial if it is an
229203955Srdivacky    /// implicitly-declared default constructor and if:
230203955Srdivacky    /// * its class has no virtual functions and no virtual base classes, and
231203955Srdivacky    /// * all the direct base classes of its class have trivial constructors, and
232203955Srdivacky    /// * for all the nonstatic data members of its class that are of class type
233203955Srdivacky    ///   (or array thereof), each such class has a trivial constructor.
234203955Srdivacky    bool HasTrivialConstructor : 1;
235198092Srdivacky
236203955Srdivacky    /// HasTrivialCopyConstructor - True when this class has a trivial copy
237203955Srdivacky    /// constructor.
238203955Srdivacky    ///
239203955Srdivacky    /// C++ [class.copy]p6.  A copy constructor for class X is trivial
240203955Srdivacky    /// if it is implicitly declared and if
241203955Srdivacky    /// * class X has no virtual functions and no virtual base classes, and
242203955Srdivacky    /// * each direct base class of X has a trivial copy constructor, and
243203955Srdivacky    /// * for all the nonstatic data members of X that are of class type (or
244203955Srdivacky    ///   array thereof), each such class type has a trivial copy constructor;
245203955Srdivacky    /// otherwise the copy constructor is non-trivial.
246203955Srdivacky    bool HasTrivialCopyConstructor : 1;
247203955Srdivacky
248203955Srdivacky    /// HasTrivialCopyAssignment - True when this class has a trivial copy
249203955Srdivacky    /// assignment operator.
250203955Srdivacky    ///
251203955Srdivacky    /// C++ [class.copy]p11.  A copy assignment operator for class X is
252203955Srdivacky    /// trivial if it is implicitly declared and if
253203955Srdivacky    /// * class X has no virtual functions and no virtual base classes, and
254203955Srdivacky    /// * each direct base class of X has a trivial copy assignment operator, and
255203955Srdivacky    /// * for all the nonstatic data members of X that are of class type (or
256203955Srdivacky    ///   array thereof), each such class type has a trivial copy assignment
257203955Srdivacky    ///   operator;
258203955Srdivacky    /// otherwise the copy assignment operator is non-trivial.
259203955Srdivacky    bool HasTrivialCopyAssignment : 1;
260203955Srdivacky
261203955Srdivacky    /// HasTrivialDestructor - True when this class has a trivial destructor.
262203955Srdivacky    ///
263203955Srdivacky    /// C++ [class.dtor]p3.  A destructor is trivial if it is an
264203955Srdivacky    /// implicitly-declared destructor and if:
265203955Srdivacky    /// * all of the direct base classes of its class have trivial destructors
266203955Srdivacky    ///   and
267203955Srdivacky    /// * for all of the non-static data members of its class that are of class
268203955Srdivacky    ///   type (or array thereof), each such class has a trivial destructor.
269203955Srdivacky    bool HasTrivialDestructor : 1;
270203955Srdivacky
271203955Srdivacky    /// ComputedVisibleConversions - True when visible conversion functions are
272203955Srdivacky    /// already computed and are available.
273203955Srdivacky    bool ComputedVisibleConversions : 1;
274193326Sed
275203955Srdivacky    /// Bases - Base classes of this class.
276203955Srdivacky    /// FIXME: This is wasted space for a union.
277203955Srdivacky    CXXBaseSpecifier *Bases;
278193326Sed
279203955Srdivacky    /// NumBases - The number of base class specifiers in Bases.
280203955Srdivacky    unsigned NumBases;
281193326Sed
282203955Srdivacky    /// VBases - direct and indirect virtual base classes of this class.
283203955Srdivacky    CXXBaseSpecifier *VBases;
284198092Srdivacky
285203955Srdivacky    /// NumVBases - The number of virtual base class specifiers in VBases.
286203955Srdivacky    unsigned NumVBases;
287198092Srdivacky
288203955Srdivacky    /// Conversions - Overload set containing the conversion functions
289203955Srdivacky    /// of this C++ class (but not its inherited conversion
290203955Srdivacky    /// functions). Each of the entries in this overload set is a
291203955Srdivacky    /// CXXConversionDecl.
292203955Srdivacky    UnresolvedSet<4> Conversions;
293193326Sed
294203955Srdivacky    /// VisibleConversions - Overload set containing the conversion
295203955Srdivacky    /// functions of this C++ class and all those inherited conversion
296203955Srdivacky    /// functions that are visible in this class. Each of the entries
297203955Srdivacky    /// in this overload set is a CXXConversionDecl or a
298203955Srdivacky    /// FunctionTemplateDecl.
299203955Srdivacky    UnresolvedSet<4> VisibleConversions;
300203955Srdivacky
301203955Srdivacky    /// Definition - The declaration which defines this record.
302203955Srdivacky    CXXRecordDecl *Definition;
303203955Srdivacky
304205219Srdivacky    /// FirstFriend - The first friend declaration in this class, or
305205219Srdivacky    /// null if there aren't any.  This is actually currently stored
306205219Srdivacky    /// in reverse order.
307205219Srdivacky    FriendDecl *FirstFriend;
308205219Srdivacky
309203955Srdivacky  } *DefinitionData;
310203955Srdivacky
311203955Srdivacky  struct DefinitionData &data() {
312203955Srdivacky    assert(DefinitionData && "queried property of class with no definition");
313203955Srdivacky    return *DefinitionData;
314203955Srdivacky  }
315203955Srdivacky
316203955Srdivacky  const struct DefinitionData &data() const {
317203955Srdivacky    assert(DefinitionData && "queried property of class with no definition");
318203955Srdivacky    return *DefinitionData;
319203955Srdivacky  }
320198092Srdivacky
321193326Sed  /// \brief The template or declaration that this declaration
322193326Sed  /// describes or was instantiated from, respectively.
323198092Srdivacky  ///
324193326Sed  /// For non-templates, this value will be NULL. For record
325193326Sed  /// declarations that describe a class template, this will be a
326193326Sed  /// pointer to a ClassTemplateDecl. For member
327193326Sed  /// classes of class template specializations, this will be the
328198092Srdivacky  /// MemberSpecializationInfo referring to the member class that was
329198092Srdivacky  /// instantiated or specialized.
330198092Srdivacky  llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*>
331193326Sed    TemplateOrInstantiation;
332206084Srdivacky
333206084Srdivacky#ifndef NDEBUG
334206084Srdivacky  void CheckConversionFunction(NamedDecl *D);
335206084Srdivacky#endif
336198092Srdivacky
337193326Sedprotected:
338193326Sed  CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
339198092Srdivacky                SourceLocation L, IdentifierInfo *Id,
340198092Srdivacky                CXXRecordDecl *PrevDecl,
341198092Srdivacky                SourceLocation TKL = SourceLocation());
342193326Sed
343193326Sed  ~CXXRecordDecl();
344193326Sed
345193326Sedpublic:
346193326Sed  /// base_class_iterator - Iterator that traverses the base classes
347198092Srdivacky  /// of a class.
348193326Sed  typedef CXXBaseSpecifier*       base_class_iterator;
349193326Sed
350193326Sed  /// base_class_const_iterator - Iterator that traverses the base
351198092Srdivacky  /// classes of a class.
352193326Sed  typedef const CXXBaseSpecifier* base_class_const_iterator;
353193326Sed
354198092Srdivacky  /// reverse_base_class_iterator = Iterator that traverses the base classes
355198092Srdivacky  /// of a class in reverse order.
356198092Srdivacky  typedef std::reverse_iterator<base_class_iterator>
357198092Srdivacky    reverse_base_class_iterator;
358198092Srdivacky
359198092Srdivacky  /// reverse_base_class_iterator = Iterator that traverses the base classes
360198092Srdivacky  /// of a class in reverse order.
361198092Srdivacky  typedef std::reverse_iterator<base_class_const_iterator>
362198092Srdivacky    reverse_base_class_const_iterator;
363198092Srdivacky
364198092Srdivacky  virtual CXXRecordDecl *getCanonicalDecl() {
365198092Srdivacky    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
366198092Srdivacky  }
367199482Srdivacky  virtual const CXXRecordDecl *getCanonicalDecl() const {
368199482Srdivacky    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
369199482Srdivacky  }
370198092Srdivacky
371203955Srdivacky  CXXRecordDecl *getDefinition() const {
372203955Srdivacky    if (!DefinitionData) return 0;
373203955Srdivacky    return data().Definition;
374203955Srdivacky  }
375203955Srdivacky
376203955Srdivacky  bool hasDefinition() const { return DefinitionData != 0; }
377203955Srdivacky
378193326Sed  static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
379193326Sed                               SourceLocation L, IdentifierInfo *Id,
380198092Srdivacky                               SourceLocation TKL = SourceLocation(),
381193326Sed                               CXXRecordDecl* PrevDecl=0,
382193326Sed                               bool DelayTypeCreation = false);
383198092Srdivacky
384195341Sed  virtual void Destroy(ASTContext& C);
385198092Srdivacky
386198092Srdivacky  bool isDynamicClass() const {
387203955Srdivacky    return data().Polymorphic || data().NumVBases != 0;
388198092Srdivacky  }
389198092Srdivacky
390193326Sed  /// setBases - Sets the base classes of this struct or class.
391203955Srdivacky  void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
392193326Sed
393193326Sed  /// getNumBases - Retrieves the number of base classes of this
394193326Sed  /// class.
395203955Srdivacky  unsigned getNumBases() const { return data().NumBases; }
396193326Sed
397203955Srdivacky  base_class_iterator bases_begin() { return data().Bases; }
398203955Srdivacky  base_class_const_iterator bases_begin() const { return data().Bases; }
399203955Srdivacky  base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
400203955Srdivacky  base_class_const_iterator bases_end() const {
401203955Srdivacky    return bases_begin() + data().NumBases;
402203955Srdivacky  }
403198092Srdivacky  reverse_base_class_iterator       bases_rbegin() {
404198092Srdivacky    return reverse_base_class_iterator(bases_end());
405198092Srdivacky  }
406198092Srdivacky  reverse_base_class_const_iterator bases_rbegin() const {
407198092Srdivacky    return reverse_base_class_const_iterator(bases_end());
408198092Srdivacky  }
409198092Srdivacky  reverse_base_class_iterator bases_rend() {
410198092Srdivacky    return reverse_base_class_iterator(bases_begin());
411198092Srdivacky  }
412198092Srdivacky  reverse_base_class_const_iterator bases_rend() const {
413198092Srdivacky    return reverse_base_class_const_iterator(bases_begin());
414198092Srdivacky  }
415193326Sed
416198092Srdivacky  /// getNumVBases - Retrieves the number of virtual base classes of this
417198092Srdivacky  /// class.
418203955Srdivacky  unsigned getNumVBases() const { return data().NumVBases; }
419198092Srdivacky
420203955Srdivacky  base_class_iterator vbases_begin() { return data().VBases; }
421203955Srdivacky  base_class_const_iterator vbases_begin() const { return data().VBases; }
422203955Srdivacky  base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
423203955Srdivacky  base_class_const_iterator vbases_end() const {
424203955Srdivacky    return vbases_begin() + data().NumVBases;
425203955Srdivacky  }
426198092Srdivacky  reverse_base_class_iterator vbases_rbegin() {
427198092Srdivacky    return reverse_base_class_iterator(vbases_end());
428198092Srdivacky  }
429198092Srdivacky  reverse_base_class_const_iterator vbases_rbegin() const {
430198092Srdivacky    return reverse_base_class_const_iterator(vbases_end());
431198092Srdivacky  }
432198092Srdivacky  reverse_base_class_iterator vbases_rend() {
433198092Srdivacky    return reverse_base_class_iterator(vbases_begin());
434198092Srdivacky  }
435198092Srdivacky  reverse_base_class_const_iterator vbases_rend() const {
436198092Srdivacky    return reverse_base_class_const_iterator(vbases_begin());
437198092Srdivacky }
438198092Srdivacky
439202379Srdivacky  /// \brief Determine whether this class has any dependent base classes.
440202379Srdivacky  bool hasAnyDependentBases() const;
441202379Srdivacky
442198092Srdivacky  /// Iterator access to method members.  The method iterator visits
443198092Srdivacky  /// all method members of the class, including non-instance methods,
444198092Srdivacky  /// special methods, etc.
445198092Srdivacky  typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
446198092Srdivacky
447198092Srdivacky  /// method_begin - Method begin iterator.  Iterates in the order the methods
448198092Srdivacky  /// were declared.
449198092Srdivacky  method_iterator method_begin() const {
450198092Srdivacky    return method_iterator(decls_begin());
451198092Srdivacky  }
452198092Srdivacky  /// method_end - Method end iterator.
453198092Srdivacky  method_iterator method_end() const {
454198092Srdivacky    return method_iterator(decls_end());
455198092Srdivacky  }
456198092Srdivacky
457198092Srdivacky  /// Iterator access to constructor members.
458198092Srdivacky  typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
459198092Srdivacky
460198092Srdivacky  ctor_iterator ctor_begin() const {
461198092Srdivacky    return ctor_iterator(decls_begin());
462198092Srdivacky  }
463198092Srdivacky  ctor_iterator ctor_end() const {
464198092Srdivacky    return ctor_iterator(decls_end());
465198092Srdivacky  }
466198092Srdivacky
467205219Srdivacky  /// An iterator over friend declarations.  All of these are defined
468205219Srdivacky  /// in DeclFriend.h.
469205219Srdivacky  class friend_iterator;
470205219Srdivacky  friend_iterator friend_begin() const;
471205219Srdivacky  friend_iterator friend_end() const;
472205219Srdivacky  void pushFriendDecl(FriendDecl *FD);
473205219Srdivacky
474207619Srdivacky  /// Determines whether this record has any friends.
475207619Srdivacky  bool hasFriends() const {
476207619Srdivacky    return data().FirstFriend != 0;
477207619Srdivacky  }
478207619Srdivacky
479193326Sed  /// hasConstCopyConstructor - Determines whether this class has a
480193326Sed  /// copy constructor that accepts a const-qualified argument.
481193326Sed  bool hasConstCopyConstructor(ASTContext &Context) const;
482193326Sed
483194711Sed  /// getCopyConstructor - Returns the copy constructor for this class
484198092Srdivacky  CXXConstructorDecl *getCopyConstructor(ASTContext &Context,
485194711Sed                                         unsigned TypeQuals) const;
486194711Sed
487193326Sed  /// hasConstCopyAssignment - Determines whether this class has a
488193326Sed  /// copy assignment operator that accepts a const-qualified argument.
489198092Srdivacky  /// It returns its decl in MD if found.
490198092Srdivacky  bool hasConstCopyAssignment(ASTContext &Context,
491198092Srdivacky                              const CXXMethodDecl *&MD) const;
492193326Sed
493193326Sed  /// addedConstructor - Notify the class that another constructor has
494193326Sed  /// been added. This routine helps maintain information about the
495193326Sed  /// class based on which constructors have been added.
496193326Sed  void addedConstructor(ASTContext &Context, CXXConstructorDecl *ConDecl);
497193326Sed
498193326Sed  /// hasUserDeclaredConstructor - Whether this class has any
499193326Sed  /// user-declared constructors. When true, a default constructor
500193326Sed  /// will not be implicitly declared.
501198092Srdivacky  bool hasUserDeclaredConstructor() const {
502203955Srdivacky    return data().UserDeclaredConstructor;
503198092Srdivacky  }
504193326Sed
505193326Sed  /// hasUserDeclaredCopyConstructor - Whether this class has a
506193326Sed  /// user-declared copy constructor. When false, a copy constructor
507193326Sed  /// will be implicitly declared.
508193326Sed  bool hasUserDeclaredCopyConstructor() const {
509203955Srdivacky    return data().UserDeclaredCopyConstructor;
510193326Sed  }
511193326Sed
512193326Sed  /// addedAssignmentOperator - Notify the class that another assignment
513193326Sed  /// operator has been added. This routine helps maintain information about the
514193326Sed   /// class based on which operators have been added.
515193326Sed  void addedAssignmentOperator(ASTContext &Context, CXXMethodDecl *OpDecl);
516193326Sed
517193326Sed  /// hasUserDeclaredCopyAssignment - Whether this class has a
518193326Sed  /// user-declared copy assignment operator. When false, a copy
519193326Sed  /// assigment operator will be implicitly declared.
520193326Sed  bool hasUserDeclaredCopyAssignment() const {
521203955Srdivacky    return data().UserDeclaredCopyAssignment;
522193326Sed  }
523193326Sed
524193326Sed  /// hasUserDeclaredDestructor - Whether this class has a
525193326Sed  /// user-declared destructor. When false, a destructor will be
526193326Sed  /// implicitly declared.
527203955Srdivacky  bool hasUserDeclaredDestructor() const {
528203955Srdivacky    return data().UserDeclaredDestructor;
529203955Srdivacky  }
530193326Sed
531193326Sed  /// setUserDeclaredDestructor - Set whether this class has a
532193326Sed  /// user-declared destructor. If not set by the time the class is
533193326Sed  /// fully defined, a destructor will be implicitly declared.
534198092Srdivacky  void setUserDeclaredDestructor(bool UCD) {
535203955Srdivacky    data().UserDeclaredDestructor = UCD;
536193326Sed  }
537193326Sed
538193326Sed  /// getConversions - Retrieve the overload set containing all of the
539193326Sed  /// conversion functions in this class.
540202879Srdivacky  UnresolvedSetImpl *getConversionFunctions() {
541203955Srdivacky    return &data().Conversions;
542193326Sed  }
543202879Srdivacky  const UnresolvedSetImpl *getConversionFunctions() const {
544203955Srdivacky    return &data().Conversions;
545193326Sed  }
546193326Sed
547202879Srdivacky  typedef UnresolvedSetImpl::iterator conversion_iterator;
548203955Srdivacky  conversion_iterator conversion_begin() const {
549203955Srdivacky    return getConversionFunctions()->begin();
550203955Srdivacky  }
551203955Srdivacky  conversion_iterator conversion_end() const {
552203955Srdivacky    return getConversionFunctions()->end();
553203955Srdivacky  }
554199990Srdivacky
555199990Srdivacky  /// Replaces a conversion function with a new declaration.
556199990Srdivacky  ///
557199990Srdivacky  /// Returns true if the old conversion was found.
558199990Srdivacky  bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
559203955Srdivacky    return getConversionFunctions()->replace(Old, New);
560199990Srdivacky  }
561199990Srdivacky
562206084Srdivacky  /// Removes a conversion function from this class.  The conversion
563206084Srdivacky  /// function must currently be a member of this class.  Furthermore,
564206084Srdivacky  /// this class must currently be in the process of being defined.
565206084Srdivacky  void removeConversion(const NamedDecl *Old);
566206084Srdivacky
567198092Srdivacky  /// getVisibleConversionFunctions - get all conversion functions visible
568198092Srdivacky  /// in current class; including conversion function templates.
569202879Srdivacky  const UnresolvedSetImpl *getVisibleConversionFunctions();
570199990Srdivacky
571206084Srdivacky  /// addConversionFunction - Registers a conversion function which
572206084Srdivacky  /// this class declares directly.
573206084Srdivacky  void addConversionFunction(NamedDecl *Decl) {
574206084Srdivacky#ifndef NDEBUG
575206084Srdivacky    CheckConversionFunction(Decl);
576206084Srdivacky#endif
577193326Sed
578206084Srdivacky    // We intentionally don't use the decl's access here because it
579206084Srdivacky    // hasn't been set yet.  That's really just a misdesign in Sema.
580206084Srdivacky    data().Conversions.addDecl(Decl);
581206084Srdivacky  }
582198092Srdivacky
583193326Sed  /// isAggregate - Whether this class is an aggregate (C++
584193326Sed  /// [dcl.init.aggr]), which is a class with no user-declared
585193326Sed  /// constructors, no private or protected non-static data members,
586193326Sed  /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
587203955Srdivacky  bool isAggregate() const { return data().Aggregate; }
588193326Sed
589193326Sed  /// setAggregate - Set whether this class is an aggregate (C++
590193326Sed  /// [dcl.init.aggr]).
591203955Srdivacky  void setAggregate(bool Agg) { data().Aggregate = Agg; }
592193326Sed
593200583Srdivacky  /// setMethodAsVirtual - Make input method virtual and set the necesssary
594200583Srdivacky  /// special function bits and other bits accordingly.
595200583Srdivacky  void setMethodAsVirtual(FunctionDecl *Method);
596200583Srdivacky
597193326Sed  /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
598193326Sed  /// that is an aggregate that has no non-static non-POD data members, no
599193326Sed  /// reference data members, no user-defined copy assignment operator and no
600193326Sed  /// user-defined destructor.
601203955Srdivacky  bool isPOD() const { return data().PlainOldData; }
602193326Sed
603193326Sed  /// setPOD - Set whether this class is a POD-type (C++ [class]p4).
604203955Srdivacky  void setPOD(bool POD) { data().PlainOldData = POD; }
605193326Sed
606198092Srdivacky  /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which
607198092Srdivacky  /// means it has a virtual function, virtual base, data member (other than
608198092Srdivacky  /// 0-width bit-field) or inherits from a non-empty class. Does NOT include
609198092Srdivacky  /// a check for union-ness.
610203955Srdivacky  bool isEmpty() const { return data().Empty; }
611198092Srdivacky
612198092Srdivacky  /// Set whether this class is empty (C++0x [meta.unary.prop])
613203955Srdivacky  void setEmpty(bool Emp) { data().Empty = Emp; }
614198092Srdivacky
615193326Sed  /// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]),
616193326Sed  /// which means that the class contains or inherits a virtual function.
617203955Srdivacky  bool isPolymorphic() const { return data().Polymorphic; }
618193326Sed
619193326Sed  /// setPolymorphic - Set whether this class is polymorphic (C++
620193326Sed  /// [class.virtual]).
621203955Srdivacky  void setPolymorphic(bool Poly) { data().Polymorphic = Poly; }
622193326Sed
623193326Sed  /// isAbstract - Whether this class is abstract (C++ [class.abstract]),
624193326Sed  /// which means that the class contains or inherits a pure virtual function.
625203955Srdivacky  bool isAbstract() const { return data().Abstract; }
626198092Srdivacky
627193326Sed  /// setAbstract - Set whether this class is abstract (C++ [class.abstract])
628203955Srdivacky  void setAbstract(bool Abs) { data().Abstract = Abs; }
629198092Srdivacky
630193326Sed  // hasTrivialConstructor - Whether this class has a trivial constructor
631193326Sed  // (C++ [class.ctor]p5)
632203955Srdivacky  bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
633198092Srdivacky
634193326Sed  // setHasTrivialConstructor - Set whether this class has a trivial constructor
635193326Sed  // (C++ [class.ctor]p5)
636203955Srdivacky  void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; }
637198092Srdivacky
638198092Srdivacky  // hasTrivialCopyConstructor - Whether this class has a trivial copy
639198092Srdivacky  // constructor (C++ [class.copy]p6)
640203955Srdivacky  bool hasTrivialCopyConstructor() const {
641203955Srdivacky    return data().HasTrivialCopyConstructor;
642203955Srdivacky  }
643198092Srdivacky
644198092Srdivacky  // setHasTrivialCopyConstructor - Set whether this class has a trivial
645198092Srdivacky  // copy constructor (C++ [class.copy]p6)
646203955Srdivacky  void setHasTrivialCopyConstructor(bool TC) {
647203955Srdivacky    data().HasTrivialCopyConstructor = TC;
648203955Srdivacky  }
649198092Srdivacky
650198092Srdivacky  // hasTrivialCopyAssignment - Whether this class has a trivial copy
651198092Srdivacky  // assignment operator (C++ [class.copy]p11)
652203955Srdivacky  bool hasTrivialCopyAssignment() const {
653203955Srdivacky    return data().HasTrivialCopyAssignment;
654203955Srdivacky  }
655198092Srdivacky
656198092Srdivacky  // setHasTrivialCopyAssignment - Set whether this class has a
657198092Srdivacky  // trivial copy assignment operator (C++ [class.copy]p11)
658203955Srdivacky  void setHasTrivialCopyAssignment(bool TC) {
659203955Srdivacky    data().HasTrivialCopyAssignment = TC;
660203955Srdivacky  }
661198092Srdivacky
662193326Sed  // hasTrivialDestructor - Whether this class has a trivial destructor
663193326Sed  // (C++ [class.dtor]p3)
664203955Srdivacky  bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
665198092Srdivacky
666193326Sed  // setHasTrivialDestructor - Set whether this class has a trivial destructor
667193326Sed  // (C++ [class.dtor]p3)
668203955Srdivacky  void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; }
669198092Srdivacky
670193326Sed  /// \brief If this record is an instantiation of a member class,
671193326Sed  /// retrieves the member class from which it was instantiated.
672193326Sed  ///
673193326Sed  /// This routine will return non-NULL for (non-templated) member
674193326Sed  /// classes of class templates. For example, given:
675193326Sed  ///
676193326Sed  /// \code
677193326Sed  /// template<typename T>
678193326Sed  /// struct X {
679193326Sed  ///   struct A { };
680193326Sed  /// };
681193326Sed  /// \endcode
682193326Sed  ///
683193326Sed  /// The declaration for X<int>::A is a (non-templated) CXXRecordDecl
684193326Sed  /// whose parent is the class template specialization X<int>. For
685193326Sed  /// this declaration, getInstantiatedFromMemberClass() will return
686193326Sed  /// the CXXRecordDecl X<T>::A. When a complete definition of
687193326Sed  /// X<int>::A is required, it will be instantiated from the
688193326Sed  /// declaration returned by getInstantiatedFromMemberClass().
689198092Srdivacky  CXXRecordDecl *getInstantiatedFromMemberClass() const;
690198092Srdivacky
691198092Srdivacky  /// \brief If this class is an instantiation of a member class of a
692198092Srdivacky  /// class template specialization, retrieves the member specialization
693198092Srdivacky  /// information.
694198092Srdivacky  MemberSpecializationInfo *getMemberSpecializationInfo() const;
695198092Srdivacky
696193326Sed  /// \brief Specify that this record is an instantiation of the
697193326Sed  /// member class RD.
698198092Srdivacky  void setInstantiationOfMemberClass(CXXRecordDecl *RD,
699198092Srdivacky                                     TemplateSpecializationKind TSK);
700193326Sed
701193326Sed  /// \brief Retrieves the class template that is described by this
702193326Sed  /// class declaration.
703193326Sed  ///
704193326Sed  /// Every class template is represented as a ClassTemplateDecl and a
705193326Sed  /// CXXRecordDecl. The former contains template properties (such as
706193326Sed  /// the template parameter lists) while the latter contains the
707193326Sed  /// actual description of the template's
708193326Sed  /// contents. ClassTemplateDecl::getTemplatedDecl() retrieves the
709193326Sed  /// CXXRecordDecl that from a ClassTemplateDecl, while
710193326Sed  /// getDescribedClassTemplate() retrieves the ClassTemplateDecl from
711193326Sed  /// a CXXRecordDecl.
712193326Sed  ClassTemplateDecl *getDescribedClassTemplate() const {
713193326Sed    return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl*>();
714193326Sed  }
715193326Sed
716193326Sed  void setDescribedClassTemplate(ClassTemplateDecl *Template) {
717193326Sed    TemplateOrInstantiation = Template;
718193326Sed  }
719193326Sed
720198092Srdivacky  /// \brief Determine whether this particular class is a specialization or
721198092Srdivacky  /// instantiation of a class template or member class of a class template,
722198092Srdivacky  /// and how it was instantiated or specialized.
723200583Srdivacky  TemplateSpecializationKind getTemplateSpecializationKind() const;
724198092Srdivacky
725198092Srdivacky  /// \brief Set the kind of specialization or template instantiation this is.
726198092Srdivacky  void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
727198092Srdivacky
728194613Sed  /// getDefaultConstructor - Returns the default constructor for this class
729194613Sed  CXXConstructorDecl *getDefaultConstructor(ASTContext &Context);
730198092Srdivacky
731193326Sed  /// getDestructor - Returns the destructor decl for this class.
732204643Srdivacky  CXXDestructorDecl *getDestructor(ASTContext &Context) const;
733198092Srdivacky
734195099Sed  /// isLocalClass - If the class is a local class [class.local], returns
735195099Sed  /// the enclosing function declaration.
736195099Sed  const FunctionDecl *isLocalClass() const {
737195099Sed    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
738195099Sed      return RD->isLocalClass();
739198092Srdivacky
740195099Sed    return dyn_cast<FunctionDecl>(getDeclContext());
741195099Sed  }
742198092Srdivacky
743198092Srdivacky  /// \brief Determine whether this class is derived from the class \p Base.
744198092Srdivacky  ///
745198092Srdivacky  /// This routine only determines whether this class is derived from \p Base,
746198092Srdivacky  /// but does not account for factors that may make a Derived -> Base class
747198092Srdivacky  /// ill-formed, such as private/protected inheritance or multiple, ambiguous
748198092Srdivacky  /// base class subobjects.
749198092Srdivacky  ///
750198092Srdivacky  /// \param Base the base class we are searching for.
751198092Srdivacky  ///
752198092Srdivacky  /// \returns true if this class is derived from Base, false otherwise.
753199482Srdivacky  bool isDerivedFrom(CXXRecordDecl *Base) const;
754195099Sed
755198092Srdivacky  /// \brief Determine whether this class is derived from the type \p Base.
756198092Srdivacky  ///
757198092Srdivacky  /// This routine only determines whether this class is derived from \p Base,
758198092Srdivacky  /// but does not account for factors that may make a Derived -> Base class
759198092Srdivacky  /// ill-formed, such as private/protected inheritance or multiple, ambiguous
760198092Srdivacky  /// base class subobjects.
761198092Srdivacky  ///
762198092Srdivacky  /// \param Base the base class we are searching for.
763198092Srdivacky  ///
764198092Srdivacky  /// \param Paths will contain the paths taken from the current class to the
765198092Srdivacky  /// given \p Base class.
766198092Srdivacky  ///
767198092Srdivacky  /// \returns true if this class is derived from Base, false otherwise.
768198092Srdivacky  ///
769198092Srdivacky  /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
770198092Srdivacky  /// tangling input and output in \p Paths
771199482Srdivacky  bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const;
772200583Srdivacky
773204643Srdivacky  /// \brief Determine whether this class is virtually derived from
774204643Srdivacky  /// the class \p Base.
775204643Srdivacky  ///
776204643Srdivacky  /// This routine only determines whether this class is virtually
777204643Srdivacky  /// derived from \p Base, but does not account for factors that may
778204643Srdivacky  /// make a Derived -> Base class ill-formed, such as
779204643Srdivacky  /// private/protected inheritance or multiple, ambiguous base class
780204643Srdivacky  /// subobjects.
781204643Srdivacky  ///
782204643Srdivacky  /// \param Base the base class we are searching for.
783204643Srdivacky  ///
784204643Srdivacky  /// \returns true if this class is virtually derived from Base,
785204643Srdivacky  /// false otherwise.
786204643Srdivacky  bool isVirtuallyDerivedFrom(CXXRecordDecl *Base) const;
787204643Srdivacky
788200583Srdivacky  /// \brief Determine whether this class is provably not derived from
789200583Srdivacky  /// the type \p Base.
790200583Srdivacky  bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const;
791200583Srdivacky
792200583Srdivacky  /// \brief Function type used by forallBases() as a callback.
793200583Srdivacky  ///
794200583Srdivacky  /// \param Base the definition of the base class
795200583Srdivacky  ///
796200583Srdivacky  /// \returns true if this base matched the search criteria
797200583Srdivacky  typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition,
798200583Srdivacky                                   void *UserData);
799200583Srdivacky
800200583Srdivacky  /// \brief Determines if the given callback holds for all the direct
801200583Srdivacky  /// or indirect base classes of this type.
802200583Srdivacky  ///
803200583Srdivacky  /// The class itself does not count as a base class.  This routine
804200583Srdivacky  /// returns false if the class has non-computable base classes.
805200583Srdivacky  ///
806200583Srdivacky  /// \param AllowShortCircuit if false, forces the callback to be called
807200583Srdivacky  /// for every base class, even if a dependent or non-matching base was
808200583Srdivacky  /// found.
809200583Srdivacky  bool forallBases(ForallBasesCallback *BaseMatches, void *UserData,
810200583Srdivacky                   bool AllowShortCircuit = true) const;
811198092Srdivacky
812198092Srdivacky  /// \brief Function type used by lookupInBases() to determine whether a
813198092Srdivacky  /// specific base class subobject matches the lookup criteria.
814198092Srdivacky  ///
815198092Srdivacky  /// \param Specifier the base-class specifier that describes the inheritance
816198092Srdivacky  /// from the base class we are trying to match.
817198092Srdivacky  ///
818198092Srdivacky  /// \param Path the current path, from the most-derived class down to the
819198092Srdivacky  /// base named by the \p Specifier.
820198092Srdivacky  ///
821198092Srdivacky  /// \param UserData a single pointer to user-specified data, provided to
822198092Srdivacky  /// lookupInBases().
823198092Srdivacky  ///
824198092Srdivacky  /// \returns true if this base matched the search criteria, false otherwise.
825199482Srdivacky  typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier,
826198092Srdivacky                                   CXXBasePath &Path,
827198092Srdivacky                                   void *UserData);
828198092Srdivacky
829198092Srdivacky  /// \brief Look for entities within the base classes of this C++ class,
830198092Srdivacky  /// transitively searching all base class subobjects.
831198092Srdivacky  ///
832198092Srdivacky  /// This routine uses the callback function \p BaseMatches to find base
833198092Srdivacky  /// classes meeting some search criteria, walking all base class subobjects
834198092Srdivacky  /// and populating the given \p Paths structure with the paths through the
835198092Srdivacky  /// inheritance hierarchy that resulted in a match. On a successful search,
836198092Srdivacky  /// the \p Paths structure can be queried to retrieve the matching paths and
837198092Srdivacky  /// to determine if there were any ambiguities.
838198092Srdivacky  ///
839198092Srdivacky  /// \param BaseMatches callback function used to determine whether a given
840198092Srdivacky  /// base matches the user-defined search criteria.
841198092Srdivacky  ///
842198092Srdivacky  /// \param UserData user data pointer that will be provided to \p BaseMatches.
843198092Srdivacky  ///
844198092Srdivacky  /// \param Paths used to record the paths from this class to its base class
845198092Srdivacky  /// subobjects that match the search criteria.
846198092Srdivacky  ///
847198092Srdivacky  /// \returns true if there exists any path from this class to a base class
848198092Srdivacky  /// subobject that matches the search criteria.
849198092Srdivacky  bool lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData,
850199482Srdivacky                     CXXBasePaths &Paths) const;
851198092Srdivacky
852198092Srdivacky  /// \brief Base-class lookup callback that determines whether the given
853198092Srdivacky  /// base class specifier refers to a specific class declaration.
854198092Srdivacky  ///
855198092Srdivacky  /// This callback can be used with \c lookupInBases() to determine whether
856198092Srdivacky  /// a given derived class has is a base class subobject of a particular type.
857198092Srdivacky  /// The user data pointer should refer to the canonical CXXRecordDecl of the
858198092Srdivacky  /// base class that we are searching for.
859199482Srdivacky  static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
860199482Srdivacky                            CXXBasePath &Path, void *BaseRecord);
861204643Srdivacky
862204643Srdivacky  /// \brief Base-class lookup callback that determines whether the
863204643Srdivacky  /// given base class specifier refers to a specific class
864204643Srdivacky  /// declaration and describes virtual derivation.
865204643Srdivacky  ///
866204643Srdivacky  /// This callback can be used with \c lookupInBases() to determine
867204643Srdivacky  /// whether a given derived class has is a virtual base class
868204643Srdivacky  /// subobject of a particular type.  The user data pointer should
869204643Srdivacky  /// refer to the canonical CXXRecordDecl of the base class that we
870204643Srdivacky  /// are searching for.
871204643Srdivacky  static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
872204643Srdivacky                                   CXXBasePath &Path, void *BaseRecord);
873198092Srdivacky
874198092Srdivacky  /// \brief Base-class lookup callback that determines whether there exists
875198092Srdivacky  /// a tag with the given name.
876198092Srdivacky  ///
877198092Srdivacky  /// This callback can be used with \c lookupInBases() to find tag members
878198092Srdivacky  /// of the given name within a C++ class hierarchy. The user data pointer
879198092Srdivacky  /// is an opaque \c DeclarationName pointer.
880199482Srdivacky  static bool FindTagMember(const CXXBaseSpecifier *Specifier,
881199482Srdivacky                            CXXBasePath &Path, void *Name);
882198092Srdivacky
883198092Srdivacky  /// \brief Base-class lookup callback that determines whether there exists
884198092Srdivacky  /// a member with the given name.
885198092Srdivacky  ///
886198092Srdivacky  /// This callback can be used with \c lookupInBases() to find members
887198092Srdivacky  /// of the given name within a C++ class hierarchy. The user data pointer
888198092Srdivacky  /// is an opaque \c DeclarationName pointer.
889199482Srdivacky  static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
890199482Srdivacky                                 CXXBasePath &Path, void *Name);
891198092Srdivacky
892198092Srdivacky  /// \brief Base-class lookup callback that determines whether there exists
893198092Srdivacky  /// a member with the given name that can be used in a nested-name-specifier.
894198092Srdivacky  ///
895198092Srdivacky  /// This callback can be used with \c lookupInBases() to find membes of
896198092Srdivacky  /// the given name within a C++ class hierarchy that can occur within
897198092Srdivacky  /// nested-name-specifiers.
898199482Srdivacky  static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
899198092Srdivacky                                            CXXBasePath &Path,
900198092Srdivacky                                            void *UserData);
901206084Srdivacky
902206084Srdivacky  /// \brief Retrieve the final overriders for each virtual member
903206084Srdivacky  /// function in the class hierarchy where this class is the
904206084Srdivacky  /// most-derived class in the class hierarchy.
905206084Srdivacky  void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const;
906206084Srdivacky
907193326Sed  /// viewInheritance - Renders and displays an inheritance diagram
908193326Sed  /// for this C++ class and all of its base classes (transitively) using
909193326Sed  /// GraphViz.
910193326Sed  void viewInheritance(ASTContext& Context) const;
911193326Sed
912202879Srdivacky  /// MergeAccess - Calculates the access of a decl that is reached
913202879Srdivacky  /// along a path.
914202879Srdivacky  static AccessSpecifier MergeAccess(AccessSpecifier PathAccess,
915202879Srdivacky                                     AccessSpecifier DeclAccess) {
916202879Srdivacky    assert(DeclAccess != AS_none);
917202879Srdivacky    if (DeclAccess == AS_private) return AS_none;
918202879Srdivacky    return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
919202879Srdivacky  }
920202879Srdivacky
921203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
922203955Srdivacky  static bool classofKind(Kind K) {
923203955Srdivacky    return K == CXXRecord ||
924203955Srdivacky           K == ClassTemplateSpecialization ||
925203955Srdivacky           K == ClassTemplatePartialSpecialization;
926193326Sed  }
927193326Sed  static bool classof(const CXXRecordDecl *D) { return true; }
928198092Srdivacky  static bool classof(const ClassTemplateSpecializationDecl *D) {
929198092Srdivacky    return true;
930193326Sed  }
931193326Sed};
932193326Sed
933193326Sed/// CXXMethodDecl - Represents a static or instance method of a
934193326Sed/// struct/union/class.
935193326Sedclass CXXMethodDecl : public FunctionDecl {
936193326Sedprotected:
937193326Sed  CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L,
938200583Srdivacky                DeclarationName N, QualType T, TypeSourceInfo *TInfo,
939207619Srdivacky                bool isStatic, StorageClass SCAsWritten, bool isInline)
940200583Srdivacky    : FunctionDecl(DK, RD, L, N, T, TInfo, (isStatic ? Static : None),
941207619Srdivacky                   SCAsWritten, isInline) {}
942193326Sed
943193326Sedpublic:
944193326Sed  static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
945193326Sed                              SourceLocation L, DeclarationName N,
946200583Srdivacky                              QualType T, TypeSourceInfo *TInfo,
947198092Srdivacky                              bool isStatic = false,
948207619Srdivacky                              StorageClass SCAsWritten = FunctionDecl::None,
949193326Sed                              bool isInline = false);
950198092Srdivacky
951193326Sed  bool isStatic() const { return getStorageClass() == Static; }
952193326Sed  bool isInstance() const { return !isStatic(); }
953193326Sed
954198092Srdivacky  bool isVirtual() const {
955198092Srdivacky    CXXMethodDecl *CD =
956198092Srdivacky      cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
957198092Srdivacky
958198092Srdivacky    if (CD->isVirtualAsWritten())
959198092Srdivacky      return true;
960198092Srdivacky
961198092Srdivacky    return (CD->begin_overridden_methods() != CD->end_overridden_methods());
962193326Sed  }
963206084Srdivacky
964198092Srdivacky  /// \brief Determine whether this is a usual deallocation function
965198092Srdivacky  /// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
966198092Srdivacky  /// delete or delete[] operator with a particular signature.
967198092Srdivacky  bool isUsualDeallocationFunction() const;
968198092Srdivacky
969207619Srdivacky  /// \brief Determine whether this is a copy-assignment operator, regardless
970207619Srdivacky  /// of whether it was declared implicitly or explicitly.
971207619Srdivacky  bool isCopyAssignmentOperator() const;
972207619Srdivacky
973198092Srdivacky  const CXXMethodDecl *getCanonicalDecl() const {
974198092Srdivacky    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
975198092Srdivacky  }
976198092Srdivacky  CXXMethodDecl *getCanonicalDecl() {
977198092Srdivacky    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
978198092Srdivacky  }
979198092Srdivacky
980198092Srdivacky  ///
981198092Srdivacky  void addOverriddenMethod(const CXXMethodDecl *MD);
982193326Sed
983193326Sed  typedef const CXXMethodDecl ** method_iterator;
984198092Srdivacky
985193326Sed  method_iterator begin_overridden_methods() const;
986193326Sed  method_iterator end_overridden_methods() const;
987198092Srdivacky
988193326Sed  /// getParent - Returns the parent of this method declaration, which
989193326Sed  /// is the class in which this method is defined.
990198092Srdivacky  const CXXRecordDecl *getParent() const {
991198092Srdivacky    return cast<CXXRecordDecl>(FunctionDecl::getParent());
992193326Sed  }
993198092Srdivacky
994193326Sed  /// getParent - Returns the parent of this method declaration, which
995193326Sed  /// is the class in which this method is defined.
996198092Srdivacky  CXXRecordDecl *getParent() {
997193326Sed    return const_cast<CXXRecordDecl *>(
998193326Sed             cast<CXXRecordDecl>(FunctionDecl::getParent()));
999193326Sed  }
1000193326Sed
1001193326Sed  /// getThisType - Returns the type of 'this' pointer.
1002193326Sed  /// Should only be called for instance methods.
1003193326Sed  QualType getThisType(ASTContext &C) const;
1004193326Sed
1005193326Sed  unsigned getTypeQualifiers() const {
1006198092Srdivacky    return getType()->getAs<FunctionProtoType>()->getTypeQuals();
1007193326Sed  }
1008193326Sed
1009200583Srdivacky  bool hasInlineBody() const;
1010200583Srdivacky
1011193326Sed  // Implement isa/cast/dyncast/etc.
1012203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1013203955Srdivacky  static bool classof(const CXXMethodDecl *D) { return true; }
1014203955Srdivacky  static bool classofKind(Kind K) {
1015203955Srdivacky    return K >= CXXMethod && K <= CXXConversion;
1016193326Sed  }
1017193326Sed};
1018193326Sed
1019193326Sed/// CXXBaseOrMemberInitializer - Represents a C++ base or member
1020193326Sed/// initializer, which is part of a constructor initializer that
1021193326Sed/// initializes one non-static member variable or one base class. For
1022193326Sed/// example, in the following, both 'A(a)' and 'f(3.14159)' are member
1023193326Sed/// initializers:
1024193326Sed///
1025193326Sed/// @code
1026193326Sed/// class A { };
1027193326Sed/// class B : public A {
1028193326Sed///   float f;
1029193326Sed/// public:
1030193326Sed///   B(A& a) : A(a), f(3.14159) { }
1031193326Sed/// };
1032194613Sed/// @endcode
1033193326Sedclass CXXBaseOrMemberInitializer {
1034200583Srdivacky  /// \brief Either the base class name (stored as a TypeSourceInfo*) or the
1035200583Srdivacky  /// field being initialized.
1036200583Srdivacky  llvm::PointerUnion<TypeSourceInfo *, FieldDecl *> BaseOrMember;
1037200583Srdivacky
1038200583Srdivacky  /// \brief The source location for the field name.
1039200583Srdivacky  SourceLocation MemberLocation;
1040200583Srdivacky
1041203955Srdivacky  /// \brief The argument used to initialize the base or member, which may
1042203955Srdivacky  /// end up constructing an object (when multiple arguments are involved).
1043203955Srdivacky  Stmt *Init;
1044198092Srdivacky
1045198092Srdivacky  /// \brief Stores either the constructor to call to initialize this base or
1046198092Srdivacky  /// member (a CXXConstructorDecl pointer), or stores the anonymous union of
1047198092Srdivacky  /// which the initialized value is a member.
1048198092Srdivacky  ///
1049198092Srdivacky  /// When the value is a FieldDecl pointer, 'BaseOrMember' is class's
1050198092Srdivacky  /// anonymous union data member, this field holds the FieldDecl for the
1051198092Srdivacky  /// member of the anonymous union being initialized.
1052198092Srdivacky  /// @code
1053198092Srdivacky  /// struct X {
1054198092Srdivacky  ///   X() : au_i1(123) {}
1055198092Srdivacky  ///   union {
1056198092Srdivacky  ///     int au_i1;
1057198092Srdivacky  ///     float au_f1;
1058198092Srdivacky  ///   };
1059198092Srdivacky  /// };
1060198092Srdivacky  /// @endcode
1061198092Srdivacky  /// In above example, BaseOrMember holds the field decl. for anonymous union
1062198092Srdivacky  /// and AnonUnionMember holds field decl for au_i1.
1063203955Srdivacky  FieldDecl *AnonUnionMember;
1064198092Srdivacky
1065207619Srdivacky  /// IsVirtual - If the initializer is a base initializer, this keeps track
1066207619Srdivacky  /// of whether the base is virtual or not.
1067207619Srdivacky  bool IsVirtual;
1068207619Srdivacky
1069200583Srdivacky  /// LParenLoc - Location of the left paren of the ctor-initializer.
1070200583Srdivacky  SourceLocation LParenLoc;
1071193326Sed
1072198092Srdivacky  /// RParenLoc - Location of the right paren of the ctor-initializer.
1073198092Srdivacky  SourceLocation RParenLoc;
1074198092Srdivacky
1075193326Sedpublic:
1076193326Sed  /// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
1077198092Srdivacky  explicit
1078200583Srdivacky  CXXBaseOrMemberInitializer(ASTContext &Context,
1079207619Srdivacky                             TypeSourceInfo *TInfo, bool IsVirtual,
1080200583Srdivacky                             SourceLocation L,
1081203955Srdivacky                             Expr *Init,
1082200583Srdivacky                             SourceLocation R);
1083193326Sed
1084193326Sed  /// CXXBaseOrMemberInitializer - Creates a new member initializer.
1085198092Srdivacky  explicit
1086200583Srdivacky  CXXBaseOrMemberInitializer(ASTContext &Context,
1087200583Srdivacky                             FieldDecl *Member, SourceLocation MemberLoc,
1088203955Srdivacky                             SourceLocation L,
1089203955Srdivacky                             Expr *Init,
1090200583Srdivacky                             SourceLocation R);
1091193326Sed
1092200583Srdivacky  /// \brief Destroy the base or member initializer.
1093200583Srdivacky  void Destroy(ASTContext &Context);
1094193326Sed
1095193326Sed  /// isBaseInitializer - Returns true when this initializer is
1096193326Sed  /// initializing a base class.
1097200583Srdivacky  bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); }
1098193326Sed
1099193326Sed  /// isMemberInitializer - Returns true when this initializer is
1100193326Sed  /// initializing a non-static data member.
1101200583Srdivacky  bool isMemberInitializer() const { return BaseOrMember.is<FieldDecl*>(); }
1102193326Sed
1103200583Srdivacky  /// If this is a base class initializer, returns the type of the
1104200583Srdivacky  /// base class with location information. Otherwise, returns an NULL
1105200583Srdivacky  /// type location.
1106200583Srdivacky  TypeLoc getBaseClassLoc() const;
1107193326Sed
1108200583Srdivacky  /// If this is a base class initializer, returns the type of the base class.
1109200583Srdivacky  /// Otherwise, returns NULL.
1110200583Srdivacky  const Type *getBaseClass() const;
1111200583Srdivacky  Type *getBaseClass();
1112207619Srdivacky
1113207619Srdivacky  /// Returns whether the base is virtual or not.
1114207619Srdivacky  bool isBaseVirtual() const {
1115207619Srdivacky    assert(isBaseInitializer() && "Must call this on base initializer!");
1116207619Srdivacky
1117207619Srdivacky    return IsVirtual;
1118207619Srdivacky  }
1119207619Srdivacky
1120200583Srdivacky  /// \brief Returns the declarator information for a base class initializer.
1121200583Srdivacky  TypeSourceInfo *getBaseClassInfo() const {
1122200583Srdivacky    return BaseOrMember.dyn_cast<TypeSourceInfo *>();
1123193326Sed  }
1124200583Srdivacky
1125193326Sed  /// getMember - If this is a member initializer, returns the
1126193326Sed  /// declaration of the non-static data member being
1127193326Sed  /// initialized. Otherwise, returns NULL.
1128198092Srdivacky  FieldDecl *getMember() {
1129193326Sed    if (isMemberInitializer())
1130200583Srdivacky      return BaseOrMember.get<FieldDecl*>();
1131193326Sed    else
1132193326Sed      return 0;
1133193326Sed  }
1134193326Sed
1135200583Srdivacky  SourceLocation getMemberLocation() const {
1136200583Srdivacky    return MemberLocation;
1137198092Srdivacky  }
1138198092Srdivacky
1139200583Srdivacky  void setMember(FieldDecl *Member) {
1140200583Srdivacky    assert(isMemberInitializer());
1141200583Srdivacky    BaseOrMember = Member;
1142200583Srdivacky  }
1143200583Srdivacky
1144200583Srdivacky  /// \brief Determine the source location of the initializer.
1145200583Srdivacky  SourceLocation getSourceLocation() const;
1146200583Srdivacky
1147200583Srdivacky  /// \brief Determine the source range covering the entire initializer.
1148200583Srdivacky  SourceRange getSourceRange() const;
1149200583Srdivacky
1150198092Srdivacky  FieldDecl *getAnonUnionMember() const {
1151203955Srdivacky    return AnonUnionMember;
1152198092Srdivacky  }
1153198092Srdivacky  void setAnonUnionMember(FieldDecl *anonMember) {
1154203955Srdivacky    AnonUnionMember = anonMember;
1155198092Srdivacky  }
1156198092Srdivacky
1157200583Srdivacky  SourceLocation getLParenLoc() const { return LParenLoc; }
1158198092Srdivacky  SourceLocation getRParenLoc() const { return RParenLoc; }
1159193326Sed
1160203955Srdivacky  Expr *getInit() { return static_cast<Expr *>(Init); }
1161193326Sed};
1162193326Sed
1163193326Sed/// CXXConstructorDecl - Represents a C++ constructor within a
1164193326Sed/// class. For example:
1165198092Srdivacky///
1166193326Sed/// @code
1167193326Sed/// class X {
1168193326Sed/// public:
1169193326Sed///   explicit X(int); // represented by a CXXConstructorDecl.
1170193326Sed/// };
1171193326Sed/// @endcode
1172193326Sedclass CXXConstructorDecl : public CXXMethodDecl {
1173203955Srdivacky  /// IsExplicitSpecified - Whether this constructor declaration has the
1174203955Srdivacky  /// 'explicit' keyword specified.
1175203955Srdivacky  bool IsExplicitSpecified : 1;
1176193326Sed
1177193326Sed  /// ImplicitlyDefined - Whether this constructor was implicitly
1178193326Sed  /// defined by the compiler. When false, the constructor was defined
1179193326Sed  /// by the user. In C++03, this flag will have the same value as
1180193326Sed  /// Implicit. In C++0x, however, a constructor that is
1181193326Sed  /// explicitly defaulted (i.e., defined with " = default") will have
1182193326Sed  /// @c !Implicit && ImplicitlyDefined.
1183193326Sed  bool ImplicitlyDefined : 1;
1184198092Srdivacky
1185195341Sed  /// Support for base and member initializers.
1186198092Srdivacky  /// BaseOrMemberInitializers - The arguments used to initialize the base
1187195341Sed  /// or member.
1188195341Sed  CXXBaseOrMemberInitializer **BaseOrMemberInitializers;
1189195341Sed  unsigned NumBaseOrMemberInitializers;
1190198092Srdivacky
1191193326Sed  CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
1192200583Srdivacky                     DeclarationName N, QualType T, TypeSourceInfo *TInfo,
1193203955Srdivacky                     bool isExplicitSpecified, bool isInline,
1194203955Srdivacky                     bool isImplicitlyDeclared)
1195207619Srdivacky    : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false,
1196207619Srdivacky                    FunctionDecl::None, isInline),
1197203955Srdivacky      IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
1198198092Srdivacky      BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
1199193326Sed    setImplicit(isImplicitlyDeclared);
1200193326Sed  }
1201195341Sed  virtual void Destroy(ASTContext& C);
1202198092Srdivacky
1203193326Sedpublic:
1204193326Sed  static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
1205193326Sed                                    SourceLocation L, DeclarationName N,
1206200583Srdivacky                                    QualType T, TypeSourceInfo *TInfo,
1207198092Srdivacky                                    bool isExplicit,
1208193326Sed                                    bool isInline, bool isImplicitlyDeclared);
1209193326Sed
1210203955Srdivacky  /// isExplicitSpecified - Whether this constructor declaration has the
1211203955Srdivacky  /// 'explicit' keyword specified.
1212203955Srdivacky  bool isExplicitSpecified() const { return IsExplicitSpecified; }
1213203955Srdivacky
1214198092Srdivacky  /// isExplicit - Whether this constructor was marked "explicit" or not.
1215203955Srdivacky  bool isExplicit() const {
1216203955Srdivacky    return cast<CXXConstructorDecl>(getFirstDeclaration())
1217203955Srdivacky      ->isExplicitSpecified();
1218203955Srdivacky  }
1219193326Sed
1220193326Sed  /// isImplicitlyDefined - Whether this constructor was implicitly
1221193326Sed  /// defined. If false, then this constructor was defined by the
1222193326Sed  /// user. This operation can only be invoked if the constructor has
1223193326Sed  /// already been defined.
1224207619Srdivacky  bool isImplicitlyDefined() const {
1225198092Srdivacky    assert(isThisDeclarationADefinition() &&
1226195341Sed           "Can only get the implicit-definition flag once the "
1227195341Sed           "constructor has been defined");
1228198092Srdivacky    return ImplicitlyDefined;
1229193326Sed  }
1230193326Sed
1231193326Sed  /// setImplicitlyDefined - Set whether this constructor was
1232193326Sed  /// implicitly defined or not.
1233198092Srdivacky  void setImplicitlyDefined(bool ID) {
1234198092Srdivacky    assert(isThisDeclarationADefinition() &&
1235195341Sed           "Can only set the implicit-definition flag once the constructor "
1236195341Sed           "has been defined");
1237198092Srdivacky    ImplicitlyDefined = ID;
1238193326Sed  }
1239198092Srdivacky
1240195341Sed  /// init_iterator - Iterates through the member/base initializer list.
1241195341Sed  typedef CXXBaseOrMemberInitializer **init_iterator;
1242198092Srdivacky
1243195341Sed  /// init_const_iterator - Iterates through the memberbase initializer list.
1244195341Sed  typedef CXXBaseOrMemberInitializer * const * init_const_iterator;
1245198092Srdivacky
1246198092Srdivacky  /// init_begin() - Retrieve an iterator to the first initializer.
1247198092Srdivacky  init_iterator       init_begin()       { return BaseOrMemberInitializers; }
1248195341Sed  /// begin() - Retrieve an iterator to the first initializer.
1249198092Srdivacky  init_const_iterator init_begin() const { return BaseOrMemberInitializers; }
1250198092Srdivacky
1251198092Srdivacky  /// init_end() - Retrieve an iterator past the last initializer.
1252198092Srdivacky  init_iterator       init_end()       {
1253198092Srdivacky    return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
1254195341Sed  }
1255195341Sed  /// end() - Retrieve an iterator past the last initializer.
1256198092Srdivacky  init_const_iterator init_end() const {
1257198092Srdivacky    return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
1258195341Sed  }
1259198092Srdivacky
1260195341Sed  /// getNumArgs - Determine the number of arguments used to
1261195341Sed  /// initialize the member or base.
1262198092Srdivacky  unsigned getNumBaseOrMemberInitializers() const {
1263198092Srdivacky      return NumBaseOrMemberInitializers;
1264195341Sed  }
1265198092Srdivacky
1266198092Srdivacky  void setNumBaseOrMemberInitializers(unsigned numBaseOrMemberInitializers) {
1267198092Srdivacky    NumBaseOrMemberInitializers = numBaseOrMemberInitializers;
1268198092Srdivacky  }
1269198092Srdivacky
1270198092Srdivacky  void setBaseOrMemberInitializers(CXXBaseOrMemberInitializer ** initializers) {
1271198092Srdivacky    BaseOrMemberInitializers = initializers;
1272198092Srdivacky  }
1273193326Sed  /// isDefaultConstructor - Whether this constructor is a default
1274193326Sed  /// constructor (C++ [class.ctor]p5), which can be used to
1275193326Sed  /// default-initialize a class of this type.
1276193326Sed  bool isDefaultConstructor() const;
1277193326Sed
1278193326Sed  /// isCopyConstructor - Whether this constructor is a copy
1279193326Sed  /// constructor (C++ [class.copy]p2, which can be used to copy the
1280193326Sed  /// class. @p TypeQuals will be set to the qualifiers on the
1281193326Sed  /// argument type. For example, @p TypeQuals would be set to @c
1282193326Sed  /// QualType::Const for the following copy constructor:
1283193326Sed  ///
1284193326Sed  /// @code
1285193326Sed  /// class X {
1286193326Sed  /// public:
1287193326Sed  ///   X(const X&);
1288193326Sed  /// };
1289193326Sed  /// @endcode
1290201361Srdivacky  bool isCopyConstructor(unsigned &TypeQuals) const;
1291193326Sed
1292193326Sed  /// isCopyConstructor - Whether this constructor is a copy
1293193326Sed  /// constructor (C++ [class.copy]p2, which can be used to copy the
1294193326Sed  /// class.
1295201361Srdivacky  bool isCopyConstructor() const {
1296193326Sed    unsigned TypeQuals = 0;
1297201361Srdivacky    return isCopyConstructor(TypeQuals);
1298193326Sed  }
1299193326Sed
1300193326Sed  /// isConvertingConstructor - Whether this constructor is a
1301193326Sed  /// converting constructor (C++ [class.conv.ctor]), which can be
1302193326Sed  /// used for user-defined conversions.
1303198092Srdivacky  bool isConvertingConstructor(bool AllowExplicit) const;
1304193326Sed
1305199482Srdivacky  /// \brief Determine whether this is a member template specialization that
1306199482Srdivacky  /// looks like a copy constructor. Such constructors are never used to copy
1307199482Srdivacky  /// an object.
1308199482Srdivacky  bool isCopyConstructorLikeSpecialization() const;
1309199482Srdivacky
1310193326Sed  // Implement isa/cast/dyncast/etc.
1311203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1312193326Sed  static bool classof(const CXXConstructorDecl *D) { return true; }
1313203955Srdivacky  static bool classofKind(Kind K) { return K == CXXConstructor; }
1314193326Sed};
1315193326Sed
1316193326Sed/// CXXDestructorDecl - Represents a C++ destructor within a
1317193326Sed/// class. For example:
1318198092Srdivacky///
1319193326Sed/// @code
1320193326Sed/// class X {
1321193326Sed/// public:
1322193326Sed///   ~X(); // represented by a CXXDestructorDecl.
1323193326Sed/// };
1324193326Sed/// @endcode
1325193326Sedclass CXXDestructorDecl : public CXXMethodDecl {
1326193326Sed  /// ImplicitlyDefined - Whether this destructor was implicitly
1327193326Sed  /// defined by the compiler. When false, the destructor was defined
1328193326Sed  /// by the user. In C++03, this flag will have the same value as
1329193326Sed  /// Implicit. In C++0x, however, a destructor that is
1330193326Sed  /// explicitly defaulted (i.e., defined with " = default") will have
1331193326Sed  /// @c !Implicit && ImplicitlyDefined.
1332193326Sed  bool ImplicitlyDefined : 1;
1333193326Sed
1334199482Srdivacky  FunctionDecl *OperatorDelete;
1335199482Srdivacky
1336193326Sed  CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
1337193326Sed                    DeclarationName N, QualType T,
1338193326Sed                    bool isInline, bool isImplicitlyDeclared)
1339207619Srdivacky    : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*TInfo=*/0, false,
1340207619Srdivacky                    FunctionDecl::None, isInline),
1341199482Srdivacky      ImplicitlyDefined(false), OperatorDelete(0) {
1342193326Sed    setImplicit(isImplicitlyDeclared);
1343193326Sed  }
1344193326Sed
1345193326Sedpublic:
1346193326Sed  static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
1347193326Sed                                   SourceLocation L, DeclarationName N,
1348198092Srdivacky                                   QualType T, bool isInline,
1349193326Sed                                   bool isImplicitlyDeclared);
1350193326Sed
1351193326Sed  /// isImplicitlyDefined - Whether this destructor was implicitly
1352193326Sed  /// defined. If false, then this destructor was defined by the
1353193326Sed  /// user. This operation can only be invoked if the destructor has
1354193326Sed  /// already been defined.
1355198092Srdivacky  bool isImplicitlyDefined() const {
1356198092Srdivacky    assert(isThisDeclarationADefinition() &&
1357193326Sed           "Can only get the implicit-definition flag once the destructor has been defined");
1358198092Srdivacky    return ImplicitlyDefined;
1359193326Sed  }
1360193326Sed
1361193326Sed  /// setImplicitlyDefined - Set whether this destructor was
1362193326Sed  /// implicitly defined or not.
1363198092Srdivacky  void setImplicitlyDefined(bool ID) {
1364198092Srdivacky    assert(isThisDeclarationADefinition() &&
1365193326Sed           "Can only set the implicit-definition flag once the destructor has been defined");
1366198092Srdivacky    ImplicitlyDefined = ID;
1367193326Sed  }
1368193326Sed
1369199482Srdivacky  void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
1370199482Srdivacky  const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
1371198092Srdivacky
1372193326Sed  // Implement isa/cast/dyncast/etc.
1373203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1374193326Sed  static bool classof(const CXXDestructorDecl *D) { return true; }
1375203955Srdivacky  static bool classofKind(Kind K) { return K == CXXDestructor; }
1376193326Sed};
1377193326Sed
1378193326Sed/// CXXConversionDecl - Represents a C++ conversion function within a
1379193326Sed/// class. For example:
1380198092Srdivacky///
1381193326Sed/// @code
1382193326Sed/// class X {
1383193326Sed/// public:
1384193326Sed///   operator bool();
1385193326Sed/// };
1386193326Sed/// @endcode
1387193326Sedclass CXXConversionDecl : public CXXMethodDecl {
1388203955Srdivacky  /// IsExplicitSpecified - Whether this conversion function declaration is
1389203955Srdivacky  /// marked "explicit", meaning that it can only be applied when the user
1390193326Sed  /// explicitly wrote a cast. This is a C++0x feature.
1391203955Srdivacky  bool IsExplicitSpecified : 1;
1392193326Sed
1393193326Sed  CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
1394200583Srdivacky                    DeclarationName N, QualType T, TypeSourceInfo *TInfo,
1395203955Srdivacky                    bool isInline, bool isExplicitSpecified)
1396207619Srdivacky    : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false,
1397207619Srdivacky                    FunctionDecl::None, isInline),
1398203955Srdivacky      IsExplicitSpecified(isExplicitSpecified) { }
1399193326Sed
1400193326Sedpublic:
1401193326Sed  static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
1402193326Sed                                   SourceLocation L, DeclarationName N,
1403200583Srdivacky                                   QualType T, TypeSourceInfo *TInfo,
1404198092Srdivacky                                   bool isInline, bool isExplicit);
1405193326Sed
1406203955Srdivacky  /// IsExplicitSpecified - Whether this conversion function declaration is
1407203955Srdivacky  /// marked "explicit", meaning that it can only be applied when the user
1408203955Srdivacky  /// explicitly wrote a cast. This is a C++0x feature.
1409203955Srdivacky  bool isExplicitSpecified() const { return IsExplicitSpecified; }
1410203955Srdivacky
1411193326Sed  /// isExplicit - Whether this is an explicit conversion operator
1412193326Sed  /// (C++0x only). Explicit conversion operators are only considered
1413193326Sed  /// when the user has explicitly written a cast.
1414203955Srdivacky  bool isExplicit() const {
1415203955Srdivacky    return cast<CXXConversionDecl>(getFirstDeclaration())
1416203955Srdivacky      ->isExplicitSpecified();
1417203955Srdivacky  }
1418193326Sed
1419193326Sed  /// getConversionType - Returns the type that this conversion
1420193326Sed  /// function is converting to.
1421198092Srdivacky  QualType getConversionType() const {
1422198092Srdivacky    return getType()->getAs<FunctionType>()->getResultType();
1423193326Sed  }
1424193326Sed
1425193326Sed  // Implement isa/cast/dyncast/etc.
1426203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1427193326Sed  static bool classof(const CXXConversionDecl *D) { return true; }
1428203955Srdivacky  static bool classofKind(Kind K) { return K == CXXConversion; }
1429193326Sed};
1430193326Sed
1431193326Sed/// LinkageSpecDecl - This represents a linkage specification.  For example:
1432193326Sed///   extern "C" void foo();
1433193326Sed///
1434193326Sedclass LinkageSpecDecl : public Decl, public DeclContext {
1435193326Sedpublic:
1436193326Sed  /// LanguageIDs - Used to represent the language in a linkage
1437193326Sed  /// specification.  The values are part of the serialization abi for
1438193326Sed  /// ASTs and cannot be changed without altering that abi.  To help
1439193326Sed  /// ensure a stable abi for this, we choose the DW_LANG_ encodings
1440193326Sed  /// from the dwarf standard.
1441193326Sed  enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002,
1442193326Sed  lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 };
1443193326Sedprivate:
1444193326Sed  /// Language - The language for this linkage specification.
1445193326Sed  LanguageIDs Language;
1446193326Sed
1447193326Sed  /// HadBraces - Whether this linkage specification had curly braces or not.
1448193326Sed  bool HadBraces : 1;
1449193326Sed
1450198092Srdivacky  LinkageSpecDecl(DeclContext *DC, SourceLocation L, LanguageIDs lang,
1451193326Sed                  bool Braces)
1452198092Srdivacky    : Decl(LinkageSpec, DC, L),
1453193326Sed      DeclContext(LinkageSpec), Language(lang), HadBraces(Braces) { }
1454193326Sed
1455193326Sedpublic:
1456198092Srdivacky  static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
1457198092Srdivacky                                 SourceLocation L, LanguageIDs Lang,
1458193326Sed                                 bool Braces);
1459193326Sed
1460193326Sed  LanguageIDs getLanguage() const { return Language; }
1461193326Sed
1462193326Sed  /// hasBraces - Determines whether this linkage specification had
1463193326Sed  /// braces in its syntactic form.
1464193326Sed  bool hasBraces() const { return HadBraces; }
1465193326Sed
1466203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1467193326Sed  static bool classof(const LinkageSpecDecl *D) { return true; }
1468203955Srdivacky  static bool classofKind(Kind K) { return K == LinkageSpec; }
1469193326Sed  static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
1470193326Sed    return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
1471193326Sed  }
1472193326Sed  static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) {
1473193326Sed    return static_cast<LinkageSpecDecl *>(const_cast<DeclContext*>(DC));
1474193326Sed  }
1475193326Sed};
1476193326Sed
1477193326Sed/// UsingDirectiveDecl - Represents C++ using-directive. For example:
1478193326Sed///
1479193326Sed///    using namespace std;
1480193326Sed///
1481193326Sed// NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide
1482193326Sed// artificial name, for all using-directives in order to store
1483193326Sed// them in DeclContext effectively.
1484193326Sedclass UsingDirectiveDecl : public NamedDecl {
1485193326Sed
1486193326Sed  /// SourceLocation - Location of 'namespace' token.
1487193326Sed  SourceLocation NamespaceLoc;
1488193326Sed
1489193326Sed  /// \brief The source range that covers the nested-name-specifier
1490193326Sed  /// preceding the namespace name.
1491193326Sed  SourceRange QualifierRange;
1492193326Sed
1493193326Sed  /// \brief The nested-name-specifier that precedes the namespace
1494193326Sed  /// name, if any.
1495193326Sed  NestedNameSpecifier *Qualifier;
1496193326Sed
1497193326Sed  /// IdentLoc - Location of nominated namespace-name identifier.
1498193326Sed  // FIXME: We don't store location of scope specifier.
1499193326Sed  SourceLocation IdentLoc;
1500193326Sed
1501193326Sed  /// NominatedNamespace - Namespace nominated by using-directive.
1502199990Srdivacky  NamedDecl *NominatedNamespace;
1503193326Sed
1504199990Srdivacky  /// Enclosing context containing both using-directive and nominated
1505193326Sed  /// namespace.
1506193326Sed  DeclContext *CommonAncestor;
1507193326Sed
1508193326Sed  /// getUsingDirectiveName - Returns special DeclarationName used by
1509193326Sed  /// using-directives. This is only used by DeclContext for storing
1510193326Sed  /// UsingDirectiveDecls in its lookup structure.
1511193326Sed  static DeclarationName getName() {
1512193326Sed    return DeclarationName::getUsingDirectiveName();
1513193326Sed  }
1514193326Sed
1515193326Sed  UsingDirectiveDecl(DeclContext *DC, SourceLocation L,
1516193326Sed                     SourceLocation NamespcLoc,
1517193326Sed                     SourceRange QualifierRange,
1518193326Sed                     NestedNameSpecifier *Qualifier,
1519193326Sed                     SourceLocation IdentLoc,
1520199990Srdivacky                     NamedDecl *Nominated,
1521193326Sed                     DeclContext *CommonAncestor)
1522193326Sed    : NamedDecl(Decl::UsingDirective, DC, L, getName()),
1523198092Srdivacky      NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange),
1524198092Srdivacky      Qualifier(Qualifier), IdentLoc(IdentLoc),
1525199990Srdivacky      NominatedNamespace(Nominated),
1526193326Sed      CommonAncestor(CommonAncestor) {
1527193326Sed  }
1528193326Sed
1529193326Sedpublic:
1530193326Sed  /// \brief Retrieve the source range of the nested-name-specifier
1531193326Sed  /// that qualifiers the namespace name.
1532193326Sed  SourceRange getQualifierRange() const { return QualifierRange; }
1533193326Sed
1534193326Sed  /// \brief Retrieve the nested-name-specifier that qualifies the
1535193326Sed  /// name of the namespace.
1536193326Sed  NestedNameSpecifier *getQualifier() const { return Qualifier; }
1537193326Sed
1538199990Srdivacky  NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
1539199990Srdivacky  const NamedDecl *getNominatedNamespaceAsWritten() const {
1540199990Srdivacky    return NominatedNamespace;
1541199990Srdivacky  }
1542199990Srdivacky
1543193326Sed  /// getNominatedNamespace - Returns namespace nominated by using-directive.
1544199990Srdivacky  NamespaceDecl *getNominatedNamespace();
1545193326Sed
1546193326Sed  const NamespaceDecl *getNominatedNamespace() const {
1547193326Sed    return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
1548193326Sed  }
1549193326Sed
1550193326Sed  /// getCommonAncestor - returns common ancestor context of using-directive,
1551193326Sed  /// and nominated by it namespace.
1552193326Sed  DeclContext *getCommonAncestor() { return CommonAncestor; }
1553193326Sed  const DeclContext *getCommonAncestor() const { return CommonAncestor; }
1554193326Sed
1555193326Sed  /// getNamespaceKeyLocation - Returns location of namespace keyword.
1556193326Sed  SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
1557193326Sed
1558193326Sed  /// getIdentLocation - Returns location of identifier.
1559193326Sed  SourceLocation getIdentLocation() const { return IdentLoc; }
1560193326Sed
1561193326Sed  static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
1562193326Sed                                    SourceLocation L,
1563193326Sed                                    SourceLocation NamespaceLoc,
1564193326Sed                                    SourceRange QualifierRange,
1565193326Sed                                    NestedNameSpecifier *Qualifier,
1566193326Sed                                    SourceLocation IdentLoc,
1567199990Srdivacky                                    NamedDecl *Nominated,
1568193326Sed                                    DeclContext *CommonAncestor);
1569193326Sed
1570203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1571193326Sed  static bool classof(const UsingDirectiveDecl *D) { return true; }
1572203955Srdivacky  static bool classofKind(Kind K) { return K == Decl::UsingDirective; }
1573193326Sed
1574193326Sed  // Friend for getUsingDirectiveName.
1575193326Sed  friend class DeclContext;
1576193326Sed};
1577193326Sed
1578193326Sed/// NamespaceAliasDecl - Represents a C++ namespace alias. For example:
1579193326Sed///
1580193326Sed/// @code
1581193326Sed/// namespace Foo = Bar;
1582193326Sed/// @endcode
1583193326Sedclass NamespaceAliasDecl : public NamedDecl {
1584193326Sed  SourceLocation AliasLoc;
1585193326Sed
1586193326Sed  /// \brief The source range that covers the nested-name-specifier
1587193326Sed  /// preceding the namespace name.
1588193326Sed  SourceRange QualifierRange;
1589193326Sed
1590193326Sed  /// \brief The nested-name-specifier that precedes the namespace
1591193326Sed  /// name, if any.
1592193326Sed  NestedNameSpecifier *Qualifier;
1593198092Srdivacky
1594193326Sed  /// IdentLoc - Location of namespace identifier.
1595193326Sed  SourceLocation IdentLoc;
1596198092Srdivacky
1597198092Srdivacky  /// Namespace - The Decl that this alias points to. Can either be a
1598193326Sed  /// NamespaceDecl or a NamespaceAliasDecl.
1599193326Sed  NamedDecl *Namespace;
1600198092Srdivacky
1601198092Srdivacky  NamespaceAliasDecl(DeclContext *DC, SourceLocation L,
1602198092Srdivacky                     SourceLocation AliasLoc, IdentifierInfo *Alias,
1603193326Sed                     SourceRange QualifierRange,
1604193326Sed                     NestedNameSpecifier *Qualifier,
1605193326Sed                     SourceLocation IdentLoc, NamedDecl *Namespace)
1606198092Srdivacky    : NamedDecl(Decl::NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc),
1607193326Sed      QualifierRange(QualifierRange), Qualifier(Qualifier),
1608193326Sed      IdentLoc(IdentLoc), Namespace(Namespace) { }
1609193326Sed
1610193326Sedpublic:
1611193326Sed  /// \brief Retrieve the source range of the nested-name-specifier
1612193326Sed  /// that qualifiers the namespace name.
1613193326Sed  SourceRange getQualifierRange() const { return QualifierRange; }
1614193326Sed
1615193326Sed  /// \brief Retrieve the nested-name-specifier that qualifies the
1616193326Sed  /// name of the namespace.
1617193326Sed  NestedNameSpecifier *getQualifier() const { return Qualifier; }
1618193326Sed
1619193326Sed  NamespaceDecl *getNamespace() {
1620193326Sed    if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
1621193326Sed      return AD->getNamespace();
1622193326Sed
1623193326Sed    return cast<NamespaceDecl>(Namespace);
1624193326Sed  }
1625198092Srdivacky
1626193326Sed  const NamespaceDecl *getNamespace() const {
1627193326Sed    return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
1628193326Sed  }
1629193326Sed
1630203955Srdivacky  /// Returns the location of the alias name, i.e. 'foo' in
1631203955Srdivacky  /// "namespace foo = ns::bar;".
1632203955Srdivacky  SourceLocation getAliasLoc() const { return AliasLoc; }
1633203955Srdivacky
1634203955Srdivacky  /// Returns the location of the 'namespace' keyword.
1635203955Srdivacky  SourceLocation getNamespaceLoc() const { return getLocation(); }
1636203955Srdivacky
1637203955Srdivacky  /// Returns the location of the identifier in the named namespace.
1638203955Srdivacky  SourceLocation getTargetNameLoc() const { return IdentLoc; }
1639203955Srdivacky
1640193326Sed  /// \brief Retrieve the namespace that this alias refers to, which
1641193326Sed  /// may either be a NamespaceDecl or a NamespaceAliasDecl.
1642193326Sed  NamedDecl *getAliasedNamespace() const { return Namespace; }
1643193326Sed
1644198092Srdivacky  static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
1645198092Srdivacky                                    SourceLocation L, SourceLocation AliasLoc,
1646198092Srdivacky                                    IdentifierInfo *Alias,
1647193326Sed                                    SourceRange QualifierRange,
1648193326Sed                                    NestedNameSpecifier *Qualifier,
1649198092Srdivacky                                    SourceLocation IdentLoc,
1650193326Sed                                    NamedDecl *Namespace);
1651198092Srdivacky
1652203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1653193326Sed  static bool classof(const NamespaceAliasDecl *D) { return true; }
1654203955Srdivacky  static bool classofKind(Kind K) { return K == Decl::NamespaceAlias; }
1655193326Sed};
1656194613Sed
1657199482Srdivacky/// UsingShadowDecl - Represents a shadow declaration introduced into
1658199482Srdivacky/// a scope by a (resolved) using declaration.  For example,
1659199482Srdivacky///
1660199482Srdivacky/// namespace A {
1661199482Srdivacky///   void foo();
1662199482Srdivacky/// }
1663199482Srdivacky/// namespace B {
1664199482Srdivacky///   using A::foo(); // <- a UsingDecl
1665199482Srdivacky///                   // Also creates a UsingShadowDecl for A::foo in B
1666199482Srdivacky/// }
1667199482Srdivacky///
1668199482Srdivackyclass UsingShadowDecl : public NamedDecl {
1669199482Srdivacky  /// The referenced declaration.
1670199482Srdivacky  NamedDecl *Underlying;
1671199482Srdivacky
1672199482Srdivacky  /// The using declaration which introduced this decl.
1673199482Srdivacky  UsingDecl *Using;
1674199482Srdivacky
1675199482Srdivacky  UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
1676199482Srdivacky                  NamedDecl *Target)
1677199482Srdivacky    : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()),
1678199482Srdivacky      Underlying(Target), Using(Using) {
1679199482Srdivacky    IdentifierNamespace = Target->getIdentifierNamespace();
1680199482Srdivacky    setImplicit();
1681199482Srdivacky  }
1682199482Srdivacky
1683199482Srdivackypublic:
1684199482Srdivacky  static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
1685199482Srdivacky                                 SourceLocation Loc, UsingDecl *Using,
1686199482Srdivacky                                 NamedDecl *Target) {
1687199482Srdivacky    return new (C) UsingShadowDecl(DC, Loc, Using, Target);
1688199482Srdivacky  }
1689199482Srdivacky
1690199482Srdivacky  /// Gets the underlying declaration which has been brought into the
1691199482Srdivacky  /// local scope.
1692199482Srdivacky  NamedDecl *getTargetDecl() const {
1693199482Srdivacky    return Underlying;
1694199482Srdivacky  }
1695199482Srdivacky
1696199482Srdivacky  /// Gets the using declaration to which this declaration is tied.
1697199482Srdivacky  UsingDecl *getUsingDecl() const {
1698199482Srdivacky    return Using;
1699199482Srdivacky  }
1700199482Srdivacky
1701203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1702199482Srdivacky  static bool classof(const UsingShadowDecl *D) { return true; }
1703203955Srdivacky  static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
1704199482Srdivacky};
1705199482Srdivacky
1706194613Sed/// UsingDecl - Represents a C++ using-declaration. For example:
1707194613Sed///    using someNameSpace::someIdentifier;
1708194613Sedclass UsingDecl : public NamedDecl {
1709194613Sed  /// \brief The source range that covers the nested-name-specifier
1710194613Sed  /// preceding the declaration name.
1711194613Sed  SourceRange NestedNameRange;
1712198092Srdivacky
1713194613Sed  /// \brief The source location of the "using" location itself.
1714194613Sed  SourceLocation UsingLocation;
1715198092Srdivacky
1716198092Srdivacky  /// \brief Target nested name specifier.
1717199482Srdivacky  NestedNameSpecifier* TargetNestedName;
1718194613Sed
1719199482Srdivacky  /// \brief The collection of shadow declarations associated with
1720199482Srdivacky  /// this using declaration.  This set can change as a class is
1721199482Srdivacky  /// processed.
1722199482Srdivacky  llvm::SmallPtrSet<UsingShadowDecl*, 8> Shadows;
1723199482Srdivacky
1724198092Srdivacky  // \brief Has 'typename' keyword.
1725194613Sed  bool IsTypeName;
1726194613Sed
1727194613Sed  UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
1728199482Srdivacky            SourceLocation UL, NestedNameSpecifier* TargetNNS,
1729199482Srdivacky            DeclarationName Name, bool IsTypeNameArg)
1730199482Srdivacky    : NamedDecl(Decl::Using, DC, L, Name),
1731199482Srdivacky      NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
1732199482Srdivacky      IsTypeName(IsTypeNameArg) {
1733194613Sed  }
1734194613Sed
1735194613Sedpublic:
1736194613Sed  /// \brief Returns the source range that covers the nested-name-specifier
1737194613Sed  /// preceding the namespace name.
1738195099Sed  SourceRange getNestedNameRange() { return NestedNameRange; }
1739198092Srdivacky
1740194613Sed  /// \brief Returns the source location of the "using" location itself.
1741195099Sed  SourceLocation getUsingLocation() { return UsingLocation; }
1742198092Srdivacky
1743194613Sed  /// \brief Get target nested name declaration.
1744198092Srdivacky  NestedNameSpecifier* getTargetNestedNameDecl() {
1745199482Srdivacky    return TargetNestedName;
1746195099Sed  }
1747198092Srdivacky
1748198092Srdivacky  /// isTypeName - Return true if using decl has 'typename'.
1749195099Sed  bool isTypeName() const { return IsTypeName; }
1750194613Sed
1751199482Srdivacky  typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
1752199482Srdivacky  shadow_iterator shadow_begin() const { return Shadows.begin(); }
1753199482Srdivacky  shadow_iterator shadow_end() const { return Shadows.end(); }
1754199482Srdivacky
1755199482Srdivacky  void addShadowDecl(UsingShadowDecl *S) {
1756199482Srdivacky    assert(S->getUsingDecl() == this);
1757199482Srdivacky    if (!Shadows.insert(S)) {
1758199482Srdivacky      assert(false && "declaration already in set");
1759199482Srdivacky    }
1760199482Srdivacky  }
1761199482Srdivacky  void removeShadowDecl(UsingShadowDecl *S) {
1762199482Srdivacky    assert(S->getUsingDecl() == this);
1763199482Srdivacky    if (!Shadows.erase(S)) {
1764199482Srdivacky      assert(false && "declaration not in set");
1765199482Srdivacky    }
1766199482Srdivacky  }
1767199482Srdivacky
1768194613Sed  static UsingDecl *Create(ASTContext &C, DeclContext *DC,
1769199482Srdivacky      SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
1770199482Srdivacky      NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
1771194613Sed
1772203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1773194613Sed  static bool classof(const UsingDecl *D) { return true; }
1774203955Srdivacky  static bool classofKind(Kind K) { return K == Decl::Using; }
1775194613Sed};
1776198092Srdivacky
1777199482Srdivacky/// UnresolvedUsingValueDecl - Represents a dependent using
1778199482Srdivacky/// declaration which was not marked with 'typename'.  Unlike
1779199482Srdivacky/// non-dependent using declarations, these *only* bring through
1780199482Srdivacky/// non-types; otherwise they would break two-phase lookup.
1781199482Srdivacky///
1782199482Srdivacky/// template <class T> class A : public Base<T> {
1783199482Srdivacky///   using Base<T>::foo;
1784199482Srdivacky/// };
1785199482Srdivackyclass UnresolvedUsingValueDecl : public ValueDecl {
1786198092Srdivacky  /// \brief The source range that covers the nested-name-specifier
1787198092Srdivacky  /// preceding the declaration name.
1788198092Srdivacky  SourceRange TargetNestedNameRange;
1789198092Srdivacky
1790199482Srdivacky  /// \brief The source location of the 'using' keyword
1791199482Srdivacky  SourceLocation UsingLocation;
1792198092Srdivacky
1793198092Srdivacky  NestedNameSpecifier *TargetNestedNameSpecifier;
1794198092Srdivacky
1795199482Srdivacky  UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
1796199482Srdivacky                           SourceLocation UsingLoc, SourceRange TargetNNR,
1797199482Srdivacky                           NestedNameSpecifier *TargetNNS,
1798199482Srdivacky                           SourceLocation TargetNameLoc,
1799199482Srdivacky                           DeclarationName TargetName)
1800199482Srdivacky    : ValueDecl(Decl::UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
1801199482Srdivacky    TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
1802199482Srdivacky    TargetNestedNameSpecifier(TargetNNS)
1803199482Srdivacky  { }
1804198092Srdivacky
1805199482Srdivackypublic:
1806199482Srdivacky  /// \brief Returns the source range that covers the nested-name-specifier
1807199482Srdivacky  /// preceding the namespace name.
1808199482Srdivacky  SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
1809198092Srdivacky
1810199482Srdivacky  /// \brief Get target nested name declaration.
1811199482Srdivacky  NestedNameSpecifier* getTargetNestedNameSpecifier() {
1812199482Srdivacky    return TargetNestedNameSpecifier;
1813199482Srdivacky  }
1814198092Srdivacky
1815199482Srdivacky  /// \brief Returns the source location of the 'using' keyword.
1816199482Srdivacky  SourceLocation getUsingLoc() const { return UsingLocation; }
1817199482Srdivacky
1818199482Srdivacky  static UnresolvedUsingValueDecl *
1819199482Srdivacky    Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
1820199482Srdivacky           SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
1821199482Srdivacky           SourceLocation TargetNameLoc, DeclarationName TargetName);
1822199482Srdivacky
1823203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1824199482Srdivacky  static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
1825203955Srdivacky  static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingValue; }
1826199482Srdivacky};
1827199482Srdivacky
1828199482Srdivacky/// UnresolvedUsingTypenameDecl - Represents a dependent using
1829199482Srdivacky/// declaration which was marked with 'typename'.
1830199482Srdivacky///
1831199482Srdivacky/// template <class T> class A : public Base<T> {
1832199482Srdivacky///   using typename Base<T>::foo;
1833199482Srdivacky/// };
1834199482Srdivacky///
1835199482Srdivacky/// The type associated with a unresolved using typename decl is
1836199482Srdivacky/// currently always a typename type.
1837199482Srdivackyclass UnresolvedUsingTypenameDecl : public TypeDecl {
1838199482Srdivacky  /// \brief The source range that covers the nested-name-specifier
1839199482Srdivacky  /// preceding the declaration name.
1840199482Srdivacky  SourceRange TargetNestedNameRange;
1841199482Srdivacky
1842199482Srdivacky  /// \brief The source location of the 'using' keyword
1843199482Srdivacky  SourceLocation UsingLocation;
1844199482Srdivacky
1845199482Srdivacky  /// \brief The source location of the 'typename' keyword
1846199482Srdivacky  SourceLocation TypenameLocation;
1847199482Srdivacky
1848199482Srdivacky  NestedNameSpecifier *TargetNestedNameSpecifier;
1849199482Srdivacky
1850199482Srdivacky  UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
1851199482Srdivacky                    SourceLocation TypenameLoc,
1852199482Srdivacky                    SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
1853199482Srdivacky                    SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
1854199482Srdivacky  : TypeDecl(Decl::UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
1855199482Srdivacky    TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
1856199482Srdivacky    TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
1857199482Srdivacky  { }
1858199482Srdivacky
1859198092Srdivackypublic:
1860198092Srdivacky  /// \brief Returns the source range that covers the nested-name-specifier
1861198092Srdivacky  /// preceding the namespace name.
1862198092Srdivacky  SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
1863198092Srdivacky
1864198092Srdivacky  /// \brief Get target nested name declaration.
1865198092Srdivacky  NestedNameSpecifier* getTargetNestedNameSpecifier() {
1866198092Srdivacky    return TargetNestedNameSpecifier;
1867198092Srdivacky  }
1868198092Srdivacky
1869199482Srdivacky  /// \brief Returns the source location of the 'using' keyword.
1870199482Srdivacky  SourceLocation getUsingLoc() const { return UsingLocation; }
1871198092Srdivacky
1872199482Srdivacky  /// \brief Returns the source location of the 'typename' keyword.
1873199482Srdivacky  SourceLocation getTypenameLoc() const { return TypenameLocation; }
1874198092Srdivacky
1875199482Srdivacky  static UnresolvedUsingTypenameDecl *
1876199482Srdivacky    Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
1877199482Srdivacky           SourceLocation TypenameLoc,
1878199482Srdivacky           SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
1879199482Srdivacky           SourceLocation TargetNameLoc, DeclarationName TargetName);
1880198092Srdivacky
1881203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1882199482Srdivacky  static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
1883203955Srdivacky  static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingTypename; }
1884198092Srdivacky};
1885198092Srdivacky
1886193326Sed/// StaticAssertDecl - Represents a C++0x static_assert declaration.
1887193326Sedclass StaticAssertDecl : public Decl {
1888193326Sed  Expr *AssertExpr;
1889193326Sed  StringLiteral *Message;
1890193326Sed
1891198092Srdivacky  StaticAssertDecl(DeclContext *DC, SourceLocation L,
1892193326Sed                   Expr *assertexpr, StringLiteral *message)
1893193326Sed  : Decl(StaticAssert, DC, L), AssertExpr(assertexpr), Message(message) { }
1894198092Srdivacky
1895193326Sedpublic:
1896193326Sed  static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
1897193326Sed                                  SourceLocation L, Expr *AssertExpr,
1898193326Sed                                  StringLiteral *Message);
1899198092Srdivacky
1900193326Sed  Expr *getAssertExpr() { return AssertExpr; }
1901193326Sed  const Expr *getAssertExpr() const { return AssertExpr; }
1902198092Srdivacky
1903193326Sed  StringLiteral *getMessage() { return Message; }
1904193326Sed  const StringLiteral *getMessage() const { return Message; }
1905198092Srdivacky
1906193326Sed  virtual ~StaticAssertDecl();
1907193326Sed  virtual void Destroy(ASTContext& C);
1908193326Sed
1909203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1910193326Sed  static bool classof(StaticAssertDecl *D) { return true; }
1911203955Srdivacky  static bool classofKind(Kind K) { return K == Decl::StaticAssert; }
1912193326Sed};
1913193326Sed
1914193326Sed/// Insertion operator for diagnostics.  This allows sending AccessSpecifier's
1915193326Sed/// into a diagnostic with <<.
1916193326Sedconst DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1917193326Sed                                    AccessSpecifier AS);
1918198092Srdivacky
1919193326Sed} // end namespace clang
1920193326Sed
1921193326Sed#endif
1922