Line data Source code
1 : //===--- StmtCXX.h - Classes for representing C++ statements ----*- 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++ statement AST node classes.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_CLANG_AST_STMTCXX_H
15 : #define LLVM_CLANG_AST_STMTCXX_H
16 :
17 : #include "clang/AST/DeclarationName.h"
18 : #include "clang/AST/Expr.h"
19 : #include "clang/AST/NestedNameSpecifier.h"
20 : #include "clang/AST/Stmt.h"
21 : #include "llvm/Support/Compiler.h"
22 :
23 : namespace clang {
24 :
25 : class VarDecl;
26 :
27 : /// CXXCatchStmt - This represents a C++ catch block.
28 : ///
29 : class CXXCatchStmt : public Stmt {
30 : SourceLocation CatchLoc;
31 : /// The exception-declaration of the type.
32 : VarDecl *ExceptionDecl;
33 : /// The handler block.
34 : Stmt *HandlerBlock;
35 :
36 : public:
37 : CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
38 : : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
39 : HandlerBlock(handlerBlock) {}
40 :
41 : CXXCatchStmt(EmptyShell Empty)
42 : : Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
43 :
44 : SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; }
45 : SourceLocation getLocEnd() const LLVM_READONLY {
46 : return HandlerBlock->getLocEnd();
47 : }
48 :
49 : SourceLocation getCatchLoc() const { return CatchLoc; }
50 0 : VarDecl *getExceptionDecl() const { return ExceptionDecl; }
51 : QualType getCaughtType() const;
52 : Stmt *getHandlerBlock() const { return HandlerBlock; }
53 :
54 : static bool classof(const Stmt *T) {
55 : return T->getStmtClass() == CXXCatchStmtClass;
56 : }
57 :
58 0 : child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
59 :
60 : friend class ASTStmtReader;
61 : };
62 :
63 : /// CXXTryStmt - A C++ try block, including all handlers.
64 : ///
65 : class CXXTryStmt : public Stmt {
66 : SourceLocation TryLoc;
67 : unsigned NumHandlers;
68 :
69 : CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers);
70 :
71 : CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
72 : : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
73 :
74 : Stmt const * const *getStmts() const {
75 : return reinterpret_cast<Stmt const * const*>(this + 1);
76 : }
77 : Stmt **getStmts() {
78 0 : return reinterpret_cast<Stmt **>(this + 1);
79 : }
80 :
81 : public:
82 : static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc,
83 : Stmt *tryBlock, ArrayRef<Stmt*> handlers);
84 :
85 : static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
86 : unsigned numHandlers);
87 :
88 : SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
89 : SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
90 :
91 : SourceLocation getTryLoc() const { return TryLoc; }
92 : SourceLocation getEndLoc() const {
93 : return getStmts()[NumHandlers]->getLocEnd();
94 : }
95 :
96 : CompoundStmt *getTryBlock() {
97 : return cast<CompoundStmt>(getStmts()[0]);
98 : }
99 : const CompoundStmt *getTryBlock() const {
100 : return cast<CompoundStmt>(getStmts()[0]);
101 : }
102 :
103 0 : unsigned getNumHandlers() const { return NumHandlers; }
104 : CXXCatchStmt *getHandler(unsigned i) {
105 : return cast<CXXCatchStmt>(getStmts()[i + 1]);
106 : }
107 : const CXXCatchStmt *getHandler(unsigned i) const {
108 : return cast<CXXCatchStmt>(getStmts()[i + 1]);
109 : }
110 :
111 : static bool classof(const Stmt *T) {
112 : return T->getStmtClass() == CXXTryStmtClass;
113 : }
114 :
115 : child_range children() {
116 0 : return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
117 : }
118 :
119 : friend class ASTStmtReader;
120 : };
121 :
122 : /// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
123 : /// statement, represented as 'for (range-declarator : range-expression)'.
124 : ///
125 : /// This is stored in a partially-desugared form to allow full semantic
126 : /// analysis of the constituent components. The original syntactic components
127 : /// can be extracted using getLoopVariable and getRangeInit.
128 : class CXXForRangeStmt : public Stmt {
129 : SourceLocation ForLoc;
130 : enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END };
131 : // SubExprs[RANGE] is an expression or declstmt.
132 : // SubExprs[COND] and SubExprs[INC] are expressions.
133 : Stmt *SubExprs[END];
134 : SourceLocation ColonLoc;
135 : SourceLocation RParenLoc;
136 : public:
137 : CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd,
138 : Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
139 : SourceLocation FL, SourceLocation CL, SourceLocation RPL);
140 : CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
141 :
142 :
143 : VarDecl *getLoopVariable();
144 : Expr *getRangeInit();
145 :
146 : const VarDecl *getLoopVariable() const;
147 : const Expr *getRangeInit() const;
148 :
149 :
150 : DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
151 : DeclStmt *getBeginEndStmt() {
152 : return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
153 : }
154 : Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
155 : Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
156 0 : DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
157 0 : Stmt *getBody() { return SubExprs[BODY]; }
158 :
159 : const DeclStmt *getRangeStmt() const {
160 : return cast<DeclStmt>(SubExprs[RANGE]);
161 : }
162 : const DeclStmt *getBeginEndStmt() const {
163 : return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
164 : }
165 : const Expr *getCond() const {
166 : return cast_or_null<Expr>(SubExprs[COND]);
167 : }
168 : const Expr *getInc() const {
169 : return cast_or_null<Expr>(SubExprs[INC]);
170 : }
171 : const DeclStmt *getLoopVarStmt() const {
172 : return cast<DeclStmt>(SubExprs[LOOPVAR]);
173 : }
174 : const Stmt *getBody() const { return SubExprs[BODY]; }
175 :
176 : void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
177 : void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
178 : void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; }
179 : void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
180 : void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
181 : void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
182 : void setBody(Stmt *S) { SubExprs[BODY] = S; }
183 :
184 :
185 : SourceLocation getForLoc() const { return ForLoc; }
186 : void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
187 : SourceLocation getColonLoc() const { return ColonLoc; }
188 : void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
189 : SourceLocation getRParenLoc() const { return RParenLoc; }
190 : void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
191 :
192 : SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
193 : SourceLocation getLocEnd() const LLVM_READONLY {
194 : return SubExprs[BODY]->getLocEnd();
195 : }
196 :
197 : static bool classof(const Stmt *T) {
198 : return T->getStmtClass() == CXXForRangeStmtClass;
199 : }
200 :
201 : // Iterators
202 : child_range children() {
203 0 : return child_range(&SubExprs[0], &SubExprs[END]);
204 : }
205 : };
206 :
207 : /// \brief Representation of a Microsoft __if_exists or __if_not_exists
208 : /// statement with a dependent name.
209 : ///
210 : /// The __if_exists statement can be used to include a sequence of statements
211 : /// in the program only when a particular dependent name does not exist. For
212 : /// example:
213 : ///
214 : /// \code
215 : /// template<typename T>
216 : /// void call_foo(T &t) {
217 : /// __if_exists (T::foo) {
218 : /// t.foo(); // okay: only called when T::foo exists.
219 : /// }
220 : /// }
221 : /// \endcode
222 : ///
223 : /// Similarly, the __if_not_exists statement can be used to include the
224 : /// statements when a particular name does not exist.
225 : ///
226 : /// Note that this statement only captures __if_exists and __if_not_exists
227 : /// statements whose name is dependent. All non-dependent cases are handled
228 : /// directly in the parser, so that they don't introduce a new scope. Clang
229 : /// introduces scopes in the dependent case to keep names inside the compound
230 : /// statement from leaking out into the surround statements, which would
231 : /// compromise the template instantiation model. This behavior differs from
232 : /// Visual C++ (which never introduces a scope), but is a fairly reasonable
233 : /// approximation of the VC++ behavior.
234 : class MSDependentExistsStmt : public Stmt {
235 : SourceLocation KeywordLoc;
236 : bool IsIfExists;
237 : NestedNameSpecifierLoc QualifierLoc;
238 : DeclarationNameInfo NameInfo;
239 : Stmt *SubStmt;
240 :
241 : friend class ASTReader;
242 : friend class ASTStmtReader;
243 :
244 : public:
245 : MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists,
246 : NestedNameSpecifierLoc QualifierLoc,
247 : DeclarationNameInfo NameInfo,
248 : CompoundStmt *SubStmt)
249 : : Stmt(MSDependentExistsStmtClass),
250 : KeywordLoc(KeywordLoc), IsIfExists(IsIfExists),
251 : QualifierLoc(QualifierLoc), NameInfo(NameInfo),
252 : SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { }
253 :
254 : /// \brief Retrieve the location of the __if_exists or __if_not_exists
255 : /// keyword.
256 : SourceLocation getKeywordLoc() const { return KeywordLoc; }
257 :
258 : /// \brief Determine whether this is an __if_exists statement.
259 : bool isIfExists() const { return IsIfExists; }
260 :
261 : /// \brief Determine whether this is an __if_exists statement.
262 : bool isIfNotExists() const { return !IsIfExists; }
263 :
264 : /// \brief Retrieve the nested-name-specifier that qualifies this name, if
265 : /// any.
266 0 : NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
267 :
268 : /// \brief Retrieve the name of the entity we're testing for, along with
269 : /// location information
270 0 : DeclarationNameInfo getNameInfo() const { return NameInfo; }
271 :
272 : /// \brief Retrieve the compound statement that will be included in the
273 : /// program only if the existence of the symbol matches the initial keyword.
274 : CompoundStmt *getSubStmt() const {
275 : return reinterpret_cast<CompoundStmt *>(SubStmt);
276 : }
277 :
278 : SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
279 : SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
280 :
281 : child_range children() {
282 0 : return child_range(&SubStmt, &SubStmt+1);
283 : }
284 :
285 : static bool classof(const Stmt *T) {
286 : return T->getStmtClass() == MSDependentExistsStmtClass;
287 : }
288 : };
289 :
290 : } // end namespace clang
291 :
292 : #endif
|