summaryrefslogtreecommitdiff
path: root/include/clang/AST/Stmt.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/Stmt.h')
-rw-r--r--include/clang/AST/Stmt.h359
1 files changed, 303 insertions, 56 deletions
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index ff5baa21adff5..403b88ac3a3c7 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -1,9 +1,8 @@
//===- Stmt.h - Classes for representing statements -------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -47,6 +46,7 @@ class Attr;
class CapturedDecl;
class Decl;
class Expr;
+class AddrLabelExpr;
class LabelDecl;
class ODRHash;
class PrinterHelper;
@@ -92,12 +92,20 @@ protected:
//===--- Statement bitfields classes ---===//
class StmtBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
friend class Stmt;
/// The statement class.
unsigned sClass : 8;
+
+ /// This bit is set only for the Stmts that are the structured-block of
+ /// OpenMP executable directives. Directives that have a structured block
+ /// are called "non-standalone" directives.
+ /// I.e. those returned by OMPExecutableDirective::getStructuredBlock().
+ unsigned IsOMPStructuredBlock : 1;
};
- enum { NumStmtBits = 8 };
+ enum { NumStmtBits = 9 };
class NullStmtBitfields {
friend class ASTStmtReader;
@@ -314,6 +322,33 @@ protected:
};
enum { NumExprBits = NumStmtBits + 9 };
+ class ConstantExprBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class ConstantExpr;
+
+ unsigned : NumExprBits;
+
+ /// The kind of result that is trail-allocated.
+ unsigned ResultKind : 2;
+
+ /// Kind of Result as defined by APValue::Kind
+ unsigned APValueKind : 4;
+
+ /// When ResultKind == RSK_Int64. whether the trail-allocated integer is
+ /// signed.
+ unsigned IsUnsigned : 1;
+
+ /// When ResultKind == RSK_Int64. the BitWidth of the trail-allocated
+ /// integer. 7 bits because it is the minimal number of bit to represent a
+ /// value from 0 to 64 (the size of the trail-allocated number).
+ unsigned BitWidth : 7;
+
+ /// When ResultKind == RSK_APValue. Wether the ASTContext will cleanup the
+ /// destructor on the trail-allocated APValue.
+ unsigned HasCleanup : 1;
+ };
+
class PredefinedExprBitfields {
friend class ASTStmtReader;
friend class PredefinedExpr;
@@ -343,19 +378,12 @@ protected:
unsigned HasFoundDecl : 1;
unsigned HadMultipleCandidates : 1;
unsigned RefersToEnclosingVariableOrCapture : 1;
+ unsigned NonOdrUseReason : 2;
/// The location of the declaration name itself.
SourceLocation Loc;
};
- enum APFloatSemantics {
- IEEEhalf,
- IEEEsingle,
- IEEEdouble,
- x87DoubleExtended,
- IEEEquad,
- PPCDoubleDouble
- };
class FloatingLiteralBitfields {
friend class FloatingLiteral;
@@ -445,6 +473,7 @@ protected:
enum { NumCallExprBits = 32 };
class MemberExprBitfields {
+ friend class ASTStmtReader;
friend class MemberExpr;
unsigned : NumExprBits;
@@ -469,6 +498,11 @@ protected:
/// was resolved from an overloaded set having size greater than 1.
unsigned HadMultipleCandidates : 1;
+ /// Value of type NonOdrUseReason indicating why this MemberExpr does
+ /// not constitute an odr-use of the named declaration. Meaningful only
+ /// when naming a static member.
+ unsigned NonOdrUseReason : 2;
+
/// This is the location of the -> or . in the expression.
SourceLocation OperatorLoc;
};
@@ -521,6 +555,16 @@ protected:
unsigned NumExprs;
};
+ class GenericSelectionExprBitfields {
+ friend class ASTStmtReader;
+ friend class GenericSelectionExpr;
+
+ unsigned : NumExprBits;
+
+ /// The location of the "_Generic".
+ SourceLocation GenericLoc;
+ };
+
class PseudoObjectExprBitfields {
friend class ASTStmtReader; // deserialization
friend class PseudoObjectExpr;
@@ -533,6 +577,17 @@ protected:
unsigned ResultIndex : 32 - 8 - NumExprBits;
};
+ class SourceLocExprBitfields {
+ friend class ASTStmtReader;
+ friend class SourceLocExpr;
+
+ unsigned : NumExprBits;
+
+ /// The kind of source location builtin represented by the SourceLocExpr.
+ /// Ex. __builtin_LINE, __builtin_FUNCTION, ect.
+ unsigned Kind : 2;
+ };
+
//===--- C++ Expression bitfields classes ---===//
class CXXOperatorCallExprBitfields {
@@ -902,6 +957,7 @@ protected:
// Expressions
ExprBitfields ExprBits;
+ ConstantExprBitfields ConstantExprBits;
PredefinedExprBitfields PredefinedExprBits;
DeclRefExprBitfields DeclRefExprBits;
FloatingLiteralBitfields FloatingLiteralBits;
@@ -916,7 +972,9 @@ protected:
BinaryOperatorBitfields BinaryOperatorBits;
InitListExprBitfields InitListExprBits;
ParenListExprBitfields ParenListExprBits;
+ GenericSelectionExprBitfields GenericSelectionExprBits;
PseudoObjectExprBitfields PseudoObjectExprBits;
+ SourceLocExprBitfields SourceLocExprBits;
// C++ Expressions
CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
@@ -976,38 +1034,31 @@ public:
struct EmptyShell {};
protected:
- /// Iterator for iterating over Stmt * arrays that contain only Expr *
+ /// Iterator for iterating over Stmt * arrays that contain only T *.
///
/// This is needed because AST nodes use Stmt* arrays to store
/// references to children (to be compatible with StmtIterator).
- struct ExprIterator
- : llvm::iterator_adaptor_base<ExprIterator, Stmt **,
- std::random_access_iterator_tag, Expr *> {
- ExprIterator() : iterator_adaptor_base(nullptr) {}
- ExprIterator(Stmt **I) : iterator_adaptor_base(I) {}
-
- reference operator*() const {
- assert((*I)->getStmtClass() >= firstExprConstant &&
- (*I)->getStmtClass() <= lastExprConstant);
- return *reinterpret_cast<Expr **>(I);
- }
- };
+ template<typename T, typename TPtr = T *, typename StmtPtr = Stmt *>
+ struct CastIterator
+ : llvm::iterator_adaptor_base<CastIterator<T, TPtr, StmtPtr>, StmtPtr *,
+ std::random_access_iterator_tag, TPtr> {
+ using Base = typename CastIterator::iterator_adaptor_base;
- /// Const iterator for iterating over Stmt * arrays that contain only Expr *
- struct ConstExprIterator
- : llvm::iterator_adaptor_base<ConstExprIterator, const Stmt *const *,
- std::random_access_iterator_tag,
- const Expr *const> {
- ConstExprIterator() : iterator_adaptor_base(nullptr) {}
- ConstExprIterator(const Stmt *const *I) : iterator_adaptor_base(I) {}
+ CastIterator() : Base(nullptr) {}
+ CastIterator(StmtPtr *I) : Base(I) {}
- reference operator*() const {
- assert((*I)->getStmtClass() >= firstExprConstant &&
- (*I)->getStmtClass() <= lastExprConstant);
- return *reinterpret_cast<const Expr *const *>(I);
+ typename Base::value_type operator*() const {
+ return cast_or_null<T>(*this->I);
}
};
+ /// Const iterator for iterating over Stmt * arrays that contain only T *.
+ template <typename T>
+ using ConstCastIterator = CastIterator<T, const T *const, const Stmt *const>;
+
+ using ExprIterator = CastIterator<Expr>;
+ using ConstExprIterator = ConstCastIterator<Expr>;
+
private:
/// Whether statistic collection is enabled.
static bool StatisticsEnabled;
@@ -1017,12 +1068,19 @@ protected:
explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {}
public:
+ Stmt() = delete;
+ Stmt(const Stmt &) = delete;
+ Stmt(Stmt &&) = delete;
+ Stmt &operator=(const Stmt &) = delete;
+ Stmt &operator=(Stmt &&) = delete;
+
Stmt(StmtClass SC) {
static_assert(sizeof(*this) <= 8,
"changing bitfields changed sizeof(Stmt)");
static_assert(sizeof(*this) % alignof(void *) == 0,
"Insufficient alignment!");
StmtBits.sClass = SC;
+ StmtBits.IsOMPStructuredBlock = false;
if (StatisticsEnabled) Stmt::addStmtClass(SC);
}
@@ -1032,6 +1090,11 @@ public:
const char *getStmtClassName() const;
+ bool isOMPStructuredBlock() const { return StmtBits.IsOMPStructuredBlock; }
+ void setIsOMPStructuredBlock(bool IsOMPStructuredBlock) {
+ StmtBits.IsOMPStructuredBlock = IsOMPStructuredBlock;
+ }
+
/// SourceLocation tokens are not useful in isolation - they are low level
/// value objects created/interpreted by SourceManager. We assume AST
/// clients will have a pointer to the respective SourceManager.
@@ -1065,17 +1128,14 @@ public:
StringRef NewlineSymbol = "\n",
const ASTContext *Context = nullptr) const;
+ /// Pretty-prints in JSON format.
+ void printJson(raw_ostream &Out, PrinterHelper *Helper,
+ const PrintingPolicy &Policy, bool AddQuotes) const;
+
/// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
/// works on systems with GraphViz (Mac OS X) or dot+gv installed.
void viewAST() const;
- /// Skip past any implicit AST nodes which might surround this
- /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
- Stmt *IgnoreImplicit();
- const Stmt *IgnoreImplicit() const {
- return const_cast<Stmt *>(this)->IgnoreImplicit();
- }
-
/// Skip no-op (attributed, compound) container stmts and skip captured
/// stmt at the top, if \a IgnoreCaptured is true.
Stmt *IgnoreContainers(bool IgnoreCaptured = false);
@@ -1178,6 +1238,11 @@ public:
child_iterator(DG.end(), DG.end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<DeclStmt *>(this)->children();
+ return const_child_range(Children);
+ }
+
using decl_iterator = DeclGroupRef::iterator;
using const_decl_iterator = DeclGroupRef::const_iterator;
using decl_range = llvm::iterator_range<decl_iterator>;
@@ -1235,6 +1300,10 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
};
/// CompoundStmt - This represents a group of statements like { stmt stmt }.
@@ -1280,11 +1349,6 @@ public:
return !body_empty() ? body_begin()[size() - 1] : nullptr;
}
- void setLastStmt(Stmt *S) {
- assert(!body_empty() && "setLastStmt");
- body_begin()[size() - 1] = S;
- }
-
using const_body_iterator = Stmt *const *;
using body_const_range = llvm::iterator_range<const_body_iterator>;
@@ -1327,6 +1391,26 @@ public:
return const_reverse_body_iterator(body_begin());
}
+ // Get the Stmt that StmtExpr would consider to be the result of this
+ // compound statement. This is used by StmtExpr to properly emulate the GCC
+ // compound expression extension, which ignores trailing NullStmts when
+ // getting the result of the expression.
+ // i.e. ({ 5;;; })
+ // ^^ ignored
+ // If we don't find something that isn't a NullStmt, just return the last
+ // Stmt.
+ Stmt *getStmtExprResult() {
+ for (auto *B : llvm::reverse(body())) {
+ if (!isa<NullStmt>(B))
+ return B;
+ }
+ return body_back();
+ }
+
+ const Stmt *getStmtExprResult() const {
+ return const_cast<CompoundStmt *>(this)->getStmtExprResult();
+ }
+
SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; }
SourceLocation getEndLoc() const { return RBraceLoc; }
@@ -1539,6 +1623,12 @@ public:
getTrailingObjects<Stmt *>() +
numTrailingObjects(OverloadToken<Stmt *>()));
}
+
+ const_child_range children() const {
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
+ }
};
class DefaultStmt : public SwitchCase {
@@ -1570,6 +1660,10 @@ public:
// Iterators
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&SubStmt, &SubStmt + 1);
+ }
};
SourceLocation SwitchCase::getEndLoc() const {
@@ -1588,21 +1682,44 @@ Stmt *SwitchCase::getSubStmt() {
llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!");
}
+/// Represents a statement that could possibly have a value and type. This
+/// covers expression-statements, as well as labels and attributed statements.
+///
+/// Value statements have a special meaning when they are the last non-null
+/// statement in a GNU statement expression, where they determine the value
+/// of the statement expression.
+class ValueStmt : public Stmt {
+protected:
+ using Stmt::Stmt;
+
+public:
+ const Expr *getExprStmt() const;
+ Expr *getExprStmt() {
+ const ValueStmt *ConstThis = this;
+ return const_cast<Expr*>(ConstThis->getExprStmt());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() >= firstValueStmtConstant &&
+ T->getStmtClass() <= lastValueStmtConstant;
+ }
+};
+
/// LabelStmt - Represents a label, which has a substatement. For example:
/// foo: return;
-class LabelStmt : public Stmt {
+class LabelStmt : public ValueStmt {
LabelDecl *TheDecl;
Stmt *SubStmt;
public:
/// Build a label statement.
LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
- : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) {
+ : ValueStmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) {
setIdentLoc(IL);
}
/// Build an empty label statement.
- explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) {}
+ explicit LabelStmt(EmptyShell Empty) : ValueStmt(LabelStmtClass, Empty) {}
SourceLocation getIdentLoc() const { return LabelStmtBits.IdentLoc; }
void setIdentLoc(SourceLocation L) { LabelStmtBits.IdentLoc = L; }
@@ -1621,6 +1738,10 @@ public:
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
+ const_child_range children() const {
+ return const_child_range(&SubStmt, &SubStmt + 1);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == LabelStmtClass;
}
@@ -1631,7 +1752,7 @@ public:
/// Represents an attribute applied to a statement. For example:
/// [[omp::for(...)]] for (...) { ... }
class AttributedStmt final
- : public Stmt,
+ : public ValueStmt,
private llvm::TrailingObjects<AttributedStmt, const Attr *> {
friend class ASTStmtReader;
friend TrailingObjects;
@@ -1640,14 +1761,14 @@ class AttributedStmt final
AttributedStmt(SourceLocation Loc, ArrayRef<const Attr *> Attrs,
Stmt *SubStmt)
- : Stmt(AttributedStmtClass), SubStmt(SubStmt) {
+ : ValueStmt(AttributedStmtClass), SubStmt(SubStmt) {
AttributedStmtBits.NumAttrs = Attrs.size();
AttributedStmtBits.AttrLoc = Loc;
std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr());
}
explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
- : Stmt(AttributedStmtClass, Empty) {
+ : ValueStmt(AttributedStmtClass, Empty) {
AttributedStmtBits.NumAttrs = NumAttrs;
AttributedStmtBits.AttrLoc = SourceLocation{};
std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr);
@@ -1678,6 +1799,10 @@ public:
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
+ const_child_range children() const {
+ return const_child_range(&SubStmt, &SubStmt + 1);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == AttributedStmtClass;
}
@@ -1877,6 +2002,12 @@ public:
numTrailingObjects(OverloadToken<Stmt *>()));
}
+ const_child_range children() const {
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == IfStmtClass;
}
@@ -2054,6 +2185,12 @@ public:
numTrailingObjects(OverloadToken<Stmt *>()));
}
+ const_child_range children() const {
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == SwitchStmtClass;
}
@@ -2179,6 +2316,12 @@ public:
getTrailingObjects<Stmt *>() +
numTrailingObjects(OverloadToken<Stmt *>()));
}
+
+ const_child_range children() const {
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
+ }
};
/// DoStmt - This represents a 'do/while' stmt.
@@ -2229,6 +2372,10 @@ public:
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
}
+
+ const_child_range children() const {
+ return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
+ }
};
/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
@@ -2298,6 +2445,10 @@ public:
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
}
+
+ const_child_range children() const {
+ return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
+ }
};
/// GotoStmt - This represents a direct goto.
@@ -2333,6 +2484,10 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
};
/// IndirectGotoStmt - This represents an indirect goto.
@@ -2378,6 +2533,10 @@ public:
// Iterators
child_range children() { return child_range(&Target, &Target + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&Target, &Target + 1);
+ }
};
/// ContinueStmt - This represents a continue.
@@ -2404,6 +2563,10 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
};
/// BreakStmt - This represents a break.
@@ -2430,6 +2593,10 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
};
/// ReturnStmt - This represents a return, optionally of an expression:
@@ -2514,6 +2681,12 @@ public:
return child_range(&RetExpr, &RetExpr + 1);
return child_range(child_iterator(), child_iterator());
}
+
+ const_child_range children() const {
+ if (RetExpr)
+ return const_child_range(&RetExpr, &RetExpr + 1);
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
};
/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
@@ -2669,6 +2842,10 @@ public:
child_range children() {
return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
}
+
+ const_child_range children() const {
+ return const_child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
+ }
};
/// This represents a GCC inline-assembly statement extension.
@@ -2682,13 +2859,15 @@ class GCCAsmStmt : public AsmStmt {
StringLiteral **Constraints = nullptr;
StringLiteral **Clobbers = nullptr;
IdentifierInfo **Names = nullptr;
+ unsigned NumLabels = 0;
public:
GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
bool isvolatile, unsigned numoutputs, unsigned numinputs,
IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
StringLiteral *asmstr, unsigned numclobbers,
- StringLiteral **clobbers, SourceLocation rparenloc);
+ StringLiteral **clobbers, unsigned numlabels,
+ SourceLocation rparenloc);
/// Build an empty inline-assembly statement.
explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {}
@@ -2813,6 +2992,51 @@ public:
return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
}
+ //===--- Labels ---===//
+
+ bool isAsmGoto() const {
+ return NumLabels > 0;
+ }
+
+ unsigned getNumLabels() const {
+ return NumLabels;
+ }
+
+ IdentifierInfo *getLabelIdentifier(unsigned i) const {
+ return Names[i + NumInputs];
+ }
+
+ AddrLabelExpr *getLabelExpr(unsigned i) const;
+ StringRef getLabelName(unsigned i) const;
+ using labels_iterator = CastIterator<AddrLabelExpr>;
+ using const_labels_iterator = ConstCastIterator<AddrLabelExpr>;
+ using labels_range = llvm::iterator_range<labels_iterator>;
+ using labels_const_range = llvm::iterator_range<const_labels_iterator>;
+
+ labels_iterator begin_labels() {
+ return &Exprs[0] + NumInputs;
+ }
+
+ labels_iterator end_labels() {
+ return &Exprs[0] + NumInputs + NumLabels;
+ }
+
+ labels_range labels() {
+ return labels_range(begin_labels(), end_labels());
+ }
+
+ const_labels_iterator begin_labels() const {
+ return &Exprs[0] + NumInputs;
+ }
+
+ const_labels_iterator end_labels() const {
+ return &Exprs[0] + NumInputs + NumLabels;
+ }
+
+ labels_const_range labels() const {
+ return labels_const_range(begin_labels(), end_labels());
+ }
+
private:
void setOutputsAndInputsAndClobbers(const ASTContext &C,
IdentifierInfo **Names,
@@ -2820,6 +3044,7 @@ private:
Stmt **Exprs,
unsigned NumOutputs,
unsigned NumInputs,
+ unsigned NumLabels,
StringLiteral **Clobbers,
unsigned NumClobbers);
@@ -2945,6 +3170,10 @@ public:
child_range children() {
return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
}
+
+ const_child_range children() const {
+ return const_child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
+ }
};
class SEHExceptStmt : public Stmt {
@@ -2982,6 +3211,10 @@ public:
return child_range(Children, Children+2);
}
+ const_child_range children() const {
+ return const_child_range(Children, Children + 2);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHExceptStmtClass;
}
@@ -3013,6 +3246,10 @@ public:
return child_range(&Block,&Block+1);
}
+ const_child_range children() const {
+ return const_child_range(&Block, &Block + 1);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHFinallyStmtClass;
}
@@ -3061,6 +3298,10 @@ public:
return child_range(Children, Children+2);
}
+ const_child_range children() const {
+ return const_child_range(Children, Children + 2);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHTryStmtClass;
}
@@ -3091,6 +3332,10 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
};
/// This captures a statement into a function. For example, the following
@@ -3311,6 +3556,8 @@ public:
}
child_range children();
+
+ const_child_range children() const;
};
} // namespace clang