DeclCXX.h revision fef35f1ce99765670482124e2bd640bbe7a20a4f
1//===-- DeclCXX.h - Classes for representing C++ declarations *- C++ -*-======//
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 defines the C++ Decl subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_DECLCXX_H
15#define LLVM_CLANG_AST_DECLCXX_H
16
17#include "clang/AST/Decl.h"
18
19namespace clang {
20class CXXRecordDecl;
21
22/// CXXFieldDecl - Represents an instance field of a C++ struct/union/class.
23class CXXFieldDecl : public FieldDecl {
24  CXXRecordDecl *Parent;
25
26  CXXFieldDecl(CXXRecordDecl *RD, SourceLocation L, IdentifierInfo *Id,
27               QualType T, Expr *BW = NULL)
28    : FieldDecl(CXXField, L, Id, T, BW), Parent(RD) {}
29public:
30  static CXXFieldDecl *Create(ASTContext &C, CXXRecordDecl *RD,SourceLocation L,
31                              IdentifierInfo *Id, QualType T, Expr *BW = NULL);
32
33  void setAccess(AccessSpecifier AS) { Access = AS; }
34  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
35  CXXRecordDecl *getParent() const { return Parent; }
36
37  // Implement isa/cast/dyncast/etc.
38  static bool classof(const Decl *D) { return D->getKind() == CXXField; }
39  static bool classof(const CXXFieldDecl *D) { return true; }
40};
41
42/// CXXRecordDecl - Represents a C++ struct/union/class.
43/// The only difference with RecordDecl is that CXXRecordDecl is a DeclContext.
44class CXXRecordDecl : public RecordDecl, public DeclContext {
45protected:
46  CXXRecordDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
47             ScopedDecl *PrevDecl) : RecordDecl(DK, DC, L, Id, PrevDecl),
48                                     DeclContext(DK) {
49    assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
50  }
51public:
52  static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
53                            SourceLocation L, IdentifierInfo *Id,
54                            ScopedDecl *PrevDecl);
55
56  const CXXFieldDecl *getMember(unsigned i) const {
57    assert(isa<CXXFieldDecl>(RecordDecl::getMember(i)));
58    return static_cast<const CXXFieldDecl*>(RecordDecl::getMember(i));
59  }
60  CXXFieldDecl *getMember(unsigned i) {
61    assert(isa<CXXFieldDecl>(RecordDecl::getMember(i)));
62    return static_cast<CXXFieldDecl*>(RecordDecl::getMember(i));
63  }
64
65  /// getMember - If the member doesn't exist, or there are no members, this
66  /// function will return 0;
67  CXXFieldDecl *getMember(IdentifierInfo *name) {
68    return cast_or_null<CXXFieldDecl>(RecordDecl::getMember(name));
69  }
70
71  static bool classof(const Decl *D) {
72    return D->getKind() >= CXXRecordFirst && D->getKind() <= CXXRecordLast;
73  }
74  static bool classof(const CXXRecordDecl *D) { return true; }
75
76protected:
77  /// EmitImpl - Serialize this CXXRecordDecl.  Called by Decl::Emit.
78  // FIXME: Implement this.
79  //virtual void EmitImpl(llvm::Serializer& S) const;
80
81  /// CreateImpl - Deserialize a CXXRecordDecl.  Called by Decl::Create.
82  // FIXME: Implement this.
83  static CXXRecordDecl* CreateImpl(Kind DK, llvm::Deserializer& D, ASTContext& C);
84
85  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
86};
87
88/// CXXMethodDecl - Represents a static or instance method of a
89/// struct/union/class.
90class CXXMethodDecl : public FunctionDecl {
91
92  CXXMethodDecl(CXXRecordDecl *RD, SourceLocation L,
93               IdentifierInfo *Id, QualType T,
94               bool isStatic, bool isInline, ScopedDecl *PrevDecl)
95    : FunctionDecl(CXXMethod, RD, L, Id, T, (isStatic ? Static : None),
96                   isInline, PrevDecl) {}
97public:
98  static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
99                              SourceLocation L, IdentifierInfo *Id,
100                              QualType T, bool isStatic = false,
101                              bool isInline = false,  ScopedDecl *PrevDecl = 0);
102
103  bool isStatic() const { return getStorageClass() == Static; }
104  bool isInstance() const { return !isStatic(); }
105
106  void setAccess(AccessSpecifier AS) { Access = AS; }
107  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
108
109  /// getThisType - Returns the type of 'this' pointer.
110  /// Should only be called for instance methods.
111  QualType getThisType(ASTContext &C) const;
112
113  // Implement isa/cast/dyncast/etc.
114  static bool classof(const Decl *D) { return D->getKind() == CXXMethod; }
115  static bool classof(const CXXMethodDecl *D) { return true; }
116
117protected:
118  /// EmitImpl - Serialize this CXXMethodDecl.  Called by Decl::Emit.
119  // FIXME: Implement this.
120  //virtual void EmitImpl(llvm::Serializer& S) const;
121
122  /// CreateImpl - Deserialize a CXXMethodDecl.  Called by Decl::Create.
123  // FIXME: Implement this.
124  static CXXMethodDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
125
126  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
127};
128
129/// CXXClassVarDecl - Represents a static data member of a struct/union/class.
130class CXXClassVarDecl : public VarDecl {
131
132  CXXClassVarDecl(CXXRecordDecl *RD, SourceLocation L,
133              IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl)
134    : VarDecl(CXXClassVar, RD, L, Id, T, None, PrevDecl) {}
135public:
136  static CXXClassVarDecl *Create(ASTContext &C, CXXRecordDecl *RD,
137                             SourceLocation L,IdentifierInfo *Id,
138                             QualType T, ScopedDecl *PrevDecl);
139
140  void setAccess(AccessSpecifier AS) { Access = AS; }
141  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
142
143  // Implement isa/cast/dyncast/etc.
144  static bool classof(const Decl *D) { return D->getKind() == CXXClassVar; }
145  static bool classof(const CXXClassVarDecl *D) { return true; }
146
147protected:
148  /// EmitImpl - Serialize this CXXClassVarDecl. Called by Decl::Emit.
149  // FIXME: Implement this.
150  //virtual void EmitImpl(llvm::Serializer& S) const;
151
152  /// CreateImpl - Deserialize a CXXClassVarDecl.  Called by Decl::Create.
153  // FIXME: Implement this.
154  static CXXClassVarDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
155
156  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
157};
158
159
160/// CXXClassMemberWrapper - A wrapper class for C++ class member decls.
161/// Common functions like set/getAccess are included here to avoid bloating
162/// the interface of non-C++ specific decl classes, like NamedDecl.
163class CXXClassMemberWrapper {
164  Decl *MD;
165
166public:
167  CXXClassMemberWrapper(Decl *D) : MD(D) {
168    assert(isMember(D) && "Not a C++ class member!");
169  }
170
171  AccessSpecifier getAccess() const {
172    return AccessSpecifier(MD->Access);
173  }
174
175  void setAccess(AccessSpecifier AS) {
176    assert(AS != AS_none && "Access must be specified.");
177    MD->Access = AS;
178  }
179
180  CXXRecordDecl *getParent() const {
181    if (ScopedDecl *SD = dyn_cast<ScopedDecl>(MD)) {
182      return cast<CXXRecordDecl>(SD->getDeclContext());
183    }
184    return cast<CXXFieldDecl>(MD)->getParent();
185  }
186
187  static bool isMember(Decl *D) {
188    if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
189      return isa<CXXRecordDecl>(SD->getDeclContext());
190    }
191    return isa<CXXFieldDecl>(D);
192  }
193};
194
195} // end namespace clang
196
197#endif
198