1193326Sed//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines the Stmt interface and subclasses. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#ifndef LLVM_CLANG_AST_STMT_H 15193326Sed#define LLVM_CLANG_AST_STMT_H 16193326Sed 17249423Sdim#include "clang/AST/DeclGroup.h" 18249423Sdim#include "clang/AST/StmtIterator.h" 19251662Sdim#include "clang/Basic/CapturedStmt.h" 20249423Sdim#include "clang/Basic/IdentifierTable.h" 21226633Sdim#include "clang/Basic/LLVM.h" 22193326Sed#include "clang/Basic/SourceLocation.h" 23249423Sdim#include "llvm/ADT/ArrayRef.h" 24251662Sdim#include "llvm/ADT/PointerIntPair.h" 25234353Sdim#include "llvm/Support/Compiler.h" 26249423Sdim#include "llvm/Support/ErrorHandling.h" 27193326Sed#include <string> 28193326Sed 29198092Srdivackynamespace llvm { 30198092Srdivacky class FoldingSetNodeID; 31198092Srdivacky} 32198092Srdivacky 33193326Sednamespace clang { 34193326Sed class ASTContext; 35249423Sdim class Attr; 36251662Sdim class CapturedDecl; 37249423Sdim class Decl; 38193326Sed class Expr; 39249423Sdim class IdentifierInfo; 40249423Sdim class LabelDecl; 41193326Sed class ParmVarDecl; 42249423Sdim class PrinterHelper; 43249423Sdim struct PrintingPolicy; 44193326Sed class QualType; 45251662Sdim class RecordDecl; 46193326Sed class SourceManager; 47193326Sed class StringLiteral; 48193326Sed class SwitchStmt; 49249423Sdim class Token; 50239462Sdim class VarDecl; 51198092Srdivacky 52234353Sdim //===--------------------------------------------------------------------===// 53193326Sed // ExprIterator - Iterators for iterating over Stmt* arrays that contain 54193326Sed // only Expr*. This is needed because AST nodes use Stmt* arrays to store 55193326Sed // references to children (to be compatible with StmtIterator). 56234353Sdim //===--------------------------------------------------------------------===// 57198092Srdivacky 58193326Sed class Stmt; 59193326Sed class Expr; 60198092Srdivacky 61193326Sed class ExprIterator { 62193326Sed Stmt** I; 63193326Sed public: 64193326Sed ExprIterator(Stmt** i) : I(i) {} 65198092Srdivacky ExprIterator() : I(0) {} 66193326Sed ExprIterator& operator++() { ++I; return *this; } 67193326Sed ExprIterator operator-(size_t i) { return I-i; } 68193326Sed ExprIterator operator+(size_t i) { return I+i; } 69193326Sed Expr* operator[](size_t idx); 70193326Sed // FIXME: Verify that this will correctly return a signed distance. 71193326Sed signed operator-(const ExprIterator& R) const { return I - R.I; } 72193326Sed Expr* operator*() const; 73193326Sed Expr* operator->() const; 74193326Sed bool operator==(const ExprIterator& R) const { return I == R.I; } 75193326Sed bool operator!=(const ExprIterator& R) const { return I != R.I; } 76193326Sed bool operator>(const ExprIterator& R) const { return I > R.I; } 77193326Sed bool operator>=(const ExprIterator& R) const { return I >= R.I; } 78193326Sed }; 79198092Srdivacky 80193326Sed class ConstExprIterator { 81207619Srdivacky const Stmt * const *I; 82193326Sed public: 83207619Srdivacky ConstExprIterator(const Stmt * const *i) : I(i) {} 84198092Srdivacky ConstExprIterator() : I(0) {} 85193326Sed ConstExprIterator& operator++() { ++I; return *this; } 86207619Srdivacky ConstExprIterator operator+(size_t i) const { return I+i; } 87207619Srdivacky ConstExprIterator operator-(size_t i) const { return I-i; } 88193326Sed const Expr * operator[](size_t idx) const; 89193326Sed signed operator-(const ConstExprIterator& R) const { return I - R.I; } 90193326Sed const Expr * operator*() const; 91193326Sed const Expr * operator->() const; 92193326Sed bool operator==(const ConstExprIterator& R) const { return I == R.I; } 93193326Sed bool operator!=(const ConstExprIterator& R) const { return I != R.I; } 94193326Sed bool operator>(const ConstExprIterator& R) const { return I > R.I; } 95193326Sed bool operator>=(const ConstExprIterator& R) const { return I >= R.I; } 96198092Srdivacky }; 97198092Srdivacky 98193326Sed//===----------------------------------------------------------------------===// 99193326Sed// AST classes for statements. 100193326Sed//===----------------------------------------------------------------------===// 101198092Srdivacky 102193326Sed/// Stmt - This represents one statement. 103193326Sed/// 104193326Sedclass Stmt { 105193326Sedpublic: 106193326Sed enum StmtClass { 107193326Sed NoStmtClass = 0, 108193326Sed#define STMT(CLASS, PARENT) CLASS##Class, 109208600Srdivacky#define STMT_RANGE(BASE, FIRST, LAST) \ 110210299Sed first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class, 111208600Srdivacky#define LAST_STMT_RANGE(BASE, FIRST, LAST) \ 112210299Sed first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class 113208600Srdivacky#define ABSTRACT_STMT(STMT) 114208600Srdivacky#include "clang/AST/StmtNodes.inc" 115218893Sdim }; 116193326Sed 117193326Sed // Make vanilla 'new' and 'delete' illegal for Stmts. 118193326Sedprotected: 119193326Sed void* operator new(size_t bytes) throw() { 120226633Sdim llvm_unreachable("Stmts cannot be allocated with regular 'new'."); 121193326Sed } 122193326Sed void operator delete(void* data) throw() { 123226633Sdim llvm_unreachable("Stmts cannot be released with regular 'delete'."); 124193326Sed } 125198092Srdivacky 126218893Sdim class StmtBitfields { 127218893Sdim friend class Stmt; 128218893Sdim 129218893Sdim /// \brief The statement class. 130218893Sdim unsigned sClass : 8; 131218893Sdim }; 132218893Sdim enum { NumStmtBits = 8 }; 133218893Sdim 134218893Sdim class CompoundStmtBitfields { 135218893Sdim friend class CompoundStmt; 136218893Sdim unsigned : NumStmtBits; 137218893Sdim 138218893Sdim unsigned NumStmts : 32 - NumStmtBits; 139218893Sdim }; 140218893Sdim 141218893Sdim class ExprBitfields { 142218893Sdim friend class Expr; 143218893Sdim friend class DeclRefExpr; // computeDependence 144218893Sdim friend class InitListExpr; // ctor 145218893Sdim friend class DesignatedInitExpr; // ctor 146218893Sdim friend class BlockDeclRefExpr; // ctor 147218893Sdim friend class ASTStmtReader; // deserialization 148218893Sdim friend class CXXNewExpr; // ctor 149218893Sdim friend class DependentScopeDeclRefExpr; // ctor 150218893Sdim friend class CXXConstructExpr; // ctor 151218893Sdim friend class CallExpr; // ctor 152218893Sdim friend class OffsetOfExpr; // ctor 153218893Sdim friend class ObjCMessageExpr; // ctor 154234353Sdim friend class ObjCArrayLiteral; // ctor 155234353Sdim friend class ObjCDictionaryLiteral; // ctor 156218893Sdim friend class ShuffleVectorExpr; // ctor 157218893Sdim friend class ParenListExpr; // ctor 158218893Sdim friend class CXXUnresolvedConstructExpr; // ctor 159218893Sdim friend class CXXDependentScopeMemberExpr; // ctor 160218893Sdim friend class OverloadExpr; // ctor 161234353Sdim friend class PseudoObjectExpr; // ctor 162226633Sdim friend class AtomicExpr; // ctor 163218893Sdim unsigned : NumStmtBits; 164218893Sdim 165218893Sdim unsigned ValueKind : 2; 166218893Sdim unsigned ObjectKind : 2; 167218893Sdim unsigned TypeDependent : 1; 168218893Sdim unsigned ValueDependent : 1; 169224145Sdim unsigned InstantiationDependent : 1; 170218893Sdim unsigned ContainsUnexpandedParameterPack : 1; 171218893Sdim }; 172224145Sdim enum { NumExprBits = 16 }; 173218893Sdim 174234353Sdim class CharacterLiteralBitfields { 175234353Sdim friend class CharacterLiteral; 176234353Sdim unsigned : NumExprBits; 177234353Sdim 178234353Sdim unsigned Kind : 2; 179234353Sdim }; 180234353Sdim 181249423Sdim enum APFloatSemantics { 182249423Sdim IEEEhalf, 183249423Sdim IEEEsingle, 184249423Sdim IEEEdouble, 185249423Sdim x87DoubleExtended, 186249423Sdim IEEEquad, 187249423Sdim PPCDoubleDouble 188249423Sdim }; 189249423Sdim 190234353Sdim class FloatingLiteralBitfields { 191234353Sdim friend class FloatingLiteral; 192234353Sdim unsigned : NumExprBits; 193234353Sdim 194249423Sdim unsigned Semantics : 3; // Provides semantics for APFloat construction 195234353Sdim unsigned IsExact : 1; 196234353Sdim }; 197234353Sdim 198234353Sdim class UnaryExprOrTypeTraitExprBitfields { 199234353Sdim friend class UnaryExprOrTypeTraitExpr; 200234353Sdim unsigned : NumExprBits; 201234353Sdim 202234353Sdim unsigned Kind : 2; 203234353Sdim unsigned IsType : 1; // true if operand is a type, false if an expression. 204234353Sdim }; 205234353Sdim 206221345Sdim class DeclRefExprBitfields { 207221345Sdim friend class DeclRefExpr; 208221345Sdim friend class ASTStmtReader; // deserialization 209221345Sdim unsigned : NumExprBits; 210221345Sdim 211221345Sdim unsigned HasQualifier : 1; 212234353Sdim unsigned HasTemplateKWAndArgsInfo : 1; 213221345Sdim unsigned HasFoundDecl : 1; 214226633Sdim unsigned HadMultipleCandidates : 1; 215234353Sdim unsigned RefersToEnclosingLocal : 1; 216221345Sdim }; 217221345Sdim 218218893Sdim class CastExprBitfields { 219218893Sdim friend class CastExpr; 220218893Sdim unsigned : NumExprBits; 221218893Sdim 222218893Sdim unsigned Kind : 6; 223218893Sdim unsigned BasePathSize : 32 - 6 - NumExprBits; 224218893Sdim }; 225218893Sdim 226218893Sdim class CallExprBitfields { 227218893Sdim friend class CallExpr; 228218893Sdim unsigned : NumExprBits; 229218893Sdim 230218893Sdim unsigned NumPreArgs : 1; 231218893Sdim }; 232218893Sdim 233234353Sdim class ExprWithCleanupsBitfields { 234234353Sdim friend class ExprWithCleanups; 235234353Sdim friend class ASTStmtReader; // deserialization 236234353Sdim 237234353Sdim unsigned : NumExprBits; 238234353Sdim 239234353Sdim unsigned NumObjects : 32 - NumExprBits; 240234353Sdim }; 241234353Sdim 242234353Sdim class PseudoObjectExprBitfields { 243234353Sdim friend class PseudoObjectExpr; 244234353Sdim friend class ASTStmtReader; // deserialization 245234353Sdim 246234353Sdim unsigned : NumExprBits; 247234353Sdim 248234353Sdim // These don't need to be particularly wide, because they're 249234353Sdim // strictly limited by the forms of expressions we permit. 250234353Sdim unsigned NumSubExprs : 8; 251234353Sdim unsigned ResultIndex : 32 - 8 - NumExprBits; 252234353Sdim }; 253234353Sdim 254224145Sdim class ObjCIndirectCopyRestoreExprBitfields { 255224145Sdim friend class ObjCIndirectCopyRestoreExpr; 256224145Sdim unsigned : NumExprBits; 257224145Sdim 258224145Sdim unsigned ShouldCopy : 1; 259224145Sdim }; 260224145Sdim 261234353Sdim class InitListExprBitfields { 262234353Sdim friend class InitListExpr; 263234353Sdim 264234353Sdim unsigned : NumExprBits; 265234353Sdim 266234353Sdim /// Whether this initializer list originally had a GNU array-range 267234353Sdim /// designator in it. This is a temporary marker used by CodeGen. 268234353Sdim unsigned HadArrayRangeDesignator : 1; 269234353Sdim }; 270234353Sdim 271234353Sdim class TypeTraitExprBitfields { 272234353Sdim friend class TypeTraitExpr; 273234353Sdim friend class ASTStmtReader; 274234353Sdim friend class ASTStmtWriter; 275234353Sdim 276234353Sdim unsigned : NumExprBits; 277234353Sdim 278234353Sdim /// \brief The kind of type trait, which is a value of a TypeTrait enumerator. 279234353Sdim unsigned Kind : 8; 280234353Sdim 281234353Sdim /// \brief If this expression is not value-dependent, this indicates whether 282234353Sdim /// the trait evaluated true or false. 283234353Sdim unsigned Value : 1; 284234353Sdim 285234353Sdim /// \brief The number of arguments to this type trait. 286234353Sdim unsigned NumArgs : 32 - 8 - 1 - NumExprBits; 287234353Sdim }; 288263508Sdim 289218893Sdim union { 290218893Sdim // FIXME: this is wasteful on 64-bit platforms. 291218893Sdim void *Aligner; 292218893Sdim 293218893Sdim StmtBitfields StmtBits; 294218893Sdim CompoundStmtBitfields CompoundStmtBits; 295218893Sdim ExprBitfields ExprBits; 296234353Sdim CharacterLiteralBitfields CharacterLiteralBits; 297234353Sdim FloatingLiteralBitfields FloatingLiteralBits; 298234353Sdim UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits; 299221345Sdim DeclRefExprBitfields DeclRefExprBits; 300218893Sdim CastExprBitfields CastExprBits; 301218893Sdim CallExprBitfields CallExprBits; 302234353Sdim ExprWithCleanupsBitfields ExprWithCleanupsBits; 303234353Sdim PseudoObjectExprBitfields PseudoObjectExprBits; 304224145Sdim ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits; 305234353Sdim InitListExprBitfields InitListExprBits; 306234353Sdim TypeTraitExprBitfields TypeTraitExprBits; 307218893Sdim }; 308218893Sdim 309218893Sdim friend class ASTStmtReader; 310234353Sdim friend class ASTStmtWriter; 311218893Sdim 312193326Sedpublic: 313193326Sed // Only allow allocation of Stmts using the allocator in ASTContext 314198092Srdivacky // or by doing a placement new. 315263508Sdim void* operator new(size_t bytes, const ASTContext& C, 316263508Sdim unsigned alignment = 8); 317198092Srdivacky 318263508Sdim void* operator new(size_t bytes, const ASTContext* C, 319263508Sdim unsigned alignment = 8) { 320263508Sdim return operator new(bytes, *C, alignment); 321263508Sdim } 322198092Srdivacky 323193326Sed void* operator new(size_t bytes, void* mem) throw() { 324193326Sed return mem; 325193326Sed } 326193326Sed 327263508Sdim void operator delete(void*, const ASTContext&, unsigned) throw() { } 328263508Sdim void operator delete(void*, const ASTContext*, unsigned) throw() { } 329263508Sdim void operator delete(void*, size_t) throw() { } 330193326Sed void operator delete(void*, void*) throw() { } 331193326Sed 332193326Sedpublic: 333193326Sed /// \brief A placeholder type used to construct an empty shell of a 334193326Sed /// type, that will be filled in later (e.g., by some 335193326Sed /// de-serialization). 336193326Sed struct EmptyShell { }; 337193326Sed 338234353Sdimprivate: 339234353Sdim /// \brief Whether statistic collection is enabled. 340234353Sdim static bool StatisticsEnabled; 341234353Sdim 342193326Sedprotected: 343193326Sed /// \brief Construct an empty statement. 344218893Sdim explicit Stmt(StmtClass SC, EmptyShell) { 345218893Sdim StmtBits.sClass = SC; 346234353Sdim if (StatisticsEnabled) Stmt::addStmtClass(SC); 347193326Sed } 348193326Sed 349193326Sedpublic: 350218893Sdim Stmt(StmtClass SC) { 351218893Sdim StmtBits.sClass = SC; 352234353Sdim if (StatisticsEnabled) Stmt::addStmtClass(SC); 353193326Sed } 354193326Sed 355234353Sdim StmtClass getStmtClass() const { 356218893Sdim return static_cast<StmtClass>(StmtBits.sClass); 357198092Srdivacky } 358193326Sed const char *getStmtClassName() const; 359198092Srdivacky 360193326Sed /// SourceLocation tokens are not useful in isolation - they are low level 361193326Sed /// value objects created/interpreted by SourceManager. We assume AST 362193326Sed /// clients will have a pointer to the respective SourceManager. 363234353Sdim SourceRange getSourceRange() const LLVM_READONLY; 364234353Sdim SourceLocation getLocStart() const LLVM_READONLY; 365234353Sdim SourceLocation getLocEnd() const LLVM_READONLY; 366218893Sdim 367193326Sed // global temp stats (until we have a per-module visitor) 368193326Sed static void addStmtClass(const StmtClass s); 369234353Sdim static void EnableStatistics(); 370193326Sed static void PrintStats(); 371193326Sed 372249423Sdim /// \brief Dumps the specified AST fragment and all subtrees to 373249423Sdim /// \c llvm::errs(). 374234353Sdim LLVM_ATTRIBUTE_USED void dump() const; 375234353Sdim LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const; 376226633Sdim void dump(raw_ostream &OS, SourceManager &SM) const; 377193326Sed 378249423Sdim /// dumpColor - same as dump(), but forces color highlighting. 379249423Sdim LLVM_ATTRIBUTE_USED void dumpColor() const; 380193326Sed 381193326Sed /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 382193326Sed /// back to its original source language syntax. 383263508Sdim void dumpPretty(const ASTContext &Context) const; 384226633Sdim void printPretty(raw_ostream &OS, PrinterHelper *Helper, 385195341Sed const PrintingPolicy &Policy, 386193326Sed unsigned Indentation = 0) const; 387198092Srdivacky 388193326Sed /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only 389193326Sed /// works on systems with GraphViz (Mac OS X) or dot+gv installed. 390193326Sed void viewAST() const; 391198092Srdivacky 392224145Sdim /// Skip past any implicit AST nodes which might surround this 393224145Sdim /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes. 394224145Sdim Stmt *IgnoreImplicit(); 395224145Sdim 396226633Sdim const Stmt *stripLabelLikeStatements() const; 397226633Sdim Stmt *stripLabelLikeStatements() { 398226633Sdim return const_cast<Stmt*>( 399226633Sdim const_cast<const Stmt*>(this)->stripLabelLikeStatements()); 400226633Sdim } 401226633Sdim 402218893Sdim /// Child Iterators: All subclasses must implement 'children' 403218893Sdim /// to permit easy iteration over the substatements/subexpessions of an 404218893Sdim /// AST node. This permits easy iteration over all nodes in the AST. 405193326Sed typedef StmtIterator child_iterator; 406193326Sed typedef ConstStmtIterator const_child_iterator; 407198092Srdivacky 408218893Sdim typedef StmtRange child_range; 409218893Sdim typedef ConstStmtRange const_child_range; 410198092Srdivacky 411218893Sdim child_range children(); 412218893Sdim const_child_range children() const { 413218893Sdim return const_cast<Stmt*>(this)->children(); 414193326Sed } 415198092Srdivacky 416218893Sdim child_iterator child_begin() { return children().first; } 417218893Sdim child_iterator child_end() { return children().second; } 418198092Srdivacky 419218893Sdim const_child_iterator child_begin() const { return children().first; } 420218893Sdim const_child_iterator child_end() const { return children().second; } 421218893Sdim 422198092Srdivacky /// \brief Produce a unique representation of the given statement. 423198092Srdivacky /// 424243830Sdim /// \param ID once the profiling operation is complete, will contain 425198092Srdivacky /// the unique representation of the given statement. 426198092Srdivacky /// 427243830Sdim /// \param Context the AST context in which the statement resides 428198092Srdivacky /// 429243830Sdim /// \param Canonical whether the profile should be based on the canonical 430198092Srdivacky /// representation of this statement (e.g., where non-type template 431198092Srdivacky /// parameters are identified by index/level rather than their 432198092Srdivacky /// declaration pointers) or the exact representation of the statement as 433198092Srdivacky /// written in the source. 434218893Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 435224145Sdim bool Canonical) const; 436193326Sed}; 437193326Sed 438193326Sed/// DeclStmt - Adaptor class for mixing declarations with statements and 439193326Sed/// expressions. For example, CompoundStmt mixes statements, expressions 440198092Srdivacky/// and declarations (variables, types). Another example is ForStmt, where 441193326Sed/// the first statement can be an expression or a declaration. 442193326Sed/// 443193326Sedclass DeclStmt : public Stmt { 444193326Sed DeclGroupRef DG; 445193326Sed SourceLocation StartLoc, EndLoc; 446198092Srdivacky 447193326Sedpublic: 448198092Srdivacky DeclStmt(DeclGroupRef dg, SourceLocation startLoc, 449193326Sed SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg), 450193326Sed StartLoc(startLoc), EndLoc(endLoc) {} 451198092Srdivacky 452193326Sed /// \brief Build an empty declaration statement. 453193326Sed explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { } 454193326Sed 455193326Sed /// isSingleDecl - This method returns true if this DeclStmt refers 456193326Sed /// to a single Decl. 457193326Sed bool isSingleDecl() const { 458193326Sed return DG.isSingleDecl(); 459193326Sed } 460198092Srdivacky 461193326Sed const Decl *getSingleDecl() const { return DG.getSingleDecl(); } 462198092Srdivacky Decl *getSingleDecl() { return DG.getSingleDecl(); } 463198092Srdivacky 464193326Sed const DeclGroupRef getDeclGroup() const { return DG; } 465193326Sed DeclGroupRef getDeclGroup() { return DG; } 466193326Sed void setDeclGroup(DeclGroupRef DGR) { DG = DGR; } 467193326Sed 468193326Sed SourceLocation getStartLoc() const { return StartLoc; } 469193326Sed void setStartLoc(SourceLocation L) { StartLoc = L; } 470193326Sed SourceLocation getEndLoc() const { return EndLoc; } 471193326Sed void setEndLoc(SourceLocation L) { EndLoc = L; } 472193326Sed 473249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return StartLoc; } 474249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; } 475198092Srdivacky 476198092Srdivacky static bool classof(const Stmt *T) { 477198092Srdivacky return T->getStmtClass() == DeclStmtClass; 478193326Sed } 479198092Srdivacky 480193326Sed // Iterators over subexpressions. 481218893Sdim child_range children() { 482218893Sdim return child_range(child_iterator(DG.begin(), DG.end()), 483218893Sdim child_iterator(DG.end(), DG.end())); 484218893Sdim } 485198092Srdivacky 486193326Sed typedef DeclGroupRef::iterator decl_iterator; 487193326Sed typedef DeclGroupRef::const_iterator const_decl_iterator; 488198092Srdivacky 489193326Sed decl_iterator decl_begin() { return DG.begin(); } 490193326Sed decl_iterator decl_end() { return DG.end(); } 491193326Sed const_decl_iterator decl_begin() const { return DG.begin(); } 492193326Sed const_decl_iterator decl_end() const { return DG.end(); } 493239462Sdim 494239462Sdim typedef std::reverse_iterator<decl_iterator> reverse_decl_iterator; 495239462Sdim reverse_decl_iterator decl_rbegin() { 496239462Sdim return reverse_decl_iterator(decl_end()); 497239462Sdim } 498239462Sdim reverse_decl_iterator decl_rend() { 499239462Sdim return reverse_decl_iterator(decl_begin()); 500239462Sdim } 501193326Sed}; 502193326Sed 503193326Sed/// NullStmt - This is the null statement ";": C99 6.8.3p3. 504193326Sed/// 505193326Sedclass NullStmt : public Stmt { 506193326Sed SourceLocation SemiLoc; 507218893Sdim 508226633Sdim /// \brief True if the null statement was preceded by an empty macro, e.g: 509218893Sdim /// @code 510218893Sdim /// #define CALL(x) 511218893Sdim /// CALL(0); 512218893Sdim /// @endcode 513226633Sdim bool HasLeadingEmptyMacro; 514193326Sedpublic: 515226633Sdim NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false) 516226633Sdim : Stmt(NullStmtClass), SemiLoc(L), 517226633Sdim HasLeadingEmptyMacro(hasLeadingEmptyMacro) {} 518193326Sed 519193326Sed /// \brief Build an empty null statement. 520226633Sdim explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty), 521226633Sdim HasLeadingEmptyMacro(false) { } 522193326Sed 523193326Sed SourceLocation getSemiLoc() const { return SemiLoc; } 524193326Sed void setSemiLoc(SourceLocation L) { SemiLoc = L; } 525193326Sed 526226633Sdim bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; } 527198092Srdivacky 528249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return SemiLoc; } 529249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return SemiLoc; } 530218893Sdim 531198092Srdivacky static bool classof(const Stmt *T) { 532198092Srdivacky return T->getStmtClass() == NullStmtClass; 533193326Sed } 534198092Srdivacky 535218893Sdim child_range children() { return child_range(); } 536218893Sdim 537218893Sdim friend class ASTStmtReader; 538218893Sdim friend class ASTStmtWriter; 539193326Sed}; 540193326Sed 541193326Sed/// CompoundStmt - This represents a group of statements like { stmt stmt }. 542193326Sed/// 543193326Sedclass CompoundStmt : public Stmt { 544193326Sed Stmt** Body; 545193326Sed SourceLocation LBracLoc, RBracLoc; 546193326Sedpublic: 547263508Sdim CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts, 548239462Sdim SourceLocation LB, SourceLocation RB); 549218893Sdim 550263508Sdim // \brief Build an empty compound statement with a location. 551239462Sdim explicit CompoundStmt(SourceLocation Loc) 552239462Sdim : Stmt(CompoundStmtClass), Body(0), LBracLoc(Loc), RBracLoc(Loc) { 553239462Sdim CompoundStmtBits.NumStmts = 0; 554198092Srdivacky } 555193326Sed 556193326Sed // \brief Build an empty compound statement. 557193326Sed explicit CompoundStmt(EmptyShell Empty) 558218893Sdim : Stmt(CompoundStmtClass, Empty), Body(0) { 559218893Sdim CompoundStmtBits.NumStmts = 0; 560218893Sdim } 561193326Sed 562263508Sdim void setStmts(const ASTContext &C, Stmt **Stmts, unsigned NumStmts); 563198092Srdivacky 564218893Sdim bool body_empty() const { return CompoundStmtBits.NumStmts == 0; } 565218893Sdim unsigned size() const { return CompoundStmtBits.NumStmts; } 566193326Sed 567193326Sed typedef Stmt** body_iterator; 568193326Sed body_iterator body_begin() { return Body; } 569218893Sdim body_iterator body_end() { return Body + size(); } 570218893Sdim Stmt *body_back() { return !body_empty() ? Body[size()-1] : 0; } 571234353Sdim 572218893Sdim void setLastStmt(Stmt *S) { 573218893Sdim assert(!body_empty() && "setLastStmt"); 574218893Sdim Body[size()-1] = S; 575218893Sdim } 576193326Sed 577193326Sed typedef Stmt* const * const_body_iterator; 578193326Sed const_body_iterator body_begin() const { return Body; } 579218893Sdim const_body_iterator body_end() const { return Body + size(); } 580218893Sdim const Stmt *body_back() const { return !body_empty() ? Body[size()-1] : 0; } 581193326Sed 582193326Sed typedef std::reverse_iterator<body_iterator> reverse_body_iterator; 583193326Sed reverse_body_iterator body_rbegin() { 584193326Sed return reverse_body_iterator(body_end()); 585193326Sed } 586193326Sed reverse_body_iterator body_rend() { 587193326Sed return reverse_body_iterator(body_begin()); 588193326Sed } 589193326Sed 590193326Sed typedef std::reverse_iterator<const_body_iterator> 591193326Sed const_reverse_body_iterator; 592193326Sed 593193326Sed const_reverse_body_iterator body_rbegin() const { 594193326Sed return const_reverse_body_iterator(body_end()); 595193326Sed } 596198092Srdivacky 597193326Sed const_reverse_body_iterator body_rend() const { 598193326Sed return const_reverse_body_iterator(body_begin()); 599193326Sed } 600198092Srdivacky 601249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; } 602249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; } 603198092Srdivacky 604193326Sed SourceLocation getLBracLoc() const { return LBracLoc; } 605193326Sed void setLBracLoc(SourceLocation L) { LBracLoc = L; } 606193326Sed SourceLocation getRBracLoc() const { return RBracLoc; } 607193326Sed void setRBracLoc(SourceLocation L) { RBracLoc = L; } 608198092Srdivacky 609198092Srdivacky static bool classof(const Stmt *T) { 610198092Srdivacky return T->getStmtClass() == CompoundStmtClass; 611193326Sed } 612198092Srdivacky 613193326Sed // Iterators 614218893Sdim child_range children() { 615218893Sdim return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts); 616218893Sdim } 617234353Sdim 618226633Sdim const_child_range children() const { 619226633Sdim return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts); 620226633Sdim } 621193326Sed}; 622193326Sed 623193326Sed// SwitchCase is the base class for CaseStmt and DefaultStmt, 624193326Sedclass SwitchCase : public Stmt { 625193326Sedprotected: 626193326Sed // A pointer to the following CaseStmt or DefaultStmt class, 627193326Sed // used by SwitchStmt. 628193326Sed SwitchCase *NextSwitchCase; 629249423Sdim SourceLocation KeywordLoc; 630249423Sdim SourceLocation ColonLoc; 631193326Sed 632249423Sdim SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc) 633249423Sdim : Stmt(SC), NextSwitchCase(0), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {} 634198092Srdivacky 635249423Sdim SwitchCase(StmtClass SC, EmptyShell) 636249423Sdim : Stmt(SC), NextSwitchCase(0) {} 637249423Sdim 638193326Sedpublic: 639193326Sed const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 640193326Sed 641193326Sed SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 642193326Sed 643193326Sed void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 644193326Sed 645249423Sdim SourceLocation getKeywordLoc() const { return KeywordLoc; } 646249423Sdim void setKeywordLoc(SourceLocation L) { KeywordLoc = L; } 647249423Sdim SourceLocation getColonLoc() const { return ColonLoc; } 648249423Sdim void setColonLoc(SourceLocation L) { ColonLoc = L; } 649249423Sdim 650218893Sdim Stmt *getSubStmt(); 651221345Sdim const Stmt *getSubStmt() const { 652221345Sdim return const_cast<SwitchCase*>(this)->getSubStmt(); 653221345Sdim } 654193326Sed 655249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } 656249423Sdim SourceLocation getLocEnd() const LLVM_READONLY; 657198092Srdivacky 658198092Srdivacky static bool classof(const Stmt *T) { 659198092Srdivacky return T->getStmtClass() == CaseStmtClass || 660218893Sdim T->getStmtClass() == DefaultStmtClass; 661193326Sed } 662193326Sed}; 663193326Sed 664193326Sedclass CaseStmt : public SwitchCase { 665221345Sdim enum { LHS, RHS, SUBSTMT, END_EXPR }; 666198092Srdivacky Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 667193326Sed // GNU "case 1 ... 4" extension 668193326Sed SourceLocation EllipsisLoc; 669193326Sedpublic: 670193326Sed CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc, 671198092Srdivacky SourceLocation ellipsisLoc, SourceLocation colonLoc) 672249423Sdim : SwitchCase(CaseStmtClass, caseLoc, colonLoc) { 673193326Sed SubExprs[SUBSTMT] = 0; 674193326Sed SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 675193326Sed SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 676193326Sed EllipsisLoc = ellipsisLoc; 677193326Sed } 678193326Sed 679193326Sed /// \brief Build an empty switch case statement. 680249423Sdim explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) { } 681193326Sed 682249423Sdim SourceLocation getCaseLoc() const { return KeywordLoc; } 683249423Sdim void setCaseLoc(SourceLocation L) { KeywordLoc = L; } 684193326Sed SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 685193326Sed void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; } 686193326Sed SourceLocation getColonLoc() const { return ColonLoc; } 687193326Sed void setColonLoc(SourceLocation L) { ColonLoc = L; } 688193326Sed 689193326Sed Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 690193326Sed Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 691193326Sed Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 692193326Sed 693198092Srdivacky const Expr *getLHS() const { 694198092Srdivacky return reinterpret_cast<const Expr*>(SubExprs[LHS]); 695193326Sed } 696198092Srdivacky const Expr *getRHS() const { 697198092Srdivacky return reinterpret_cast<const Expr*>(SubExprs[RHS]); 698193326Sed } 699193326Sed const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 700193326Sed 701193326Sed void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; } 702193326Sed void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); } 703193326Sed void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); } 704198092Srdivacky 705249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } 706249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { 707193326Sed // Handle deeply nested case statements with iteration instead of recursion. 708193326Sed const CaseStmt *CS = this; 709193326Sed while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt())) 710193326Sed CS = CS2; 711198092Srdivacky 712249423Sdim return CS->getSubStmt()->getLocEnd(); 713193326Sed } 714249423Sdim 715198092Srdivacky static bool classof(const Stmt *T) { 716198092Srdivacky return T->getStmtClass() == CaseStmtClass; 717193326Sed } 718198092Srdivacky 719193326Sed // Iterators 720218893Sdim child_range children() { 721218893Sdim return child_range(&SubExprs[0], &SubExprs[END_EXPR]); 722218893Sdim } 723193326Sed}; 724193326Sed 725193326Sedclass DefaultStmt : public SwitchCase { 726193326Sed Stmt* SubStmt; 727193326Sedpublic: 728198092Srdivacky DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) : 729249423Sdim SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {} 730193326Sed 731193326Sed /// \brief Build an empty default statement. 732249423Sdim explicit DefaultStmt(EmptyShell Empty) 733249423Sdim : SwitchCase(DefaultStmtClass, Empty) { } 734193326Sed 735193326Sed Stmt *getSubStmt() { return SubStmt; } 736193326Sed const Stmt *getSubStmt() const { return SubStmt; } 737193326Sed void setSubStmt(Stmt *S) { SubStmt = S; } 738193326Sed 739249423Sdim SourceLocation getDefaultLoc() const { return KeywordLoc; } 740249423Sdim void setDefaultLoc(SourceLocation L) { KeywordLoc = L; } 741193326Sed SourceLocation getColonLoc() const { return ColonLoc; } 742193326Sed void setColonLoc(SourceLocation L) { ColonLoc = L; } 743193326Sed 744249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } 745249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} 746249423Sdim 747198092Srdivacky static bool classof(const Stmt *T) { 748198092Srdivacky return T->getStmtClass() == DefaultStmtClass; 749193326Sed } 750198092Srdivacky 751193326Sed // Iterators 752218893Sdim child_range children() { return child_range(&SubStmt, &SubStmt+1); } 753193326Sed}; 754193326Sed 755249423Sdiminline SourceLocation SwitchCase::getLocEnd() const { 756249423Sdim if (const CaseStmt *CS = dyn_cast<CaseStmt>(this)) 757249423Sdim return CS->getLocEnd(); 758249423Sdim return cast<DefaultStmt>(this)->getLocEnd(); 759249423Sdim} 760234353Sdim 761218893Sdim/// LabelStmt - Represents a label, which has a substatement. For example: 762218893Sdim/// foo: return; 763218893Sdim/// 764193326Sedclass LabelStmt : public Stmt { 765218893Sdim LabelDecl *TheDecl; 766193326Sed Stmt *SubStmt; 767193326Sed SourceLocation IdentLoc; 768193326Sedpublic: 769218893Sdim LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt) 770218893Sdim : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt), IdentLoc(IL) { 771218893Sdim } 772193326Sed 773193326Sed // \brief Build an empty label statement. 774193326Sed explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { } 775198092Srdivacky 776193326Sed SourceLocation getIdentLoc() const { return IdentLoc; } 777218893Sdim LabelDecl *getDecl() const { return TheDecl; } 778218893Sdim void setDecl(LabelDecl *D) { TheDecl = D; } 779193326Sed const char *getName() const; 780193326Sed Stmt *getSubStmt() { return SubStmt; } 781193326Sed const Stmt *getSubStmt() const { return SubStmt; } 782193326Sed void setIdentLoc(SourceLocation L) { IdentLoc = L; } 783193326Sed void setSubStmt(Stmt *SS) { SubStmt = SS; } 784193326Sed 785249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return IdentLoc; } 786249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} 787249423Sdim 788218893Sdim child_range children() { return child_range(&SubStmt, &SubStmt+1); } 789218893Sdim 790198092Srdivacky static bool classof(const Stmt *T) { 791198092Srdivacky return T->getStmtClass() == LabelStmtClass; 792198092Srdivacky } 793193326Sed}; 794193326Sed 795193326Sed 796234982Sdim/// \brief Represents an attribute applied to a statement. 797234982Sdim/// 798234982Sdim/// Represents an attribute applied to a statement. For example: 799234982Sdim/// [[omp::for(...)]] for (...) { ... } 800234982Sdim/// 801234982Sdimclass AttributedStmt : public Stmt { 802234982Sdim Stmt *SubStmt; 803234982Sdim SourceLocation AttrLoc; 804239462Sdim unsigned NumAttrs; 805239462Sdim const Attr *Attrs[1]; 806234982Sdim 807234982Sdim friend class ASTStmtReader; 808234982Sdim 809239462Sdim AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt) 810239462Sdim : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc), 811239462Sdim NumAttrs(Attrs.size()) { 812239462Sdim memcpy(this->Attrs, Attrs.data(), Attrs.size() * sizeof(Attr*)); 813234982Sdim } 814234982Sdim 815239462Sdim explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs) 816239462Sdim : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) { 817239462Sdim memset(Attrs, 0, NumAttrs * sizeof(Attr*)); 818234982Sdim } 819234982Sdim 820239462Sdimpublic: 821263508Sdim static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc, 822239462Sdim ArrayRef<const Attr*> Attrs, Stmt *SubStmt); 823239462Sdim // \brief Build an empty attributed statement. 824263508Sdim static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs); 825239462Sdim 826234982Sdim SourceLocation getAttrLoc() const { return AttrLoc; } 827239462Sdim ArrayRef<const Attr*> getAttrs() const { 828239462Sdim return ArrayRef<const Attr*>(Attrs, NumAttrs); 829239462Sdim } 830234982Sdim Stmt *getSubStmt() { return SubStmt; } 831234982Sdim const Stmt *getSubStmt() const { return SubStmt; } 832234982Sdim 833249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return AttrLoc; } 834249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} 835249423Sdim 836234982Sdim child_range children() { return child_range(&SubStmt, &SubStmt + 1); } 837234982Sdim 838234982Sdim static bool classof(const Stmt *T) { 839234982Sdim return T->getStmtClass() == AttributedStmtClass; 840234982Sdim } 841234982Sdim}; 842234982Sdim 843234982Sdim 844193326Sed/// IfStmt - This represents an if/then/else. 845193326Sed/// 846193326Sedclass IfStmt : public Stmt { 847210299Sed enum { VAR, COND, THEN, ELSE, END_EXPR }; 848193326Sed Stmt* SubExprs[END_EXPR]; 849199990Srdivacky 850193326Sed SourceLocation IfLoc; 851193326Sed SourceLocation ElseLoc; 852234353Sdim 853193326Sedpublic: 854263508Sdim IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, 855210299Sed Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0); 856234353Sdim 857193326Sed /// \brief Build an empty if/then/else statement 858193326Sed explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { } 859193326Sed 860199990Srdivacky /// \brief Retrieve the variable declared in this "if" statement, if any. 861199990Srdivacky /// 862199990Srdivacky /// In the following example, "x" is the condition variable. 863199990Srdivacky /// \code 864199990Srdivacky /// if (int x = foo()) { 865199990Srdivacky /// printf("x is %d", x); 866199990Srdivacky /// } 867199990Srdivacky /// \endcode 868210299Sed VarDecl *getConditionVariable() const; 869263508Sdim void setConditionVariable(const ASTContext &C, VarDecl *V); 870234353Sdim 871221345Sdim /// If this IfStmt has a condition variable, return the faux DeclStmt 872221345Sdim /// associated with the creation of that condition variable. 873221345Sdim const DeclStmt *getConditionVariableDeclStmt() const { 874221345Sdim return reinterpret_cast<DeclStmt*>(SubExprs[VAR]); 875221345Sdim } 876234353Sdim 877193326Sed const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 878193326Sed void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } 879193326Sed const Stmt *getThen() const { return SubExprs[THEN]; } 880198092Srdivacky void setThen(Stmt *S) { SubExprs[THEN] = S; } 881193326Sed const Stmt *getElse() const { return SubExprs[ELSE]; } 882193326Sed void setElse(Stmt *S) { SubExprs[ELSE] = S; } 883193326Sed 884193326Sed Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 885193326Sed Stmt *getThen() { return SubExprs[THEN]; } 886193326Sed Stmt *getElse() { return SubExprs[ELSE]; } 887193326Sed 888193326Sed SourceLocation getIfLoc() const { return IfLoc; } 889193326Sed void setIfLoc(SourceLocation L) { IfLoc = L; } 890193326Sed SourceLocation getElseLoc() const { return ElseLoc; } 891193326Sed void setElseLoc(SourceLocation L) { ElseLoc = L; } 892193326Sed 893249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; } 894249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { 895193326Sed if (SubExprs[ELSE]) 896249423Sdim return SubExprs[ELSE]->getLocEnd(); 897193326Sed else 898249423Sdim return SubExprs[THEN]->getLocEnd(); 899193326Sed } 900198092Srdivacky 901218893Sdim // Iterators over subexpressions. The iterators will include iterating 902218893Sdim // over the initialization expression referenced by the condition variable. 903218893Sdim child_range children() { 904218893Sdim return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 905218893Sdim } 906218893Sdim 907198092Srdivacky static bool classof(const Stmt *T) { 908198092Srdivacky return T->getStmtClass() == IfStmtClass; 909193326Sed } 910193326Sed}; 911193326Sed 912193326Sed/// SwitchStmt - This represents a 'switch' stmt. 913193326Sed/// 914193326Sedclass SwitchStmt : public Stmt { 915210299Sed enum { VAR, COND, BODY, END_EXPR }; 916198092Srdivacky Stmt* SubExprs[END_EXPR]; 917193326Sed // This points to a linked list of case and default statements. 918193326Sed SwitchCase *FirstCase; 919193326Sed SourceLocation SwitchLoc; 920198092Srdivacky 921218893Sdim /// If the SwitchStmt is a switch on an enum value, this records whether 922218893Sdim /// all the enum values were covered by CaseStmts. This value is meant to 923218893Sdim /// be a hint for possible clients. 924218893Sdim unsigned AllEnumCasesCovered : 1; 925218893Sdim 926193326Sedpublic: 927263508Sdim SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond); 928198092Srdivacky 929193326Sed /// \brief Build a empty switch statement. 930193326Sed explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { } 931193326Sed 932199990Srdivacky /// \brief Retrieve the variable declared in this "switch" statement, if any. 933199990Srdivacky /// 934199990Srdivacky /// In the following example, "x" is the condition variable. 935199990Srdivacky /// \code 936199990Srdivacky /// switch (int x = foo()) { 937199990Srdivacky /// case 0: break; 938199990Srdivacky /// // ... 939199990Srdivacky /// } 940199990Srdivacky /// \endcode 941210299Sed VarDecl *getConditionVariable() const; 942263508Sdim void setConditionVariable(const ASTContext &C, VarDecl *V); 943234353Sdim 944221345Sdim /// If this SwitchStmt has a condition variable, return the faux DeclStmt 945221345Sdim /// associated with the creation of that condition variable. 946221345Sdim const DeclStmt *getConditionVariableDeclStmt() const { 947221345Sdim return reinterpret_cast<DeclStmt*>(SubExprs[VAR]); 948221345Sdim } 949199990Srdivacky 950193326Sed const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 951193326Sed const Stmt *getBody() const { return SubExprs[BODY]; } 952193326Sed const SwitchCase *getSwitchCaseList() const { return FirstCase; } 953193326Sed 954193326Sed Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 955193326Sed void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } 956193326Sed Stmt *getBody() { return SubExprs[BODY]; } 957193326Sed void setBody(Stmt *S) { SubExprs[BODY] = S; } 958193326Sed SwitchCase *getSwitchCaseList() { return FirstCase; } 959198092Srdivacky 960198092Srdivacky /// \brief Set the case list for this switch statement. 961193326Sed void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; } 962193326Sed 963193326Sed SourceLocation getSwitchLoc() const { return SwitchLoc; } 964193326Sed void setSwitchLoc(SourceLocation L) { SwitchLoc = L; } 965193326Sed 966198092Srdivacky void setBody(Stmt *S, SourceLocation SL) { 967198092Srdivacky SubExprs[BODY] = S; 968193326Sed SwitchLoc = SL; 969198092Srdivacky } 970193326Sed void addSwitchCase(SwitchCase *SC) { 971234353Sdim assert(!SC->getNextSwitchCase() 972234353Sdim && "case/default already added to a switch"); 973193326Sed SC->setNextSwitchCase(FirstCase); 974193326Sed FirstCase = SC; 975193326Sed } 976218893Sdim 977218893Sdim /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a 978218893Sdim /// switch over an enum value then all cases have been explicitly covered. 979218893Sdim void setAllEnumCasesCovered() { 980218893Sdim AllEnumCasesCovered = 1; 981218893Sdim } 982218893Sdim 983218893Sdim /// Returns true if the SwitchStmt is a switch of an enum value and all cases 984218893Sdim /// have been explicitly covered. 985218893Sdim bool isAllEnumCasesCovered() const { 986218893Sdim return (bool) AllEnumCasesCovered; 987218893Sdim } 988218893Sdim 989249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; } 990249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { 991249423Sdim return SubExprs[BODY]->getLocEnd(); 992193326Sed } 993249423Sdim 994218893Sdim // Iterators 995218893Sdim child_range children() { 996218893Sdim return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 997218893Sdim } 998218893Sdim 999198092Srdivacky static bool classof(const Stmt *T) { 1000198092Srdivacky return T->getStmtClass() == SwitchStmtClass; 1001193326Sed } 1002193326Sed}; 1003193326Sed 1004193326Sed 1005193326Sed/// WhileStmt - This represents a 'while' stmt. 1006193326Sed/// 1007193326Sedclass WhileStmt : public Stmt { 1008210299Sed enum { VAR, COND, BODY, END_EXPR }; 1009193326Sed Stmt* SubExprs[END_EXPR]; 1010193326Sed SourceLocation WhileLoc; 1011193326Sedpublic: 1012263508Sdim WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, 1013210299Sed SourceLocation WL); 1014198092Srdivacky 1015193326Sed /// \brief Build an empty while statement. 1016193326Sed explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { } 1017193326Sed 1018199990Srdivacky /// \brief Retrieve the variable declared in this "while" statement, if any. 1019199990Srdivacky /// 1020199990Srdivacky /// In the following example, "x" is the condition variable. 1021199990Srdivacky /// \code 1022199990Srdivacky /// while (int x = random()) { 1023199990Srdivacky /// // ... 1024199990Srdivacky /// } 1025199990Srdivacky /// \endcode 1026210299Sed VarDecl *getConditionVariable() const; 1027263508Sdim void setConditionVariable(const ASTContext &C, VarDecl *V); 1028199990Srdivacky 1029221345Sdim /// If this WhileStmt has a condition variable, return the faux DeclStmt 1030221345Sdim /// associated with the creation of that condition variable. 1031221345Sdim const DeclStmt *getConditionVariableDeclStmt() const { 1032221345Sdim return reinterpret_cast<DeclStmt*>(SubExprs[VAR]); 1033221345Sdim } 1034221345Sdim 1035193326Sed Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 1036193326Sed const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 1037193326Sed void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 1038193326Sed Stmt *getBody() { return SubExprs[BODY]; } 1039193326Sed const Stmt *getBody() const { return SubExprs[BODY]; } 1040193326Sed void setBody(Stmt *S) { SubExprs[BODY] = S; } 1041193326Sed 1042193326Sed SourceLocation getWhileLoc() const { return WhileLoc; } 1043193326Sed void setWhileLoc(SourceLocation L) { WhileLoc = L; } 1044193326Sed 1045249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return WhileLoc; } 1046249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { 1047249423Sdim return SubExprs[BODY]->getLocEnd(); 1048193326Sed } 1049249423Sdim 1050198092Srdivacky static bool classof(const Stmt *T) { 1051198092Srdivacky return T->getStmtClass() == WhileStmtClass; 1052193326Sed } 1053198092Srdivacky 1054193326Sed // Iterators 1055218893Sdim child_range children() { 1056218893Sdim return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 1057218893Sdim } 1058193326Sed}; 1059193326Sed 1060193326Sed/// DoStmt - This represents a 'do/while' stmt. 1061193326Sed/// 1062193326Sedclass DoStmt : public Stmt { 1063218893Sdim enum { BODY, COND, END_EXPR }; 1064193326Sed Stmt* SubExprs[END_EXPR]; 1065193326Sed SourceLocation DoLoc; 1066193326Sed SourceLocation WhileLoc; 1067194179Sed SourceLocation RParenLoc; // Location of final ')' in do stmt condition. 1068193326Sed 1069193326Sedpublic: 1070194179Sed DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL, 1071194179Sed SourceLocation RP) 1072194179Sed : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) { 1073193326Sed SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 1074193326Sed SubExprs[BODY] = body; 1075198092Srdivacky } 1076193326Sed 1077193326Sed /// \brief Build an empty do-while statement. 1078193326Sed explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { } 1079198092Srdivacky 1080193326Sed Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 1081193326Sed const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 1082193326Sed void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 1083193326Sed Stmt *getBody() { return SubExprs[BODY]; } 1084198092Srdivacky const Stmt *getBody() const { return SubExprs[BODY]; } 1085193326Sed void setBody(Stmt *S) { SubExprs[BODY] = S; } 1086193326Sed 1087193326Sed SourceLocation getDoLoc() const { return DoLoc; } 1088193326Sed void setDoLoc(SourceLocation L) { DoLoc = L; } 1089193326Sed SourceLocation getWhileLoc() const { return WhileLoc; } 1090193326Sed void setWhileLoc(SourceLocation L) { WhileLoc = L; } 1091193326Sed 1092194179Sed SourceLocation getRParenLoc() const { return RParenLoc; } 1093194179Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 1094194179Sed 1095249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return DoLoc; } 1096249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } 1097249423Sdim 1098198092Srdivacky static bool classof(const Stmt *T) { 1099198092Srdivacky return T->getStmtClass() == DoStmtClass; 1100193326Sed } 1101193326Sed 1102193326Sed // Iterators 1103218893Sdim child_range children() { 1104218893Sdim return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 1105218893Sdim } 1106193326Sed}; 1107193326Sed 1108193326Sed 1109193326Sed/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 1110193326Sed/// the init/cond/inc parts of the ForStmt will be null if they were not 1111193326Sed/// specified in the source. 1112193326Sed/// 1113193326Sedclass ForStmt : public Stmt { 1114210299Sed enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR }; 1115193326Sed Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 1116193326Sed SourceLocation ForLoc; 1117193326Sed SourceLocation LParenLoc, RParenLoc; 1118193326Sed 1119193326Sedpublic: 1120263508Sdim ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, 1121263508Sdim Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, 1122263508Sdim SourceLocation RP); 1123198092Srdivacky 1124193326Sed /// \brief Build an empty for statement. 1125193326Sed explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { } 1126193326Sed 1127193326Sed Stmt *getInit() { return SubExprs[INIT]; } 1128234353Sdim 1129199990Srdivacky /// \brief Retrieve the variable declared in this "for" statement, if any. 1130199990Srdivacky /// 1131199990Srdivacky /// In the following example, "y" is the condition variable. 1132199990Srdivacky /// \code 1133199990Srdivacky /// for (int x = random(); int y = mangle(x); ++x) { 1134199990Srdivacky /// // ... 1135199990Srdivacky /// } 1136199990Srdivacky /// \endcode 1137210299Sed VarDecl *getConditionVariable() const; 1138263508Sdim void setConditionVariable(const ASTContext &C, VarDecl *V); 1139234353Sdim 1140221345Sdim /// If this ForStmt has a condition variable, return the faux DeclStmt 1141221345Sdim /// associated with the creation of that condition variable. 1142221345Sdim const DeclStmt *getConditionVariableDeclStmt() const { 1143221345Sdim return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]); 1144221345Sdim } 1145221345Sdim 1146193326Sed Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 1147193326Sed Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 1148193326Sed Stmt *getBody() { return SubExprs[BODY]; } 1149193326Sed 1150193326Sed const Stmt *getInit() const { return SubExprs[INIT]; } 1151193326Sed const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 1152193326Sed const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 1153193326Sed const Stmt *getBody() const { return SubExprs[BODY]; } 1154193326Sed 1155193326Sed void setInit(Stmt *S) { SubExprs[INIT] = S; } 1156193326Sed void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 1157193326Sed void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } 1158193326Sed void setBody(Stmt *S) { SubExprs[BODY] = S; } 1159193326Sed 1160193326Sed SourceLocation getForLoc() const { return ForLoc; } 1161193326Sed void setForLoc(SourceLocation L) { ForLoc = L; } 1162193326Sed SourceLocation getLParenLoc() const { return LParenLoc; } 1163193326Sed void setLParenLoc(SourceLocation L) { LParenLoc = L; } 1164193326Sed SourceLocation getRParenLoc() const { return RParenLoc; } 1165193326Sed void setRParenLoc(SourceLocation L) { RParenLoc = L; } 1166193326Sed 1167249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; } 1168249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { 1169249423Sdim return SubExprs[BODY]->getLocEnd(); 1170193326Sed } 1171249423Sdim 1172198092Srdivacky static bool classof(const Stmt *T) { 1173198092Srdivacky return T->getStmtClass() == ForStmtClass; 1174193326Sed } 1175198092Srdivacky 1176193326Sed // Iterators 1177218893Sdim child_range children() { 1178218893Sdim return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 1179218893Sdim } 1180193326Sed}; 1181198092Srdivacky 1182193326Sed/// GotoStmt - This represents a direct goto. 1183193326Sed/// 1184193326Sedclass GotoStmt : public Stmt { 1185218893Sdim LabelDecl *Label; 1186193326Sed SourceLocation GotoLoc; 1187193326Sed SourceLocation LabelLoc; 1188193326Sedpublic: 1189218893Sdim GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL) 1190193326Sed : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 1191198092Srdivacky 1192193326Sed /// \brief Build an empty goto statement. 1193193326Sed explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { } 1194193326Sed 1195218893Sdim LabelDecl *getLabel() const { return Label; } 1196218893Sdim void setLabel(LabelDecl *D) { Label = D; } 1197193326Sed 1198193326Sed SourceLocation getGotoLoc() const { return GotoLoc; } 1199193326Sed void setGotoLoc(SourceLocation L) { GotoLoc = L; } 1200193326Sed SourceLocation getLabelLoc() const { return LabelLoc; } 1201193326Sed void setLabelLoc(SourceLocation L) { LabelLoc = L; } 1202193326Sed 1203249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; } 1204249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; } 1205249423Sdim 1206198092Srdivacky static bool classof(const Stmt *T) { 1207198092Srdivacky return T->getStmtClass() == GotoStmtClass; 1208193326Sed } 1209198092Srdivacky 1210193326Sed // Iterators 1211218893Sdim child_range children() { return child_range(); } 1212193326Sed}; 1213193326Sed 1214193326Sed/// IndirectGotoStmt - This represents an indirect goto. 1215193326Sed/// 1216193326Sedclass IndirectGotoStmt : public Stmt { 1217193326Sed SourceLocation GotoLoc; 1218193326Sed SourceLocation StarLoc; 1219193326Sed Stmt *Target; 1220193326Sedpublic: 1221198092Srdivacky IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc, 1222193326Sed Expr *target) 1223193326Sed : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc), 1224193326Sed Target((Stmt*)target) {} 1225193326Sed 1226193326Sed /// \brief Build an empty indirect goto statement. 1227198092Srdivacky explicit IndirectGotoStmt(EmptyShell Empty) 1228193326Sed : Stmt(IndirectGotoStmtClass, Empty) { } 1229198092Srdivacky 1230193326Sed void setGotoLoc(SourceLocation L) { GotoLoc = L; } 1231193326Sed SourceLocation getGotoLoc() const { return GotoLoc; } 1232193326Sed void setStarLoc(SourceLocation L) { StarLoc = L; } 1233193326Sed SourceLocation getStarLoc() const { return StarLoc; } 1234198092Srdivacky 1235218893Sdim Expr *getTarget() { return reinterpret_cast<Expr*>(Target); } 1236218893Sdim const Expr *getTarget() const {return reinterpret_cast<const Expr*>(Target);} 1237193326Sed void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); } 1238193326Sed 1239218893Sdim /// getConstantTarget - Returns the fixed target of this indirect 1240218893Sdim /// goto, if one exists. 1241218893Sdim LabelDecl *getConstantTarget(); 1242218893Sdim const LabelDecl *getConstantTarget() const { 1243218893Sdim return const_cast<IndirectGotoStmt*>(this)->getConstantTarget(); 1244218893Sdim } 1245218893Sdim 1246249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; } 1247249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return Target->getLocEnd(); } 1248198092Srdivacky 1249198092Srdivacky static bool classof(const Stmt *T) { 1250198092Srdivacky return T->getStmtClass() == IndirectGotoStmtClass; 1251193326Sed } 1252198092Srdivacky 1253193326Sed // Iterators 1254218893Sdim child_range children() { return child_range(&Target, &Target+1); } 1255193326Sed}; 1256193326Sed 1257193326Sed 1258193326Sed/// ContinueStmt - This represents a continue. 1259193326Sed/// 1260193326Sedclass ContinueStmt : public Stmt { 1261193326Sed SourceLocation ContinueLoc; 1262193326Sedpublic: 1263193326Sed ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 1264198092Srdivacky 1265193326Sed /// \brief Build an empty continue statement. 1266193326Sed explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { } 1267193326Sed 1268193326Sed SourceLocation getContinueLoc() const { return ContinueLoc; } 1269193326Sed void setContinueLoc(SourceLocation L) { ContinueLoc = L; } 1270193326Sed 1271249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return ContinueLoc; } 1272249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return ContinueLoc; } 1273193326Sed 1274198092Srdivacky static bool classof(const Stmt *T) { 1275198092Srdivacky return T->getStmtClass() == ContinueStmtClass; 1276193326Sed } 1277198092Srdivacky 1278193326Sed // Iterators 1279218893Sdim child_range children() { return child_range(); } 1280193326Sed}; 1281193326Sed 1282193326Sed/// BreakStmt - This represents a break. 1283193326Sed/// 1284193326Sedclass BreakStmt : public Stmt { 1285193326Sed SourceLocation BreakLoc; 1286193326Sedpublic: 1287193326Sed BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 1288198092Srdivacky 1289193326Sed /// \brief Build an empty break statement. 1290193326Sed explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { } 1291193326Sed 1292193326Sed SourceLocation getBreakLoc() const { return BreakLoc; } 1293193326Sed void setBreakLoc(SourceLocation L) { BreakLoc = L; } 1294193326Sed 1295249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return BreakLoc; } 1296249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return BreakLoc; } 1297193326Sed 1298198092Srdivacky static bool classof(const Stmt *T) { 1299198092Srdivacky return T->getStmtClass() == BreakStmtClass; 1300193326Sed } 1301198092Srdivacky 1302193326Sed // Iterators 1303218893Sdim child_range children() { return child_range(); } 1304193326Sed}; 1305193326Sed 1306193326Sed 1307193326Sed/// ReturnStmt - This represents a return, optionally of an expression: 1308193326Sed/// return; 1309193326Sed/// return 4; 1310193326Sed/// 1311193326Sed/// Note that GCC allows return with no argument in a function declared to 1312193326Sed/// return a value, and it allows returning a value in functions declared to 1313193326Sed/// return void. We explicitly model this in the AST, which means you can't 1314193326Sed/// depend on the return type of the function and the presence of an argument. 1315193326Sed/// 1316193326Sedclass ReturnStmt : public Stmt { 1317193326Sed Stmt *RetExpr; 1318193326Sed SourceLocation RetLoc; 1319208600Srdivacky const VarDecl *NRVOCandidate; 1320234353Sdim 1321193326Sedpublic: 1322208600Srdivacky ReturnStmt(SourceLocation RL) 1323208600Srdivacky : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { } 1324193326Sed 1325208600Srdivacky ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate) 1326208600Srdivacky : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL), 1327208600Srdivacky NRVOCandidate(NRVOCandidate) {} 1328208600Srdivacky 1329193326Sed /// \brief Build an empty return expression. 1330193326Sed explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { } 1331193326Sed 1332193326Sed const Expr *getRetValue() const; 1333193326Sed Expr *getRetValue(); 1334193326Sed void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); } 1335193326Sed 1336193326Sed SourceLocation getReturnLoc() const { return RetLoc; } 1337193326Sed void setReturnLoc(SourceLocation L) { RetLoc = L; } 1338193326Sed 1339208600Srdivacky /// \brief Retrieve the variable that might be used for the named return 1340208600Srdivacky /// value optimization. 1341208600Srdivacky /// 1342208600Srdivacky /// The optimization itself can only be performed if the variable is 1343208600Srdivacky /// also marked as an NRVO object. 1344208600Srdivacky const VarDecl *getNRVOCandidate() const { return NRVOCandidate; } 1345208600Srdivacky void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; } 1346198092Srdivacky 1347249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return RetLoc; } 1348249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { 1349249423Sdim return RetExpr ? RetExpr->getLocEnd() : RetLoc; 1350249423Sdim } 1351234353Sdim 1352198092Srdivacky static bool classof(const Stmt *T) { 1353198092Srdivacky return T->getStmtClass() == ReturnStmtClass; 1354193326Sed } 1355198092Srdivacky 1356193326Sed // Iterators 1357218893Sdim child_range children() { 1358218893Sdim if (RetExpr) return child_range(&RetExpr, &RetExpr+1); 1359218893Sdim return child_range(); 1360218893Sdim } 1361193326Sed}; 1362193326Sed 1363243830Sdim/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt. 1364193326Sed/// 1365193326Sedclass AsmStmt : public Stmt { 1366243830Sdimprotected: 1367243830Sdim SourceLocation AsmLoc; 1368243830Sdim /// \brief True if the assembly statement does not have any input or output 1369243830Sdim /// operands. 1370243830Sdim bool IsSimple; 1371193326Sed 1372243830Sdim /// \brief If true, treat this inline assembly as having side effects. 1373243830Sdim /// This assembly statement should not be optimized, deleted or moved. 1374193326Sed bool IsVolatile; 1375198092Srdivacky 1376193326Sed unsigned NumOutputs; 1377193326Sed unsigned NumInputs; 1378203955Srdivacky unsigned NumClobbers; 1379198092Srdivacky 1380203955Srdivacky Stmt **Exprs; 1381234353Sdim 1382243830Sdim AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile, 1383243830Sdim unsigned numoutputs, unsigned numinputs, unsigned numclobbers) : 1384243830Sdim Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile), 1385243830Sdim NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { } 1386243830Sdim 1387251662Sdim friend class ASTStmtReader; 1388251662Sdim 1389193326Sedpublic: 1390193326Sed /// \brief Build an empty inline-assembly statement. 1391243830Sdim explicit AsmStmt(StmtClass SC, EmptyShell Empty) : 1392251662Sdim Stmt(SC, Empty), Exprs(0) { } 1393193326Sed 1394193326Sed SourceLocation getAsmLoc() const { return AsmLoc; } 1395193326Sed void setAsmLoc(SourceLocation L) { AsmLoc = L; } 1396193326Sed 1397193326Sed bool isSimple() const { return IsSimple; } 1398202379Srdivacky void setSimple(bool V) { IsSimple = V; } 1399193326Sed 1400243830Sdim bool isVolatile() const { return IsVolatile; } 1401243830Sdim void setVolatile(bool V) { IsVolatile = V; } 1402243830Sdim 1403249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); } 1404249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); } 1405243830Sdim 1406193326Sed //===--- Asm String Analysis ---===// 1407193326Sed 1408243830Sdim /// Assemble final IR asm string. 1409263508Sdim std::string generateAsmString(const ASTContext &C) const; 1410243830Sdim 1411243830Sdim //===--- Output operands ---===// 1412243830Sdim 1413243830Sdim unsigned getNumOutputs() const { return NumOutputs; } 1414243830Sdim 1415243830Sdim /// getOutputConstraint - Return the constraint string for the specified 1416243830Sdim /// output operand. All output constraints are known to be non-empty (either 1417243830Sdim /// '=' or '+'). 1418243830Sdim StringRef getOutputConstraint(unsigned i) const; 1419243830Sdim 1420243830Sdim /// isOutputPlusConstraint - Return true if the specified output constraint 1421243830Sdim /// is a "+" constraint (which is both an input and an output) or false if it 1422243830Sdim /// is an "=" constraint (just an output). 1423243830Sdim bool isOutputPlusConstraint(unsigned i) const { 1424243830Sdim return getOutputConstraint(i)[0] == '+'; 1425243830Sdim } 1426243830Sdim 1427243830Sdim const Expr *getOutputExpr(unsigned i) const; 1428243830Sdim 1429243830Sdim /// getNumPlusOperands - Return the number of output operands that have a "+" 1430243830Sdim /// constraint. 1431243830Sdim unsigned getNumPlusOperands() const; 1432243830Sdim 1433243830Sdim //===--- Input operands ---===// 1434243830Sdim 1435243830Sdim unsigned getNumInputs() const { return NumInputs; } 1436243830Sdim 1437243830Sdim /// getInputConstraint - Return the specified input constraint. Unlike output 1438243830Sdim /// constraints, these can be empty. 1439243830Sdim StringRef getInputConstraint(unsigned i) const; 1440243830Sdim 1441243830Sdim const Expr *getInputExpr(unsigned i) const; 1442243830Sdim 1443243830Sdim //===--- Other ---===// 1444243830Sdim 1445243830Sdim unsigned getNumClobbers() const { return NumClobbers; } 1446243830Sdim StringRef getClobber(unsigned i) const; 1447243830Sdim 1448243830Sdim static bool classof(const Stmt *T) { 1449243830Sdim return T->getStmtClass() == GCCAsmStmtClass || 1450243830Sdim T->getStmtClass() == MSAsmStmtClass; 1451243830Sdim } 1452243830Sdim 1453243830Sdim // Input expr iterators. 1454243830Sdim 1455243830Sdim typedef ExprIterator inputs_iterator; 1456243830Sdim typedef ConstExprIterator const_inputs_iterator; 1457243830Sdim 1458243830Sdim inputs_iterator begin_inputs() { 1459243830Sdim return &Exprs[0] + NumOutputs; 1460243830Sdim } 1461243830Sdim 1462243830Sdim inputs_iterator end_inputs() { 1463243830Sdim return &Exprs[0] + NumOutputs + NumInputs; 1464243830Sdim } 1465243830Sdim 1466243830Sdim const_inputs_iterator begin_inputs() const { 1467243830Sdim return &Exprs[0] + NumOutputs; 1468243830Sdim } 1469243830Sdim 1470243830Sdim const_inputs_iterator end_inputs() const { 1471243830Sdim return &Exprs[0] + NumOutputs + NumInputs; 1472243830Sdim } 1473243830Sdim 1474243830Sdim // Output expr iterators. 1475243830Sdim 1476243830Sdim typedef ExprIterator outputs_iterator; 1477243830Sdim typedef ConstExprIterator const_outputs_iterator; 1478243830Sdim 1479243830Sdim outputs_iterator begin_outputs() { 1480243830Sdim return &Exprs[0]; 1481243830Sdim } 1482243830Sdim outputs_iterator end_outputs() { 1483243830Sdim return &Exprs[0] + NumOutputs; 1484243830Sdim } 1485243830Sdim 1486243830Sdim const_outputs_iterator begin_outputs() const { 1487243830Sdim return &Exprs[0]; 1488243830Sdim } 1489243830Sdim const_outputs_iterator end_outputs() const { 1490243830Sdim return &Exprs[0] + NumOutputs; 1491243830Sdim } 1492243830Sdim 1493243830Sdim child_range children() { 1494243830Sdim return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); 1495243830Sdim } 1496243830Sdim}; 1497243830Sdim 1498243830Sdim/// This represents a GCC inline-assembly statement extension. 1499243830Sdim/// 1500243830Sdimclass GCCAsmStmt : public AsmStmt { 1501243830Sdim SourceLocation RParenLoc; 1502243830Sdim StringLiteral *AsmStr; 1503243830Sdim 1504243830Sdim // FIXME: If we wanted to, we could allocate all of these in one big array. 1505243830Sdim StringLiteral **Constraints; 1506243830Sdim StringLiteral **Clobbers; 1507251662Sdim IdentifierInfo **Names; 1508243830Sdim 1509251662Sdim friend class ASTStmtReader; 1510251662Sdim 1511243830Sdimpublic: 1512263508Sdim GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple, 1513243830Sdim bool isvolatile, unsigned numoutputs, unsigned numinputs, 1514243830Sdim IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, 1515243830Sdim StringLiteral *asmstr, unsigned numclobbers, 1516243830Sdim StringLiteral **clobbers, SourceLocation rparenloc); 1517243830Sdim 1518243830Sdim /// \brief Build an empty inline-assembly statement. 1519243830Sdim explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty), 1520251662Sdim Constraints(0), Clobbers(0), Names(0) { } 1521243830Sdim 1522243830Sdim SourceLocation getRParenLoc() const { return RParenLoc; } 1523243830Sdim void setRParenLoc(SourceLocation L) { RParenLoc = L; } 1524243830Sdim 1525243830Sdim //===--- Asm String Analysis ---===// 1526243830Sdim 1527193326Sed const StringLiteral *getAsmString() const { return AsmStr; } 1528193326Sed StringLiteral *getAsmString() { return AsmStr; } 1529193326Sed void setAsmString(StringLiteral *E) { AsmStr = E; } 1530193326Sed 1531193326Sed /// AsmStringPiece - this is part of a decomposed asm string specification 1532193326Sed /// (for use with the AnalyzeAsmString function below). An asm string is 1533193326Sed /// considered to be a concatenation of these parts. 1534193326Sed class AsmStringPiece { 1535193326Sed public: 1536193326Sed enum Kind { 1537193326Sed String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%". 1538193326Sed Operand // Operand reference, with optional modifier %c4. 1539193326Sed }; 1540193326Sed private: 1541193326Sed Kind MyKind; 1542193326Sed std::string Str; 1543193326Sed unsigned OperandNo; 1544193326Sed public: 1545193326Sed AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {} 1546193326Sed AsmStringPiece(unsigned OpNo, char Modifier) 1547193326Sed : MyKind(Operand), Str(), OperandNo(OpNo) { 1548193326Sed Str += Modifier; 1549193326Sed } 1550198092Srdivacky 1551193326Sed bool isString() const { return MyKind == String; } 1552193326Sed bool isOperand() const { return MyKind == Operand; } 1553198092Srdivacky 1554193326Sed const std::string &getString() const { 1555193326Sed assert(isString()); 1556193326Sed return Str; 1557193326Sed } 1558193326Sed 1559193326Sed unsigned getOperandNo() const { 1560193326Sed assert(isOperand()); 1561193326Sed return OperandNo; 1562193326Sed } 1563198092Srdivacky 1564193326Sed /// getModifier - Get the modifier for this operand, if present. This 1565193326Sed /// returns '\0' if there was no modifier. 1566193326Sed char getModifier() const { 1567193326Sed assert(isOperand()); 1568193326Sed return Str[0]; 1569193326Sed } 1570193326Sed }; 1571198092Srdivacky 1572193326Sed /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing 1573193326Sed /// it into pieces. If the asm string is erroneous, emit errors and return 1574193326Sed /// true, otherwise return false. This handles canonicalization and 1575193326Sed /// translation of strings from GCC syntax to LLVM IR syntax, and handles 1576198092Srdivacky //// flattening of named references like %[foo] to Operand AsmStringPiece's. 1577226633Sdim unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces, 1578263508Sdim const ASTContext &C, unsigned &DiagOffs) const; 1579198092Srdivacky 1580243830Sdim /// Assemble final IR asm string. 1581263508Sdim std::string generateAsmString(const ASTContext &C) const; 1582198092Srdivacky 1583193326Sed //===--- Output operands ---===// 1584193326Sed 1585251662Sdim IdentifierInfo *getOutputIdentifier(unsigned i) const { 1586251662Sdim return Names[i]; 1587251662Sdim } 1588251662Sdim 1589251662Sdim StringRef getOutputName(unsigned i) const { 1590251662Sdim if (IdentifierInfo *II = getOutputIdentifier(i)) 1591251662Sdim return II->getName(); 1592251662Sdim 1593251662Sdim return StringRef(); 1594251662Sdim } 1595251662Sdim 1596226633Sdim StringRef getOutputConstraint(unsigned i) const; 1597198092Srdivacky 1598193326Sed const StringLiteral *getOutputConstraintLiteral(unsigned i) const { 1599193326Sed return Constraints[i]; 1600193326Sed } 1601193326Sed StringLiteral *getOutputConstraintLiteral(unsigned i) { 1602193326Sed return Constraints[i]; 1603193326Sed } 1604198092Srdivacky 1605193326Sed Expr *getOutputExpr(unsigned i); 1606198092Srdivacky 1607193326Sed const Expr *getOutputExpr(unsigned i) const { 1608243830Sdim return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i); 1609193326Sed } 1610198092Srdivacky 1611193326Sed //===--- Input operands ---===// 1612198092Srdivacky 1613251662Sdim IdentifierInfo *getInputIdentifier(unsigned i) const { 1614251662Sdim return Names[i + NumOutputs]; 1615251662Sdim } 1616251662Sdim 1617251662Sdim StringRef getInputName(unsigned i) const { 1618251662Sdim if (IdentifierInfo *II = getInputIdentifier(i)) 1619251662Sdim return II->getName(); 1620251662Sdim 1621251662Sdim return StringRef(); 1622251662Sdim } 1623251662Sdim 1624226633Sdim StringRef getInputConstraint(unsigned i) const; 1625198092Srdivacky 1626193326Sed const StringLiteral *getInputConstraintLiteral(unsigned i) const { 1627193326Sed return Constraints[i + NumOutputs]; 1628193326Sed } 1629193326Sed StringLiteral *getInputConstraintLiteral(unsigned i) { 1630193326Sed return Constraints[i + NumOutputs]; 1631193326Sed } 1632198092Srdivacky 1633193326Sed Expr *getInputExpr(unsigned i); 1634219077Sdim void setInputExpr(unsigned i, Expr *E); 1635234353Sdim 1636193326Sed const Expr *getInputExpr(unsigned i) const { 1637243830Sdim return const_cast<GCCAsmStmt*>(this)->getInputExpr(i); 1638193326Sed } 1639193326Sed 1640251662Sdimprivate: 1641263508Sdim void setOutputsAndInputsAndClobbers(const ASTContext &C, 1642203955Srdivacky IdentifierInfo **Names, 1643203955Srdivacky StringLiteral **Constraints, 1644203955Srdivacky Stmt **Exprs, 1645203955Srdivacky unsigned NumOutputs, 1646234353Sdim unsigned NumInputs, 1647203955Srdivacky StringLiteral **Clobbers, 1648203955Srdivacky unsigned NumClobbers); 1649251662Sdimpublic: 1650193326Sed 1651193326Sed //===--- Other ---===// 1652198092Srdivacky 1653193326Sed /// getNamedOperand - Given a symbolic operand reference like %[foo], 1654193326Sed /// translate this into a numeric value needed to reference the same operand. 1655193326Sed /// This returns -1 if the operand name is invalid. 1656226633Sdim int getNamedOperand(StringRef SymbolicName) const; 1657193326Sed 1658243830Sdim StringRef getClobber(unsigned i) const; 1659243830Sdim StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; } 1660243830Sdim const StringLiteral *getClobberStringLiteral(unsigned i) const { 1661243830Sdim return Clobbers[i]; 1662243830Sdim } 1663193326Sed 1664249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; } 1665249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } 1666198092Srdivacky 1667243830Sdim static bool classof(const Stmt *T) { 1668243830Sdim return T->getStmtClass() == GCCAsmStmtClass; 1669193326Sed } 1670193326Sed}; 1671193326Sed 1672243830Sdim/// This represents a Microsoft inline-assembly statement extension. 1673239462Sdim/// 1674243830Sdimclass MSAsmStmt : public AsmStmt { 1675249423Sdim SourceLocation LBraceLoc, EndLoc; 1676251662Sdim StringRef AsmStr; 1677239462Sdim 1678239462Sdim unsigned NumAsmToks; 1679239462Sdim 1680239462Sdim Token *AsmToks; 1681243830Sdim StringRef *Constraints; 1682239462Sdim StringRef *Clobbers; 1683239462Sdim 1684251662Sdim friend class ASTStmtReader; 1685251662Sdim 1686239462Sdimpublic: 1687263508Sdim MSAsmStmt(const ASTContext &C, SourceLocation asmloc, 1688263508Sdim SourceLocation lbraceloc, bool issimple, bool isvolatile, 1689263508Sdim ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs, 1690251662Sdim ArrayRef<StringRef> constraints, 1691243830Sdim ArrayRef<Expr*> exprs, StringRef asmstr, 1692243830Sdim ArrayRef<StringRef> clobbers, SourceLocation endloc); 1693239462Sdim 1694243830Sdim /// \brief Build an empty MS-style inline-assembly statement. 1695243830Sdim explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty), 1696243830Sdim NumAsmToks(0), AsmToks(0), Constraints(0), Clobbers(0) { } 1697243830Sdim 1698239462Sdim SourceLocation getLBraceLoc() const { return LBraceLoc; } 1699239462Sdim void setLBraceLoc(SourceLocation L) { LBraceLoc = L; } 1700239462Sdim SourceLocation getEndLoc() const { return EndLoc; } 1701239462Sdim void setEndLoc(SourceLocation L) { EndLoc = L; } 1702239462Sdim 1703239462Sdim bool hasBraces() const { return LBraceLoc.isValid(); } 1704239462Sdim 1705239462Sdim unsigned getNumAsmToks() { return NumAsmToks; } 1706239462Sdim Token *getAsmToks() { return AsmToks; } 1707239462Sdim 1708239462Sdim //===--- Asm String Analysis ---===// 1709251662Sdim StringRef getAsmString() const { return AsmStr; } 1710239462Sdim 1711243830Sdim /// Assemble final IR asm string. 1712263508Sdim std::string generateAsmString(const ASTContext &C) const; 1713243830Sdim 1714243830Sdim //===--- Output operands ---===// 1715243830Sdim 1716243830Sdim StringRef getOutputConstraint(unsigned i) const { 1717251662Sdim assert(i < NumOutputs); 1718243830Sdim return Constraints[i]; 1719243830Sdim } 1720243830Sdim 1721243830Sdim Expr *getOutputExpr(unsigned i); 1722243830Sdim 1723243830Sdim const Expr *getOutputExpr(unsigned i) const { 1724243830Sdim return const_cast<MSAsmStmt*>(this)->getOutputExpr(i); 1725243830Sdim } 1726243830Sdim 1727243830Sdim //===--- Input operands ---===// 1728243830Sdim 1729243830Sdim StringRef getInputConstraint(unsigned i) const { 1730251662Sdim assert(i < NumInputs); 1731243830Sdim return Constraints[i + NumOutputs]; 1732243830Sdim } 1733243830Sdim 1734243830Sdim Expr *getInputExpr(unsigned i); 1735243830Sdim void setInputExpr(unsigned i, Expr *E); 1736243830Sdim 1737243830Sdim const Expr *getInputExpr(unsigned i) const { 1738243830Sdim return const_cast<MSAsmStmt*>(this)->getInputExpr(i); 1739243830Sdim } 1740243830Sdim 1741239462Sdim //===--- Other ---===// 1742239462Sdim 1743251662Sdim ArrayRef<StringRef> getAllConstraints() const { 1744251662Sdim return ArrayRef<StringRef>(Constraints, NumInputs + NumOutputs); 1745251662Sdim } 1746251662Sdim ArrayRef<StringRef> getClobbers() const { 1747251662Sdim return ArrayRef<StringRef>(Clobbers, NumClobbers); 1748251662Sdim } 1749251662Sdim ArrayRef<Expr*> getAllExprs() const { 1750251662Sdim return ArrayRef<Expr*>(reinterpret_cast<Expr**>(Exprs), 1751251662Sdim NumInputs + NumOutputs); 1752251662Sdim } 1753239462Sdim 1754251662Sdim StringRef getClobber(unsigned i) const { return getClobbers()[i]; } 1755251662Sdim 1756251662Sdimprivate: 1757263508Sdim void initialize(const ASTContext &C, StringRef AsmString, 1758263508Sdim ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints, 1759263508Sdim ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers); 1760251662Sdimpublic: 1761251662Sdim 1762249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; } 1763249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; } 1764249423Sdim 1765239462Sdim static bool classof(const Stmt *T) { 1766239462Sdim return T->getStmtClass() == MSAsmStmtClass; 1767239462Sdim } 1768239462Sdim 1769239462Sdim child_range children() { 1770239462Sdim return child_range(&Exprs[0], &Exprs[0]); 1771239462Sdim } 1772239462Sdim}; 1773239462Sdim 1774221345Sdimclass SEHExceptStmt : public Stmt { 1775221345Sdim SourceLocation Loc; 1776221345Sdim Stmt *Children[2]; 1777221345Sdim 1778221345Sdim enum { FILTER_EXPR, BLOCK }; 1779221345Sdim 1780221345Sdim SEHExceptStmt(SourceLocation Loc, 1781221345Sdim Expr *FilterExpr, 1782221345Sdim Stmt *Block); 1783221345Sdim 1784224145Sdim friend class ASTReader; 1785224145Sdim friend class ASTStmtReader; 1786224145Sdim explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { } 1787224145Sdim 1788221345Sdimpublic: 1789263508Sdim static SEHExceptStmt* Create(const ASTContext &C, 1790221345Sdim SourceLocation ExceptLoc, 1791221345Sdim Expr *FilterExpr, 1792221345Sdim Stmt *Block); 1793221345Sdim 1794249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return getExceptLoc(); } 1795249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } 1796249423Sdim 1797221345Sdim SourceLocation getExceptLoc() const { return Loc; } 1798221345Sdim SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); } 1799221345Sdim 1800234353Sdim Expr *getFilterExpr() const { 1801234353Sdim return reinterpret_cast<Expr*>(Children[FILTER_EXPR]); 1802234353Sdim } 1803221345Sdim 1804234353Sdim CompoundStmt *getBlock() const { 1805249423Sdim return cast<CompoundStmt>(Children[BLOCK]); 1806234353Sdim } 1807234353Sdim 1808221345Sdim child_range children() { 1809221345Sdim return child_range(Children,Children+2); 1810221345Sdim } 1811221345Sdim 1812221345Sdim static bool classof(const Stmt *T) { 1813221345Sdim return T->getStmtClass() == SEHExceptStmtClass; 1814221345Sdim } 1815221345Sdim 1816221345Sdim}; 1817221345Sdim 1818221345Sdimclass SEHFinallyStmt : public Stmt { 1819221345Sdim SourceLocation Loc; 1820221345Sdim Stmt *Block; 1821221345Sdim 1822221345Sdim SEHFinallyStmt(SourceLocation Loc, 1823221345Sdim Stmt *Block); 1824221345Sdim 1825224145Sdim friend class ASTReader; 1826224145Sdim friend class ASTStmtReader; 1827224145Sdim explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { } 1828224145Sdim 1829221345Sdimpublic: 1830263508Sdim static SEHFinallyStmt* Create(const ASTContext &C, 1831221345Sdim SourceLocation FinallyLoc, 1832221345Sdim Stmt *Block); 1833221345Sdim 1834249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return getFinallyLoc(); } 1835249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } 1836221345Sdim 1837221345Sdim SourceLocation getFinallyLoc() const { return Loc; } 1838221345Sdim SourceLocation getEndLoc() const { return Block->getLocEnd(); } 1839221345Sdim 1840249423Sdim CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); } 1841221345Sdim 1842221345Sdim child_range children() { 1843221345Sdim return child_range(&Block,&Block+1); 1844221345Sdim } 1845221345Sdim 1846221345Sdim static bool classof(const Stmt *T) { 1847221345Sdim return T->getStmtClass() == SEHFinallyStmtClass; 1848221345Sdim } 1849221345Sdim 1850221345Sdim}; 1851221345Sdim 1852221345Sdimclass SEHTryStmt : public Stmt { 1853221345Sdim bool IsCXXTry; 1854221345Sdim SourceLocation TryLoc; 1855221345Sdim Stmt *Children[2]; 1856221345Sdim 1857221345Sdim enum { TRY = 0, HANDLER = 1 }; 1858221345Sdim 1859221345Sdim SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try' 1860221345Sdim SourceLocation TryLoc, 1861221345Sdim Stmt *TryBlock, 1862221345Sdim Stmt *Handler); 1863221345Sdim 1864224145Sdim friend class ASTReader; 1865224145Sdim friend class ASTStmtReader; 1866224145Sdim explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { } 1867224145Sdim 1868221345Sdimpublic: 1869263508Sdim static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry, 1870263508Sdim SourceLocation TryLoc, Stmt *TryBlock, 1871221345Sdim Stmt *Handler); 1872221345Sdim 1873249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } 1874249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } 1875221345Sdim 1876221345Sdim SourceLocation getTryLoc() const { return TryLoc; } 1877221345Sdim SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); } 1878221345Sdim 1879221345Sdim bool getIsCXXTry() const { return IsCXXTry; } 1880234353Sdim 1881234353Sdim CompoundStmt* getTryBlock() const { 1882249423Sdim return cast<CompoundStmt>(Children[TRY]); 1883234353Sdim } 1884234353Sdim 1885221345Sdim Stmt *getHandler() const { return Children[HANDLER]; } 1886221345Sdim 1887221345Sdim /// Returns 0 if not defined 1888221345Sdim SEHExceptStmt *getExceptHandler() const; 1889221345Sdim SEHFinallyStmt *getFinallyHandler() const; 1890221345Sdim 1891221345Sdim child_range children() { 1892221345Sdim return child_range(Children,Children+2); 1893221345Sdim } 1894221345Sdim 1895221345Sdim static bool classof(const Stmt *T) { 1896221345Sdim return T->getStmtClass() == SEHTryStmtClass; 1897221345Sdim } 1898221345Sdim}; 1899221345Sdim 1900251662Sdim/// \brief This captures a statement into a function. For example, the following 1901251662Sdim/// pragma annotated compound statement can be represented as a CapturedStmt, 1902251662Sdim/// and this compound statement is the body of an anonymous outlined function. 1903251662Sdim/// @code 1904251662Sdim/// #pragma omp parallel 1905251662Sdim/// { 1906251662Sdim/// compute(); 1907251662Sdim/// } 1908251662Sdim/// @endcode 1909251662Sdimclass CapturedStmt : public Stmt { 1910251662Sdimpublic: 1911251662Sdim /// \brief The different capture forms: by 'this' or by reference, etc. 1912251662Sdim enum VariableCaptureKind { 1913251662Sdim VCK_This, 1914251662Sdim VCK_ByRef 1915251662Sdim }; 1916251662Sdim 1917251662Sdim /// \brief Describes the capture of either a variable or 'this'. 1918251662Sdim class Capture { 1919251662Sdim llvm::PointerIntPair<VarDecl *, 1, VariableCaptureKind> VarAndKind; 1920251662Sdim SourceLocation Loc; 1921251662Sdim 1922251662Sdim public: 1923251662Sdim /// \brief Create a new capture. 1924251662Sdim /// 1925251662Sdim /// \param Loc The source location associated with this capture. 1926251662Sdim /// 1927251662Sdim /// \param Kind The kind of capture (this, ByRef, ...). 1928251662Sdim /// 1929251662Sdim /// \param Var The variable being captured, or null if capturing this. 1930251662Sdim /// 1931251662Sdim Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var = 0) 1932251662Sdim : VarAndKind(Var, Kind), Loc(Loc) { 1933251662Sdim switch (Kind) { 1934251662Sdim case VCK_This: 1935251662Sdim assert(Var == 0 && "'this' capture cannot have a variable!"); 1936251662Sdim break; 1937251662Sdim case VCK_ByRef: 1938251662Sdim assert(Var && "capturing by reference must have a variable!"); 1939251662Sdim break; 1940251662Sdim } 1941251662Sdim } 1942251662Sdim 1943251662Sdim /// \brief Determine the kind of capture. 1944251662Sdim VariableCaptureKind getCaptureKind() const { return VarAndKind.getInt(); } 1945251662Sdim 1946251662Sdim /// \brief Retrieve the source location at which the variable or 'this' was 1947251662Sdim /// first used. 1948251662Sdim SourceLocation getLocation() const { return Loc; } 1949251662Sdim 1950251662Sdim /// \brief Determine whether this capture handles the C++ 'this' pointer. 1951251662Sdim bool capturesThis() const { return getCaptureKind() == VCK_This; } 1952251662Sdim 1953251662Sdim /// \brief Determine whether this capture handles a variable. 1954251662Sdim bool capturesVariable() const { return getCaptureKind() != VCK_This; } 1955251662Sdim 1956251662Sdim /// \brief Retrieve the declaration of the variable being captured. 1957251662Sdim /// 1958251662Sdim /// This operation is only valid if this capture does not capture 'this'. 1959251662Sdim VarDecl *getCapturedVar() const { 1960251662Sdim assert(!capturesThis() && "No variable available for 'this' capture"); 1961251662Sdim return VarAndKind.getPointer(); 1962251662Sdim } 1963251662Sdim friend class ASTStmtReader; 1964251662Sdim }; 1965251662Sdim 1966251662Sdimprivate: 1967251662Sdim /// \brief The number of variable captured, including 'this'. 1968251662Sdim unsigned NumCaptures; 1969251662Sdim 1970251662Sdim /// \brief The pointer part is the implicit the outlined function and the 1971251662Sdim /// int part is the captured region kind, 'CR_Default' etc. 1972251662Sdim llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind; 1973251662Sdim 1974251662Sdim /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl. 1975251662Sdim RecordDecl *TheRecordDecl; 1976251662Sdim 1977251662Sdim /// \brief Construct a captured statement. 1978251662Sdim CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures, 1979251662Sdim ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD); 1980251662Sdim 1981251662Sdim /// \brief Construct an empty captured statement. 1982251662Sdim CapturedStmt(EmptyShell Empty, unsigned NumCaptures); 1983251662Sdim 1984251662Sdim Stmt **getStoredStmts() const { 1985251662Sdim return reinterpret_cast<Stmt **>(const_cast<CapturedStmt *>(this) + 1); 1986251662Sdim } 1987251662Sdim 1988251662Sdim Capture *getStoredCaptures() const; 1989251662Sdim 1990251662Sdim void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; } 1991251662Sdim 1992251662Sdimpublic: 1993263508Sdim static CapturedStmt *Create(const ASTContext &Context, Stmt *S, 1994251662Sdim CapturedRegionKind Kind, 1995251662Sdim ArrayRef<Capture> Captures, 1996251662Sdim ArrayRef<Expr *> CaptureInits, 1997251662Sdim CapturedDecl *CD, RecordDecl *RD); 1998251662Sdim 1999263508Sdim static CapturedStmt *CreateDeserialized(const ASTContext &Context, 2000251662Sdim unsigned NumCaptures); 2001251662Sdim 2002251662Sdim /// \brief Retrieve the statement being captured. 2003251662Sdim Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; } 2004251662Sdim const Stmt *getCapturedStmt() const { 2005251662Sdim return const_cast<CapturedStmt *>(this)->getCapturedStmt(); 2006251662Sdim } 2007251662Sdim 2008251662Sdim /// \brief Retrieve the outlined function declaration. 2009251662Sdim CapturedDecl *getCapturedDecl() { return CapDeclAndKind.getPointer(); } 2010251662Sdim const CapturedDecl *getCapturedDecl() const { 2011251662Sdim return const_cast<CapturedStmt *>(this)->getCapturedDecl(); 2012251662Sdim } 2013251662Sdim 2014251662Sdim /// \brief Set the outlined function declaration. 2015251662Sdim void setCapturedDecl(CapturedDecl *D) { 2016251662Sdim assert(D && "null CapturedDecl"); 2017251662Sdim CapDeclAndKind.setPointer(D); 2018251662Sdim } 2019251662Sdim 2020251662Sdim /// \brief Retrieve the captured region kind. 2021251662Sdim CapturedRegionKind getCapturedRegionKind() const { 2022251662Sdim return CapDeclAndKind.getInt(); 2023251662Sdim } 2024251662Sdim 2025251662Sdim /// \brief Set the captured region kind. 2026251662Sdim void setCapturedRegionKind(CapturedRegionKind Kind) { 2027251662Sdim CapDeclAndKind.setInt(Kind); 2028251662Sdim } 2029251662Sdim 2030251662Sdim /// \brief Retrieve the record declaration for captured variables. 2031251662Sdim const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; } 2032251662Sdim 2033251662Sdim /// \brief Set the record declaration for captured variables. 2034251662Sdim void setCapturedRecordDecl(RecordDecl *D) { 2035251662Sdim assert(D && "null RecordDecl"); 2036251662Sdim TheRecordDecl = D; 2037251662Sdim } 2038251662Sdim 2039251662Sdim /// \brief True if this variable has been captured. 2040251662Sdim bool capturesVariable(const VarDecl *Var) const; 2041251662Sdim 2042251662Sdim /// \brief An iterator that walks over the captures. 2043251662Sdim typedef Capture *capture_iterator; 2044251662Sdim typedef const Capture *const_capture_iterator; 2045251662Sdim 2046251662Sdim /// \brief Retrieve an iterator pointing to the first capture. 2047251662Sdim capture_iterator capture_begin() { return getStoredCaptures(); } 2048251662Sdim const_capture_iterator capture_begin() const { return getStoredCaptures(); } 2049251662Sdim 2050251662Sdim /// \brief Retrieve an iterator pointing past the end of the sequence of 2051251662Sdim /// captures. 2052251662Sdim capture_iterator capture_end() const { 2053251662Sdim return getStoredCaptures() + NumCaptures; 2054251662Sdim } 2055251662Sdim 2056251662Sdim /// \brief Retrieve the number of captures, including 'this'. 2057251662Sdim unsigned capture_size() const { return NumCaptures; } 2058251662Sdim 2059251662Sdim /// \brief Iterator that walks over the capture initialization arguments. 2060251662Sdim typedef Expr **capture_init_iterator; 2061251662Sdim 2062251662Sdim /// \brief Retrieve the first initialization argument. 2063251662Sdim capture_init_iterator capture_init_begin() const { 2064251662Sdim return reinterpret_cast<Expr **>(getStoredStmts()); 2065251662Sdim } 2066251662Sdim 2067251662Sdim /// \brief Retrieve the iterator pointing one past the last initialization 2068251662Sdim /// argument. 2069251662Sdim capture_init_iterator capture_init_end() const { 2070251662Sdim return capture_init_begin() + NumCaptures; 2071251662Sdim } 2072251662Sdim 2073251662Sdim SourceLocation getLocStart() const LLVM_READONLY { 2074251662Sdim return getCapturedStmt()->getLocStart(); 2075251662Sdim } 2076251662Sdim SourceLocation getLocEnd() const LLVM_READONLY { 2077251662Sdim return getCapturedStmt()->getLocEnd(); 2078251662Sdim } 2079251662Sdim SourceRange getSourceRange() const LLVM_READONLY { 2080251662Sdim return getCapturedStmt()->getSourceRange(); 2081251662Sdim } 2082251662Sdim 2083251662Sdim static bool classof(const Stmt *T) { 2084251662Sdim return T->getStmtClass() == CapturedStmtClass; 2085251662Sdim } 2086251662Sdim 2087251662Sdim child_range children(); 2088251662Sdim 2089251662Sdim friend class ASTStmtReader; 2090251662Sdim}; 2091251662Sdim 2092193326Sed} // end namespace clang 2093193326Sed 2094193326Sed#endif 2095