1193326Sed//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This file implements the C++ related Decl classes.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed#include "clang/AST/DeclCXX.h"
14193326Sed#include "clang/AST/ASTContext.h"
15263509Sdim#include "clang/AST/ASTLambda.h"
16218893Sdim#include "clang/AST/ASTMutationListener.h"
17218893Sdim#include "clang/AST/CXXInheritance.h"
18252723Sdim#include "clang/AST/DeclTemplate.h"
19193326Sed#include "clang/AST/Expr.h"
20235633Sdim#include "clang/AST/ExprCXX.h"
21200583Srdivacky#include "clang/AST/TypeLoc.h"
22193326Sed#include "clang/Basic/IdentifierTable.h"
23193326Sed#include "llvm/ADT/STLExtras.h"
24198092Srdivacky#include "llvm/ADT/SmallPtrSet.h"
25193326Sedusing namespace clang;
26193326Sed
27193326Sed//===----------------------------------------------------------------------===//
28193326Sed// Decl Allocation/Deallocation Method Implementations
29193326Sed//===----------------------------------------------------------------------===//
30193326Sed
31235633Sdimvoid AccessSpecDecl::anchor() { }
32235633Sdim
33235633SdimAccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
34235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(AccessSpecDecl));
35235633Sdim  return new (Mem) AccessSpecDecl(EmptyShell());
36235633Sdim}
37235633Sdim
38263509Sdimvoid LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const {
39263509Sdim  ExternalASTSource *Source = C.getExternalSource();
40263509Sdim  assert(Impl.Decls.isLazy() && "getFromExternalSource for non-lazy set");
41263509Sdim  assert(Source && "getFromExternalSource with no external source");
42263509Sdim
43263509Sdim  for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I)
44263509Sdim    I.setDecl(cast<NamedDecl>(Source->GetExternalDecl(
45263509Sdim        reinterpret_cast<uintptr_t>(I.getDecl()) >> 2)));
46263509Sdim  Impl.Decls.setLazy(false);
47263509Sdim}
48263509Sdim
49203955SrdivackyCXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
50252723Sdim  : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0),
51198092Srdivacky    Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
52221345Sdim    Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true),
53221345Sdim    HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false),
54235633Sdim    HasMutableFields(false), HasOnlyCMembers(true),
55252723Sdim    HasInClassInitializer(false), HasUninitializedReferenceMember(false),
56252723Sdim    NeedOverloadResolutionForMoveConstructor(false),
57252723Sdim    NeedOverloadResolutionForMoveAssignment(false),
58252723Sdim    NeedOverloadResolutionForDestructor(false),
59252723Sdim    DefaultedMoveConstructorIsDeleted(false),
60252723Sdim    DefaultedMoveAssignmentIsDeleted(false),
61252723Sdim    DefaultedDestructorIsDeleted(false),
62252723Sdim    HasTrivialSpecialMembers(SMF_All),
63252723Sdim    DeclaredNonTrivialSpecialMembers(0),
64252723Sdim    HasIrrelevantDestructor(true),
65235633Sdim    HasConstexprNonCopyMoveConstructor(false),
66235633Sdim    DefaultedDefaultConstructorIsConstexpr(true),
67252723Sdim    HasConstexprDefaultConstructor(false),
68223017Sdim    HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
69252723Sdim    UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0),
70252723Sdim    ImplicitCopyConstructorHasConstParam(true),
71252723Sdim    ImplicitCopyAssignmentHasConstParam(true),
72252723Sdim    HasDeclaredCopyConstructorWithConstParam(false),
73252723Sdim    HasDeclaredCopyAssignmentWithConstParam(false),
74252723Sdim    IsLambda(false), NumBases(0), NumVBases(0), Bases(), VBases(),
75263509Sdim    Definition(D), FirstFriend() {
76203955Srdivacky}
77203955Srdivacky
78245431SdimCXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const {
79245431Sdim  return Bases.get(Definition->getASTContext().getExternalSource());
80245431Sdim}
81245431Sdim
82245431SdimCXXBaseSpecifier *CXXRecordDecl::DefinitionData::getVBasesSlowCase() const {
83245431Sdim  return VBases.get(Definition->getASTContext().getExternalSource());
84245431Sdim}
85245431Sdim
86203955SrdivackyCXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
87221345Sdim                             SourceLocation StartLoc, SourceLocation IdLoc,
88221345Sdim                             IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
89221345Sdim  : RecordDecl(K, TK, DC, StartLoc, IdLoc, Id, PrevDecl),
90203955Srdivacky    DefinitionData(PrevDecl ? PrevDecl->DefinitionData : 0),
91193326Sed    TemplateOrInstantiation() { }
92193326Sed
93218893SdimCXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
94221345Sdim                                     DeclContext *DC, SourceLocation StartLoc,
95221345Sdim                                     SourceLocation IdLoc, IdentifierInfo *Id,
96193326Sed                                     CXXRecordDecl* PrevDecl,
97193326Sed                                     bool DelayTypeCreation) {
98221345Sdim  CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, StartLoc, IdLoc,
99221345Sdim                                           Id, PrevDecl);
100252723Sdim  R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
101198092Srdivacky
102198092Srdivacky  // FIXME: DelayTypeCreation seems like such a hack
103193326Sed  if (!DelayTypeCreation)
104198092Srdivacky    C.getTypeDeclType(R, PrevDecl);
105193326Sed  return R;
106193326Sed}
107193326Sed
108235633SdimCXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
109245431Sdim                                           TypeSourceInfo *Info, SourceLocation Loc,
110263509Sdim                                           bool Dependent, bool IsGeneric,
111263509Sdim                                           LambdaCaptureDefault CaptureDefault) {
112235633Sdim  CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc,
113235633Sdim                                           0, 0);
114235633Sdim  R->IsBeingDefined = true;
115263509Sdim  R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info,
116263509Sdim                                                          Dependent,
117263509Sdim                                                          IsGeneric,
118263509Sdim                                                          CaptureDefault);
119252723Sdim  R->MayHaveOutOfDateDef = false;
120263509Sdim  R->setImplicit(true);
121235633Sdim  C.getTypeDeclType(R, /*PrevDecl=*/0);
122235633Sdim  return R;
123210299Sed}
124210299Sed
125235633SdimCXXRecordDecl *
126235633SdimCXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
127235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXRecordDecl));
128252723Sdim  CXXRecordDecl *R = new (Mem) CXXRecordDecl(CXXRecord, TTK_Struct, 0,
129252723Sdim                                             SourceLocation(), SourceLocation(),
130252723Sdim                                             0, 0);
131252723Sdim  R->MayHaveOutOfDateDef = false;
132252723Sdim  return R;
133235633Sdim}
134235633Sdim
135198092Srdivackyvoid
136203955SrdivackyCXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
137193326Sed                        unsigned NumBases) {
138203955Srdivacky  ASTContext &C = getASTContext();
139193326Sed
140218893Sdim  if (!data().Bases.isOffset() && data().NumBases > 0)
141218893Sdim    C.Deallocate(data().getBases());
142193326Sed
143235633Sdim  if (NumBases) {
144235633Sdim    // C++ [dcl.init.aggr]p1:
145235633Sdim    //   An aggregate is [...] a class with [...] no base classes [...].
146235633Sdim    data().Aggregate = false;
147235633Sdim
148235633Sdim    // C++ [class]p4:
149235633Sdim    //   A POD-struct is an aggregate class...
150235633Sdim    data().PlainOldData = false;
151235633Sdim  }
152235633Sdim
153206084Srdivacky  // The set of seen virtual base types.
154206084Srdivacky  llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes;
155206084Srdivacky
156206084Srdivacky  // The virtual bases of this class.
157226890Sdim  SmallVector<const CXXBaseSpecifier *, 8> VBases;
158198092Srdivacky
159203955Srdivacky  data().Bases = new(C) CXXBaseSpecifier [NumBases];
160203955Srdivacky  data().NumBases = NumBases;
161198092Srdivacky  for (unsigned i = 0; i < NumBases; ++i) {
162218893Sdim    data().getBases()[i] = *Bases[i];
163198092Srdivacky    // Keep track of inherited vbases for this base class.
164198092Srdivacky    const CXXBaseSpecifier *Base = Bases[i];
165198092Srdivacky    QualType BaseType = Base->getType();
166204643Srdivacky    // Skip dependent types; we can't do any checking on them now.
167198092Srdivacky    if (BaseType->isDependentType())
168198092Srdivacky      continue;
169198092Srdivacky    CXXRecordDecl *BaseClassDecl
170198092Srdivacky      = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
171206084Srdivacky
172218893Sdim    // A class with a non-empty base class is not empty.
173218893Sdim    // FIXME: Standard ref?
174221345Sdim    if (!BaseClassDecl->isEmpty()) {
175221345Sdim      if (!data().Empty) {
176221345Sdim        // C++0x [class]p7:
177221345Sdim        //   A standard-layout class is a class that:
178221345Sdim        //    [...]
179221345Sdim        //    -- either has no non-static data members in the most derived
180221345Sdim        //       class and at most one base class with non-static data members,
181221345Sdim        //       or has no base classes with non-static data members, and
182221345Sdim        // If this is the second non-empty base, then neither of these two
183221345Sdim        // clauses can be true.
184221345Sdim        data().IsStandardLayout = false;
185221345Sdim      }
186221345Sdim
187218893Sdim      data().Empty = false;
188221345Sdim      data().HasNoNonEmptyBases = false;
189221345Sdim    }
190218893Sdim
191218893Sdim    // C++ [class.virtual]p1:
192218893Sdim    //   A class that declares or inherits a virtual function is called a
193218893Sdim    //   polymorphic class.
194218893Sdim    if (BaseClassDecl->isPolymorphic())
195218893Sdim      data().Polymorphic = true;
196221345Sdim
197221345Sdim    // C++0x [class]p7:
198221345Sdim    //   A standard-layout class is a class that: [...]
199221345Sdim    //    -- has no non-standard-layout base classes
200221345Sdim    if (!BaseClassDecl->isStandardLayout())
201221345Sdim      data().IsStandardLayout = false;
202221345Sdim
203221345Sdim    // Record if this base is the first non-literal field or base.
204252723Sdim    if (!hasNonLiteralTypeFieldsOrBases() && !BaseType->isLiteralType(C))
205221345Sdim      data().HasNonLiteralTypeFieldsOrBases = true;
206218893Sdim
207206084Srdivacky    // Now go through all virtual bases of this base and add them.
208198092Srdivacky    for (CXXRecordDecl::base_class_iterator VBase =
209198092Srdivacky          BaseClassDecl->vbases_begin(),
210198092Srdivacky         E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
211206084Srdivacky      // Add this base if it's not already in the list.
212252723Sdim      if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType()))) {
213206084Srdivacky        VBases.push_back(VBase);
214252723Sdim
215252723Sdim        // C++11 [class.copy]p8:
216252723Sdim        //   The implicitly-declared copy constructor for a class X will have
217252723Sdim        //   the form 'X::X(const X&)' if each [...] virtual base class B of X
218252723Sdim        //   has a copy constructor whose first parameter is of type
219252723Sdim        //   'const B&' or 'const volatile B&' [...]
220252723Sdim        if (CXXRecordDecl *VBaseDecl = VBase->getType()->getAsCXXRecordDecl())
221252723Sdim          if (!VBaseDecl->hasCopyConstructorWithConstParam())
222252723Sdim            data().ImplicitCopyConstructorHasConstParam = false;
223252723Sdim      }
224198092Srdivacky    }
225206084Srdivacky
226206084Srdivacky    if (Base->isVirtual()) {
227206084Srdivacky      // Add this base if it's not already in the list.
228206084Srdivacky      if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)))
229252723Sdim        VBases.push_back(Base);
230252723Sdim
231218893Sdim      // C++0x [meta.unary.prop] is_empty:
232218893Sdim      //    T is a class type, but not a union type, with ... no virtual base
233218893Sdim      //    classes
234218893Sdim      data().Empty = false;
235221345Sdim
236252723Sdim      // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25:
237252723Sdim      //   A [default constructor, copy/move constructor, or copy/move assignment
238252723Sdim      //   operator for a class X] is trivial [...] if:
239252723Sdim      //    -- class X has [...] no virtual base classes
240252723Sdim      data().HasTrivialSpecialMembers &= SMF_Destructor;
241221345Sdim
242221345Sdim      // C++0x [class]p7:
243221345Sdim      //   A standard-layout class is a class that: [...]
244221345Sdim      //    -- has [...] no virtual base classes
245221345Sdim      data().IsStandardLayout = false;
246235633Sdim
247235633Sdim      // C++11 [dcl.constexpr]p4:
248235633Sdim      //   In the definition of a constexpr constructor [...]
249235633Sdim      //    -- the class shall not have any virtual base classes
250235633Sdim      data().DefaultedDefaultConstructorIsConstexpr = false;
251218893Sdim    } else {
252218893Sdim      // C++ [class.ctor]p5:
253223017Sdim      //   A default constructor is trivial [...] if:
254223017Sdim      //    -- all the direct base classes of its class have trivial default
255223017Sdim      //       constructors.
256223017Sdim      if (!BaseClassDecl->hasTrivialDefaultConstructor())
257252723Sdim        data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor;
258252723Sdim
259221345Sdim      // C++0x [class.copy]p13:
260221345Sdim      //   A copy/move constructor for class X is trivial if [...]
261221345Sdim      //    [...]
262221345Sdim      //    -- the constructor selected to copy/move each direct base class
263221345Sdim      //       subobject is trivial, and
264218893Sdim      if (!BaseClassDecl->hasTrivialCopyConstructor())
265252723Sdim        data().HasTrivialSpecialMembers &= ~SMF_CopyConstructor;
266252723Sdim      // If the base class doesn't have a simple move constructor, we'll eagerly
267252723Sdim      // declare it and perform overload resolution to determine which function
268252723Sdim      // it actually calls. If it does have a simple move constructor, this
269252723Sdim      // check is correct.
270252723Sdim      if (!BaseClassDecl->hasTrivialMoveConstructor())
271252723Sdim        data().HasTrivialSpecialMembers &= ~SMF_MoveConstructor;
272221345Sdim
273221345Sdim      // C++0x [class.copy]p27:
274221345Sdim      //   A copy/move assignment operator for class X is trivial if [...]
275221345Sdim      //    [...]
276221345Sdim      //    -- the assignment operator selected to copy/move each direct base
277221345Sdim      //       class subobject is trivial, and
278218893Sdim      if (!BaseClassDecl->hasTrivialCopyAssignment())
279252723Sdim        data().HasTrivialSpecialMembers &= ~SMF_CopyAssignment;
280252723Sdim      // If the base class doesn't have a simple move assignment, we'll eagerly
281252723Sdim      // declare it and perform overload resolution to determine which function
282252723Sdim      // it actually calls. If it does have a simple move assignment, this
283252723Sdim      // check is correct.
284252723Sdim      if (!BaseClassDecl->hasTrivialMoveAssignment())
285252723Sdim        data().HasTrivialSpecialMembers &= ~SMF_MoveAssignment;
286235633Sdim
287235633Sdim      // C++11 [class.ctor]p6:
288235633Sdim      //   If that user-written default constructor would satisfy the
289235633Sdim      //   requirements of a constexpr constructor, the implicitly-defined
290235633Sdim      //   default constructor is constexpr.
291235633Sdim      if (!BaseClassDecl->hasConstexprDefaultConstructor())
292235633Sdim        data().DefaultedDefaultConstructorIsConstexpr = false;
293198092Srdivacky    }
294252723Sdim
295218893Sdim    // C++ [class.ctor]p3:
296218893Sdim    //   A destructor is trivial if all the direct base classes of its class
297218893Sdim    //   have trivial destructors.
298218893Sdim    if (!BaseClassDecl->hasTrivialDestructor())
299252723Sdim      data().HasTrivialSpecialMembers &= ~SMF_Destructor;
300235633Sdim
301235633Sdim    if (!BaseClassDecl->hasIrrelevantDestructor())
302235633Sdim      data().HasIrrelevantDestructor = false;
303235633Sdim
304252723Sdim    // C++11 [class.copy]p18:
305252723Sdim    //   The implicitly-declared copy assignment oeprator for a class X will
306252723Sdim    //   have the form 'X& X::operator=(const X&)' if each direct base class B
307252723Sdim    //   of X has a copy assignment operator whose parameter is of type 'const
308252723Sdim    //   B&', 'const volatile B&', or 'B' [...]
309252723Sdim    if (!BaseClassDecl->hasCopyAssignmentWithConstParam())
310252723Sdim      data().ImplicitCopyAssignmentHasConstParam = false;
311252723Sdim
312252723Sdim    // C++11 [class.copy]p8:
313252723Sdim    //   The implicitly-declared copy constructor for a class X will have
314252723Sdim    //   the form 'X::X(const X&)' if each direct [...] base class B of X
315252723Sdim    //   has a copy constructor whose first parameter is of type
316252723Sdim    //   'const B&' or 'const volatile B&' [...]
317252723Sdim    if (!BaseClassDecl->hasCopyConstructorWithConstParam())
318252723Sdim      data().ImplicitCopyConstructorHasConstParam = false;
319252723Sdim
320224145Sdim    // A class has an Objective-C object member if... or any of its bases
321224145Sdim    // has an Objective-C object member.
322224145Sdim    if (BaseClassDecl->hasObjectMember())
323224145Sdim      setHasObjectMember(true);
324252723Sdim
325252723Sdim    if (BaseClassDecl->hasVolatileMember())
326252723Sdim      setHasVolatileMember(true);
327224145Sdim
328223017Sdim    // Keep track of the presence of mutable fields.
329223017Sdim    if (BaseClassDecl->hasMutableFields())
330223017Sdim      data().HasMutableFields = true;
331252723Sdim
332252723Sdim    if (BaseClassDecl->hasUninitializedReferenceMember())
333252723Sdim      data().HasUninitializedReferenceMember = true;
334252723Sdim
335252723Sdim    addedClassSubobject(BaseClassDecl);
336198092Srdivacky  }
337206084Srdivacky
338206084Srdivacky  if (VBases.empty())
339206084Srdivacky    return;
340206084Srdivacky
341206084Srdivacky  // Create base specifier for any direct or indirect virtual bases.
342206084Srdivacky  data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
343206084Srdivacky  data().NumVBases = VBases.size();
344252723Sdim  for (int I = 0, E = VBases.size(); I != E; ++I) {
345252723Sdim    QualType Type = VBases[I]->getType();
346252723Sdim    if (!Type->isDependentType())
347252723Sdim      addedClassSubobject(Type->getAsCXXRecordDecl());
348224145Sdim    data().getVBases()[I] = *VBases[I];
349252723Sdim  }
350193326Sed}
351193326Sed
352252723Sdimvoid CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
353252723Sdim  // C++11 [class.copy]p11:
354252723Sdim  //   A defaulted copy/move constructor for a class X is defined as
355252723Sdim  //   deleted if X has:
356252723Sdim  //    -- a direct or virtual base class B that cannot be copied/moved [...]
357252723Sdim  //    -- a non-static data member of class type M (or array thereof)
358252723Sdim  //       that cannot be copied or moved [...]
359252723Sdim  if (!Subobj->hasSimpleMoveConstructor())
360252723Sdim    data().NeedOverloadResolutionForMoveConstructor = true;
361252723Sdim
362252723Sdim  // C++11 [class.copy]p23:
363252723Sdim  //   A defaulted copy/move assignment operator for a class X is defined as
364252723Sdim  //   deleted if X has:
365252723Sdim  //    -- a direct or virtual base class B that cannot be copied/moved [...]
366252723Sdim  //    -- a non-static data member of class type M (or array thereof)
367252723Sdim  //        that cannot be copied or moved [...]
368252723Sdim  if (!Subobj->hasSimpleMoveAssignment())
369252723Sdim    data().NeedOverloadResolutionForMoveAssignment = true;
370252723Sdim
371252723Sdim  // C++11 [class.ctor]p5, C++11 [class.copy]p11, C++11 [class.dtor]p5:
372252723Sdim  //   A defaulted [ctor or dtor] for a class X is defined as
373252723Sdim  //   deleted if X has:
374252723Sdim  //    -- any direct or virtual base class [...] has a type with a destructor
375252723Sdim  //       that is deleted or inaccessible from the defaulted [ctor or dtor].
376252723Sdim  //    -- any non-static data member has a type with a destructor
377252723Sdim  //       that is deleted or inaccessible from the defaulted [ctor or dtor].
378252723Sdim  if (!Subobj->hasSimpleDestructor()) {
379252723Sdim    data().NeedOverloadResolutionForMoveConstructor = true;
380252723Sdim    data().NeedOverloadResolutionForDestructor = true;
381252723Sdim  }
382252723Sdim}
383252723Sdim
384202379Srdivacky/// Callback function for CXXRecordDecl::forallBases that acknowledges
385202379Srdivacky/// that it saw a base class.
386202379Srdivackystatic bool SawBase(const CXXRecordDecl *, void *) {
387202379Srdivacky  return true;
388202379Srdivacky}
389202379Srdivacky
390202379Srdivackybool CXXRecordDecl::hasAnyDependentBases() const {
391202379Srdivacky  if (!isDependentContext())
392202379Srdivacky    return false;
393202379Srdivacky
394202379Srdivacky  return !forallBases(SawBase, 0);
395202379Srdivacky}
396202379Srdivacky
397221345Sdimbool CXXRecordDecl::isTriviallyCopyable() const {
398221345Sdim  // C++0x [class]p5:
399221345Sdim  //   A trivially copyable class is a class that:
400221345Sdim  //   -- has no non-trivial copy constructors,
401252723Sdim  if (hasNonTrivialCopyConstructor()) return false;
402221345Sdim  //   -- has no non-trivial move constructors,
403252723Sdim  if (hasNonTrivialMoveConstructor()) return false;
404221345Sdim  //   -- has no non-trivial copy assignment operators,
405252723Sdim  if (hasNonTrivialCopyAssignment()) return false;
406221345Sdim  //   -- has no non-trivial move assignment operators, and
407252723Sdim  if (hasNonTrivialMoveAssignment()) return false;
408221345Sdim  //   -- has a trivial destructor.
409221345Sdim  if (!hasTrivialDestructor()) return false;
410221345Sdim
411221345Sdim  return true;
412221345Sdim}
413221345Sdim
414218893Sdimvoid CXXRecordDecl::markedVirtualFunctionPure() {
415218893Sdim  // C++ [class.abstract]p2:
416218893Sdim  //   A class is abstract if it has at least one pure virtual function.
417218893Sdim  data().Abstract = true;
418218893Sdim}
419193326Sed
420218893Sdimvoid CXXRecordDecl::addedMember(Decl *D) {
421235633Sdim  if (!D->isImplicit() &&
422235633Sdim      !isa<FieldDecl>(D) &&
423235633Sdim      !isa<IndirectFieldDecl>(D) &&
424245431Sdim      (!isa<TagDecl>(D) || cast<TagDecl>(D)->getTagKind() == TTK_Class ||
425245431Sdim        cast<TagDecl>(D)->getTagKind() == TTK_Interface))
426235633Sdim    data().HasOnlyCMembers = false;
427235633Sdim
428218893Sdim  // Ignore friends and invalid declarations.
429218893Sdim  if (D->getFriendObjectKind() || D->isInvalidDecl())
430218893Sdim    return;
431210299Sed
432218893Sdim  FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D);
433218893Sdim  if (FunTmpl)
434218893Sdim    D = FunTmpl->getTemplatedDecl();
435218893Sdim
436218893Sdim  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
437218893Sdim    if (Method->isVirtual()) {
438218893Sdim      // C++ [dcl.init.aggr]p1:
439218893Sdim      //   An aggregate is an array or a class with [...] no virtual functions.
440218893Sdim      data().Aggregate = false;
441218893Sdim
442218893Sdim      // C++ [class]p4:
443218893Sdim      //   A POD-struct is an aggregate class...
444218893Sdim      data().PlainOldData = false;
445218893Sdim
446218893Sdim      // Virtual functions make the class non-empty.
447218893Sdim      // FIXME: Standard ref?
448218893Sdim      data().Empty = false;
449193326Sed
450218893Sdim      // C++ [class.virtual]p1:
451218893Sdim      //   A class that declares or inherits a virtual function is called a
452218893Sdim      //   polymorphic class.
453218893Sdim      data().Polymorphic = true;
454221345Sdim
455252723Sdim      // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25:
456252723Sdim      //   A [default constructor, copy/move constructor, or copy/move
457252723Sdim      //   assignment operator for a class X] is trivial [...] if:
458221345Sdim      //    -- class X has no virtual functions [...]
459252723Sdim      data().HasTrivialSpecialMembers &= SMF_Destructor;
460221345Sdim
461221345Sdim      // C++0x [class]p7:
462221345Sdim      //   A standard-layout class is a class that: [...]
463221345Sdim      //    -- has no virtual functions
464221345Sdim      data().IsStandardLayout = false;
465218893Sdim    }
466218893Sdim  }
467193326Sed
468252723Sdim  // Notify the listener if an implicit member was added after the definition
469252723Sdim  // was completed.
470252723Sdim  if (!isBeingDefined() && D->isImplicit())
471252723Sdim    if (ASTMutationListener *L = getASTMutationListener())
472252723Sdim      L->AddedCXXImplicitMember(data().Definition, D);
473218893Sdim
474252723Sdim  // The kind of special member this declaration is, if any.
475252723Sdim  unsigned SMKind = 0;
476252723Sdim
477252723Sdim  // Handle constructors.
478218893Sdim  if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
479252723Sdim    if (!Constructor->isImplicit()) {
480252723Sdim      // Note that we have a user-declared constructor.
481252723Sdim      data().UserDeclaredConstructor = true;
482218893Sdim
483252723Sdim      // C++ [class]p4:
484252723Sdim      //   A POD-struct is an aggregate class [...]
485252723Sdim      // Since the POD bit is meant to be C++03 POD-ness, clear it even if the
486252723Sdim      // type is technically an aggregate in C++0x since it wouldn't be in 03.
487252723Sdim      data().PlainOldData = false;
488252723Sdim    }
489252723Sdim
490226890Sdim    // Technically, "user-provided" is only defined for special member
491226890Sdim    // functions, but the intent of the standard is clearly that it should apply
492226890Sdim    // to all functions.
493226890Sdim    bool UserProvided = Constructor->isUserProvided();
494218893Sdim
495223017Sdim    if (Constructor->isDefaultConstructor()) {
496252723Sdim      SMKind |= SMF_DefaultConstructor;
497252723Sdim
498252723Sdim      if (UserProvided)
499223017Sdim        data().UserProvidedDefaultConstructor = true;
500252723Sdim      if (Constructor->isConstexpr())
501235633Sdim        data().HasConstexprDefaultConstructor = true;
502223017Sdim    }
503218893Sdim
504221345Sdim    if (!FunTmpl) {
505252723Sdim      unsigned Quals;
506252723Sdim      if (Constructor->isCopyConstructor(Quals)) {
507252723Sdim        SMKind |= SMF_CopyConstructor;
508221345Sdim
509252723Sdim        if (Quals & Qualifiers::Const)
510252723Sdim          data().HasDeclaredCopyConstructorWithConstParam = true;
511252723Sdim      } else if (Constructor->isMoveConstructor())
512252723Sdim        SMKind |= SMF_MoveConstructor;
513252723Sdim    }
514223017Sdim
515252723Sdim    // Record if we see any constexpr constructors which are neither copy
516252723Sdim    // nor move constructors.
517252723Sdim    if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor())
518226890Sdim      data().HasConstexprNonCopyMoveConstructor = true;
519221345Sdim
520223017Sdim    // C++ [dcl.init.aggr]p1:
521223017Sdim    //   An aggregate is an array or a class with no user-declared
522223017Sdim    //   constructors [...].
523252723Sdim    // C++11 [dcl.init.aggr]p1:
524223017Sdim    //   An aggregate is an array or a class with no user-provided
525223017Sdim    //   constructors [...].
526252723Sdim    if (getASTContext().getLangOpts().CPlusPlus11
527252723Sdim          ? UserProvided : !Constructor->isImplicit())
528223017Sdim      data().Aggregate = false;
529198092Srdivacky  }
530193326Sed
531252723Sdim  // Handle destructors.
532223017Sdim  if (CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D)) {
533252723Sdim    SMKind |= SMF_Destructor;
534235633Sdim
535252723Sdim    if (!DD->isImplicit())
536252723Sdim      data().HasIrrelevantDestructor = false;
537245431Sdim
538252723Sdim    // C++11 [class.dtor]p5:
539252723Sdim    //   A destructor is trivial if [...] the destructor is not virtual.
540252723Sdim    if (DD->isVirtual())
541252723Sdim      data().HasTrivialSpecialMembers &= ~SMF_Destructor;
542218893Sdim  }
543252723Sdim
544252723Sdim  // Handle member functions.
545218893Sdim  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
546223017Sdim    if (Method->isCopyAssignmentOperator()) {
547252723Sdim      SMKind |= SMF_CopyAssignment;
548221345Sdim
549252723Sdim      const ReferenceType *ParamTy =
550252723Sdim        Method->getParamDecl(0)->getType()->getAs<ReferenceType>();
551252723Sdim      if (!ParamTy || ParamTy->getPointeeType().isConstQualified())
552252723Sdim        data().HasDeclaredCopyAssignmentWithConstParam = true;
553223017Sdim    }
554223017Sdim
555252723Sdim    if (Method->isMoveAssignmentOperator())
556252723Sdim      SMKind |= SMF_MoveAssignment;
557223017Sdim
558218893Sdim    // Keep the list of conversion functions up-to-date.
559218893Sdim    if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
560252723Sdim      // FIXME: We use the 'unsafe' accessor for the access specifier here,
561252723Sdim      // because Sema may not have set it yet. That's really just a misdesign
562252723Sdim      // in Sema. However, LLDB *will* have set the access specifier correctly,
563252723Sdim      // and adds declarations after the class is technically completed,
564252723Sdim      // so completeDefinition()'s overriding of the access specifiers doesn't
565252723Sdim      // work.
566252723Sdim      AccessSpecifier AS = Conversion->getAccessUnsafe();
567193326Sed
568252723Sdim      if (Conversion->getPrimaryTemplate()) {
569252723Sdim        // We don't record specializations.
570218893Sdim      } else {
571263509Sdim        ASTContext &Ctx = getASTContext();
572263509Sdim        ASTUnresolvedSet &Conversions = data().Conversions.get(Ctx);
573263509Sdim        NamedDecl *Primary =
574263509Sdim            FunTmpl ? cast<NamedDecl>(FunTmpl) : cast<NamedDecl>(Conversion);
575263509Sdim        if (Primary->getPreviousDecl())
576263509Sdim          Conversions.replace(cast<NamedDecl>(Primary->getPreviousDecl()),
577263509Sdim                              Primary, AS);
578218893Sdim        else
579263509Sdim          Conversions.addDecl(Ctx, Primary, AS);
580218893Sdim      }
581218893Sdim    }
582252723Sdim
583252723Sdim    if (SMKind) {
584252723Sdim      // If this is the first declaration of a special member, we no longer have
585252723Sdim      // an implicit trivial special member.
586252723Sdim      data().HasTrivialSpecialMembers &=
587252723Sdim        data().DeclaredSpecialMembers | ~SMKind;
588252723Sdim
589252723Sdim      if (!Method->isImplicit() && !Method->isUserProvided()) {
590252723Sdim        // This method is user-declared but not user-provided. We can't work out
591252723Sdim        // whether it's trivial yet (not until we get to the end of the class).
592252723Sdim        // We'll handle this method in finishedDefaultedOrDeletedMember.
593252723Sdim      } else if (Method->isTrivial())
594252723Sdim        data().HasTrivialSpecialMembers |= SMKind;
595252723Sdim      else
596252723Sdim        data().DeclaredNonTrivialSpecialMembers |= SMKind;
597252723Sdim
598252723Sdim      // Note when we have declared a declared special member, and suppress the
599252723Sdim      // implicit declaration of this special member.
600252723Sdim      data().DeclaredSpecialMembers |= SMKind;
601252723Sdim
602252723Sdim      if (!Method->isImplicit()) {
603252723Sdim        data().UserDeclaredSpecialMembers |= SMKind;
604252723Sdim
605252723Sdim        // C++03 [class]p4:
606252723Sdim        //   A POD-struct is an aggregate class that has [...] no user-defined
607252723Sdim        //   copy assignment operator and no user-defined destructor.
608252723Sdim        //
609252723Sdim        // Since the POD bit is meant to be C++03 POD-ness, and in C++03,
610252723Sdim        // aggregates could not have any constructors, clear it even for an
611252723Sdim        // explicitly defaulted or deleted constructor.
612252723Sdim        // type is technically an aggregate in C++0x since it wouldn't be in 03.
613252723Sdim        //
614252723Sdim        // Also, a user-declared move assignment operator makes a class non-POD.
615252723Sdim        // This is an extension in C++03.
616252723Sdim        data().PlainOldData = false;
617252723Sdim      }
618252723Sdim    }
619252723Sdim
620193326Sed    return;
621218893Sdim  }
622252723Sdim
623218893Sdim  // Handle non-static data members.
624218893Sdim  if (FieldDecl *Field = dyn_cast<FieldDecl>(D)) {
625226890Sdim    // C++ [class.bit]p2:
626226890Sdim    //   A declaration for a bit-field that omits the identifier declares an
627226890Sdim    //   unnamed bit-field. Unnamed bit-fields are not members and cannot be
628226890Sdim    //   initialized.
629226890Sdim    if (Field->isUnnamedBitfield())
630226890Sdim      return;
631226890Sdim
632218893Sdim    // C++ [dcl.init.aggr]p1:
633218893Sdim    //   An aggregate is an array or a class (clause 9) with [...] no
634218893Sdim    //   private or protected non-static data members (clause 11).
635218893Sdim    //
636218893Sdim    // A POD must be an aggregate.
637218893Sdim    if (D->getAccess() == AS_private || D->getAccess() == AS_protected) {
638218893Sdim      data().Aggregate = false;
639218893Sdim      data().PlainOldData = false;
640218893Sdim    }
641221345Sdim
642221345Sdim    // C++0x [class]p7:
643221345Sdim    //   A standard-layout class is a class that:
644221345Sdim    //    [...]
645221345Sdim    //    -- has the same access control for all non-static data members,
646221345Sdim    switch (D->getAccess()) {
647221345Sdim    case AS_private:    data().HasPrivateFields = true;   break;
648221345Sdim    case AS_protected:  data().HasProtectedFields = true; break;
649221345Sdim    case AS_public:     data().HasPublicFields = true;    break;
650226890Sdim    case AS_none:       llvm_unreachable("Invalid access specifier");
651221345Sdim    };
652221345Sdim    if ((data().HasPrivateFields + data().HasProtectedFields +
653221345Sdim         data().HasPublicFields) > 1)
654221345Sdim      data().IsStandardLayout = false;
655221345Sdim
656223017Sdim    // Keep track of the presence of mutable fields.
657223017Sdim    if (Field->isMutable())
658223017Sdim      data().HasMutableFields = true;
659223017Sdim
660221345Sdim    // C++0x [class]p9:
661218893Sdim    //   A POD struct is a class that is both a trivial class and a
662218893Sdim    //   standard-layout class, and has no non-static data members of type
663218893Sdim    //   non-POD struct, non-POD union (or array of such types).
664224145Sdim    //
665224145Sdim    // Automatic Reference Counting: the presence of a member of Objective-C pointer type
666224145Sdim    // that does not explicitly have no lifetime makes the class a non-POD.
667224145Sdim    // However, we delay setting PlainOldData to false in this case so that
668224145Sdim    // Sema has a chance to diagnostic causes where the same class will be
669245431Sdim    // non-POD with Automatic Reference Counting but a POD without ARC.
670224145Sdim    // In this case, the class will become a non-POD class when we complete
671224145Sdim    // the definition.
672218893Sdim    ASTContext &Context = getASTContext();
673218893Sdim    QualType T = Context.getBaseElementType(Field->getType());
674224145Sdim    if (T->isObjCRetainableType() || T.isObjCGCStrong()) {
675235633Sdim      if (!Context.getLangOpts().ObjCAutoRefCount ||
676224145Sdim          T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone)
677224145Sdim        setHasObjectMember(true);
678263509Sdim    } else if (!T.isCXX98PODType(Context))
679218893Sdim      data().PlainOldData = false;
680224145Sdim
681221345Sdim    if (T->isReferenceType()) {
682252723Sdim      if (!Field->hasInClassInitializer())
683252723Sdim        data().HasUninitializedReferenceMember = true;
684221345Sdim
685221345Sdim      // C++0x [class]p7:
686221345Sdim      //   A standard-layout class is a class that:
687221345Sdim      //    -- has no non-static data members of type [...] reference,
688221345Sdim      data().IsStandardLayout = false;
689221345Sdim    }
690221345Sdim
691235633Sdim    // Record if this field is the first non-literal or volatile field or base.
692252723Sdim    if (!T->isLiteralType(Context) || T.isVolatileQualified())
693221345Sdim      data().HasNonLiteralTypeFieldsOrBases = true;
694221345Sdim
695223017Sdim    if (Field->hasInClassInitializer()) {
696245431Sdim      data().HasInClassInitializer = true;
697245431Sdim
698245431Sdim      // C++11 [class]p5:
699223017Sdim      //   A default constructor is trivial if [...] no non-static data member
700223017Sdim      //   of its class has a brace-or-equal-initializer.
701252723Sdim      data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor;
702223017Sdim
703245431Sdim      // C++11 [dcl.init.aggr]p1:
704223017Sdim      //   An aggregate is a [...] class with [...] no
705223017Sdim      //   brace-or-equal-initializers for non-static data members.
706252723Sdim      //
707252723Sdim      // This rule was removed in C++1y.
708252723Sdim      if (!getASTContext().getLangOpts().CPlusPlus1y)
709252723Sdim        data().Aggregate = false;
710223017Sdim
711245431Sdim      // C++11 [class]p10:
712223017Sdim      //   A POD struct is [...] a trivial class.
713223017Sdim      data().PlainOldData = false;
714223017Sdim    }
715223017Sdim
716252723Sdim    // C++11 [class.copy]p23:
717252723Sdim    //   A defaulted copy/move assignment operator for a class X is defined
718252723Sdim    //   as deleted if X has:
719252723Sdim    //    -- a non-static data member of reference type
720252723Sdim    if (T->isReferenceType())
721252723Sdim      data().DefaultedMoveAssignmentIsDeleted = true;
722252723Sdim
723218893Sdim    if (const RecordType *RecordTy = T->getAs<RecordType>()) {
724218893Sdim      CXXRecordDecl* FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl());
725218893Sdim      if (FieldRec->getDefinition()) {
726252723Sdim        addedClassSubobject(FieldRec);
727252723Sdim
728263509Sdim        // We may need to perform overload resolution to determine whether a
729263509Sdim        // field can be moved if it's const or volatile qualified.
730263509Sdim        if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) {
731263509Sdim          data().NeedOverloadResolutionForMoveConstructor = true;
732263509Sdim          data().NeedOverloadResolutionForMoveAssignment = true;
733263509Sdim        }
734263509Sdim
735252723Sdim        // C++11 [class.ctor]p5, C++11 [class.copy]p11:
736252723Sdim        //   A defaulted [special member] for a class X is defined as
737252723Sdim        //   deleted if:
738252723Sdim        //    -- X is a union-like class that has a variant member with a
739252723Sdim        //       non-trivial [corresponding special member]
740252723Sdim        if (isUnion()) {
741252723Sdim          if (FieldRec->hasNonTrivialMoveConstructor())
742252723Sdim            data().DefaultedMoveConstructorIsDeleted = true;
743252723Sdim          if (FieldRec->hasNonTrivialMoveAssignment())
744252723Sdim            data().DefaultedMoveAssignmentIsDeleted = true;
745252723Sdim          if (FieldRec->hasNonTrivialDestructor())
746252723Sdim            data().DefaultedDestructorIsDeleted = true;
747252723Sdim        }
748252723Sdim
749223017Sdim        // C++0x [class.ctor]p5:
750235633Sdim        //   A default constructor is trivial [...] if:
751223017Sdim        //    -- for all the non-static data members of its class that are of
752223017Sdim        //       class type (or array thereof), each such class has a trivial
753223017Sdim        //       default constructor.
754223017Sdim        if (!FieldRec->hasTrivialDefaultConstructor())
755252723Sdim          data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor;
756221345Sdim
757221345Sdim        // C++0x [class.copy]p13:
758221345Sdim        //   A copy/move constructor for class X is trivial if [...]
759221345Sdim        //    [...]
760221345Sdim        //    -- for each non-static data member of X that is of class type (or
761221345Sdim        //       an array thereof), the constructor selected to copy/move that
762221345Sdim        //       member is trivial;
763218893Sdim        if (!FieldRec->hasTrivialCopyConstructor())
764252723Sdim          data().HasTrivialSpecialMembers &= ~SMF_CopyConstructor;
765252723Sdim        // If the field doesn't have a simple move constructor, we'll eagerly
766252723Sdim        // declare the move constructor for this class and we'll decide whether
767252723Sdim        // it's trivial then.
768252723Sdim        if (!FieldRec->hasTrivialMoveConstructor())
769252723Sdim          data().HasTrivialSpecialMembers &= ~SMF_MoveConstructor;
770221345Sdim
771221345Sdim        // C++0x [class.copy]p27:
772221345Sdim        //   A copy/move assignment operator for class X is trivial if [...]
773221345Sdim        //    [...]
774221345Sdim        //    -- for each non-static data member of X that is of class type (or
775221345Sdim        //       an array thereof), the assignment operator selected to
776221345Sdim        //       copy/move that member is trivial;
777218893Sdim        if (!FieldRec->hasTrivialCopyAssignment())
778252723Sdim          data().HasTrivialSpecialMembers &= ~SMF_CopyAssignment;
779252723Sdim        // If the field doesn't have a simple move assignment, we'll eagerly
780252723Sdim        // declare the move assignment for this class and we'll decide whether
781252723Sdim        // it's trivial then.
782252723Sdim        if (!FieldRec->hasTrivialMoveAssignment())
783252723Sdim          data().HasTrivialSpecialMembers &= ~SMF_MoveAssignment;
784221345Sdim
785218893Sdim        if (!FieldRec->hasTrivialDestructor())
786252723Sdim          data().HasTrivialSpecialMembers &= ~SMF_Destructor;
787235633Sdim        if (!FieldRec->hasIrrelevantDestructor())
788235633Sdim          data().HasIrrelevantDestructor = false;
789224145Sdim        if (FieldRec->hasObjectMember())
790224145Sdim          setHasObjectMember(true);
791252723Sdim        if (FieldRec->hasVolatileMember())
792252723Sdim          setHasVolatileMember(true);
793221345Sdim
794221345Sdim        // C++0x [class]p7:
795221345Sdim        //   A standard-layout class is a class that:
796221345Sdim        //    -- has no non-static data members of type non-standard-layout
797221345Sdim        //       class (or array of such types) [...]
798221345Sdim        if (!FieldRec->isStandardLayout())
799221345Sdim          data().IsStandardLayout = false;
800221345Sdim
801221345Sdim        // C++0x [class]p7:
802221345Sdim        //   A standard-layout class is a class that:
803221345Sdim        //    [...]
804221345Sdim        //    -- has no base classes of the same type as the first non-static
805221345Sdim        //       data member.
806221345Sdim        // We don't want to expend bits in the state of the record decl
807221345Sdim        // tracking whether this is the first non-static data member so we
808221345Sdim        // cheat a bit and use some of the existing state: the empty bit.
809221345Sdim        // Virtual bases and virtual methods make a class non-empty, but they
810221345Sdim        // also make it non-standard-layout so we needn't check here.
811221345Sdim        // A non-empty base class may leave the class standard-layout, but not
812221345Sdim        // if we have arrived here, and have at least on non-static data
813221345Sdim        // member. If IsStandardLayout remains true, then the first non-static
814221345Sdim        // data member must come through here with Empty still true, and Empty
815221345Sdim        // will subsequently be set to false below.
816221345Sdim        if (data().IsStandardLayout && data().Empty) {
817221345Sdim          for (CXXRecordDecl::base_class_const_iterator BI = bases_begin(),
818221345Sdim                                                        BE = bases_end();
819221345Sdim               BI != BE; ++BI) {
820221345Sdim            if (Context.hasSameUnqualifiedType(BI->getType(), T)) {
821221345Sdim              data().IsStandardLayout = false;
822221345Sdim              break;
823221345Sdim            }
824221345Sdim          }
825221345Sdim        }
826223017Sdim
827223017Sdim        // Keep track of the presence of mutable fields.
828223017Sdim        if (FieldRec->hasMutableFields())
829223017Sdim          data().HasMutableFields = true;
830235633Sdim
831235633Sdim        // C++11 [class.copy]p13:
832235633Sdim        //   If the implicitly-defined constructor would satisfy the
833235633Sdim        //   requirements of a constexpr constructor, the implicitly-defined
834235633Sdim        //   constructor is constexpr.
835235633Sdim        // C++11 [dcl.constexpr]p4:
836235633Sdim        //    -- every constructor involved in initializing non-static data
837235633Sdim        //       members [...] shall be a constexpr constructor
838235633Sdim        if (!Field->hasInClassInitializer() &&
839245431Sdim            !FieldRec->hasConstexprDefaultConstructor() && !isUnion())
840235633Sdim          // The standard requires any in-class initializer to be a constant
841235633Sdim          // expression. We consider this to be a defect.
842235633Sdim          data().DefaultedDefaultConstructorIsConstexpr = false;
843252723Sdim
844252723Sdim        // C++11 [class.copy]p8:
845252723Sdim        //   The implicitly-declared copy constructor for a class X will have
846252723Sdim        //   the form 'X::X(const X&)' if [...] for all the non-static data
847252723Sdim        //   members of X that are of a class type M (or array thereof), each
848252723Sdim        //   such class type has a copy constructor whose first parameter is
849252723Sdim        //   of type 'const M&' or 'const volatile M&'.
850252723Sdim        if (!FieldRec->hasCopyConstructorWithConstParam())
851252723Sdim          data().ImplicitCopyConstructorHasConstParam = false;
852252723Sdim
853252723Sdim        // C++11 [class.copy]p18:
854252723Sdim        //   The implicitly-declared copy assignment oeprator for a class X will
855252723Sdim        //   have the form 'X& X::operator=(const X&)' if [...] for all the
856252723Sdim        //   non-static data members of X that are of a class type M (or array
857252723Sdim        //   thereof), each such class type has a copy assignment operator whose
858252723Sdim        //   parameter is of type 'const M&', 'const volatile M&' or 'M'.
859252723Sdim        if (!FieldRec->hasCopyAssignmentWithConstParam())
860252723Sdim          data().ImplicitCopyAssignmentHasConstParam = false;
861252723Sdim
862252723Sdim        if (FieldRec->hasUninitializedReferenceMember() &&
863252723Sdim            !Field->hasInClassInitializer())
864252723Sdim          data().HasUninitializedReferenceMember = true;
865218893Sdim      }
866235633Sdim    } else {
867235633Sdim      // Base element type of field is a non-class type.
868252723Sdim      if (!T->isLiteralType(Context) ||
869245431Sdim          (!Field->hasInClassInitializer() && !isUnion()))
870235633Sdim        data().DefaultedDefaultConstructorIsConstexpr = false;
871252723Sdim
872252723Sdim      // C++11 [class.copy]p23:
873252723Sdim      //   A defaulted copy/move assignment operator for a class X is defined
874252723Sdim      //   as deleted if X has:
875252723Sdim      //    -- a non-static data member of const non-class type (or array
876252723Sdim      //       thereof)
877252723Sdim      if (T.isConstQualified())
878252723Sdim        data().DefaultedMoveAssignmentIsDeleted = true;
879218893Sdim    }
880221345Sdim
881221345Sdim    // C++0x [class]p7:
882221345Sdim    //   A standard-layout class is a class that:
883221345Sdim    //    [...]
884221345Sdim    //    -- either has no non-static data members in the most derived
885221345Sdim    //       class and at most one base class with non-static data members,
886221345Sdim    //       or has no base classes with non-static data members, and
887221345Sdim    // At this point we know that we have a non-static data member, so the last
888221345Sdim    // clause holds.
889221345Sdim    if (!data().HasNoNonEmptyBases)
890221345Sdim      data().IsStandardLayout = false;
891221345Sdim
892218893Sdim    // If this is not a zero-length bit-field, then the class is not empty.
893218893Sdim    if (data().Empty) {
894226890Sdim      if (!Field->isBitField() ||
895226890Sdim          (!Field->getBitWidth()->isTypeDependent() &&
896226890Sdim           !Field->getBitWidth()->isValueDependent() &&
897226890Sdim           Field->getBitWidthValue(Context) != 0))
898218893Sdim        data().Empty = false;
899218893Sdim    }
900218893Sdim  }
901218893Sdim
902218893Sdim  // Handle using declarations of conversion functions.
903263509Sdim  if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(D)) {
904218893Sdim    if (Shadow->getDeclName().getNameKind()
905263509Sdim          == DeclarationName::CXXConversionFunctionName) {
906263509Sdim      ASTContext &Ctx = getASTContext();
907263509Sdim      data().Conversions.get(Ctx).addDecl(Ctx, Shadow, Shadow->getAccess());
908263509Sdim    }
909263509Sdim  }
910193326Sed}
911193326Sed
912252723Sdimvoid CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) {
913252723Sdim  assert(!D->isImplicit() && !D->isUserProvided());
914252723Sdim
915252723Sdim  // The kind of special member this declaration is, if any.
916252723Sdim  unsigned SMKind = 0;
917252723Sdim
918252723Sdim  if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
919252723Sdim    if (Constructor->isDefaultConstructor()) {
920252723Sdim      SMKind |= SMF_DefaultConstructor;
921252723Sdim      if (Constructor->isConstexpr())
922252723Sdim        data().HasConstexprDefaultConstructor = true;
923252723Sdim    }
924252723Sdim    if (Constructor->isCopyConstructor())
925252723Sdim      SMKind |= SMF_CopyConstructor;
926252723Sdim    else if (Constructor->isMoveConstructor())
927252723Sdim      SMKind |= SMF_MoveConstructor;
928252723Sdim    else if (Constructor->isConstexpr())
929252723Sdim      // We may now know that the constructor is constexpr.
930252723Sdim      data().HasConstexprNonCopyMoveConstructor = true;
931252723Sdim  } else if (isa<CXXDestructorDecl>(D))
932252723Sdim    SMKind |= SMF_Destructor;
933252723Sdim  else if (D->isCopyAssignmentOperator())
934252723Sdim    SMKind |= SMF_CopyAssignment;
935252723Sdim  else if (D->isMoveAssignmentOperator())
936252723Sdim    SMKind |= SMF_MoveAssignment;
937252723Sdim
938252723Sdim  // Update which trivial / non-trivial special members we have.
939252723Sdim  // addedMember will have skipped this step for this member.
940252723Sdim  if (D->isTrivial())
941252723Sdim    data().HasTrivialSpecialMembers |= SMKind;
942252723Sdim  else
943252723Sdim    data().DeclaredNonTrivialSpecialMembers |= SMKind;
944252723Sdim}
945252723Sdim
946235633Sdimbool CXXRecordDecl::isCLike() const {
947245431Sdim  if (getTagKind() == TTK_Class || getTagKind() == TTK_Interface ||
948245431Sdim      !TemplateOrInstantiation.isNull())
949235633Sdim    return false;
950235633Sdim  if (!hasDefinition())
951235633Sdim    return true;
952235633Sdim
953235633Sdim  return isPOD() && data().HasOnlyCMembers;
954235633Sdim}
955263509Sdim
956263509Sdimbool CXXRecordDecl::isGenericLambda() const {
957263509Sdim  if (!isLambda()) return false;
958263509Sdim  return getLambdaData().IsGenericLambda;
959263509Sdim}
960235633Sdim
961263509SdimCXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const {
962263509Sdim  if (!isLambda()) return 0;
963263509Sdim  DeclarationName Name =
964263509Sdim    getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
965263509Sdim  DeclContext::lookup_const_result Calls = lookup(Name);
966263509Sdim
967263509Sdim  assert(!Calls.empty() && "Missing lambda call operator!");
968263509Sdim  assert(Calls.size() == 1 && "More than one lambda call operator!");
969263509Sdim
970263509Sdim  NamedDecl *CallOp = Calls.front();
971263509Sdim  if (FunctionTemplateDecl *CallOpTmpl =
972263509Sdim                    dyn_cast<FunctionTemplateDecl>(CallOp))
973263509Sdim    return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl());
974263509Sdim
975263509Sdim  return cast<CXXMethodDecl>(CallOp);
976263509Sdim}
977263509Sdim
978263509SdimCXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const {
979263509Sdim  if (!isLambda()) return 0;
980263509Sdim  DeclarationName Name =
981263509Sdim    &getASTContext().Idents.get(getLambdaStaticInvokerName());
982263509Sdim  DeclContext::lookup_const_result Invoker = lookup(Name);
983263509Sdim  if (Invoker.empty()) return 0;
984263509Sdim  assert(Invoker.size() == 1 && "More than one static invoker operator!");
985263509Sdim  NamedDecl *InvokerFun = Invoker.front();
986263509Sdim  if (FunctionTemplateDecl *InvokerTemplate =
987263509Sdim                  dyn_cast<FunctionTemplateDecl>(InvokerFun))
988263509Sdim    return cast<CXXMethodDecl>(InvokerTemplate->getTemplatedDecl());
989263509Sdim
990263509Sdim  return cast<CXXMethodDecl>(InvokerFun);
991263509Sdim}
992263509Sdim
993235633Sdimvoid CXXRecordDecl::getCaptureFields(
994235633Sdim       llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
995235633Sdim       FieldDecl *&ThisCapture) const {
996235633Sdim  Captures.clear();
997235633Sdim  ThisCapture = 0;
998235633Sdim
999235633Sdim  LambdaDefinitionData &Lambda = getLambdaData();
1000235633Sdim  RecordDecl::field_iterator Field = field_begin();
1001235633Sdim  for (LambdaExpr::Capture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
1002235633Sdim       C != CEnd; ++C, ++Field) {
1003263509Sdim    if (C->capturesThis())
1004235633Sdim      ThisCapture = *Field;
1005263509Sdim    else if (C->capturesVariable())
1006263509Sdim      Captures[C->getCapturedVar()] = *Field;
1007235633Sdim  }
1008263509Sdim  assert(Field == field_end());
1009235633Sdim}
1010235633Sdim
1011263509SdimTemplateParameterList *
1012263509SdimCXXRecordDecl::getGenericLambdaTemplateParameterList() const {
1013263509Sdim  if (!isLambda()) return 0;
1014263509Sdim  CXXMethodDecl *CallOp = getLambdaCallOperator();
1015263509Sdim  if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate())
1016263509Sdim    return Tmpl->getTemplateParameters();
1017263509Sdim  return 0;
1018263509Sdim}
1019235633Sdim
1020205219Srdivackystatic CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
1021205219Srdivacky  QualType T;
1022206084Srdivacky  if (isa<UsingShadowDecl>(Conv))
1023206084Srdivacky    Conv = cast<UsingShadowDecl>(Conv)->getTargetDecl();
1024205219Srdivacky  if (FunctionTemplateDecl *ConvTemp = dyn_cast<FunctionTemplateDecl>(Conv))
1025205219Srdivacky    T = ConvTemp->getTemplatedDecl()->getResultType();
1026205219Srdivacky  else
1027205219Srdivacky    T = cast<CXXConversionDecl>(Conv)->getConversionType();
1028205219Srdivacky  return Context.getCanonicalType(T);
1029198092Srdivacky}
1030198092Srdivacky
1031205219Srdivacky/// Collect the visible conversions of a base class.
1032205219Srdivacky///
1033245431Sdim/// \param Record a base class of the class we're considering
1034205219Srdivacky/// \param InVirtual whether this base class is a virtual base (or a base
1035205219Srdivacky///   of a virtual base)
1036205219Srdivacky/// \param Access the access along the inheritance path to this base
1037205219Srdivacky/// \param ParentHiddenTypes the conversions provided by the inheritors
1038205219Srdivacky///   of this base
1039205219Srdivacky/// \param Output the set to which to add conversions from non-virtual bases
1040205219Srdivacky/// \param VOutput the set to which to add conversions from virtual bases
1041205219Srdivacky/// \param HiddenVBaseCs the set of conversions which were hidden in a
1042205219Srdivacky///   virtual base along some inheritance path
1043205219Srdivackystatic void CollectVisibleConversions(ASTContext &Context,
1044205219Srdivacky                                      CXXRecordDecl *Record,
1045205219Srdivacky                                      bool InVirtual,
1046205219Srdivacky                                      AccessSpecifier Access,
1047205219Srdivacky                  const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes,
1048252723Sdim                                      ASTUnresolvedSet &Output,
1049205219Srdivacky                                      UnresolvedSetImpl &VOutput,
1050205219Srdivacky                           llvm::SmallPtrSet<NamedDecl*, 8> &HiddenVBaseCs) {
1051205219Srdivacky  // The set of types which have conversions in this class or its
1052205219Srdivacky  // subclasses.  As an optimization, we don't copy the derived set
1053205219Srdivacky  // unless it might change.
1054205219Srdivacky  const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes;
1055205219Srdivacky  llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer;
1056205219Srdivacky
1057205219Srdivacky  // Collect the direct conversions and figure out which conversions
1058205219Srdivacky  // will be hidden in the subclasses.
1059252723Sdim  CXXRecordDecl::conversion_iterator ConvI = Record->conversion_begin();
1060252723Sdim  CXXRecordDecl::conversion_iterator ConvE = Record->conversion_end();
1061252723Sdim  if (ConvI != ConvE) {
1062205219Srdivacky    HiddenTypesBuffer = ParentHiddenTypes;
1063205219Srdivacky    HiddenTypes = &HiddenTypesBuffer;
1064205219Srdivacky
1065252723Sdim    for (CXXRecordDecl::conversion_iterator I = ConvI; I != ConvE; ++I) {
1066245431Sdim      CanQualType ConvType(GetConversionType(Context, I.getDecl()));
1067245431Sdim      bool Hidden = ParentHiddenTypes.count(ConvType);
1068245431Sdim      if (!Hidden)
1069245431Sdim        HiddenTypesBuffer.insert(ConvType);
1070205219Srdivacky
1071205219Srdivacky      // If this conversion is hidden and we're in a virtual base,
1072205219Srdivacky      // remember that it's hidden along some inheritance path.
1073205219Srdivacky      if (Hidden && InVirtual)
1074205219Srdivacky        HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()));
1075205219Srdivacky
1076205219Srdivacky      // If this conversion isn't hidden, add it to the appropriate output.
1077205219Srdivacky      else if (!Hidden) {
1078205219Srdivacky        AccessSpecifier IAccess
1079205219Srdivacky          = CXXRecordDecl::MergeAccess(Access, I.getAccess());
1080205219Srdivacky
1081205219Srdivacky        if (InVirtual)
1082205219Srdivacky          VOutput.addDecl(I.getDecl(), IAccess);
1083198092Srdivacky        else
1084252723Sdim          Output.addDecl(Context, I.getDecl(), IAccess);
1085198092Srdivacky      }
1086198092Srdivacky    }
1087198092Srdivacky  }
1088198893Srdivacky
1089205219Srdivacky  // Collect information recursively from any base classes.
1090205219Srdivacky  for (CXXRecordDecl::base_class_iterator
1091205219Srdivacky         I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
1092205219Srdivacky    const RecordType *RT = I->getType()->getAs<RecordType>();
1093205219Srdivacky    if (!RT) continue;
1094198893Srdivacky
1095205219Srdivacky    AccessSpecifier BaseAccess
1096205219Srdivacky      = CXXRecordDecl::MergeAccess(Access, I->getAccessSpecifier());
1097205219Srdivacky    bool BaseInVirtual = InVirtual || I->isVirtual();
1098198893Srdivacky
1099205219Srdivacky    CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
1100205219Srdivacky    CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess,
1101205219Srdivacky                              *HiddenTypes, Output, VOutput, HiddenVBaseCs);
1102198092Srdivacky  }
1103205219Srdivacky}
1104198893Srdivacky
1105205219Srdivacky/// Collect the visible conversions of a class.
1106205219Srdivacky///
1107205219Srdivacky/// This would be extremely straightforward if it weren't for virtual
1108205219Srdivacky/// bases.  It might be worth special-casing that, really.
1109205219Srdivackystatic void CollectVisibleConversions(ASTContext &Context,
1110205219Srdivacky                                      CXXRecordDecl *Record,
1111252723Sdim                                      ASTUnresolvedSet &Output) {
1112205219Srdivacky  // The collection of all conversions in virtual bases that we've
1113205219Srdivacky  // found.  These will be added to the output as long as they don't
1114205219Srdivacky  // appear in the hidden-conversions set.
1115205219Srdivacky  UnresolvedSet<8> VBaseCs;
1116205219Srdivacky
1117205219Srdivacky  // The set of conversions in virtual bases that we've determined to
1118205219Srdivacky  // be hidden.
1119205219Srdivacky  llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs;
1120205219Srdivacky
1121205219Srdivacky  // The set of types hidden by classes derived from this one.
1122205219Srdivacky  llvm::SmallPtrSet<CanQualType, 8> HiddenTypes;
1123205219Srdivacky
1124205219Srdivacky  // Go ahead and collect the direct conversions and add them to the
1125205219Srdivacky  // hidden-types set.
1126252723Sdim  CXXRecordDecl::conversion_iterator ConvI = Record->conversion_begin();
1127252723Sdim  CXXRecordDecl::conversion_iterator ConvE = Record->conversion_end();
1128252723Sdim  Output.append(Context, ConvI, ConvE);
1129252723Sdim  for (; ConvI != ConvE; ++ConvI)
1130252723Sdim    HiddenTypes.insert(GetConversionType(Context, ConvI.getDecl()));
1131205219Srdivacky
1132205219Srdivacky  // Recursively collect conversions from base classes.
1133205219Srdivacky  for (CXXRecordDecl::base_class_iterator
1134205219Srdivacky         I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
1135205219Srdivacky    const RecordType *RT = I->getType()->getAs<RecordType>();
1136205219Srdivacky    if (!RT) continue;
1137205219Srdivacky
1138205219Srdivacky    CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()),
1139205219Srdivacky                              I->isVirtual(), I->getAccessSpecifier(),
1140205219Srdivacky                              HiddenTypes, Output, VBaseCs, HiddenVBaseCs);
1141198092Srdivacky  }
1142205219Srdivacky
1143205219Srdivacky  // Add any unhidden conversions provided by virtual bases.
1144205219Srdivacky  for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end();
1145205219Srdivacky         I != E; ++I) {
1146205219Srdivacky    if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())))
1147252723Sdim      Output.addDecl(Context, I.getDecl(), I.getAccess());
1148205219Srdivacky  }
1149198092Srdivacky}
1150198092Srdivacky
1151198092Srdivacky/// getVisibleConversionFunctions - get all conversion functions visible
1152198092Srdivacky/// in current class; including conversion function templates.
1153252723Sdimstd::pair<CXXRecordDecl::conversion_iterator,CXXRecordDecl::conversion_iterator>
1154252723SdimCXXRecordDecl::getVisibleConversionFunctions() {
1155263509Sdim  ASTContext &Ctx = getASTContext();
1156263509Sdim
1157263509Sdim  ASTUnresolvedSet *Set;
1158263509Sdim  if (bases_begin() == bases_end()) {
1159263509Sdim    // If root class, all conversions are visible.
1160263509Sdim    Set = &data().Conversions.get(Ctx);
1161263509Sdim  } else {
1162263509Sdim    Set = &data().VisibleConversions.get(Ctx);
1163263509Sdim    // If visible conversion list is not evaluated, evaluate it.
1164263509Sdim    if (!data().ComputedVisibleConversions) {
1165263509Sdim      CollectVisibleConversions(Ctx, this, *Set);
1166263509Sdim      data().ComputedVisibleConversions = true;
1167263509Sdim    }
1168252723Sdim  }
1169263509Sdim  return std::make_pair(Set->begin(), Set->end());
1170198092Srdivacky}
1171198092Srdivacky
1172206084Srdivackyvoid CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
1173206084Srdivacky  // This operation is O(N) but extremely rare.  Sema only uses it to
1174206084Srdivacky  // remove UsingShadowDecls in a class that were followed by a direct
1175206084Srdivacky  // declaration, e.g.:
1176206084Srdivacky  //   class A : B {
1177206084Srdivacky  //     using B::operator int;
1178206084Srdivacky  //     operator int();
1179206084Srdivacky  //   };
1180206084Srdivacky  // This is uncommon by itself and even more uncommon in conjunction
1181206084Srdivacky  // with sufficiently large numbers of directly-declared conversions
1182206084Srdivacky  // that asymptotic behavior matters.
1183206084Srdivacky
1184263509Sdim  ASTUnresolvedSet &Convs = data().Conversions.get(getASTContext());
1185206084Srdivacky  for (unsigned I = 0, E = Convs.size(); I != E; ++I) {
1186206084Srdivacky    if (Convs[I].getDecl() == ConvDecl) {
1187206084Srdivacky      Convs.erase(I);
1188206084Srdivacky      assert(std::find(Convs.begin(), Convs.end(), ConvDecl) == Convs.end()
1189206084Srdivacky             && "conversion was found multiple times in unresolved set");
1190206084Srdivacky      return;
1191206084Srdivacky    }
1192206084Srdivacky  }
1193206084Srdivacky
1194206084Srdivacky  llvm_unreachable("conversion not found in set!");
1195198092Srdivacky}
1196194613Sed
1197198092SrdivackyCXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
1198198092Srdivacky  if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
1199198092Srdivacky    return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
1200198092Srdivacky
1201198092Srdivacky  return 0;
1202198092Srdivacky}
1203198092Srdivacky
1204198092Srdivackyvoid
1205198092SrdivackyCXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
1206198092Srdivacky                                             TemplateSpecializationKind TSK) {
1207198092Srdivacky  assert(TemplateOrInstantiation.isNull() &&
1208198092Srdivacky         "Previous template or instantiation?");
1209263509Sdim  assert(!isa<ClassTemplatePartialSpecializationDecl>(this));
1210198092Srdivacky  TemplateOrInstantiation
1211198092Srdivacky    = new (getASTContext()) MemberSpecializationInfo(RD, TSK);
1212198092Srdivacky}
1213198092Srdivacky
1214200583SrdivackyTemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{
1215200583Srdivacky  if (const ClassTemplateSpecializationDecl *Spec
1216198092Srdivacky        = dyn_cast<ClassTemplateSpecializationDecl>(this))
1217198092Srdivacky    return Spec->getSpecializationKind();
1218198092Srdivacky
1219198092Srdivacky  if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
1220198092Srdivacky    return MSInfo->getTemplateSpecializationKind();
1221198092Srdivacky
1222198092Srdivacky  return TSK_Undeclared;
1223198092Srdivacky}
1224198092Srdivacky
1225198092Srdivackyvoid
1226198092SrdivackyCXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
1227198092Srdivacky  if (ClassTemplateSpecializationDecl *Spec
1228198092Srdivacky      = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
1229198092Srdivacky    Spec->setSpecializationKind(TSK);
1230198092Srdivacky    return;
1231198092Srdivacky  }
1232198092Srdivacky
1233198092Srdivacky  if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
1234198092Srdivacky    MSInfo->setTemplateSpecializationKind(TSK);
1235198092Srdivacky    return;
1236198092Srdivacky  }
1237198092Srdivacky
1238226890Sdim  llvm_unreachable("Not a class template or member class specialization");
1239198092Srdivacky}
1240198092Srdivacky
1241210299SedCXXDestructorDecl *CXXRecordDecl::getDestructor() const {
1242210299Sed  ASTContext &Context = getASTContext();
1243193326Sed  QualType ClassType = Context.getTypeDeclType(this);
1244193326Sed
1245198092Srdivacky  DeclarationName Name
1246198092Srdivacky    = Context.DeclarationNames.getCXXDestructorName(
1247198092Srdivacky                                          Context.getCanonicalType(ClassType));
1248198092Srdivacky
1249252723Sdim  DeclContext::lookup_const_result R = lookup(Name);
1250252723Sdim  if (R.empty())
1251212904Sdim    return 0;
1252198092Srdivacky
1253252723Sdim  CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(R.front());
1254193326Sed  return Dtor;
1255193326Sed}
1256193326Sed
1257218893Sdimvoid CXXRecordDecl::completeDefinition() {
1258218893Sdim  completeDefinition(0);
1259218893Sdim}
1260218893Sdim
1261218893Sdimvoid CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
1262218893Sdim  RecordDecl::completeDefinition();
1263218893Sdim
1264235633Sdim  if (hasObjectMember() && getASTContext().getLangOpts().ObjCAutoRefCount) {
1265224145Sdim    // Objective-C Automatic Reference Counting:
1266224145Sdim    //   If a class has a non-static data member of Objective-C pointer
1267224145Sdim    //   type (or array thereof), it is a non-POD type and its
1268245431Sdim    //   default constructor (if any), copy constructor, move constructor,
1269245431Sdim    //   copy assignment operator, move assignment operator, and destructor are
1270245431Sdim    //   non-trivial.
1271224145Sdim    struct DefinitionData &Data = data();
1272224145Sdim    Data.PlainOldData = false;
1273252723Sdim    Data.HasTrivialSpecialMembers = 0;
1274235633Sdim    Data.HasIrrelevantDestructor = false;
1275224145Sdim  }
1276224145Sdim
1277218893Sdim  // If the class may be abstract (but hasn't been marked as such), check for
1278218893Sdim  // any pure final overriders.
1279218893Sdim  if (mayBeAbstract()) {
1280218893Sdim    CXXFinalOverriderMap MyFinalOverriders;
1281218893Sdim    if (!FinalOverriders) {
1282218893Sdim      getFinalOverriders(MyFinalOverriders);
1283218893Sdim      FinalOverriders = &MyFinalOverriders;
1284218893Sdim    }
1285218893Sdim
1286218893Sdim    bool Done = false;
1287218893Sdim    for (CXXFinalOverriderMap::iterator M = FinalOverriders->begin(),
1288218893Sdim                                     MEnd = FinalOverriders->end();
1289218893Sdim         M != MEnd && !Done; ++M) {
1290218893Sdim      for (OverridingMethods::iterator SO = M->second.begin(),
1291218893Sdim                                    SOEnd = M->second.end();
1292218893Sdim           SO != SOEnd && !Done; ++SO) {
1293218893Sdim        assert(SO->second.size() > 0 &&
1294218893Sdim               "All virtual functions have overridding virtual functions");
1295218893Sdim
1296218893Sdim        // C++ [class.abstract]p4:
1297218893Sdim        //   A class is abstract if it contains or inherits at least one
1298218893Sdim        //   pure virtual function for which the final overrider is pure
1299218893Sdim        //   virtual.
1300218893Sdim        if (SO->second.front().Method->isPure()) {
1301218893Sdim          data().Abstract = true;
1302218893Sdim          Done = true;
1303218893Sdim          break;
1304218893Sdim        }
1305218893Sdim      }
1306218893Sdim    }
1307218893Sdim  }
1308218893Sdim
1309218893Sdim  // Set access bits correctly on the directly-declared conversions.
1310263509Sdim  for (conversion_iterator I = conversion_begin(), E = conversion_end();
1311218893Sdim       I != E; ++I)
1312252723Sdim    I.setAccess((*I)->getAccess());
1313218893Sdim}
1314218893Sdim
1315218893Sdimbool CXXRecordDecl::mayBeAbstract() const {
1316218893Sdim  if (data().Abstract || isInvalidDecl() || !data().Polymorphic ||
1317218893Sdim      isDependentContext())
1318218893Sdim    return false;
1319218893Sdim
1320218893Sdim  for (CXXRecordDecl::base_class_const_iterator B = bases_begin(),
1321218893Sdim                                             BEnd = bases_end();
1322218893Sdim       B != BEnd; ++B) {
1323218893Sdim    CXXRecordDecl *BaseDecl
1324218893Sdim      = cast<CXXRecordDecl>(B->getType()->getAs<RecordType>()->getDecl());
1325218893Sdim    if (BaseDecl->isAbstract())
1326218893Sdim      return true;
1327218893Sdim  }
1328218893Sdim
1329218893Sdim  return false;
1330218893Sdim}
1331218893Sdim
1332235633Sdimvoid CXXMethodDecl::anchor() { }
1333235633Sdim
1334252723Sdimbool CXXMethodDecl::isStatic() const {
1335252723Sdim  const CXXMethodDecl *MD = getCanonicalDecl();
1336252723Sdim
1337252723Sdim  if (MD->getStorageClass() == SC_Static)
1338252723Sdim    return true;
1339252723Sdim
1340263509Sdim  OverloadedOperatorKind OOK = getDeclName().getCXXOverloadedOperator();
1341263509Sdim  return isStaticOverloadedOperator(OOK);
1342252723Sdim}
1343252723Sdim
1344245431Sdimstatic bool recursivelyOverrides(const CXXMethodDecl *DerivedMD,
1345245431Sdim                                 const CXXMethodDecl *BaseMD) {
1346245431Sdim  for (CXXMethodDecl::method_iterator I = DerivedMD->begin_overridden_methods(),
1347245431Sdim         E = DerivedMD->end_overridden_methods(); I != E; ++I) {
1348245431Sdim    const CXXMethodDecl *MD = *I;
1349245431Sdim    if (MD->getCanonicalDecl() == BaseMD->getCanonicalDecl())
1350245431Sdim      return true;
1351245431Sdim    if (recursivelyOverrides(MD, BaseMD))
1352245431Sdim      return true;
1353245431Sdim  }
1354245431Sdim  return false;
1355245431Sdim}
1356245431Sdim
1357193326SedCXXMethodDecl *
1358245431SdimCXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
1359245431Sdim                                             bool MayBeBase) {
1360245431Sdim  if (this->getParent()->getCanonicalDecl() == RD->getCanonicalDecl())
1361245431Sdim    return this;
1362245431Sdim
1363245431Sdim  // Lookup doesn't work for destructors, so handle them separately.
1364245431Sdim  if (isa<CXXDestructorDecl>(this)) {
1365245431Sdim    CXXMethodDecl *MD = RD->getDestructor();
1366245431Sdim    if (MD) {
1367245431Sdim      if (recursivelyOverrides(MD, this))
1368245431Sdim        return MD;
1369245431Sdim      if (MayBeBase && recursivelyOverrides(this, MD))
1370245431Sdim        return MD;
1371245431Sdim    }
1372245431Sdim    return NULL;
1373245431Sdim  }
1374245431Sdim
1375245431Sdim  lookup_const_result Candidates = RD->lookup(getDeclName());
1376252723Sdim  for (NamedDecl * const * I = Candidates.begin(); I != Candidates.end(); ++I) {
1377245431Sdim    CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*I);
1378245431Sdim    if (!MD)
1379245431Sdim      continue;
1380245431Sdim    if (recursivelyOverrides(MD, this))
1381245431Sdim      return MD;
1382245431Sdim    if (MayBeBase && recursivelyOverrides(this, MD))
1383245431Sdim      return MD;
1384245431Sdim  }
1385245431Sdim
1386245431Sdim  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
1387245431Sdim         E = RD->bases_end(); I != E; ++I) {
1388245431Sdim    const RecordType *RT = I->getType()->getAs<RecordType>();
1389245431Sdim    if (!RT)
1390245431Sdim      continue;
1391245431Sdim    const CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
1392245431Sdim    CXXMethodDecl *T = this->getCorrespondingMethodInClass(Base);
1393245431Sdim    if (T)
1394245431Sdim      return T;
1395245431Sdim  }
1396245431Sdim
1397245431Sdim  return NULL;
1398245431Sdim}
1399245431Sdim
1400245431SdimCXXMethodDecl *
1401193326SedCXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
1402221345Sdim                      SourceLocation StartLoc,
1403212904Sdim                      const DeclarationNameInfo &NameInfo,
1404200583Srdivacky                      QualType T, TypeSourceInfo *TInfo,
1405252723Sdim                      StorageClass SC, bool isInline,
1406226890Sdim                      bool isConstexpr, SourceLocation EndLocation) {
1407221345Sdim  return new (C) CXXMethodDecl(CXXMethod, RD, StartLoc, NameInfo, T, TInfo,
1408252723Sdim                               SC, isInline, isConstexpr,
1409226890Sdim                               EndLocation);
1410193326Sed}
1411193326Sed
1412235633SdimCXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1413235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXMethodDecl));
1414235633Sdim  return new (Mem) CXXMethodDecl(CXXMethod, 0, SourceLocation(),
1415235633Sdim                                 DeclarationNameInfo(), QualType(),
1416252723Sdim                                 0, SC_None, false, false,
1417235633Sdim                                 SourceLocation());
1418235633Sdim}
1419235633Sdim
1420198092Srdivackybool CXXMethodDecl::isUsualDeallocationFunction() const {
1421198092Srdivacky  if (getOverloadedOperator() != OO_Delete &&
1422198092Srdivacky      getOverloadedOperator() != OO_Array_Delete)
1423198092Srdivacky    return false;
1424204643Srdivacky
1425198092Srdivacky  // C++ [basic.stc.dynamic.deallocation]p2:
1426204643Srdivacky  //   A template instance is never a usual deallocation function,
1427204643Srdivacky  //   regardless of its signature.
1428204643Srdivacky  if (getPrimaryTemplate())
1429204643Srdivacky    return false;
1430204643Srdivacky
1431204643Srdivacky  // C++ [basic.stc.dynamic.deallocation]p2:
1432198092Srdivacky  //   If a class T has a member deallocation function named operator delete
1433198092Srdivacky  //   with exactly one parameter, then that function is a usual (non-placement)
1434198092Srdivacky  //   deallocation function. [...]
1435198092Srdivacky  if (getNumParams() == 1)
1436198092Srdivacky    return true;
1437198092Srdivacky
1438198092Srdivacky  // C++ [basic.stc.dynamic.deallocation]p2:
1439198092Srdivacky  //   [...] If class T does not declare such an operator delete but does
1440198092Srdivacky  //   declare a member deallocation function named operator delete with
1441198092Srdivacky  //   exactly two parameters, the second of which has type std::size_t (18.1),
1442198092Srdivacky  //   then this function is a usual deallocation function.
1443198092Srdivacky  ASTContext &Context = getASTContext();
1444198092Srdivacky  if (getNumParams() != 2 ||
1445203955Srdivacky      !Context.hasSameUnqualifiedType(getParamDecl(1)->getType(),
1446203955Srdivacky                                      Context.getSizeType()))
1447198092Srdivacky    return false;
1448198092Srdivacky
1449198092Srdivacky  // This function is a usual deallocation function if there are no
1450198092Srdivacky  // single-parameter deallocation functions of the same kind.
1451252723Sdim  DeclContext::lookup_const_result R = getDeclContext()->lookup(getDeclName());
1452252723Sdim  for (DeclContext::lookup_const_result::iterator I = R.begin(), E = R.end();
1453252723Sdim       I != E; ++I) {
1454252723Sdim    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I))
1455198092Srdivacky      if (FD->getNumParams() == 1)
1456198092Srdivacky        return false;
1457198092Srdivacky  }
1458198092Srdivacky
1459198092Srdivacky  return true;
1460198092Srdivacky}
1461193326Sed
1462207619Srdivackybool CXXMethodDecl::isCopyAssignmentOperator() const {
1463223017Sdim  // C++0x [class.copy]p17:
1464207619Srdivacky  //  A user-declared copy assignment operator X::operator= is a non-static
1465207619Srdivacky  //  non-template member function of class X with exactly one parameter of
1466207619Srdivacky  //  type X, X&, const X&, volatile X& or const volatile X&.
1467207619Srdivacky  if (/*operator=*/getOverloadedOperator() != OO_Equal ||
1468207619Srdivacky      /*non-static*/ isStatic() ||
1469263509Sdim      /*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate() ||
1470263509Sdim      getNumParams() != 1)
1471207619Srdivacky    return false;
1472207619Srdivacky
1473207619Srdivacky  QualType ParamType = getParamDecl(0)->getType();
1474207619Srdivacky  if (const LValueReferenceType *Ref = ParamType->getAs<LValueReferenceType>())
1475207619Srdivacky    ParamType = Ref->getPointeeType();
1476207619Srdivacky
1477207619Srdivacky  ASTContext &Context = getASTContext();
1478207619Srdivacky  QualType ClassType
1479207619Srdivacky    = Context.getCanonicalType(Context.getTypeDeclType(getParent()));
1480207619Srdivacky  return Context.hasSameUnqualifiedType(ClassType, ParamType);
1481207619Srdivacky}
1482207619Srdivacky
1483223017Sdimbool CXXMethodDecl::isMoveAssignmentOperator() const {
1484223017Sdim  // C++0x [class.copy]p19:
1485223017Sdim  //  A user-declared move assignment operator X::operator= is a non-static
1486223017Sdim  //  non-template member function of class X with exactly one parameter of type
1487223017Sdim  //  X&&, const X&&, volatile X&&, or const volatile X&&.
1488223017Sdim  if (getOverloadedOperator() != OO_Equal || isStatic() ||
1489263509Sdim      getPrimaryTemplate() || getDescribedFunctionTemplate() ||
1490263509Sdim      getNumParams() != 1)
1491223017Sdim    return false;
1492223017Sdim
1493223017Sdim  QualType ParamType = getParamDecl(0)->getType();
1494223017Sdim  if (!isa<RValueReferenceType>(ParamType))
1495223017Sdim    return false;
1496223017Sdim  ParamType = ParamType->getPointeeType();
1497223017Sdim
1498223017Sdim  ASTContext &Context = getASTContext();
1499223017Sdim  QualType ClassType
1500223017Sdim    = Context.getCanonicalType(Context.getTypeDeclType(getParent()));
1501223017Sdim  return Context.hasSameUnqualifiedType(ClassType, ParamType);
1502223017Sdim}
1503223017Sdim
1504193326Sedvoid CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
1505200583Srdivacky  assert(MD->isCanonicalDecl() && "Method is not canonical!");
1506203955Srdivacky  assert(!MD->getParent()->isDependentContext() &&
1507203955Srdivacky         "Can't add an overridden method to a class template!");
1508235633Sdim  assert(MD->isVirtual() && "Method is not virtual!");
1509203955Srdivacky
1510204643Srdivacky  getASTContext().addOverriddenMethod(this, MD);
1511193326Sed}
1512193326Sed
1513193326SedCXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
1514235633Sdim  if (isa<CXXConstructorDecl>(this)) return 0;
1515204643Srdivacky  return getASTContext().overridden_methods_begin(this);
1516193326Sed}
1517193326Sed
1518193326SedCXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
1519235633Sdim  if (isa<CXXConstructorDecl>(this)) return 0;
1520204643Srdivacky  return getASTContext().overridden_methods_end(this);
1521193326Sed}
1522193326Sed
1523210299Sedunsigned CXXMethodDecl::size_overridden_methods() const {
1524235633Sdim  if (isa<CXXConstructorDecl>(this)) return 0;
1525210299Sed  return getASTContext().overridden_methods_size(this);
1526210299Sed}
1527210299Sed
1528193326SedQualType CXXMethodDecl::getThisType(ASTContext &C) const {
1529193326Sed  // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
1530193326Sed  // If the member function is declared const, the type of this is const X*,
1531193326Sed  // if the member function is declared volatile, the type of this is
1532193326Sed  // volatile X*, and if the member function is declared const volatile,
1533193326Sed  // the type of this is const volatile X*.
1534193326Sed
1535193326Sed  assert(isInstance() && "No 'this' for static methods!");
1536194179Sed
1537204962Srdivacky  QualType ClassTy = C.getTypeDeclType(getParent());
1538198092Srdivacky  ClassTy = C.getQualifiedType(ClassTy,
1539198092Srdivacky                               Qualifiers::fromCVRMask(getTypeQualifiers()));
1540198092Srdivacky  return C.getPointerType(ClassTy);
1541193326Sed}
1542193326Sed
1543200583Srdivackybool CXXMethodDecl::hasInlineBody() const {
1544202379Srdivacky  // If this function is a template instantiation, look at the template from
1545202379Srdivacky  // which it was instantiated.
1546202379Srdivacky  const FunctionDecl *CheckFn = getTemplateInstantiationPattern();
1547202379Srdivacky  if (!CheckFn)
1548202379Srdivacky    CheckFn = this;
1549202379Srdivacky
1550200583Srdivacky  const FunctionDecl *fn;
1551210299Sed  return CheckFn->hasBody(fn) && !fn->isOutOfLine();
1552200583Srdivacky}
1553200583Srdivacky
1554235633Sdimbool CXXMethodDecl::isLambdaStaticInvoker() const {
1555263509Sdim  const CXXRecordDecl *P = getParent();
1556263509Sdim  if (P->isLambda()) {
1557263509Sdim    if (const CXXMethodDecl *StaticInvoker = P->getLambdaStaticInvoker()) {
1558263509Sdim      if (StaticInvoker == this) return true;
1559263509Sdim      if (P->isGenericLambda() && this->isFunctionTemplateSpecialization())
1560263509Sdim        return StaticInvoker == this->getPrimaryTemplate()->getTemplatedDecl();
1561263509Sdim    }
1562263509Sdim  }
1563263509Sdim  return false;
1564235633Sdim}
1565235633Sdim
1566218893SdimCXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
1567218893Sdim                                       TypeSourceInfo *TInfo, bool IsVirtual,
1568218893Sdim                                       SourceLocation L, Expr *Init,
1569218893Sdim                                       SourceLocation R,
1570218893Sdim                                       SourceLocation EllipsisLoc)
1571218893Sdim  : Initializee(TInfo), MemberOrEllipsisLocation(EllipsisLoc), Init(Init),
1572235633Sdim    LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(IsVirtual),
1573235633Sdim    IsWritten(false), SourceOrderOrNumArrayIndices(0)
1574200583Srdivacky{
1575193326Sed}
1576193326Sed
1577218893SdimCXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
1578218893Sdim                                       FieldDecl *Member,
1579218893Sdim                                       SourceLocation MemberLoc,
1580218893Sdim                                       SourceLocation L, Expr *Init,
1581218893Sdim                                       SourceLocation R)
1582218893Sdim  : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
1583235633Sdim    LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
1584208600Srdivacky    IsWritten(false), SourceOrderOrNumArrayIndices(0)
1585208600Srdivacky{
1586208600Srdivacky}
1587208600Srdivacky
1588218893SdimCXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
1589218893Sdim                                       IndirectFieldDecl *Member,
1590218893Sdim                                       SourceLocation MemberLoc,
1591218893Sdim                                       SourceLocation L, Expr *Init,
1592218893Sdim                                       SourceLocation R)
1593218893Sdim  : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
1594235633Sdim    LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
1595218893Sdim    IsWritten(false), SourceOrderOrNumArrayIndices(0)
1596218893Sdim{
1597218893Sdim}
1598218893Sdim
1599218893SdimCXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
1600235633Sdim                                       TypeSourceInfo *TInfo,
1601235633Sdim                                       SourceLocation L, Expr *Init,
1602221345Sdim                                       SourceLocation R)
1603235633Sdim  : Initializee(TInfo), MemberOrEllipsisLocation(), Init(Init),
1604235633Sdim    LParenLoc(L), RParenLoc(R), IsDelegating(true), IsVirtual(false),
1605221345Sdim    IsWritten(false), SourceOrderOrNumArrayIndices(0)
1606221345Sdim{
1607221345Sdim}
1608221345Sdim
1609221345SdimCXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
1610218893Sdim                                       FieldDecl *Member,
1611218893Sdim                                       SourceLocation MemberLoc,
1612218893Sdim                                       SourceLocation L, Expr *Init,
1613218893Sdim                                       SourceLocation R,
1614218893Sdim                                       VarDecl **Indices,
1615218893Sdim                                       unsigned NumIndices)
1616218893Sdim  : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
1617218893Sdim    LParenLoc(L), RParenLoc(R), IsVirtual(false),
1618208600Srdivacky    IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
1619200583Srdivacky{
1620208600Srdivacky  VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
1621208600Srdivacky  memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));
1622193326Sed}
1623193326Sed
1624218893SdimCXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context,
1625218893Sdim                                               FieldDecl *Member,
1626218893Sdim                                               SourceLocation MemberLoc,
1627218893Sdim                                               SourceLocation L, Expr *Init,
1628218893Sdim                                               SourceLocation R,
1629218893Sdim                                               VarDecl **Indices,
1630218893Sdim                                               unsigned NumIndices) {
1631218893Sdim  void *Mem = Context.Allocate(sizeof(CXXCtorInitializer) +
1632208600Srdivacky                               sizeof(VarDecl *) * NumIndices,
1633218893Sdim                               llvm::alignOf<CXXCtorInitializer>());
1634218893Sdim  return new (Mem) CXXCtorInitializer(Context, Member, MemberLoc, L, Init, R,
1635218893Sdim                                      Indices, NumIndices);
1636208600Srdivacky}
1637208600Srdivacky
1638218893SdimTypeLoc CXXCtorInitializer::getBaseClassLoc() const {
1639200583Srdivacky  if (isBaseInitializer())
1640218893Sdim    return Initializee.get<TypeSourceInfo*>()->getTypeLoc();
1641200583Srdivacky  else
1642200583Srdivacky    return TypeLoc();
1643200583Srdivacky}
1644200583Srdivacky
1645218893Sdimconst Type *CXXCtorInitializer::getBaseClass() const {
1646200583Srdivacky  if (isBaseInitializer())
1647218893Sdim    return Initializee.get<TypeSourceInfo*>()->getType().getTypePtr();
1648200583Srdivacky  else
1649200583Srdivacky    return 0;
1650200583Srdivacky}
1651200583Srdivacky
1652218893SdimSourceLocation CXXCtorInitializer::getSourceLocation() const {
1653235633Sdim  if (isAnyMemberInitializer())
1654200583Srdivacky    return getMemberLocation();
1655223017Sdim
1656223017Sdim  if (isInClassMemberInitializer())
1657223017Sdim    return getAnyMember()->getLocation();
1658200583Srdivacky
1659235633Sdim  if (TypeSourceInfo *TSInfo = Initializee.get<TypeSourceInfo*>())
1660235633Sdim    return TSInfo->getTypeLoc().getLocalSourceRange().getBegin();
1661235633Sdim
1662235633Sdim  return SourceLocation();
1663200583Srdivacky}
1664200583Srdivacky
1665218893SdimSourceRange CXXCtorInitializer::getSourceRange() const {
1666223017Sdim  if (isInClassMemberInitializer()) {
1667223017Sdim    FieldDecl *D = getAnyMember();
1668223017Sdim    if (Expr *I = D->getInClassInitializer())
1669223017Sdim      return I->getSourceRange();
1670223017Sdim    return SourceRange();
1671223017Sdim  }
1672223017Sdim
1673200583Srdivacky  return SourceRange(getSourceLocation(), getRParenLoc());
1674200583Srdivacky}
1675200583Srdivacky
1676235633Sdimvoid CXXConstructorDecl::anchor() { }
1677235633Sdim
1678193326SedCXXConstructorDecl *
1679235633SdimCXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1680235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXConstructorDecl));
1681235633Sdim  return new (Mem) CXXConstructorDecl(0, SourceLocation(),DeclarationNameInfo(),
1682235633Sdim                                      QualType(), 0, false, false, false,false);
1683208600Srdivacky}
1684208600Srdivacky
1685208600SrdivackyCXXConstructorDecl *
1686193326SedCXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
1687221345Sdim                           SourceLocation StartLoc,
1688212904Sdim                           const DeclarationNameInfo &NameInfo,
1689200583Srdivacky                           QualType T, TypeSourceInfo *TInfo,
1690226890Sdim                           bool isExplicit, bool isInline,
1691226890Sdim                           bool isImplicitlyDeclared, bool isConstexpr) {
1692212904Sdim  assert(NameInfo.getName().getNameKind()
1693212904Sdim         == DeclarationName::CXXConstructorName &&
1694193326Sed         "Name must refer to a constructor");
1695221345Sdim  return new (C) CXXConstructorDecl(RD, StartLoc, NameInfo, T, TInfo,
1696226890Sdim                                    isExplicit, isInline, isImplicitlyDeclared,
1697226890Sdim                                    isConstexpr);
1698193326Sed}
1699193326Sed
1700235633SdimCXXConstructorDecl *CXXConstructorDecl::getTargetConstructor() const {
1701235633Sdim  assert(isDelegatingConstructor() && "Not a delegating constructor!");
1702235633Sdim  Expr *E = (*init_begin())->getInit()->IgnoreImplicit();
1703235633Sdim  if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(E))
1704235633Sdim    return Construct->getConstructor();
1705235633Sdim
1706235633Sdim  return 0;
1707235633Sdim}
1708235633Sdim
1709193326Sedbool CXXConstructorDecl::isDefaultConstructor() const {
1710193326Sed  // C++ [class.ctor]p5:
1711193326Sed  //   A default constructor for a class X is a constructor of class
1712193326Sed  //   X that can be called without an argument.
1713193326Sed  return (getNumParams() == 0) ||
1714198092Srdivacky         (getNumParams() > 0 && getParamDecl(0)->hasDefaultArg());
1715193326Sed}
1716193326Sed
1717198092Srdivackybool
1718201361SrdivackyCXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const {
1719218893Sdim  return isCopyOrMoveConstructor(TypeQuals) &&
1720218893Sdim         getParamDecl(0)->getType()->isLValueReferenceType();
1721218893Sdim}
1722218893Sdim
1723218893Sdimbool CXXConstructorDecl::isMoveConstructor(unsigned &TypeQuals) const {
1724218893Sdim  return isCopyOrMoveConstructor(TypeQuals) &&
1725218893Sdim    getParamDecl(0)->getType()->isRValueReferenceType();
1726218893Sdim}
1727218893Sdim
1728218893Sdim/// \brief Determine whether this is a copy or move constructor.
1729218893Sdimbool CXXConstructorDecl::isCopyOrMoveConstructor(unsigned &TypeQuals) const {
1730193326Sed  // C++ [class.copy]p2:
1731193326Sed  //   A non-template constructor for class X is a copy constructor
1732193326Sed  //   if its first parameter is of type X&, const X&, volatile X& or
1733193326Sed  //   const volatile X&, and either there are no other parameters
1734193326Sed  //   or else all other parameters have default arguments (8.3.6).
1735218893Sdim  // C++0x [class.copy]p3:
1736218893Sdim  //   A non-template constructor for class X is a move constructor if its
1737218893Sdim  //   first parameter is of type X&&, const X&&, volatile X&&, or
1738218893Sdim  //   const volatile X&&, and either there are no other parameters or else
1739218893Sdim  //   all other parameters have default arguments.
1740193326Sed  if ((getNumParams() < 1) ||
1741198092Srdivacky      (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
1742198092Srdivacky      (getPrimaryTemplate() != 0) ||
1743198092Srdivacky      (getDescribedFunctionTemplate() != 0))
1744193326Sed    return false;
1745218893Sdim
1746193326Sed  const ParmVarDecl *Param = getParamDecl(0);
1747218893Sdim
1748218893Sdim  // Do we have a reference type?
1749218893Sdim  const ReferenceType *ParamRefType = Param->getType()->getAs<ReferenceType>();
1750193326Sed  if (!ParamRefType)
1751193326Sed    return false;
1752218893Sdim
1753193326Sed  // Is it a reference to our class type?
1754201361Srdivacky  ASTContext &Context = getASTContext();
1755201361Srdivacky
1756198092Srdivacky  CanQualType PointeeType
1757193326Sed    = Context.getCanonicalType(ParamRefType->getPointeeType());
1758198092Srdivacky  CanQualType ClassTy
1759198092Srdivacky    = Context.getCanonicalType(Context.getTagDeclType(getParent()));
1760193326Sed  if (PointeeType.getUnqualifiedType() != ClassTy)
1761193326Sed    return false;
1762218893Sdim
1763198092Srdivacky  // FIXME: other qualifiers?
1764218893Sdim
1765218893Sdim  // We have a copy or move constructor.
1766193326Sed  TypeQuals = PointeeType.getCVRQualifiers();
1767218893Sdim  return true;
1768193326Sed}
1769193326Sed
1770198092Srdivackybool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {
1771193326Sed  // C++ [class.conv.ctor]p1:
1772193326Sed  //   A constructor declared without the function-specifier explicit
1773193326Sed  //   that can be called with a single parameter specifies a
1774193326Sed  //   conversion from the type of its first parameter to the type of
1775193326Sed  //   its class. Such a constructor is called a converting
1776193326Sed  //   constructor.
1777198092Srdivacky  if (isExplicit() && !AllowExplicit)
1778193326Sed    return false;
1779193326Sed
1780198092Srdivacky  return (getNumParams() == 0 &&
1781198092Srdivacky          getType()->getAs<FunctionProtoType>()->isVariadic()) ||
1782193326Sed         (getNumParams() == 1) ||
1783245431Sdim         (getNumParams() > 1 &&
1784245431Sdim          (getParamDecl(1)->hasDefaultArg() ||
1785245431Sdim           getParamDecl(1)->isParameterPack()));
1786193326Sed}
1787193326Sed
1788218893Sdimbool CXXConstructorDecl::isSpecializationCopyingObject() const {
1789199482Srdivacky  if ((getNumParams() < 1) ||
1790199482Srdivacky      (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
1791199482Srdivacky      (getPrimaryTemplate() == 0) ||
1792199482Srdivacky      (getDescribedFunctionTemplate() != 0))
1793199482Srdivacky    return false;
1794199482Srdivacky
1795199482Srdivacky  const ParmVarDecl *Param = getParamDecl(0);
1796199482Srdivacky
1797199482Srdivacky  ASTContext &Context = getASTContext();
1798199482Srdivacky  CanQualType ParamType = Context.getCanonicalType(Param->getType());
1799199482Srdivacky
1800199482Srdivacky  // Is it the same as our our class type?
1801199482Srdivacky  CanQualType ClassTy
1802199482Srdivacky    = Context.getCanonicalType(Context.getTagDeclType(getParent()));
1803199482Srdivacky  if (ParamType.getUnqualifiedType() != ClassTy)
1804199482Srdivacky    return false;
1805199482Srdivacky
1806199482Srdivacky  return true;
1807199482Srdivacky}
1808199482Srdivacky
1809218893Sdimconst CXXConstructorDecl *CXXConstructorDecl::getInheritedConstructor() const {
1810218893Sdim  // Hack: we store the inherited constructor in the overridden method table
1811235633Sdim  method_iterator It = getASTContext().overridden_methods_begin(this);
1812235633Sdim  if (It == getASTContext().overridden_methods_end(this))
1813218893Sdim    return 0;
1814218893Sdim
1815218893Sdim  return cast<CXXConstructorDecl>(*It);
1816218893Sdim}
1817218893Sdim
1818218893Sdimvoid
1819218893SdimCXXConstructorDecl::setInheritedConstructor(const CXXConstructorDecl *BaseCtor){
1820218893Sdim  // Hack: we store the inherited constructor in the overridden method table
1821235633Sdim  assert(getASTContext().overridden_methods_size(this) == 0 &&
1822235633Sdim         "Base ctor already set.");
1823235633Sdim  getASTContext().addOverriddenMethod(this, BaseCtor);
1824218893Sdim}
1825218893Sdim
1826235633Sdimvoid CXXDestructorDecl::anchor() { }
1827235633Sdim
1828193326SedCXXDestructorDecl *
1829235633SdimCXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1830235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXDestructorDecl));
1831235633Sdim  return new (Mem) CXXDestructorDecl(0, SourceLocation(), DeclarationNameInfo(),
1832218893Sdim                                   QualType(), 0, false, false);
1833208600Srdivacky}
1834208600Srdivacky
1835208600SrdivackyCXXDestructorDecl *
1836193326SedCXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
1837221345Sdim                          SourceLocation StartLoc,
1838212904Sdim                          const DeclarationNameInfo &NameInfo,
1839218893Sdim                          QualType T, TypeSourceInfo *TInfo,
1840226890Sdim                          bool isInline, bool isImplicitlyDeclared) {
1841212904Sdim  assert(NameInfo.getName().getNameKind()
1842212904Sdim         == DeclarationName::CXXDestructorName &&
1843193326Sed         "Name must refer to a destructor");
1844221345Sdim  return new (C) CXXDestructorDecl(RD, StartLoc, NameInfo, T, TInfo, isInline,
1845212904Sdim                                   isImplicitlyDeclared);
1846193326Sed}
1847193326Sed
1848235633Sdimvoid CXXConversionDecl::anchor() { }
1849235633Sdim
1850193326SedCXXConversionDecl *
1851235633SdimCXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1852235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXConversionDecl));
1853235633Sdim  return new (Mem) CXXConversionDecl(0, SourceLocation(), DeclarationNameInfo(),
1854235633Sdim                                     QualType(), 0, false, false, false,
1855235633Sdim                                     SourceLocation());
1856208600Srdivacky}
1857208600Srdivacky
1858208600SrdivackyCXXConversionDecl *
1859193326SedCXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
1860221345Sdim                          SourceLocation StartLoc,
1861212904Sdim                          const DeclarationNameInfo &NameInfo,
1862200583Srdivacky                          QualType T, TypeSourceInfo *TInfo,
1863221345Sdim                          bool isInline, bool isExplicit,
1864226890Sdim                          bool isConstexpr, SourceLocation EndLocation) {
1865212904Sdim  assert(NameInfo.getName().getNameKind()
1866212904Sdim         == DeclarationName::CXXConversionFunctionName &&
1867193326Sed         "Name must refer to a conversion function");
1868221345Sdim  return new (C) CXXConversionDecl(RD, StartLoc, NameInfo, T, TInfo,
1869226890Sdim                                   isInline, isExplicit, isConstexpr,
1870226890Sdim                                   EndLocation);
1871193326Sed}
1872193326Sed
1873235633Sdimbool CXXConversionDecl::isLambdaToBlockPointerConversion() const {
1874235633Sdim  return isImplicit() && getParent()->isLambda() &&
1875235633Sdim         getConversionType()->isBlockPointerType();
1876235633Sdim}
1877235633Sdim
1878235633Sdimvoid LinkageSpecDecl::anchor() { }
1879235633Sdim
1880193326SedLinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
1881198092Srdivacky                                         DeclContext *DC,
1882221345Sdim                                         SourceLocation ExternLoc,
1883221345Sdim                                         SourceLocation LangLoc,
1884221345Sdim                                         LanguageIDs Lang,
1885252723Sdim                                         bool HasBraces) {
1886252723Sdim  return new (C) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces);
1887193326Sed}
1888193326Sed
1889235633SdimLinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1890235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(LinkageSpecDecl));
1891235633Sdim  return new (Mem) LinkageSpecDecl(0, SourceLocation(), SourceLocation(),
1892252723Sdim                                   lang_c, false);
1893235633Sdim}
1894235633Sdim
1895235633Sdimvoid UsingDirectiveDecl::anchor() { }
1896235633Sdim
1897193326SedUsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
1898193326Sed                                               SourceLocation L,
1899193326Sed                                               SourceLocation NamespaceLoc,
1900219077Sdim                                           NestedNameSpecifierLoc QualifierLoc,
1901193326Sed                                               SourceLocation IdentLoc,
1902199990Srdivacky                                               NamedDecl *Used,
1903193326Sed                                               DeclContext *CommonAncestor) {
1904199990Srdivacky  if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used))
1905199990Srdivacky    Used = NS->getOriginalNamespace();
1906219077Sdim  return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc,
1907219077Sdim                                    IdentLoc, Used, CommonAncestor);
1908193326Sed}
1909193326Sed
1910235633SdimUsingDirectiveDecl *
1911235633SdimUsingDirectiveDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1912235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingDirectiveDecl));
1913235633Sdim  return new (Mem) UsingDirectiveDecl(0, SourceLocation(), SourceLocation(),
1914235633Sdim                                      NestedNameSpecifierLoc(),
1915235633Sdim                                      SourceLocation(), 0, 0);
1916235633Sdim}
1917235633Sdim
1918199990SrdivackyNamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
1919199990Srdivacky  if (NamespaceAliasDecl *NA =
1920199990Srdivacky        dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace))
1921199990Srdivacky    return NA->getNamespace();
1922199990Srdivacky  return cast_or_null<NamespaceDecl>(NominatedNamespace);
1923199990Srdivacky}
1924199990Srdivacky
1925235633Sdimvoid NamespaceDecl::anchor() { }
1926235633Sdim
1927235633SdimNamespaceDecl::NamespaceDecl(DeclContext *DC, bool Inline,
1928235633Sdim                             SourceLocation StartLoc,
1929235633Sdim                             SourceLocation IdLoc, IdentifierInfo *Id,
1930235633Sdim                             NamespaceDecl *PrevDecl)
1931235633Sdim  : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
1932235633Sdim    LocStart(StartLoc), RBraceLoc(), AnonOrFirstNamespaceAndInline(0, Inline)
1933235633Sdim{
1934263509Sdim  setPreviousDecl(PrevDecl);
1935235633Sdim
1936235633Sdim  if (PrevDecl)
1937235633Sdim    AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace());
1938235633Sdim}
1939235633Sdim
1940235633SdimNamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
1941235633Sdim                                     bool Inline, SourceLocation StartLoc,
1942235633Sdim                                     SourceLocation IdLoc, IdentifierInfo *Id,
1943235633Sdim                                     NamespaceDecl *PrevDecl) {
1944235633Sdim  return new (C) NamespaceDecl(DC, Inline, StartLoc, IdLoc, Id, PrevDecl);
1945235633Sdim}
1946235633Sdim
1947235633SdimNamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1948235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NamespaceDecl));
1949235633Sdim  return new (Mem) NamespaceDecl(0, false, SourceLocation(), SourceLocation(),
1950235633Sdim                                 0, 0);
1951235633Sdim}
1952235633Sdim
1953235633Sdimvoid NamespaceAliasDecl::anchor() { }
1954235633Sdim
1955198092SrdivackyNamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
1956212904Sdim                                               SourceLocation UsingLoc,
1957198092Srdivacky                                               SourceLocation AliasLoc,
1958198092Srdivacky                                               IdentifierInfo *Alias,
1959219077Sdim                                           NestedNameSpecifierLoc QualifierLoc,
1960198092Srdivacky                                               SourceLocation IdentLoc,
1961193326Sed                                               NamedDecl *Namespace) {
1962199990Srdivacky  if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
1963199990Srdivacky    Namespace = NS->getOriginalNamespace();
1964219077Sdim  return new (C) NamespaceAliasDecl(DC, UsingLoc, AliasLoc, Alias,
1965219077Sdim                                    QualifierLoc, IdentLoc, Namespace);
1966193326Sed}
1967193326Sed
1968235633SdimNamespaceAliasDecl *
1969235633SdimNamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1970235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NamespaceAliasDecl));
1971235633Sdim  return new (Mem) NamespaceAliasDecl(0, SourceLocation(), SourceLocation(), 0,
1972235633Sdim                                      NestedNameSpecifierLoc(),
1973235633Sdim                                      SourceLocation(), 0);
1974235633Sdim}
1975235633Sdim
1976235633Sdimvoid UsingShadowDecl::anchor() { }
1977235633Sdim
1978235633SdimUsingShadowDecl *
1979235633SdimUsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1980235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingShadowDecl));
1981235633Sdim  return new (Mem) UsingShadowDecl(0, SourceLocation(), 0, 0);
1982235633Sdim}
1983235633Sdim
1984218893SdimUsingDecl *UsingShadowDecl::getUsingDecl() const {
1985218893Sdim  const UsingShadowDecl *Shadow = this;
1986218893Sdim  while (const UsingShadowDecl *NextShadow =
1987218893Sdim         dyn_cast<UsingShadowDecl>(Shadow->UsingOrNextShadow))
1988218893Sdim    Shadow = NextShadow;
1989218893Sdim  return cast<UsingDecl>(Shadow->UsingOrNextShadow);
1990218893Sdim}
1991218893Sdim
1992235633Sdimvoid UsingDecl::anchor() { }
1993235633Sdim
1994218893Sdimvoid UsingDecl::addShadowDecl(UsingShadowDecl *S) {
1995218893Sdim  assert(std::find(shadow_begin(), shadow_end(), S) == shadow_end() &&
1996218893Sdim         "declaration already in set");
1997218893Sdim  assert(S->getUsingDecl() == this);
1998218893Sdim
1999235633Sdim  if (FirstUsingShadow.getPointer())
2000235633Sdim    S->UsingOrNextShadow = FirstUsingShadow.getPointer();
2001235633Sdim  FirstUsingShadow.setPointer(S);
2002218893Sdim}
2003218893Sdim
2004218893Sdimvoid UsingDecl::removeShadowDecl(UsingShadowDecl *S) {
2005218893Sdim  assert(std::find(shadow_begin(), shadow_end(), S) != shadow_end() &&
2006218893Sdim         "declaration not in set");
2007218893Sdim  assert(S->getUsingDecl() == this);
2008218893Sdim
2009218893Sdim  // Remove S from the shadow decl chain. This is O(n) but hopefully rare.
2010218893Sdim
2011235633Sdim  if (FirstUsingShadow.getPointer() == S) {
2012235633Sdim    FirstUsingShadow.setPointer(
2013235633Sdim      dyn_cast<UsingShadowDecl>(S->UsingOrNextShadow));
2014218893Sdim    S->UsingOrNextShadow = this;
2015218893Sdim    return;
2016218893Sdim  }
2017218893Sdim
2018235633Sdim  UsingShadowDecl *Prev = FirstUsingShadow.getPointer();
2019218893Sdim  while (Prev->UsingOrNextShadow != S)
2020218893Sdim    Prev = cast<UsingShadowDecl>(Prev->UsingOrNextShadow);
2021218893Sdim  Prev->UsingOrNextShadow = S->UsingOrNextShadow;
2022218893Sdim  S->UsingOrNextShadow = this;
2023218893Sdim}
2024218893Sdim
2025219077SdimUsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL,
2026219077Sdim                             NestedNameSpecifierLoc QualifierLoc,
2027212904Sdim                             const DeclarationNameInfo &NameInfo,
2028263509Sdim                             bool HasTypename) {
2029263509Sdim  return new (C) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename);
2030194613Sed}
2031194613Sed
2032235633SdimUsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
2033235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingDecl));
2034235633Sdim  return new (Mem) UsingDecl(0, SourceLocation(), NestedNameSpecifierLoc(),
2035235633Sdim                             DeclarationNameInfo(), false);
2036235633Sdim}
2037235633Sdim
2038263509SdimSourceRange UsingDecl::getSourceRange() const {
2039263509Sdim  SourceLocation Begin = isAccessDeclaration()
2040263509Sdim    ? getQualifierLoc().getBeginLoc() : UsingLocation;
2041263509Sdim  return SourceRange(Begin, getNameInfo().getEndLoc());
2042263509Sdim}
2043263509Sdim
2044235633Sdimvoid UnresolvedUsingValueDecl::anchor() { }
2045235633Sdim
2046199482SrdivackyUnresolvedUsingValueDecl *
2047199482SrdivackyUnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
2048199482Srdivacky                                 SourceLocation UsingLoc,
2049219077Sdim                                 NestedNameSpecifierLoc QualifierLoc,
2050212904Sdim                                 const DeclarationNameInfo &NameInfo) {
2051199482Srdivacky  return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
2052219077Sdim                                          QualifierLoc, NameInfo);
2053198092Srdivacky}
2054198092Srdivacky
2055235633SdimUnresolvedUsingValueDecl *
2056235633SdimUnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
2057235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UnresolvedUsingValueDecl));
2058235633Sdim  return new (Mem) UnresolvedUsingValueDecl(0, QualType(), SourceLocation(),
2059235633Sdim                                            NestedNameSpecifierLoc(),
2060235633Sdim                                            DeclarationNameInfo());
2061235633Sdim}
2062235633Sdim
2063263509SdimSourceRange UnresolvedUsingValueDecl::getSourceRange() const {
2064263509Sdim  SourceLocation Begin = isAccessDeclaration()
2065263509Sdim    ? getQualifierLoc().getBeginLoc() : UsingLocation;
2066263509Sdim  return SourceRange(Begin, getNameInfo().getEndLoc());
2067263509Sdim}
2068263509Sdim
2069235633Sdimvoid UnresolvedUsingTypenameDecl::anchor() { }
2070235633Sdim
2071199482SrdivackyUnresolvedUsingTypenameDecl *
2072199482SrdivackyUnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
2073199482Srdivacky                                    SourceLocation UsingLoc,
2074199482Srdivacky                                    SourceLocation TypenameLoc,
2075219077Sdim                                    NestedNameSpecifierLoc QualifierLoc,
2076199482Srdivacky                                    SourceLocation TargetNameLoc,
2077199482Srdivacky                                    DeclarationName TargetName) {
2078199482Srdivacky  return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
2079219077Sdim                                             QualifierLoc, TargetNameLoc,
2080199482Srdivacky                                             TargetName.getAsIdentifierInfo());
2081199482Srdivacky}
2082199482Srdivacky
2083235633SdimUnresolvedUsingTypenameDecl *
2084235633SdimUnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
2085235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID,
2086235633Sdim                                       sizeof(UnresolvedUsingTypenameDecl));
2087235633Sdim  return new (Mem) UnresolvedUsingTypenameDecl(0, SourceLocation(),
2088235633Sdim                                               SourceLocation(),
2089235633Sdim                                               NestedNameSpecifierLoc(),
2090235633Sdim                                               SourceLocation(),
2091235633Sdim                                               0);
2092235633Sdim}
2093235633Sdim
2094235633Sdimvoid StaticAssertDecl::anchor() { }
2095235633Sdim
2096193326SedStaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
2097221345Sdim                                           SourceLocation StaticAssertLoc,
2098221345Sdim                                           Expr *AssertExpr,
2099221345Sdim                                           StringLiteral *Message,
2100245431Sdim                                           SourceLocation RParenLoc,
2101245431Sdim                                           bool Failed) {
2102221345Sdim  return new (C) StaticAssertDecl(DC, StaticAssertLoc, AssertExpr, Message,
2103245431Sdim                                  RParenLoc, Failed);
2104193326Sed}
2105193326Sed
2106235633SdimStaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C,
2107235633Sdim                                                       unsigned ID) {
2108235633Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(StaticAssertDecl));
2109245431Sdim  return new (Mem) StaticAssertDecl(0, SourceLocation(), 0, 0,
2110245431Sdim                                    SourceLocation(), false);
2111235633Sdim}
2112235633Sdim
2113193326Sedstatic const char *getAccessName(AccessSpecifier AS) {
2114193326Sed  switch (AS) {
2115193326Sed    case AS_none:
2116226890Sdim      llvm_unreachable("Invalid access specifier!");
2117193326Sed    case AS_public:
2118193326Sed      return "public";
2119193326Sed    case AS_private:
2120193326Sed      return "private";
2121193326Sed    case AS_protected:
2122193326Sed      return "protected";
2123193326Sed  }
2124235633Sdim  llvm_unreachable("Invalid access specifier!");
2125193326Sed}
2126193326Sed
2127193326Sedconst DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
2128193326Sed                                           AccessSpecifier AS) {
2129193326Sed  return DB << getAccessName(AS);
2130193326Sed}
2131235633Sdim
2132235633Sdimconst PartialDiagnostic &clang::operator<<(const PartialDiagnostic &DB,
2133235633Sdim                                           AccessSpecifier AS) {
2134235633Sdim  return DB << getAccessName(AS);
2135235633Sdim}
2136