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