DeclCXX.cpp revision 194711
1281760Ssjg//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===//
2281760Ssjg//
3281760Ssjg//                     The LLVM Compiler Infrastructure
4281760Ssjg//
5281760Ssjg// This file is distributed under the University of Illinois Open Source
6281760Ssjg// License. See LICENSE.TXT for details.
7281760Ssjg//
8281760Ssjg//===----------------------------------------------------------------------===//
9281760Ssjg//
10281760Ssjg// This file implements the C++ related Decl classes.
11281760Ssjg//
12281760Ssjg//===----------------------------------------------------------------------===//
13281760Ssjg
14281760Ssjg#include "clang/AST/DeclCXX.h"
15281760Ssjg#include "clang/AST/DeclTemplate.h"
16281760Ssjg#include "clang/AST/ASTContext.h"
17281760Ssjg#include "clang/AST/Expr.h"
18281760Ssjg#include "clang/Basic/IdentifierTable.h"
19281760Ssjg#include "llvm/ADT/STLExtras.h"
20using namespace clang;
21
22//===----------------------------------------------------------------------===//
23// Decl Allocation/Deallocation Method Implementations
24//===----------------------------------------------------------------------===//
25
26CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
27                             SourceLocation L, IdentifierInfo *Id)
28  : RecordDecl(K, TK, DC, L, Id),
29    UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
30    UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false),
31    Aggregate(true), PlainOldData(true), Polymorphic(false), Abstract(false),
32    HasTrivialConstructor(true), HasTrivialDestructor(true),
33    Bases(0), NumBases(0), Conversions(DC, DeclarationName()),
34    TemplateOrInstantiation() { }
35
36CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
37                                     SourceLocation L, IdentifierInfo *Id,
38                                     CXXRecordDecl* PrevDecl,
39                                     bool DelayTypeCreation) {
40  CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id);
41  if (!DelayTypeCreation)
42    C.getTypeDeclType(R, PrevDecl);
43  return R;
44}
45
46CXXRecordDecl::~CXXRecordDecl() {
47  delete [] Bases;
48}
49
50void
51CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
52                        unsigned NumBases) {
53  // C++ [dcl.init.aggr]p1:
54  //   An aggregate is an array or a class (clause 9) with [...]
55  //   no base classes [...].
56  Aggregate = false;
57
58  if (this->Bases)
59    delete [] this->Bases;
60
61  // FIXME: allocate using the ASTContext
62  this->Bases = new CXXBaseSpecifier[NumBases];
63  this->NumBases = NumBases;
64  for (unsigned i = 0; i < NumBases; ++i)
65    this->Bases[i] = *Bases[i];
66}
67
68bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const {
69  return getCopyConstructor(Context, QualType::Const) != 0;
70}
71
72CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context,
73                                                      unsigned TypeQuals) const{
74  QualType ClassType
75    = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this));
76  DeclarationName ConstructorName
77    = Context.DeclarationNames.getCXXConstructorName(
78                                          Context.getCanonicalType(ClassType));
79  unsigned FoundTQs;
80  DeclContext::lookup_const_iterator Con, ConEnd;
81  for (llvm::tie(Con, ConEnd) = this->lookup(Context, ConstructorName);
82       Con != ConEnd; ++Con) {
83    if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context,
84                                                          FoundTQs)) {
85      if (((TypeQuals & QualType::Const) == (FoundTQs & QualType::Const)) ||
86          (!(TypeQuals & QualType::Const) && (FoundTQs & QualType::Const)))
87        return cast<CXXConstructorDecl>(*Con);
88
89    }
90  }
91  return 0;
92}
93
94bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const {
95  QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
96    const_cast<CXXRecordDecl*>(this)));
97  DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
98
99  DeclContext::lookup_const_iterator Op, OpEnd;
100  for (llvm::tie(Op, OpEnd) = this->lookup(Context, OpName);
101       Op != OpEnd; ++Op) {
102    // C++ [class.copy]p9:
103    //   A user-declared copy assignment operator is a non-static non-template
104    //   member function of class X with exactly one parameter of type X, X&,
105    //   const X&, volatile X& or const volatile X&.
106    const CXXMethodDecl* Method = cast<CXXMethodDecl>(*Op);
107    if (Method->isStatic())
108      continue;
109    // TODO: Skip templates? Or is this implicitly done due to parameter types?
110    const FunctionProtoType *FnType =
111      Method->getType()->getAsFunctionProtoType();
112    assert(FnType && "Overloaded operator has no prototype.");
113    // Don't assert on this; an invalid decl might have been left in the AST.
114    if (FnType->getNumArgs() != 1 || FnType->isVariadic())
115      continue;
116    bool AcceptsConst = true;
117    QualType ArgType = FnType->getArgType(0);
118    if (const LValueReferenceType *Ref = ArgType->getAsLValueReferenceType()) {
119      ArgType = Ref->getPointeeType();
120      // Is it a non-const lvalue reference?
121      if (!ArgType.isConstQualified())
122        AcceptsConst = false;
123    }
124    if (Context.getCanonicalType(ArgType).getUnqualifiedType() != ClassType)
125      continue;
126
127    // We have a single argument of type cv X or cv X&, i.e. we've found the
128    // copy assignment operator. Return whether it accepts const arguments.
129    return AcceptsConst;
130  }
131  assert(isInvalidDecl() &&
132         "No copy assignment operator declared in valid code.");
133  return false;
134}
135
136void
137CXXRecordDecl::addedConstructor(ASTContext &Context,
138                                CXXConstructorDecl *ConDecl) {
139  assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl");
140  // Note that we have a user-declared constructor.
141  UserDeclaredConstructor = true;
142
143  // C++ [dcl.init.aggr]p1:
144  //   An aggregate is an array or a class (clause 9) with no
145  //   user-declared constructors (12.1) [...].
146  Aggregate = false;
147
148  // C++ [class]p4:
149  //   A POD-struct is an aggregate class [...]
150  PlainOldData = false;
151
152  // C++ [class.ctor]p5:
153  //   A constructor is trivial if it is an implicitly-declared default
154  //   constructor.
155  HasTrivialConstructor = false;
156
157  // Note when we have a user-declared copy constructor, which will
158  // suppress the implicit declaration of a copy constructor.
159  if (ConDecl->isCopyConstructor(Context))
160    UserDeclaredCopyConstructor = true;
161}
162
163void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
164                                            CXXMethodDecl *OpDecl) {
165  // We're interested specifically in copy assignment operators.
166  const FunctionProtoType *FnType = OpDecl->getType()->getAsFunctionProtoType();
167  assert(FnType && "Overloaded operator has no proto function type.");
168  assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
169  QualType ArgType = FnType->getArgType(0);
170  if (const LValueReferenceType *Ref = ArgType->getAsLValueReferenceType())
171    ArgType = Ref->getPointeeType();
172
173  ArgType = ArgType.getUnqualifiedType();
174  QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
175    const_cast<CXXRecordDecl*>(this)));
176
177  if (ClassType != Context.getCanonicalType(ArgType))
178    return;
179
180  // This is a copy assignment operator.
181  // Suppress the implicit declaration of a copy constructor.
182  UserDeclaredCopyAssignment = true;
183
184  // C++ [class]p4:
185  //   A POD-struct is an aggregate class that [...] has no user-defined copy
186  //   assignment operator [...].
187  PlainOldData = false;
188}
189
190void CXXRecordDecl::addConversionFunction(ASTContext &Context,
191                                          CXXConversionDecl *ConvDecl) {
192  Conversions.addOverload(ConvDecl);
193}
194
195
196CXXConstructorDecl *
197CXXRecordDecl::getDefaultConstructor(ASTContext &Context) {
198  QualType ClassType = Context.getTypeDeclType(this);
199  DeclarationName ConstructorName
200    = Context.DeclarationNames.getCXXConstructorName(
201                      Context.getCanonicalType(ClassType.getUnqualifiedType()));
202
203  DeclContext::lookup_const_iterator Con, ConEnd;
204  for (llvm::tie(Con, ConEnd) = lookup(Context, ConstructorName);
205       Con != ConEnd; ++Con) {
206    CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
207    if (Constructor->isDefaultConstructor())
208      return Constructor;
209  }
210  return 0;
211}
212
213const CXXDestructorDecl *
214CXXRecordDecl::getDestructor(ASTContext &Context) {
215  QualType ClassType = Context.getTypeDeclType(this);
216
217  DeclarationName Name
218    = Context.DeclarationNames.getCXXDestructorName(ClassType);
219
220  DeclContext::lookup_iterator I, E;
221  llvm::tie(I, E) = lookup(Context, Name);
222  assert(I != E && "Did not find a destructor!");
223
224  const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I);
225  assert(++I == E && "Found more than one destructor!");
226
227  return Dtor;
228}
229
230CXXMethodDecl *
231CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
232                      SourceLocation L, DeclarationName N,
233                      QualType T, bool isStatic, bool isInline) {
234  return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline);
235}
236
237
238typedef llvm::DenseMap<const CXXMethodDecl*,
239                       std::vector<const CXXMethodDecl *> *>
240                       OverriddenMethodsMapTy;
241
242static OverriddenMethodsMapTy *OverriddenMethods = 0;
243
244void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
245  // FIXME: The CXXMethodDecl dtor needs to remove and free the entry.
246
247  if (!OverriddenMethods)
248    OverriddenMethods = new OverriddenMethodsMapTy();
249
250  std::vector<const CXXMethodDecl *> *&Methods = (*OverriddenMethods)[this];
251  if (!Methods)
252    Methods = new std::vector<const CXXMethodDecl *>;
253
254  Methods->push_back(MD);
255}
256
257CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
258  if (!OverriddenMethods)
259    return 0;
260
261  OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this);
262  if (it == OverriddenMethods->end())
263    return 0;
264  return &(*it->second)[0];
265}
266
267CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
268  if (!OverriddenMethods)
269    return 0;
270
271  OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this);
272  if (it == OverriddenMethods->end())
273    return 0;
274
275  return &(*it->second)[it->second->size()];
276}
277
278QualType CXXMethodDecl::getThisType(ASTContext &C) const {
279  // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
280  // If the member function is declared const, the type of this is const X*,
281  // if the member function is declared volatile, the type of this is
282  // volatile X*, and if the member function is declared const volatile,
283  // the type of this is const volatile X*.
284
285  assert(isInstance() && "No 'this' for static methods!");
286
287  QualType ClassTy;
288  if (ClassTemplateDecl *TD = getParent()->getDescribedClassTemplate())
289    ClassTy = TD->getInjectedClassNameType(C);
290  else
291    ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
292  ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers());
293  return C.getPointerType(ClassTy).withConst();
294}
295
296CXXBaseOrMemberInitializer::
297CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs)
298  : Args(0), NumArgs(0) {
299  BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
300  assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
301  BaseOrMember |= 0x01;
302
303  if (NumArgs > 0) {
304    this->NumArgs = NumArgs;
305    this->Args = new Expr*[NumArgs];
306    for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
307      this->Args[Idx] = Args[Idx];
308  }
309}
310
311CXXBaseOrMemberInitializer::
312CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs)
313  : Args(0), NumArgs(0) {
314  BaseOrMember = reinterpret_cast<uintptr_t>(Member);
315  assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");
316
317  if (NumArgs > 0) {
318    this->NumArgs = NumArgs;
319    this->Args = new Expr*[NumArgs];
320    for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
321      this->Args[Idx] = Args[Idx];
322  }
323}
324
325CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() {
326  delete [] Args;
327}
328
329CXXConstructorDecl *
330CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
331                           SourceLocation L, DeclarationName N,
332                           QualType T, bool isExplicit,
333                           bool isInline, bool isImplicitlyDeclared) {
334  assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
335         "Name must refer to a constructor");
336  return new (C) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline,
337                                      isImplicitlyDeclared);
338}
339
340bool CXXConstructorDecl::isDefaultConstructor() const {
341  // C++ [class.ctor]p5:
342  //   A default constructor for a class X is a constructor of class
343  //   X that can be called without an argument.
344  return (getNumParams() == 0) ||
345         (getNumParams() > 0 && getParamDecl(0)->getDefaultArg() != 0);
346}
347
348bool
349CXXConstructorDecl::isCopyConstructor(ASTContext &Context,
350                                      unsigned &TypeQuals) const {
351  // C++ [class.copy]p2:
352  //   A non-template constructor for class X is a copy constructor
353  //   if its first parameter is of type X&, const X&, volatile X& or
354  //   const volatile X&, and either there are no other parameters
355  //   or else all other parameters have default arguments (8.3.6).
356  if ((getNumParams() < 1) ||
357      (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()))
358    return false;
359
360  const ParmVarDecl *Param = getParamDecl(0);
361
362  // Do we have a reference type? Rvalue references don't count.
363  const LValueReferenceType *ParamRefType =
364    Param->getType()->getAsLValueReferenceType();
365  if (!ParamRefType)
366    return false;
367
368  // Is it a reference to our class type?
369  QualType PointeeType
370    = Context.getCanonicalType(ParamRefType->getPointeeType());
371  QualType ClassTy
372    = Context.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
373  if (PointeeType.getUnqualifiedType() != ClassTy)
374    return false;
375
376  // We have a copy constructor.
377  TypeQuals = PointeeType.getCVRQualifiers();
378  return true;
379}
380
381bool CXXConstructorDecl::isConvertingConstructor() const {
382  // C++ [class.conv.ctor]p1:
383  //   A constructor declared without the function-specifier explicit
384  //   that can be called with a single parameter specifies a
385  //   conversion from the type of its first parameter to the type of
386  //   its class. Such a constructor is called a converting
387  //   constructor.
388  if (isExplicit())
389    return false;
390
391  return (getNumParams() == 0 &&
392          getType()->getAsFunctionProtoType()->isVariadic()) ||
393         (getNumParams() == 1) ||
394         (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg());
395}
396
397CXXDestructorDecl *
398CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
399                          SourceLocation L, DeclarationName N,
400                          QualType T, bool isInline,
401                          bool isImplicitlyDeclared) {
402  assert(N.getNameKind() == DeclarationName::CXXDestructorName &&
403         "Name must refer to a destructor");
404  return new (C) CXXDestructorDecl(RD, L, N, T, isInline,
405                                   isImplicitlyDeclared);
406}
407
408CXXConversionDecl *
409CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
410                          SourceLocation L, DeclarationName N,
411                          QualType T, bool isInline, bool isExplicit) {
412  assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName &&
413         "Name must refer to a conversion function");
414  return new (C) CXXConversionDecl(RD, L, N, T, isInline, isExplicit);
415}
416
417OverloadedFunctionDecl *
418OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
419                               DeclarationName N) {
420  return new (C) OverloadedFunctionDecl(DC, N);
421}
422
423LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
424                                         DeclContext *DC,
425                                         SourceLocation L,
426                                         LanguageIDs Lang, bool Braces) {
427  return new (C) LinkageSpecDecl(DC, L, Lang, Braces);
428}
429
430UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
431                                               SourceLocation L,
432                                               SourceLocation NamespaceLoc,
433                                               SourceRange QualifierRange,
434                                               NestedNameSpecifier *Qualifier,
435                                               SourceLocation IdentLoc,
436                                               NamespaceDecl *Used,
437                                               DeclContext *CommonAncestor) {
438  return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange,
439                                    Qualifier, IdentLoc, Used, CommonAncestor);
440}
441
442NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
443                                               SourceLocation L,
444                                               SourceLocation AliasLoc,
445                                               IdentifierInfo *Alias,
446                                               SourceRange QualifierRange,
447                                               NestedNameSpecifier *Qualifier,
448                                               SourceLocation IdentLoc,
449                                               NamedDecl *Namespace) {
450  return new (C) NamespaceAliasDecl(DC, L, AliasLoc, Alias, QualifierRange,
451                                    Qualifier, IdentLoc, Namespace);
452}
453
454UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
455      SourceLocation L, SourceRange NNR, SourceLocation TargetNL,
456      SourceLocation UL, NamedDecl* Target,
457      NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) {
458  return new (C) UsingDecl(DC, L, NNR, TargetNL, UL, Target,
459      TargetNNS, IsTypeNameArg);
460}
461
462StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
463                                           SourceLocation L, Expr *AssertExpr,
464                                           StringLiteral *Message) {
465  return new (C) StaticAssertDecl(DC, L, AssertExpr, Message);
466}
467
468void StaticAssertDecl::Destroy(ASTContext& C) {
469  AssertExpr->Destroy(C);
470  Message->Destroy(C);
471  this->~StaticAssertDecl();
472  C.Deallocate((void *)this);
473}
474
475StaticAssertDecl::~StaticAssertDecl() {
476}
477
478static const char *getAccessName(AccessSpecifier AS) {
479  switch (AS) {
480    default:
481    case AS_none:
482      assert("Invalid access specifier!");
483      return 0;
484    case AS_public:
485      return "public";
486    case AS_private:
487      return "private";
488    case AS_protected:
489      return "protected";
490  }
491}
492
493const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
494                                           AccessSpecifier AS) {
495  return DB << getAccessName(AS);
496}
497
498
499