1193326Sed//===-- DeclCXX.h - Classes for representing C++ declarations -*- C++ -*-=====//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10205219Srdivacky//  This file defines the C++ Decl subclasses, other than those for
11205219Srdivacky//  templates (in DeclTemplate.h) and friends (in DeclFriend.h).
12193326Sed//
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15193326Sed#ifndef LLVM_CLANG_AST_DECLCXX_H
16193326Sed#define LLVM_CLANG_AST_DECLCXX_H
17193326Sed
18249423Sdim#include "clang/AST/ASTUnresolvedSet.h"
19249423Sdim#include "clang/AST/Decl.h"
20198092Srdivacky#include "clang/AST/Expr.h"
21234353Sdim#include "clang/AST/ExprCXX.h"
22212904Sdim#include "clang/AST/TypeLoc.h"
23234353Sdim#include "llvm/ADT/DenseMap.h"
24234353Sdim#include "llvm/ADT/PointerIntPair.h"
25198092Srdivacky#include "llvm/ADT/SmallPtrSet.h"
26234353Sdim#include "llvm/Support/Compiler.h"
27193326Sed
28193326Sednamespace clang {
29193326Sed
30193326Sedclass ClassTemplateDecl;
31198092Srdivackyclass ClassTemplateSpecializationDecl;
32198092Srdivackyclass CXXBasePath;
33198092Srdivackyclass CXXBasePaths;
34193326Sedclass CXXConstructorDecl;
35198092Srdivackyclass CXXConversionDecl;
36193326Sedclass CXXDestructorDecl;
37193326Sedclass CXXMethodDecl;
38198092Srdivackyclass CXXRecordDecl;
39198092Srdivackyclass CXXMemberLookupCriteria;
40206084Srdivackyclass CXXFinalOverriderMap;
41218893Sdimclass CXXIndirectPrimaryBaseSet;
42205219Srdivackyclass FriendDecl;
43234353Sdimclass LambdaExpr;
44239462Sdimclass UsingDecl;
45234353Sdim
46198092Srdivacky/// \brief Represents any kind of function declaration, whether it is a
47195099Sed/// concrete function or a function template.
48195099Sedclass AnyFunctionDecl {
49195099Sed  NamedDecl *Function;
50198092Srdivacky
51195341Sed  AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
52198092Srdivacky
53195099Sedpublic:
54195099Sed  AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
55195099Sed  AnyFunctionDecl(FunctionTemplateDecl *FTD);
56198092Srdivacky
57198092Srdivacky  /// \brief Implicily converts any function or function template into a
58195099Sed  /// named declaration.
59195099Sed  operator NamedDecl *() const { return Function; }
60198092Srdivacky
61195099Sed  /// \brief Retrieve the underlying function or function template.
62195099Sed  NamedDecl *get() const { return Function; }
63198092Srdivacky
64198092Srdivacky  static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
65195341Sed    return AnyFunctionDecl(ND);
66195341Sed  }
67195099Sed};
68198092Srdivacky
69195099Sed} // end namespace clang
70195099Sed
71195099Sednamespace llvm {
72195341Sed  // Provide PointerLikeTypeTraits for non-cvr pointers.
73195341Sed  template<>
74195341Sed  class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
75195341Sed  public:
76195341Sed    static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
77198092Srdivacky      return F.get();
78195341Sed    }
79195341Sed    static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
80195341Sed      return ::clang::AnyFunctionDecl::getFromNamedDecl(
81195341Sed                                      static_cast< ::clang::NamedDecl*>(P));
82195341Sed    }
83198092Srdivacky
84195341Sed    enum { NumLowBitsAvailable = 2 };
85195341Sed  };
86198092Srdivacky
87195099Sed} // end namespace llvm
88195099Sed
89195099Sednamespace clang {
90198092Srdivacky
91239462Sdim/// @brief Represents an access specifier followed by colon ':'.
92210299Sed///
93210299Sed/// An objects of this class represents sugar for the syntactic occurrence
94210299Sed/// of an access specifier followed by a colon in the list of member
95210299Sed/// specifiers of a C++ class definition.
96210299Sed///
97210299Sed/// Note that they do not represent other uses of access specifiers,
98210299Sed/// such as those occurring in a list of base specifiers.
99210299Sed/// Also note that this class has nothing to do with so-called
100210299Sed/// "access declarations" (C++98 11.3 [class.access.dcl]).
101210299Sedclass AccessSpecDecl : public Decl {
102234353Sdim  virtual void anchor();
103239462Sdim  /// \brief The location of the ':'.
104210299Sed  SourceLocation ColonLoc;
105210299Sed
106210299Sed  AccessSpecDecl(AccessSpecifier AS, DeclContext *DC,
107210299Sed                 SourceLocation ASLoc, SourceLocation ColonLoc)
108210299Sed    : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
109210299Sed    setAccess(AS);
110210299Sed  }
111218893Sdim  AccessSpecDecl(EmptyShell Empty)
112218893Sdim    : Decl(AccessSpec, Empty) { }
113210299Sedpublic:
114239462Sdim  /// \brief The location of the access specifier.
115210299Sed  SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
116239462Sdim  /// \brief Sets the location of the access specifier.
117210299Sed  void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
118210299Sed
119239462Sdim  /// \brief The location of the colon following the access specifier.
120210299Sed  SourceLocation getColonLoc() const { return ColonLoc; }
121239462Sdim  /// \brief Sets the location of the colon.
122210299Sed  void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
123210299Sed
124234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
125210299Sed    return SourceRange(getAccessSpecifierLoc(), getColonLoc());
126210299Sed  }
127210299Sed
128210299Sed  static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
129210299Sed                                DeclContext *DC, SourceLocation ASLoc,
130210299Sed                                SourceLocation ColonLoc) {
131210299Sed    return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
132210299Sed  }
133234353Sdim  static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
134210299Sed
135210299Sed  // Implement isa/cast/dyncast/etc.
136210299Sed  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
137210299Sed  static bool classofKind(Kind K) { return K == AccessSpec; }
138210299Sed};
139210299Sed
140210299Sed
141239462Sdim/// \brief Represents a base class of a C++ class.
142193326Sed///
143193326Sed/// Each CXXBaseSpecifier represents a single, direct base class (or
144193326Sed/// struct) of a C++ class (or struct). It specifies the type of that
145193326Sed/// base class, whether it is a virtual or non-virtual base, and what
146193326Sed/// level of access (public, protected, private) is used for the
147193326Sed/// derivation. For example:
148193326Sed///
149193326Sed/// @code
150193326Sed///   class A { };
151193326Sed///   class B { };
152193326Sed///   class C : public virtual A, protected B { };
153193326Sed/// @endcode
154193326Sed///
155193326Sed/// In this code, C will have two CXXBaseSpecifiers, one for "public
156193326Sed/// virtual A" and the other for "protected B".
157193326Sedclass CXXBaseSpecifier {
158193326Sed  /// Range - The source code range that covers the full base
159193326Sed  /// specifier, including the "virtual" (if present) and access
160193326Sed  /// specifier (if present).
161193326Sed  SourceRange Range;
162193326Sed
163218893Sdim  /// \brief The source location of the ellipsis, if this is a pack
164218893Sdim  /// expansion.
165218893Sdim  SourceLocation EllipsisLoc;
166234353Sdim
167239462Sdim  /// \brief Whether this is a virtual base class or not.
168193326Sed  bool Virtual : 1;
169193326Sed
170193326Sed  /// BaseOfClass - Whether this is the base of a class (true) or of a
171193326Sed  /// struct (false). This determines the mapping from the access
172193326Sed  /// specifier as written in the source code to the access specifier
173193326Sed  /// used for semantic analysis.
174198092Srdivacky  bool BaseOfClass : 1;
175193326Sed
176193326Sed  /// Access - Access specifier as written in the source code (which
177193326Sed  /// may be AS_none). The actual type of data stored here is an
178193326Sed  /// AccessSpecifier, but we use "unsigned" here to work around a
179193326Sed  /// VC++ bug.
180193326Sed  unsigned Access : 2;
181193326Sed
182218893Sdim  /// InheritConstructors - Whether the class contains a using declaration
183218893Sdim  /// to inherit the named class's constructors.
184218893Sdim  bool InheritConstructors : 1;
185218893Sdim
186212904Sdim  /// BaseTypeInfo - The type of the base class. This will be a class or struct
187212904Sdim  /// (or a typedef of such). The source code range does not include the
188212904Sdim  /// "virtual" or access specifier.
189212904Sdim  TypeSourceInfo *BaseTypeInfo;
190198092Srdivacky
191193326Sedpublic:
192193326Sed  CXXBaseSpecifier() { }
193193326Sed
194212904Sdim  CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A,
195218893Sdim                   TypeSourceInfo *TInfo, SourceLocation EllipsisLoc)
196234353Sdim    : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC),
197218893Sdim      Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { }
198193326Sed
199193326Sed  /// getSourceRange - Retrieves the source range that contains the
200193326Sed  /// entire base specifier.
201234353Sdim  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
202234353Sdim  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
203234353Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
204198092Srdivacky
205193326Sed  /// isVirtual - Determines whether the base class is a virtual base
206193326Sed  /// class (or not).
207193326Sed  bool isVirtual() const { return Virtual; }
208193326Sed
209212904Sdim  /// \brief Determine whether this base class is a base of a class declared
210203955Srdivacky  /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
211203955Srdivacky  bool isBaseOfClass() const { return BaseOfClass; }
212234353Sdim
213218893Sdim  /// \brief Determine whether this base specifier is a pack expansion.
214218893Sdim  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
215218893Sdim
216218893Sdim  /// \brief Determine whether this base class's constructors get inherited.
217218893Sdim  bool getInheritConstructors() const { return InheritConstructors; }
218218893Sdim
219218893Sdim  /// \brief Set that this base class's constructors should be inherited.
220218893Sdim  void setInheritConstructors(bool Inherit = true) {
221218893Sdim    InheritConstructors = Inherit;
222218893Sdim  }
223218893Sdim
224218893Sdim  /// \brief For a pack expansion, determine the location of the ellipsis.
225218893Sdim  SourceLocation getEllipsisLoc() const {
226218893Sdim    return EllipsisLoc;
227218893Sdim  }
228218893Sdim
229193326Sed  /// getAccessSpecifier - Returns the access specifier for this base
230193326Sed  /// specifier. This is the actual base specifier as used for
231193326Sed  /// semantic analysis, so the result can never be AS_none. To
232193326Sed  /// retrieve the access specifier as written in the source code, use
233193326Sed  /// getAccessSpecifierAsWritten().
234198092Srdivacky  AccessSpecifier getAccessSpecifier() const {
235193326Sed    if ((AccessSpecifier)Access == AS_none)
236193326Sed      return BaseOfClass? AS_private : AS_public;
237193326Sed    else
238198092Srdivacky      return (AccessSpecifier)Access;
239193326Sed  }
240193326Sed
241193326Sed  /// getAccessSpecifierAsWritten - Retrieves the access specifier as
242193326Sed  /// written in the source code (which may mean that no access
243193326Sed  /// specifier was explicitly written). Use getAccessSpecifier() to
244193326Sed  /// retrieve the access specifier for use in semantic analysis.
245193326Sed  AccessSpecifier getAccessSpecifierAsWritten() const {
246193326Sed    return (AccessSpecifier)Access;
247193326Sed  }
248193326Sed
249193326Sed  /// getType - Retrieves the type of the base class. This type will
250193326Sed  /// always be an unqualified class type.
251212904Sdim  QualType getType() const { return BaseTypeInfo->getType(); }
252212904Sdim
253212904Sdim  /// getTypeLoc - Retrieves the type and source location of the base class.
254212904Sdim  TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
255193326Sed};
256193326Sed
257251662Sdim/// The inheritance model to use for member pointers of a given CXXRecordDecl.
258251662Sdimenum MSInheritanceModel {
259251662Sdim  MSIM_Single,
260251662Sdim  MSIM_SinglePolymorphic,
261251662Sdim  MSIM_Multiple,
262251662Sdim  MSIM_MultiplePolymorphic,
263251662Sdim  MSIM_Virtual,
264251662Sdim  MSIM_Unspecified
265251662Sdim};
266251662Sdim
267193326Sed/// CXXRecordDecl - Represents a C++ struct/union/class.
268193326Sed/// FIXME: This class will disappear once we've properly taught RecordDecl
269193326Sed/// to deal with C++-specific things.
270193326Sedclass CXXRecordDecl : public RecordDecl {
271193326Sed
272203955Srdivacky  friend void TagDecl::startDefinition();
273193326Sed
274249423Sdim  /// Values used in DefinitionData fields to represent special members.
275249423Sdim  enum SpecialMemberFlags {
276249423Sdim    SMF_DefaultConstructor = 0x1,
277249423Sdim    SMF_CopyConstructor = 0x2,
278249423Sdim    SMF_MoveConstructor = 0x4,
279249423Sdim    SMF_CopyAssignment = 0x8,
280249423Sdim    SMF_MoveAssignment = 0x10,
281249423Sdim    SMF_Destructor = 0x20,
282249423Sdim    SMF_All = 0x3f
283249423Sdim  };
284249423Sdim
285203955Srdivacky  struct DefinitionData {
286203955Srdivacky    DefinitionData(CXXRecordDecl *D);
287193326Sed
288249423Sdim    /// \brief True if this class has any user-declared constructors.
289203955Srdivacky    bool UserDeclaredConstructor : 1;
290193326Sed
291249423Sdim    /// The user-declared special members which this class has.
292249423Sdim    unsigned UserDeclaredSpecialMembers : 6;
293193326Sed
294203955Srdivacky    /// Aggregate - True when this class is an aggregate.
295203955Srdivacky    bool Aggregate : 1;
296193326Sed
297203955Srdivacky    /// PlainOldData - True when this class is a POD-type.
298203955Srdivacky    bool PlainOldData : 1;
299198092Srdivacky
300203955Srdivacky    /// Empty - true when this class is empty for traits purposes,
301203955Srdivacky    /// i.e. has no data members other than 0-width bit-fields, has no
302203955Srdivacky    /// virtual function/base, and doesn't inherit from a non-empty
303203955Srdivacky    /// class. Doesn't take union-ness into account.
304203955Srdivacky    bool Empty : 1;
305198092Srdivacky
306203955Srdivacky    /// Polymorphic - True when this class is polymorphic, i.e. has at
307203955Srdivacky    /// least one virtual member or derives from a polymorphic class.
308203955Srdivacky    bool Polymorphic : 1;
309198092Srdivacky
310203955Srdivacky    /// Abstract - True when this class is abstract, i.e. has at least
311203955Srdivacky    /// one pure virtual function, (that can come from a base class).
312203955Srdivacky    bool Abstract : 1;
313198092Srdivacky
314221345Sdim    /// IsStandardLayout - True when this class has standard layout.
315221345Sdim    ///
316221345Sdim    /// C++0x [class]p7.  A standard-layout class is a class that:
317221345Sdim    /// * has no non-static data members of type non-standard-layout class (or
318221345Sdim    ///   array of such types) or reference,
319221345Sdim    /// * has no virtual functions (10.3) and no virtual base classes (10.1),
320234353Sdim    /// * has the same access control (Clause 11) for all non-static data
321234353Sdim    ///   members
322221345Sdim    /// * has no non-standard-layout base classes,
323221345Sdim    /// * either has no non-static data members in the most derived class and at
324221345Sdim    ///   most one base class with non-static data members, or has no base
325221345Sdim    ///   classes with non-static data members, and
326221345Sdim    /// * has no base classes of the same type as the first non-static data
327221345Sdim    ///   member.
328221345Sdim    bool IsStandardLayout : 1;
329221345Sdim
330221345Sdim    /// HasNoNonEmptyBases - True when there are no non-empty base classes.
331221345Sdim    ///
332221345Sdim    /// This is a helper bit of state used to implement IsStandardLayout more
333221345Sdim    /// efficiently.
334221345Sdim    bool HasNoNonEmptyBases : 1;
335221345Sdim
336221345Sdim    /// HasPrivateFields - True when there are private non-static data members.
337221345Sdim    bool HasPrivateFields : 1;
338221345Sdim
339221345Sdim    /// HasProtectedFields - True when there are protected non-static data
340221345Sdim    /// members.
341221345Sdim    bool HasProtectedFields : 1;
342221345Sdim
343221345Sdim    /// HasPublicFields - True when there are private non-static data members.
344221345Sdim    bool HasPublicFields : 1;
345221345Sdim
346223017Sdim    /// \brief True if this class (or any subobject) has mutable fields.
347223017Sdim    bool HasMutableFields : 1;
348234353Sdim
349234353Sdim    /// \brief True if there no non-field members declared by the user.
350234353Sdim    bool HasOnlyCMembers : 1;
351234353Sdim
352239462Sdim    /// \brief True if any field has an in-class initializer.
353239462Sdim    bool HasInClassInitializer : 1;
354239462Sdim
355249423Sdim    /// \brief True if any field is of reference type, and does not have an
356249423Sdim    /// in-class initializer. In this case, value-initialization of this class
357249423Sdim    /// is illegal in C++98 even if the class has a trivial default constructor.
358249423Sdim    bool HasUninitializedReferenceMember : 1;
359249423Sdim
360249423Sdim    /// \brief These flags are \c true if a defaulted corresponding special
361249423Sdim    /// member can't be fully analyzed without performing overload resolution.
362249423Sdim    /// @{
363249423Sdim    bool NeedOverloadResolutionForMoveConstructor : 1;
364249423Sdim    bool NeedOverloadResolutionForMoveAssignment : 1;
365249423Sdim    bool NeedOverloadResolutionForDestructor : 1;
366249423Sdim    /// @}
367249423Sdim
368249423Sdim    /// \brief These flags are \c true if an implicit defaulted corresponding
369249423Sdim    /// special member would be defined as deleted.
370249423Sdim    /// @{
371249423Sdim    bool DefaultedMoveConstructorIsDeleted : 1;
372249423Sdim    bool DefaultedMoveAssignmentIsDeleted : 1;
373249423Sdim    bool DefaultedDestructorIsDeleted : 1;
374249423Sdim    /// @}
375249423Sdim
376249423Sdim    /// \brief The trivial special members which this class has, per
377249423Sdim    /// C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25,
378249423Sdim    /// C++11 [class.dtor]p5, or would have if the member were not suppressed.
379203955Srdivacky    ///
380249423Sdim    /// This excludes any user-declared but not user-provided special members
381249423Sdim    /// which have been declared but not yet defined.
382249423Sdim    unsigned HasTrivialSpecialMembers : 6;
383198092Srdivacky
384249423Sdim    /// \brief The declared special members of this class which are known to be
385249423Sdim    /// non-trivial.
386249423Sdim    ///
387249423Sdim    /// This excludes any user-declared but not user-provided special members
388249423Sdim    /// which have been declared but not yet defined, and any implicit special
389249423Sdim    /// members which have not yet been declared.
390249423Sdim    unsigned DeclaredNonTrivialSpecialMembers : 6;
391249423Sdim
392249423Sdim    /// HasIrrelevantDestructor - True when this class has a destructor with no
393249423Sdim    /// semantic effect.
394249423Sdim    bool HasIrrelevantDestructor : 1;
395249423Sdim
396226633Sdim    /// HasConstexprNonCopyMoveConstructor - True when this class has at least
397234353Sdim    /// one user-declared constexpr constructor which is neither the copy nor
398234353Sdim    /// move constructor.
399226633Sdim    bool HasConstexprNonCopyMoveConstructor : 1;
400221345Sdim
401234353Sdim    /// DefaultedDefaultConstructorIsConstexpr - True if a defaulted default
402234353Sdim    /// constructor for this class would be constexpr.
403234353Sdim    bool DefaultedDefaultConstructorIsConstexpr : 1;
404234353Sdim
405234353Sdim    /// HasConstexprDefaultConstructor - True if this class has a constexpr
406234353Sdim    /// default constructor (either user-declared or implicitly declared).
407234353Sdim    bool HasConstexprDefaultConstructor : 1;
408234353Sdim
409221345Sdim    /// HasNonLiteralTypeFieldsOrBases - True when this class contains at least
410234353Sdim    /// one non-static data member or base class of non-literal or volatile
411234353Sdim    /// type.
412221345Sdim    bool HasNonLiteralTypeFieldsOrBases : 1;
413221345Sdim
414203955Srdivacky    /// ComputedVisibleConversions - True when visible conversion functions are
415203955Srdivacky    /// already computed and are available.
416203955Srdivacky    bool ComputedVisibleConversions : 1;
417210299Sed
418249423Sdim    /// \brief Whether we have a C++11 user-provided default constructor (not
419223017Sdim    /// explicitly deleted or defaulted).
420223017Sdim    bool UserProvidedDefaultConstructor : 1;
421223017Sdim
422249423Sdim    /// \brief The special members which have been declared for this class,
423249423Sdim    /// either by the user or implicitly.
424249423Sdim    unsigned DeclaredSpecialMembers : 6;
425210299Sed
426249423Sdim    /// \brief Whether an implicit copy constructor would have a const-qualified
427249423Sdim    /// parameter.
428249423Sdim    bool ImplicitCopyConstructorHasConstParam : 1;
429223017Sdim
430249423Sdim    /// \brief Whether an implicit copy assignment operator would have a
431249423Sdim    /// const-qualified parameter.
432249423Sdim    bool ImplicitCopyAssignmentHasConstParam : 1;
433234353Sdim
434249423Sdim    /// \brief Whether any declared copy constructor has a const-qualified
435249423Sdim    /// parameter.
436249423Sdim    bool HasDeclaredCopyConstructorWithConstParam : 1;
437223017Sdim
438249423Sdim    /// \brief Whether any declared copy assignment operator has either a
439249423Sdim    /// const-qualified reference parameter or a non-reference parameter.
440249423Sdim    bool HasDeclaredCopyAssignmentWithConstParam : 1;
441234353Sdim
442226633Sdim    /// \brief Whether an implicit move constructor was attempted to be declared
443226633Sdim    /// but would have been deleted.
444226633Sdim    bool FailedImplicitMoveConstructor : 1;
445226633Sdim
446226633Sdim    /// \brief Whether an implicit move assignment operator was attempted to be
447226633Sdim    /// declared but would have been deleted.
448226633Sdim    bool FailedImplicitMoveAssignment : 1;
449226633Sdim
450234353Sdim    /// \brief Whether this class describes a C++ lambda.
451234353Sdim    bool IsLambda : 1;
452234353Sdim
453218893Sdim    /// NumBases - The number of base class specifiers in Bases.
454218893Sdim    unsigned NumBases;
455234353Sdim
456218893Sdim    /// NumVBases - The number of virtual base class specifiers in VBases.
457218893Sdim    unsigned NumVBases;
458218893Sdim
459203955Srdivacky    /// Bases - Base classes of this class.
460203955Srdivacky    /// FIXME: This is wasted space for a union.
461218893Sdim    LazyCXXBaseSpecifiersPtr Bases;
462193326Sed
463203955Srdivacky    /// VBases - direct and indirect virtual base classes of this class.
464218893Sdim    LazyCXXBaseSpecifiersPtr VBases;
465198092Srdivacky
466203955Srdivacky    /// Conversions - Overload set containing the conversion functions
467203955Srdivacky    /// of this C++ class (but not its inherited conversion
468203955Srdivacky    /// functions). Each of the entries in this overload set is a
469203955Srdivacky    /// CXXConversionDecl.
470249423Sdim    ASTUnresolvedSet Conversions;
471193326Sed
472203955Srdivacky    /// VisibleConversions - Overload set containing the conversion
473203955Srdivacky    /// functions of this C++ class and all those inherited conversion
474203955Srdivacky    /// functions that are visible in this class. Each of the entries
475203955Srdivacky    /// in this overload set is a CXXConversionDecl or a
476203955Srdivacky    /// FunctionTemplateDecl.
477249423Sdim    ASTUnresolvedSet VisibleConversions;
478203955Srdivacky
479203955Srdivacky    /// Definition - The declaration which defines this record.
480203955Srdivacky    CXXRecordDecl *Definition;
481203955Srdivacky
482205219Srdivacky    /// FirstFriend - The first friend declaration in this class, or
483205219Srdivacky    /// null if there aren't any.  This is actually currently stored
484205219Srdivacky    /// in reverse order.
485205219Srdivacky    FriendDecl *FirstFriend;
486205219Srdivacky
487234353Sdim    /// \brief Retrieve the set of direct base classes.
488218893Sdim    CXXBaseSpecifier *getBases() const {
489239462Sdim      if (!Bases.isOffset())
490239462Sdim        return Bases.get(0);
491239462Sdim      return getBasesSlowCase();
492218893Sdim    }
493218893Sdim
494234353Sdim    /// \brief Retrieve the set of virtual base classes.
495218893Sdim    CXXBaseSpecifier *getVBases() const {
496239462Sdim      if (!VBases.isOffset())
497239462Sdim        return VBases.get(0);
498239462Sdim      return getVBasesSlowCase();
499218893Sdim    }
500239462Sdim
501239462Sdim  private:
502239462Sdim    CXXBaseSpecifier *getBasesSlowCase() const;
503239462Sdim    CXXBaseSpecifier *getVBasesSlowCase() const;
504203955Srdivacky  } *DefinitionData;
505203955Srdivacky
506234353Sdim  /// \brief Describes a C++ closure type (generated by a lambda expression).
507234353Sdim  struct LambdaDefinitionData : public DefinitionData {
508234353Sdim    typedef LambdaExpr::Capture Capture;
509234353Sdim
510243830Sdim    LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent)
511234353Sdim      : DefinitionData(D), Dependent(Dependent), NumCaptures(0),
512243830Sdim        NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0),
513243830Sdim        MethodTyInfo(Info)
514234353Sdim    {
515234353Sdim      IsLambda = true;
516234353Sdim    }
517234353Sdim
518234353Sdim    /// \brief Whether this lambda is known to be dependent, even if its
519234353Sdim    /// context isn't dependent.
520234353Sdim    ///
521234353Sdim    /// A lambda with a non-dependent context can be dependent if it occurs
522234353Sdim    /// within the default argument of a function template, because the
523234353Sdim    /// lambda will have been created with the enclosing context as its
524234353Sdim    /// declaration context, rather than function. This is an unfortunate
525234353Sdim    /// artifact of having to parse the default arguments before
526234353Sdim    unsigned Dependent : 1;
527234353Sdim
528234353Sdim    /// \brief The number of captures in this lambda.
529234353Sdim    unsigned NumCaptures : 16;
530234353Sdim
531234353Sdim    /// \brief The number of explicit captures in this lambda.
532234353Sdim    unsigned NumExplicitCaptures : 15;
533234353Sdim
534234353Sdim    /// \brief The number used to indicate this lambda expression for name
535234353Sdim    /// mangling in the Itanium C++ ABI.
536234353Sdim    unsigned ManglingNumber;
537234353Sdim
538234353Sdim    /// \brief The declaration that provides context for this lambda, if the
539234353Sdim    /// actual DeclContext does not suffice. This is used for lambdas that
540234353Sdim    /// occur within default arguments of function parameters within the class
541234353Sdim    /// or within a data member initializer.
542234353Sdim    Decl *ContextDecl;
543234353Sdim
544234353Sdim    /// \brief The list of captures, both explicit and implicit, for this
545234353Sdim    /// lambda.
546243830Sdim    Capture *Captures;
547243830Sdim
548243830Sdim    /// \brief The type of the call method.
549243830Sdim    TypeSourceInfo *MethodTyInfo;
550234353Sdim  };
551234353Sdim
552203955Srdivacky  struct DefinitionData &data() {
553203955Srdivacky    assert(DefinitionData && "queried property of class with no definition");
554203955Srdivacky    return *DefinitionData;
555203955Srdivacky  }
556203955Srdivacky
557203955Srdivacky  const struct DefinitionData &data() const {
558203955Srdivacky    assert(DefinitionData && "queried property of class with no definition");
559203955Srdivacky    return *DefinitionData;
560203955Srdivacky  }
561234353Sdim
562234353Sdim  struct LambdaDefinitionData &getLambdaData() const {
563234353Sdim    assert(DefinitionData && "queried property of lambda with no definition");
564234353Sdim    assert(DefinitionData->IsLambda &&
565234353Sdim           "queried lambda property of non-lambda class");
566234353Sdim    return static_cast<LambdaDefinitionData &>(*DefinitionData);
567234353Sdim  }
568198092Srdivacky
569193326Sed  /// \brief The template or declaration that this declaration
570193326Sed  /// describes or was instantiated from, respectively.
571198092Srdivacky  ///
572193326Sed  /// For non-templates, this value will be NULL. For record
573193326Sed  /// declarations that describe a class template, this will be a
574193326Sed  /// pointer to a ClassTemplateDecl. For member
575193326Sed  /// classes of class template specializations, this will be the
576234353Sdim  /// MemberSpecializationInfo referring to the member class that was
577198092Srdivacky  /// instantiated or specialized.
578198092Srdivacky  llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*>
579193326Sed    TemplateOrInstantiation;
580206084Srdivacky
581218893Sdim  friend class DeclContext;
582234353Sdim  friend class LambdaExpr;
583234353Sdim
584249423Sdim  /// \brief Called from setBases and addedMember to notify the class that a
585249423Sdim  /// direct or virtual base class or a member of class type has been added.
586249423Sdim  void addedClassSubobject(CXXRecordDecl *Base);
587249423Sdim
588218893Sdim  /// \brief Notify the class that member has been added.
589218893Sdim  ///
590234353Sdim  /// This routine helps maintain information about the class based on which
591218893Sdim  /// members have been added. It will be invoked by DeclContext::addDecl()
592218893Sdim  /// whenever a member is added to this record.
593218893Sdim  void addedMember(Decl *D);
594218893Sdim
595218893Sdim  void markedVirtualFunctionPure();
596218893Sdim  friend void FunctionDecl::setPure(bool);
597234353Sdim
598234353Sdim  friend class ASTNodeImporter;
599234353Sdim
600193326Sedprotected:
601193326Sed  CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
602221345Sdim                SourceLocation StartLoc, SourceLocation IdLoc,
603221345Sdim                IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
604193326Sed
605193326Sedpublic:
606193326Sed  /// base_class_iterator - Iterator that traverses the base classes
607198092Srdivacky  /// of a class.
608193326Sed  typedef CXXBaseSpecifier*       base_class_iterator;
609193326Sed
610193326Sed  /// base_class_const_iterator - Iterator that traverses the base
611198092Srdivacky  /// classes of a class.
612193326Sed  typedef const CXXBaseSpecifier* base_class_const_iterator;
613193326Sed
614198092Srdivacky  /// reverse_base_class_iterator = Iterator that traverses the base classes
615198092Srdivacky  /// of a class in reverse order.
616198092Srdivacky  typedef std::reverse_iterator<base_class_iterator>
617198092Srdivacky    reverse_base_class_iterator;
618198092Srdivacky
619198092Srdivacky  /// reverse_base_class_iterator = Iterator that traverses the base classes
620198092Srdivacky  /// of a class in reverse order.
621198092Srdivacky  typedef std::reverse_iterator<base_class_const_iterator>
622198092Srdivacky    reverse_base_class_const_iterator;
623198092Srdivacky
624198092Srdivacky  virtual CXXRecordDecl *getCanonicalDecl() {
625198092Srdivacky    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
626198092Srdivacky  }
627199482Srdivacky  virtual const CXXRecordDecl *getCanonicalDecl() const {
628199482Srdivacky    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
629199482Srdivacky  }
630234353Sdim
631234353Sdim  const CXXRecordDecl *getPreviousDecl() const {
632234353Sdim    return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDecl());
633210299Sed  }
634234353Sdim  CXXRecordDecl *getPreviousDecl() {
635234353Sdim    return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDecl());
636210299Sed  }
637198092Srdivacky
638234353Sdim  const CXXRecordDecl *getMostRecentDecl() const {
639234353Sdim    return cast_or_null<CXXRecordDecl>(RecordDecl::getMostRecentDecl());
640234353Sdim  }
641234353Sdim  CXXRecordDecl *getMostRecentDecl() {
642234353Sdim    return cast_or_null<CXXRecordDecl>(RecordDecl::getMostRecentDecl());
643234353Sdim  }
644234353Sdim
645203955Srdivacky  CXXRecordDecl *getDefinition() const {
646203955Srdivacky    if (!DefinitionData) return 0;
647203955Srdivacky    return data().Definition;
648203955Srdivacky  }
649203955Srdivacky
650203955Srdivacky  bool hasDefinition() const { return DefinitionData != 0; }
651203955Srdivacky
652218893Sdim  static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
653221345Sdim                               SourceLocation StartLoc, SourceLocation IdLoc,
654221345Sdim                               IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0,
655193326Sed                               bool DelayTypeCreation = false);
656234353Sdim  static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
657243830Sdim                                     TypeSourceInfo *Info, SourceLocation Loc,
658243830Sdim                                     bool DependentLambda);
659234353Sdim  static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
660198092Srdivacky
661198092Srdivacky  bool isDynamicClass() const {
662203955Srdivacky    return data().Polymorphic || data().NumVBases != 0;
663198092Srdivacky  }
664198092Srdivacky
665193326Sed  /// setBases - Sets the base classes of this struct or class.
666203955Srdivacky  void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
667193326Sed
668193326Sed  /// getNumBases - Retrieves the number of base classes of this
669193326Sed  /// class.
670203955Srdivacky  unsigned getNumBases() const { return data().NumBases; }
671193326Sed
672218893Sdim  base_class_iterator bases_begin() { return data().getBases(); }
673218893Sdim  base_class_const_iterator bases_begin() const { return data().getBases(); }
674203955Srdivacky  base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
675203955Srdivacky  base_class_const_iterator bases_end() const {
676203955Srdivacky    return bases_begin() + data().NumBases;
677203955Srdivacky  }
678198092Srdivacky  reverse_base_class_iterator       bases_rbegin() {
679198092Srdivacky    return reverse_base_class_iterator(bases_end());
680198092Srdivacky  }
681198092Srdivacky  reverse_base_class_const_iterator bases_rbegin() const {
682198092Srdivacky    return reverse_base_class_const_iterator(bases_end());
683198092Srdivacky  }
684198092Srdivacky  reverse_base_class_iterator bases_rend() {
685198092Srdivacky    return reverse_base_class_iterator(bases_begin());
686198092Srdivacky  }
687198092Srdivacky  reverse_base_class_const_iterator bases_rend() const {
688198092Srdivacky    return reverse_base_class_const_iterator(bases_begin());
689198092Srdivacky  }
690193326Sed
691198092Srdivacky  /// getNumVBases - Retrieves the number of virtual base classes of this
692198092Srdivacky  /// class.
693203955Srdivacky  unsigned getNumVBases() const { return data().NumVBases; }
694198092Srdivacky
695218893Sdim  base_class_iterator vbases_begin() { return data().getVBases(); }
696218893Sdim  base_class_const_iterator vbases_begin() const { return data().getVBases(); }
697203955Srdivacky  base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
698203955Srdivacky  base_class_const_iterator vbases_end() const {
699203955Srdivacky    return vbases_begin() + data().NumVBases;
700203955Srdivacky  }
701198092Srdivacky  reverse_base_class_iterator vbases_rbegin() {
702198092Srdivacky    return reverse_base_class_iterator(vbases_end());
703198092Srdivacky  }
704198092Srdivacky  reverse_base_class_const_iterator vbases_rbegin() const {
705198092Srdivacky    return reverse_base_class_const_iterator(vbases_end());
706198092Srdivacky  }
707198092Srdivacky  reverse_base_class_iterator vbases_rend() {
708198092Srdivacky    return reverse_base_class_iterator(vbases_begin());
709198092Srdivacky  }
710198092Srdivacky  reverse_base_class_const_iterator vbases_rend() const {
711198092Srdivacky    return reverse_base_class_const_iterator(vbases_begin());
712198092Srdivacky }
713198092Srdivacky
714249423Sdim  /// \brief Determine whether this class has any dependent base classes which
715249423Sdim  /// are not the current instantiation.
716202379Srdivacky  bool hasAnyDependentBases() const;
717202379Srdivacky
718198092Srdivacky  /// Iterator access to method members.  The method iterator visits
719198092Srdivacky  /// all method members of the class, including non-instance methods,
720198092Srdivacky  /// special methods, etc.
721198092Srdivacky  typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
722198092Srdivacky
723198092Srdivacky  /// method_begin - Method begin iterator.  Iterates in the order the methods
724198092Srdivacky  /// were declared.
725198092Srdivacky  method_iterator method_begin() const {
726198092Srdivacky    return method_iterator(decls_begin());
727198092Srdivacky  }
728198092Srdivacky  /// method_end - Method end iterator.
729198092Srdivacky  method_iterator method_end() const {
730198092Srdivacky    return method_iterator(decls_end());
731198092Srdivacky  }
732198092Srdivacky
733198092Srdivacky  /// Iterator access to constructor members.
734198092Srdivacky  typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
735198092Srdivacky
736198092Srdivacky  ctor_iterator ctor_begin() const {
737198092Srdivacky    return ctor_iterator(decls_begin());
738198092Srdivacky  }
739198092Srdivacky  ctor_iterator ctor_end() const {
740198092Srdivacky    return ctor_iterator(decls_end());
741198092Srdivacky  }
742198092Srdivacky
743205219Srdivacky  /// An iterator over friend declarations.  All of these are defined
744205219Srdivacky  /// in DeclFriend.h.
745205219Srdivacky  class friend_iterator;
746205219Srdivacky  friend_iterator friend_begin() const;
747205219Srdivacky  friend_iterator friend_end() const;
748205219Srdivacky  void pushFriendDecl(FriendDecl *FD);
749205219Srdivacky
750207619Srdivacky  /// Determines whether this record has any friends.
751207619Srdivacky  bool hasFriends() const {
752207619Srdivacky    return data().FirstFriend != 0;
753207619Srdivacky  }
754207619Srdivacky
755249423Sdim  /// \brief \c true if we know for sure that this class has a single,
756249423Sdim  /// accessible, unambiguous move constructor that is not deleted.
757249423Sdim  bool hasSimpleMoveConstructor() const {
758249423Sdim    return !hasUserDeclaredMoveConstructor() && hasMoveConstructor();
759249423Sdim  }
760249423Sdim  /// \brief \c true if we know for sure that this class has a single,
761249423Sdim  /// accessible, unambiguous move assignment operator that is not deleted.
762249423Sdim  bool hasSimpleMoveAssignment() const {
763249423Sdim    return !hasUserDeclaredMoveAssignment() && hasMoveAssignment();
764249423Sdim  }
765249423Sdim  /// \brief \c true if we know for sure that this class has an accessible
766249423Sdim  /// destructor that is not deleted.
767249423Sdim  bool hasSimpleDestructor() const {
768249423Sdim    return !hasUserDeclaredDestructor() &&
769249423Sdim           !data().DefaultedDestructorIsDeleted;
770249423Sdim  }
771249423Sdim
772249423Sdim  /// \brief Determine whether this class has any default constructors.
773249423Sdim  bool hasDefaultConstructor() const {
774249423Sdim    return (data().DeclaredSpecialMembers & SMF_DefaultConstructor) ||
775249423Sdim           needsImplicitDefaultConstructor();
776249423Sdim  }
777249423Sdim
778223017Sdim  /// \brief Determine if we need to declare a default constructor for
779223017Sdim  /// this class.
780210299Sed  ///
781210299Sed  /// This value is used for lazy creation of default constructors.
782223017Sdim  bool needsImplicitDefaultConstructor() const {
783234353Sdim    return !data().UserDeclaredConstructor &&
784249423Sdim           !(data().DeclaredSpecialMembers & SMF_DefaultConstructor);
785223017Sdim  }
786223017Sdim
787193326Sed  /// hasUserDeclaredConstructor - Whether this class has any
788193326Sed  /// user-declared constructors. When true, a default constructor
789193326Sed  /// will not be implicitly declared.
790198092Srdivacky  bool hasUserDeclaredConstructor() const {
791203955Srdivacky    return data().UserDeclaredConstructor;
792198092Srdivacky  }
793193326Sed
794223017Sdim  /// hasUserProvidedDefaultconstructor - Whether this class has a
795223017Sdim  /// user-provided default constructor per C++0x.
796223017Sdim  bool hasUserProvidedDefaultConstructor() const {
797223017Sdim    return data().UserProvidedDefaultConstructor;
798223017Sdim  }
799223017Sdim
800193326Sed  /// hasUserDeclaredCopyConstructor - Whether this class has a
801193326Sed  /// user-declared copy constructor. When false, a copy constructor
802193326Sed  /// will be implicitly declared.
803193326Sed  bool hasUserDeclaredCopyConstructor() const {
804249423Sdim    return data().UserDeclaredSpecialMembers & SMF_CopyConstructor;
805193326Sed  }
806193326Sed
807249423Sdim  /// \brief Determine whether this class needs an implicit copy
808249423Sdim  /// constructor to be lazily declared.
809249423Sdim  bool needsImplicitCopyConstructor() const {
810249423Sdim    return !(data().DeclaredSpecialMembers & SMF_CopyConstructor);
811210299Sed  }
812223017Sdim
813249423Sdim  /// \brief Determine whether we need to eagerly declare a defaulted copy
814249423Sdim  /// constructor for this class.
815249423Sdim  bool needsOverloadResolutionForCopyConstructor() const {
816249423Sdim    return data().HasMutableFields;
817249423Sdim  }
818249423Sdim
819249423Sdim  /// \brief Determine whether an implicit copy constructor for this type
820249423Sdim  /// would have a parameter with a const-qualified reference type.
821249423Sdim  bool implicitCopyConstructorHasConstParam() const {
822249423Sdim    return data().ImplicitCopyConstructorHasConstParam;
823249423Sdim  }
824249423Sdim
825249423Sdim  /// \brief Determine whether this class has a copy constructor with
826249423Sdim  /// a parameter type which is a reference to a const-qualified type.
827249423Sdim  bool hasCopyConstructorWithConstParam() const {
828249423Sdim    return data().HasDeclaredCopyConstructorWithConstParam ||
829249423Sdim           (needsImplicitCopyConstructor() &&
830249423Sdim            implicitCopyConstructorHasConstParam());
831249423Sdim  }
832249423Sdim
833223017Sdim  /// hasUserDeclaredMoveOperation - Whether this class has a user-
834223017Sdim  /// declared move constructor or assignment operator. When false, a
835223017Sdim  /// move constructor and assignment operator may be implicitly declared.
836223017Sdim  bool hasUserDeclaredMoveOperation() const {
837249423Sdim    return data().UserDeclaredSpecialMembers &
838249423Sdim             (SMF_MoveConstructor | SMF_MoveAssignment);
839223017Sdim  }
840223017Sdim
841223017Sdim  /// \brief Determine whether this class has had a move constructor
842223017Sdim  /// declared by the user.
843223017Sdim  bool hasUserDeclaredMoveConstructor() const {
844249423Sdim    return data().UserDeclaredSpecialMembers & SMF_MoveConstructor;
845223017Sdim  }
846223017Sdim
847249423Sdim  /// \brief Determine whether this class has a move constructor.
848249423Sdim  bool hasMoveConstructor() const {
849249423Sdim    return (data().DeclaredSpecialMembers & SMF_MoveConstructor) ||
850249423Sdim           needsImplicitMoveConstructor();
851223017Sdim  }
852223017Sdim
853226633Sdim  /// \brief Determine whether implicit move constructor generation for this
854226633Sdim  /// class has failed before.
855226633Sdim  bool hasFailedImplicitMoveConstructor() const {
856226633Sdim    return data().FailedImplicitMoveConstructor;
857226633Sdim  }
858226633Sdim
859226633Sdim  /// \brief Set whether implicit move constructor generation for this class
860226633Sdim  /// has failed before.
861226633Sdim  void setFailedImplicitMoveConstructor(bool Failed = true) {
862226633Sdim    data().FailedImplicitMoveConstructor = Failed;
863226633Sdim  }
864226633Sdim
865226633Sdim  /// \brief Determine whether this class should get an implicit move
866226633Sdim  /// constructor or if any existing special member function inhibits this.
867226633Sdim  bool needsImplicitMoveConstructor() const {
868226633Sdim    return !hasFailedImplicitMoveConstructor() &&
869249423Sdim           !(data().DeclaredSpecialMembers & SMF_MoveConstructor) &&
870226633Sdim           !hasUserDeclaredCopyConstructor() &&
871226633Sdim           !hasUserDeclaredCopyAssignment() &&
872226633Sdim           !hasUserDeclaredMoveAssignment() &&
873249423Sdim           !hasUserDeclaredDestructor() &&
874249423Sdim           !data().DefaultedMoveConstructorIsDeleted;
875226633Sdim  }
876226633Sdim
877249423Sdim  /// \brief Determine whether we need to eagerly declare a defaulted move
878249423Sdim  /// constructor for this class.
879249423Sdim  bool needsOverloadResolutionForMoveConstructor() const {
880249423Sdim    return data().NeedOverloadResolutionForMoveConstructor;
881249423Sdim  }
882249423Sdim
883193326Sed  /// hasUserDeclaredCopyAssignment - Whether this class has a
884193326Sed  /// user-declared copy assignment operator. When false, a copy
885193326Sed  /// assigment operator will be implicitly declared.
886193326Sed  bool hasUserDeclaredCopyAssignment() const {
887249423Sdim    return data().UserDeclaredSpecialMembers & SMF_CopyAssignment;
888193326Sed  }
889193326Sed
890249423Sdim  /// \brief Determine whether this class needs an implicit copy
891249423Sdim  /// assignment operator to be lazily declared.
892249423Sdim  bool needsImplicitCopyAssignment() const {
893249423Sdim    return !(data().DeclaredSpecialMembers & SMF_CopyAssignment);
894210299Sed  }
895223017Sdim
896249423Sdim  /// \brief Determine whether we need to eagerly declare a defaulted copy
897249423Sdim  /// assignment operator for this class.
898249423Sdim  bool needsOverloadResolutionForCopyAssignment() const {
899249423Sdim    return data().HasMutableFields;
900249423Sdim  }
901249423Sdim
902249423Sdim  /// \brief Determine whether an implicit copy assignment operator for this
903249423Sdim  /// type would have a parameter with a const-qualified reference type.
904249423Sdim  bool implicitCopyAssignmentHasConstParam() const {
905249423Sdim    return data().ImplicitCopyAssignmentHasConstParam;
906249423Sdim  }
907249423Sdim
908249423Sdim  /// \brief Determine whether this class has a copy assignment operator with
909249423Sdim  /// a parameter type which is a reference to a const-qualified type or is not
910249423Sdim  /// a reference..
911249423Sdim  bool hasCopyAssignmentWithConstParam() const {
912249423Sdim    return data().HasDeclaredCopyAssignmentWithConstParam ||
913249423Sdim           (needsImplicitCopyAssignment() &&
914249423Sdim            implicitCopyAssignmentHasConstParam());
915249423Sdim  }
916249423Sdim
917223017Sdim  /// \brief Determine whether this class has had a move assignment
918223017Sdim  /// declared by the user.
919223017Sdim  bool hasUserDeclaredMoveAssignment() const {
920249423Sdim    return data().UserDeclaredSpecialMembers & SMF_MoveAssignment;
921223017Sdim  }
922223017Sdim
923249423Sdim  /// \brief Determine whether this class has a move assignment operator.
924249423Sdim  bool hasMoveAssignment() const {
925249423Sdim    return (data().DeclaredSpecialMembers & SMF_MoveAssignment) ||
926249423Sdim           needsImplicitMoveAssignment();
927223017Sdim  }
928223017Sdim
929226633Sdim  /// \brief Determine whether implicit move assignment generation for this
930226633Sdim  /// class has failed before.
931226633Sdim  bool hasFailedImplicitMoveAssignment() const {
932226633Sdim    return data().FailedImplicitMoveAssignment;
933226633Sdim  }
934226633Sdim
935226633Sdim  /// \brief Set whether implicit move assignment generation for this class
936226633Sdim  /// has failed before.
937226633Sdim  void setFailedImplicitMoveAssignment(bool Failed = true) {
938226633Sdim    data().FailedImplicitMoveAssignment = Failed;
939226633Sdim  }
940226633Sdim
941226633Sdim  /// \brief Determine whether this class should get an implicit move
942226633Sdim  /// assignment operator or if any existing special member function inhibits
943226633Sdim  /// this.
944226633Sdim  bool needsImplicitMoveAssignment() const {
945226633Sdim    return !hasFailedImplicitMoveAssignment() &&
946249423Sdim           !(data().DeclaredSpecialMembers & SMF_MoveAssignment) &&
947226633Sdim           !hasUserDeclaredCopyConstructor() &&
948226633Sdim           !hasUserDeclaredCopyAssignment() &&
949226633Sdim           !hasUserDeclaredMoveConstructor() &&
950249423Sdim           !hasUserDeclaredDestructor() &&
951249423Sdim           !data().DefaultedMoveAssignmentIsDeleted;
952226633Sdim  }
953226633Sdim
954249423Sdim  /// \brief Determine whether we need to eagerly declare a move assignment
955249423Sdim  /// operator for this class.
956249423Sdim  bool needsOverloadResolutionForMoveAssignment() const {
957249423Sdim    return data().NeedOverloadResolutionForMoveAssignment;
958249423Sdim  }
959249423Sdim
960193326Sed  /// hasUserDeclaredDestructor - Whether this class has a
961193326Sed  /// user-declared destructor. When false, a destructor will be
962193326Sed  /// implicitly declared.
963203955Srdivacky  bool hasUserDeclaredDestructor() const {
964249423Sdim    return data().UserDeclaredSpecialMembers & SMF_Destructor;
965203955Srdivacky  }
966193326Sed
967249423Sdim  /// \brief Determine whether this class needs an implicit destructor to
968249423Sdim  /// be lazily declared.
969249423Sdim  bool needsImplicitDestructor() const {
970249423Sdim    return !(data().DeclaredSpecialMembers & SMF_Destructor);
971249423Sdim  }
972218893Sdim
973249423Sdim  /// \brief Determine whether we need to eagerly declare a destructor for this
974249423Sdim  /// class.
975249423Sdim  bool needsOverloadResolutionForDestructor() const {
976249423Sdim    return data().NeedOverloadResolutionForDestructor;
977249423Sdim  }
978249423Sdim
979234353Sdim  /// \brief Determine whether this class describes a lambda function object.
980234353Sdim  bool isLambda() const { return hasDefinition() && data().IsLambda; }
981249423Sdim
982234353Sdim  /// \brief For a closure type, retrieve the mapping from captured
983234353Sdim  /// variables and this to the non-static data members that store the
984234353Sdim  /// values or references of the captures.
985234353Sdim  ///
986234353Sdim  /// \param Captures Will be populated with the mapping from captured
987234353Sdim  /// variables to the corresponding fields.
988234353Sdim  ///
989234353Sdim  /// \param ThisCapture Will be set to the field declaration for the
990234353Sdim  /// 'this' capture.
991234353Sdim  void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
992234353Sdim                        FieldDecl *&ThisCapture) const;
993234353Sdim
994234353Sdim  typedef const LambdaExpr::Capture* capture_const_iterator;
995234353Sdim  capture_const_iterator captures_begin() const {
996234353Sdim    return isLambda() ? getLambdaData().Captures : NULL;
997234353Sdim  }
998234353Sdim  capture_const_iterator captures_end() const {
999234353Sdim    return isLambda() ? captures_begin() + getLambdaData().NumCaptures : NULL;
1000234353Sdim  }
1001234353Sdim
1002249423Sdim  typedef UnresolvedSetIterator conversion_iterator;
1003203955Srdivacky  conversion_iterator conversion_begin() const {
1004249423Sdim    return data().Conversions.begin();
1005203955Srdivacky  }
1006203955Srdivacky  conversion_iterator conversion_end() const {
1007249423Sdim    return data().Conversions.end();
1008203955Srdivacky  }
1009199990Srdivacky
1010206084Srdivacky  /// Removes a conversion function from this class.  The conversion
1011206084Srdivacky  /// function must currently be a member of this class.  Furthermore,
1012206084Srdivacky  /// this class must currently be in the process of being defined.
1013206084Srdivacky  void removeConversion(const NamedDecl *Old);
1014206084Srdivacky
1015198092Srdivacky  /// getVisibleConversionFunctions - get all conversion functions visible
1016198092Srdivacky  /// in current class; including conversion function templates.
1017249423Sdim  std::pair<conversion_iterator, conversion_iterator>
1018249423Sdim    getVisibleConversionFunctions();
1019199990Srdivacky
1020193326Sed  /// isAggregate - Whether this class is an aggregate (C++
1021193326Sed  /// [dcl.init.aggr]), which is a class with no user-declared
1022193326Sed  /// constructors, no private or protected non-static data members,
1023193326Sed  /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
1024203955Srdivacky  bool isAggregate() const { return data().Aggregate; }
1025193326Sed
1026239462Sdim  /// hasInClassInitializer - Whether this class has any in-class initializers
1027239462Sdim  /// for non-static data members.
1028239462Sdim  bool hasInClassInitializer() const { return data().HasInClassInitializer; }
1029239462Sdim
1030249423Sdim  /// \brief Whether this class or any of its subobjects has any members of
1031249423Sdim  /// reference type which would make value-initialization ill-formed, per
1032249423Sdim  /// C++03 [dcl.init]p5:
1033249423Sdim  ///  -- if T is a non-union class type without a user-declared constructor,
1034249423Sdim  ///     then every non-static data member and base-class component of T is
1035249423Sdim  ///     value-initialized
1036249423Sdim  /// [...]
1037249423Sdim  /// A program that calls for [...] value-initialization of an entity of
1038249423Sdim  /// reference type is ill-formed.
1039249423Sdim  bool hasUninitializedReferenceMember() const {
1040249423Sdim    return !isUnion() && !hasUserDeclaredConstructor() &&
1041249423Sdim           data().HasUninitializedReferenceMember;
1042249423Sdim  }
1043249423Sdim
1044193326Sed  /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
1045193326Sed  /// that is an aggregate that has no non-static non-POD data members, no
1046193326Sed  /// reference data members, no user-defined copy assignment operator and no
1047193326Sed  /// user-defined destructor.
1048249423Sdim  ///
1049249423Sdim  /// Note that this is the C++ TR1 definition of POD.
1050203955Srdivacky  bool isPOD() const { return data().PlainOldData; }
1051193326Sed
1052234353Sdim  /// \brief True if this class is C-like, without C++-specific features, e.g.
1053234353Sdim  /// it contains only public fields, no bases, tag kind is not 'class', etc.
1054234353Sdim  bool isCLike() const;
1055234353Sdim
1056198092Srdivacky  /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which
1057198092Srdivacky  /// means it has a virtual function, virtual base, data member (other than
1058198092Srdivacky  /// 0-width bit-field) or inherits from a non-empty class. Does NOT include
1059198092Srdivacky  /// a check for union-ness.
1060203955Srdivacky  bool isEmpty() const { return data().Empty; }
1061198092Srdivacky
1062193326Sed  /// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]),
1063193326Sed  /// which means that the class contains or inherits a virtual function.
1064203955Srdivacky  bool isPolymorphic() const { return data().Polymorphic; }
1065193326Sed
1066193326Sed  /// isAbstract - Whether this class is abstract (C++ [class.abstract]),
1067193326Sed  /// which means that the class contains or inherits a pure virtual function.
1068203955Srdivacky  bool isAbstract() const { return data().Abstract; }
1069198092Srdivacky
1070221345Sdim  /// isStandardLayout - Whether this class has standard layout
1071221345Sdim  /// (C++ [class]p7)
1072221345Sdim  bool isStandardLayout() const { return data().IsStandardLayout; }
1073221345Sdim
1074223017Sdim  /// \brief Whether this class, or any of its class subobjects, contains a
1075223017Sdim  /// mutable field.
1076223017Sdim  bool hasMutableFields() const { return data().HasMutableFields; }
1077234353Sdim
1078249423Sdim  /// \brief Determine whether this class has a trivial default constructor
1079249423Sdim  /// (C++11 [class.ctor]p5).
1080223017Sdim  bool hasTrivialDefaultConstructor() const {
1081249423Sdim    return hasDefaultConstructor() &&
1082249423Sdim           (data().HasTrivialSpecialMembers & SMF_DefaultConstructor);
1083223017Sdim  }
1084198092Srdivacky
1085249423Sdim  /// \brief Determine whether this class has a non-trivial default constructor
1086249423Sdim  /// (C++11 [class.ctor]p5).
1087249423Sdim  bool hasNonTrivialDefaultConstructor() const {
1088249423Sdim    return (data().DeclaredNonTrivialSpecialMembers & SMF_DefaultConstructor) ||
1089249423Sdim           (needsImplicitDefaultConstructor() &&
1090249423Sdim            !(data().HasTrivialSpecialMembers & SMF_DefaultConstructor));
1091249423Sdim  }
1092249423Sdim
1093249423Sdim  /// \brief Determine whether this class has at least one constexpr constructor
1094249423Sdim  /// other than the copy or move constructors.
1095226633Sdim  bool hasConstexprNonCopyMoveConstructor() const {
1096234353Sdim    return data().HasConstexprNonCopyMoveConstructor ||
1097249423Sdim           (needsImplicitDefaultConstructor() &&
1098234353Sdim            defaultedDefaultConstructorIsConstexpr());
1099221345Sdim  }
1100221345Sdim
1101249423Sdim  /// \brief Determine whether a defaulted default constructor for this class
1102249423Sdim  /// would be constexpr.
1103234353Sdim  bool defaultedDefaultConstructorIsConstexpr() const {
1104239462Sdim    return data().DefaultedDefaultConstructorIsConstexpr &&
1105239462Sdim           (!isUnion() || hasInClassInitializer());
1106234353Sdim  }
1107234353Sdim
1108249423Sdim  /// \brief Determine whether this class has a constexpr default constructor.
1109234353Sdim  bool hasConstexprDefaultConstructor() const {
1110234353Sdim    return data().HasConstexprDefaultConstructor ||
1111249423Sdim           (needsImplicitDefaultConstructor() &&
1112239462Sdim            defaultedDefaultConstructorIsConstexpr());
1113234353Sdim  }
1114234353Sdim
1115249423Sdim  /// \brief Determine whether this class has a trivial copy constructor
1116249423Sdim  /// (C++ [class.copy]p6, C++11 [class.copy]p12)
1117203955Srdivacky  bool hasTrivialCopyConstructor() const {
1118249423Sdim    return data().HasTrivialSpecialMembers & SMF_CopyConstructor;
1119203955Srdivacky  }
1120198092Srdivacky
1121249423Sdim  /// \brief Determine whether this class has a non-trivial copy constructor
1122249423Sdim  /// (C++ [class.copy]p6, C++11 [class.copy]p12)
1123249423Sdim  bool hasNonTrivialCopyConstructor() const {
1124249423Sdim    return data().DeclaredNonTrivialSpecialMembers & SMF_CopyConstructor ||
1125249423Sdim           !hasTrivialCopyConstructor();
1126249423Sdim  }
1127249423Sdim
1128249423Sdim  /// \brief Determine whether this class has a trivial move constructor
1129249423Sdim  /// (C++11 [class.copy]p12)
1130221345Sdim  bool hasTrivialMoveConstructor() const {
1131249423Sdim    return hasMoveConstructor() &&
1132249423Sdim           (data().HasTrivialSpecialMembers & SMF_MoveConstructor);
1133221345Sdim  }
1134221345Sdim
1135249423Sdim  /// \brief Determine whether this class has a non-trivial move constructor
1136249423Sdim  /// (C++11 [class.copy]p12)
1137249423Sdim  bool hasNonTrivialMoveConstructor() const {
1138249423Sdim    return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveConstructor) ||
1139249423Sdim           (needsImplicitMoveConstructor() &&
1140249423Sdim            !(data().HasTrivialSpecialMembers & SMF_MoveConstructor));
1141249423Sdim  }
1142249423Sdim
1143249423Sdim  /// \brief Determine whether this class has a trivial copy assignment operator
1144249423Sdim  /// (C++ [class.copy]p11, C++11 [class.copy]p25)
1145203955Srdivacky  bool hasTrivialCopyAssignment() const {
1146249423Sdim    return data().HasTrivialSpecialMembers & SMF_CopyAssignment;
1147203955Srdivacky  }
1148198092Srdivacky
1149249423Sdim  /// \brief Determine whether this class has a non-trivial copy assignment
1150249423Sdim  /// operator (C++ [class.copy]p11, C++11 [class.copy]p25)
1151249423Sdim  bool hasNonTrivialCopyAssignment() const {
1152249423Sdim    return data().DeclaredNonTrivialSpecialMembers & SMF_CopyAssignment ||
1153249423Sdim           !hasTrivialCopyAssignment();
1154249423Sdim  }
1155249423Sdim
1156249423Sdim  /// \brief Determine whether this class has a trivial move assignment operator
1157249423Sdim  /// (C++11 [class.copy]p25)
1158221345Sdim  bool hasTrivialMoveAssignment() const {
1159249423Sdim    return hasMoveAssignment() &&
1160249423Sdim           (data().HasTrivialSpecialMembers & SMF_MoveAssignment);
1161221345Sdim  }
1162221345Sdim
1163249423Sdim  /// \brief Determine whether this class has a non-trivial move assignment
1164249423Sdim  /// operator (C++11 [class.copy]p25)
1165249423Sdim  bool hasNonTrivialMoveAssignment() const {
1166249423Sdim    return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveAssignment) ||
1167249423Sdim           (needsImplicitMoveAssignment() &&
1168249423Sdim            !(data().HasTrivialSpecialMembers & SMF_MoveAssignment));
1169249423Sdim  }
1170198092Srdivacky
1171249423Sdim  /// \brief Determine whether this class has a trivial destructor
1172249423Sdim  /// (C++ [class.dtor]p3)
1173249423Sdim  bool hasTrivialDestructor() const {
1174249423Sdim    return data().HasTrivialSpecialMembers & SMF_Destructor;
1175249423Sdim  }
1176249423Sdim
1177249423Sdim  /// \brief Determine whether this class has a non-trivial destructor
1178249423Sdim  /// (C++ [class.dtor]p3)
1179249423Sdim  bool hasNonTrivialDestructor() const {
1180249423Sdim    return !(data().HasTrivialSpecialMembers & SMF_Destructor);
1181249423Sdim  }
1182249423Sdim
1183234353Sdim  // hasIrrelevantDestructor - Whether this class has a destructor which has no
1184234353Sdim  // semantic effect. Any such destructor will be trivial, public, defaulted
1185234353Sdim  // and not deleted, and will call only irrelevant destructors.
1186234353Sdim  bool hasIrrelevantDestructor() const {
1187234353Sdim    return data().HasIrrelevantDestructor;
1188234353Sdim  }
1189234353Sdim
1190234353Sdim  // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal or
1191234353Sdim  // volatile type non-static data member or base class.
1192221345Sdim  bool hasNonLiteralTypeFieldsOrBases() const {
1193221345Sdim    return data().HasNonLiteralTypeFieldsOrBases;
1194221345Sdim  }
1195221345Sdim
1196221345Sdim  // isTriviallyCopyable - Whether this class is considered trivially copyable
1197223017Sdim  // (C++0x [class]p6).
1198221345Sdim  bool isTriviallyCopyable() const;
1199221345Sdim
1200223017Sdim  // isTrivial - Whether this class is considered trivial
1201223017Sdim  //
1202223017Sdim  // C++0x [class]p6
1203223017Sdim  //    A trivial class is a class that has a trivial default constructor and
1204223017Sdim  //    is trivially copiable.
1205223017Sdim  bool isTrivial() const {
1206223017Sdim    return isTriviallyCopyable() && hasTrivialDefaultConstructor();
1207223017Sdim  }
1208223017Sdim
1209226633Sdim  // isLiteral - Whether this class is a literal type.
1210226633Sdim  //
1211234353Sdim  // C++11 [basic.types]p10
1212226633Sdim  //   A class type that has all the following properties:
1213234353Sdim  //     -- it has a trivial destructor
1214226633Sdim  //     -- every constructor call and full-expression in the
1215226633Sdim  //        brace-or-equal-intializers for non-static data members (if any) is
1216226633Sdim  //        a constant expression.
1217226633Sdim  //     -- it is an aggregate type or has at least one constexpr constructor or
1218226633Sdim  //        constructor template that is not a copy or move constructor, and
1219234353Sdim  //     -- all of its non-static data members and base classes are of literal
1220234353Sdim  //        types
1221226633Sdim  //
1222234353Sdim  // We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
1223234353Sdim  // treating types with trivial default constructors as literal types.
1224226633Sdim  bool isLiteral() const {
1225226633Sdim    return hasTrivialDestructor() &&
1226234353Sdim           (isAggregate() || hasConstexprNonCopyMoveConstructor() ||
1227234353Sdim            hasTrivialDefaultConstructor()) &&
1228226633Sdim           !hasNonLiteralTypeFieldsOrBases();
1229226633Sdim  }
1230226633Sdim
1231193326Sed  /// \brief If this record is an instantiation of a member class,
1232193326Sed  /// retrieves the member class from which it was instantiated.
1233193326Sed  ///
1234193326Sed  /// This routine will return non-NULL for (non-templated) member
1235193326Sed  /// classes of class templates. For example, given:
1236193326Sed  ///
1237239462Sdim  /// @code
1238193326Sed  /// template<typename T>
1239193326Sed  /// struct X {
1240193326Sed  ///   struct A { };
1241193326Sed  /// };
1242239462Sdim  /// @endcode
1243193326Sed  ///
1244193326Sed  /// The declaration for X<int>::A is a (non-templated) CXXRecordDecl
1245193326Sed  /// whose parent is the class template specialization X<int>. For
1246193326Sed  /// this declaration, getInstantiatedFromMemberClass() will return
1247193326Sed  /// the CXXRecordDecl X<T>::A. When a complete definition of
1248193326Sed  /// X<int>::A is required, it will be instantiated from the
1249193326Sed  /// declaration returned by getInstantiatedFromMemberClass().
1250198092Srdivacky  CXXRecordDecl *getInstantiatedFromMemberClass() const;
1251234353Sdim
1252198092Srdivacky  /// \brief If this class is an instantiation of a member class of a
1253198092Srdivacky  /// class template specialization, retrieves the member specialization
1254198092Srdivacky  /// information.
1255249423Sdim  MemberSpecializationInfo *getMemberSpecializationInfo() const {
1256249423Sdim    return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>();
1257249423Sdim  }
1258234353Sdim
1259193326Sed  /// \brief Specify that this record is an instantiation of the
1260193326Sed  /// member class RD.
1261198092Srdivacky  void setInstantiationOfMemberClass(CXXRecordDecl *RD,
1262198092Srdivacky                                     TemplateSpecializationKind TSK);
1263193326Sed
1264193326Sed  /// \brief Retrieves the class template that is described by this
1265193326Sed  /// class declaration.
1266193326Sed  ///
1267193326Sed  /// Every class template is represented as a ClassTemplateDecl and a
1268193326Sed  /// CXXRecordDecl. The former contains template properties (such as
1269193326Sed  /// the template parameter lists) while the latter contains the
1270193326Sed  /// actual description of the template's
1271193326Sed  /// contents. ClassTemplateDecl::getTemplatedDecl() retrieves the
1272193326Sed  /// CXXRecordDecl that from a ClassTemplateDecl, while
1273193326Sed  /// getDescribedClassTemplate() retrieves the ClassTemplateDecl from
1274193326Sed  /// a CXXRecordDecl.
1275193326Sed  ClassTemplateDecl *getDescribedClassTemplate() const {
1276193326Sed    return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl*>();
1277193326Sed  }
1278193326Sed
1279193326Sed  void setDescribedClassTemplate(ClassTemplateDecl *Template) {
1280193326Sed    TemplateOrInstantiation = Template;
1281193326Sed  }
1282193326Sed
1283198092Srdivacky  /// \brief Determine whether this particular class is a specialization or
1284198092Srdivacky  /// instantiation of a class template or member class of a class template,
1285198092Srdivacky  /// and how it was instantiated or specialized.
1286200583Srdivacky  TemplateSpecializationKind getTemplateSpecializationKind() const;
1287234353Sdim
1288198092Srdivacky  /// \brief Set the kind of specialization or template instantiation this is.
1289198092Srdivacky  void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
1290198092Srdivacky
1291193326Sed  /// getDestructor - Returns the destructor decl for this class.
1292210299Sed  CXXDestructorDecl *getDestructor() const;
1293198092Srdivacky
1294195099Sed  /// isLocalClass - If the class is a local class [class.local], returns
1295195099Sed  /// the enclosing function declaration.
1296195099Sed  const FunctionDecl *isLocalClass() const {
1297195099Sed    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
1298195099Sed      return RD->isLocalClass();
1299198092Srdivacky
1300195099Sed    return dyn_cast<FunctionDecl>(getDeclContext());
1301195099Sed  }
1302198092Srdivacky
1303249423Sdim  /// \brief Determine whether this dependent class is a current instantiation,
1304249423Sdim  /// when viewed from within the given context.
1305249423Sdim  bool isCurrentInstantiation(const DeclContext *CurContext) const;
1306249423Sdim
1307198092Srdivacky  /// \brief Determine whether this class is derived from the class \p Base.
1308198092Srdivacky  ///
1309198092Srdivacky  /// This routine only determines whether this class is derived from \p Base,
1310198092Srdivacky  /// but does not account for factors that may make a Derived -> Base class
1311198092Srdivacky  /// ill-formed, such as private/protected inheritance or multiple, ambiguous
1312198092Srdivacky  /// base class subobjects.
1313198092Srdivacky  ///
1314198092Srdivacky  /// \param Base the base class we are searching for.
1315198092Srdivacky  ///
1316198092Srdivacky  /// \returns true if this class is derived from Base, false otherwise.
1317218893Sdim  bool isDerivedFrom(const CXXRecordDecl *Base) const;
1318234353Sdim
1319198092Srdivacky  /// \brief Determine whether this class is derived from the type \p Base.
1320198092Srdivacky  ///
1321198092Srdivacky  /// This routine only determines whether this class is derived from \p Base,
1322198092Srdivacky  /// but does not account for factors that may make a Derived -> Base class
1323198092Srdivacky  /// ill-formed, such as private/protected inheritance or multiple, ambiguous
1324198092Srdivacky  /// base class subobjects.
1325198092Srdivacky  ///
1326198092Srdivacky  /// \param Base the base class we are searching for.
1327198092Srdivacky  ///
1328198092Srdivacky  /// \param Paths will contain the paths taken from the current class to the
1329198092Srdivacky  /// given \p Base class.
1330198092Srdivacky  ///
1331198092Srdivacky  /// \returns true if this class is derived from Base, false otherwise.
1332198092Srdivacky  ///
1333234353Sdim  /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
1334234353Sdim  /// tangling input and output in \p Paths
1335218893Sdim  bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const;
1336200583Srdivacky
1337204643Srdivacky  /// \brief Determine whether this class is virtually derived from
1338204643Srdivacky  /// the class \p Base.
1339204643Srdivacky  ///
1340204643Srdivacky  /// This routine only determines whether this class is virtually
1341204643Srdivacky  /// derived from \p Base, but does not account for factors that may
1342204643Srdivacky  /// make a Derived -> Base class ill-formed, such as
1343204643Srdivacky  /// private/protected inheritance or multiple, ambiguous base class
1344204643Srdivacky  /// subobjects.
1345204643Srdivacky  ///
1346204643Srdivacky  /// \param Base the base class we are searching for.
1347204643Srdivacky  ///
1348204643Srdivacky  /// \returns true if this class is virtually derived from Base,
1349204643Srdivacky  /// false otherwise.
1350239462Sdim  bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const;
1351204643Srdivacky
1352200583Srdivacky  /// \brief Determine whether this class is provably not derived from
1353200583Srdivacky  /// the type \p Base.
1354200583Srdivacky  bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const;
1355200583Srdivacky
1356200583Srdivacky  /// \brief Function type used by forallBases() as a callback.
1357200583Srdivacky  ///
1358243830Sdim  /// \param BaseDefinition the definition of the base class
1359200583Srdivacky  ///
1360200583Srdivacky  /// \returns true if this base matched the search criteria
1361200583Srdivacky  typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition,
1362200583Srdivacky                                   void *UserData);
1363200583Srdivacky
1364200583Srdivacky  /// \brief Determines if the given callback holds for all the direct
1365200583Srdivacky  /// or indirect base classes of this type.
1366200583Srdivacky  ///
1367200583Srdivacky  /// The class itself does not count as a base class.  This routine
1368200583Srdivacky  /// returns false if the class has non-computable base classes.
1369234353Sdim  ///
1370200583Srdivacky  /// \param AllowShortCircuit if false, forces the callback to be called
1371200583Srdivacky  /// for every base class, even if a dependent or non-matching base was
1372200583Srdivacky  /// found.
1373200583Srdivacky  bool forallBases(ForallBasesCallback *BaseMatches, void *UserData,
1374200583Srdivacky                   bool AllowShortCircuit = true) const;
1375234353Sdim
1376234353Sdim  /// \brief Function type used by lookupInBases() to determine whether a
1377198092Srdivacky  /// specific base class subobject matches the lookup criteria.
1378198092Srdivacky  ///
1379234353Sdim  /// \param Specifier the base-class specifier that describes the inheritance
1380198092Srdivacky  /// from the base class we are trying to match.
1381198092Srdivacky  ///
1382234353Sdim  /// \param Path the current path, from the most-derived class down to the
1383198092Srdivacky  /// base named by the \p Specifier.
1384198092Srdivacky  ///
1385198092Srdivacky  /// \param UserData a single pointer to user-specified data, provided to
1386198092Srdivacky  /// lookupInBases().
1387198092Srdivacky  ///
1388198092Srdivacky  /// \returns true if this base matched the search criteria, false otherwise.
1389199482Srdivacky  typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier,
1390198092Srdivacky                                   CXXBasePath &Path,
1391198092Srdivacky                                   void *UserData);
1392234353Sdim
1393198092Srdivacky  /// \brief Look for entities within the base classes of this C++ class,
1394198092Srdivacky  /// transitively searching all base class subobjects.
1395198092Srdivacky  ///
1396234353Sdim  /// This routine uses the callback function \p BaseMatches to find base
1397198092Srdivacky  /// classes meeting some search criteria, walking all base class subobjects
1398234353Sdim  /// and populating the given \p Paths structure with the paths through the
1399198092Srdivacky  /// inheritance hierarchy that resulted in a match. On a successful search,
1400198092Srdivacky  /// the \p Paths structure can be queried to retrieve the matching paths and
1401198092Srdivacky  /// to determine if there were any ambiguities.
1402198092Srdivacky  ///
1403198092Srdivacky  /// \param BaseMatches callback function used to determine whether a given
1404198092Srdivacky  /// base matches the user-defined search criteria.
1405198092Srdivacky  ///
1406198092Srdivacky  /// \param UserData user data pointer that will be provided to \p BaseMatches.
1407198092Srdivacky  ///
1408198092Srdivacky  /// \param Paths used to record the paths from this class to its base class
1409198092Srdivacky  /// subobjects that match the search criteria.
1410198092Srdivacky  ///
1411198092Srdivacky  /// \returns true if there exists any path from this class to a base class
1412198092Srdivacky  /// subobject that matches the search criteria.
1413198092Srdivacky  bool lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData,
1414199482Srdivacky                     CXXBasePaths &Paths) const;
1415234353Sdim
1416198092Srdivacky  /// \brief Base-class lookup callback that determines whether the given
1417198092Srdivacky  /// base class specifier refers to a specific class declaration.
1418198092Srdivacky  ///
1419198092Srdivacky  /// This callback can be used with \c lookupInBases() to determine whether
1420198092Srdivacky  /// a given derived class has is a base class subobject of a particular type.
1421198092Srdivacky  /// The user data pointer should refer to the canonical CXXRecordDecl of the
1422198092Srdivacky  /// base class that we are searching for.
1423199482Srdivacky  static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
1424199482Srdivacky                            CXXBasePath &Path, void *BaseRecord);
1425204643Srdivacky
1426204643Srdivacky  /// \brief Base-class lookup callback that determines whether the
1427204643Srdivacky  /// given base class specifier refers to a specific class
1428204643Srdivacky  /// declaration and describes virtual derivation.
1429204643Srdivacky  ///
1430204643Srdivacky  /// This callback can be used with \c lookupInBases() to determine
1431204643Srdivacky  /// whether a given derived class has is a virtual base class
1432204643Srdivacky  /// subobject of a particular type.  The user data pointer should
1433204643Srdivacky  /// refer to the canonical CXXRecordDecl of the base class that we
1434204643Srdivacky  /// are searching for.
1435204643Srdivacky  static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
1436204643Srdivacky                                   CXXBasePath &Path, void *BaseRecord);
1437234353Sdim
1438198092Srdivacky  /// \brief Base-class lookup callback that determines whether there exists
1439198092Srdivacky  /// a tag with the given name.
1440198092Srdivacky  ///
1441198092Srdivacky  /// This callback can be used with \c lookupInBases() to find tag members
1442198092Srdivacky  /// of the given name within a C++ class hierarchy. The user data pointer
1443198092Srdivacky  /// is an opaque \c DeclarationName pointer.
1444199482Srdivacky  static bool FindTagMember(const CXXBaseSpecifier *Specifier,
1445199482Srdivacky                            CXXBasePath &Path, void *Name);
1446198092Srdivacky
1447198092Srdivacky  /// \brief Base-class lookup callback that determines whether there exists
1448198092Srdivacky  /// a member with the given name.
1449198092Srdivacky  ///
1450198092Srdivacky  /// This callback can be used with \c lookupInBases() to find members
1451198092Srdivacky  /// of the given name within a C++ class hierarchy. The user data pointer
1452198092Srdivacky  /// is an opaque \c DeclarationName pointer.
1453199482Srdivacky  static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
1454199482Srdivacky                                 CXXBasePath &Path, void *Name);
1455234353Sdim
1456198092Srdivacky  /// \brief Base-class lookup callback that determines whether there exists
1457198092Srdivacky  /// a member with the given name that can be used in a nested-name-specifier.
1458198092Srdivacky  ///
1459198092Srdivacky  /// This callback can be used with \c lookupInBases() to find membes of
1460198092Srdivacky  /// the given name within a C++ class hierarchy that can occur within
1461198092Srdivacky  /// nested-name-specifiers.
1462199482Srdivacky  static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
1463198092Srdivacky                                            CXXBasePath &Path,
1464198092Srdivacky                                            void *UserData);
1465206084Srdivacky
1466206084Srdivacky  /// \brief Retrieve the final overriders for each virtual member
1467206084Srdivacky  /// function in the class hierarchy where this class is the
1468206084Srdivacky  /// most-derived class in the class hierarchy.
1469206084Srdivacky  void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const;
1470206084Srdivacky
1471218893Sdim  /// \brief Get the indirect primary bases for this class.
1472218893Sdim  void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
1473218893Sdim
1474193326Sed  /// viewInheritance - Renders and displays an inheritance diagram
1475193326Sed  /// for this C++ class and all of its base classes (transitively) using
1476193326Sed  /// GraphViz.
1477193326Sed  void viewInheritance(ASTContext& Context) const;
1478193326Sed
1479202879Srdivacky  /// MergeAccess - Calculates the access of a decl that is reached
1480202879Srdivacky  /// along a path.
1481202879Srdivacky  static AccessSpecifier MergeAccess(AccessSpecifier PathAccess,
1482202879Srdivacky                                     AccessSpecifier DeclAccess) {
1483202879Srdivacky    assert(DeclAccess != AS_none);
1484202879Srdivacky    if (DeclAccess == AS_private) return AS_none;
1485202879Srdivacky    return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
1486202879Srdivacky  }
1487202879Srdivacky
1488249423Sdim  /// \brief Indicates that the declaration of a defaulted or deleted special
1489249423Sdim  /// member function is now complete.
1490249423Sdim  void finishedDefaultedOrDeletedMember(CXXMethodDecl *MD);
1491249423Sdim
1492218893Sdim  /// \brief Indicates that the definition of this class is now complete.
1493218893Sdim  virtual void completeDefinition();
1494218893Sdim
1495234353Sdim  /// \brief Indicates that the definition of this class is now complete,
1496218893Sdim  /// and provides a final overrider map to help determine
1497234353Sdim  ///
1498218893Sdim  /// \param FinalOverriders The final overrider map for this class, which can
1499218893Sdim  /// be provided as an optimization for abstract-class checking. If NULL,
1500218893Sdim  /// final overriders will be computed if they are needed to complete the
1501218893Sdim  /// definition.
1502218893Sdim  void completeDefinition(CXXFinalOverriderMap *FinalOverriders);
1503234353Sdim
1504218893Sdim  /// \brief Determine whether this class may end up being abstract, even though
1505218893Sdim  /// it is not yet known to be abstract.
1506218893Sdim  ///
1507218893Sdim  /// \returns true if this class is not known to be abstract but has any
1508218893Sdim  /// base classes that are abstract. In this case, \c completeDefinition()
1509218893Sdim  /// will need to compute final overriders to determine whether the class is
1510218893Sdim  /// actually abstract.
1511218893Sdim  bool mayBeAbstract() const;
1512234353Sdim
1513234353Sdim  /// \brief If this is the closure type of a lambda expression, retrieve the
1514234353Sdim  /// number to be used for name mangling in the Itanium C++ ABI.
1515234353Sdim  ///
1516234353Sdim  /// Zero indicates that this closure type has internal linkage, so the
1517234353Sdim  /// mangling number does not matter, while a non-zero value indicates which
1518234353Sdim  /// lambda expression this is in this particular context.
1519234353Sdim  unsigned getLambdaManglingNumber() const {
1520234353Sdim    assert(isLambda() && "Not a lambda closure type!");
1521234353Sdim    return getLambdaData().ManglingNumber;
1522234353Sdim  }
1523218893Sdim
1524234353Sdim  /// \brief Retrieve the declaration that provides additional context for a
1525234353Sdim  /// lambda, when the normal declaration context is not specific enough.
1526234353Sdim  ///
1527234353Sdim  /// Certain contexts (default arguments of in-class function parameters and
1528234353Sdim  /// the initializers of data members) have separate name mangling rules for
1529234353Sdim  /// lambdas within the Itanium C++ ABI. For these cases, this routine provides
1530234353Sdim  /// the declaration in which the lambda occurs, e.g., the function parameter
1531234353Sdim  /// or the non-static data member. Otherwise, it returns NULL to imply that
1532234353Sdim  /// the declaration context suffices.
1533234353Sdim  Decl *getLambdaContextDecl() const {
1534234353Sdim    assert(isLambda() && "Not a lambda closure type!");
1535234353Sdim    return getLambdaData().ContextDecl;
1536234353Sdim  }
1537234353Sdim
1538234353Sdim  /// \brief Set the mangling number and context declaration for a lambda
1539234353Sdim  /// class.
1540234353Sdim  void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl) {
1541234353Sdim    getLambdaData().ManglingNumber = ManglingNumber;
1542234353Sdim    getLambdaData().ContextDecl = ContextDecl;
1543234353Sdim  }
1544234353Sdim
1545249423Sdim  /// \brief Returns the inheritance model used for this record.
1546249423Sdim  MSInheritanceModel getMSInheritanceModel() const;
1547249423Sdim
1548234353Sdim  /// \brief Determine whether this lambda expression was known to be dependent
1549234353Sdim  /// at the time it was created, even if its context does not appear to be
1550234353Sdim  /// dependent.
1551234353Sdim  ///
1552234353Sdim  /// This flag is a workaround for an issue with parsing, where default
1553234353Sdim  /// arguments are parsed before their enclosing function declarations have
1554234353Sdim  /// been created. This means that any lambda expressions within those
1555234353Sdim  /// default arguments will have as their DeclContext the context enclosing
1556234353Sdim  /// the function declaration, which may be non-dependent even when the
1557234353Sdim  /// function declaration itself is dependent. This flag indicates when we
1558234353Sdim  /// know that the lambda is dependent despite that.
1559234353Sdim  bool isDependentLambda() const {
1560234353Sdim    return isLambda() && getLambdaData().Dependent;
1561234353Sdim  }
1562243830Sdim
1563243830Sdim  TypeSourceInfo *getLambdaTypeInfo() const {
1564243830Sdim    return getLambdaData().MethodTyInfo;
1565243830Sdim  }
1566243830Sdim
1567203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1568203955Srdivacky  static bool classofKind(Kind K) {
1569210299Sed    return K >= firstCXXRecord && K <= lastCXXRecord;
1570193326Sed  }
1571210299Sed
1572212904Sdim  friend class ASTDeclReader;
1573212904Sdim  friend class ASTDeclWriter;
1574218893Sdim  friend class ASTReader;
1575218893Sdim  friend class ASTWriter;
1576193326Sed};
1577193326Sed
1578193326Sed/// CXXMethodDecl - Represents a static or instance method of a
1579193326Sed/// struct/union/class.
1580193326Sedclass CXXMethodDecl : public FunctionDecl {
1581234353Sdim  virtual void anchor();
1582193326Sedprotected:
1583221345Sdim  CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
1584212904Sdim                const DeclarationNameInfo &NameInfo,
1585212904Sdim                QualType T, TypeSourceInfo *TInfo,
1586249423Sdim                StorageClass SC, bool isInline,
1587226633Sdim                bool isConstexpr, SourceLocation EndLocation)
1588221345Sdim    : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo,
1589249423Sdim                   SC, isInline, isConstexpr) {
1590234353Sdim    if (EndLocation.isValid())
1591234353Sdim      setRangeEnd(EndLocation);
1592234353Sdim  }
1593193326Sed
1594193326Sedpublic:
1595193326Sed  static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
1596221345Sdim                               SourceLocation StartLoc,
1597212904Sdim                               const DeclarationNameInfo &NameInfo,
1598212904Sdim                               QualType T, TypeSourceInfo *TInfo,
1599249423Sdim                               StorageClass SC,
1600221345Sdim                               bool isInline,
1601226633Sdim                               bool isConstexpr,
1602221345Sdim                               SourceLocation EndLocation);
1603198092Srdivacky
1604234353Sdim  static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1605249423Sdim
1606249423Sdim  bool isStatic() const;
1607193326Sed  bool isInstance() const { return !isStatic(); }
1608193326Sed
1609243830Sdim  bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); }
1610243830Sdim  bool isVolatile() const { return getType()->castAs<FunctionType>()->isVolatile(); }
1611239462Sdim
1612198092Srdivacky  bool isVirtual() const {
1613234353Sdim    CXXMethodDecl *CD =
1614198092Srdivacky      cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
1615198092Srdivacky
1616243830Sdim    // Methods declared in interfaces are automatically (pure) virtual.
1617243830Sdim    if (CD->isVirtualAsWritten() ||
1618243830Sdim          (CD->getParent()->isInterface() && CD->isUserProvided()))
1619198092Srdivacky      return true;
1620234353Sdim
1621198092Srdivacky    return (CD->begin_overridden_methods() != CD->end_overridden_methods());
1622193326Sed  }
1623206084Srdivacky
1624198092Srdivacky  /// \brief Determine whether this is a usual deallocation function
1625198092Srdivacky  /// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
1626198092Srdivacky  /// delete or delete[] operator with a particular signature.
1627198092Srdivacky  bool isUsualDeallocationFunction() const;
1628234353Sdim
1629207619Srdivacky  /// \brief Determine whether this is a copy-assignment operator, regardless
1630207619Srdivacky  /// of whether it was declared implicitly or explicitly.
1631207619Srdivacky  bool isCopyAssignmentOperator() const;
1632223017Sdim
1633223017Sdim  /// \brief Determine whether this is a move assignment operator.
1634223017Sdim  bool isMoveAssignmentOperator() const;
1635234353Sdim
1636198092Srdivacky  const CXXMethodDecl *getCanonicalDecl() const {
1637198092Srdivacky    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
1638198092Srdivacky  }
1639198092Srdivacky  CXXMethodDecl *getCanonicalDecl() {
1640198092Srdivacky    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
1641198092Srdivacky  }
1642223017Sdim
1643239462Sdim  /// isUserProvided - True if this method is user-declared and was not
1644239462Sdim  /// deleted or defaulted on its first declaration.
1645223017Sdim  bool isUserProvided() const {
1646223017Sdim    return !(isDeleted() || getCanonicalDecl()->isDefaulted());
1647223017Sdim  }
1648234353Sdim
1649198092Srdivacky  ///
1650198092Srdivacky  void addOverriddenMethod(const CXXMethodDecl *MD);
1651193326Sed
1652234353Sdim  typedef const CXXMethodDecl *const* method_iterator;
1653198092Srdivacky
1654193326Sed  method_iterator begin_overridden_methods() const;
1655193326Sed  method_iterator end_overridden_methods() const;
1656210299Sed  unsigned size_overridden_methods() const;
1657198092Srdivacky
1658193326Sed  /// getParent - Returns the parent of this method declaration, which
1659193326Sed  /// is the class in which this method is defined.
1660198092Srdivacky  const CXXRecordDecl *getParent() const {
1661198092Srdivacky    return cast<CXXRecordDecl>(FunctionDecl::getParent());
1662193326Sed  }
1663198092Srdivacky
1664193326Sed  /// getParent - Returns the parent of this method declaration, which
1665193326Sed  /// is the class in which this method is defined.
1666198092Srdivacky  CXXRecordDecl *getParent() {
1667193326Sed    return const_cast<CXXRecordDecl *>(
1668193326Sed             cast<CXXRecordDecl>(FunctionDecl::getParent()));
1669193326Sed  }
1670193326Sed
1671193326Sed  /// getThisType - Returns the type of 'this' pointer.
1672193326Sed  /// Should only be called for instance methods.
1673193326Sed  QualType getThisType(ASTContext &C) const;
1674193326Sed
1675193326Sed  unsigned getTypeQualifiers() const {
1676198092Srdivacky    return getType()->getAs<FunctionProtoType>()->getTypeQuals();
1677193326Sed  }
1678193326Sed
1679218893Sdim  /// \brief Retrieve the ref-qualifier associated with this method.
1680218893Sdim  ///
1681218893Sdim  /// In the following example, \c f() has an lvalue ref-qualifier, \c g()
1682218893Sdim  /// has an rvalue ref-qualifier, and \c h() has no ref-qualifier.
1683239462Sdim  /// @code
1684218893Sdim  /// struct X {
1685218893Sdim  ///   void f() &;
1686218893Sdim  ///   void g() &&;
1687218893Sdim  ///   void h();
1688218893Sdim  /// };
1689239462Sdim  /// @endcode
1690218893Sdim  RefQualifierKind getRefQualifier() const {
1691218893Sdim    return getType()->getAs<FunctionProtoType>()->getRefQualifier();
1692218893Sdim  }
1693234353Sdim
1694200583Srdivacky  bool hasInlineBody() const;
1695200583Srdivacky
1696234353Sdim  /// \brief Determine whether this is a lambda closure type's static member
1697234353Sdim  /// function that is used for the result of the lambda's conversion to
1698234353Sdim  /// function pointer (for a lambda with no captures).
1699234353Sdim  ///
1700234353Sdim  /// The function itself, if used, will have a placeholder body that will be
1701234353Sdim  /// supplied by IR generation to either forward to the function call operator
1702234353Sdim  /// or clone the function call operator.
1703234353Sdim  bool isLambdaStaticInvoker() const;
1704239462Sdim
1705239462Sdim  /// \brief Find the method in RD that corresponds to this one.
1706239462Sdim  ///
1707239462Sdim  /// Find if RD or one of the classes it inherits from override this method.
1708239462Sdim  /// If so, return it. RD is assumed to be a subclass of the class defining
1709239462Sdim  /// this method (or be the class itself), unless MayBeBase is set to true.
1710239462Sdim  CXXMethodDecl *
1711239462Sdim  getCorrespondingMethodInClass(const CXXRecordDecl *RD,
1712239462Sdim                                bool MayBeBase = false);
1713239462Sdim
1714239462Sdim  const CXXMethodDecl *
1715239462Sdim  getCorrespondingMethodInClass(const CXXRecordDecl *RD,
1716239462Sdim                                bool MayBeBase = false) const {
1717239462Sdim    return const_cast<CXXMethodDecl *>(this)
1718239462Sdim              ->getCorrespondingMethodInClass(RD, MayBeBase);
1719239462Sdim  }
1720239462Sdim
1721193326Sed  // Implement isa/cast/dyncast/etc.
1722203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1723203955Srdivacky  static bool classofKind(Kind K) {
1724210299Sed    return K >= firstCXXMethod && K <= lastCXXMethod;
1725193326Sed  }
1726193326Sed};
1727193326Sed
1728218893Sdim/// CXXCtorInitializer - Represents a C++ base or member
1729193326Sed/// initializer, which is part of a constructor initializer that
1730193326Sed/// initializes one non-static member variable or one base class. For
1731193326Sed/// example, in the following, both 'A(a)' and 'f(3.14159)' are member
1732193326Sed/// initializers:
1733193326Sed///
1734193326Sed/// @code
1735193326Sed/// class A { };
1736193326Sed/// class B : public A {
1737193326Sed///   float f;
1738193326Sed/// public:
1739193326Sed///   B(A& a) : A(a), f(3.14159) { }
1740193326Sed/// };
1741194613Sed/// @endcode
1742218893Sdimclass CXXCtorInitializer {
1743234353Sdim  /// \brief Either the base class name/delegating constructor type (stored as
1744234353Sdim  /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
1745234353Sdim  /// (IndirectFieldDecl*) being initialized.
1746234353Sdim  llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *>
1747218893Sdim    Initializee;
1748234353Sdim
1749218893Sdim  /// \brief The source location for the field name or, for a base initializer
1750221345Sdim  /// pack expansion, the location of the ellipsis. In the case of a delegating
1751221345Sdim  /// constructor, it will still include the type's source location as the
1752221345Sdim  /// Initializee points to the CXXConstructorDecl (to allow loop detection).
1753218893Sdim  SourceLocation MemberOrEllipsisLocation;
1754234353Sdim
1755203955Srdivacky  /// \brief The argument used to initialize the base or member, which may
1756203955Srdivacky  /// end up constructing an object (when multiple arguments are involved).
1757203955Srdivacky  Stmt *Init;
1758234353Sdim
1759200583Srdivacky  /// LParenLoc - Location of the left paren of the ctor-initializer.
1760200583Srdivacky  SourceLocation LParenLoc;
1761193326Sed
1762198092Srdivacky  /// RParenLoc - Location of the right paren of the ctor-initializer.
1763198092Srdivacky  SourceLocation RParenLoc;
1764198092Srdivacky
1765234353Sdim  /// \brief If the initializee is a type, whether that type makes this
1766234353Sdim  /// a delegating initialization.
1767234353Sdim  bool IsDelegating : 1;
1768234353Sdim
1769208600Srdivacky  /// IsVirtual - If the initializer is a base initializer, this keeps track
1770208600Srdivacky  /// of whether the base is virtual or not.
1771208600Srdivacky  bool IsVirtual : 1;
1772208600Srdivacky
1773208600Srdivacky  /// IsWritten - Whether or not the initializer is explicitly written
1774208600Srdivacky  /// in the sources.
1775208600Srdivacky  bool IsWritten : 1;
1776218893Sdim
1777208600Srdivacky  /// SourceOrderOrNumArrayIndices - If IsWritten is true, then this
1778208600Srdivacky  /// number keeps track of the textual order of this initializer in the
1779208600Srdivacky  /// original sources, counting from 0; otherwise, if IsWritten is false,
1780208600Srdivacky  /// it stores the number of array index variables stored after this
1781208600Srdivacky  /// object in memory.
1782234353Sdim  unsigned SourceOrderOrNumArrayIndices : 13;
1783208600Srdivacky
1784218893Sdim  CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
1785218893Sdim                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
1786218893Sdim                     SourceLocation R, VarDecl **Indices, unsigned NumIndices);
1787234353Sdim
1788193326Sedpublic:
1789218893Sdim  /// CXXCtorInitializer - Creates a new base-class initializer.
1790198092Srdivacky  explicit
1791218893Sdim  CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual,
1792218893Sdim                     SourceLocation L, Expr *Init, SourceLocation R,
1793218893Sdim                     SourceLocation EllipsisLoc);
1794193326Sed
1795218893Sdim  /// CXXCtorInitializer - Creates a new member initializer.
1796198092Srdivacky  explicit
1797218893Sdim  CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
1798218893Sdim                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
1799218893Sdim                     SourceLocation R);
1800193326Sed
1801221345Sdim  /// CXXCtorInitializer - Creates a new anonymous field initializer.
1802218893Sdim  explicit
1803218893Sdim  CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,
1804218893Sdim                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
1805218893Sdim                     SourceLocation R);
1806218893Sdim
1807221345Sdim  /// CXXCtorInitializer - Creates a new delegating Initializer.
1808221345Sdim  explicit
1809234353Sdim  CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
1810234353Sdim                     SourceLocation L, Expr *Init, SourceLocation R);
1811221345Sdim
1812234353Sdim  /// \brief Creates a new member initializer that optionally contains
1813208600Srdivacky  /// array indices used to describe an elementwise initialization.
1814218893Sdim  static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
1815218893Sdim                                    SourceLocation MemberLoc, SourceLocation L,
1816218893Sdim                                    Expr *Init, SourceLocation R,
1817218893Sdim                                    VarDecl **Indices, unsigned NumIndices);
1818234353Sdim
1819193326Sed  /// isBaseInitializer - Returns true when this initializer is
1820193326Sed  /// initializing a base class.
1821234353Sdim  bool isBaseInitializer() const {
1822234353Sdim    return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
1823234353Sdim  }
1824193326Sed
1825193326Sed  /// isMemberInitializer - Returns true when this initializer is
1826193326Sed  /// initializing a non-static data member.
1827218893Sdim  bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); }
1828193326Sed
1829234353Sdim  bool isAnyMemberInitializer() const {
1830218893Sdim    return isMemberInitializer() || isIndirectMemberInitializer();
1831218893Sdim  }
1832218893Sdim
1833218893Sdim  bool isIndirectMemberInitializer() const {
1834218893Sdim    return Initializee.is<IndirectFieldDecl*>();
1835218893Sdim  }
1836218893Sdim
1837223017Sdim  /// isInClassMemberInitializer - Returns true when this initializer is an
1838223017Sdim  /// implicit ctor initializer generated for a field with an initializer
1839223017Sdim  /// defined on the member declaration.
1840223017Sdim  bool isInClassMemberInitializer() const {
1841251662Sdim    return isa<CXXDefaultInitExpr>(Init);
1842223017Sdim  }
1843223017Sdim
1844221345Sdim  /// isDelegatingInitializer - Returns true when this initializer is creating
1845221345Sdim  /// a delegating constructor.
1846221345Sdim  bool isDelegatingInitializer() const {
1847234353Sdim    return Initializee.is<TypeSourceInfo*>() && IsDelegating;
1848221345Sdim  }
1849221345Sdim
1850218893Sdim  /// \brief Determine whether this initializer is a pack expansion.
1851234353Sdim  bool isPackExpansion() const {
1852234353Sdim    return isBaseInitializer() && MemberOrEllipsisLocation.isValid();
1853218893Sdim  }
1854234353Sdim
1855218893Sdim  // \brief For a pack expansion, returns the location of the ellipsis.
1856218893Sdim  SourceLocation getEllipsisLoc() const {
1857218893Sdim    assert(isPackExpansion() && "Initializer is not a pack expansion");
1858218893Sdim    return MemberOrEllipsisLocation;
1859218893Sdim  }
1860234353Sdim
1861234353Sdim  /// If this is a base class initializer, returns the type of the
1862200583Srdivacky  /// base class with location information. Otherwise, returns an NULL
1863200583Srdivacky  /// type location.
1864200583Srdivacky  TypeLoc getBaseClassLoc() const;
1865193326Sed
1866200583Srdivacky  /// If this is a base class initializer, returns the type of the base class.
1867200583Srdivacky  /// Otherwise, returns NULL.
1868200583Srdivacky  const Type *getBaseClass() const;
1869207619Srdivacky
1870207619Srdivacky  /// Returns whether the base is virtual or not.
1871207619Srdivacky  bool isBaseVirtual() const {
1872207619Srdivacky    assert(isBaseInitializer() && "Must call this on base initializer!");
1873234353Sdim
1874207619Srdivacky    return IsVirtual;
1875207619Srdivacky  }
1876207619Srdivacky
1877234353Sdim  /// \brief Returns the declarator information for a base class or delegating
1878234353Sdim  /// initializer.
1879234353Sdim  TypeSourceInfo *getTypeSourceInfo() const {
1880218893Sdim    return Initializee.dyn_cast<TypeSourceInfo *>();
1881193326Sed  }
1882234353Sdim
1883193326Sed  /// getMember - If this is a member initializer, returns the
1884193326Sed  /// declaration of the non-static data member being
1885193326Sed  /// initialized. Otherwise, returns NULL.
1886212904Sdim  FieldDecl *getMember() const {
1887193326Sed    if (isMemberInitializer())
1888218893Sdim      return Initializee.get<FieldDecl*>();
1889234353Sdim    return 0;
1890193326Sed  }
1891218893Sdim  FieldDecl *getAnyMember() const {
1892218893Sdim    if (isMemberInitializer())
1893218893Sdim      return Initializee.get<FieldDecl*>();
1894234353Sdim    if (isIndirectMemberInitializer())
1895218893Sdim      return Initializee.get<IndirectFieldDecl*>()->getAnonField();
1896234353Sdim    return 0;
1897218893Sdim  }
1898193326Sed
1899218893Sdim  IndirectFieldDecl *getIndirectMember() const {
1900218893Sdim    if (isIndirectMemberInitializer())
1901218893Sdim      return Initializee.get<IndirectFieldDecl*>();
1902234353Sdim    return 0;
1903198092Srdivacky  }
1904198092Srdivacky
1905234353Sdim  SourceLocation getMemberLocation() const {
1906234353Sdim    return MemberOrEllipsisLocation;
1907221345Sdim  }
1908221345Sdim
1909200583Srdivacky  /// \brief Determine the source location of the initializer.
1910200583Srdivacky  SourceLocation getSourceLocation() const;
1911234353Sdim
1912200583Srdivacky  /// \brief Determine the source range covering the entire initializer.
1913234353Sdim  SourceRange getSourceRange() const LLVM_READONLY;
1914208600Srdivacky
1915208600Srdivacky  /// isWritten - Returns true if this initializer is explicitly written
1916208600Srdivacky  /// in the source code.
1917208600Srdivacky  bool isWritten() const { return IsWritten; }
1918208600Srdivacky
1919208600Srdivacky  /// \brief Return the source position of the initializer, counting from 0.
1920208600Srdivacky  /// If the initializer was implicit, -1 is returned.
1921208600Srdivacky  int getSourceOrder() const {
1922208600Srdivacky    return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
1923208600Srdivacky  }
1924208600Srdivacky
1925208600Srdivacky  /// \brief Set the source order of this initializer. This method can only
1926208600Srdivacky  /// be called once for each initializer; it cannot be called on an
1927208600Srdivacky  /// initializer having a positive number of (implicit) array indices.
1928208600Srdivacky  void setSourceOrder(int pos) {
1929208600Srdivacky    assert(!IsWritten &&
1930208600Srdivacky           "calling twice setSourceOrder() on the same initializer");
1931208600Srdivacky    assert(SourceOrderOrNumArrayIndices == 0 &&
1932208600Srdivacky           "setSourceOrder() used when there are implicit array indices");
1933208600Srdivacky    assert(pos >= 0 &&
1934208600Srdivacky           "setSourceOrder() used to make an initializer implicit");
1935208600Srdivacky    IsWritten = true;
1936208600Srdivacky    SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
1937208600Srdivacky  }
1938198092Srdivacky
1939200583Srdivacky  SourceLocation getLParenLoc() const { return LParenLoc; }
1940198092Srdivacky  SourceLocation getRParenLoc() const { return RParenLoc; }
1941193326Sed
1942208600Srdivacky  /// \brief Determine the number of implicit array indices used while
1943208600Srdivacky  /// described an array member initialization.
1944208600Srdivacky  unsigned getNumArrayIndices() const {
1945208600Srdivacky    return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
1946208600Srdivacky  }
1947208600Srdivacky
1948234353Sdim  /// \brief Retrieve a particular array index variable used to
1949208600Srdivacky  /// describe an array member initialization.
1950208600Srdivacky  VarDecl *getArrayIndex(unsigned I) {
1951208600Srdivacky    assert(I < getNumArrayIndices() && "Out of bounds member array index");
1952208600Srdivacky    return reinterpret_cast<VarDecl **>(this + 1)[I];
1953208600Srdivacky  }
1954208600Srdivacky  const VarDecl *getArrayIndex(unsigned I) const {
1955208600Srdivacky    assert(I < getNumArrayIndices() && "Out of bounds member array index");
1956208600Srdivacky    return reinterpret_cast<const VarDecl * const *>(this + 1)[I];
1957208600Srdivacky  }
1958208600Srdivacky  void setArrayIndex(unsigned I, VarDecl *Index) {
1959208600Srdivacky    assert(I < getNumArrayIndices() && "Out of bounds member array index");
1960208600Srdivacky    reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
1961208600Srdivacky  }
1962234353Sdim  ArrayRef<VarDecl *> getArrayIndexes() {
1963234353Sdim    assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
1964234353Sdim    return ArrayRef<VarDecl *>(reinterpret_cast<VarDecl **>(this + 1),
1965234353Sdim                               getNumArrayIndices());
1966234353Sdim  }
1967234353Sdim
1968251662Sdim  /// \brief Get the initializer.
1969251662Sdim  Expr *getInit() const { return static_cast<Expr*>(Init); }
1970193326Sed};
1971193326Sed
1972193326Sed/// CXXConstructorDecl - Represents a C++ constructor within a
1973193326Sed/// class. For example:
1974198092Srdivacky///
1975193326Sed/// @code
1976193326Sed/// class X {
1977193326Sed/// public:
1978193326Sed///   explicit X(int); // represented by a CXXConstructorDecl.
1979193326Sed/// };
1980193326Sed/// @endcode
1981193326Sedclass CXXConstructorDecl : public CXXMethodDecl {
1982234353Sdim  virtual void anchor();
1983203955Srdivacky  /// IsExplicitSpecified - Whether this constructor declaration has the
1984203955Srdivacky  /// 'explicit' keyword specified.
1985203955Srdivacky  bool IsExplicitSpecified : 1;
1986193326Sed
1987193326Sed  /// ImplicitlyDefined - Whether this constructor was implicitly
1988193326Sed  /// defined by the compiler. When false, the constructor was defined
1989193326Sed  /// by the user. In C++03, this flag will have the same value as
1990193326Sed  /// Implicit. In C++0x, however, a constructor that is
1991193326Sed  /// explicitly defaulted (i.e., defined with " = default") will have
1992193326Sed  /// @c !Implicit && ImplicitlyDefined.
1993193326Sed  bool ImplicitlyDefined : 1;
1994198092Srdivacky
1995195341Sed  /// Support for base and member initializers.
1996218893Sdim  /// CtorInitializers - The arguments used to initialize the base
1997195341Sed  /// or member.
1998218893Sdim  CXXCtorInitializer **CtorInitializers;
1999218893Sdim  unsigned NumCtorInitializers;
2000198092Srdivacky
2001221345Sdim  CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
2002221345Sdim                     const DeclarationNameInfo &NameInfo,
2003212904Sdim                     QualType T, TypeSourceInfo *TInfo,
2004234353Sdim                     bool isExplicitSpecified, bool isInline,
2005226633Sdim                     bool isImplicitlyDeclared, bool isConstexpr)
2006249423Sdim    : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo,
2007226633Sdim                    SC_None, isInline, isConstexpr, SourceLocation()),
2008203955Srdivacky      IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
2009218893Sdim      CtorInitializers(0), NumCtorInitializers(0) {
2010193326Sed    setImplicit(isImplicitlyDeclared);
2011193326Sed  }
2012198092Srdivacky
2013193326Sedpublic:
2014234353Sdim  static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2015193326Sed  static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
2016221345Sdim                                    SourceLocation StartLoc,
2017212904Sdim                                    const DeclarationNameInfo &NameInfo,
2018200583Srdivacky                                    QualType T, TypeSourceInfo *TInfo,
2019198092Srdivacky                                    bool isExplicit,
2020226633Sdim                                    bool isInline, bool isImplicitlyDeclared,
2021226633Sdim                                    bool isConstexpr);
2022193326Sed
2023203955Srdivacky  /// isExplicitSpecified - Whether this constructor declaration has the
2024203955Srdivacky  /// 'explicit' keyword specified.
2025203955Srdivacky  bool isExplicitSpecified() const { return IsExplicitSpecified; }
2026234353Sdim
2027198092Srdivacky  /// isExplicit - Whether this constructor was marked "explicit" or not.
2028203955Srdivacky  bool isExplicit() const {
2029203955Srdivacky    return cast<CXXConstructorDecl>(getFirstDeclaration())
2030203955Srdivacky      ->isExplicitSpecified();
2031203955Srdivacky  }
2032193326Sed
2033193326Sed  /// isImplicitlyDefined - Whether this constructor was implicitly
2034193326Sed  /// defined. If false, then this constructor was defined by the
2035193326Sed  /// user. This operation can only be invoked if the constructor has
2036193326Sed  /// already been defined.
2037207619Srdivacky  bool isImplicitlyDefined() const {
2038198092Srdivacky    assert(isThisDeclarationADefinition() &&
2039195341Sed           "Can only get the implicit-definition flag once the "
2040195341Sed           "constructor has been defined");
2041198092Srdivacky    return ImplicitlyDefined;
2042193326Sed  }
2043193326Sed
2044193326Sed  /// setImplicitlyDefined - Set whether this constructor was
2045193326Sed  /// implicitly defined or not.
2046198092Srdivacky  void setImplicitlyDefined(bool ID) {
2047198092Srdivacky    assert(isThisDeclarationADefinition() &&
2048195341Sed           "Can only set the implicit-definition flag once the constructor "
2049195341Sed           "has been defined");
2050198092Srdivacky    ImplicitlyDefined = ID;
2051193326Sed  }
2052198092Srdivacky
2053195341Sed  /// init_iterator - Iterates through the member/base initializer list.
2054218893Sdim  typedef CXXCtorInitializer **init_iterator;
2055198092Srdivacky
2056195341Sed  /// init_const_iterator - Iterates through the memberbase initializer list.
2057218893Sdim  typedef CXXCtorInitializer * const * init_const_iterator;
2058198092Srdivacky
2059198092Srdivacky  /// init_begin() - Retrieve an iterator to the first initializer.
2060218893Sdim  init_iterator       init_begin()       { return CtorInitializers; }
2061195341Sed  /// begin() - Retrieve an iterator to the first initializer.
2062218893Sdim  init_const_iterator init_begin() const { return CtorInitializers; }
2063198092Srdivacky
2064198092Srdivacky  /// init_end() - Retrieve an iterator past the last initializer.
2065198092Srdivacky  init_iterator       init_end()       {
2066218893Sdim    return CtorInitializers + NumCtorInitializers;
2067195341Sed  }
2068195341Sed  /// end() - Retrieve an iterator past the last initializer.
2069198092Srdivacky  init_const_iterator init_end() const {
2070218893Sdim    return CtorInitializers + NumCtorInitializers;
2071195341Sed  }
2072198092Srdivacky
2073218893Sdim  typedef std::reverse_iterator<init_iterator> init_reverse_iterator;
2074234353Sdim  typedef std::reverse_iterator<init_const_iterator>
2075234353Sdim          init_const_reverse_iterator;
2076218893Sdim
2077218893Sdim  init_reverse_iterator init_rbegin() {
2078218893Sdim    return init_reverse_iterator(init_end());
2079218893Sdim  }
2080218893Sdim  init_const_reverse_iterator init_rbegin() const {
2081218893Sdim    return init_const_reverse_iterator(init_end());
2082218893Sdim  }
2083218893Sdim
2084218893Sdim  init_reverse_iterator init_rend() {
2085218893Sdim    return init_reverse_iterator(init_begin());
2086218893Sdim  }
2087218893Sdim  init_const_reverse_iterator init_rend() const {
2088218893Sdim    return init_const_reverse_iterator(init_begin());
2089218893Sdim  }
2090218893Sdim
2091195341Sed  /// getNumArgs - Determine the number of arguments used to
2092195341Sed  /// initialize the member or base.
2093218893Sdim  unsigned getNumCtorInitializers() const {
2094218893Sdim      return NumCtorInitializers;
2095195341Sed  }
2096198092Srdivacky
2097218893Sdim  void setNumCtorInitializers(unsigned numCtorInitializers) {
2098218893Sdim    NumCtorInitializers = numCtorInitializers;
2099198092Srdivacky  }
2100198092Srdivacky
2101218893Sdim  void setCtorInitializers(CXXCtorInitializer ** initializers) {
2102218893Sdim    CtorInitializers = initializers;
2103198092Srdivacky  }
2104221345Sdim
2105221345Sdim  /// isDelegatingConstructor - Whether this constructor is a
2106221345Sdim  /// delegating constructor
2107221345Sdim  bool isDelegatingConstructor() const {
2108221345Sdim    return (getNumCtorInitializers() == 1) &&
2109221345Sdim      CtorInitializers[0]->isDelegatingInitializer();
2110221345Sdim  }
2111221345Sdim
2112221345Sdim  /// getTargetConstructor - When this constructor delegates to
2113221345Sdim  /// another, retrieve the target
2114234353Sdim  CXXConstructorDecl *getTargetConstructor() const;
2115221345Sdim
2116193326Sed  /// isDefaultConstructor - Whether this constructor is a default
2117193326Sed  /// constructor (C++ [class.ctor]p5), which can be used to
2118193326Sed  /// default-initialize a class of this type.
2119193326Sed  bool isDefaultConstructor() const;
2120193326Sed
2121193326Sed  /// isCopyConstructor - Whether this constructor is a copy
2122193326Sed  /// constructor (C++ [class.copy]p2, which can be used to copy the
2123193326Sed  /// class. @p TypeQuals will be set to the qualifiers on the
2124193326Sed  /// argument type. For example, @p TypeQuals would be set to @c
2125249423Sdim  /// Qualifiers::Const for the following copy constructor:
2126193326Sed  ///
2127193326Sed  /// @code
2128193326Sed  /// class X {
2129193326Sed  /// public:
2130193326Sed  ///   X(const X&);
2131193326Sed  /// };
2132193326Sed  /// @endcode
2133201361Srdivacky  bool isCopyConstructor(unsigned &TypeQuals) const;
2134193326Sed
2135193326Sed  /// isCopyConstructor - Whether this constructor is a copy
2136193326Sed  /// constructor (C++ [class.copy]p2, which can be used to copy the
2137193326Sed  /// class.
2138201361Srdivacky  bool isCopyConstructor() const {
2139193326Sed    unsigned TypeQuals = 0;
2140201361Srdivacky    return isCopyConstructor(TypeQuals);
2141193326Sed  }
2142193326Sed
2143218893Sdim  /// \brief Determine whether this constructor is a move constructor
2144218893Sdim  /// (C++0x [class.copy]p3), which can be used to move values of the class.
2145218893Sdim  ///
2146218893Sdim  /// \param TypeQuals If this constructor is a move constructor, will be set
2147218893Sdim  /// to the type qualifiers on the referent of the first parameter's type.
2148218893Sdim  bool isMoveConstructor(unsigned &TypeQuals) const;
2149218893Sdim
2150218893Sdim  /// \brief Determine whether this constructor is a move constructor
2151218893Sdim  /// (C++0x [class.copy]p3), which can be used to move values of the class.
2152221345Sdim  bool isMoveConstructor() const {
2153221345Sdim    unsigned TypeQuals = 0;
2154221345Sdim    return isMoveConstructor(TypeQuals);
2155221345Sdim  }
2156221345Sdim
2157218893Sdim  /// \brief Determine whether this is a copy or move constructor.
2158218893Sdim  ///
2159218893Sdim  /// \param TypeQuals Will be set to the type qualifiers on the reference
2160218893Sdim  /// parameter, if in fact this is a copy or move constructor.
2161218893Sdim  bool isCopyOrMoveConstructor(unsigned &TypeQuals) const;
2162218893Sdim
2163218893Sdim  /// \brief Determine whether this a copy or move constructor.
2164218893Sdim  bool isCopyOrMoveConstructor() const {
2165218893Sdim    unsigned Quals;
2166218893Sdim    return isCopyOrMoveConstructor(Quals);
2167218893Sdim  }
2168218893Sdim
2169193326Sed  /// isConvertingConstructor - Whether this constructor is a
2170193326Sed  /// converting constructor (C++ [class.conv.ctor]), which can be
2171193326Sed  /// used for user-defined conversions.
2172198092Srdivacky  bool isConvertingConstructor(bool AllowExplicit) const;
2173193326Sed
2174199482Srdivacky  /// \brief Determine whether this is a member template specialization that
2175218893Sdim  /// would copy the object to itself. Such constructors are never used to copy
2176199482Srdivacky  /// an object.
2177218893Sdim  bool isSpecializationCopyingObject() const;
2178218893Sdim
2179218893Sdim  /// \brief Get the constructor that this inheriting constructor is based on.
2180218893Sdim  const CXXConstructorDecl *getInheritedConstructor() const;
2181218893Sdim
2182218893Sdim  /// \brief Set the constructor that this inheriting constructor is based on.
2183218893Sdim  void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
2184223017Sdim
2185223017Sdim  const CXXConstructorDecl *getCanonicalDecl() const {
2186223017Sdim    return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
2187223017Sdim  }
2188223017Sdim  CXXConstructorDecl *getCanonicalDecl() {
2189223017Sdim    return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
2190223017Sdim  }
2191234353Sdim
2192193326Sed  // Implement isa/cast/dyncast/etc.
2193203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2194203955Srdivacky  static bool classofKind(Kind K) { return K == CXXConstructor; }
2195234353Sdim
2196212904Sdim  friend class ASTDeclReader;
2197212904Sdim  friend class ASTDeclWriter;
2198193326Sed};
2199193326Sed
2200193326Sed/// CXXDestructorDecl - Represents a C++ destructor within a
2201193326Sed/// class. For example:
2202198092Srdivacky///
2203193326Sed/// @code
2204193326Sed/// class X {
2205193326Sed/// public:
2206193326Sed///   ~X(); // represented by a CXXDestructorDecl.
2207193326Sed/// };
2208193326Sed/// @endcode
2209193326Sedclass CXXDestructorDecl : public CXXMethodDecl {
2210234353Sdim  virtual void anchor();
2211193326Sed  /// ImplicitlyDefined - Whether this destructor was implicitly
2212193326Sed  /// defined by the compiler. When false, the destructor was defined
2213193326Sed  /// by the user. In C++03, this flag will have the same value as
2214193326Sed  /// Implicit. In C++0x, however, a destructor that is
2215193326Sed  /// explicitly defaulted (i.e., defined with " = default") will have
2216193326Sed  /// @c !Implicit && ImplicitlyDefined.
2217193326Sed  bool ImplicitlyDefined : 1;
2218193326Sed
2219199482Srdivacky  FunctionDecl *OperatorDelete;
2220234353Sdim
2221221345Sdim  CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
2222221345Sdim                    const DeclarationNameInfo &NameInfo,
2223218893Sdim                    QualType T, TypeSourceInfo *TInfo,
2224218893Sdim                    bool isInline, bool isImplicitlyDeclared)
2225249423Sdim    : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo,
2226226633Sdim                    SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
2227199482Srdivacky      ImplicitlyDefined(false), OperatorDelete(0) {
2228193326Sed    setImplicit(isImplicitlyDeclared);
2229193326Sed  }
2230193326Sed
2231193326Sedpublic:
2232193326Sed  static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
2233221345Sdim                                   SourceLocation StartLoc,
2234212904Sdim                                   const DeclarationNameInfo &NameInfo,
2235218893Sdim                                   QualType T, TypeSourceInfo* TInfo,
2236218893Sdim                                   bool isInline,
2237193326Sed                                   bool isImplicitlyDeclared);
2238234353Sdim  static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
2239193326Sed
2240193326Sed  /// isImplicitlyDefined - Whether this destructor was implicitly
2241193326Sed  /// defined. If false, then this destructor was defined by the
2242193326Sed  /// user. This operation can only be invoked if the destructor has
2243193326Sed  /// already been defined.
2244198092Srdivacky  bool isImplicitlyDefined() const {
2245198092Srdivacky    assert(isThisDeclarationADefinition() &&
2246234353Sdim           "Can only get the implicit-definition flag once the destructor has "
2247234353Sdim           "been defined");
2248198092Srdivacky    return ImplicitlyDefined;
2249193326Sed  }
2250193326Sed
2251193326Sed  /// setImplicitlyDefined - Set whether this destructor was
2252193326Sed  /// implicitly defined or not.
2253198092Srdivacky  void setImplicitlyDefined(bool ID) {
2254198092Srdivacky    assert(isThisDeclarationADefinition() &&
2255234353Sdim           "Can only set the implicit-definition flag once the destructor has "
2256234353Sdim           "been defined");
2257198092Srdivacky    ImplicitlyDefined = ID;
2258193326Sed  }
2259193326Sed
2260199482Srdivacky  void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
2261199482Srdivacky  const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
2262198092Srdivacky
2263193326Sed  // Implement isa/cast/dyncast/etc.
2264203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2265203955Srdivacky  static bool classofKind(Kind K) { return K == CXXDestructor; }
2266234353Sdim
2267212904Sdim  friend class ASTDeclReader;
2268212904Sdim  friend class ASTDeclWriter;
2269193326Sed};
2270193326Sed
2271193326Sed/// CXXConversionDecl - Represents a C++ conversion function within a
2272193326Sed/// class. For example:
2273198092Srdivacky///
2274193326Sed/// @code
2275193326Sed/// class X {
2276193326Sed/// public:
2277193326Sed///   operator bool();
2278193326Sed/// };
2279193326Sed/// @endcode
2280193326Sedclass CXXConversionDecl : public CXXMethodDecl {
2281234353Sdim  virtual void anchor();
2282234353Sdim  /// IsExplicitSpecified - Whether this conversion function declaration is
2283203955Srdivacky  /// marked "explicit", meaning that it can only be applied when the user
2284193326Sed  /// explicitly wrote a cast. This is a C++0x feature.
2285203955Srdivacky  bool IsExplicitSpecified : 1;
2286193326Sed
2287221345Sdim  CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
2288221345Sdim                    const DeclarationNameInfo &NameInfo,
2289212904Sdim                    QualType T, TypeSourceInfo *TInfo,
2290221345Sdim                    bool isInline, bool isExplicitSpecified,
2291226633Sdim                    bool isConstexpr, SourceLocation EndLocation)
2292249423Sdim    : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo,
2293226633Sdim                    SC_None, isInline, isConstexpr, EndLocation),
2294203955Srdivacky      IsExplicitSpecified(isExplicitSpecified) { }
2295193326Sed
2296193326Sedpublic:
2297193326Sed  static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
2298221345Sdim                                   SourceLocation StartLoc,
2299212904Sdim                                   const DeclarationNameInfo &NameInfo,
2300200583Srdivacky                                   QualType T, TypeSourceInfo *TInfo,
2301221345Sdim                                   bool isInline, bool isExplicit,
2302226633Sdim                                   bool isConstexpr,
2303221345Sdim                                   SourceLocation EndLocation);
2304234353Sdim  static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2305193326Sed
2306234353Sdim  /// IsExplicitSpecified - Whether this conversion function declaration is
2307203955Srdivacky  /// marked "explicit", meaning that it can only be applied when the user
2308203955Srdivacky  /// explicitly wrote a cast. This is a C++0x feature.
2309203955Srdivacky  bool isExplicitSpecified() const { return IsExplicitSpecified; }
2310203955Srdivacky
2311193326Sed  /// isExplicit - Whether this is an explicit conversion operator
2312193326Sed  /// (C++0x only). Explicit conversion operators are only considered
2313193326Sed  /// when the user has explicitly written a cast.
2314203955Srdivacky  bool isExplicit() const {
2315203955Srdivacky    return cast<CXXConversionDecl>(getFirstDeclaration())
2316203955Srdivacky      ->isExplicitSpecified();
2317203955Srdivacky  }
2318193326Sed
2319193326Sed  /// getConversionType - Returns the type that this conversion
2320193326Sed  /// function is converting to.
2321198092Srdivacky  QualType getConversionType() const {
2322198092Srdivacky    return getType()->getAs<FunctionType>()->getResultType();
2323193326Sed  }
2324193326Sed
2325234353Sdim  /// \brief Determine whether this conversion function is a conversion from
2326234353Sdim  /// a lambda closure type to a block pointer.
2327234353Sdim  bool isLambdaToBlockPointerConversion() const;
2328234353Sdim
2329193326Sed  // Implement isa/cast/dyncast/etc.
2330203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2331203955Srdivacky  static bool classofKind(Kind K) { return K == CXXConversion; }
2332234353Sdim
2333212904Sdim  friend class ASTDeclReader;
2334212904Sdim  friend class ASTDeclWriter;
2335193326Sed};
2336193326Sed
2337193326Sed/// LinkageSpecDecl - This represents a linkage specification.  For example:
2338193326Sed///   extern "C" void foo();
2339193326Sed///
2340193326Sedclass LinkageSpecDecl : public Decl, public DeclContext {
2341234353Sdim  virtual void anchor();
2342193326Sedpublic:
2343193326Sed  /// LanguageIDs - Used to represent the language in a linkage
2344193326Sed  /// specification.  The values are part of the serialization abi for
2345193326Sed  /// ASTs and cannot be changed without altering that abi.  To help
2346193326Sed  /// ensure a stable abi for this, we choose the DW_LANG_ encodings
2347193326Sed  /// from the dwarf standard.
2348208600Srdivacky  enum LanguageIDs {
2349208600Srdivacky    lang_c = /* DW_LANG_C */ 0x0002,
2350208600Srdivacky    lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
2351208600Srdivacky  };
2352193326Sedprivate:
2353193326Sed  /// Language - The language for this linkage specification.
2354251662Sdim  unsigned Language : 3;
2355251662Sdim  /// True if this linkage spec has brances. This is needed so that hasBraces()
2356251662Sdim  /// returns the correct result while the linkage spec body is being parsed.
2357251662Sdim  /// Once RBraceLoc has been set this is not used, so it doesn't need to be
2358251662Sdim  /// serialized.
2359251662Sdim  unsigned HasBraces : 1;
2360221345Sdim  /// ExternLoc - The source location for the extern keyword.
2361221345Sdim  SourceLocation ExternLoc;
2362221345Sdim  /// RBraceLoc - The source location for the right brace (if valid).
2363221345Sdim  SourceLocation RBraceLoc;
2364193326Sed
2365221345Sdim  LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
2366251662Sdim                  SourceLocation LangLoc, LanguageIDs lang, bool HasBraces)
2367221345Sdim    : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
2368251662Sdim      Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc),
2369251662Sdim      RBraceLoc(SourceLocation()) { }
2370193326Sed
2371193326Sedpublic:
2372198092Srdivacky  static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
2373221345Sdim                                 SourceLocation ExternLoc,
2374221345Sdim                                 SourceLocation LangLoc, LanguageIDs Lang,
2375251662Sdim                                 bool HasBraces);
2376234353Sdim  static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2377234353Sdim
2378208600Srdivacky  /// \brief Return the language specified by this linkage specification.
2379251662Sdim  LanguageIDs getLanguage() const { return LanguageIDs(Language); }
2380208600Srdivacky  /// \brief Set the language specified by this linkage specification.
2381208600Srdivacky  void setLanguage(LanguageIDs L) { Language = L; }
2382208600Srdivacky
2383208600Srdivacky  /// \brief Determines whether this linkage specification had braces in
2384208600Srdivacky  /// its syntactic form.
2385251662Sdim  bool hasBraces() const {
2386251662Sdim    assert(!RBraceLoc.isValid() || HasBraces);
2387251662Sdim    return HasBraces;
2388251662Sdim  }
2389193326Sed
2390221345Sdim  SourceLocation getExternLoc() const { return ExternLoc; }
2391221345Sdim  SourceLocation getRBraceLoc() const { return RBraceLoc; }
2392221345Sdim  void setExternLoc(SourceLocation L) { ExternLoc = L; }
2393251662Sdim  void setRBraceLoc(SourceLocation L) {
2394251662Sdim    RBraceLoc = L;
2395251662Sdim    HasBraces = RBraceLoc.isValid();
2396251662Sdim  }
2397208600Srdivacky
2398234353Sdim  SourceLocation getLocEnd() const LLVM_READONLY {
2399221345Sdim    if (hasBraces())
2400221345Sdim      return getRBraceLoc();
2401221345Sdim    // No braces: get the end location of the (only) declaration in context
2402221345Sdim    // (if present).
2403221345Sdim    return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
2404221345Sdim  }
2405221345Sdim
2406234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
2407221345Sdim    return SourceRange(ExternLoc, getLocEnd());
2408221345Sdim  }
2409221345Sdim
2410203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2411203955Srdivacky  static bool classofKind(Kind K) { return K == LinkageSpec; }
2412193326Sed  static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
2413193326Sed    return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
2414193326Sed  }
2415193326Sed  static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) {
2416193326Sed    return static_cast<LinkageSpecDecl *>(const_cast<DeclContext*>(DC));
2417193326Sed  }
2418193326Sed};
2419193326Sed
2420193326Sed/// UsingDirectiveDecl - Represents C++ using-directive. For example:
2421193326Sed///
2422193326Sed///    using namespace std;
2423193326Sed///
2424193326Sed// NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide
2425234353Sdim// artificial names for all using-directives in order to store
2426193326Sed// them in DeclContext effectively.
2427193326Sedclass UsingDirectiveDecl : public NamedDecl {
2428234353Sdim  virtual void anchor();
2429212904Sdim  /// \brief The location of the "using" keyword.
2430212904Sdim  SourceLocation UsingLoc;
2431234353Sdim
2432193326Sed  /// SourceLocation - Location of 'namespace' token.
2433193326Sed  SourceLocation NamespaceLoc;
2434193326Sed
2435219077Sdim  /// \brief The nested-name-specifier that precedes the namespace.
2436219077Sdim  NestedNameSpecifierLoc QualifierLoc;
2437193326Sed
2438193326Sed  /// NominatedNamespace - Namespace nominated by using-directive.
2439199990Srdivacky  NamedDecl *NominatedNamespace;
2440193326Sed
2441199990Srdivacky  /// Enclosing context containing both using-directive and nominated
2442193326Sed  /// namespace.
2443193326Sed  DeclContext *CommonAncestor;
2444193326Sed
2445193326Sed  /// getUsingDirectiveName - Returns special DeclarationName used by
2446193326Sed  /// using-directives. This is only used by DeclContext for storing
2447193326Sed  /// UsingDirectiveDecls in its lookup structure.
2448193326Sed  static DeclarationName getName() {
2449193326Sed    return DeclarationName::getUsingDirectiveName();
2450193326Sed  }
2451193326Sed
2452212904Sdim  UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc,
2453193326Sed                     SourceLocation NamespcLoc,
2454219077Sdim                     NestedNameSpecifierLoc QualifierLoc,
2455193326Sed                     SourceLocation IdentLoc,
2456199990Srdivacky                     NamedDecl *Nominated,
2457193326Sed                     DeclContext *CommonAncestor)
2458212904Sdim    : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc),
2459219077Sdim      NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc),
2460219077Sdim      NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { }
2461193326Sed
2462193326Sedpublic:
2463193326Sed  /// \brief Retrieve the nested-name-specifier that qualifies the
2464219077Sdim  /// name of the namespace, with source-location information.
2465219077Sdim  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
2466234353Sdim
2467219077Sdim  /// \brief Retrieve the nested-name-specifier that qualifies the
2468193326Sed  /// name of the namespace.
2469234353Sdim  NestedNameSpecifier *getQualifier() const {
2470234353Sdim    return QualifierLoc.getNestedNameSpecifier();
2471219077Sdim  }
2472193326Sed
2473199990Srdivacky  NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
2474199990Srdivacky  const NamedDecl *getNominatedNamespaceAsWritten() const {
2475199990Srdivacky    return NominatedNamespace;
2476199990Srdivacky  }
2477199990Srdivacky
2478193326Sed  /// getNominatedNamespace - Returns namespace nominated by using-directive.
2479199990Srdivacky  NamespaceDecl *getNominatedNamespace();
2480193326Sed
2481193326Sed  const NamespaceDecl *getNominatedNamespace() const {
2482193326Sed    return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
2483193326Sed  }
2484193326Sed
2485208600Srdivacky  /// \brief Returns the common ancestor context of this using-directive and
2486208600Srdivacky  /// its nominated namespace.
2487193326Sed  DeclContext *getCommonAncestor() { return CommonAncestor; }
2488193326Sed  const DeclContext *getCommonAncestor() const { return CommonAncestor; }
2489193326Sed
2490212904Sdim  /// \brief Return the location of the "using" keyword.
2491212904Sdim  SourceLocation getUsingLoc() const { return UsingLoc; }
2492234353Sdim
2493208600Srdivacky  // FIXME: Could omit 'Key' in name.
2494193326Sed  /// getNamespaceKeyLocation - Returns location of namespace keyword.
2495193326Sed  SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
2496193326Sed
2497193326Sed  /// getIdentLocation - Returns location of identifier.
2498212904Sdim  SourceLocation getIdentLocation() const { return getLocation(); }
2499193326Sed
2500193326Sed  static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
2501212904Sdim                                    SourceLocation UsingLoc,
2502193326Sed                                    SourceLocation NamespaceLoc,
2503219077Sdim                                    NestedNameSpecifierLoc QualifierLoc,
2504193326Sed                                    SourceLocation IdentLoc,
2505199990Srdivacky                                    NamedDecl *Nominated,
2506193326Sed                                    DeclContext *CommonAncestor);
2507234353Sdim  static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2508234353Sdim
2509234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
2510212904Sdim    return SourceRange(UsingLoc, getLocation());
2511212904Sdim  }
2512234353Sdim
2513203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2514210299Sed  static bool classofKind(Kind K) { return K == UsingDirective; }
2515193326Sed
2516193326Sed  // Friend for getUsingDirectiveName.
2517193326Sed  friend class DeclContext;
2518234353Sdim
2519212904Sdim  friend class ASTDeclReader;
2520193326Sed};
2521193326Sed
2522239462Sdim/// \brief Represents a C++ namespace alias.
2523193326Sed///
2524239462Sdim/// For example:
2525239462Sdim///
2526193326Sed/// @code
2527193326Sed/// namespace Foo = Bar;
2528193326Sed/// @endcode
2529193326Sedclass NamespaceAliasDecl : public NamedDecl {
2530234353Sdim  virtual void anchor();
2531234353Sdim
2532212904Sdim  /// \brief The location of the "namespace" keyword.
2533212904Sdim  SourceLocation NamespaceLoc;
2534193326Sed
2535208600Srdivacky  /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc.
2536193326Sed  SourceLocation IdentLoc;
2537234353Sdim
2538219077Sdim  /// \brief The nested-name-specifier that precedes the namespace.
2539219077Sdim  NestedNameSpecifierLoc QualifierLoc;
2540234353Sdim
2541198092Srdivacky  /// Namespace - The Decl that this alias points to. Can either be a
2542193326Sed  /// NamespaceDecl or a NamespaceAliasDecl.
2543193326Sed  NamedDecl *Namespace;
2544198092Srdivacky
2545212904Sdim  NamespaceAliasDecl(DeclContext *DC, SourceLocation NamespaceLoc,
2546198092Srdivacky                     SourceLocation AliasLoc, IdentifierInfo *Alias,
2547219077Sdim                     NestedNameSpecifierLoc QualifierLoc,
2548193326Sed                     SourceLocation IdentLoc, NamedDecl *Namespace)
2549234353Sdim    : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias),
2550219077Sdim      NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
2551219077Sdim      QualifierLoc(QualifierLoc), Namespace(Namespace) { }
2552193326Sed
2553212904Sdim  friend class ASTDeclReader;
2554234353Sdim
2555193326Sedpublic:
2556193326Sed  /// \brief Retrieve the nested-name-specifier that qualifies the
2557219077Sdim  /// name of the namespace, with source-location information.
2558219077Sdim  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
2559234353Sdim
2560219077Sdim  /// \brief Retrieve the nested-name-specifier that qualifies the
2561193326Sed  /// name of the namespace.
2562234353Sdim  NestedNameSpecifier *getQualifier() const {
2563234353Sdim    return QualifierLoc.getNestedNameSpecifier();
2564219077Sdim  }
2565234353Sdim
2566208600Srdivacky  /// \brief Retrieve the namespace declaration aliased by this directive.
2567193326Sed  NamespaceDecl *getNamespace() {
2568193326Sed    if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
2569193326Sed      return AD->getNamespace();
2570193326Sed
2571193326Sed    return cast<NamespaceDecl>(Namespace);
2572193326Sed  }
2573198092Srdivacky
2574193326Sed  const NamespaceDecl *getNamespace() const {
2575193326Sed    return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
2576193326Sed  }
2577193326Sed
2578203955Srdivacky  /// Returns the location of the alias name, i.e. 'foo' in
2579203955Srdivacky  /// "namespace foo = ns::bar;".
2580212904Sdim  SourceLocation getAliasLoc() const { return getLocation(); }
2581203955Srdivacky
2582203955Srdivacky  /// Returns the location of the 'namespace' keyword.
2583212904Sdim  SourceLocation getNamespaceLoc() const { return NamespaceLoc; }
2584203955Srdivacky
2585203955Srdivacky  /// Returns the location of the identifier in the named namespace.
2586203955Srdivacky  SourceLocation getTargetNameLoc() const { return IdentLoc; }
2587203955Srdivacky
2588193326Sed  /// \brief Retrieve the namespace that this alias refers to, which
2589193326Sed  /// may either be a NamespaceDecl or a NamespaceAliasDecl.
2590193326Sed  NamedDecl *getAliasedNamespace() const { return Namespace; }
2591193326Sed
2592198092Srdivacky  static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
2593234353Sdim                                    SourceLocation NamespaceLoc,
2594212904Sdim                                    SourceLocation AliasLoc,
2595198092Srdivacky                                    IdentifierInfo *Alias,
2596219077Sdim                                    NestedNameSpecifierLoc QualifierLoc,
2597198092Srdivacky                                    SourceLocation IdentLoc,
2598193326Sed                                    NamedDecl *Namespace);
2599198092Srdivacky
2600234353Sdim  static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2601234353Sdim
2602234353Sdim  virtual SourceRange getSourceRange() const LLVM_READONLY {
2603212904Sdim    return SourceRange(NamespaceLoc, IdentLoc);
2604212904Sdim  }
2605234353Sdim
2606203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2607210299Sed  static bool classofKind(Kind K) { return K == NamespaceAlias; }
2608193326Sed};
2609194613Sed
2610239462Sdim/// \brief Represents a shadow declaration introduced into a scope by a
2611239462Sdim/// (resolved) using declaration.
2612199482Srdivacky///
2613239462Sdim/// For example,
2614239462Sdim/// @code
2615199482Srdivacky/// namespace A {
2616199482Srdivacky///   void foo();
2617199482Srdivacky/// }
2618199482Srdivacky/// namespace B {
2619239462Sdim///   using A::foo; // <- a UsingDecl
2620239462Sdim///                 // Also creates a UsingShadowDecl for A::foo() in B
2621199482Srdivacky/// }
2622239462Sdim/// @endcode
2623199482Srdivackyclass UsingShadowDecl : public NamedDecl {
2624234353Sdim  virtual void anchor();
2625234353Sdim
2626199482Srdivacky  /// The referenced declaration.
2627199482Srdivacky  NamedDecl *Underlying;
2628199482Srdivacky
2629218893Sdim  /// \brief The using declaration which introduced this decl or the next using
2630218893Sdim  /// shadow declaration contained in the aforementioned using declaration.
2631218893Sdim  NamedDecl *UsingOrNextShadow;
2632218893Sdim  friend class UsingDecl;
2633199482Srdivacky
2634199482Srdivacky  UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
2635199482Srdivacky                  NamedDecl *Target)
2636210299Sed    : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
2637218893Sdim      Underlying(Target),
2638218893Sdim      UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
2639210299Sed    if (Target) {
2640210299Sed      setDeclName(Target->getDeclName());
2641210299Sed      IdentifierNamespace = Target->getIdentifierNamespace();
2642210299Sed    }
2643199482Srdivacky    setImplicit();
2644199482Srdivacky  }
2645199482Srdivacky
2646199482Srdivackypublic:
2647199482Srdivacky  static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
2648199482Srdivacky                                 SourceLocation Loc, UsingDecl *Using,
2649199482Srdivacky                                 NamedDecl *Target) {
2650199482Srdivacky    return new (C) UsingShadowDecl(DC, Loc, Using, Target);
2651199482Srdivacky  }
2652199482Srdivacky
2653234353Sdim  static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2654234353Sdim
2655208600Srdivacky  /// \brief Gets the underlying declaration which has been brought into the
2656199482Srdivacky  /// local scope.
2657208600Srdivacky  NamedDecl *getTargetDecl() const { return Underlying; }
2658199482Srdivacky
2659208600Srdivacky  /// \brief Sets the underlying declaration which has been brought into the
2660208600Srdivacky  /// local scope.
2661210299Sed  void setTargetDecl(NamedDecl* ND) {
2662210299Sed    assert(ND && "Target decl is null!");
2663210299Sed    Underlying = ND;
2664210299Sed    IdentifierNamespace = ND->getIdentifierNamespace();
2665210299Sed  }
2666199482Srdivacky
2667208600Srdivacky  /// \brief Gets the using declaration to which this declaration is tied.
2668218893Sdim  UsingDecl *getUsingDecl() const;
2669208600Srdivacky
2670218893Sdim  /// \brief The next using shadow declaration contained in the shadow decl
2671218893Sdim  /// chain of the using declaration which introduced this decl.
2672218893Sdim  UsingShadowDecl *getNextUsingShadowDecl() const {
2673218893Sdim    return dyn_cast_or_null<UsingShadowDecl>(UsingOrNextShadow);
2674218893Sdim  }
2675208600Srdivacky
2676203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2677203955Srdivacky  static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
2678218893Sdim
2679218893Sdim  friend class ASTDeclReader;
2680218893Sdim  friend class ASTDeclWriter;
2681199482Srdivacky};
2682199482Srdivacky
2683239462Sdim/// \brief Represents a C++ using-declaration.
2684239462Sdim///
2685239462Sdim/// For example:
2686239462Sdim/// @code
2687194613Sed///    using someNameSpace::someIdentifier;
2688239462Sdim/// @endcode
2689194613Sedclass UsingDecl : public NamedDecl {
2690234353Sdim  virtual void anchor();
2691234353Sdim
2692194613Sed  /// \brief The source location of the "using" location itself.
2693194613Sed  SourceLocation UsingLocation;
2694198092Srdivacky
2695219077Sdim  /// \brief The nested-name-specifier that precedes the name.
2696219077Sdim  NestedNameSpecifierLoc QualifierLoc;
2697194613Sed
2698212904Sdim  /// DNLoc - Provides source/type location info for the
2699212904Sdim  /// declaration name embedded in the ValueDecl base class.
2700212904Sdim  DeclarationNameLoc DNLoc;
2701212904Sdim
2702218893Sdim  /// \brief The first shadow declaration of the shadow decl chain associated
2703239462Sdim  /// with this using declaration.
2704239462Sdim  ///
2705239462Sdim  /// The bool member of the pair store whether this decl has the \c typename
2706239462Sdim  /// keyword.
2707234353Sdim  llvm::PointerIntPair<UsingShadowDecl *, 1, bool> FirstUsingShadow;
2708199482Srdivacky
2709234353Sdim  UsingDecl(DeclContext *DC, SourceLocation UL,
2710219077Sdim            NestedNameSpecifierLoc QualifierLoc,
2711212904Sdim            const DeclarationNameInfo &NameInfo, bool IsTypeNameArg)
2712212904Sdim    : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
2713219077Sdim      UsingLocation(UL), QualifierLoc(QualifierLoc),
2714234353Sdim      DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, IsTypeNameArg) {
2715194613Sed  }
2716194613Sed
2717194613Sedpublic:
2718208600Srdivacky  /// \brief Returns the source location of the "using" keyword.
2719212904Sdim  SourceLocation getUsingLocation() const { return UsingLocation; }
2720198092Srdivacky
2721208600Srdivacky  /// \brief Set the source location of the 'using' keyword.
2722208600Srdivacky  void setUsingLocation(SourceLocation L) { UsingLocation = L; }
2723208600Srdivacky
2724219077Sdim  /// \brief Retrieve the nested-name-specifier that qualifies the name,
2725219077Sdim  /// with source-location information.
2726219077Sdim  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
2727219077Sdim
2728219077Sdim  /// \brief Retrieve the nested-name-specifier that qualifies the name.
2729234353Sdim  NestedNameSpecifier *getQualifier() const {
2730234353Sdim    return QualifierLoc.getNestedNameSpecifier();
2731195099Sed  }
2732198092Srdivacky
2733212904Sdim  DeclarationNameInfo getNameInfo() const {
2734212904Sdim    return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
2735212904Sdim  }
2736212904Sdim
2737208600Srdivacky  /// \brief Return true if the using declaration has 'typename'.
2738234353Sdim  bool isTypeName() const { return FirstUsingShadow.getInt(); }
2739194613Sed
2740208600Srdivacky  /// \brief Sets whether the using declaration has 'typename'.
2741234353Sdim  void setTypeName(bool TN) { FirstUsingShadow.setInt(TN); }
2742208600Srdivacky
2743218893Sdim  /// \brief Iterates through the using shadow declarations assosiated with
2744218893Sdim  /// this using declaration.
2745218893Sdim  class shadow_iterator {
2746218893Sdim    /// \brief The current using shadow declaration.
2747218893Sdim    UsingShadowDecl *Current;
2748199482Srdivacky
2749218893Sdim  public:
2750218893Sdim    typedef UsingShadowDecl*          value_type;
2751218893Sdim    typedef UsingShadowDecl*          reference;
2752218893Sdim    typedef UsingShadowDecl*          pointer;
2753218893Sdim    typedef std::forward_iterator_tag iterator_category;
2754218893Sdim    typedef std::ptrdiff_t            difference_type;
2755218893Sdim
2756218893Sdim    shadow_iterator() : Current(0) { }
2757218893Sdim    explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
2758218893Sdim
2759218893Sdim    reference operator*() const { return Current; }
2760218893Sdim    pointer operator->() const { return Current; }
2761218893Sdim
2762218893Sdim    shadow_iterator& operator++() {
2763218893Sdim      Current = Current->getNextUsingShadowDecl();
2764218893Sdim      return *this;
2765199482Srdivacky    }
2766218893Sdim
2767218893Sdim    shadow_iterator operator++(int) {
2768218893Sdim      shadow_iterator tmp(*this);
2769218893Sdim      ++(*this);
2770218893Sdim      return tmp;
2771199482Srdivacky    }
2772218893Sdim
2773218893Sdim    friend bool operator==(shadow_iterator x, shadow_iterator y) {
2774218893Sdim      return x.Current == y.Current;
2775218893Sdim    }
2776218893Sdim    friend bool operator!=(shadow_iterator x, shadow_iterator y) {
2777218893Sdim      return x.Current != y.Current;
2778218893Sdim    }
2779218893Sdim  };
2780218893Sdim
2781218893Sdim  shadow_iterator shadow_begin() const {
2782234353Sdim    return shadow_iterator(FirstUsingShadow.getPointer());
2783199482Srdivacky  }
2784218893Sdim  shadow_iterator shadow_end() const { return shadow_iterator(); }
2785199482Srdivacky
2786208600Srdivacky  /// \brief Return the number of shadowed declarations associated with this
2787208600Srdivacky  /// using declaration.
2788218893Sdim  unsigned shadow_size() const {
2789218893Sdim    return std::distance(shadow_begin(), shadow_end());
2790208600Srdivacky  }
2791208600Srdivacky
2792218893Sdim  void addShadowDecl(UsingShadowDecl *S);
2793218893Sdim  void removeShadowDecl(UsingShadowDecl *S);
2794218893Sdim
2795194613Sed  static UsingDecl *Create(ASTContext &C, DeclContext *DC,
2796219077Sdim                           SourceLocation UsingL,
2797219077Sdim                           NestedNameSpecifierLoc QualifierLoc,
2798212904Sdim                           const DeclarationNameInfo &NameInfo,
2799212904Sdim                           bool IsTypeNameArg);
2800194613Sed
2801234353Sdim  static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2802234353Sdim
2803234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
2804212904Sdim    return SourceRange(UsingLocation, getNameInfo().getEndLoc());
2805212904Sdim  }
2806212904Sdim
2807203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2808210299Sed  static bool classofKind(Kind K) { return K == Using; }
2809210299Sed
2810212904Sdim  friend class ASTDeclReader;
2811212904Sdim  friend class ASTDeclWriter;
2812194613Sed};
2813198092Srdivacky
2814239462Sdim/// \brief Represents a dependent using declaration which was not marked with
2815239462Sdim/// \c typename.
2816239462Sdim///
2817239462Sdim/// Unlike non-dependent using declarations, these *only* bring through
2818199482Srdivacky/// non-types; otherwise they would break two-phase lookup.
2819199482Srdivacky///
2820239462Sdim/// @code
2821239462Sdim/// template \<class T> class A : public Base<T> {
2822199482Srdivacky///   using Base<T>::foo;
2823199482Srdivacky/// };
2824239462Sdim/// @endcode
2825199482Srdivackyclass UnresolvedUsingValueDecl : public ValueDecl {
2826234353Sdim  virtual void anchor();
2827234353Sdim
2828199482Srdivacky  /// \brief The source location of the 'using' keyword
2829199482Srdivacky  SourceLocation UsingLocation;
2830198092Srdivacky
2831219077Sdim  /// \brief The nested-name-specifier that precedes the name.
2832219077Sdim  NestedNameSpecifierLoc QualifierLoc;
2833198092Srdivacky
2834212904Sdim  /// DNLoc - Provides source/type location info for the
2835212904Sdim  /// declaration name embedded in the ValueDecl base class.
2836212904Sdim  DeclarationNameLoc DNLoc;
2837212904Sdim
2838199482Srdivacky  UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
2839234353Sdim                           SourceLocation UsingLoc,
2840219077Sdim                           NestedNameSpecifierLoc QualifierLoc,
2841212904Sdim                           const DeclarationNameInfo &NameInfo)
2842212904Sdim    : ValueDecl(UnresolvedUsingValue, DC,
2843212904Sdim                NameInfo.getLoc(), NameInfo.getName(), Ty),
2844219077Sdim      UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),
2845219077Sdim      DNLoc(NameInfo.getInfo())
2846199482Srdivacky  { }
2847198092Srdivacky
2848199482Srdivackypublic:
2849199482Srdivacky  /// \brief Returns the source location of the 'using' keyword.
2850199482Srdivacky  SourceLocation getUsingLoc() const { return UsingLocation; }
2851199482Srdivacky
2852208600Srdivacky  /// \brief Set the source location of the 'using' keyword.
2853208600Srdivacky  void setUsingLoc(SourceLocation L) { UsingLocation = L; }
2854208600Srdivacky
2855219077Sdim  /// \brief Retrieve the nested-name-specifier that qualifies the name,
2856219077Sdim  /// with source-location information.
2857219077Sdim  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
2858219077Sdim
2859219077Sdim  /// \brief Retrieve the nested-name-specifier that qualifies the name.
2860234353Sdim  NestedNameSpecifier *getQualifier() const {
2861234353Sdim    return QualifierLoc.getNestedNameSpecifier();
2862219077Sdim  }
2863234353Sdim
2864212904Sdim  DeclarationNameInfo getNameInfo() const {
2865212904Sdim    return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
2866212904Sdim  }
2867212904Sdim
2868199482Srdivacky  static UnresolvedUsingValueDecl *
2869199482Srdivacky    Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
2870234353Sdim           NestedNameSpecifierLoc QualifierLoc,
2871212904Sdim           const DeclarationNameInfo &NameInfo);
2872199482Srdivacky
2873234353Sdim  static UnresolvedUsingValueDecl *
2874234353Sdim  CreateDeserialized(ASTContext &C, unsigned ID);
2875234353Sdim
2876234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
2877212904Sdim    return SourceRange(UsingLocation, getNameInfo().getEndLoc());
2878212904Sdim  }
2879212904Sdim
2880203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2881210299Sed  static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
2882218893Sdim
2883218893Sdim  friend class ASTDeclReader;
2884218893Sdim  friend class ASTDeclWriter;
2885199482Srdivacky};
2886199482Srdivacky
2887239462Sdim/// @brief Represents a dependent using declaration which was marked with
2888239462Sdim/// \c typename.
2889199482Srdivacky///
2890239462Sdim/// @code
2891239462Sdim/// template \<class T> class A : public Base<T> {
2892199482Srdivacky///   using typename Base<T>::foo;
2893199482Srdivacky/// };
2894239462Sdim/// @endcode
2895199482Srdivacky///
2896239462Sdim/// The type associated with an unresolved using typename decl is
2897199482Srdivacky/// currently always a typename type.
2898199482Srdivackyclass UnresolvedUsingTypenameDecl : public TypeDecl {
2899234353Sdim  virtual void anchor();
2900234353Sdim
2901199482Srdivacky  /// \brief The source location of the 'using' keyword
2902199482Srdivacky  SourceLocation UsingLocation;
2903199482Srdivacky
2904199482Srdivacky  /// \brief The source location of the 'typename' keyword
2905199482Srdivacky  SourceLocation TypenameLocation;
2906199482Srdivacky
2907219077Sdim  /// \brief The nested-name-specifier that precedes the name.
2908219077Sdim  NestedNameSpecifierLoc QualifierLoc;
2909199482Srdivacky
2910199482Srdivacky  UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
2911219077Sdim                              SourceLocation TypenameLoc,
2912219077Sdim                              NestedNameSpecifierLoc QualifierLoc,
2913234353Sdim                              SourceLocation TargetNameLoc,
2914219077Sdim                              IdentifierInfo *TargetName)
2915221345Sdim    : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
2916221345Sdim               UsingLoc),
2917221345Sdim      TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }
2918199482Srdivacky
2919212904Sdim  friend class ASTDeclReader;
2920234353Sdim
2921198092Srdivackypublic:
2922199482Srdivacky  /// \brief Returns the source location of the 'using' keyword.
2923221345Sdim  SourceLocation getUsingLoc() const { return getLocStart(); }
2924198092Srdivacky
2925199482Srdivacky  /// \brief Returns the source location of the 'typename' keyword.
2926199482Srdivacky  SourceLocation getTypenameLoc() const { return TypenameLocation; }
2927198092Srdivacky
2928219077Sdim  /// \brief Retrieve the nested-name-specifier that qualifies the name,
2929219077Sdim  /// with source-location information.
2930219077Sdim  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
2931219077Sdim
2932219077Sdim  /// \brief Retrieve the nested-name-specifier that qualifies the name.
2933234353Sdim  NestedNameSpecifier *getQualifier() const {
2934234353Sdim    return QualifierLoc.getNestedNameSpecifier();
2935219077Sdim  }
2936219077Sdim
2937199482Srdivacky  static UnresolvedUsingTypenameDecl *
2938199482Srdivacky    Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
2939219077Sdim           SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
2940199482Srdivacky           SourceLocation TargetNameLoc, DeclarationName TargetName);
2941198092Srdivacky
2942234353Sdim  static UnresolvedUsingTypenameDecl *
2943234353Sdim  CreateDeserialized(ASTContext &C, unsigned ID);
2944234353Sdim
2945203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2946210299Sed  static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
2947198092Srdivacky};
2948198092Srdivacky
2949239462Sdim/// \brief Represents a C++11 static_assert declaration.
2950193326Sedclass StaticAssertDecl : public Decl {
2951234353Sdim  virtual void anchor();
2952239462Sdim  llvm::PointerIntPair<Expr *, 1, bool> AssertExprAndFailed;
2953193326Sed  StringLiteral *Message;
2954221345Sdim  SourceLocation RParenLoc;
2955193326Sed
2956221345Sdim  StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc,
2957239462Sdim                   Expr *AssertExpr, StringLiteral *Message,
2958239462Sdim                   SourceLocation RParenLoc, bool Failed)
2959239462Sdim    : Decl(StaticAssert, DC, StaticAssertLoc),
2960239462Sdim      AssertExprAndFailed(AssertExpr, Failed), Message(Message),
2961239462Sdim      RParenLoc(RParenLoc) { }
2962198092Srdivacky
2963193326Sedpublic:
2964193326Sed  static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
2965221345Sdim                                  SourceLocation StaticAssertLoc,
2966221345Sdim                                  Expr *AssertExpr, StringLiteral *Message,
2967239462Sdim                                  SourceLocation RParenLoc, bool Failed);
2968234353Sdim  static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2969234353Sdim
2970239462Sdim  Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); }
2971239462Sdim  const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); }
2972198092Srdivacky
2973193326Sed  StringLiteral *getMessage() { return Message; }
2974193326Sed  const StringLiteral *getMessage() const { return Message; }
2975198092Srdivacky
2976239462Sdim  bool isFailed() const { return AssertExprAndFailed.getInt(); }
2977239462Sdim
2978221345Sdim  SourceLocation getRParenLoc() const { return RParenLoc; }
2979221345Sdim
2980234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
2981221345Sdim    return SourceRange(getLocation(), getRParenLoc());
2982221345Sdim  }
2983221345Sdim
2984203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2985210299Sed  static bool classofKind(Kind K) { return K == StaticAssert; }
2986212904Sdim
2987212904Sdim  friend class ASTDeclReader;
2988193326Sed};
2989193326Sed
2990251662Sdim/// An instance of this class represents the declaration of a property
2991251662Sdim/// member.  This is a Microsoft extension to C++, first introduced in
2992251662Sdim/// Visual Studio .NET 2003 as a parallel to similar features in C#
2993251662Sdim/// and Managed C++.
2994251662Sdim///
2995251662Sdim/// A property must always be a non-static class member.
2996251662Sdim///
2997251662Sdim/// A property member superficially resembles a non-static data
2998251662Sdim/// member, except preceded by a property attribute:
2999251662Sdim///   __declspec(property(get=GetX, put=PutX)) int x;
3000251662Sdim/// Either (but not both) of the 'get' and 'put' names may be omitted.
3001251662Sdim///
3002251662Sdim/// A reference to a property is always an lvalue.  If the lvalue
3003251662Sdim/// undergoes lvalue-to-rvalue conversion, then a getter name is
3004251662Sdim/// required, and that member is called with no arguments.
3005251662Sdim/// If the lvalue is assigned into, then a setter name is required,
3006251662Sdim/// and that member is called with one argument, the value assigned.
3007251662Sdim/// Both operations are potentially overloaded.  Compound assignments
3008251662Sdim/// are permitted, as are the increment and decrement operators.
3009251662Sdim///
3010251662Sdim/// The getter and putter methods are permitted to be overloaded,
3011251662Sdim/// although their return and parameter types are subject to certain
3012251662Sdim/// restrictions according to the type of the property.
3013251662Sdim///
3014251662Sdim/// A property declared using an incomplete array type may
3015251662Sdim/// additionally be subscripted, adding extra parameters to the getter
3016251662Sdim/// and putter methods.
3017251662Sdimclass MSPropertyDecl : public DeclaratorDecl {
3018251662Sdim  IdentifierInfo *GetterId, *SetterId;
3019251662Sdim
3020251662Sdimpublic:
3021251662Sdim  MSPropertyDecl(DeclContext *DC, SourceLocation L,
3022251662Sdim                 DeclarationName N, QualType T, TypeSourceInfo *TInfo,
3023251662Sdim                 SourceLocation StartL, IdentifierInfo *Getter,
3024251662Sdim                 IdentifierInfo *Setter):
3025251662Sdim  DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL), GetterId(Getter),
3026251662Sdim  SetterId(Setter) {}
3027251662Sdim
3028251662Sdim  static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
3029251662Sdim
3030251662Sdim  static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
3031251662Sdim
3032251662Sdim  bool hasGetter() const { return GetterId != NULL; }
3033251662Sdim  IdentifierInfo* getGetterId() const { return GetterId; }
3034251662Sdim  bool hasSetter() const { return SetterId != NULL; }
3035251662Sdim  IdentifierInfo* getSetterId() const { return SetterId; }
3036251662Sdim
3037251662Sdim  friend class ASTDeclReader;
3038251662Sdim};
3039251662Sdim
3040239462Sdim/// Insertion operator for diagnostics.  This allows sending an AccessSpecifier
3041193326Sed/// into a diagnostic with <<.
3042193326Sedconst DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
3043193326Sed                                    AccessSpecifier AS);
3044198092Srdivacky
3045234353Sdimconst PartialDiagnostic &operator<<(const PartialDiagnostic &DB,
3046234353Sdim                                    AccessSpecifier AS);
3047234353Sdim
3048193326Sed} // end namespace clang
3049193326Sed
3050193326Sed#endif
3051