DeclCXX.h revision 221345
1227569Sphilip//===-- DeclCXX.h - Classes for representing C++ declarations -*- C++ -*-=====//
2284555Sarybchik//
3284555Sarybchik//                     The LLVM Compiler Infrastructure
4227569Sphilip//
5227569Sphilip// This file is distributed under the University of Illinois Open Source
6284555Sarybchik// License. See LICENSE.TXT for details.
7227569Sphilip//
8284555Sarybchik//===----------------------------------------------------------------------===//
9284555Sarybchik//
10284555Sarybchik//  This file defines the C++ Decl subclasses, other than those for
11284555Sarybchik//  templates (in DeclTemplate.h) and friends (in DeclFriend.h).
12284555Sarybchik//
13228078Sphilip//===----------------------------------------------------------------------===//
14284555Sarybchik
15284555Sarybchik#ifndef LLVM_CLANG_AST_DECLCXX_H
16284555Sarybchik#define LLVM_CLANG_AST_DECLCXX_H
17284555Sarybchik
18284555Sarybchik#include "clang/AST/Expr.h"
19284555Sarybchik#include "clang/AST/Decl.h"
20284555Sarybchik#include "clang/AST/TypeLoc.h"
21284555Sarybchik#include "clang/AST/UnresolvedSet.h"
22284555Sarybchik#include "llvm/ADT/SmallVector.h"
23284555Sarybchik#include "llvm/ADT/SmallPtrSet.h"
24284555Sarybchik
25284555Sarybchiknamespace clang {
26284555Sarybchik
27284555Sarybchikclass ClassTemplateDecl;
28284555Sarybchikclass ClassTemplateSpecializationDecl;
29284555Sarybchikclass CXXBasePath;
30228078Sphilipclass CXXBasePaths;
31227569Sphilipclass CXXConstructorDecl;
32227569Sphilipclass CXXConversionDecl;
33227569Sphilipclass CXXDestructorDecl;
34227569Sphilipclass CXXMethodDecl;
35227569Sphilipclass CXXRecordDecl;
36227569Sphilipclass CXXMemberLookupCriteria;
37284555Sarybchikclass CXXFinalOverriderMap;
38227569Sphilipclass CXXIndirectPrimaryBaseSet;
39227569Sphilipclass FriendDecl;
40227569Sphilip
41227569Sphilip/// \brief Represents any kind of function declaration, whether it is a
42227569Sphilip/// concrete function or a function template.
43293927Sarybchikclass AnyFunctionDecl {
44293927Sarybchik  NamedDecl *Function;
45227569Sphilip
46293927Sarybchik  AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
47293927Sarybchik
48227569Sphilippublic:
49293927Sarybchik  AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
50293927Sarybchik  AnyFunctionDecl(FunctionTemplateDecl *FTD);
51227569Sphilip
52293927Sarybchik  /// \brief Implicily converts any function or function template into a
53293927Sarybchik  /// named declaration.
54293927Sarybchik  operator NamedDecl *() const { return Function; }
55293927Sarybchik
56293927Sarybchik  /// \brief Retrieve the underlying function or function template.
57293927Sarybchik  NamedDecl *get() const { return Function; }
58293927Sarybchik
59227569Sphilip  static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
60227569Sphilip    return AnyFunctionDecl(ND);
61227569Sphilip  }
62227569Sphilip};
63284555Sarybchik
64293975Sarybchik} // end namespace clang
65227569Sphilip
66227569Sphilipnamespace llvm {
67227569Sphilip  /// Implement simplify_type for AnyFunctionDecl, so that we can dyn_cast from
68293927Sarybchik  /// AnyFunctionDecl to any function or function template declaration.
69227569Sphilip  template<> struct simplify_type<const ::clang::AnyFunctionDecl> {
70227569Sphilip    typedef ::clang::NamedDecl* SimpleType;
71227569Sphilip    static SimpleType getSimplifiedValue(const ::clang::AnyFunctionDecl &Val) {
72227569Sphilip      return Val;
73227569Sphilip    }
74293927Sarybchik  };
75227569Sphilip  template<> struct simplify_type< ::clang::AnyFunctionDecl>
76227569Sphilip  : public simplify_type<const ::clang::AnyFunctionDecl> {};
77227569Sphilip
78227569Sphilip  // Provide PointerLikeTypeTraits for non-cvr pointers.
79284555Sarybchik  template<>
80227569Sphilip  class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
81284555Sarybchik  public:
82284555Sarybchik    static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
83284555Sarybchik      return F.get();
84284555Sarybchik    }
85284555Sarybchik    static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
86284555Sarybchik      return ::clang::AnyFunctionDecl::getFromNamedDecl(
87284555Sarybchik                                      static_cast< ::clang::NamedDecl*>(P));
88284555Sarybchik    }
89284555Sarybchik
90284555Sarybchik    enum { NumLowBitsAvailable = 2 };
91284555Sarybchik  };
92284555Sarybchik
93284555Sarybchik} // end namespace llvm
94293975Sarybchik
95293975Sarybchiknamespace clang {
96293975Sarybchik
97284555Sarybchik/// AccessSpecDecl - An access specifier followed by colon ':'.
98227569Sphilip///
99227569Sphilip/// An objects of this class represents sugar for the syntactic occurrence
100227569Sphilip/// of an access specifier followed by a colon in the list of member
101227569Sphilip/// specifiers of a C++ class definition.
102227569Sphilip///
103227569Sphilip/// Note that they do not represent other uses of access specifiers,
104227569Sphilip/// such as those occurring in a list of base specifiers.
105227569Sphilip/// Also note that this class has nothing to do with so-called
106227569Sphilip/// "access declarations" (C++98 11.3 [class.access.dcl]).
107227569Sphilipclass AccessSpecDecl : public Decl {
108227569Sphilip  /// ColonLoc - The location of the ':'.
109227569Sphilip  SourceLocation ColonLoc;
110227569Sphilip
111227569Sphilip  AccessSpecDecl(AccessSpecifier AS, DeclContext *DC,
112227569Sphilip                 SourceLocation ASLoc, SourceLocation ColonLoc)
113227569Sphilip    : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
114227569Sphilip    setAccess(AS);
115227569Sphilip  }
116227569Sphilip  AccessSpecDecl(EmptyShell Empty)
117227569Sphilip    : Decl(AccessSpec, Empty) { }
118284555Sarybchikpublic:
119284555Sarybchik  /// getAccessSpecifierLoc - The location of the access specifier.
120284555Sarybchik  SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
121284555Sarybchik  /// setAccessSpecifierLoc - Sets the location of the access specifier.
122284555Sarybchik  void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
123284555Sarybchik
124284555Sarybchik  /// getColonLoc - The location of the colon following the access specifier.
125284555Sarybchik  SourceLocation getColonLoc() const { return ColonLoc; }
126284555Sarybchik  /// setColonLoc - Sets the location of the colon.
127284555Sarybchik  void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
128284555Sarybchik
129284555Sarybchik  SourceRange getSourceRange() const {
130227569Sphilip    return SourceRange(getAccessSpecifierLoc(), getColonLoc());
131227569Sphilip  }
132227569Sphilip
133227569Sphilip  static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
134284555Sarybchik                                DeclContext *DC, SourceLocation ASLoc,
135284555Sarybchik                                SourceLocation ColonLoc) {
136284555Sarybchik    return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
137284555Sarybchik  }
138284555Sarybchik  static AccessSpecDecl *Create(ASTContext &C, EmptyShell Empty) {
139293927Sarybchik    return new (C) AccessSpecDecl(Empty);
140227569Sphilip  }
141227569Sphilip
142227569Sphilip  // Implement isa/cast/dyncast/etc.
143227569Sphilip  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
144227569Sphilip  static bool classof(const AccessSpecDecl *D) { return true; }
145227569Sphilip  static bool classofKind(Kind K) { return K == AccessSpec; }
146227569Sphilip};
147293927Sarybchik
148227569Sphilip
149227569Sphilip/// CXXBaseSpecifier - A base class of a C++ class.
150227569Sphilip///
151227569Sphilip/// Each CXXBaseSpecifier represents a single, direct base class (or
152227569Sphilip/// struct) of a C++ class (or struct). It specifies the type of that
153293927Sarybchik/// base class, whether it is a virtual or non-virtual base, and what
154227569Sphilip/// level of access (public, protected, private) is used for the
155227569Sphilip/// derivation. For example:
156227569Sphilip///
157227569Sphilip/// @code
158293927Sarybchik///   class A { };
159227569Sphilip///   class B { };
160227569Sphilip///   class C : public virtual A, protected B { };
161227569Sphilip/// @endcode
162227569Sphilip///
163227569Sphilip/// In this code, C will have two CXXBaseSpecifiers, one for "public
164293927Sarybchik/// virtual A" and the other for "protected B".
165227569Sphilipclass CXXBaseSpecifier {
166227569Sphilip  /// Range - The source code range that covers the full base
167227569Sphilip  /// specifier, including the "virtual" (if present) and access
168293927Sarybchik  /// specifier (if present).
169227569Sphilip  SourceRange Range;
170227569Sphilip
171227569Sphilip  /// \brief The source location of the ellipsis, if this is a pack
172227569Sphilip  /// expansion.
173227569Sphilip  SourceLocation EllipsisLoc;
174293927Sarybchik
175227569Sphilip  /// Virtual - Whether this is a virtual base class or not.
176227569Sphilip  bool Virtual : 1;
177227569Sphilip
178227569Sphilip  /// BaseOfClass - Whether this is the base of a class (true) or of a
179227569Sphilip  /// struct (false). This determines the mapping from the access
180227569Sphilip  /// specifier as written in the source code to the access specifier
181227569Sphilip  /// used for semantic analysis.
182227569Sphilip  bool BaseOfClass : 1;
183227569Sphilip
184227569Sphilip  /// Access - Access specifier as written in the source code (which
185227569Sphilip  /// may be AS_none). The actual type of data stored here is an
186227569Sphilip  /// AccessSpecifier, but we use "unsigned" here to work around a
187227569Sphilip  /// VC++ bug.
188227569Sphilip  unsigned Access : 2;
189227569Sphilip
190227569Sphilip  /// InheritConstructors - Whether the class contains a using declaration
191227569Sphilip  /// to inherit the named class's constructors.
192227569Sphilip  bool InheritConstructors : 1;
193227569Sphilip
194293976Sarybchik  /// BaseTypeInfo - The type of the base class. This will be a class or struct
195293976Sarybchik  /// (or a typedef of such). The source code range does not include the
196284555Sarybchik  /// "virtual" or access specifier.
197284555Sarybchik  TypeSourceInfo *BaseTypeInfo;
198284555Sarybchik
199227569Sphilippublic:
200227569Sphilip  CXXBaseSpecifier() { }
201227569Sphilip
202227569Sphilip  CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A,
203227569Sphilip                   TypeSourceInfo *TInfo, SourceLocation EllipsisLoc)
204227569Sphilip    : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC),
205227569Sphilip      Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { }
206293939Sarybchik
207293939Sarybchik  /// getSourceRange - Retrieves the source range that contains the
208293939Sarybchik  /// entire base specifier.
209293939Sarybchik  SourceRange getSourceRange() const { return Range; }
210293939Sarybchik
211293939Sarybchik  /// isVirtual - Determines whether the base class is a virtual base
212293939Sarybchik  /// class (or not).
213293939Sarybchik  bool isVirtual() const { return Virtual; }
214293939Sarybchik
215227569Sphilip  /// \brief Determine whether this base class is a base of a class declared
216227569Sphilip  /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
217284555Sarybchik  bool isBaseOfClass() const { return BaseOfClass; }
218227569Sphilip
219227569Sphilip  /// \brief Determine whether this base specifier is a pack expansion.
220227569Sphilip  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
221293939Sarybchik
222293939Sarybchik  /// \brief Determine whether this base class's constructors get inherited.
223293939Sarybchik  bool getInheritConstructors() const { return InheritConstructors; }
224293939Sarybchik
225293963Sarybchik  /// \brief Set that this base class's constructors should be inherited.
226293963Sarybchik  void setInheritConstructors(bool Inherit = true) {
227293963Sarybchik    InheritConstructors = Inherit;
228227569Sphilip  }
229227569Sphilip
230293927Sarybchik  /// \brief For a pack expansion, determine the location of the ellipsis.
231227569Sphilip  SourceLocation getEllipsisLoc() const {
232227569Sphilip    return EllipsisLoc;
233227569Sphilip  }
234227569Sphilip
235293927Sarybchik  /// getAccessSpecifier - Returns the access specifier for this base
236227569Sphilip  /// specifier. This is the actual base specifier as used for
237227569Sphilip  /// semantic analysis, so the result can never be AS_none. To
238227569Sphilip  /// retrieve the access specifier as written in the source code, use
239284555Sarybchik  /// getAccessSpecifierAsWritten().
240284555Sarybchik  AccessSpecifier getAccessSpecifier() const {
241284555Sarybchik    if ((AccessSpecifier)Access == AS_none)
242284555Sarybchik      return BaseOfClass? AS_private : AS_public;
243227569Sphilip    else
244227569Sphilip      return (AccessSpecifier)Access;
245227569Sphilip  }
246227569Sphilip
247227569Sphilip  /// getAccessSpecifierAsWritten - Retrieves the access specifier as
248227569Sphilip  /// written in the source code (which may mean that no access
249227569Sphilip  /// specifier was explicitly written). Use getAccessSpecifier() to
250227569Sphilip  /// retrieve the access specifier for use in semantic analysis.
251227569Sphilip  AccessSpecifier getAccessSpecifierAsWritten() const {
252227569Sphilip    return (AccessSpecifier)Access;
253227569Sphilip  }
254227569Sphilip
255227569Sphilip  /// getType - Retrieves the type of the base class. This type will
256227569Sphilip  /// always be an unqualified class type.
257227569Sphilip  QualType getType() const { return BaseTypeInfo->getType(); }
258227569Sphilip
259227569Sphilip  /// getTypeLoc - Retrieves the type and source location of the base class.
260227569Sphilip  TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
261227569Sphilip};
262227569Sphilip
263227569Sphilip/// CXXRecordDecl - Represents a C++ struct/union/class.
264227569Sphilip/// FIXME: This class will disappear once we've properly taught RecordDecl
265227569Sphilip/// to deal with C++-specific things.
266227569Sphilipclass CXXRecordDecl : public RecordDecl {
267227569Sphilip
268227569Sphilip  friend void TagDecl::startDefinition();
269227569Sphilip
270227569Sphilip  struct DefinitionData {
271227569Sphilip    DefinitionData(CXXRecordDecl *D);
272227569Sphilip
273227569Sphilip    /// UserDeclaredConstructor - True when this class has a
274227569Sphilip    /// user-declared constructor.
275227569Sphilip    bool UserDeclaredConstructor : 1;
276227569Sphilip
277293927Sarybchik    /// UserDeclaredCopyConstructor - True when this class has a
278227569Sphilip    /// user-declared copy constructor.
279227569Sphilip    bool UserDeclaredCopyConstructor : 1;
280227569Sphilip
281227569Sphilip    /// UserDeclaredCopyAssignment - True when this class has a
282227569Sphilip    /// user-declared copy assignment operator.
283227569Sphilip    bool UserDeclaredCopyAssignment : 1;
284227569Sphilip
285227569Sphilip    /// UserDeclaredDestructor - True when this class has a
286227569Sphilip    /// user-declared destructor.
287227569Sphilip    bool UserDeclaredDestructor : 1;
288227569Sphilip
289227569Sphilip    /// Aggregate - True when this class is an aggregate.
290227569Sphilip    bool Aggregate : 1;
291227569Sphilip
292227569Sphilip    /// PlainOldData - True when this class is a POD-type.
293227569Sphilip    bool PlainOldData : 1;
294227569Sphilip
295227569Sphilip    /// Empty - true when this class is empty for traits purposes,
296227569Sphilip    /// i.e. has no data members other than 0-width bit-fields, has no
297293927Sarybchik    /// virtual function/base, and doesn't inherit from a non-empty
298227569Sphilip    /// class. Doesn't take union-ness into account.
299227569Sphilip    bool Empty : 1;
300227569Sphilip
301227569Sphilip    /// Polymorphic - True when this class is polymorphic, i.e. has at
302227569Sphilip    /// least one virtual member or derives from a polymorphic class.
303227569Sphilip    bool Polymorphic : 1;
304227569Sphilip
305227569Sphilip    /// Abstract - True when this class is abstract, i.e. has at least
306227569Sphilip    /// one pure virtual function, (that can come from a base class).
307227569Sphilip    bool Abstract : 1;
308227569Sphilip
309227569Sphilip    /// IsStandardLayout - True when this class has standard layout.
310227569Sphilip    ///
311227569Sphilip    /// C++0x [class]p7.  A standard-layout class is a class that:
312227569Sphilip    /// * has no non-static data members of type non-standard-layout class (or
313227569Sphilip    ///   array of such types) or reference,
314227569Sphilip    /// * has no virtual functions (10.3) and no virtual base classes (10.1),
315227569Sphilip    /// * has the same access control (Clause 11) for all non-static data members
316227569Sphilip    /// * has no non-standard-layout base classes,
317227569Sphilip    /// * either has no non-static data members in the most derived class and at
318227569Sphilip    ///   most one base class with non-static data members, or has no base
319227569Sphilip    ///   classes with non-static data members, and
320227569Sphilip    /// * has no base classes of the same type as the first non-static data
321227569Sphilip    ///   member.
322227569Sphilip    bool IsStandardLayout : 1;
323227569Sphilip
324227569Sphilip    /// HasNoNonEmptyBases - True when there are no non-empty base classes.
325227569Sphilip    ///
326284555Sarybchik    /// This is a helper bit of state used to implement IsStandardLayout more
327227569Sphilip    /// efficiently.
328227569Sphilip    bool HasNoNonEmptyBases : 1;
329227569Sphilip
330227569Sphilip    /// HasPrivateFields - True when there are private non-static data members.
331227569Sphilip    bool HasPrivateFields : 1;
332227569Sphilip
333227569Sphilip    /// HasProtectedFields - True when there are protected non-static data
334227569Sphilip    /// members.
335227569Sphilip    bool HasProtectedFields : 1;
336227569Sphilip
337227569Sphilip    /// HasPublicFields - True when there are private non-static data members.
338227569Sphilip    bool HasPublicFields : 1;
339227569Sphilip
340227569Sphilip    /// HasTrivialConstructor - True when this class has a trivial constructor.
341227569Sphilip    ///
342227569Sphilip    /// C++ [class.ctor]p5.  A constructor is trivial if it is an
343227569Sphilip    /// implicitly-declared default constructor and if:
344227569Sphilip    /// * its class has no virtual functions and no virtual base classes, and
345227569Sphilip    /// * all the direct base classes of its class have trivial constructors, and
346227569Sphilip    /// * for all the nonstatic data members of its class that are of class type
347227569Sphilip    ///   (or array thereof), each such class has a trivial constructor.
348227569Sphilip    bool HasTrivialConstructor : 1;
349227569Sphilip
350227569Sphilip    /// HasConstExprNonCopyMoveConstructor - True when this class has at least
351227569Sphilip    /// one constexpr constructor which is neither the copy nor move
352227569Sphilip    /// constructor.
353227569Sphilip    bool HasConstExprNonCopyMoveConstructor : 1;
354227569Sphilip
355227569Sphilip    /// HasTrivialCopyConstructor - True when this class has a trivial copy
356227569Sphilip    /// constructor.
357227569Sphilip    ///
358227569Sphilip    /// C++0x [class.copy]p13:
359227569Sphilip    ///   A copy/move constructor for class X is trivial if it is neither
360227569Sphilip    ///   user-provided nor deleted and if
361227569Sphilip    ///    -- class X has no virtual functions and no virtual base classes, and
362227569Sphilip    ///    -- the constructor selected to copy/move each direct base class
363227569Sphilip    ///       subobject is trivial, and
364227569Sphilip    ///    -- for each non-static data member of X that is of class type (or an
365227569Sphilip    ///       array thereof), the constructor selected to copy/move that member
366227569Sphilip    ///       is trivial;
367227569Sphilip    ///   otherwise the copy/move constructor is non-trivial.
368227569Sphilip    bool HasTrivialCopyConstructor : 1;
369227569Sphilip
370227569Sphilip    /// HasTrivialMoveConstructor - True when this class has a trivial move
371227569Sphilip    /// constructor.
372227569Sphilip    ///
373227569Sphilip    /// C++0x [class.copy]p13:
374227569Sphilip    ///   A copy/move constructor for class X is trivial if it is neither
375227569Sphilip    ///   user-provided nor deleted and if
376227569Sphilip    ///    -- class X has no virtual functions and no virtual base classes, and
377227569Sphilip    ///    -- the constructor selected to copy/move each direct base class
378227569Sphilip    ///       subobject is trivial, and
379284555Sarybchik    ///    -- for each non-static data member of X that is of class type (or an
380284555Sarybchik    ///       array thereof), the constructor selected to copy/move that member
381284555Sarybchik    ///       is trivial;
382284555Sarybchik    ///   otherwise the copy/move constructor is non-trivial.
383284555Sarybchik    bool HasTrivialMoveConstructor : 1;
384284555Sarybchik
385284555Sarybchik    /// HasTrivialCopyAssignment - True when this class has a trivial copy
386284555Sarybchik    /// assignment operator.
387284555Sarybchik    ///
388284555Sarybchik    /// C++0x [class.copy]p27:
389284555Sarybchik    ///   A copy/move assignment operator for class X is trivial if it is
390284555Sarybchik    ///   neither user-provided nor deleted and if
391284555Sarybchik    ///    -- class X has no virtual functions and no virtual base classes, and
392284555Sarybchik    ///    -- the assignment operator selected to copy/move each direct base
393284555Sarybchik    ///       class subobject is trivial, and
394284555Sarybchik    ///    -- for each non-static data member of X that is of class type (or an
395284555Sarybchik    ///       array thereof), the assignment operator selected to copy/move
396284555Sarybchik    ///       that member is trivial;
397284555Sarybchik    ///   otherwise the copy/move assignment operator is non-trivial.
398284555Sarybchik    bool HasTrivialCopyAssignment : 1;
399284555Sarybchik
400284555Sarybchik    /// HasTrivialMoveAssignment - True when this class has a trivial move
401284555Sarybchik    /// assignment operator.
402284555Sarybchik    ///
403284555Sarybchik    /// C++0x [class.copy]p27:
404284555Sarybchik    ///   A copy/move assignment operator for class X is trivial if it is
405284555Sarybchik    ///   neither user-provided nor deleted and if
406284555Sarybchik    ///    -- class X has no virtual functions and no virtual base classes, and
407284555Sarybchik    ///    -- the assignment operator selected to copy/move each direct base
408284555Sarybchik    ///       class subobject is trivial, and
409227569Sphilip    ///    -- for each non-static data member of X that is of class type (or an
410227569Sphilip    ///       array thereof), the assignment operator selected to copy/move
411227569Sphilip    ///       that member is trivial;
412227569Sphilip    ///   otherwise the copy/move assignment operator is non-trivial.
413227569Sphilip    bool HasTrivialMoveAssignment : 1;
414227569Sphilip
415227569Sphilip    /// HasTrivialDestructor - True when this class has a trivial destructor.
416227569Sphilip    ///
417227569Sphilip    /// C++ [class.dtor]p3.  A destructor is trivial if it is an
418227569Sphilip    /// implicitly-declared destructor and if:
419227569Sphilip    /// * all of the direct base classes of its class have trivial destructors
420227569Sphilip    ///   and
421227569Sphilip    /// * for all of the non-static data members of its class that are of class
422227569Sphilip    ///   type (or array thereof), each such class has a trivial destructor.
423227569Sphilip    bool HasTrivialDestructor : 1;
424227569Sphilip
425227569Sphilip    /// HasNonLiteralTypeFieldsOrBases - True when this class contains at least
426284555Sarybchik    /// one non-static data member or base class of non literal type.
427227569Sphilip    bool HasNonLiteralTypeFieldsOrBases : 1;
428227569Sphilip
429227569Sphilip    /// ComputedVisibleConversions - True when visible conversion functions are
430284555Sarybchik    /// already computed and are available.
431284555Sarybchik    bool ComputedVisibleConversions : 1;
432284555Sarybchik
433284555Sarybchik    /// \brief Whether we have already declared the default constructor or
434284555Sarybchik    /// do not need to have one declared.
435284555Sarybchik    bool DeclaredDefaultConstructor : 1;
436227569Sphilip
437227569Sphilip    /// \brief Whether we have already declared the copy constructor.
438227569Sphilip    bool DeclaredCopyConstructor : 1;
439227569Sphilip
440227569Sphilip    /// \brief Whether we have already declared the copy-assignment operator.
441227569Sphilip    bool DeclaredCopyAssignment : 1;
442227569Sphilip
443227569Sphilip    /// \brief Whether we have already declared a destructor within the class.
444227569Sphilip    bool DeclaredDestructor : 1;
445227569Sphilip
446227569Sphilip    /// NumBases - The number of base class specifiers in Bases.
447227569Sphilip    unsigned NumBases;
448227569Sphilip
449293927Sarybchik    /// NumVBases - The number of virtual base class specifiers in VBases.
450227569Sphilip    unsigned NumVBases;
451227569Sphilip
452227569Sphilip    /// Bases - Base classes of this class.
453227569Sphilip    /// FIXME: This is wasted space for a union.
454293927Sarybchik    LazyCXXBaseSpecifiersPtr Bases;
455227569Sphilip
456227569Sphilip    /// VBases - direct and indirect virtual base classes of this class.
457227569Sphilip    LazyCXXBaseSpecifiersPtr VBases;
458227569Sphilip
459293927Sarybchik    /// Conversions - Overload set containing the conversion functions
460284555Sarybchik    /// of this C++ class (but not its inherited conversion
461284555Sarybchik    /// functions). Each of the entries in this overload set is a
462284555Sarybchik    /// CXXConversionDecl.
463284555Sarybchik    UnresolvedSet<4> Conversions;
464284555Sarybchik
465284555Sarybchik    /// VisibleConversions - Overload set containing the conversion
466284555Sarybchik    /// functions of this C++ class and all those inherited conversion
467293927Sarybchik    /// functions that are visible in this class. Each of the entries
468284555Sarybchik    /// in this overload set is a CXXConversionDecl or a
469284555Sarybchik    /// FunctionTemplateDecl.
470284555Sarybchik    UnresolvedSet<4> VisibleConversions;
471284555Sarybchik
472284555Sarybchik    /// Definition - The declaration which defines this record.
473293927Sarybchik    CXXRecordDecl *Definition;
474284555Sarybchik
475227569Sphilip    /// FirstFriend - The first friend declaration in this class, or
476284555Sarybchik    /// null if there aren't any.  This is actually currently stored
477284555Sarybchik    /// in reverse order.
478227569Sphilip    FriendDecl *FirstFriend;
479284555Sarybchik
480284555Sarybchik    /// \brief Retrieve the set of direct base classes.
481284555Sarybchik    CXXBaseSpecifier *getBases() const {
482284555Sarybchik      return Bases.get(Definition->getASTContext().getExternalSource());
483293927Sarybchik    }
484227569Sphilip
485227569Sphilip    /// \brief Retrieve the set of virtual base classes.
486227569Sphilip    CXXBaseSpecifier *getVBases() const {
487227569Sphilip      return VBases.get(Definition->getASTContext().getExternalSource());
488293927Sarybchik    }
489227569Sphilip  } *DefinitionData;
490227569Sphilip
491227569Sphilip  struct DefinitionData &data() {
492227569Sphilip    assert(DefinitionData && "queried property of class with no definition");
493227569Sphilip    return *DefinitionData;
494227569Sphilip  }
495227569Sphilip
496293927Sarybchik  const struct DefinitionData &data() const {
497227569Sphilip    assert(DefinitionData && "queried property of class with no definition");
498227569Sphilip    return *DefinitionData;
499227569Sphilip  }
500227569Sphilip
501227569Sphilip  /// \brief The template or declaration that this declaration
502227569Sphilip  /// describes or was instantiated from, respectively.
503227569Sphilip  ///
504227569Sphilip  /// For non-templates, this value will be NULL. For record
505227569Sphilip  /// declarations that describe a class template, this will be a
506227569Sphilip  /// pointer to a ClassTemplateDecl. For member
507227569Sphilip  /// classes of class template specializations, this will be the
508227569Sphilip  /// MemberSpecializationInfo referring to the member class that was
509227569Sphilip  /// instantiated or specialized.
510227569Sphilip  llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*>
511227569Sphilip    TemplateOrInstantiation;
512227569Sphilip
513284555Sarybchik  friend class DeclContext;
514227569Sphilip
515227569Sphilip  /// \brief Notify the class that member has been added.
516227569Sphilip  ///
517227569Sphilip  /// This routine helps maintain information about the class based on which
518227569Sphilip  /// members have been added. It will be invoked by DeclContext::addDecl()
519227569Sphilip  /// whenever a member is added to this record.
520227569Sphilip  void addedMember(Decl *D);
521227569Sphilip
522227569Sphilip  void markedVirtualFunctionPure();
523227569Sphilip  friend void FunctionDecl::setPure(bool);
524227569Sphilip
525227569Sphilipprotected:
526227569Sphilip  CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
527227569Sphilip                SourceLocation StartLoc, SourceLocation IdLoc,
528227569Sphilip                IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
529227569Sphilip
530227569Sphilippublic:
531227569Sphilip  /// base_class_iterator - Iterator that traverses the base classes
532227569Sphilip  /// of a class.
533227569Sphilip  typedef CXXBaseSpecifier*       base_class_iterator;
534227569Sphilip
535293927Sarybchik  /// base_class_const_iterator - Iterator that traverses the base
536227569Sphilip  /// classes of a class.
537227569Sphilip  typedef const CXXBaseSpecifier* base_class_const_iterator;
538227569Sphilip
539227569Sphilip  /// reverse_base_class_iterator = Iterator that traverses the base classes
540293927Sarybchik  /// of a class in reverse order.
541227569Sphilip  typedef std::reverse_iterator<base_class_iterator>
542227569Sphilip    reverse_base_class_iterator;
543227569Sphilip
544227569Sphilip  /// reverse_base_class_iterator = Iterator that traverses the base classes
545227569Sphilip  /// of a class in reverse order.
546227569Sphilip  typedef std::reverse_iterator<base_class_const_iterator>
547293927Sarybchik    reverse_base_class_const_iterator;
548227569Sphilip
549227569Sphilip  virtual CXXRecordDecl *getCanonicalDecl() {
550227569Sphilip    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
551227569Sphilip  }
552293923Sarybchik  virtual const CXXRecordDecl *getCanonicalDecl() const {
553227569Sphilip    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
554227569Sphilip  }
555227569Sphilip
556227569Sphilip  const CXXRecordDecl *getPreviousDeclaration() const {
557227569Sphilip    return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDeclaration());
558227569Sphilip  }
559227569Sphilip  CXXRecordDecl *getPreviousDeclaration() {
560227569Sphilip    return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDeclaration());
561227569Sphilip  }
562227569Sphilip
563227569Sphilip  CXXRecordDecl *getDefinition() const {
564284555Sarybchik    if (!DefinitionData) return 0;
565293978Sarybchik    return data().Definition;
566227569Sphilip  }
567227569Sphilip
568227569Sphilip  bool hasDefinition() const { return DefinitionData != 0; }
569227569Sphilip
570227569Sphilip  static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
571284555Sarybchik                               SourceLocation StartLoc, SourceLocation IdLoc,
572227569Sphilip                               IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0,
573227569Sphilip                               bool DelayTypeCreation = false);
574227569Sphilip  static CXXRecordDecl *Create(const ASTContext &C, EmptyShell Empty);
575227569Sphilip
576227569Sphilip  bool isDynamicClass() const {
577293927Sarybchik    return data().Polymorphic || data().NumVBases != 0;
578227569Sphilip  }
579227569Sphilip
580227569Sphilip  /// setBases - Sets the base classes of this struct or class.
581227569Sphilip  void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
582227569Sphilip
583284555Sarybchik  /// getNumBases - Retrieves the number of base classes of this
584284555Sarybchik  /// class.
585227569Sphilip  unsigned getNumBases() const { return data().NumBases; }
586293981Sarybchik
587227569Sphilip  base_class_iterator bases_begin() { return data().getBases(); }
588227569Sphilip  base_class_const_iterator bases_begin() const { return data().getBases(); }
589227569Sphilip  base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
590227569Sphilip  base_class_const_iterator bases_end() const {
591227569Sphilip    return bases_begin() + data().NumBases;
592227569Sphilip  }
593227569Sphilip  reverse_base_class_iterator       bases_rbegin() {
594227569Sphilip    return reverse_base_class_iterator(bases_end());
595227569Sphilip  }
596227569Sphilip  reverse_base_class_const_iterator bases_rbegin() const {
597227569Sphilip    return reverse_base_class_const_iterator(bases_end());
598227569Sphilip  }
599227569Sphilip  reverse_base_class_iterator bases_rend() {
600227569Sphilip    return reverse_base_class_iterator(bases_begin());
601227569Sphilip  }
602227569Sphilip  reverse_base_class_const_iterator bases_rend() const {
603227569Sphilip    return reverse_base_class_const_iterator(bases_begin());
604280551Sarybchik  }
605280551Sarybchik
606280551Sarybchik  /// getNumVBases - Retrieves the number of virtual base classes of this
607280551Sarybchik  /// class.
608280551Sarybchik  unsigned getNumVBases() const { return data().NumVBases; }
609280551Sarybchik
610280551Sarybchik  base_class_iterator vbases_begin() { return data().getVBases(); }
611280551Sarybchik  base_class_const_iterator vbases_begin() const { return data().getVBases(); }
612280551Sarybchik  base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
613280551Sarybchik  base_class_const_iterator vbases_end() const {
614280551Sarybchik    return vbases_begin() + data().NumVBases;
615280551Sarybchik  }
616280551Sarybchik  reverse_base_class_iterator vbases_rbegin() {
617280551Sarybchik    return reverse_base_class_iterator(vbases_end());
618284555Sarybchik  }
619284555Sarybchik  reverse_base_class_const_iterator vbases_rbegin() const {
620284555Sarybchik    return reverse_base_class_const_iterator(vbases_end());
621284555Sarybchik  }
622284555Sarybchik  reverse_base_class_iterator vbases_rend() {
623284555Sarybchik    return reverse_base_class_iterator(vbases_begin());
624284555Sarybchik  }
625284555Sarybchik  reverse_base_class_const_iterator vbases_rend() const {
626284555Sarybchik    return reverse_base_class_const_iterator(vbases_begin());
627284555Sarybchik }
628284555Sarybchik
629284555Sarybchik  /// \brief Determine whether this class has any dependent base classes.
630284555Sarybchik  bool hasAnyDependentBases() const;
631284555Sarybchik
632284555Sarybchik  /// Iterator access to method members.  The method iterator visits
633284555Sarybchik  /// all method members of the class, including non-instance methods,
634284555Sarybchik  /// special methods, etc.
635284555Sarybchik  typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
636284555Sarybchik
637284555Sarybchik  /// method_begin - Method begin iterator.  Iterates in the order the methods
638284555Sarybchik  /// were declared.
639284555Sarybchik  method_iterator method_begin() const {
640284555Sarybchik    return method_iterator(decls_begin());
641284555Sarybchik  }
642284555Sarybchik  /// method_end - Method end iterator.
643284555Sarybchik  method_iterator method_end() const {
644284555Sarybchik    return method_iterator(decls_end());
645284555Sarybchik  }
646284555Sarybchik
647284555Sarybchik  /// Iterator access to constructor members.
648284555Sarybchik  typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
649284555Sarybchik
650284555Sarybchik  ctor_iterator ctor_begin() const {
651284555Sarybchik    return ctor_iterator(decls_begin());
652284555Sarybchik  }
653284555Sarybchik  ctor_iterator ctor_end() const {
654284555Sarybchik    return ctor_iterator(decls_end());
655284555Sarybchik  }
656284555Sarybchik
657293981Sarybchik  /// An iterator over friend declarations.  All of these are defined
658293981Sarybchik  /// in DeclFriend.h.
659293981Sarybchik  class friend_iterator;
660293981Sarybchik  friend_iterator friend_begin() const;
661293981Sarybchik  friend_iterator friend_end() const;
662293981Sarybchik  void pushFriendDecl(FriendDecl *FD);
663227569Sphilip
664227569Sphilip  /// Determines whether this record has any friends.
665227569Sphilip  bool hasFriends() const {
666227569Sphilip    return data().FirstFriend != 0;
667227569Sphilip  }
668227569Sphilip
669227569Sphilip  /// \brief Determine whether this class has had its default constructor
670227569Sphilip  /// declared implicitly or does not need one declared implicitly.
671227569Sphilip  ///
672227569Sphilip  /// This value is used for lazy creation of default constructors.
673284555Sarybchik  bool hasDeclaredDefaultConstructor() const {
674227569Sphilip    return data().DeclaredDefaultConstructor;
675227569Sphilip  }
676284555Sarybchik
677227569Sphilip  /// hasConstCopyConstructor - Determines whether this class has a
678227569Sphilip  /// copy constructor that accepts a const-qualified argument.
679227569Sphilip  bool hasConstCopyConstructor(const ASTContext &Context) const;
680227569Sphilip
681227569Sphilip  /// getCopyConstructor - Returns the copy constructor for this class
682227569Sphilip  CXXConstructorDecl *getCopyConstructor(const ASTContext &Context,
683284555Sarybchik                                         unsigned TypeQuals) const;
684227569Sphilip
685227569Sphilip  /// \brief Retrieve the copy-assignment operator for this class, if available.
686227569Sphilip  ///
687227569Sphilip  /// This routine attempts to find the copy-assignment operator for this
688227569Sphilip  /// class, using a simplistic form of overload resolution.
689227569Sphilip  ///
690293927Sarybchik  /// \param ArgIsConst Whether the argument to the copy-assignment operator
691227569Sphilip  /// is const-qualified.
692227569Sphilip  ///
693227569Sphilip  /// \returns The copy-assignment operator that can be invoked, or NULL if
694293921Sarybchik  /// a unique copy-assignment operator could not be found.
695227569Sphilip  CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const;
696227569Sphilip
697227569Sphilip  /// hasUserDeclaredConstructor - Whether this class has any
698227569Sphilip  /// user-declared constructors. When true, a default constructor
699227569Sphilip  /// will not be implicitly declared.
700227569Sphilip  bool hasUserDeclaredConstructor() const {
701227569Sphilip    return data().UserDeclaredConstructor;
702227569Sphilip  }
703227569Sphilip
704227569Sphilip  /// hasUserDeclaredCopyConstructor - Whether this class has a
705227569Sphilip  /// user-declared copy constructor. When false, a copy constructor
706227569Sphilip  /// will be implicitly declared.
707227569Sphilip  bool hasUserDeclaredCopyConstructor() const {
708227569Sphilip    return data().UserDeclaredCopyConstructor;
709227569Sphilip  }
710227569Sphilip
711227569Sphilip  /// \brief Determine whether this class has had its copy constructor
712227569Sphilip  /// declared, either via the user or via an implicit declaration.
713293927Sarybchik  ///
714227569Sphilip  /// This value is used for lazy creation of copy constructors.
715227569Sphilip  bool hasDeclaredCopyConstructor() const {
716227569Sphilip    return data().DeclaredCopyConstructor;
717227569Sphilip  }
718227569Sphilip
719227569Sphilip  /// hasUserDeclaredCopyAssignment - Whether this class has a
720227569Sphilip  /// user-declared copy assignment operator. When false, a copy
721227569Sphilip  /// assigment operator will be implicitly declared.
722227569Sphilip  bool hasUserDeclaredCopyAssignment() const {
723227569Sphilip    return data().UserDeclaredCopyAssignment;
724227569Sphilip  }
725227569Sphilip
726227569Sphilip  /// \brief Determine whether this class has had its copy assignment operator
727293927Sarybchik  /// declared, either via the user or via an implicit declaration.
728227569Sphilip  ///
729227569Sphilip  /// This value is used for lazy creation of copy assignment operators.
730227569Sphilip  bool hasDeclaredCopyAssignment() const {
731227569Sphilip    return data().DeclaredCopyAssignment;
732227569Sphilip  }
733227569Sphilip
734293927Sarybchik  /// hasUserDeclaredDestructor - Whether this class has a
735227569Sphilip  /// user-declared destructor. When false, a destructor will be
736227569Sphilip  /// implicitly declared.
737227569Sphilip  bool hasUserDeclaredDestructor() const {
738227569Sphilip    return data().UserDeclaredDestructor;
739227569Sphilip  }
740227569Sphilip
741227569Sphilip  /// \brief Determine whether this class has had its destructor declared,
742227569Sphilip  /// either via the user or via an implicit declaration.
743227569Sphilip  ///
744227569Sphilip  /// This value is used for lazy creation of destructors.
745227569Sphilip  bool hasDeclaredDestructor() const { return data().DeclaredDestructor; }
746227569Sphilip
747227569Sphilip  /// getConversions - Retrieve the overload set containing all of the
748227569Sphilip  /// conversion functions in this class.
749227569Sphilip  UnresolvedSetImpl *getConversionFunctions() {
750227569Sphilip    return &data().Conversions;
751227569Sphilip  }
752227569Sphilip  const UnresolvedSetImpl *getConversionFunctions() const {
753227569Sphilip    return &data().Conversions;
754227569Sphilip  }
755227569Sphilip
756227569Sphilip  typedef UnresolvedSetImpl::iterator conversion_iterator;
757227569Sphilip  conversion_iterator conversion_begin() const {
758227569Sphilip    return getConversionFunctions()->begin();
759284555Sarybchik  }
760284555Sarybchik  conversion_iterator conversion_end() const {
761284555Sarybchik    return getConversionFunctions()->end();
762284555Sarybchik  }
763284555Sarybchik
764284555Sarybchik  /// Removes a conversion function from this class.  The conversion
765284555Sarybchik  /// function must currently be a member of this class.  Furthermore,
766284555Sarybchik  /// this class must currently be in the process of being defined.
767284555Sarybchik  void removeConversion(const NamedDecl *Old);
768284555Sarybchik
769284555Sarybchik  /// getVisibleConversionFunctions - get all conversion functions visible
770284555Sarybchik  /// in current class; including conversion function templates.
771284555Sarybchik  const UnresolvedSetImpl *getVisibleConversionFunctions();
772284555Sarybchik
773284555Sarybchik  /// isAggregate - Whether this class is an aggregate (C++
774284555Sarybchik  /// [dcl.init.aggr]), which is a class with no user-declared
775284555Sarybchik  /// constructors, no private or protected non-static data members,
776227569Sphilip  /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
777227569Sphilip  bool isAggregate() const { return data().Aggregate; }
778227569Sphilip
779284555Sarybchik  /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
780284555Sarybchik  /// that is an aggregate that has no non-static non-POD data members, no
781284555Sarybchik  /// reference data members, no user-defined copy assignment operator and no
782284555Sarybchik  /// user-defined destructor.
783284555Sarybchik  bool isPOD() const { return data().PlainOldData; }
784284555Sarybchik
785284555Sarybchik  /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which
786227569Sphilip  /// means it has a virtual function, virtual base, data member (other than
787284555Sarybchik  /// 0-width bit-field) or inherits from a non-empty class. Does NOT include
788284555Sarybchik  /// a check for union-ness.
789284555Sarybchik  bool isEmpty() const { return data().Empty; }
790284555Sarybchik
791227569Sphilip  /// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]),
792293927Sarybchik  /// which means that the class contains or inherits a virtual function.
793227569Sphilip  bool isPolymorphic() const { return data().Polymorphic; }
794227569Sphilip
795227569Sphilip  /// isAbstract - Whether this class is abstract (C++ [class.abstract]),
796227569Sphilip  /// which means that the class contains or inherits a pure virtual function.
797227569Sphilip  bool isAbstract() const { return data().Abstract; }
798227569Sphilip
799227569Sphilip  /// isStandardLayout - Whether this class has standard layout
800284555Sarybchik  /// (C++ [class]p7)
801227569Sphilip  bool isStandardLayout() const { return data().IsStandardLayout; }
802227569Sphilip
803227569Sphilip  // hasTrivialConstructor - Whether this class has a trivial constructor
804227569Sphilip  // (C++ [class.ctor]p5)
805227569Sphilip  bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
806227569Sphilip
807227569Sphilip  // hasConstExprNonCopyMoveConstructor - Whether this class has at least one
808227569Sphilip  // constexpr constructor other than the copy or move constructors
809293927Sarybchik  bool hasConstExprNonCopyMoveConstructor() const {
810227569Sphilip    return data().HasConstExprNonCopyMoveConstructor;
811227569Sphilip  }
812284555Sarybchik
813227569Sphilip  // hasTrivialCopyConstructor - Whether this class has a trivial copy
814227569Sphilip  // constructor (C++ [class.copy]p6, C++0x [class.copy]p13)
815227569Sphilip  bool hasTrivialCopyConstructor() const {
816227569Sphilip    return data().HasTrivialCopyConstructor;
817227569Sphilip  }
818227569Sphilip
819227569Sphilip  // hasTrivialMoveConstructor - Whether this class has a trivial move
820227569Sphilip  // constructor (C++0x [class.copy]p13)
821227569Sphilip  bool hasTrivialMoveConstructor() const {
822227569Sphilip    return data().HasTrivialMoveConstructor;
823227569Sphilip  }
824227569Sphilip
825227569Sphilip  // hasTrivialCopyAssignment - Whether this class has a trivial copy
826227569Sphilip  // assignment operator (C++ [class.copy]p11, C++0x [class.copy]p27)
827227569Sphilip  bool hasTrivialCopyAssignment() const {
828227569Sphilip    return data().HasTrivialCopyAssignment;
829227569Sphilip  }
830284555Sarybchik
831227569Sphilip  // hasTrivialMoveAssignment - Whether this class has a trivial move
832227569Sphilip  // assignment operator (C++0x [class.copy]p27)
833227569Sphilip  bool hasTrivialMoveAssignment() const {
834227569Sphilip    return data().HasTrivialMoveAssignment;
835227569Sphilip  }
836227569Sphilip
837227569Sphilip  // hasTrivialDestructor - Whether this class has a trivial destructor
838227569Sphilip  // (C++ [class.dtor]p3)
839227569Sphilip  bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
840227569Sphilip
841227569Sphilip  // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal type
842227569Sphilip  // non-static data member or base class.
843227569Sphilip  bool hasNonLiteralTypeFieldsOrBases() const {
844227569Sphilip    return data().HasNonLiteralTypeFieldsOrBases;
845293927Sarybchik  }
846227569Sphilip
847227569Sphilip  // isTriviallyCopyable - Whether this class is considered trivially copyable
848227569Sphilip  // (C++0x [class]p5).
849227569Sphilip  bool isTriviallyCopyable() const;
850227569Sphilip
851227569Sphilip  /// \brief If this record is an instantiation of a member class,
852227569Sphilip  /// retrieves the member class from which it was instantiated.
853227569Sphilip  ///
854227569Sphilip  /// This routine will return non-NULL for (non-templated) member
855293927Sarybchik  /// classes of class templates. For example, given:
856227569Sphilip  ///
857227569Sphilip  /// \code
858227569Sphilip  /// template<typename T>
859227569Sphilip  /// struct X {
860227569Sphilip  ///   struct A { };
861227569Sphilip  /// };
862227569Sphilip  /// \endcode
863227569Sphilip  ///
864227569Sphilip  /// The declaration for X<int>::A is a (non-templated) CXXRecordDecl
865227569Sphilip  /// whose parent is the class template specialization X<int>. For
866227569Sphilip  /// this declaration, getInstantiatedFromMemberClass() will return
867227569Sphilip  /// the CXXRecordDecl X<T>::A. When a complete definition of
868284555Sarybchik  /// X<int>::A is required, it will be instantiated from the
869227569Sphilip  /// declaration returned by getInstantiatedFromMemberClass().
870227569Sphilip  CXXRecordDecl *getInstantiatedFromMemberClass() const;
871227569Sphilip
872227569Sphilip  /// \brief If this class is an instantiation of a member class of a
873227569Sphilip  /// class template specialization, retrieves the member specialization
874227569Sphilip  /// information.
875227569Sphilip  MemberSpecializationInfo *getMemberSpecializationInfo() const;
876227569Sphilip
877227569Sphilip  /// \brief Specify that this record is an instantiation of the
878227569Sphilip  /// member class RD.
879227569Sphilip  void setInstantiationOfMemberClass(CXXRecordDecl *RD,
880227569Sphilip                                     TemplateSpecializationKind TSK);
881227569Sphilip
882295526Sarybchik  /// \brief Retrieves the class template that is described by this
883295526Sarybchik  /// class declaration.
884295526Sarybchik  ///
885295526Sarybchik  /// Every class template is represented as a ClassTemplateDecl and a
886295526Sarybchik  /// CXXRecordDecl. The former contains template properties (such as
887295526Sarybchik  /// the template parameter lists) while the latter contains the
888295526Sarybchik  /// actual description of the template's
889295526Sarybchik  /// contents. ClassTemplateDecl::getTemplatedDecl() retrieves the
890227569Sphilip  /// CXXRecordDecl that from a ClassTemplateDecl, while
891227569Sphilip  /// getDescribedClassTemplate() retrieves the ClassTemplateDecl from
892227569Sphilip  /// a CXXRecordDecl.
893227569Sphilip  ClassTemplateDecl *getDescribedClassTemplate() const {
894227569Sphilip    return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl*>();
895227569Sphilip  }
896227569Sphilip
897227569Sphilip  void setDescribedClassTemplate(ClassTemplateDecl *Template) {
898227569Sphilip    TemplateOrInstantiation = Template;
899227569Sphilip  }
900227569Sphilip
901227569Sphilip  /// \brief Determine whether this particular class is a specialization or
902227569Sphilip  /// instantiation of a class template or member class of a class template,
903227569Sphilip  /// and how it was instantiated or specialized.
904227569Sphilip  TemplateSpecializationKind getTemplateSpecializationKind() const;
905227569Sphilip
906227569Sphilip  /// \brief Set the kind of specialization or template instantiation this is.
907227569Sphilip  void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
908227569Sphilip
909227569Sphilip  /// getDestructor - Returns the destructor decl for this class.
910227569Sphilip  CXXDestructorDecl *getDestructor() const;
911227569Sphilip
912227569Sphilip  /// isLocalClass - If the class is a local class [class.local], returns
913227569Sphilip  /// the enclosing function declaration.
914227569Sphilip  const FunctionDecl *isLocalClass() const {
915227569Sphilip    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
916227569Sphilip      return RD->isLocalClass();
917227569Sphilip
918227569Sphilip    return dyn_cast<FunctionDecl>(getDeclContext());
919227569Sphilip  }
920227569Sphilip
921227569Sphilip  /// \brief Determine whether this class is derived from the class \p Base.
922227569Sphilip  ///
923227569Sphilip  /// This routine only determines whether this class is derived from \p Base,
924227569Sphilip  /// but does not account for factors that may make a Derived -> Base class
925227569Sphilip  /// ill-formed, such as private/protected inheritance or multiple, ambiguous
926227569Sphilip  /// base class subobjects.
927227569Sphilip  ///
928227569Sphilip  /// \param Base the base class we are searching for.
929227569Sphilip  ///
930227569Sphilip  /// \returns true if this class is derived from Base, false otherwise.
931227569Sphilip  bool isDerivedFrom(const CXXRecordDecl *Base) const;
932227569Sphilip
933227569Sphilip  /// \brief Determine whether this class is derived from the type \p Base.
934227569Sphilip  ///
935227569Sphilip  /// This routine only determines whether this class is derived from \p Base,
936227569Sphilip  /// but does not account for factors that may make a Derived -> Base class
937227569Sphilip  /// ill-formed, such as private/protected inheritance or multiple, ambiguous
938227569Sphilip  /// base class subobjects.
939227569Sphilip  ///
940227569Sphilip  /// \param Base the base class we are searching for.
941227569Sphilip  ///
942227569Sphilip  /// \param Paths will contain the paths taken from the current class to the
943227569Sphilip  /// given \p Base class.
944227569Sphilip  ///
945227569Sphilip  /// \returns true if this class is derived from Base, false otherwise.
946227569Sphilip  ///
947284555Sarybchik  /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
948227569Sphilip  /// tangling input and output in \p Paths
949227569Sphilip  bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const;
950227569Sphilip
951227569Sphilip  /// \brief Determine whether this class is virtually derived from
952227569Sphilip  /// the class \p Base.
953227569Sphilip  ///
954227569Sphilip  /// This routine only determines whether this class is virtually
955227569Sphilip  /// derived from \p Base, but does not account for factors that may
956293927Sarybchik  /// make a Derived -> Base class ill-formed, such as
957227569Sphilip  /// private/protected inheritance or multiple, ambiguous base class
958227569Sphilip  /// subobjects.
959227569Sphilip  ///
960293921Sarybchik  /// \param Base the base class we are searching for.
961227569Sphilip  ///
962227569Sphilip  /// \returns true if this class is virtually derived from Base,
963227569Sphilip  /// false otherwise.
964227569Sphilip  bool isVirtuallyDerivedFrom(CXXRecordDecl *Base) const;
965227569Sphilip
966227569Sphilip  /// \brief Determine whether this class is provably not derived from
967227569Sphilip  /// the type \p Base.
968284555Sarybchik  bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const;
969227569Sphilip
970227569Sphilip  /// \brief Function type used by forallBases() as a callback.
971227569Sphilip  ///
972227569Sphilip  /// \param Base the definition of the base class
973227569Sphilip  ///
974227569Sphilip  /// \returns true if this base matched the search criteria
975227569Sphilip  typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition,
976227569Sphilip                                   void *UserData);
977293927Sarybchik
978227569Sphilip  /// \brief Determines if the given callback holds for all the direct
979227569Sphilip  /// or indirect base classes of this type.
980227569Sphilip  ///
981227569Sphilip  /// The class itself does not count as a base class.  This routine
982227569Sphilip  /// returns false if the class has non-computable base classes.
983227569Sphilip  ///
984293927Sarybchik  /// \param AllowShortCircuit if false, forces the callback to be called
985227569Sphilip  /// for every base class, even if a dependent or non-matching base was
986227569Sphilip  /// found.
987227569Sphilip  bool forallBases(ForallBasesCallback *BaseMatches, void *UserData,
988227569Sphilip                   bool AllowShortCircuit = true) const;
989227569Sphilip
990227569Sphilip  /// \brief Function type used by lookupInBases() to determine whether a
991227569Sphilip  /// specific base class subobject matches the lookup criteria.
992284555Sarybchik  ///
993227569Sphilip  /// \param Specifier the base-class specifier that describes the inheritance
994284555Sarybchik  /// from the base class we are trying to match.
995284555Sarybchik  ///
996284555Sarybchik  /// \param Path the current path, from the most-derived class down to the
997284555Sarybchik  /// base named by the \p Specifier.
998284555Sarybchik  ///
999284555Sarybchik  /// \param UserData a single pointer to user-specified data, provided to
1000284555Sarybchik  /// lookupInBases().
1001284555Sarybchik  ///
1002284555Sarybchik  /// \returns true if this base matched the search criteria, false otherwise.
1003284555Sarybchik  typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier,
1004227569Sphilip                                   CXXBasePath &Path,
1005284555Sarybchik                                   void *UserData);
1006284555Sarybchik
1007284555Sarybchik  /// \brief Look for entities within the base classes of this C++ class,
1008284555Sarybchik  /// transitively searching all base class subobjects.
1009284555Sarybchik  ///
1010284555Sarybchik  /// This routine uses the callback function \p BaseMatches to find base
1011227569Sphilip  /// classes meeting some search criteria, walking all base class subobjects
1012227569Sphilip  /// and populating the given \p Paths structure with the paths through the
1013227569Sphilip  /// inheritance hierarchy that resulted in a match. On a successful search,
1014227569Sphilip  /// the \p Paths structure can be queried to retrieve the matching paths and
1015227569Sphilip  /// to determine if there were any ambiguities.
1016227569Sphilip  ///
1017227569Sphilip  /// \param BaseMatches callback function used to determine whether a given
1018227569Sphilip  /// base matches the user-defined search criteria.
1019227569Sphilip  ///
1020227569Sphilip  /// \param UserData user data pointer that will be provided to \p BaseMatches.
1021284555Sarybchik  ///
1022284555Sarybchik  /// \param Paths used to record the paths from this class to its base class
1023284555Sarybchik  /// subobjects that match the search criteria.
1024284555Sarybchik  ///
1025284555Sarybchik  /// \returns true if there exists any path from this class to a base class
1026284555Sarybchik  /// subobject that matches the search criteria.
1027284555Sarybchik  bool lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData,
1028284555Sarybchik                     CXXBasePaths &Paths) const;
1029284555Sarybchik
1030284555Sarybchik  /// \brief Base-class lookup callback that determines whether the given
1031284555Sarybchik  /// base class specifier refers to a specific class declaration.
1032284555Sarybchik  ///
1033284555Sarybchik  /// This callback can be used with \c lookupInBases() to determine whether
1034284555Sarybchik  /// a given derived class has is a base class subobject of a particular type.
1035284555Sarybchik  /// The user data pointer should refer to the canonical CXXRecordDecl of the
1036284555Sarybchik  /// base class that we are searching for.
1037284555Sarybchik  static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
1038284555Sarybchik                            CXXBasePath &Path, void *BaseRecord);
1039284555Sarybchik
1040284555Sarybchik  /// \brief Base-class lookup callback that determines whether the
1041284555Sarybchik  /// given base class specifier refers to a specific class
1042284555Sarybchik  /// declaration and describes virtual derivation.
1043227569Sphilip  ///
1044293927Sarybchik  /// This callback can be used with \c lookupInBases() to determine
1045284555Sarybchik  /// whether a given derived class has is a virtual base class
1046284555Sarybchik  /// subobject of a particular type.  The user data pointer should
1047284555Sarybchik  /// refer to the canonical CXXRecordDecl of the base class that we
1048293927Sarybchik  /// are searching for.
1049284555Sarybchik  static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
1050227569Sphilip                                   CXXBasePath &Path, void *BaseRecord);
1051284555Sarybchik
1052227569Sphilip  /// \brief Base-class lookup callback that determines whether there exists
1053293927Sarybchik  /// a tag with the given name.
1054284555Sarybchik  ///
1055227569Sphilip  /// This callback can be used with \c lookupInBases() to find tag members
1056284555Sarybchik  /// of the given name within a C++ class hierarchy. The user data pointer
1057284555Sarybchik  /// is an opaque \c DeclarationName pointer.
1058227569Sphilip  static bool FindTagMember(const CXXBaseSpecifier *Specifier,
1059227569Sphilip                            CXXBasePath &Path, void *Name);
1060227569Sphilip
1061227569Sphilip  /// \brief Base-class lookup callback that determines whether there exists
1062227569Sphilip  /// a member with the given name.
1063284555Sarybchik  ///
1064227569Sphilip  /// This callback can be used with \c lookupInBases() to find members
1065284555Sarybchik  /// of the given name within a C++ class hierarchy. The user data pointer
1066227569Sphilip  /// is an opaque \c DeclarationName pointer.
1067284555Sarybchik  static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
1068227569Sphilip                                 CXXBasePath &Path, void *Name);
1069227569Sphilip
1070227569Sphilip  /// \brief Base-class lookup callback that determines whether there exists
1071227569Sphilip  /// a member with the given name that can be used in a nested-name-specifier.
1072227569Sphilip  ///
1073227569Sphilip  /// This callback can be used with \c lookupInBases() to find membes of
1074227569Sphilip  /// the given name within a C++ class hierarchy that can occur within
1075227569Sphilip  /// nested-name-specifiers.
1076227569Sphilip  static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
1077280550Sarybchik                                            CXXBasePath &Path,
1078284555Sarybchik                                            void *UserData);
1079284555Sarybchik
1080284555Sarybchik  /// \brief Retrieve the final overriders for each virtual member
1081284555Sarybchik  /// function in the class hierarchy where this class is the
1082294381Sarybchik  /// most-derived class in the class hierarchy.
1083227569Sphilip  void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const;
1084227569Sphilip
1085227569Sphilip  /// \brief Get the indirect primary bases for this class.
1086227569Sphilip  void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
1087227569Sphilip
1088227569Sphilip  /// viewInheritance - Renders and displays an inheritance diagram
1089227569Sphilip  /// for this C++ class and all of its base classes (transitively) using
1090227569Sphilip  /// GraphViz.
1091227569Sphilip  void viewInheritance(ASTContext& Context) const;
1092227569Sphilip
1093284555Sarybchik  /// MergeAccess - Calculates the access of a decl that is reached
1094284555Sarybchik  /// along a path.
1095227569Sphilip  static AccessSpecifier MergeAccess(AccessSpecifier PathAccess,
1096227569Sphilip                                     AccessSpecifier DeclAccess) {
1097227569Sphilip    assert(DeclAccess != AS_none);
1098284555Sarybchik    if (DeclAccess == AS_private) return AS_none;
1099284555Sarybchik    return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
1100284555Sarybchik  }
1101284555Sarybchik
1102227569Sphilip  /// \brief Indicates that the definition of this class is now complete.
1103227569Sphilip  virtual void completeDefinition();
1104227569Sphilip
1105227569Sphilip  /// \brief Indicates that the definition of this class is now complete,
1106284555Sarybchik  /// and provides a final overrider map to help determine
1107284555Sarybchik  ///
1108293983Sarybchik  /// \param FinalOverriders The final overrider map for this class, which can
1109280588Sarybchik  /// be provided as an optimization for abstract-class checking. If NULL,
1110280588Sarybchik  /// final overriders will be computed if they are needed to complete the
1111280550Sarybchik  /// definition.
1112284555Sarybchik  void completeDefinition(CXXFinalOverriderMap *FinalOverriders);
1113284555Sarybchik
1114284555Sarybchik  /// \brief Determine whether this class may end up being abstract, even though
1115227569Sphilip  /// it is not yet known to be abstract.
1116284555Sarybchik  ///
1117227569Sphilip  /// \returns true if this class is not known to be abstract but has any
1118227569Sphilip  /// base classes that are abstract. In this case, \c completeDefinition()
1119227569Sphilip  /// will need to compute final overriders to determine whether the class is
1120227569Sphilip  /// actually abstract.
1121227569Sphilip  bool mayBeAbstract() const;
1122227569Sphilip
1123227569Sphilip  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1124227569Sphilip  static bool classofKind(Kind K) {
1125227569Sphilip    return K >= firstCXXRecord && K <= lastCXXRecord;
1126227569Sphilip  }
1127227569Sphilip  static bool classof(const CXXRecordDecl *D) { return true; }
1128227569Sphilip  static bool classof(const ClassTemplateSpecializationDecl *D) {
1129227569Sphilip    return true;
1130227569Sphilip  }
1131284555Sarybchik
1132227569Sphilip  friend class ASTDeclReader;
1133284555Sarybchik  friend class ASTDeclWriter;
1134227569Sphilip  friend class ASTReader;
1135284555Sarybchik  friend class ASTWriter;
1136293978Sarybchik};
1137227569Sphilip
1138284555Sarybchik/// CXXMethodDecl - Represents a static or instance method of a
1139284555Sarybchik/// struct/union/class.
1140227569Sphilipclass CXXMethodDecl : public FunctionDecl {
1141293978Sarybchikprotected:
1142284555Sarybchik  CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
1143227569Sphilip                const DeclarationNameInfo &NameInfo,
1144284555Sarybchik                QualType T, TypeSourceInfo *TInfo,
1145293975Sarybchik                bool isStatic, StorageClass SCAsWritten, bool isInline,
1146284555Sarybchik                SourceLocation EndLocation)
1147284555Sarybchik    : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo,
1148284555Sarybchik                   (isStatic ? SC_Static : SC_None),
1149293975Sarybchik                   SCAsWritten, isInline) {
1150284555Sarybchik      if (EndLocation.isValid())
1151284555Sarybchik        setRangeEnd(EndLocation);
1152284555Sarybchik    }
1153284555Sarybchik
1154284555Sarybchikpublic:
1155284555Sarybchik  static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
1156284555Sarybchik                               SourceLocation StartLoc,
1157284555Sarybchik                               const DeclarationNameInfo &NameInfo,
1158284555Sarybchik                               QualType T, TypeSourceInfo *TInfo,
1159284555Sarybchik                               bool isStatic,
1160284555Sarybchik                               StorageClass SCAsWritten,
1161284555Sarybchik                               bool isInline,
1162284555Sarybchik                               SourceLocation EndLocation);
1163284555Sarybchik
1164294381Sarybchik  bool isStatic() const { return getStorageClass() == SC_Static; }
1165284555Sarybchik  bool isInstance() const { return !isStatic(); }
1166284555Sarybchik
1167284555Sarybchik  bool isVirtual() const {
1168293945Sarybchik    CXXMethodDecl *CD =
1169293953Sarybchik      cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
1170294397Sarybchik
1171284555Sarybchik    if (CD->isVirtualAsWritten())
1172284555Sarybchik      return true;
1173293954Sarybchik
1174294391Sarybchik    return (CD->begin_overridden_methods() != CD->end_overridden_methods());
1175294391Sarybchik  }
1176227569Sphilip
1177227569Sphilip  /// \brief Determine whether this is a usual deallocation function
1178284555Sarybchik  /// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
1179284555Sarybchik  /// delete or delete[] operator with a particular signature.
1180284555Sarybchik  bool isUsualDeallocationFunction() const;
1181284555Sarybchik
1182284555Sarybchik  /// \brief Determine whether this is a copy-assignment operator, regardless
1183284555Sarybchik  /// of whether it was declared implicitly or explicitly.
1184284555Sarybchik  bool isCopyAssignmentOperator() const;
1185284555Sarybchik
1186227569Sphilip  const CXXMethodDecl *getCanonicalDecl() const {
1187227569Sphilip    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
1188227569Sphilip  }
1189227569Sphilip  CXXMethodDecl *getCanonicalDecl() {
1190284555Sarybchik    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
1191284555Sarybchik  }
1192284555Sarybchik
1193284555Sarybchik  ///
1194284555Sarybchik  void addOverriddenMethod(const CXXMethodDecl *MD);
1195284555Sarybchik
1196284555Sarybchik  typedef const CXXMethodDecl ** method_iterator;
1197284555Sarybchik
1198284555Sarybchik  method_iterator begin_overridden_methods() const;
1199284555Sarybchik  method_iterator end_overridden_methods() const;
1200284555Sarybchik  unsigned size_overridden_methods() const;
1201284555Sarybchik
1202284555Sarybchik  /// getParent - Returns the parent of this method declaration, which
1203284555Sarybchik  /// is the class in which this method is defined.
1204284555Sarybchik  const CXXRecordDecl *getParent() const {
1205284555Sarybchik    return cast<CXXRecordDecl>(FunctionDecl::getParent());
1206284555Sarybchik  }
1207293927Sarybchik
1208284555Sarybchik  /// getParent - Returns the parent of this method declaration, which
1209284555Sarybchik  /// is the class in which this method is defined.
1210284555Sarybchik  CXXRecordDecl *getParent() {
1211284555Sarybchik    return const_cast<CXXRecordDecl *>(
1212284555Sarybchik             cast<CXXRecordDecl>(FunctionDecl::getParent()));
1213284555Sarybchik  }
1214284555Sarybchik
1215284555Sarybchik  /// getThisType - Returns the type of 'this' pointer.
1216284555Sarybchik  /// Should only be called for instance methods.
1217293927Sarybchik  QualType getThisType(ASTContext &C) const;
1218284555Sarybchik
1219284555Sarybchik  unsigned getTypeQualifiers() const {
1220284555Sarybchik    return getType()->getAs<FunctionProtoType>()->getTypeQuals();
1221284555Sarybchik  }
1222284555Sarybchik
1223284555Sarybchik  /// \brief Retrieve the ref-qualifier associated with this method.
1224293927Sarybchik  ///
1225284555Sarybchik  /// In the following example, \c f() has an lvalue ref-qualifier, \c g()
1226284555Sarybchik  /// has an rvalue ref-qualifier, and \c h() has no ref-qualifier.
1227284555Sarybchik  /// \code
1228284555Sarybchik  /// struct X {
1229284555Sarybchik  ///   void f() &;
1230284555Sarybchik  ///   void g() &&;
1231284555Sarybchik  ///   void h();
1232227569Sphilip  /// };
1233227569Sphilip  RefQualifierKind getRefQualifier() const {
1234227569Sphilip    return getType()->getAs<FunctionProtoType>()->getRefQualifier();
1235227569Sphilip  }
1236227569Sphilip
1237227569Sphilip  bool hasInlineBody() const;
1238227569Sphilip
1239227569Sphilip  // Implement isa/cast/dyncast/etc.
1240227569Sphilip  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1241227569Sphilip  static bool classof(const CXXMethodDecl *D) { return true; }
1242227569Sphilip  static bool classofKind(Kind K) {
1243227569Sphilip    return K >= firstCXXMethod && K <= lastCXXMethod;
1244227569Sphilip  }
1245227569Sphilip};
1246227569Sphilip
1247227569Sphilip/// CXXCtorInitializer - Represents a C++ base or member
1248227569Sphilip/// initializer, which is part of a constructor initializer that
1249227569Sphilip/// initializes one non-static member variable or one base class. For
1250227569Sphilip/// example, in the following, both 'A(a)' and 'f(3.14159)' are member
1251227569Sphilip/// initializers:
1252227569Sphilip///
1253293927Sarybchik/// @code
1254227569Sphilip/// class A { };
1255227569Sphilip/// class B : public A {
1256227569Sphilip///   float f;
1257293927Sarybchik/// public:
1258227569Sphilip///   B(A& a) : A(a), f(3.14159) { }
1259227569Sphilip/// };
1260227569Sphilip/// @endcode
1261227569Sphilipclass CXXCtorInitializer {
1262293927Sarybchik  /// \brief Either the base class name (stored as a TypeSourceInfo*), an normal
1263227569Sphilip  /// field (FieldDecl), anonymous field (IndirectFieldDecl*), or target
1264227569Sphilip  /// constructor (CXXConstructorDecl*) being initialized.
1265227569Sphilip  llvm::PointerUnion4<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *,
1266227569Sphilip                      CXXConstructorDecl *>
1267227569Sphilip    Initializee;
1268293927Sarybchik
1269227569Sphilip  /// \brief The source location for the field name or, for a base initializer
1270227569Sphilip  /// pack expansion, the location of the ellipsis. In the case of a delegating
1271227569Sphilip  /// constructor, it will still include the type's source location as the
1272227569Sphilip  /// Initializee points to the CXXConstructorDecl (to allow loop detection).
1273227569Sphilip  SourceLocation MemberOrEllipsisLocation;
1274293927Sarybchik
1275227569Sphilip  /// \brief The argument used to initialize the base or member, which may
1276227569Sphilip  /// end up constructing an object (when multiple arguments are involved).
1277227569Sphilip  Stmt *Init;
1278227569Sphilip
1279227569Sphilip  /// LParenLoc - Location of the left paren of the ctor-initializer.
1280293927Sarybchik  SourceLocation LParenLoc;
1281227569Sphilip
1282227569Sphilip  /// RParenLoc - Location of the right paren of the ctor-initializer.
1283227569Sphilip  SourceLocation RParenLoc;
1284227569Sphilip
1285227569Sphilip  /// IsVirtual - If the initializer is a base initializer, this keeps track
1286227569Sphilip  /// of whether the base is virtual or not.
1287293927Sarybchik  bool IsVirtual : 1;
1288227569Sphilip
1289227569Sphilip  /// IsWritten - Whether or not the initializer is explicitly written
1290227569Sphilip  /// in the sources.
1291227569Sphilip  bool IsWritten : 1;
1292227569Sphilip
1293227569Sphilip  /// SourceOrderOrNumArrayIndices - If IsWritten is true, then this
1294293927Sarybchik  /// number keeps track of the textual order of this initializer in the
1295227569Sphilip  /// original sources, counting from 0; otherwise, if IsWritten is false,
1296227569Sphilip  /// it stores the number of array index variables stored after this
1297227569Sphilip  /// object in memory.
1298227569Sphilip  unsigned SourceOrderOrNumArrayIndices : 14;
1299227569Sphilip
1300227569Sphilip  CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
1301227569Sphilip                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
1302293927Sarybchik                     SourceLocation R, VarDecl **Indices, unsigned NumIndices);
1303227569Sphilip
1304227569Sphilippublic:
1305227569Sphilip  /// CXXCtorInitializer - Creates a new base-class initializer.
1306227569Sphilip  explicit
1307227569Sphilip  CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual,
1308227569Sphilip                     SourceLocation L, Expr *Init, SourceLocation R,
1309227569Sphilip                     SourceLocation EllipsisLoc);
1310227569Sphilip
1311227569Sphilip  /// CXXCtorInitializer - Creates a new member initializer.
1312227569Sphilip  explicit
1313227569Sphilip  CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
1314227569Sphilip                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
1315227569Sphilip                     SourceLocation R);
1316227569Sphilip
1317227569Sphilip  /// CXXCtorInitializer - Creates a new anonymous field initializer.
1318227569Sphilip  explicit
1319227569Sphilip  CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,
1320227569Sphilip                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
1321227569Sphilip                     SourceLocation R);
1322227569Sphilip
1323227569Sphilip  /// CXXCtorInitializer - Creates a new delegating Initializer.
1324227569Sphilip  explicit
1325227569Sphilip  CXXCtorInitializer(ASTContext &Context, SourceLocation D, SourceLocation L,
1326280577Sarybchik                     CXXConstructorDecl *Target, Expr *Init, SourceLocation R);
1327280577Sarybchik
1328280577Sarybchik  /// \brief Creates a new member initializer that optionally contains
1329280577Sarybchik  /// array indices used to describe an elementwise initialization.
1330284555Sarybchik  static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
1331294385Sarybchik                                    SourceLocation MemberLoc, SourceLocation L,
1332227569Sphilip                                    Expr *Init, SourceLocation R,
1333227569Sphilip                                    VarDecl **Indices, unsigned NumIndices);
1334227569Sphilip
1335293927Sarybchik  /// isBaseInitializer - Returns true when this initializer is
1336227569Sphilip  /// initializing a base class.
1337227569Sphilip  bool isBaseInitializer() const { return Initializee.is<TypeSourceInfo*>(); }
1338227569Sphilip
1339227569Sphilip  /// isMemberInitializer - Returns true when this initializer is
1340227569Sphilip  /// initializing a non-static data member.
1341293927Sarybchik  bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); }
1342227569Sphilip
1343227569Sphilip  bool isAnyMemberInitializer() const {
1344227569Sphilip    return isMemberInitializer() || isIndirectMemberInitializer();
1345227569Sphilip  }
1346227569Sphilip
1347293927Sarybchik  bool isIndirectMemberInitializer() const {
1348227569Sphilip    return Initializee.is<IndirectFieldDecl*>();
1349227569Sphilip  }
1350227569Sphilip
1351227569Sphilip  /// isDelegatingInitializer - Returns true when this initializer is creating
1352227569Sphilip  /// a delegating constructor.
1353293927Sarybchik  bool isDelegatingInitializer() const {
1354227569Sphilip    return Initializee.is<CXXConstructorDecl *>();
1355227569Sphilip  }
1356227569Sphilip
1357227569Sphilip  /// \brief Determine whether this initializer is a pack expansion.
1358227569Sphilip  bool isPackExpansion() const {
1359227569Sphilip    return isBaseInitializer() && MemberOrEllipsisLocation.isValid();
1360227569Sphilip  }
1361227569Sphilip
1362227569Sphilip  // \brief For a pack expansion, returns the location of the ellipsis.
1363227569Sphilip  SourceLocation getEllipsisLoc() const {
1364293927Sarybchik    assert(isPackExpansion() && "Initializer is not a pack expansion");
1365227569Sphilip    return MemberOrEllipsisLocation;
1366227569Sphilip  }
1367227569Sphilip
1368227569Sphilip  /// If this is a base class initializer, returns the type of the
1369227569Sphilip  /// base class with location information. Otherwise, returns an NULL
1370227569Sphilip  /// type location.
1371293927Sarybchik  TypeLoc getBaseClassLoc() const;
1372227569Sphilip
1373227569Sphilip  /// If this is a base class initializer, returns the type of the base class.
1374227569Sphilip  /// Otherwise, returns NULL.
1375227569Sphilip  const Type *getBaseClass() const;
1376227569Sphilip
1377227569Sphilip  /// Returns whether the base is virtual or not.
1378227569Sphilip  bool isBaseVirtual() const {
1379293927Sarybchik    assert(isBaseInitializer() && "Must call this on base initializer!");
1380227569Sphilip
1381227569Sphilip    return IsVirtual;
1382227569Sphilip  }
1383284555Sarybchik
1384227569Sphilip  /// \brief Returns the declarator information for a base class initializer.
1385284555Sarybchik  TypeSourceInfo *getBaseClassInfo() const {
1386293927Sarybchik    return Initializee.dyn_cast<TypeSourceInfo *>();
1387284555Sarybchik  }
1388284555Sarybchik
1389284555Sarybchik  /// getMember - If this is a member initializer, returns the
1390284555Sarybchik  /// declaration of the non-static data member being
1391284555Sarybchik  /// initialized. Otherwise, returns NULL.
1392284555Sarybchik  FieldDecl *getMember() const {
1393293927Sarybchik    if (isMemberInitializer())
1394227569Sphilip      return Initializee.get<FieldDecl*>();
1395227569Sphilip    else
1396227569Sphilip      return 0;
1397227569Sphilip  }
1398293927Sarybchik  FieldDecl *getAnyMember() const {
1399227569Sphilip    if (isMemberInitializer())
1400227569Sphilip      return Initializee.get<FieldDecl*>();
1401227569Sphilip    else if (isIndirectMemberInitializer())
1402227569Sphilip      return Initializee.get<IndirectFieldDecl*>()->getAnonField();
1403227569Sphilip    else
1404227569Sphilip      return 0;
1405227569Sphilip  }
1406227569Sphilip
1407227569Sphilip  IndirectFieldDecl *getIndirectMember() const {
1408227569Sphilip    if (isIndirectMemberInitializer())
1409227569Sphilip      return Initializee.get<IndirectFieldDecl*>();
1410227569Sphilip    else
1411227569Sphilip      return 0;
1412227569Sphilip  }
1413227569Sphilip
1414293927Sarybchik  CXXConstructorDecl *getTargetConstructor() const {
1415227569Sphilip    if (isDelegatingInitializer())
1416227569Sphilip      return Initializee.get<CXXConstructorDecl*>();
1417227569Sphilip    else
1418227569Sphilip      return 0;
1419227569Sphilip  }
1420293927Sarybchik
1421227569Sphilip  SourceLocation getMemberLocation() const {
1422227569Sphilip    return MemberOrEllipsisLocation;
1423227569Sphilip  }
1424227569Sphilip
1425227569Sphilip  /// \brief Determine the source location of the initializer.
1426227569Sphilip  SourceLocation getSourceLocation() const;
1427227569Sphilip
1428227569Sphilip  /// \brief Determine the source range covering the entire initializer.
1429227569Sphilip  SourceRange getSourceRange() const;
1430227569Sphilip
1431227569Sphilip  /// isWritten - Returns true if this initializer is explicitly written
1432227569Sphilip  /// in the source code.
1433227569Sphilip  bool isWritten() const { return IsWritten; }
1434227569Sphilip
1435227569Sphilip  /// \brief Return the source position of the initializer, counting from 0.
1436227569Sphilip  /// If the initializer was implicit, -1 is returned.
1437227569Sphilip  int getSourceOrder() const {
1438227569Sphilip    return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
1439227569Sphilip  }
1440227569Sphilip
1441227569Sphilip  /// \brief Set the source order of this initializer. This method can only
1442227569Sphilip  /// be called once for each initializer; it cannot be called on an
1443227569Sphilip  /// initializer having a positive number of (implicit) array indices.
1444227569Sphilip  void setSourceOrder(int pos) {
1445227569Sphilip    assert(!IsWritten &&
1446227569Sphilip           "calling twice setSourceOrder() on the same initializer");
1447227569Sphilip    assert(SourceOrderOrNumArrayIndices == 0 &&
1448227569Sphilip           "setSourceOrder() used when there are implicit array indices");
1449227569Sphilip    assert(pos >= 0 &&
1450227569Sphilip           "setSourceOrder() used to make an initializer implicit");
1451227569Sphilip    IsWritten = true;
1452227569Sphilip    SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
1453227569Sphilip  }
1454227569Sphilip
1455227569Sphilip  SourceLocation getLParenLoc() const { return LParenLoc; }
1456227569Sphilip  SourceLocation getRParenLoc() const { return RParenLoc; }
1457227569Sphilip
1458227569Sphilip  /// \brief Determine the number of implicit array indices used while
1459227569Sphilip  /// described an array member initialization.
1460227569Sphilip  unsigned getNumArrayIndices() const {
1461227569Sphilip    return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
1462227569Sphilip  }
1463227569Sphilip
1464227569Sphilip  /// \brief Retrieve a particular array index variable used to
1465227569Sphilip  /// describe an array member initialization.
1466227569Sphilip  VarDecl *getArrayIndex(unsigned I) {
1467227569Sphilip    assert(I < getNumArrayIndices() && "Out of bounds member array index");
1468227569Sphilip    return reinterpret_cast<VarDecl **>(this + 1)[I];
1469227569Sphilip  }
1470293927Sarybchik  const VarDecl *getArrayIndex(unsigned I) const {
1471227569Sphilip    assert(I < getNumArrayIndices() && "Out of bounds member array index");
1472227569Sphilip    return reinterpret_cast<const VarDecl * const *>(this + 1)[I];
1473227569Sphilip  }
1474293927Sarybchik  void setArrayIndex(unsigned I, VarDecl *Index) {
1475227569Sphilip    assert(I < getNumArrayIndices() && "Out of bounds member array index");
1476227569Sphilip    reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
1477227569Sphilip  }
1478293927Sarybchik
1479227569Sphilip  Expr *getInit() const { return static_cast<Expr *>(Init); }
1480227569Sphilip};
1481227569Sphilip
1482227569Sphilip/// CXXConstructorDecl - Represents a C++ constructor within a
1483227569Sphilip/// class. For example:
1484227569Sphilip///
1485293927Sarybchik/// @code
1486227569Sphilip/// class X {
1487227569Sphilip/// public:
1488227569Sphilip///   explicit X(int); // represented by a CXXConstructorDecl.
1489227569Sphilip/// };
1490293927Sarybchik/// @endcode
1491227569Sphilipclass CXXConstructorDecl : public CXXMethodDecl {
1492227569Sphilip  /// IsExplicitSpecified - Whether this constructor declaration has the
1493227569Sphilip  /// 'explicit' keyword specified.
1494227569Sphilip  bool IsExplicitSpecified : 1;
1495227569Sphilip
1496227569Sphilip  /// ImplicitlyDefined - Whether this constructor was implicitly
1497293927Sarybchik  /// defined by the compiler. When false, the constructor was defined
1498227569Sphilip  /// by the user. In C++03, this flag will have the same value as
1499227569Sphilip  /// Implicit. In C++0x, however, a constructor that is
1500227569Sphilip  /// explicitly defaulted (i.e., defined with " = default") will have
1501227569Sphilip  /// @c !Implicit && ImplicitlyDefined.
1502227569Sphilip  bool ImplicitlyDefined : 1;
1503227569Sphilip
1504227569Sphilip  /// Support for base and member initializers.
1505227569Sphilip  /// CtorInitializers - The arguments used to initialize the base
1506227569Sphilip  /// or member.
1507227569Sphilip  CXXCtorInitializer **CtorInitializers;
1508227569Sphilip  unsigned NumCtorInitializers;
1509227569Sphilip
1510227569Sphilip  CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
1511227569Sphilip                     const DeclarationNameInfo &NameInfo,
1512227569Sphilip                     QualType T, TypeSourceInfo *TInfo,
1513227569Sphilip                     bool isExplicitSpecified, bool isInline,
1514227569Sphilip                     bool isImplicitlyDeclared)
1515227569Sphilip    : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, false,
1516227569Sphilip                    SC_None, isInline, SourceLocation()),
1517227569Sphilip      IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
1518227569Sphilip      CtorInitializers(0), NumCtorInitializers(0) {
1519227569Sphilip    setImplicit(isImplicitlyDeclared);
1520227569Sphilip  }
1521227569Sphilip
1522227569Sphilippublic:
1523227569Sphilip  static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty);
1524227569Sphilip  static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
1525227569Sphilip                                    SourceLocation StartLoc,
1526227569Sphilip                                    const DeclarationNameInfo &NameInfo,
1527293927Sarybchik                                    QualType T, TypeSourceInfo *TInfo,
1528227569Sphilip                                    bool isExplicit,
1529227569Sphilip                                    bool isInline, bool isImplicitlyDeclared);
1530227569Sphilip
1531227569Sphilip  /// isExplicitSpecified - Whether this constructor declaration has the
1532227569Sphilip  /// 'explicit' keyword specified.
1533227569Sphilip  bool isExplicitSpecified() const { return IsExplicitSpecified; }
1534293927Sarybchik
1535227569Sphilip  /// isExplicit - Whether this constructor was marked "explicit" or not.
1536227569Sphilip  bool isExplicit() const {
1537227569Sphilip    return cast<CXXConstructorDecl>(getFirstDeclaration())
1538227569Sphilip      ->isExplicitSpecified();
1539227569Sphilip  }
1540227569Sphilip
1541227569Sphilip  /// isImplicitlyDefined - Whether this constructor was implicitly
1542227569Sphilip  /// defined. If false, then this constructor was defined by the
1543227569Sphilip  /// user. This operation can only be invoked if the constructor has
1544227569Sphilip  /// already been defined.
1545227569Sphilip  bool isImplicitlyDefined() const {
1546227569Sphilip    assert(isThisDeclarationADefinition() &&
1547227569Sphilip           "Can only get the implicit-definition flag once the "
1548227569Sphilip           "constructor has been defined");
1549227569Sphilip    return ImplicitlyDefined;
1550227569Sphilip  }
1551227569Sphilip
1552227569Sphilip  /// setImplicitlyDefined - Set whether this constructor was
1553227569Sphilip  /// implicitly defined or not.
1554227569Sphilip  void setImplicitlyDefined(bool ID) {
1555227569Sphilip    assert(isThisDeclarationADefinition() &&
1556227569Sphilip           "Can only set the implicit-definition flag once the constructor "
1557284555Sarybchik           "has been defined");
1558227569Sphilip    ImplicitlyDefined = ID;
1559227569Sphilip  }
1560227569Sphilip
1561227569Sphilip  /// init_iterator - Iterates through the member/base initializer list.
1562227569Sphilip  typedef CXXCtorInitializer **init_iterator;
1563227569Sphilip
1564227569Sphilip  /// init_const_iterator - Iterates through the memberbase initializer list.
1565227569Sphilip  typedef CXXCtorInitializer * const * init_const_iterator;
1566227569Sphilip
1567227569Sphilip  /// init_begin() - Retrieve an iterator to the first initializer.
1568227569Sphilip  init_iterator       init_begin()       { return CtorInitializers; }
1569227569Sphilip  /// begin() - Retrieve an iterator to the first initializer.
1570227569Sphilip  init_const_iterator init_begin() const { return CtorInitializers; }
1571227569Sphilip
1572227569Sphilip  /// init_end() - Retrieve an iterator past the last initializer.
1573227569Sphilip  init_iterator       init_end()       {
1574227569Sphilip    return CtorInitializers + NumCtorInitializers;
1575227569Sphilip  }
1576227569Sphilip  /// end() - Retrieve an iterator past the last initializer.
1577227569Sphilip  init_const_iterator init_end() const {
1578227569Sphilip    return CtorInitializers + NumCtorInitializers;
1579284555Sarybchik  }
1580227569Sphilip
1581227569Sphilip  typedef std::reverse_iterator<init_iterator> init_reverse_iterator;
1582227569Sphilip  typedef std::reverse_iterator<init_const_iterator> init_const_reverse_iterator;
1583227569Sphilip
1584227569Sphilip  init_reverse_iterator init_rbegin() {
1585227569Sphilip    return init_reverse_iterator(init_end());
1586227569Sphilip  }
1587227569Sphilip  init_const_reverse_iterator init_rbegin() const {
1588227569Sphilip    return init_const_reverse_iterator(init_end());
1589227569Sphilip  }
1590227569Sphilip
1591227569Sphilip  init_reverse_iterator init_rend() {
1592227569Sphilip    return init_reverse_iterator(init_begin());
1593227569Sphilip  }
1594227569Sphilip  init_const_reverse_iterator init_rend() const {
1595227569Sphilip    return init_const_reverse_iterator(init_begin());
1596227569Sphilip  }
1597227569Sphilip
1598227569Sphilip  /// getNumArgs - Determine the number of arguments used to
1599227569Sphilip  /// initialize the member or base.
1600227569Sphilip  unsigned getNumCtorInitializers() const {
1601227569Sphilip      return NumCtorInitializers;
1602227569Sphilip  }
1603293927Sarybchik
1604227569Sphilip  void setNumCtorInitializers(unsigned numCtorInitializers) {
1605227569Sphilip    NumCtorInitializers = numCtorInitializers;
1606227569Sphilip  }
1607227569Sphilip
1608227569Sphilip  void setCtorInitializers(CXXCtorInitializer ** initializers) {
1609227569Sphilip    CtorInitializers = initializers;
1610227569Sphilip  }
1611227569Sphilip
1612227569Sphilip  /// isDelegatingConstructor - Whether this constructor is a
1613227569Sphilip  /// delegating constructor
1614227569Sphilip  bool isDelegatingConstructor() const {
1615227569Sphilip    return (getNumCtorInitializers() == 1) &&
1616227569Sphilip      CtorInitializers[0]->isDelegatingInitializer();
1617293927Sarybchik  }
1618227569Sphilip
1619227569Sphilip  /// getTargetConstructor - When this constructor delegates to
1620227569Sphilip  /// another, retrieve the target
1621227569Sphilip  CXXConstructorDecl *getTargetConstructor() const {
1622227569Sphilip    if (isDelegatingConstructor())
1623227569Sphilip      return CtorInitializers[0]->getTargetConstructor();
1624227569Sphilip    else
1625227569Sphilip      return 0;
1626227569Sphilip  }
1627227569Sphilip
1628227569Sphilip  /// isDefaultConstructor - Whether this constructor is a default
1629227569Sphilip  /// constructor (C++ [class.ctor]p5), which can be used to
1630227569Sphilip  /// default-initialize a class of this type.
1631227569Sphilip  bool isDefaultConstructor() const;
1632227569Sphilip
1633227569Sphilip  /// isCopyConstructor - Whether this constructor is a copy
1634227569Sphilip  /// constructor (C++ [class.copy]p2, which can be used to copy the
1635227569Sphilip  /// class. @p TypeQuals will be set to the qualifiers on the
1636227569Sphilip  /// argument type. For example, @p TypeQuals would be set to @c
1637227569Sphilip  /// QualType::Const for the following copy constructor:
1638227569Sphilip  ///
1639227569Sphilip  /// @code
1640227569Sphilip  /// class X {
1641227569Sphilip  /// public:
1642227569Sphilip  ///   X(const X&);
1643227569Sphilip  /// };
1644227569Sphilip  /// @endcode
1645227569Sphilip  bool isCopyConstructor(unsigned &TypeQuals) const;
1646227569Sphilip
1647227569Sphilip  /// isCopyConstructor - Whether this constructor is a copy
1648227569Sphilip  /// constructor (C++ [class.copy]p2, which can be used to copy the
1649284555Sarybchik  /// class.
1650227569Sphilip  bool isCopyConstructor() const {
1651227569Sphilip    unsigned TypeQuals = 0;
1652227569Sphilip    return isCopyConstructor(TypeQuals);
1653227569Sphilip  }
1654227569Sphilip
1655227569Sphilip  /// \brief Determine whether this constructor is a move constructor
1656227569Sphilip  /// (C++0x [class.copy]p3), which can be used to move values of the class.
1657227569Sphilip  ///
1658227569Sphilip  /// \param TypeQuals If this constructor is a move constructor, will be set
1659227569Sphilip  /// to the type qualifiers on the referent of the first parameter's type.
1660227569Sphilip  bool isMoveConstructor(unsigned &TypeQuals) const;
1661227569Sphilip
1662227569Sphilip  /// \brief Determine whether this constructor is a move constructor
1663227569Sphilip  /// (C++0x [class.copy]p3), which can be used to move values of the class.
1664227569Sphilip  bool isMoveConstructor() const {
1665227569Sphilip    unsigned TypeQuals = 0;
1666227569Sphilip    return isMoveConstructor(TypeQuals);
1667227569Sphilip  }
1668227569Sphilip
1669227569Sphilip  /// \brief Determine whether this is a copy or move constructor.
1670227569Sphilip  ///
1671227569Sphilip  /// \param TypeQuals Will be set to the type qualifiers on the reference
1672227569Sphilip  /// parameter, if in fact this is a copy or move constructor.
1673227569Sphilip  bool isCopyOrMoveConstructor(unsigned &TypeQuals) const;
1674227569Sphilip
1675227569Sphilip  /// \brief Determine whether this a copy or move constructor.
1676284555Sarybchik  bool isCopyOrMoveConstructor() const {
1677284555Sarybchik    unsigned Quals;
1678284555Sarybchik    return isCopyOrMoveConstructor(Quals);
1679227569Sphilip  }
1680227569Sphilip
1681227569Sphilip  /// isConvertingConstructor - Whether this constructor is a
1682227569Sphilip  /// converting constructor (C++ [class.conv.ctor]), which can be
1683227569Sphilip  /// used for user-defined conversions.
1684227569Sphilip  bool isConvertingConstructor(bool AllowExplicit) const;
1685227569Sphilip
1686227569Sphilip  /// \brief Determine whether this is a member template specialization that
1687227569Sphilip  /// would copy the object to itself. Such constructors are never used to copy
1688227569Sphilip  /// an object.
1689265884Sgnn  bool isSpecializationCopyingObject() const;
1690227569Sphilip
1691227569Sphilip  /// \brief Get the constructor that this inheriting constructor is based on.
1692227569Sphilip  const CXXConstructorDecl *getInheritedConstructor() const;
1693227569Sphilip
1694265884Sgnn  /// \brief Set the constructor that this inheriting constructor is based on.
1695227569Sphilip  void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
1696227569Sphilip
1697227569Sphilip  // Implement isa/cast/dyncast/etc.
1698227569Sphilip  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1699265884Sgnn  static bool classof(const CXXConstructorDecl *D) { return true; }
1700227569Sphilip  static bool classofKind(Kind K) { return K == CXXConstructor; }
1701227569Sphilip
1702227569Sphilip  friend class ASTDeclReader;
1703227569Sphilip  friend class ASTDeclWriter;
1704227569Sphilip};
1705227569Sphilip
1706227569Sphilip/// CXXDestructorDecl - Represents a C++ destructor within a
1707227569Sphilip/// class. For example:
1708227569Sphilip///
1709227569Sphilip/// @code
1710227569Sphilip/// class X {
1711227569Sphilip/// public:
1712227569Sphilip///   ~X(); // represented by a CXXDestructorDecl.
1713227569Sphilip/// };
1714227569Sphilip/// @endcode
1715227569Sphilipclass CXXDestructorDecl : public CXXMethodDecl {
1716227569Sphilip  /// ImplicitlyDefined - Whether this destructor was implicitly
1717227569Sphilip  /// defined by the compiler. When false, the destructor was defined
1718227569Sphilip  /// by the user. In C++03, this flag will have the same value as
1719227569Sphilip  /// Implicit. In C++0x, however, a destructor that is
1720227569Sphilip  /// explicitly defaulted (i.e., defined with " = default") will have
1721227569Sphilip  /// @c !Implicit && ImplicitlyDefined.
1722227569Sphilip  bool ImplicitlyDefined : 1;
1723227569Sphilip
1724227569Sphilip  FunctionDecl *OperatorDelete;
1725227569Sphilip
1726227569Sphilip  CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
1727227569Sphilip                    const DeclarationNameInfo &NameInfo,
1728227569Sphilip                    QualType T, TypeSourceInfo *TInfo,
1729227569Sphilip                    bool isInline, bool isImplicitlyDeclared)
1730227569Sphilip    : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, false,
1731227569Sphilip                    SC_None, isInline, SourceLocation()),
1732227569Sphilip      ImplicitlyDefined(false), OperatorDelete(0) {
1733227569Sphilip    setImplicit(isImplicitlyDeclared);
1734227569Sphilip  }
1735227569Sphilip
1736227569Sphilippublic:
1737227569Sphilip  static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
1738227569Sphilip  static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
1739227569Sphilip                                   SourceLocation StartLoc,
1740227569Sphilip                                   const DeclarationNameInfo &NameInfo,
1741227569Sphilip                                   QualType T, TypeSourceInfo* TInfo,
1742227569Sphilip                                   bool isInline,
1743227569Sphilip                                   bool isImplicitlyDeclared);
1744227569Sphilip
1745227569Sphilip  /// isImplicitlyDefined - Whether this destructor was implicitly
1746227569Sphilip  /// defined. If false, then this destructor was defined by the
1747227569Sphilip  /// user. This operation can only be invoked if the destructor has
1748227569Sphilip  /// already been defined.
1749227569Sphilip  bool isImplicitlyDefined() const {
1750227569Sphilip    assert(isThisDeclarationADefinition() &&
1751227569Sphilip           "Can only get the implicit-definition flag once the destructor has been defined");
1752227569Sphilip    return ImplicitlyDefined;
1753227569Sphilip  }
1754227569Sphilip
1755227569Sphilip  /// setImplicitlyDefined - Set whether this destructor was
1756227569Sphilip  /// implicitly defined or not.
1757227569Sphilip  void setImplicitlyDefined(bool ID) {
1758227569Sphilip    assert(isThisDeclarationADefinition() &&
1759227569Sphilip           "Can only set the implicit-definition flag once the destructor has been defined");
1760227569Sphilip    ImplicitlyDefined = ID;
1761227569Sphilip  }
1762227569Sphilip
1763227569Sphilip  void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
1764227569Sphilip  const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
1765227569Sphilip
1766227569Sphilip  // Implement isa/cast/dyncast/etc.
1767227569Sphilip  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1768284555Sarybchik  static bool classof(const CXXDestructorDecl *D) { return true; }
1769227569Sphilip  static bool classofKind(Kind K) { return K == CXXDestructor; }
1770227569Sphilip
1771227569Sphilip  friend class ASTDeclReader;
1772227569Sphilip  friend class ASTDeclWriter;
1773227569Sphilip};
1774227569Sphilip
1775227569Sphilip/// CXXConversionDecl - Represents a C++ conversion function within a
1776227569Sphilip/// class. For example:
1777227569Sphilip///
1778227569Sphilip/// @code
1779227569Sphilip/// class X {
1780227569Sphilip/// public:
1781227569Sphilip///   operator bool();
1782227569Sphilip/// };
1783227569Sphilip/// @endcode
1784227569Sphilipclass CXXConversionDecl : public CXXMethodDecl {
1785227569Sphilip  /// IsExplicitSpecified - Whether this conversion function declaration is
1786227569Sphilip  /// marked "explicit", meaning that it can only be applied when the user
1787227569Sphilip  /// explicitly wrote a cast. This is a C++0x feature.
1788227569Sphilip  bool IsExplicitSpecified : 1;
1789227569Sphilip
1790227569Sphilip  CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
1791227569Sphilip                    const DeclarationNameInfo &NameInfo,
1792293927Sarybchik                    QualType T, TypeSourceInfo *TInfo,
1793227569Sphilip                    bool isInline, bool isExplicitSpecified,
1794227569Sphilip                    SourceLocation EndLocation)
1795227569Sphilip    : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, false,
1796227569Sphilip                    SC_None, isInline, EndLocation),
1797293927Sarybchik      IsExplicitSpecified(isExplicitSpecified) { }
1798227569Sphilip
1799227569Sphilippublic:
1800227569Sphilip  static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty);
1801227569Sphilip  static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
1802227569Sphilip                                   SourceLocation StartLoc,
1803227569Sphilip                                   const DeclarationNameInfo &NameInfo,
1804227569Sphilip                                   QualType T, TypeSourceInfo *TInfo,
1805227569Sphilip                                   bool isInline, bool isExplicit,
1806284555Sarybchik                                   SourceLocation EndLocation);
1807227569Sphilip
1808227569Sphilip  /// IsExplicitSpecified - Whether this conversion function declaration is
1809227569Sphilip  /// marked "explicit", meaning that it can only be applied when the user
1810227569Sphilip  /// explicitly wrote a cast. This is a C++0x feature.
1811227569Sphilip  bool isExplicitSpecified() const { return IsExplicitSpecified; }
1812227569Sphilip
1813227569Sphilip  /// isExplicit - Whether this is an explicit conversion operator
1814227569Sphilip  /// (C++0x only). Explicit conversion operators are only considered
1815227569Sphilip  /// when the user has explicitly written a cast.
1816227569Sphilip  bool isExplicit() const {
1817227569Sphilip    return cast<CXXConversionDecl>(getFirstDeclaration())
1818227569Sphilip      ->isExplicitSpecified();
1819227569Sphilip  }
1820227569Sphilip
1821227569Sphilip  /// getConversionType - Returns the type that this conversion
1822227569Sphilip  /// function is converting to.
1823227569Sphilip  QualType getConversionType() const {
1824227569Sphilip    return getType()->getAs<FunctionType>()->getResultType();
1825227569Sphilip  }
1826293927Sarybchik
1827227569Sphilip  // Implement isa/cast/dyncast/etc.
1828284555Sarybchik  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1829227569Sphilip  static bool classof(const CXXConversionDecl *D) { return true; }
1830227569Sphilip  static bool classofKind(Kind K) { return K == CXXConversion; }
1831227569Sphilip
1832227569Sphilip  friend class ASTDeclReader;
1833227569Sphilip  friend class ASTDeclWriter;
1834227569Sphilip};
1835293927Sarybchik
1836227569Sphilip/// LinkageSpecDecl - This represents a linkage specification.  For example:
1837227569Sphilip///   extern "C" void foo();
1838227569Sphilip///
1839227569Sphilipclass LinkageSpecDecl : public Decl, public DeclContext {
1840227569Sphilippublic:
1841227569Sphilip  /// LanguageIDs - Used to represent the language in a linkage
1842227569Sphilip  /// specification.  The values are part of the serialization abi for
1843227569Sphilip  /// ASTs and cannot be changed without altering that abi.  To help
1844227569Sphilip  /// ensure a stable abi for this, we choose the DW_LANG_ encodings
1845227569Sphilip  /// from the dwarf standard.
1846227569Sphilip  enum LanguageIDs {
1847227569Sphilip    lang_c = /* DW_LANG_C */ 0x0002,
1848227569Sphilip    lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
1849227569Sphilip  };
1850227569Sphilipprivate:
1851227569Sphilip  /// Language - The language for this linkage specification.
1852227569Sphilip  LanguageIDs Language;
1853227569Sphilip  /// ExternLoc - The source location for the extern keyword.
1854227569Sphilip  SourceLocation ExternLoc;
1855284555Sarybchik  /// RBraceLoc - The source location for the right brace (if valid).
1856284555Sarybchik  SourceLocation RBraceLoc;
1857284555Sarybchik
1858284555Sarybchik  LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
1859284555Sarybchik                  SourceLocation LangLoc, LanguageIDs lang,
1860227569Sphilip                  SourceLocation RBLoc)
1861227569Sphilip    : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
1862227569Sphilip      Language(lang), ExternLoc(ExternLoc), RBraceLoc(RBLoc) { }
1863227569Sphilip
1864284555Sarybchikpublic:
1865284555Sarybchik  static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
1866284555Sarybchik                                 SourceLocation ExternLoc,
1867284555Sarybchik                                 SourceLocation LangLoc, LanguageIDs Lang,
1868284555Sarybchik                                 SourceLocation RBraceLoc = SourceLocation());
1869284555Sarybchik
1870293927Sarybchik  /// \brief Return the language specified by this linkage specification.
1871284555Sarybchik  LanguageIDs getLanguage() const { return Language; }
1872284555Sarybchik  /// \brief Set the language specified by this linkage specification.
1873284555Sarybchik  void setLanguage(LanguageIDs L) { Language = L; }
1874284555Sarybchik
1875284555Sarybchik  /// \brief Determines whether this linkage specification had braces in
1876293927Sarybchik  /// its syntactic form.
1877284555Sarybchik  bool hasBraces() const { return RBraceLoc.isValid(); }
1878284555Sarybchik
1879284555Sarybchik  SourceLocation getExternLoc() const { return ExternLoc; }
1880284555Sarybchik  SourceLocation getRBraceLoc() const { return RBraceLoc; }
1881293927Sarybchik  void setExternLoc(SourceLocation L) { ExternLoc = L; }
1882227569Sphilip  void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
1883227569Sphilip
1884227569Sphilip  SourceLocation getLocEnd() const {
1885227569Sphilip    if (hasBraces())
1886227569Sphilip      return getRBraceLoc();
1887227569Sphilip    // No braces: get the end location of the (only) declaration in context
1888293927Sarybchik    // (if present).
1889227569Sphilip    return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
1890227569Sphilip  }
1891227569Sphilip
1892227569Sphilip  SourceRange getSourceRange() const {
1893227569Sphilip    return SourceRange(ExternLoc, getLocEnd());
1894293927Sarybchik  }
1895284555Sarybchik
1896227569Sphilip  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1897227569Sphilip  static bool classof(const LinkageSpecDecl *D) { return true; }
1898227569Sphilip  static bool classofKind(Kind K) { return K == LinkageSpec; }
1899227569Sphilip  static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
1900294008Sarybchik    return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
1901284555Sarybchik  }
1902227569Sphilip  static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) {
1903284555Sarybchik    return static_cast<LinkageSpecDecl *>(const_cast<DeclContext*>(DC));
1904284555Sarybchik  }
1905227569Sphilip};
1906284555Sarybchik
1907227569Sphilip/// UsingDirectiveDecl - Represents C++ using-directive. For example:
1908293927Sarybchik///
1909284555Sarybchik///    using namespace std;
1910284555Sarybchik///
1911284555Sarybchik// NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide
1912284555Sarybchik// artificial name, for all using-directives in order to store
1913227569Sphilip// them in DeclContext effectively.
1914280553Sarybchikclass UsingDirectiveDecl : public NamedDecl {
1915280553Sarybchik  /// \brief The location of the "using" keyword.
1916227569Sphilip  SourceLocation UsingLoc;
1917280553Sarybchik
1918280553Sarybchik  /// SourceLocation - Location of 'namespace' token.
1919280553Sarybchik  SourceLocation NamespaceLoc;
1920280562Sarybchik
1921227569Sphilip  /// \brief The nested-name-specifier that precedes the namespace.
1922227569Sphilip  NestedNameSpecifierLoc QualifierLoc;
1923227569Sphilip
1924227569Sphilip  /// NominatedNamespace - Namespace nominated by using-directive.
1925227569Sphilip  NamedDecl *NominatedNamespace;
1926227569Sphilip
1927227569Sphilip  /// Enclosing context containing both using-directive and nominated
1928293927Sarybchik  /// namespace.
1929227569Sphilip  DeclContext *CommonAncestor;
1930227569Sphilip
1931227569Sphilip  /// getUsingDirectiveName - Returns special DeclarationName used by
1932227569Sphilip  /// using-directives. This is only used by DeclContext for storing
1933227569Sphilip  /// UsingDirectiveDecls in its lookup structure.
1934227569Sphilip  static DeclarationName getName() {
1935227569Sphilip    return DeclarationName::getUsingDirectiveName();
1936227569Sphilip  }
1937227569Sphilip
1938227569Sphilip  UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc,
1939227569Sphilip                     SourceLocation NamespcLoc,
1940227569Sphilip                     NestedNameSpecifierLoc QualifierLoc,
1941227569Sphilip                     SourceLocation IdentLoc,
1942227569Sphilip                     NamedDecl *Nominated,
1943227569Sphilip                     DeclContext *CommonAncestor)
1944227569Sphilip    : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc),
1945227569Sphilip      NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc),
1946284555Sarybchik      NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { }
1947284555Sarybchik
1948284555Sarybchikpublic:
1949284555Sarybchik  /// \brief Retrieve the nested-name-specifier that qualifies the
1950227569Sphilip  /// name of the namespace, with source-location information.
1951227569Sphilip  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
1952227569Sphilip
1953227569Sphilip  /// \brief Retrieve the nested-name-specifier that qualifies the
1954227569Sphilip  /// name of the namespace.
1955227569Sphilip  NestedNameSpecifier *getQualifier() const {
1956227569Sphilip    return QualifierLoc.getNestedNameSpecifier();
1957227569Sphilip  }
1958227569Sphilip
1959227569Sphilip  NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
1960227569Sphilip  const NamedDecl *getNominatedNamespaceAsWritten() const {
1961227569Sphilip    return NominatedNamespace;
1962284555Sarybchik  }
1963284555Sarybchik
1964227569Sphilip  /// getNominatedNamespace - Returns namespace nominated by using-directive.
1965293927Sarybchik  NamespaceDecl *getNominatedNamespace();
1966227569Sphilip
1967227569Sphilip  const NamespaceDecl *getNominatedNamespace() const {
1968227569Sphilip    return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
1969227569Sphilip  }
1970227569Sphilip
1971227569Sphilip  /// \brief Returns the common ancestor context of this using-directive and
1972227569Sphilip  /// its nominated namespace.
1973227569Sphilip  DeclContext *getCommonAncestor() { return CommonAncestor; }
1974227569Sphilip  const DeclContext *getCommonAncestor() const { return CommonAncestor; }
1975227569Sphilip
1976227569Sphilip  /// \brief Return the location of the "using" keyword.
1977227569Sphilip  SourceLocation getUsingLoc() const { return UsingLoc; }
1978227569Sphilip
1979227569Sphilip  // FIXME: Could omit 'Key' in name.
1980227569Sphilip  /// getNamespaceKeyLocation - Returns location of namespace keyword.
1981227569Sphilip  SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
1982227569Sphilip
1983284555Sarybchik  /// getIdentLocation - Returns location of identifier.
1984227569Sphilip  SourceLocation getIdentLocation() const { return getLocation(); }
1985227569Sphilip
1986284555Sarybchik  static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
1987227569Sphilip                                    SourceLocation UsingLoc,
1988227569Sphilip                                    SourceLocation NamespaceLoc,
1989227569Sphilip                                    NestedNameSpecifierLoc QualifierLoc,
1990227569Sphilip                                    SourceLocation IdentLoc,
1991227569Sphilip                                    NamedDecl *Nominated,
1992227569Sphilip                                    DeclContext *CommonAncestor);
1993227569Sphilip
1994293927Sarybchik  SourceRange getSourceRange() const {
1995227569Sphilip    return SourceRange(UsingLoc, getLocation());
1996227569Sphilip  }
1997227569Sphilip
1998227569Sphilip  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1999227569Sphilip  static bool classof(const UsingDirectiveDecl *D) { return true; }
2000227569Sphilip  static bool classofKind(Kind K) { return K == UsingDirective; }
2001227569Sphilip
2002284555Sarybchik  // Friend for getUsingDirectiveName.
2003284555Sarybchik  friend class DeclContext;
2004284555Sarybchik
2005284555Sarybchik  friend class ASTDeclReader;
2006284555Sarybchik};
2007284555Sarybchik
2008280553Sarybchik/// NamespaceAliasDecl - Represents a C++ namespace alias. For example:
2009227569Sphilip///
2010280553Sarybchik/// @code
2011280553Sarybchik/// namespace Foo = Bar;
2012280553Sarybchik/// @endcode
2013280562Sarybchikclass NamespaceAliasDecl : public NamedDecl {
2014227569Sphilip  /// \brief The location of the "namespace" keyword.
2015284555Sarybchik  SourceLocation NamespaceLoc;
2016284555Sarybchik
2017293955Sarybchik  /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc.
2018293955Sarybchik  SourceLocation IdentLoc;
2019294381Sarybchik
2020293955Sarybchik  /// \brief The nested-name-specifier that precedes the namespace.
2021293927Sarybchik  NestedNameSpecifierLoc QualifierLoc;
2022227569Sphilip
2023227569Sphilip  /// Namespace - The Decl that this alias points to. Can either be a
2024227569Sphilip  /// NamespaceDecl or a NamespaceAliasDecl.
2025227569Sphilip  NamedDecl *Namespace;
2026227569Sphilip
2027227569Sphilip  NamespaceAliasDecl(DeclContext *DC, SourceLocation NamespaceLoc,
2028227569Sphilip                     SourceLocation AliasLoc, IdentifierInfo *Alias,
2029227569Sphilip                     NestedNameSpecifierLoc QualifierLoc,
2030227569Sphilip                     SourceLocation IdentLoc, NamedDecl *Namespace)
2031284555Sarybchik    : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias),
2032284555Sarybchik      NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
2033227569Sphilip      QualifierLoc(QualifierLoc), Namespace(Namespace) { }
2034293927Sarybchik
2035227569Sphilip  friend class ASTDeclReader;
2036227569Sphilip
2037227569Sphilippublic:
2038227569Sphilip  /// \brief Retrieve the nested-name-specifier that qualifies the
2039227569Sphilip  /// name of the namespace, with source-location information.
2040227569Sphilip  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
2041227569Sphilip
2042293927Sarybchik  /// \brief Retrieve the nested-name-specifier that qualifies the
2043280589Sarybchik  /// name of the namespace.
2044280589Sarybchik  NestedNameSpecifier *getQualifier() const {
2045280589Sarybchik    return QualifierLoc.getNestedNameSpecifier();
2046280589Sarybchik  }
2047284555Sarybchik
2048227569Sphilip  /// \brief Retrieve the namespace declaration aliased by this directive.
2049284555Sarybchik  NamespaceDecl *getNamespace() {
2050284555Sarybchik    if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
2051284555Sarybchik      return AD->getNamespace();
2052227569Sphilip
2053293927Sarybchik    return cast<NamespaceDecl>(Namespace);
2054227569Sphilip  }
2055284555Sarybchik
2056227569Sphilip  const NamespaceDecl *getNamespace() const {
2057284555Sarybchik    return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
2058227569Sphilip  }
2059284555Sarybchik
2060227569Sphilip  /// Returns the location of the alias name, i.e. 'foo' in
2061293927Sarybchik  /// "namespace foo = ns::bar;".
2062284555Sarybchik  SourceLocation getAliasLoc() const { return getLocation(); }
2063284555Sarybchik
2064284555Sarybchik  /// Returns the location of the 'namespace' keyword.
2065284555Sarybchik  SourceLocation getNamespaceLoc() const { return NamespaceLoc; }
2066284555Sarybchik
2067284555Sarybchik  /// Returns the location of the identifier in the named namespace.
2068284555Sarybchik  SourceLocation getTargetNameLoc() const { return IdentLoc; }
2069293927Sarybchik
2070284555Sarybchik  /// \brief Retrieve the namespace that this alias refers to, which
2071284555Sarybchik  /// may either be a NamespaceDecl or a NamespaceAliasDecl.
2072284555Sarybchik  NamedDecl *getAliasedNamespace() const { return Namespace; }
2073284555Sarybchik
2074284555Sarybchik  static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
2075284555Sarybchik                                    SourceLocation NamespaceLoc,
2076293927Sarybchik                                    SourceLocation AliasLoc,
2077284555Sarybchik                                    IdentifierInfo *Alias,
2078284555Sarybchik                                    NestedNameSpecifierLoc QualifierLoc,
2079284555Sarybchik                                    SourceLocation IdentLoc,
2080284555Sarybchik                                    NamedDecl *Namespace);
2081284555Sarybchik
2082284555Sarybchik  virtual SourceRange getSourceRange() const {
2083293927Sarybchik    return SourceRange(NamespaceLoc, IdentLoc);
2084284555Sarybchik  }
2085284555Sarybchik
2086284555Sarybchik  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2087284555Sarybchik  static bool classof(const NamespaceAliasDecl *D) { return true; }
2088284555Sarybchik  static bool classofKind(Kind K) { return K == NamespaceAlias; }
2089284555Sarybchik};
2090284555Sarybchik
2091284555Sarybchik/// UsingShadowDecl - Represents a shadow declaration introduced into
2092284555Sarybchik/// a scope by a (resolved) using declaration.  For example,
2093284555Sarybchik///
2094284555Sarybchik/// namespace A {
2095284555Sarybchik///   void foo();
2096284555Sarybchik/// }
2097284555Sarybchik/// namespace B {
2098284555Sarybchik///   using A::foo(); // <- a UsingDecl
2099284555Sarybchik///                   // Also creates a UsingShadowDecl for A::foo in B
2100284555Sarybchik/// }
2101284555Sarybchik///
2102284555Sarybchikclass UsingShadowDecl : public NamedDecl {
2103284555Sarybchik  /// The referenced declaration.
2104284555Sarybchik  NamedDecl *Underlying;
2105284555Sarybchik
2106284555Sarybchik  /// \brief The using declaration which introduced this decl or the next using
2107294381Sarybchik  /// shadow declaration contained in the aforementioned using declaration.
2108294381Sarybchik  NamedDecl *UsingOrNextShadow;
2109294381Sarybchik  friend class UsingDecl;
2110294381Sarybchik
2111294381Sarybchik  UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
2112294381Sarybchik                  NamedDecl *Target)
2113284555Sarybchik    : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
2114294381Sarybchik      Underlying(Target),
2115294381Sarybchik      UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
2116294381Sarybchik    if (Target) {
2117294381Sarybchik      setDeclName(Target->getDeclName());
2118294381Sarybchik      IdentifierNamespace = Target->getIdentifierNamespace();
2119294381Sarybchik    }
2120294381Sarybchik    setImplicit();
2121294381Sarybchik  }
2122294381Sarybchik
2123284555Sarybchikpublic:
2124284555Sarybchik  static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
2125284555Sarybchik                                 SourceLocation Loc, UsingDecl *Using,
2126284555Sarybchik                                 NamedDecl *Target) {
2127284555Sarybchik    return new (C) UsingShadowDecl(DC, Loc, Using, Target);
2128227569Sphilip  }
2129227569Sphilip
2130227569Sphilip  /// \brief Gets the underlying declaration which has been brought into the
2131227569Sphilip  /// local scope.
2132284555Sarybchik  NamedDecl *getTargetDecl() const { return Underlying; }
2133227569Sphilip
2134227569Sphilip  /// \brief Sets the underlying declaration which has been brought into the
2135227569Sphilip  /// local scope.
2136227569Sphilip  void setTargetDecl(NamedDecl* ND) {
2137227569Sphilip    assert(ND && "Target decl is null!");
2138227569Sphilip    Underlying = ND;
2139227569Sphilip    IdentifierNamespace = ND->getIdentifierNamespace();
2140227569Sphilip  }
2141227569Sphilip
2142227569Sphilip  /// \brief Gets the using declaration to which this declaration is tied.
2143227569Sphilip  UsingDecl *getUsingDecl() const;
2144227569Sphilip
2145227569Sphilip  /// \brief The next using shadow declaration contained in the shadow decl
2146227569Sphilip  /// chain of the using declaration which introduced this decl.
2147227569Sphilip  UsingShadowDecl *getNextUsingShadowDecl() const {
2148227569Sphilip    return dyn_cast_or_null<UsingShadowDecl>(UsingOrNextShadow);
2149227569Sphilip  }
2150227569Sphilip
2151227569Sphilip  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2152227569Sphilip  static bool classof(const UsingShadowDecl *D) { return true; }
2153227569Sphilip  static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
2154227569Sphilip
2155284555Sarybchik  friend class ASTDeclReader;
2156284555Sarybchik  friend class ASTDeclWriter;
2157284555Sarybchik};
2158284555Sarybchik
2159284555Sarybchik/// UsingDecl - Represents a C++ using-declaration. For example:
2160284555Sarybchik///    using someNameSpace::someIdentifier;
2161227569Sphilipclass UsingDecl : public NamedDecl {
2162227569Sphilip  /// \brief The source location of the "using" location itself.
2163227569Sphilip  SourceLocation UsingLocation;
2164227569Sphilip
2165284555Sarybchik  /// \brief The nested-name-specifier that precedes the name.
2166284555Sarybchik  NestedNameSpecifierLoc QualifierLoc;
2167284555Sarybchik
2168284555Sarybchik  /// DNLoc - Provides source/type location info for the
2169284555Sarybchik  /// declaration name embedded in the ValueDecl base class.
2170284555Sarybchik  DeclarationNameLoc DNLoc;
2171284555Sarybchik
2172284555Sarybchik  /// \brief The first shadow declaration of the shadow decl chain associated
2173284555Sarybchik  /// with this using declaration.
2174227569Sphilip  UsingShadowDecl *FirstUsingShadow;
2175227569Sphilip
2176284555Sarybchik  // \brief Has 'typename' keyword.
2177284555Sarybchik  bool IsTypeName;
2178284555Sarybchik
2179284555Sarybchik  UsingDecl(DeclContext *DC, SourceLocation UL,
2180284555Sarybchik            NestedNameSpecifierLoc QualifierLoc,
2181284555Sarybchik            const DeclarationNameInfo &NameInfo, bool IsTypeNameArg)
2182284555Sarybchik    : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
2183284555Sarybchik      UsingLocation(UL), QualifierLoc(QualifierLoc),
2184284555Sarybchik      DNLoc(NameInfo.getInfo()), FirstUsingShadow(0),IsTypeName(IsTypeNameArg) {
2185284555Sarybchik  }
2186284555Sarybchik
2187284555Sarybchikpublic:
2188284555Sarybchik  /// \brief Returns the source location of the "using" keyword.
2189284555Sarybchik  SourceLocation getUsingLocation() const { return UsingLocation; }
2190284555Sarybchik
2191284555Sarybchik  /// \brief Set the source location of the 'using' keyword.
2192284555Sarybchik  void setUsingLocation(SourceLocation L) { UsingLocation = L; }
2193284555Sarybchik
2194284555Sarybchik  /// \brief Retrieve the nested-name-specifier that qualifies the name,
2195284555Sarybchik  /// with source-location information.
2196284555Sarybchik  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
2197284555Sarybchik
2198284555Sarybchik  /// \brief Retrieve the nested-name-specifier that qualifies the name.
2199284555Sarybchik  NestedNameSpecifier *getQualifier() const {
2200284555Sarybchik    return QualifierLoc.getNestedNameSpecifier();
2201284555Sarybchik  }
2202284555Sarybchik
2203284555Sarybchik  DeclarationNameInfo getNameInfo() const {
2204284555Sarybchik    return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
2205284555Sarybchik  }
2206284555Sarybchik
2207284555Sarybchik  /// \brief Return true if the using declaration has 'typename'.
2208284555Sarybchik  bool isTypeName() const { return IsTypeName; }
2209284555Sarybchik
2210284555Sarybchik  /// \brief Sets whether the using declaration has 'typename'.
2211284555Sarybchik  void setTypeName(bool TN) { IsTypeName = TN; }
2212284555Sarybchik
2213284555Sarybchik  /// \brief Iterates through the using shadow declarations assosiated with
2214227569Sphilip  /// this using declaration.
2215284555Sarybchik  class shadow_iterator {
2216284555Sarybchik    /// \brief The current using shadow declaration.
2217284555Sarybchik    UsingShadowDecl *Current;
2218284555Sarybchik
2219284555Sarybchik  public:
2220284555Sarybchik    typedef UsingShadowDecl*          value_type;
2221284555Sarybchik    typedef UsingShadowDecl*          reference;
2222284555Sarybchik    typedef UsingShadowDecl*          pointer;
2223284555Sarybchik    typedef std::forward_iterator_tag iterator_category;
2224284555Sarybchik    typedef std::ptrdiff_t            difference_type;
2225284555Sarybchik
2226284555Sarybchik    shadow_iterator() : Current(0) { }
2227284555Sarybchik    explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
2228284555Sarybchik
2229284555Sarybchik    reference operator*() const { return Current; }
2230227569Sphilip    pointer operator->() const { return Current; }
2231227569Sphilip
2232284555Sarybchik    shadow_iterator& operator++() {
2233284555Sarybchik      Current = Current->getNextUsingShadowDecl();
2234284555Sarybchik      return *this;
2235284555Sarybchik    }
2236284555Sarybchik
2237284555Sarybchik    shadow_iterator operator++(int) {
2238293927Sarybchik      shadow_iterator tmp(*this);
2239227569Sphilip      ++(*this);
2240227569Sphilip      return tmp;
2241227569Sphilip    }
2242227569Sphilip
2243227569Sphilip    friend bool operator==(shadow_iterator x, shadow_iterator y) {
2244227569Sphilip      return x.Current == y.Current;
2245227569Sphilip    }
2246293927Sarybchik    friend bool operator!=(shadow_iterator x, shadow_iterator y) {
2247284555Sarybchik      return x.Current != y.Current;
2248284555Sarybchik    }
2249227569Sphilip  };
2250227569Sphilip
2251293927Sarybchik  shadow_iterator shadow_begin() const {
2252284555Sarybchik    return shadow_iterator(FirstUsingShadow);
2253284555Sarybchik  }
2254227569Sphilip  shadow_iterator shadow_end() const { return shadow_iterator(); }
2255227569Sphilip
2256293927Sarybchik  /// \brief Return the number of shadowed declarations associated with this
2257227569Sphilip  /// using declaration.
2258227569Sphilip  unsigned shadow_size() const {
2259227569Sphilip    return std::distance(shadow_begin(), shadow_end());
2260293927Sarybchik  }
2261284555Sarybchik
2262284555Sarybchik  void addShadowDecl(UsingShadowDecl *S);
2263284555Sarybchik  void removeShadowDecl(UsingShadowDecl *S);
2264284555Sarybchik
2265227569Sphilip  static UsingDecl *Create(ASTContext &C, DeclContext *DC,
2266227569Sphilip                           SourceLocation UsingL,
2267284555Sarybchik                           NestedNameSpecifierLoc QualifierLoc,
2268294017Sarybchik                           const DeclarationNameInfo &NameInfo,
2269284555Sarybchik                           bool IsTypeNameArg);
2270284555Sarybchik
2271284555Sarybchik  SourceRange getSourceRange() const {
2272227569Sphilip    return SourceRange(UsingLocation, getNameInfo().getEndLoc());
2273227569Sphilip  }
2274284555Sarybchik
2275294017Sarybchik  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2276284555Sarybchik  static bool classof(const UsingDecl *D) { return true; }
2277227569Sphilip  static bool classofKind(Kind K) { return K == Using; }
2278293927Sarybchik
2279284555Sarybchik  friend class ASTDeclReader;
2280227569Sphilip  friend class ASTDeclWriter;
2281284555Sarybchik};
2282284555Sarybchik
2283284555Sarybchik/// UnresolvedUsingValueDecl - Represents a dependent using
2284227569Sphilip/// declaration which was not marked with 'typename'.  Unlike
2285293927Sarybchik/// non-dependent using declarations, these *only* bring through
2286284555Sarybchik/// non-types; otherwise they would break two-phase lookup.
2287227569Sphilip///
2288284555Sarybchik/// template <class T> class A : public Base<T> {
2289284555Sarybchik///   using Base<T>::foo;
2290284555Sarybchik/// };
2291284555Sarybchikclass UnresolvedUsingValueDecl : public ValueDecl {
2292284555Sarybchik  /// \brief The source location of the 'using' keyword
2293227569Sphilip  SourceLocation UsingLocation;
2294293927Sarybchik
2295284555Sarybchik  /// \brief The nested-name-specifier that precedes the name.
2296227569Sphilip  NestedNameSpecifierLoc QualifierLoc;
2297284555Sarybchik
2298284555Sarybchik  /// DNLoc - Provides source/type location info for the
2299227569Sphilip  /// declaration name embedded in the ValueDecl base class.
2300293927Sarybchik  DeclarationNameLoc DNLoc;
2301284555Sarybchik
2302227569Sphilip  UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
2303227569Sphilip                           SourceLocation UsingLoc,
2304293927Sarybchik                           NestedNameSpecifierLoc QualifierLoc,
2305284555Sarybchik                           const DeclarationNameInfo &NameInfo)
2306227569Sphilip    : ValueDecl(UnresolvedUsingValue, DC,
2307227569Sphilip                NameInfo.getLoc(), NameInfo.getName(), Ty),
2308284555Sarybchik      UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),
2309227569Sphilip      DNLoc(NameInfo.getInfo())
2310284555Sarybchik  { }
2311227569Sphilip
2312284555Sarybchikpublic:
2313284555Sarybchik  /// \brief Returns the source location of the 'using' keyword.
2314284555Sarybchik  SourceLocation getUsingLoc() const { return UsingLocation; }
2315284555Sarybchik
2316284555Sarybchik  /// \brief Set the source location of the 'using' keyword.
2317227569Sphilip  void setUsingLoc(SourceLocation L) { UsingLocation = L; }
2318284555Sarybchik
2319284555Sarybchik  /// \brief Retrieve the nested-name-specifier that qualifies the name,
2320284555Sarybchik  /// with source-location information.
2321284555Sarybchik  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
2322284555Sarybchik
2323227569Sphilip  /// \brief Retrieve the nested-name-specifier that qualifies the name.
2324294386Sarybchik  NestedNameSpecifier *getQualifier() const {
2325227569Sphilip    return QualifierLoc.getNestedNameSpecifier();
2326294386Sarybchik  }
2327294386Sarybchik
2328294386Sarybchik  DeclarationNameInfo getNameInfo() const {
2329294386Sarybchik    return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
2330294386Sarybchik  }
2331294386Sarybchik
2332294386Sarybchik  static UnresolvedUsingValueDecl *
2333294386Sarybchik    Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
2334294386Sarybchik           NestedNameSpecifierLoc QualifierLoc,
2335294386Sarybchik           const DeclarationNameInfo &NameInfo);
2336294386Sarybchik
2337294386Sarybchik  SourceRange getSourceRange() const {
2338294386Sarybchik    return SourceRange(UsingLocation, getNameInfo().getEndLoc());
2339294386Sarybchik  }
2340294386Sarybchik
2341294386Sarybchik  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2342294386Sarybchik  static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
2343294386Sarybchik  static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
2344294386Sarybchik
2345294386Sarybchik  friend class ASTDeclReader;
2346294386Sarybchik  friend class ASTDeclWriter;
2347294386Sarybchik};
2348294386Sarybchik
2349294386Sarybchik/// UnresolvedUsingTypenameDecl - Represents a dependent using
2350294386Sarybchik/// declaration which was marked with 'typename'.
2351294386Sarybchik///
2352294386Sarybchik/// template <class T> class A : public Base<T> {
2353294386Sarybchik///   using typename Base<T>::foo;
2354294386Sarybchik/// };
2355294386Sarybchik///
2356294386Sarybchik/// The type associated with a unresolved using typename decl is
2357294386Sarybchik/// currently always a typename type.
2358294386Sarybchikclass UnresolvedUsingTypenameDecl : public TypeDecl {
2359294386Sarybchik  /// \brief The source location of the 'using' keyword
2360294386Sarybchik  SourceLocation UsingLocation;
2361294386Sarybchik
2362294386Sarybchik  /// \brief The source location of the 'typename' keyword
2363294386Sarybchik  SourceLocation TypenameLocation;
2364294386Sarybchik
2365294386Sarybchik  /// \brief The nested-name-specifier that precedes the name.
2366294386Sarybchik  NestedNameSpecifierLoc QualifierLoc;
2367294386Sarybchik
2368294386Sarybchik  UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
2369294386Sarybchik                              SourceLocation TypenameLoc,
2370294386Sarybchik                              NestedNameSpecifierLoc QualifierLoc,
2371294386Sarybchik                              SourceLocation TargetNameLoc,
2372294386Sarybchik                              IdentifierInfo *TargetName)
2373294386Sarybchik    : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
2374294386Sarybchik               UsingLoc),
2375294386Sarybchik      TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }
2376227569Sphilip
2377227569Sphilip  friend class ASTDeclReader;
2378227569Sphilip
2379227569Sphilippublic:
2380227569Sphilip  /// \brief Returns the source location of the 'using' keyword.
2381  SourceLocation getUsingLoc() const { return getLocStart(); }
2382
2383  /// \brief Returns the source location of the 'typename' keyword.
2384  SourceLocation getTypenameLoc() const { return TypenameLocation; }
2385
2386  /// \brief Retrieve the nested-name-specifier that qualifies the name,
2387  /// with source-location information.
2388  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
2389
2390  /// \brief Retrieve the nested-name-specifier that qualifies the name.
2391  NestedNameSpecifier *getQualifier() const {
2392    return QualifierLoc.getNestedNameSpecifier();
2393  }
2394
2395  static UnresolvedUsingTypenameDecl *
2396    Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
2397           SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
2398           SourceLocation TargetNameLoc, DeclarationName TargetName);
2399
2400  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2401  static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
2402  static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
2403};
2404
2405/// StaticAssertDecl - Represents a C++0x static_assert declaration.
2406class StaticAssertDecl : public Decl {
2407  Expr *AssertExpr;
2408  StringLiteral *Message;
2409  SourceLocation RParenLoc;
2410
2411  StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc,
2412                   Expr *assertexpr, StringLiteral *message,
2413                   SourceLocation RParenLoc)
2414  : Decl(StaticAssert, DC, StaticAssertLoc), AssertExpr(assertexpr),
2415    Message(message), RParenLoc(RParenLoc) { }
2416
2417public:
2418  static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
2419                                  SourceLocation StaticAssertLoc,
2420                                  Expr *AssertExpr, StringLiteral *Message,
2421                                  SourceLocation RParenLoc);
2422
2423  Expr *getAssertExpr() { return AssertExpr; }
2424  const Expr *getAssertExpr() const { return AssertExpr; }
2425
2426  StringLiteral *getMessage() { return Message; }
2427  const StringLiteral *getMessage() const { return Message; }
2428
2429  SourceLocation getRParenLoc() const { return RParenLoc; }
2430  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
2431
2432  SourceRange getSourceRange() const {
2433    return SourceRange(getLocation(), getRParenLoc());
2434  }
2435
2436  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2437  static bool classof(StaticAssertDecl *D) { return true; }
2438  static bool classofKind(Kind K) { return K == StaticAssert; }
2439
2440  friend class ASTDeclReader;
2441};
2442
2443/// Insertion operator for diagnostics.  This allows sending AccessSpecifier's
2444/// into a diagnostic with <<.
2445const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
2446                                    AccessSpecifier AS);
2447
2448} // end namespace clang
2449
2450#endif
2451