DeclCXX.cpp revision f27ef733ed988505288433714313488cc05ab5b0
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  assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl");
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
155void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
156                                            CXXMethodDecl *OpDecl) {
157  // We're interested specifically in copy assignment operators.
158  const FunctionProtoType *FnType = OpDecl->getType()->getAsFunctionProtoType();
159  assert(FnType && "Overloaded operator has no proto function type.");
160  assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
161  QualType ArgType = FnType->getArgType(0);
162  if (const LValueReferenceType *Ref = ArgType->getAsLValueReferenceType())
163    ArgType = Ref->getPointeeType();
164
165  ArgType = ArgType.getUnqualifiedType();
166  QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
167    const_cast<CXXRecordDecl*>(this)));
168
169  if (ClassType != Context.getCanonicalType(ArgType))
170    return;
171
172  // This is a copy assignment operator.
173  // Suppress the implicit declaration of a copy constructor.
174  UserDeclaredCopyAssignment = true;
175
176  // C++ [class]p4:
177  //   A POD-struct is an aggregate class that [...] has no user-defined copy
178  //   assignment operator [...].
179  PlainOldData = false;
180}
181
182void CXXRecordDecl::addConversionFunction(ASTContext &Context,
183                                          CXXConversionDecl *ConvDecl) {
184  Conversions.addOverload(ConvDecl);
185}
186
187const CXXDestructorDecl *
188CXXRecordDecl::getDestructor(ASTContext &Context) {
189  QualType ClassType = Context.getTypeDeclType(this);
190
191  DeclarationName Name
192    = Context.DeclarationNames.getCXXDestructorName(ClassType);
193
194  DeclContext::lookup_iterator I, E;
195  llvm::tie(I, E) = lookup(Context, Name);
196  assert(I != E && "Did not find a destructor!");
197
198  const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I);
199  assert(++I == E && "Found more than one destructor!");
200
201  return Dtor;
202}
203
204CXXMethodDecl *
205CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
206                      SourceLocation L, DeclarationName N,
207                      QualType T, bool isStatic, bool isInline) {
208  return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline);
209}
210
211
212typedef llvm::DenseMap<const CXXMethodDecl*,
213                       std::vector<const CXXMethodDecl *> *>
214                       OverriddenMethodsMapTy;
215
216static OverriddenMethodsMapTy *OverriddenMethods = 0;
217
218void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
219  // FIXME: The CXXMethodDecl dtor needs to remove and free the entry.
220
221  if (!OverriddenMethods)
222    OverriddenMethods = new OverriddenMethodsMapTy();
223
224  std::vector<const CXXMethodDecl *> *&Methods = (*OverriddenMethods)[this];
225  if (!Methods)
226    Methods = new std::vector<const CXXMethodDecl *>;
227
228  Methods->push_back(MD);
229}
230
231CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
232  if (!OverriddenMethods)
233    return 0;
234
235  OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this);
236  if (it == OverriddenMethods->end())
237    return 0;
238  return &(*it->second)[0];
239}
240
241CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
242  if (!OverriddenMethods)
243    return 0;
244
245  OverriddenMethodsMapTy::iterator it = OverriddenMethods->find(this);
246  if (it == OverriddenMethods->end())
247    return 0;
248
249  return &(*it->second)[it->second->size()];
250}
251
252QualType CXXMethodDecl::getThisType(ASTContext &C) const {
253  // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
254  // If the member function is declared const, the type of this is const X*,
255  // if the member function is declared volatile, the type of this is
256  // volatile X*, and if the member function is declared const volatile,
257  // the type of this is const volatile X*.
258
259  assert(isInstance() && "No 'this' for static methods!");
260
261  QualType ClassTy;
262  if (ClassTemplateDecl *TD = getParent()->getDescribedClassTemplate())
263    ClassTy = TD->getInjectedClassNameType(C);
264  else
265    ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
266  ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers());
267  return C.getPointerType(ClassTy).withConst();
268}
269
270CXXBaseOrMemberInitializer::
271CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs)
272  : Args(0), NumArgs(0) {
273  BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
274  assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
275  BaseOrMember |= 0x01;
276
277  if (NumArgs > 0) {
278    this->NumArgs = NumArgs;
279    this->Args = new Expr*[NumArgs];
280    for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
281      this->Args[Idx] = Args[Idx];
282  }
283}
284
285CXXBaseOrMemberInitializer::
286CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs)
287  : Args(0), NumArgs(0) {
288  BaseOrMember = reinterpret_cast<uintptr_t>(Member);
289  assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");
290
291  if (NumArgs > 0) {
292    this->NumArgs = NumArgs;
293    this->Args = new Expr*[NumArgs];
294    for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
295      this->Args[Idx] = Args[Idx];
296  }
297}
298
299CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() {
300  delete [] Args;
301}
302
303CXXConstructorDecl *
304CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
305                           SourceLocation L, DeclarationName N,
306                           QualType T, bool isExplicit,
307                           bool isInline, bool isImplicitlyDeclared) {
308  assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
309         "Name must refer to a constructor");
310  return new (C) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline,
311                                      isImplicitlyDeclared);
312}
313
314bool CXXConstructorDecl::isDefaultConstructor() const {
315  // C++ [class.ctor]p5:
316  //   A default constructor for a class X is a constructor of class
317  //   X that can be called without an argument.
318  return (getNumParams() == 0) ||
319         (getNumParams() > 0 && getParamDecl(0)->getDefaultArg() != 0);
320}
321
322bool
323CXXConstructorDecl::isCopyConstructor(ASTContext &Context,
324                                      unsigned &TypeQuals) const {
325  // C++ [class.copy]p2:
326  //   A non-template constructor for class X is a copy constructor
327  //   if its first parameter is of type X&, const X&, volatile X& or
328  //   const volatile X&, and either there are no other parameters
329  //   or else all other parameters have default arguments (8.3.6).
330  if ((getNumParams() < 1) ||
331      (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()))
332    return false;
333
334  const ParmVarDecl *Param = getParamDecl(0);
335
336  // Do we have a reference type? Rvalue references don't count.
337  const LValueReferenceType *ParamRefType =
338    Param->getType()->getAsLValueReferenceType();
339  if (!ParamRefType)
340    return false;
341
342  // Is it a reference to our class type?
343  QualType PointeeType
344    = Context.getCanonicalType(ParamRefType->getPointeeType());
345  QualType ClassTy
346    = Context.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
347  if (PointeeType.getUnqualifiedType() != ClassTy)
348    return false;
349
350  // We have a copy constructor.
351  TypeQuals = PointeeType.getCVRQualifiers();
352  return true;
353}
354
355bool CXXConstructorDecl::isConvertingConstructor() const {
356  // C++ [class.conv.ctor]p1:
357  //   A constructor declared without the function-specifier explicit
358  //   that can be called with a single parameter specifies a
359  //   conversion from the type of its first parameter to the type of
360  //   its class. Such a constructor is called a converting
361  //   constructor.
362  if (isExplicit())
363    return false;
364
365  return (getNumParams() == 0 &&
366          getType()->getAsFunctionProtoType()->isVariadic()) ||
367         (getNumParams() == 1) ||
368         (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg());
369}
370
371CXXDestructorDecl *
372CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
373                          SourceLocation L, DeclarationName N,
374                          QualType T, bool isInline,
375                          bool isImplicitlyDeclared) {
376  assert(N.getNameKind() == DeclarationName::CXXDestructorName &&
377         "Name must refer to a destructor");
378  return new (C) CXXDestructorDecl(RD, L, N, T, isInline,
379                                   isImplicitlyDeclared);
380}
381
382CXXConversionDecl *
383CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
384                          SourceLocation L, DeclarationName N,
385                          QualType T, bool isInline, bool isExplicit) {
386  assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName &&
387         "Name must refer to a conversion function");
388  return new (C) CXXConversionDecl(RD, L, N, T, isInline, isExplicit);
389}
390
391OverloadedFunctionDecl *
392OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
393                               DeclarationName N) {
394  return new (C) OverloadedFunctionDecl(DC, N);
395}
396
397LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
398                                         DeclContext *DC,
399                                         SourceLocation L,
400                                         LanguageIDs Lang, bool Braces) {
401  return new (C) LinkageSpecDecl(DC, L, Lang, Braces);
402}
403
404UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
405                                               SourceLocation L,
406                                               SourceLocation NamespaceLoc,
407                                               SourceRange QualifierRange,
408                                               NestedNameSpecifier *Qualifier,
409                                               SourceLocation IdentLoc,
410                                               NamespaceDecl *Used,
411                                               DeclContext *CommonAncestor) {
412  return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange,
413                                    Qualifier, IdentLoc, Used, CommonAncestor);
414}
415
416NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
417                                               SourceLocation L,
418                                               SourceLocation AliasLoc,
419                                               IdentifierInfo *Alias,
420                                               SourceRange QualifierRange,
421                                               NestedNameSpecifier *Qualifier,
422                                               SourceLocation IdentLoc,
423                                               NamedDecl *Namespace) {
424  return new (C) NamespaceAliasDecl(DC, L, AliasLoc, Alias, QualifierRange,
425                                    Qualifier, IdentLoc, Namespace);
426}
427
428StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
429                                           SourceLocation L, Expr *AssertExpr,
430                                           StringLiteral *Message) {
431  return new (C) StaticAssertDecl(DC, L, AssertExpr, Message);
432}
433
434void StaticAssertDecl::Destroy(ASTContext& C) {
435  AssertExpr->Destroy(C);
436  Message->Destroy(C);
437  this->~StaticAssertDecl();
438  C.Deallocate((void *)this);
439}
440
441StaticAssertDecl::~StaticAssertDecl() {
442}
443
444static const char *getAccessName(AccessSpecifier AS) {
445  switch (AS) {
446    default:
447    case AS_none:
448      assert("Invalid access specifier!");
449      return 0;
450    case AS_public:
451      return "public";
452    case AS_private:
453      return "private";
454    case AS_protected:
455      return "protected";
456  }
457}
458
459const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
460                                           AccessSpecifier AS) {
461  return DB << getAccessName(AS);
462}
463
464
465