DeclCXX.cpp revision 60d62c29d260596454aaf4cb50cbc756ac08875e
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/ASTContext.h"
16using namespace clang;
17
18//===----------------------------------------------------------------------===//
19// Decl Allocation/Deallocation Method Implementations
20//===----------------------------------------------------------------------===//
21
22CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD,
23                                   SourceLocation L, IdentifierInfo *Id,
24                                   QualType T, Expr *BW) {
25  void *Mem = C.getAllocator().Allocate<CXXFieldDecl>();
26  return new (Mem) CXXFieldDecl(RD, L, Id, T, BW);
27}
28
29CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
30                                     SourceLocation L, IdentifierInfo *Id,
31                                     CXXRecordDecl* PrevDecl) {
32  void *Mem = C.getAllocator().Allocate<CXXRecordDecl>();
33  CXXRecordDecl* R = new (Mem) CXXRecordDecl(TK, DC, L, Id);
34  C.getTypeDeclType(R, PrevDecl);
35  return R;
36}
37
38CXXRecordDecl::~CXXRecordDecl() {
39  delete [] Bases;
40}
41
42void CXXRecordDecl::Destroy(ASTContext &C) {
43  for (OverloadedFunctionDecl::function_iterator func
44         = Constructors.function_begin();
45       func != Constructors.function_end(); ++func)
46    (*func)->Destroy(C);
47  RecordDecl::Destroy(C);
48}
49
50void
51CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
52                        unsigned NumBases) {
53  if (this->Bases)
54    delete [] this->Bases;
55
56  this->Bases = new CXXBaseSpecifier[NumBases];
57  this->NumBases = NumBases;
58  for (unsigned i = 0; i < NumBases; ++i)
59    this->Bases[i] = *Bases[i];
60}
61
62CXXMethodDecl *
63CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
64                      SourceLocation L, IdentifierInfo *Id,
65                      QualType T, bool isStatic, bool isInline,
66                      ScopedDecl *PrevDecl) {
67  void *Mem = C.getAllocator().Allocate<CXXMethodDecl>();
68  return new (Mem) CXXMethodDecl(RD, L, Id, T, isStatic, isInline, PrevDecl);
69}
70
71QualType CXXMethodDecl::getThisType(ASTContext &C) const {
72  // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
73  // If the member function is declared const, the type of this is const X*,
74  // if the member function is declared volatile, the type of this is
75  // volatile X*, and if the member function is declared const volatile,
76  // the type of this is const volatile X*.
77
78  assert(isInstance() && "No 'this' for static methods!");
79  QualType ClassTy = C.getTagDeclType(const_cast<CXXRecordDecl*>(
80                                            cast<CXXRecordDecl>(getParent())));
81  ClassTy = ClassTy.getWithAdditionalQualifiers(getTypeQualifiers());
82  return C.getPointerType(ClassTy).withConst();
83}
84
85CXXConstructorDecl *
86CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
87                           SourceLocation L, IdentifierInfo *Id,
88                           QualType T, bool isExplicit,
89                           bool isInline, bool isImplicitlyDeclared) {
90  void *Mem = C.getAllocator().Allocate<CXXConstructorDecl>();
91  return new (Mem) CXXConstructorDecl(RD, L, Id, T, isExplicit, isInline,
92                                      isImplicitlyDeclared);
93}
94
95bool CXXConstructorDecl::isConvertingConstructor() const {
96  // C++ [class.conv.ctor]p1:
97  //   A constructor declared without the function-specifier explicit
98  //   that can be called with a single parameter specifies a
99  //   conversion from the type of its first parameter to the type of
100  //   its class. Such a constructor is called a converting
101  //   constructor.
102  if (isExplicit())
103    return false;
104
105  return (getNumParams() == 0 &&
106          getType()->getAsFunctionTypeProto()->isVariadic()) ||
107         (getNumParams() == 1) ||
108         (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0);
109}
110
111CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,
112                                   SourceLocation L, IdentifierInfo *Id,
113                                   QualType T, ScopedDecl *PrevDecl) {
114  void *Mem = C.getAllocator().Allocate<CXXClassVarDecl>();
115  return new (Mem) CXXClassVarDecl(RD, L, Id, T, PrevDecl);
116}
117
118OverloadedFunctionDecl *
119OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
120                               IdentifierInfo *Id) {
121  void *Mem = C.getAllocator().Allocate<OverloadedFunctionDecl>();
122  return new (Mem) OverloadedFunctionDecl(DC, Id);
123}
124