DeclCXX.cpp revision 212904
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
14193326Sed#include "clang/AST/DeclCXX.h"
15193326Sed#include "clang/AST/DeclTemplate.h"
16193326Sed#include "clang/AST/ASTContext.h"
17193326Sed#include "clang/AST/Expr.h"
18200583Srdivacky#include "clang/AST/TypeLoc.h"
19193326Sed#include "clang/Basic/IdentifierTable.h"
20193326Sed#include "llvm/ADT/STLExtras.h"
21198092Srdivacky#include "llvm/ADT/SmallPtrSet.h"
22193326Sedusing namespace clang;
23193326Sed
24193326Sed//===----------------------------------------------------------------------===//
25193326Sed// Decl Allocation/Deallocation Method Implementations
26193326Sed//===----------------------------------------------------------------------===//
27193326Sed
28203955SrdivackyCXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
29203955Srdivacky  : UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
30193326Sed    UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false),
31198092Srdivacky    Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
32198092Srdivacky    Abstract(false), HasTrivialConstructor(true),
33198092Srdivacky    HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true),
34198092Srdivacky    HasTrivialDestructor(true), ComputedVisibleConversions(false),
35210299Sed    DeclaredDefaultConstructor(false), DeclaredCopyConstructor(false),
36210299Sed    DeclaredCopyAssignment(false), DeclaredDestructor(false),
37198092Srdivacky    Bases(0), NumBases(0), VBases(0), NumVBases(0),
38205219Srdivacky    Definition(D), FirstFriend(0) {
39203955Srdivacky}
40203955Srdivacky
41203955SrdivackyCXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
42203955Srdivacky                             SourceLocation L, IdentifierInfo *Id,
43203955Srdivacky                             CXXRecordDecl *PrevDecl,
44203955Srdivacky                             SourceLocation TKL)
45203955Srdivacky  : RecordDecl(K, TK, DC, L, Id, PrevDecl, TKL),
46203955Srdivacky    DefinitionData(PrevDecl ? PrevDecl->DefinitionData : 0),
47193326Sed    TemplateOrInstantiation() { }
48193326Sed
49193326SedCXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
50193326Sed                                     SourceLocation L, IdentifierInfo *Id,
51198092Srdivacky                                     SourceLocation TKL,
52193326Sed                                     CXXRecordDecl* PrevDecl,
53193326Sed                                     bool DelayTypeCreation) {
54198092Srdivacky  CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id,
55198092Srdivacky                                           PrevDecl, TKL);
56198092Srdivacky
57198092Srdivacky  // FIXME: DelayTypeCreation seems like such a hack
58193326Sed  if (!DelayTypeCreation)
59198092Srdivacky    C.getTypeDeclType(R, PrevDecl);
60193326Sed  return R;
61193326Sed}
62193326Sed
63210299SedCXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, EmptyShell Empty) {
64210299Sed  return new (C) CXXRecordDecl(CXXRecord, TTK_Struct, 0, SourceLocation(), 0, 0,
65210299Sed                               SourceLocation());
66210299Sed}
67210299Sed
68198092Srdivackyvoid
69203955SrdivackyCXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
70193326Sed                        unsigned NumBases) {
71203955Srdivacky  ASTContext &C = getASTContext();
72203955Srdivacky
73198092Srdivacky  // C++ [dcl.init.aggr]p1:
74193326Sed  //   An aggregate is an array or a class (clause 9) with [...]
75193326Sed  //   no base classes [...].
76203955Srdivacky  data().Aggregate = false;
77193326Sed
78203955Srdivacky  if (data().Bases)
79203955Srdivacky    C.Deallocate(data().Bases);
80193326Sed
81206084Srdivacky  // The set of seen virtual base types.
82206084Srdivacky  llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes;
83206084Srdivacky
84206084Srdivacky  // The virtual bases of this class.
85206084Srdivacky  llvm::SmallVector<const CXXBaseSpecifier *, 8> VBases;
86198092Srdivacky
87203955Srdivacky  data().Bases = new(C) CXXBaseSpecifier [NumBases];
88203955Srdivacky  data().NumBases = NumBases;
89198092Srdivacky  for (unsigned i = 0; i < NumBases; ++i) {
90203955Srdivacky    data().Bases[i] = *Bases[i];
91198092Srdivacky    // Keep track of inherited vbases for this base class.
92198092Srdivacky    const CXXBaseSpecifier *Base = Bases[i];
93198092Srdivacky    QualType BaseType = Base->getType();
94204643Srdivacky    // Skip dependent types; we can't do any checking on them now.
95198092Srdivacky    if (BaseType->isDependentType())
96198092Srdivacky      continue;
97198092Srdivacky    CXXRecordDecl *BaseClassDecl
98198092Srdivacky      = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
99206084Srdivacky
100206084Srdivacky    // Now go through all virtual bases of this base and add them.
101198092Srdivacky    for (CXXRecordDecl::base_class_iterator VBase =
102198092Srdivacky          BaseClassDecl->vbases_begin(),
103198092Srdivacky         E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
104206084Srdivacky      // Add this base if it's not already in the list.
105206084Srdivacky      if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType())))
106206084Srdivacky        VBases.push_back(VBase);
107198092Srdivacky    }
108206084Srdivacky
109206084Srdivacky    if (Base->isVirtual()) {
110206084Srdivacky      // Add this base if it's not already in the list.
111206084Srdivacky      if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)))
112206084Srdivacky          VBases.push_back(Base);
113198092Srdivacky    }
114206084Srdivacky
115198092Srdivacky  }
116206084Srdivacky
117206084Srdivacky  if (VBases.empty())
118206084Srdivacky    return;
119206084Srdivacky
120206084Srdivacky  // Create base specifier for any direct or indirect virtual bases.
121206084Srdivacky  data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
122206084Srdivacky  data().NumVBases = VBases.size();
123206084Srdivacky  for (int I = 0, E = VBases.size(); I != E; ++I) {
124212904Sdim    TypeSourceInfo *VBaseTypeInfo = VBases[I]->getTypeSourceInfo();
125212904Sdim
126206084Srdivacky    // Skip dependent types; we can't do any checking on them now.
127212904Sdim    if (VBaseTypeInfo->getType()->isDependentType())
128206084Srdivacky      continue;
129206084Srdivacky
130212904Sdim    CXXRecordDecl *VBaseClassDecl = cast<CXXRecordDecl>(
131212904Sdim      VBaseTypeInfo->getType()->getAs<RecordType>()->getDecl());
132206084Srdivacky
133206084Srdivacky    data().VBases[I] =
134206084Srdivacky      CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
135208600Srdivacky                       VBaseClassDecl->getTagKind() == TTK_Class,
136212904Sdim                       VBases[I]->getAccessSpecifier(), VBaseTypeInfo);
137198092Srdivacky  }
138193326Sed}
139193326Sed
140202379Srdivacky/// Callback function for CXXRecordDecl::forallBases that acknowledges
141202379Srdivacky/// that it saw a base class.
142202379Srdivackystatic bool SawBase(const CXXRecordDecl *, void *) {
143202379Srdivacky  return true;
144202379Srdivacky}
145202379Srdivacky
146202379Srdivackybool CXXRecordDecl::hasAnyDependentBases() const {
147202379Srdivacky  if (!isDependentContext())
148202379Srdivacky    return false;
149202379Srdivacky
150202379Srdivacky  return !forallBases(SawBase, 0);
151202379Srdivacky}
152202379Srdivacky
153193326Sedbool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const {
154198092Srdivacky  return getCopyConstructor(Context, Qualifiers::Const) != 0;
155194711Sed}
156194711Sed
157210299Sed/// \brief Perform a simplistic form of overload resolution that only considers
158210299Sed/// cv-qualifiers on a single parameter, and return the best overload candidate
159210299Sed/// (if there is one).
160210299Sedstatic CXXMethodDecl *
161210299SedGetBestOverloadCandidateSimple(
162210299Sed  const llvm::SmallVectorImpl<std::pair<CXXMethodDecl *, Qualifiers> > &Cands) {
163210299Sed  if (Cands.empty())
164210299Sed    return 0;
165210299Sed  if (Cands.size() == 1)
166210299Sed    return Cands[0].first;
167210299Sed
168210299Sed  unsigned Best = 0, N = Cands.size();
169210299Sed  for (unsigned I = 1; I != N; ++I)
170210299Sed    if (Cands[Best].second.isSupersetOf(Cands[I].second))
171210299Sed      Best = I;
172210299Sed
173210299Sed  for (unsigned I = 1; I != N; ++I)
174210299Sed    if (Cands[Best].second.isSupersetOf(Cands[I].second))
175210299Sed      return 0;
176210299Sed
177210299Sed  return Cands[Best].first;
178210299Sed}
179210299Sed
180198092SrdivackyCXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context,
181194711Sed                                                      unsigned TypeQuals) const{
182193326Sed  QualType ClassType
183193326Sed    = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this));
184198092Srdivacky  DeclarationName ConstructorName
185193326Sed    = Context.DeclarationNames.getCXXConstructorName(
186194711Sed                                          Context.getCanonicalType(ClassType));
187194711Sed  unsigned FoundTQs;
188210299Sed  llvm::SmallVector<std::pair<CXXMethodDecl *, Qualifiers>, 4> Found;
189193326Sed  DeclContext::lookup_const_iterator Con, ConEnd;
190195341Sed  for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
191193326Sed       Con != ConEnd; ++Con) {
192198092Srdivacky    // C++ [class.copy]p2:
193198092Srdivacky    //   A non-template constructor for class X is a copy constructor if [...]
194198092Srdivacky    if (isa<FunctionTemplateDecl>(*Con))
195198092Srdivacky      continue;
196198092Srdivacky
197210299Sed    CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
198210299Sed    if (Constructor->isCopyConstructor(FoundTQs)) {
199198092Srdivacky      if (((TypeQuals & Qualifiers::Const) == (FoundTQs & Qualifiers::Const)) ||
200198092Srdivacky          (!(TypeQuals & Qualifiers::Const) && (FoundTQs & Qualifiers::Const)))
201210299Sed        Found.push_back(std::make_pair(
202210299Sed                                 const_cast<CXXConstructorDecl *>(Constructor),
203210299Sed                                       Qualifiers::fromCVRMask(FoundTQs)));
204194711Sed    }
205193326Sed  }
206210299Sed
207210299Sed  return cast_or_null<CXXConstructorDecl>(
208210299Sed                                        GetBestOverloadCandidateSimple(Found));
209193326Sed}
210193326Sed
211210299SedCXXMethodDecl *CXXRecordDecl::getCopyAssignmentOperator(bool ArgIsConst) const {
212210299Sed  ASTContext &Context = getASTContext();
213210299Sed  QualType Class = Context.getTypeDeclType(const_cast<CXXRecordDecl *>(this));
214210299Sed  DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
215210299Sed
216210299Sed  llvm::SmallVector<std::pair<CXXMethodDecl *, Qualifiers>, 4> Found;
217193326Sed  DeclContext::lookup_const_iterator Op, OpEnd;
218210299Sed  for (llvm::tie(Op, OpEnd) = this->lookup(Name); Op != OpEnd; ++Op) {
219193326Sed    // C++ [class.copy]p9:
220193326Sed    //   A user-declared copy assignment operator is a non-static non-template
221193326Sed    //   member function of class X with exactly one parameter of type X, X&,
222193326Sed    //   const X&, volatile X& or const volatile X&.
223198893Srdivacky    const CXXMethodDecl* Method = dyn_cast<CXXMethodDecl>(*Op);
224210299Sed    if (!Method || Method->isStatic() || Method->getPrimaryTemplate())
225198893Srdivacky      continue;
226210299Sed
227210299Sed    const FunctionProtoType *FnType
228210299Sed      = Method->getType()->getAs<FunctionProtoType>();
229193326Sed    assert(FnType && "Overloaded operator has no prototype.");
230193326Sed    // Don't assert on this; an invalid decl might have been left in the AST.
231193326Sed    if (FnType->getNumArgs() != 1 || FnType->isVariadic())
232193326Sed      continue;
233210299Sed
234193326Sed    QualType ArgType = FnType->getArgType(0);
235210299Sed    Qualifiers Quals;
236198092Srdivacky    if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>()) {
237193326Sed      ArgType = Ref->getPointeeType();
238210299Sed      // If we have a const argument and we have a reference to a non-const,
239210299Sed      // this function does not match.
240210299Sed      if (ArgIsConst && !ArgType.isConstQualified())
241210299Sed        continue;
242210299Sed
243210299Sed      Quals = ArgType.getQualifiers();
244210299Sed    } else {
245210299Sed      // By-value copy-assignment operators are treated like const X&
246210299Sed      // copy-assignment operators.
247210299Sed      Quals = Qualifiers::fromCVRMask(Qualifiers::Const);
248193326Sed    }
249210299Sed
250210299Sed    if (!Context.hasSameUnqualifiedType(ArgType, Class))
251193326Sed      continue;
252210299Sed
253210299Sed    // Save this copy-assignment operator. It might be "the one".
254210299Sed    Found.push_back(std::make_pair(const_cast<CXXMethodDecl *>(Method), Quals));
255193326Sed  }
256210299Sed
257210299Sed  // Use a simplistic form of overload resolution to find the candidate.
258210299Sed  return GetBestOverloadCandidateSimple(Found);
259193326Sed}
260193326Sed
261193326Sedvoid
262198092SrdivackyCXXRecordDecl::addedConstructor(ASTContext &Context,
263193326Sed                                CXXConstructorDecl *ConDecl) {
264194613Sed  assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl");
265194613Sed  // Note that we have a user-declared constructor.
266203955Srdivacky  data().UserDeclaredConstructor = true;
267193326Sed
268210299Sed  // Note that we have no need of an implicitly-declared default constructor.
269210299Sed  data().DeclaredDefaultConstructor = true;
270210299Sed
271198092Srdivacky  // C++ [dcl.init.aggr]p1:
272194613Sed  //   An aggregate is an array or a class (clause 9) with no
273194613Sed  //   user-declared constructors (12.1) [...].
274203955Srdivacky  data().Aggregate = false;
275193326Sed
276194613Sed  // C++ [class]p4:
277194613Sed  //   A POD-struct is an aggregate class [...]
278203955Srdivacky  data().PlainOldData = false;
279193326Sed
280194613Sed  // C++ [class.ctor]p5:
281194613Sed  //   A constructor is trivial if it is an implicitly-declared default
282194613Sed  //   constructor.
283198092Srdivacky  // FIXME: C++0x: don't do this for "= default" default constructors.
284203955Srdivacky  data().HasTrivialConstructor = false;
285198092Srdivacky
286194613Sed  // Note when we have a user-declared copy constructor, which will
287194613Sed  // suppress the implicit declaration of a copy constructor.
288201361Srdivacky  if (ConDecl->isCopyConstructor()) {
289203955Srdivacky    data().UserDeclaredCopyConstructor = true;
290210299Sed    data().DeclaredCopyConstructor = true;
291210299Sed
292198092Srdivacky    // C++ [class.copy]p6:
293198092Srdivacky    //   A copy constructor is trivial if it is implicitly declared.
294198092Srdivacky    // FIXME: C++0x: don't do this for "= default" copy constructors.
295203955Srdivacky    data().HasTrivialCopyConstructor = false;
296210299Sed
297198092Srdivacky  }
298193326Sed}
299193326Sed
300193326Sedvoid CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
301193326Sed                                            CXXMethodDecl *OpDecl) {
302193326Sed  // We're interested specifically in copy assignment operators.
303198092Srdivacky  const FunctionProtoType *FnType = OpDecl->getType()->getAs<FunctionProtoType>();
304193326Sed  assert(FnType && "Overloaded operator has no proto function type.");
305193326Sed  assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
306198092Srdivacky
307198092Srdivacky  // Copy assignment operators must be non-templates.
308198092Srdivacky  if (OpDecl->getPrimaryTemplate() || OpDecl->getDescribedFunctionTemplate())
309198092Srdivacky    return;
310198092Srdivacky
311193326Sed  QualType ArgType = FnType->getArgType(0);
312198092Srdivacky  if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>())
313193326Sed    ArgType = Ref->getPointeeType();
314193326Sed
315193326Sed  ArgType = ArgType.getUnqualifiedType();
316193326Sed  QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
317193326Sed    const_cast<CXXRecordDecl*>(this)));
318193326Sed
319199482Srdivacky  if (!Context.hasSameUnqualifiedType(ClassType, ArgType))
320193326Sed    return;
321193326Sed
322193326Sed  // This is a copy assignment operator.
323199482Srdivacky  // Note on the decl that it is a copy assignment operator.
324199482Srdivacky  OpDecl->setCopyAssignment(true);
325199482Srdivacky
326193326Sed  // Suppress the implicit declaration of a copy constructor.
327203955Srdivacky  data().UserDeclaredCopyAssignment = true;
328210299Sed  data().DeclaredCopyAssignment = true;
329210299Sed
330198092Srdivacky  // C++ [class.copy]p11:
331198092Srdivacky  //   A copy assignment operator is trivial if it is implicitly declared.
332198092Srdivacky  // FIXME: C++0x: don't do this for "= default" copy operators.
333203955Srdivacky  data().HasTrivialCopyAssignment = false;
334198092Srdivacky
335193326Sed  // C++ [class]p4:
336193326Sed  //   A POD-struct is an aggregate class that [...] has no user-defined copy
337193326Sed  //   assignment operator [...].
338203955Srdivacky  data().PlainOldData = false;
339193326Sed}
340193326Sed
341205219Srdivackystatic CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
342205219Srdivacky  QualType T;
343206084Srdivacky  if (isa<UsingShadowDecl>(Conv))
344206084Srdivacky    Conv = cast<UsingShadowDecl>(Conv)->getTargetDecl();
345205219Srdivacky  if (FunctionTemplateDecl *ConvTemp = dyn_cast<FunctionTemplateDecl>(Conv))
346205219Srdivacky    T = ConvTemp->getTemplatedDecl()->getResultType();
347205219Srdivacky  else
348205219Srdivacky    T = cast<CXXConversionDecl>(Conv)->getConversionType();
349205219Srdivacky  return Context.getCanonicalType(T);
350198092Srdivacky}
351198092Srdivacky
352205219Srdivacky/// Collect the visible conversions of a base class.
353205219Srdivacky///
354205219Srdivacky/// \param Base a base class of the class we're considering
355205219Srdivacky/// \param InVirtual whether this base class is a virtual base (or a base
356205219Srdivacky///   of a virtual base)
357205219Srdivacky/// \param Access the access along the inheritance path to this base
358205219Srdivacky/// \param ParentHiddenTypes the conversions provided by the inheritors
359205219Srdivacky///   of this base
360205219Srdivacky/// \param Output the set to which to add conversions from non-virtual bases
361205219Srdivacky/// \param VOutput the set to which to add conversions from virtual bases
362205219Srdivacky/// \param HiddenVBaseCs the set of conversions which were hidden in a
363205219Srdivacky///   virtual base along some inheritance path
364205219Srdivackystatic void CollectVisibleConversions(ASTContext &Context,
365205219Srdivacky                                      CXXRecordDecl *Record,
366205219Srdivacky                                      bool InVirtual,
367205219Srdivacky                                      AccessSpecifier Access,
368205219Srdivacky                  const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes,
369205219Srdivacky                                      UnresolvedSetImpl &Output,
370205219Srdivacky                                      UnresolvedSetImpl &VOutput,
371205219Srdivacky                           llvm::SmallPtrSet<NamedDecl*, 8> &HiddenVBaseCs) {
372205219Srdivacky  // The set of types which have conversions in this class or its
373205219Srdivacky  // subclasses.  As an optimization, we don't copy the derived set
374205219Srdivacky  // unless it might change.
375205219Srdivacky  const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes;
376205219Srdivacky  llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer;
377205219Srdivacky
378205219Srdivacky  // Collect the direct conversions and figure out which conversions
379205219Srdivacky  // will be hidden in the subclasses.
380205219Srdivacky  UnresolvedSetImpl &Cs = *Record->getConversionFunctions();
381205219Srdivacky  if (!Cs.empty()) {
382205219Srdivacky    HiddenTypesBuffer = ParentHiddenTypes;
383205219Srdivacky    HiddenTypes = &HiddenTypesBuffer;
384205219Srdivacky
385205219Srdivacky    for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I) {
386205219Srdivacky      bool Hidden =
387205219Srdivacky        !HiddenTypesBuffer.insert(GetConversionType(Context, I.getDecl()));
388205219Srdivacky
389205219Srdivacky      // If this conversion is hidden and we're in a virtual base,
390205219Srdivacky      // remember that it's hidden along some inheritance path.
391205219Srdivacky      if (Hidden && InVirtual)
392205219Srdivacky        HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()));
393205219Srdivacky
394205219Srdivacky      // If this conversion isn't hidden, add it to the appropriate output.
395205219Srdivacky      else if (!Hidden) {
396205219Srdivacky        AccessSpecifier IAccess
397205219Srdivacky          = CXXRecordDecl::MergeAccess(Access, I.getAccess());
398205219Srdivacky
399205219Srdivacky        if (InVirtual)
400205219Srdivacky          VOutput.addDecl(I.getDecl(), IAccess);
401198092Srdivacky        else
402205219Srdivacky          Output.addDecl(I.getDecl(), IAccess);
403198092Srdivacky      }
404198092Srdivacky    }
405198092Srdivacky  }
406198893Srdivacky
407205219Srdivacky  // Collect information recursively from any base classes.
408205219Srdivacky  for (CXXRecordDecl::base_class_iterator
409205219Srdivacky         I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
410205219Srdivacky    const RecordType *RT = I->getType()->getAs<RecordType>();
411205219Srdivacky    if (!RT) continue;
412198893Srdivacky
413205219Srdivacky    AccessSpecifier BaseAccess
414205219Srdivacky      = CXXRecordDecl::MergeAccess(Access, I->getAccessSpecifier());
415205219Srdivacky    bool BaseInVirtual = InVirtual || I->isVirtual();
416198893Srdivacky
417205219Srdivacky    CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
418205219Srdivacky    CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess,
419205219Srdivacky                              *HiddenTypes, Output, VOutput, HiddenVBaseCs);
420198092Srdivacky  }
421205219Srdivacky}
422198893Srdivacky
423205219Srdivacky/// Collect the visible conversions of a class.
424205219Srdivacky///
425205219Srdivacky/// This would be extremely straightforward if it weren't for virtual
426205219Srdivacky/// bases.  It might be worth special-casing that, really.
427205219Srdivackystatic void CollectVisibleConversions(ASTContext &Context,
428205219Srdivacky                                      CXXRecordDecl *Record,
429205219Srdivacky                                      UnresolvedSetImpl &Output) {
430205219Srdivacky  // The collection of all conversions in virtual bases that we've
431205219Srdivacky  // found.  These will be added to the output as long as they don't
432205219Srdivacky  // appear in the hidden-conversions set.
433205219Srdivacky  UnresolvedSet<8> VBaseCs;
434205219Srdivacky
435205219Srdivacky  // The set of conversions in virtual bases that we've determined to
436205219Srdivacky  // be hidden.
437205219Srdivacky  llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs;
438205219Srdivacky
439205219Srdivacky  // The set of types hidden by classes derived from this one.
440205219Srdivacky  llvm::SmallPtrSet<CanQualType, 8> HiddenTypes;
441205219Srdivacky
442205219Srdivacky  // Go ahead and collect the direct conversions and add them to the
443205219Srdivacky  // hidden-types set.
444205219Srdivacky  UnresolvedSetImpl &Cs = *Record->getConversionFunctions();
445205219Srdivacky  Output.append(Cs.begin(), Cs.end());
446205219Srdivacky  for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I)
447205219Srdivacky    HiddenTypes.insert(GetConversionType(Context, I.getDecl()));
448205219Srdivacky
449205219Srdivacky  // Recursively collect conversions from base classes.
450205219Srdivacky  for (CXXRecordDecl::base_class_iterator
451205219Srdivacky         I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
452205219Srdivacky    const RecordType *RT = I->getType()->getAs<RecordType>();
453205219Srdivacky    if (!RT) continue;
454205219Srdivacky
455205219Srdivacky    CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()),
456205219Srdivacky                              I->isVirtual(), I->getAccessSpecifier(),
457205219Srdivacky                              HiddenTypes, Output, VBaseCs, HiddenVBaseCs);
458198092Srdivacky  }
459205219Srdivacky
460205219Srdivacky  // Add any unhidden conversions provided by virtual bases.
461205219Srdivacky  for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end();
462205219Srdivacky         I != E; ++I) {
463205219Srdivacky    if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())))
464205219Srdivacky      Output.addDecl(I.getDecl(), I.getAccess());
465205219Srdivacky  }
466198092Srdivacky}
467198092Srdivacky
468198092Srdivacky/// getVisibleConversionFunctions - get all conversion functions visible
469198092Srdivacky/// in current class; including conversion function templates.
470202879Srdivackyconst UnresolvedSetImpl *CXXRecordDecl::getVisibleConversionFunctions() {
471198092Srdivacky  // If root class, all conversions are visible.
472198092Srdivacky  if (bases_begin() == bases_end())
473203955Srdivacky    return &data().Conversions;
474198092Srdivacky  // If visible conversion list is already evaluated, return it.
475203955Srdivacky  if (data().ComputedVisibleConversions)
476203955Srdivacky    return &data().VisibleConversions;
477205219Srdivacky  CollectVisibleConversions(getASTContext(), this, data().VisibleConversions);
478203955Srdivacky  data().ComputedVisibleConversions = true;
479203955Srdivacky  return &data().VisibleConversions;
480198092Srdivacky}
481198092Srdivacky
482206084Srdivacky#ifndef NDEBUG
483206084Srdivackyvoid CXXRecordDecl::CheckConversionFunction(NamedDecl *ConvDecl) {
484205219Srdivacky  assert(ConvDecl->getDeclContext() == this &&
485205219Srdivacky         "conversion function does not belong to this record");
486198092Srdivacky
487206084Srdivacky  ConvDecl = ConvDecl->getUnderlyingDecl();
488206084Srdivacky  if (FunctionTemplateDecl *Temp = dyn_cast<FunctionTemplateDecl>(ConvDecl)) {
489206084Srdivacky    assert(isa<CXXConversionDecl>(Temp->getTemplatedDecl()));
490206084Srdivacky  } else {
491206084Srdivacky    assert(isa<CXXConversionDecl>(ConvDecl));
492206084Srdivacky  }
493193326Sed}
494206084Srdivacky#endif
495193326Sed
496206084Srdivackyvoid CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
497206084Srdivacky  // This operation is O(N) but extremely rare.  Sema only uses it to
498206084Srdivacky  // remove UsingShadowDecls in a class that were followed by a direct
499206084Srdivacky  // declaration, e.g.:
500206084Srdivacky  //   class A : B {
501206084Srdivacky  //     using B::operator int;
502206084Srdivacky  //     operator int();
503206084Srdivacky  //   };
504206084Srdivacky  // This is uncommon by itself and even more uncommon in conjunction
505206084Srdivacky  // with sufficiently large numbers of directly-declared conversions
506206084Srdivacky  // that asymptotic behavior matters.
507206084Srdivacky
508206084Srdivacky  UnresolvedSetImpl &Convs = *getConversionFunctions();
509206084Srdivacky  for (unsigned I = 0, E = Convs.size(); I != E; ++I) {
510206084Srdivacky    if (Convs[I].getDecl() == ConvDecl) {
511206084Srdivacky      Convs.erase(I);
512206084Srdivacky      assert(std::find(Convs.begin(), Convs.end(), ConvDecl) == Convs.end()
513206084Srdivacky             && "conversion was found multiple times in unresolved set");
514206084Srdivacky      return;
515206084Srdivacky    }
516206084Srdivacky  }
517206084Srdivacky
518206084Srdivacky  llvm_unreachable("conversion not found in set!");
519198092Srdivacky}
520194613Sed
521200583Srdivackyvoid CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) {
522200583Srdivacky  Method->setVirtualAsWritten(true);
523200583Srdivacky  setAggregate(false);
524200583Srdivacky  setPOD(false);
525200583Srdivacky  setEmpty(false);
526200583Srdivacky  setPolymorphic(true);
527200583Srdivacky  setHasTrivialConstructor(false);
528200583Srdivacky  setHasTrivialCopyConstructor(false);
529200583Srdivacky  setHasTrivialCopyAssignment(false);
530200583Srdivacky}
531200583Srdivacky
532198092SrdivackyCXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
533198092Srdivacky  if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
534198092Srdivacky    return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
535198092Srdivacky
536198092Srdivacky  return 0;
537198092Srdivacky}
538198092Srdivacky
539198092SrdivackyMemberSpecializationInfo *CXXRecordDecl::getMemberSpecializationInfo() const {
540198092Srdivacky  return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>();
541198092Srdivacky}
542198092Srdivacky
543198092Srdivackyvoid
544198092SrdivackyCXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
545198092Srdivacky                                             TemplateSpecializationKind TSK) {
546198092Srdivacky  assert(TemplateOrInstantiation.isNull() &&
547198092Srdivacky         "Previous template or instantiation?");
548198092Srdivacky  assert(!isa<ClassTemplateSpecializationDecl>(this));
549198092Srdivacky  TemplateOrInstantiation
550198092Srdivacky    = new (getASTContext()) MemberSpecializationInfo(RD, TSK);
551198092Srdivacky}
552198092Srdivacky
553200583SrdivackyTemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{
554200583Srdivacky  if (const ClassTemplateSpecializationDecl *Spec
555198092Srdivacky        = dyn_cast<ClassTemplateSpecializationDecl>(this))
556198092Srdivacky    return Spec->getSpecializationKind();
557198092Srdivacky
558198092Srdivacky  if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
559198092Srdivacky    return MSInfo->getTemplateSpecializationKind();
560198092Srdivacky
561198092Srdivacky  return TSK_Undeclared;
562198092Srdivacky}
563198092Srdivacky
564198092Srdivackyvoid
565198092SrdivackyCXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
566198092Srdivacky  if (ClassTemplateSpecializationDecl *Spec
567198092Srdivacky      = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
568198092Srdivacky    Spec->setSpecializationKind(TSK);
569198092Srdivacky    return;
570198092Srdivacky  }
571198092Srdivacky
572198092Srdivacky  if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
573198092Srdivacky    MSInfo->setTemplateSpecializationKind(TSK);
574198092Srdivacky    return;
575198092Srdivacky  }
576198092Srdivacky
577198092Srdivacky  assert(false && "Not a class template or member class specialization");
578198092Srdivacky}
579198092Srdivacky
580194613SedCXXConstructorDecl *
581210299SedCXXRecordDecl::getDefaultConstructor() {
582210299Sed  ASTContext &Context = getASTContext();
583194613Sed  QualType ClassType = Context.getTypeDeclType(this);
584194613Sed  DeclarationName ConstructorName
585194613Sed    = Context.DeclarationNames.getCXXConstructorName(
586194613Sed                      Context.getCanonicalType(ClassType.getUnqualifiedType()));
587198092Srdivacky
588194613Sed  DeclContext::lookup_const_iterator Con, ConEnd;
589195341Sed  for (llvm::tie(Con, ConEnd) = lookup(ConstructorName);
590194613Sed       Con != ConEnd; ++Con) {
591198092Srdivacky    // FIXME: In C++0x, a constructor template can be a default constructor.
592198092Srdivacky    if (isa<FunctionTemplateDecl>(*Con))
593198092Srdivacky      continue;
594198092Srdivacky
595194613Sed    CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
596194613Sed    if (Constructor->isDefaultConstructor())
597194613Sed      return Constructor;
598194613Sed  }
599194613Sed  return 0;
600194613Sed}
601194613Sed
602210299SedCXXDestructorDecl *CXXRecordDecl::getDestructor() const {
603210299Sed  ASTContext &Context = getASTContext();
604193326Sed  QualType ClassType = Context.getTypeDeclType(this);
605193326Sed
606198092Srdivacky  DeclarationName Name
607198092Srdivacky    = Context.DeclarationNames.getCXXDestructorName(
608198092Srdivacky                                          Context.getCanonicalType(ClassType));
609198092Srdivacky
610204643Srdivacky  DeclContext::lookup_const_iterator I, E;
611198092Srdivacky  llvm::tie(I, E) = lookup(Name);
612212904Sdim  if (I == E)
613212904Sdim    return 0;
614198092Srdivacky
615200583Srdivacky  CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I);
616193326Sed  assert(++I == E && "Found more than one destructor!");
617198092Srdivacky
618193326Sed  return Dtor;
619193326Sed}
620193326Sed
621193326SedCXXMethodDecl *
622193326SedCXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
623212904Sdim                      const DeclarationNameInfo &NameInfo,
624200583Srdivacky                      QualType T, TypeSourceInfo *TInfo,
625207619Srdivacky                      bool isStatic, StorageClass SCAsWritten, bool isInline) {
626212904Sdim  return new (C) CXXMethodDecl(CXXMethod, RD, NameInfo, T, TInfo,
627207619Srdivacky                               isStatic, SCAsWritten, isInline);
628193326Sed}
629193326Sed
630198092Srdivackybool CXXMethodDecl::isUsualDeallocationFunction() const {
631198092Srdivacky  if (getOverloadedOperator() != OO_Delete &&
632198092Srdivacky      getOverloadedOperator() != OO_Array_Delete)
633198092Srdivacky    return false;
634204643Srdivacky
635198092Srdivacky  // C++ [basic.stc.dynamic.deallocation]p2:
636204643Srdivacky  //   A template instance is never a usual deallocation function,
637204643Srdivacky  //   regardless of its signature.
638204643Srdivacky  if (getPrimaryTemplate())
639204643Srdivacky    return false;
640204643Srdivacky
641204643Srdivacky  // C++ [basic.stc.dynamic.deallocation]p2:
642198092Srdivacky  //   If a class T has a member deallocation function named operator delete
643198092Srdivacky  //   with exactly one parameter, then that function is a usual (non-placement)
644198092Srdivacky  //   deallocation function. [...]
645198092Srdivacky  if (getNumParams() == 1)
646198092Srdivacky    return true;
647198092Srdivacky
648198092Srdivacky  // C++ [basic.stc.dynamic.deallocation]p2:
649198092Srdivacky  //   [...] If class T does not declare such an operator delete but does
650198092Srdivacky  //   declare a member deallocation function named operator delete with
651198092Srdivacky  //   exactly two parameters, the second of which has type std::size_t (18.1),
652198092Srdivacky  //   then this function is a usual deallocation function.
653198092Srdivacky  ASTContext &Context = getASTContext();
654198092Srdivacky  if (getNumParams() != 2 ||
655203955Srdivacky      !Context.hasSameUnqualifiedType(getParamDecl(1)->getType(),
656203955Srdivacky                                      Context.getSizeType()))
657198092Srdivacky    return false;
658198092Srdivacky
659198092Srdivacky  // This function is a usual deallocation function if there are no
660198092Srdivacky  // single-parameter deallocation functions of the same kind.
661198092Srdivacky  for (DeclContext::lookup_const_result R = getDeclContext()->lookup(getDeclName());
662198092Srdivacky       R.first != R.second; ++R.first) {
663198092Srdivacky    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*R.first))
664198092Srdivacky      if (FD->getNumParams() == 1)
665198092Srdivacky        return false;
666198092Srdivacky  }
667198092Srdivacky
668198092Srdivacky  return true;
669198092Srdivacky}
670193326Sed
671207619Srdivackybool CXXMethodDecl::isCopyAssignmentOperator() const {
672207619Srdivacky  // C++0x [class.copy]p19:
673207619Srdivacky  //  A user-declared copy assignment operator X::operator= is a non-static
674207619Srdivacky  //  non-template member function of class X with exactly one parameter of
675207619Srdivacky  //  type X, X&, const X&, volatile X& or const volatile X&.
676207619Srdivacky  if (/*operator=*/getOverloadedOperator() != OO_Equal ||
677207619Srdivacky      /*non-static*/ isStatic() ||
678207619Srdivacky      /*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate() ||
679207619Srdivacky      /*exactly one parameter*/getNumParams() != 1)
680207619Srdivacky    return false;
681207619Srdivacky
682207619Srdivacky  QualType ParamType = getParamDecl(0)->getType();
683207619Srdivacky  if (const LValueReferenceType *Ref = ParamType->getAs<LValueReferenceType>())
684207619Srdivacky    ParamType = Ref->getPointeeType();
685207619Srdivacky
686207619Srdivacky  ASTContext &Context = getASTContext();
687207619Srdivacky  QualType ClassType
688207619Srdivacky    = Context.getCanonicalType(Context.getTypeDeclType(getParent()));
689207619Srdivacky  return Context.hasSameUnqualifiedType(ClassType, ParamType);
690207619Srdivacky}
691207619Srdivacky
692193326Sedvoid CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
693200583Srdivacky  assert(MD->isCanonicalDecl() && "Method is not canonical!");
694203955Srdivacky  assert(!MD->getParent()->isDependentContext() &&
695203955Srdivacky         "Can't add an overridden method to a class template!");
696203955Srdivacky
697204643Srdivacky  getASTContext().addOverriddenMethod(this, MD);
698193326Sed}
699193326Sed
700193326SedCXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
701204643Srdivacky  return getASTContext().overridden_methods_begin(this);
702193326Sed}
703193326Sed
704193326SedCXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
705204643Srdivacky  return getASTContext().overridden_methods_end(this);
706193326Sed}
707193326Sed
708210299Sedunsigned CXXMethodDecl::size_overridden_methods() const {
709210299Sed  return getASTContext().overridden_methods_size(this);
710210299Sed}
711210299Sed
712193326SedQualType CXXMethodDecl::getThisType(ASTContext &C) const {
713193326Sed  // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
714193326Sed  // If the member function is declared const, the type of this is const X*,
715193326Sed  // if the member function is declared volatile, the type of this is
716193326Sed  // volatile X*, and if the member function is declared const volatile,
717193326Sed  // the type of this is const volatile X*.
718193326Sed
719193326Sed  assert(isInstance() && "No 'this' for static methods!");
720194179Sed
721204962Srdivacky  QualType ClassTy = C.getTypeDeclType(getParent());
722198092Srdivacky  ClassTy = C.getQualifiedType(ClassTy,
723198092Srdivacky                               Qualifiers::fromCVRMask(getTypeQualifiers()));
724198092Srdivacky  return C.getPointerType(ClassTy);
725193326Sed}
726193326Sed
727200583Srdivackybool CXXMethodDecl::hasInlineBody() const {
728202379Srdivacky  // If this function is a template instantiation, look at the template from
729202379Srdivacky  // which it was instantiated.
730202379Srdivacky  const FunctionDecl *CheckFn = getTemplateInstantiationPattern();
731202379Srdivacky  if (!CheckFn)
732202379Srdivacky    CheckFn = this;
733202379Srdivacky
734200583Srdivacky  const FunctionDecl *fn;
735210299Sed  return CheckFn->hasBody(fn) && !fn->isOutOfLine();
736200583Srdivacky}
737200583Srdivacky
738193326SedCXXBaseOrMemberInitializer::
739200583SrdivackyCXXBaseOrMemberInitializer(ASTContext &Context,
740207619Srdivacky                           TypeSourceInfo *TInfo, bool IsVirtual,
741203955Srdivacky                           SourceLocation L, Expr *Init, SourceLocation R)
742208600Srdivacky  : BaseOrMember(TInfo), Init(Init), AnonUnionMember(0),
743208600Srdivacky    LParenLoc(L), RParenLoc(R), IsVirtual(IsVirtual), IsWritten(false),
744208600Srdivacky    SourceOrderOrNumArrayIndices(0)
745200583Srdivacky{
746193326Sed}
747193326Sed
748193326SedCXXBaseOrMemberInitializer::
749200583SrdivackyCXXBaseOrMemberInitializer(ASTContext &Context,
750200583Srdivacky                           FieldDecl *Member, SourceLocation MemberLoc,
751203955Srdivacky                           SourceLocation L, Expr *Init, SourceLocation R)
752208600Srdivacky  : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init),
753208600Srdivacky    AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false),
754208600Srdivacky    IsWritten(false), SourceOrderOrNumArrayIndices(0)
755208600Srdivacky{
756208600Srdivacky}
757208600Srdivacky
758208600SrdivackyCXXBaseOrMemberInitializer::
759208600SrdivackyCXXBaseOrMemberInitializer(ASTContext &Context,
760208600Srdivacky                           FieldDecl *Member, SourceLocation MemberLoc,
761208600Srdivacky                           SourceLocation L, Expr *Init, SourceLocation R,
762208600Srdivacky                           VarDecl **Indices,
763208600Srdivacky                           unsigned NumIndices)
764203955Srdivacky  : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init),
765208600Srdivacky    AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false),
766208600Srdivacky    IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
767200583Srdivacky{
768208600Srdivacky  VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
769208600Srdivacky  memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));
770193326Sed}
771193326Sed
772208600SrdivackyCXXBaseOrMemberInitializer *
773208600SrdivackyCXXBaseOrMemberInitializer::Create(ASTContext &Context,
774208600Srdivacky                                   FieldDecl *Member,
775208600Srdivacky                                   SourceLocation MemberLoc,
776208600Srdivacky                                   SourceLocation L,
777208600Srdivacky                                   Expr *Init,
778208600Srdivacky                                   SourceLocation R,
779208600Srdivacky                                   VarDecl **Indices,
780208600Srdivacky                                   unsigned NumIndices) {
781208600Srdivacky  void *Mem = Context.Allocate(sizeof(CXXBaseOrMemberInitializer) +
782208600Srdivacky                               sizeof(VarDecl *) * NumIndices,
783208600Srdivacky                               llvm::alignof<CXXBaseOrMemberInitializer>());
784208600Srdivacky  return new (Mem) CXXBaseOrMemberInitializer(Context, Member, MemberLoc,
785208600Srdivacky                                              L, Init, R, Indices, NumIndices);
786208600Srdivacky}
787208600Srdivacky
788200583SrdivackyTypeLoc CXXBaseOrMemberInitializer::getBaseClassLoc() const {
789200583Srdivacky  if (isBaseInitializer())
790200583Srdivacky    return BaseOrMember.get<TypeSourceInfo*>()->getTypeLoc();
791200583Srdivacky  else
792200583Srdivacky    return TypeLoc();
793200583Srdivacky}
794200583Srdivacky
795200583SrdivackyType *CXXBaseOrMemberInitializer::getBaseClass() {
796200583Srdivacky  if (isBaseInitializer())
797200583Srdivacky    return BaseOrMember.get<TypeSourceInfo*>()->getType().getTypePtr();
798200583Srdivacky  else
799200583Srdivacky    return 0;
800200583Srdivacky}
801200583Srdivacky
802200583Srdivackyconst Type *CXXBaseOrMemberInitializer::getBaseClass() const {
803200583Srdivacky  if (isBaseInitializer())
804200583Srdivacky    return BaseOrMember.get<TypeSourceInfo*>()->getType().getTypePtr();
805200583Srdivacky  else
806200583Srdivacky    return 0;
807200583Srdivacky}
808200583Srdivacky
809200583SrdivackySourceLocation CXXBaseOrMemberInitializer::getSourceLocation() const {
810200583Srdivacky  if (isMemberInitializer())
811200583Srdivacky    return getMemberLocation();
812200583Srdivacky
813208600Srdivacky  return getBaseClassLoc().getLocalSourceRange().getBegin();
814200583Srdivacky}
815200583Srdivacky
816200583SrdivackySourceRange CXXBaseOrMemberInitializer::getSourceRange() const {
817200583Srdivacky  return SourceRange(getSourceLocation(), getRParenLoc());
818200583Srdivacky}
819200583Srdivacky
820193326SedCXXConstructorDecl *
821208600SrdivackyCXXConstructorDecl::Create(ASTContext &C, EmptyShell Empty) {
822212904Sdim  return new (C) CXXConstructorDecl(0, DeclarationNameInfo(),
823208600Srdivacky                                    QualType(), 0, false, false, false);
824208600Srdivacky}
825208600Srdivacky
826208600SrdivackyCXXConstructorDecl *
827193326SedCXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
828212904Sdim                           const DeclarationNameInfo &NameInfo,
829200583Srdivacky                           QualType T, TypeSourceInfo *TInfo,
830198092Srdivacky                           bool isExplicit,
831207619Srdivacky                           bool isInline,
832207619Srdivacky                           bool isImplicitlyDeclared) {
833212904Sdim  assert(NameInfo.getName().getNameKind()
834212904Sdim         == DeclarationName::CXXConstructorName &&
835193326Sed         "Name must refer to a constructor");
836212904Sdim  return new (C) CXXConstructorDecl(RD, NameInfo, T, TInfo, isExplicit,
837207619Srdivacky                                    isInline, isImplicitlyDeclared);
838193326Sed}
839193326Sed
840193326Sedbool CXXConstructorDecl::isDefaultConstructor() const {
841193326Sed  // C++ [class.ctor]p5:
842193326Sed  //   A default constructor for a class X is a constructor of class
843193326Sed  //   X that can be called without an argument.
844193326Sed  return (getNumParams() == 0) ||
845198092Srdivacky         (getNumParams() > 0 && getParamDecl(0)->hasDefaultArg());
846193326Sed}
847193326Sed
848198092Srdivackybool
849201361SrdivackyCXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const {
850193326Sed  // C++ [class.copy]p2:
851193326Sed  //   A non-template constructor for class X is a copy constructor
852193326Sed  //   if its first parameter is of type X&, const X&, volatile X& or
853193326Sed  //   const volatile X&, and either there are no other parameters
854193326Sed  //   or else all other parameters have default arguments (8.3.6).
855193326Sed  if ((getNumParams() < 1) ||
856198092Srdivacky      (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
857198092Srdivacky      (getPrimaryTemplate() != 0) ||
858198092Srdivacky      (getDescribedFunctionTemplate() != 0))
859193326Sed    return false;
860193326Sed
861193326Sed  const ParmVarDecl *Param = getParamDecl(0);
862193326Sed
863193326Sed  // Do we have a reference type? Rvalue references don't count.
864193326Sed  const LValueReferenceType *ParamRefType =
865198092Srdivacky    Param->getType()->getAs<LValueReferenceType>();
866193326Sed  if (!ParamRefType)
867193326Sed    return false;
868193326Sed
869193326Sed  // Is it a reference to our class type?
870201361Srdivacky  ASTContext &Context = getASTContext();
871201361Srdivacky
872198092Srdivacky  CanQualType PointeeType
873193326Sed    = Context.getCanonicalType(ParamRefType->getPointeeType());
874198092Srdivacky  CanQualType ClassTy
875198092Srdivacky    = Context.getCanonicalType(Context.getTagDeclType(getParent()));
876193326Sed  if (PointeeType.getUnqualifiedType() != ClassTy)
877193326Sed    return false;
878193326Sed
879198092Srdivacky  // FIXME: other qualifiers?
880198092Srdivacky
881193326Sed  // We have a copy constructor.
882193326Sed  TypeQuals = PointeeType.getCVRQualifiers();
883193326Sed  return true;
884193326Sed}
885193326Sed
886198092Srdivackybool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {
887193326Sed  // C++ [class.conv.ctor]p1:
888193326Sed  //   A constructor declared without the function-specifier explicit
889193326Sed  //   that can be called with a single parameter specifies a
890193326Sed  //   conversion from the type of its first parameter to the type of
891193326Sed  //   its class. Such a constructor is called a converting
892193326Sed  //   constructor.
893198092Srdivacky  if (isExplicit() && !AllowExplicit)
894193326Sed    return false;
895193326Sed
896198092Srdivacky  return (getNumParams() == 0 &&
897198092Srdivacky          getType()->getAs<FunctionProtoType>()->isVariadic()) ||
898193326Sed         (getNumParams() == 1) ||
899193576Sed         (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg());
900193326Sed}
901193326Sed
902199482Srdivackybool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const {
903199482Srdivacky  if ((getNumParams() < 1) ||
904199482Srdivacky      (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
905199482Srdivacky      (getPrimaryTemplate() == 0) ||
906199482Srdivacky      (getDescribedFunctionTemplate() != 0))
907199482Srdivacky    return false;
908199482Srdivacky
909199482Srdivacky  const ParmVarDecl *Param = getParamDecl(0);
910199482Srdivacky
911199482Srdivacky  ASTContext &Context = getASTContext();
912199482Srdivacky  CanQualType ParamType = Context.getCanonicalType(Param->getType());
913199482Srdivacky
914199482Srdivacky  // Strip off the lvalue reference, if any.
915199482Srdivacky  if (CanQual<LValueReferenceType> ParamRefType
916199482Srdivacky                                    = ParamType->getAs<LValueReferenceType>())
917199482Srdivacky    ParamType = ParamRefType->getPointeeType();
918199482Srdivacky
919199482Srdivacky
920199482Srdivacky  // Is it the same as our our class type?
921199482Srdivacky  CanQualType ClassTy
922199482Srdivacky    = Context.getCanonicalType(Context.getTagDeclType(getParent()));
923199482Srdivacky  if (ParamType.getUnqualifiedType() != ClassTy)
924199482Srdivacky    return false;
925199482Srdivacky
926199482Srdivacky  return true;
927199482Srdivacky}
928199482Srdivacky
929193326SedCXXDestructorDecl *
930208600SrdivackyCXXDestructorDecl::Create(ASTContext &C, EmptyShell Empty) {
931212904Sdim  return new (C) CXXDestructorDecl(0, DeclarationNameInfo(),
932208600Srdivacky                                   QualType(), false, false);
933208600Srdivacky}
934208600Srdivacky
935208600SrdivackyCXXDestructorDecl *
936193326SedCXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
937212904Sdim                          const DeclarationNameInfo &NameInfo,
938198092Srdivacky                          QualType T, bool isInline,
939193326Sed                          bool isImplicitlyDeclared) {
940212904Sdim  assert(NameInfo.getName().getNameKind()
941212904Sdim         == DeclarationName::CXXDestructorName &&
942193326Sed         "Name must refer to a destructor");
943212904Sdim  return new (C) CXXDestructorDecl(RD, NameInfo, T, isInline,
944212904Sdim                                   isImplicitlyDeclared);
945193326Sed}
946193326Sed
947193326SedCXXConversionDecl *
948208600SrdivackyCXXConversionDecl::Create(ASTContext &C, EmptyShell Empty) {
949212904Sdim  return new (C) CXXConversionDecl(0, DeclarationNameInfo(),
950208600Srdivacky                                   QualType(), 0, false, false);
951208600Srdivacky}
952208600Srdivacky
953208600SrdivackyCXXConversionDecl *
954193326SedCXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
955212904Sdim                          const DeclarationNameInfo &NameInfo,
956200583Srdivacky                          QualType T, TypeSourceInfo *TInfo,
957198092Srdivacky                          bool isInline, bool isExplicit) {
958212904Sdim  assert(NameInfo.getName().getNameKind()
959212904Sdim         == DeclarationName::CXXConversionFunctionName &&
960193326Sed         "Name must refer to a conversion function");
961212904Sdim  return new (C) CXXConversionDecl(RD, NameInfo, T, TInfo,
962212904Sdim                                   isInline, isExplicit);
963193326Sed}
964193326Sed
965193326SedLinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
966198092Srdivacky                                         DeclContext *DC,
967193326Sed                                         SourceLocation L,
968193326Sed                                         LanguageIDs Lang, bool Braces) {
969193326Sed  return new (C) LinkageSpecDecl(DC, L, Lang, Braces);
970193326Sed}
971193326Sed
972193326SedUsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
973193326Sed                                               SourceLocation L,
974193326Sed                                               SourceLocation NamespaceLoc,
975193326Sed                                               SourceRange QualifierRange,
976193326Sed                                               NestedNameSpecifier *Qualifier,
977193326Sed                                               SourceLocation IdentLoc,
978199990Srdivacky                                               NamedDecl *Used,
979193326Sed                                               DeclContext *CommonAncestor) {
980199990Srdivacky  if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used))
981199990Srdivacky    Used = NS->getOriginalNamespace();
982198092Srdivacky  return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange,
983193326Sed                                    Qualifier, IdentLoc, Used, CommonAncestor);
984193326Sed}
985193326Sed
986199990SrdivackyNamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
987199990Srdivacky  if (NamespaceAliasDecl *NA =
988199990Srdivacky        dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace))
989199990Srdivacky    return NA->getNamespace();
990199990Srdivacky  return cast_or_null<NamespaceDecl>(NominatedNamespace);
991199990Srdivacky}
992199990Srdivacky
993198092SrdivackyNamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
994212904Sdim                                               SourceLocation UsingLoc,
995198092Srdivacky                                               SourceLocation AliasLoc,
996198092Srdivacky                                               IdentifierInfo *Alias,
997193326Sed                                               SourceRange QualifierRange,
998193326Sed                                               NestedNameSpecifier *Qualifier,
999198092Srdivacky                                               SourceLocation IdentLoc,
1000193326Sed                                               NamedDecl *Namespace) {
1001199990Srdivacky  if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
1002199990Srdivacky    Namespace = NS->getOriginalNamespace();
1003212904Sdim  return new (C) NamespaceAliasDecl(DC, UsingLoc, AliasLoc, Alias, QualifierRange,
1004193326Sed                                    Qualifier, IdentLoc, Namespace);
1005193326Sed}
1006193326Sed
1007194613SedUsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
1008212904Sdim                             SourceRange NNR, SourceLocation UL,
1009212904Sdim                             NestedNameSpecifier* TargetNNS,
1010212904Sdim                             const DeclarationNameInfo &NameInfo,
1011212904Sdim                             bool IsTypeNameArg) {
1012212904Sdim  return new (C) UsingDecl(DC, NNR, UL, TargetNNS, NameInfo, IsTypeNameArg);
1013194613Sed}
1014194613Sed
1015199482SrdivackyUnresolvedUsingValueDecl *
1016199482SrdivackyUnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
1017199482Srdivacky                                 SourceLocation UsingLoc,
1018199482Srdivacky                                 SourceRange TargetNNR,
1019199482Srdivacky                                 NestedNameSpecifier *TargetNNS,
1020212904Sdim                                 const DeclarationNameInfo &NameInfo) {
1021199482Srdivacky  return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
1022212904Sdim                                          TargetNNR, TargetNNS, NameInfo);
1023198092Srdivacky}
1024198092Srdivacky
1025199482SrdivackyUnresolvedUsingTypenameDecl *
1026199482SrdivackyUnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
1027199482Srdivacky                                    SourceLocation UsingLoc,
1028199482Srdivacky                                    SourceLocation TypenameLoc,
1029199482Srdivacky                                    SourceRange TargetNNR,
1030199482Srdivacky                                    NestedNameSpecifier *TargetNNS,
1031199482Srdivacky                                    SourceLocation TargetNameLoc,
1032199482Srdivacky                                    DeclarationName TargetName) {
1033199482Srdivacky  return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
1034199482Srdivacky                                             TargetNNR, TargetNNS,
1035199482Srdivacky                                             TargetNameLoc,
1036199482Srdivacky                                             TargetName.getAsIdentifierInfo());
1037199482Srdivacky}
1038199482Srdivacky
1039193326SedStaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
1040193326Sed                                           SourceLocation L, Expr *AssertExpr,
1041193326Sed                                           StringLiteral *Message) {
1042193326Sed  return new (C) StaticAssertDecl(DC, L, AssertExpr, Message);
1043193326Sed}
1044193326Sed
1045193326Sedstatic const char *getAccessName(AccessSpecifier AS) {
1046193326Sed  switch (AS) {
1047193326Sed    default:
1048193326Sed    case AS_none:
1049193326Sed      assert("Invalid access specifier!");
1050193326Sed      return 0;
1051193326Sed    case AS_public:
1052193326Sed      return "public";
1053193326Sed    case AS_private:
1054193326Sed      return "private";
1055193326Sed    case AS_protected:
1056193326Sed      return "protected";
1057193326Sed  }
1058193326Sed}
1059193326Sed
1060193326Sedconst DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
1061193326Sed                                           AccessSpecifier AS) {
1062193326Sed  return DB << getAccessName(AS);
1063193326Sed}
1064