1 //===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the Stmt interface and subclasses. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_STMT_H 15 #define LLVM_CLANG_AST_STMT_H 16 17 #include "clang/Basic/LLVM.h" 18 #include "clang/Basic/SourceLocation.h" 19 #include "clang/AST/PrettyPrinter.h" 20 #include "clang/AST/StmtIterator.h" 21 #include "clang/AST/DeclGroup.h" 22 #include "clang/AST/ASTContext.h" 23 #include "clang/AST/Attr.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include "llvm/Support/Compiler.h" 26 #include "llvm/Support/raw_ostream.h" 27 #include <string> 28 29 namespace llvm { 30 class FoldingSetNodeID; 31 } 32 33 namespace clang { 34 class ASTContext; 35 class Expr; 36 class Decl; 37 class ParmVarDecl; 38 class QualType; 39 class IdentifierInfo; 40 class SourceManager; 41 class StringLiteral; 42 class SwitchStmt; 43 44 //===--------------------------------------------------------------------===// 45 // ExprIterator - Iterators for iterating over Stmt* arrays that contain 46 // only Expr*. This is needed because AST nodes use Stmt* arrays to store 47 // references to children (to be compatible with StmtIterator). 48 //===--------------------------------------------------------------------===// 49 50 class Stmt; 51 class Expr; 52 53 class ExprIterator { 54 Stmt** I; 55 public: ExprIterator(Stmt ** i)56 ExprIterator(Stmt** i) : I(i) {} ExprIterator()57 ExprIterator() : I(0) {} 58 ExprIterator& operator++() { ++I; return *this; } 59 ExprIterator operator-(size_t i) { return I-i; } 60 ExprIterator operator+(size_t i) { return I+i; } 61 Expr* operator[](size_t idx); 62 // FIXME: Verify that this will correctly return a signed distance. 63 signed operator-(const ExprIterator& R) const { return I - R.I; } 64 Expr* operator*() const; 65 Expr* operator->() const; 66 bool operator==(const ExprIterator& R) const { return I == R.I; } 67 bool operator!=(const ExprIterator& R) const { return I != R.I; } 68 bool operator>(const ExprIterator& R) const { return I > R.I; } 69 bool operator>=(const ExprIterator& R) const { return I >= R.I; } 70 }; 71 72 class ConstExprIterator { 73 const Stmt * const *I; 74 public: ConstExprIterator(const Stmt * const * i)75 ConstExprIterator(const Stmt * const *i) : I(i) {} ConstExprIterator()76 ConstExprIterator() : I(0) {} 77 ConstExprIterator& operator++() { ++I; return *this; } 78 ConstExprIterator operator+(size_t i) const { return I+i; } 79 ConstExprIterator operator-(size_t i) const { return I-i; } 80 const Expr * operator[](size_t idx) const; 81 signed operator-(const ConstExprIterator& R) const { return I - R.I; } 82 const Expr * operator*() const; 83 const Expr * operator->() const; 84 bool operator==(const ConstExprIterator& R) const { return I == R.I; } 85 bool operator!=(const ConstExprIterator& R) const { return I != R.I; } 86 bool operator>(const ConstExprIterator& R) const { return I > R.I; } 87 bool operator>=(const ConstExprIterator& R) const { return I >= R.I; } 88 }; 89 90 //===----------------------------------------------------------------------===// 91 // AST classes for statements. 92 //===----------------------------------------------------------------------===// 93 94 /// Stmt - This represents one statement. 95 /// 96 class Stmt { 97 public: 98 enum StmtClass { 99 NoStmtClass = 0, 100 #define STMT(CLASS, PARENT) CLASS##Class, 101 #define STMT_RANGE(BASE, FIRST, LAST) \ 102 first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class, 103 #define LAST_STMT_RANGE(BASE, FIRST, LAST) \ 104 first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class 105 #define ABSTRACT_STMT(STMT) 106 #include "clang/AST/StmtNodes.inc" 107 }; 108 109 // Make vanilla 'new' and 'delete' illegal for Stmts. 110 protected: new(size_t bytes)111 void* operator new(size_t bytes) throw() { 112 llvm_unreachable("Stmts cannot be allocated with regular 'new'."); 113 } delete(void * data)114 void operator delete(void* data) throw() { 115 llvm_unreachable("Stmts cannot be released with regular 'delete'."); 116 } 117 118 class StmtBitfields { 119 friend class Stmt; 120 121 /// \brief The statement class. 122 unsigned sClass : 8; 123 }; 124 enum { NumStmtBits = 8 }; 125 126 class CompoundStmtBitfields { 127 friend class CompoundStmt; 128 unsigned : NumStmtBits; 129 130 unsigned NumStmts : 32 - NumStmtBits; 131 }; 132 133 class ExprBitfields { 134 friend class Expr; 135 friend class DeclRefExpr; // computeDependence 136 friend class InitListExpr; // ctor 137 friend class DesignatedInitExpr; // ctor 138 friend class BlockDeclRefExpr; // ctor 139 friend class ASTStmtReader; // deserialization 140 friend class CXXNewExpr; // ctor 141 friend class DependentScopeDeclRefExpr; // ctor 142 friend class CXXConstructExpr; // ctor 143 friend class CallExpr; // ctor 144 friend class OffsetOfExpr; // ctor 145 friend class ObjCMessageExpr; // ctor 146 friend class ObjCArrayLiteral; // ctor 147 friend class ObjCDictionaryLiteral; // ctor 148 friend class ShuffleVectorExpr; // ctor 149 friend class ParenListExpr; // ctor 150 friend class CXXUnresolvedConstructExpr; // ctor 151 friend class CXXDependentScopeMemberExpr; // ctor 152 friend class OverloadExpr; // ctor 153 friend class PseudoObjectExpr; // ctor 154 friend class AtomicExpr; // ctor 155 unsigned : NumStmtBits; 156 157 unsigned ValueKind : 2; 158 unsigned ObjectKind : 2; 159 unsigned TypeDependent : 1; 160 unsigned ValueDependent : 1; 161 unsigned InstantiationDependent : 1; 162 unsigned ContainsUnexpandedParameterPack : 1; 163 }; 164 enum { NumExprBits = 16 }; 165 166 class CharacterLiteralBitfields { 167 friend class CharacterLiteral; 168 unsigned : NumExprBits; 169 170 unsigned Kind : 2; 171 }; 172 173 class FloatingLiteralBitfields { 174 friend class FloatingLiteral; 175 unsigned : NumExprBits; 176 177 unsigned IsIEEE : 1; // Distinguishes between PPC128 and IEEE128. 178 unsigned IsExact : 1; 179 }; 180 181 class UnaryExprOrTypeTraitExprBitfields { 182 friend class UnaryExprOrTypeTraitExpr; 183 unsigned : NumExprBits; 184 185 unsigned Kind : 2; 186 unsigned IsType : 1; // true if operand is a type, false if an expression. 187 }; 188 189 class DeclRefExprBitfields { 190 friend class DeclRefExpr; 191 friend class ASTStmtReader; // deserialization 192 unsigned : NumExprBits; 193 194 unsigned HasQualifier : 1; 195 unsigned HasTemplateKWAndArgsInfo : 1; 196 unsigned HasFoundDecl : 1; 197 unsigned HadMultipleCandidates : 1; 198 unsigned RefersToEnclosingLocal : 1; 199 }; 200 201 class CastExprBitfields { 202 friend class CastExpr; 203 unsigned : NumExprBits; 204 205 unsigned Kind : 6; 206 unsigned BasePathSize : 32 - 6 - NumExprBits; 207 }; 208 209 class CallExprBitfields { 210 friend class CallExpr; 211 unsigned : NumExprBits; 212 213 unsigned NumPreArgs : 1; 214 }; 215 216 class ExprWithCleanupsBitfields { 217 friend class ExprWithCleanups; 218 friend class ASTStmtReader; // deserialization 219 220 unsigned : NumExprBits; 221 222 unsigned NumObjects : 32 - NumExprBits; 223 }; 224 225 class PseudoObjectExprBitfields { 226 friend class PseudoObjectExpr; 227 friend class ASTStmtReader; // deserialization 228 229 unsigned : NumExprBits; 230 231 // These don't need to be particularly wide, because they're 232 // strictly limited by the forms of expressions we permit. 233 unsigned NumSubExprs : 8; 234 unsigned ResultIndex : 32 - 8 - NumExprBits; 235 }; 236 237 class ObjCIndirectCopyRestoreExprBitfields { 238 friend class ObjCIndirectCopyRestoreExpr; 239 unsigned : NumExprBits; 240 241 unsigned ShouldCopy : 1; 242 }; 243 244 class InitListExprBitfields { 245 friend class InitListExpr; 246 247 unsigned : NumExprBits; 248 249 /// Whether this initializer list originally had a GNU array-range 250 /// designator in it. This is a temporary marker used by CodeGen. 251 unsigned HadArrayRangeDesignator : 1; 252 253 /// Whether this initializer list initializes a std::initializer_list 254 /// object. 255 unsigned InitializesStdInitializerList : 1; 256 }; 257 258 class TypeTraitExprBitfields { 259 friend class TypeTraitExpr; 260 friend class ASTStmtReader; 261 friend class ASTStmtWriter; 262 263 unsigned : NumExprBits; 264 265 /// \brief The kind of type trait, which is a value of a TypeTrait enumerator. 266 unsigned Kind : 8; 267 268 /// \brief If this expression is not value-dependent, this indicates whether 269 /// the trait evaluated true or false. 270 unsigned Value : 1; 271 272 /// \brief The number of arguments to this type trait. 273 unsigned NumArgs : 32 - 8 - 1 - NumExprBits; 274 }; 275 276 union { 277 // FIXME: this is wasteful on 64-bit platforms. 278 void *Aligner; 279 280 StmtBitfields StmtBits; 281 CompoundStmtBitfields CompoundStmtBits; 282 ExprBitfields ExprBits; 283 CharacterLiteralBitfields CharacterLiteralBits; 284 FloatingLiteralBitfields FloatingLiteralBits; 285 UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits; 286 DeclRefExprBitfields DeclRefExprBits; 287 CastExprBitfields CastExprBits; 288 CallExprBitfields CallExprBits; 289 ExprWithCleanupsBitfields ExprWithCleanupsBits; 290 PseudoObjectExprBitfields PseudoObjectExprBits; 291 ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits; 292 InitListExprBitfields InitListExprBits; 293 TypeTraitExprBitfields TypeTraitExprBits; 294 }; 295 296 friend class ASTStmtReader; 297 friend class ASTStmtWriter; 298 299 public: 300 // Only allow allocation of Stmts using the allocator in ASTContext 301 // or by doing a placement new. 302 void* operator new(size_t bytes, ASTContext& C, throw()303 unsigned alignment = 8) throw() { 304 return ::operator new(bytes, C, alignment); 305 } 306 307 void* operator new(size_t bytes, ASTContext* C, throw()308 unsigned alignment = 8) throw() { 309 return ::operator new(bytes, *C, alignment); 310 } 311 new(size_t bytes,void * mem)312 void* operator new(size_t bytes, void* mem) throw() { 313 return mem; 314 } 315 delete(void *,ASTContext &,unsigned)316 void operator delete(void*, ASTContext&, unsigned) throw() { } delete(void *,ASTContext *,unsigned)317 void operator delete(void*, ASTContext*, unsigned) throw() { } delete(void *,std::size_t)318 void operator delete(void*, std::size_t) throw() { } delete(void *,void *)319 void operator delete(void*, void*) throw() { } 320 321 public: 322 /// \brief A placeholder type used to construct an empty shell of a 323 /// type, that will be filled in later (e.g., by some 324 /// de-serialization). 325 struct EmptyShell { }; 326 327 private: 328 /// \brief Whether statistic collection is enabled. 329 static bool StatisticsEnabled; 330 331 protected: 332 /// \brief Construct an empty statement. Stmt(StmtClass SC,EmptyShell)333 explicit Stmt(StmtClass SC, EmptyShell) { 334 StmtBits.sClass = SC; 335 if (StatisticsEnabled) Stmt::addStmtClass(SC); 336 } 337 338 public: Stmt(StmtClass SC)339 Stmt(StmtClass SC) { 340 StmtBits.sClass = SC; 341 if (StatisticsEnabled) Stmt::addStmtClass(SC); 342 } 343 getStmtClass()344 StmtClass getStmtClass() const { 345 return static_cast<StmtClass>(StmtBits.sClass); 346 } 347 const char *getStmtClassName() const; 348 349 /// SourceLocation tokens are not useful in isolation - they are low level 350 /// value objects created/interpreted by SourceManager. We assume AST 351 /// clients will have a pointer to the respective SourceManager. 352 SourceRange getSourceRange() const LLVM_READONLY; 353 SourceLocation getLocStart() const LLVM_READONLY; 354 SourceLocation getLocEnd() const LLVM_READONLY; 355 356 // global temp stats (until we have a per-module visitor) 357 static void addStmtClass(const StmtClass s); 358 static void EnableStatistics(); 359 static void PrintStats(); 360 361 /// dump - This does a local dump of the specified AST fragment. It dumps the 362 /// specified node and a few nodes underneath it, but not the whole subtree. 363 /// This is useful in a debugger. 364 LLVM_ATTRIBUTE_USED void dump() const; 365 LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const; 366 void dump(raw_ostream &OS, SourceManager &SM) const; 367 368 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 369 void dumpAll() const; 370 void dumpAll(SourceManager &SM) const; 371 372 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 373 /// back to its original source language syntax. 374 void dumpPretty(ASTContext& Context) const; 375 void printPretty(raw_ostream &OS, PrinterHelper *Helper, 376 const PrintingPolicy &Policy, 377 unsigned Indentation = 0) const { 378 printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation); 379 } 380 void printPretty(raw_ostream &OS, ASTContext &Context, 381 PrinterHelper *Helper, 382 const PrintingPolicy &Policy, 383 unsigned Indentation = 0) const; 384 385 /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only 386 /// works on systems with GraphViz (Mac OS X) or dot+gv installed. 387 void viewAST() const; 388 389 /// Skip past any implicit AST nodes which might surround this 390 /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes. 391 Stmt *IgnoreImplicit(); 392 393 const Stmt *stripLabelLikeStatements() const; stripLabelLikeStatements()394 Stmt *stripLabelLikeStatements() { 395 return const_cast<Stmt*>( 396 const_cast<const Stmt*>(this)->stripLabelLikeStatements()); 397 } 398 399 // Implement isa<T> support. classof(const Stmt *)400 static bool classof(const Stmt *) { return true; } 401 402 /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) 403 /// contain implicit control-flow in the order their subexpressions 404 /// are evaluated. This predicate returns true if this statement has 405 /// such implicit control-flow. Such statements are also specially handled 406 /// within CFGs. 407 bool hasImplicitControlFlow() const; 408 409 /// Child Iterators: All subclasses must implement 'children' 410 /// to permit easy iteration over the substatements/subexpessions of an 411 /// AST node. This permits easy iteration over all nodes in the AST. 412 typedef StmtIterator child_iterator; 413 typedef ConstStmtIterator const_child_iterator; 414 415 typedef StmtRange child_range; 416 typedef ConstStmtRange const_child_range; 417 418 child_range children(); children()419 const_child_range children() const { 420 return const_cast<Stmt*>(this)->children(); 421 } 422 child_begin()423 child_iterator child_begin() { return children().first; } child_end()424 child_iterator child_end() { return children().second; } 425 child_begin()426 const_child_iterator child_begin() const { return children().first; } child_end()427 const_child_iterator child_end() const { return children().second; } 428 429 /// \brief Produce a unique representation of the given statement. 430 /// 431 /// \brief ID once the profiling operation is complete, will contain 432 /// the unique representation of the given statement. 433 /// 434 /// \brief Context the AST context in which the statement resides 435 /// 436 /// \brief Canonical whether the profile should be based on the canonical 437 /// representation of this statement (e.g., where non-type template 438 /// parameters are identified by index/level rather than their 439 /// declaration pointers) or the exact representation of the statement as 440 /// written in the source. 441 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 442 bool Canonical) const; 443 }; 444 445 /// DeclStmt - Adaptor class for mixing declarations with statements and 446 /// expressions. For example, CompoundStmt mixes statements, expressions 447 /// and declarations (variables, types). Another example is ForStmt, where 448 /// the first statement can be an expression or a declaration. 449 /// 450 class DeclStmt : public Stmt { 451 DeclGroupRef DG; 452 SourceLocation StartLoc, EndLoc; 453 454 public: DeclStmt(DeclGroupRef dg,SourceLocation startLoc,SourceLocation endLoc)455 DeclStmt(DeclGroupRef dg, SourceLocation startLoc, 456 SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg), 457 StartLoc(startLoc), EndLoc(endLoc) {} 458 459 /// \brief Build an empty declaration statement. DeclStmt(EmptyShell Empty)460 explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { } 461 462 /// isSingleDecl - This method returns true if this DeclStmt refers 463 /// to a single Decl. isSingleDecl()464 bool isSingleDecl() const { 465 return DG.isSingleDecl(); 466 } 467 getSingleDecl()468 const Decl *getSingleDecl() const { return DG.getSingleDecl(); } getSingleDecl()469 Decl *getSingleDecl() { return DG.getSingleDecl(); } 470 getDeclGroup()471 const DeclGroupRef getDeclGroup() const { return DG; } getDeclGroup()472 DeclGroupRef getDeclGroup() { return DG; } setDeclGroup(DeclGroupRef DGR)473 void setDeclGroup(DeclGroupRef DGR) { DG = DGR; } 474 getStartLoc()475 SourceLocation getStartLoc() const { return StartLoc; } setStartLoc(SourceLocation L)476 void setStartLoc(SourceLocation L) { StartLoc = L; } getEndLoc()477 SourceLocation getEndLoc() const { return EndLoc; } setEndLoc(SourceLocation L)478 void setEndLoc(SourceLocation L) { EndLoc = L; } 479 getSourceRange()480 SourceRange getSourceRange() const LLVM_READONLY { 481 return SourceRange(StartLoc, EndLoc); 482 } 483 classof(const Stmt * T)484 static bool classof(const Stmt *T) { 485 return T->getStmtClass() == DeclStmtClass; 486 } classof(const DeclStmt *)487 static bool classof(const DeclStmt *) { return true; } 488 489 // Iterators over subexpressions. children()490 child_range children() { 491 return child_range(child_iterator(DG.begin(), DG.end()), 492 child_iterator(DG.end(), DG.end())); 493 } 494 495 typedef DeclGroupRef::iterator decl_iterator; 496 typedef DeclGroupRef::const_iterator const_decl_iterator; 497 decl_begin()498 decl_iterator decl_begin() { return DG.begin(); } decl_end()499 decl_iterator decl_end() { return DG.end(); } decl_begin()500 const_decl_iterator decl_begin() const { return DG.begin(); } decl_end()501 const_decl_iterator decl_end() const { return DG.end(); } 502 }; 503 504 /// NullStmt - This is the null statement ";": C99 6.8.3p3. 505 /// 506 class NullStmt : public Stmt { 507 SourceLocation SemiLoc; 508 509 /// \brief True if the null statement was preceded by an empty macro, e.g: 510 /// @code 511 /// #define CALL(x) 512 /// CALL(0); 513 /// @endcode 514 bool HasLeadingEmptyMacro; 515 public: 516 NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false) Stmt(NullStmtClass)517 : Stmt(NullStmtClass), SemiLoc(L), 518 HasLeadingEmptyMacro(hasLeadingEmptyMacro) {} 519 520 /// \brief Build an empty null statement. NullStmt(EmptyShell Empty)521 explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty), 522 HasLeadingEmptyMacro(false) { } 523 getSemiLoc()524 SourceLocation getSemiLoc() const { return SemiLoc; } setSemiLoc(SourceLocation L)525 void setSemiLoc(SourceLocation L) { SemiLoc = L; } 526 hasLeadingEmptyMacro()527 bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; } 528 getSourceRange()529 SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(SemiLoc); } 530 classof(const Stmt * T)531 static bool classof(const Stmt *T) { 532 return T->getStmtClass() == NullStmtClass; 533 } classof(const NullStmt *)534 static bool classof(const NullStmt *) { return true; } 535 children()536 child_range children() { return child_range(); } 537 538 friend class ASTStmtReader; 539 friend class ASTStmtWriter; 540 }; 541 542 /// CompoundStmt - This represents a group of statements like { stmt stmt }. 543 /// 544 class CompoundStmt : public Stmt { 545 Stmt** Body; 546 SourceLocation LBracLoc, RBracLoc; 547 public: CompoundStmt(ASTContext & C,Stmt ** StmtStart,unsigned NumStmts,SourceLocation LB,SourceLocation RB)548 CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned NumStmts, 549 SourceLocation LB, SourceLocation RB) 550 : Stmt(CompoundStmtClass), LBracLoc(LB), RBracLoc(RB) { 551 CompoundStmtBits.NumStmts = NumStmts; 552 assert(CompoundStmtBits.NumStmts == NumStmts && 553 "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!"); 554 555 if (NumStmts == 0) { 556 Body = 0; 557 return; 558 } 559 560 Body = new (C) Stmt*[NumStmts]; 561 memcpy(Body, StmtStart, NumStmts * sizeof(*Body)); 562 } 563 564 // \brief Build an empty compound statement. CompoundStmt(EmptyShell Empty)565 explicit CompoundStmt(EmptyShell Empty) 566 : Stmt(CompoundStmtClass, Empty), Body(0) { 567 CompoundStmtBits.NumStmts = 0; 568 } 569 570 void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts); 571 body_empty()572 bool body_empty() const { return CompoundStmtBits.NumStmts == 0; } size()573 unsigned size() const { return CompoundStmtBits.NumStmts; } 574 575 typedef Stmt** body_iterator; body_begin()576 body_iterator body_begin() { return Body; } body_end()577 body_iterator body_end() { return Body + size(); } body_back()578 Stmt *body_back() { return !body_empty() ? Body[size()-1] : 0; } 579 setLastStmt(Stmt * S)580 void setLastStmt(Stmt *S) { 581 assert(!body_empty() && "setLastStmt"); 582 Body[size()-1] = S; 583 } 584 585 typedef Stmt* const * const_body_iterator; body_begin()586 const_body_iterator body_begin() const { return Body; } body_end()587 const_body_iterator body_end() const { return Body + size(); } body_back()588 const Stmt *body_back() const { return !body_empty() ? Body[size()-1] : 0; } 589 590 typedef std::reverse_iterator<body_iterator> reverse_body_iterator; body_rbegin()591 reverse_body_iterator body_rbegin() { 592 return reverse_body_iterator(body_end()); 593 } body_rend()594 reverse_body_iterator body_rend() { 595 return reverse_body_iterator(body_begin()); 596 } 597 598 typedef std::reverse_iterator<const_body_iterator> 599 const_reverse_body_iterator; 600 body_rbegin()601 const_reverse_body_iterator body_rbegin() const { 602 return const_reverse_body_iterator(body_end()); 603 } 604 body_rend()605 const_reverse_body_iterator body_rend() const { 606 return const_reverse_body_iterator(body_begin()); 607 } 608 getSourceRange()609 SourceRange getSourceRange() const LLVM_READONLY { 610 return SourceRange(LBracLoc, RBracLoc); 611 } 612 getLBracLoc()613 SourceLocation getLBracLoc() const { return LBracLoc; } setLBracLoc(SourceLocation L)614 void setLBracLoc(SourceLocation L) { LBracLoc = L; } getRBracLoc()615 SourceLocation getRBracLoc() const { return RBracLoc; } setRBracLoc(SourceLocation L)616 void setRBracLoc(SourceLocation L) { RBracLoc = L; } 617 classof(const Stmt * T)618 static bool classof(const Stmt *T) { 619 return T->getStmtClass() == CompoundStmtClass; 620 } classof(const CompoundStmt *)621 static bool classof(const CompoundStmt *) { return true; } 622 623 // Iterators children()624 child_range children() { 625 return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts); 626 } 627 children()628 const_child_range children() const { 629 return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts); 630 } 631 }; 632 633 // SwitchCase is the base class for CaseStmt and DefaultStmt, 634 class SwitchCase : public Stmt { 635 protected: 636 // A pointer to the following CaseStmt or DefaultStmt class, 637 // used by SwitchStmt. 638 SwitchCase *NextSwitchCase; 639 SwitchCase(StmtClass SC)640 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 641 642 public: getNextSwitchCase()643 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 644 getNextSwitchCase()645 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 646 setNextSwitchCase(SwitchCase * SC)647 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 648 649 Stmt *getSubStmt(); getSubStmt()650 const Stmt *getSubStmt() const { 651 return const_cast<SwitchCase*>(this)->getSubStmt(); 652 } 653 getSourceRange()654 SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); } 655 classof(const Stmt * T)656 static bool classof(const Stmt *T) { 657 return T->getStmtClass() == CaseStmtClass || 658 T->getStmtClass() == DefaultStmtClass; 659 } classof(const SwitchCase *)660 static bool classof(const SwitchCase *) { return true; } 661 }; 662 663 class CaseStmt : public SwitchCase { 664 enum { LHS, RHS, SUBSTMT, END_EXPR }; 665 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 666 // GNU "case 1 ... 4" extension 667 SourceLocation CaseLoc; 668 SourceLocation EllipsisLoc; 669 SourceLocation ColonLoc; 670 public: CaseStmt(Expr * lhs,Expr * rhs,SourceLocation caseLoc,SourceLocation ellipsisLoc,SourceLocation colonLoc)671 CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc, 672 SourceLocation ellipsisLoc, SourceLocation colonLoc) 673 : SwitchCase(CaseStmtClass) { 674 SubExprs[SUBSTMT] = 0; 675 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 676 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 677 CaseLoc = caseLoc; 678 EllipsisLoc = ellipsisLoc; 679 ColonLoc = colonLoc; 680 } 681 682 /// \brief Build an empty switch case statement. CaseStmt(EmptyShell Empty)683 explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { } 684 getCaseLoc()685 SourceLocation getCaseLoc() const { return CaseLoc; } setCaseLoc(SourceLocation L)686 void setCaseLoc(SourceLocation L) { CaseLoc = L; } getEllipsisLoc()687 SourceLocation getEllipsisLoc() const { return EllipsisLoc; } setEllipsisLoc(SourceLocation L)688 void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; } getColonLoc()689 SourceLocation getColonLoc() const { return ColonLoc; } setColonLoc(SourceLocation L)690 void setColonLoc(SourceLocation L) { ColonLoc = L; } 691 getLHS()692 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } getRHS()693 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } getSubStmt()694 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 695 getLHS()696 const Expr *getLHS() const { 697 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 698 } getRHS()699 const Expr *getRHS() const { 700 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 701 } getSubStmt()702 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 703 setSubStmt(Stmt * S)704 void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; } setLHS(Expr * Val)705 void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); } setRHS(Expr * Val)706 void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); } 707 708 getSourceRange()709 SourceRange getSourceRange() const LLVM_READONLY { 710 // Handle deeply nested case statements with iteration instead of recursion. 711 const CaseStmt *CS = this; 712 while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt())) 713 CS = CS2; 714 715 return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd()); 716 } classof(const Stmt * T)717 static bool classof(const Stmt *T) { 718 return T->getStmtClass() == CaseStmtClass; 719 } classof(const CaseStmt *)720 static bool classof(const CaseStmt *) { return true; } 721 722 // Iterators children()723 child_range children() { 724 return child_range(&SubExprs[0], &SubExprs[END_EXPR]); 725 } 726 }; 727 728 class DefaultStmt : public SwitchCase { 729 Stmt* SubStmt; 730 SourceLocation DefaultLoc; 731 SourceLocation ColonLoc; 732 public: DefaultStmt(SourceLocation DL,SourceLocation CL,Stmt * substmt)733 DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) : 734 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL), 735 ColonLoc(CL) {} 736 737 /// \brief Build an empty default statement. DefaultStmt(EmptyShell)738 explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { } 739 getSubStmt()740 Stmt *getSubStmt() { return SubStmt; } getSubStmt()741 const Stmt *getSubStmt() const { return SubStmt; } setSubStmt(Stmt * S)742 void setSubStmt(Stmt *S) { SubStmt = S; } 743 getDefaultLoc()744 SourceLocation getDefaultLoc() const { return DefaultLoc; } setDefaultLoc(SourceLocation L)745 void setDefaultLoc(SourceLocation L) { DefaultLoc = L; } getColonLoc()746 SourceLocation getColonLoc() const { return ColonLoc; } setColonLoc(SourceLocation L)747 void setColonLoc(SourceLocation L) { ColonLoc = L; } 748 getSourceRange()749 SourceRange getSourceRange() const LLVM_READONLY { 750 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 751 } classof(const Stmt * T)752 static bool classof(const Stmt *T) { 753 return T->getStmtClass() == DefaultStmtClass; 754 } classof(const DefaultStmt *)755 static bool classof(const DefaultStmt *) { return true; } 756 757 // Iterators children()758 child_range children() { return child_range(&SubStmt, &SubStmt+1); } 759 }; 760 761 762 /// LabelStmt - Represents a label, which has a substatement. For example: 763 /// foo: return; 764 /// 765 class LabelStmt : public Stmt { 766 LabelDecl *TheDecl; 767 Stmt *SubStmt; 768 SourceLocation IdentLoc; 769 public: LabelStmt(SourceLocation IL,LabelDecl * D,Stmt * substmt)770 LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt) 771 : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt), IdentLoc(IL) { 772 } 773 774 // \brief Build an empty label statement. LabelStmt(EmptyShell Empty)775 explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { } 776 getIdentLoc()777 SourceLocation getIdentLoc() const { return IdentLoc; } getDecl()778 LabelDecl *getDecl() const { return TheDecl; } setDecl(LabelDecl * D)779 void setDecl(LabelDecl *D) { TheDecl = D; } 780 const char *getName() const; getSubStmt()781 Stmt *getSubStmt() { return SubStmt; } getSubStmt()782 const Stmt *getSubStmt() const { return SubStmt; } setIdentLoc(SourceLocation L)783 void setIdentLoc(SourceLocation L) { IdentLoc = L; } setSubStmt(Stmt * SS)784 void setSubStmt(Stmt *SS) { SubStmt = SS; } 785 getSourceRange()786 SourceRange getSourceRange() const LLVM_READONLY { 787 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 788 } children()789 child_range children() { return child_range(&SubStmt, &SubStmt+1); } 790 classof(const Stmt * T)791 static bool classof(const Stmt *T) { 792 return T->getStmtClass() == LabelStmtClass; 793 } classof(const LabelStmt *)794 static bool classof(const LabelStmt *) { return true; } 795 }; 796 797 798 /// \brief Represents an attribute applied to a statement. 799 /// 800 /// Represents an attribute applied to a statement. For example: 801 /// [[omp::for(...)]] for (...) { ... } 802 /// 803 class AttributedStmt : public Stmt { 804 Stmt *SubStmt; 805 SourceLocation AttrLoc; 806 AttrVec Attrs; 807 // TODO: It can be done as Attr *Attrs[1]; and variable size array as in 808 // StringLiteral 809 810 friend class ASTStmtReader; 811 812 public: AttributedStmt(SourceLocation loc,const AttrVec & attrs,Stmt * substmt)813 AttributedStmt(SourceLocation loc, const AttrVec &attrs, Stmt *substmt) 814 : Stmt(AttributedStmtClass), SubStmt(substmt), AttrLoc(loc), Attrs(attrs) { 815 } 816 817 // \brief Build an empty attributed statement. AttributedStmt(EmptyShell Empty)818 explicit AttributedStmt(EmptyShell Empty) 819 : Stmt(AttributedStmtClass, Empty) { 820 } 821 getAttrLoc()822 SourceLocation getAttrLoc() const { return AttrLoc; } getAttrs()823 const AttrVec &getAttrs() const { return Attrs; } getSubStmt()824 Stmt *getSubStmt() { return SubStmt; } getSubStmt()825 const Stmt *getSubStmt() const { return SubStmt; } 826 getSourceRange()827 SourceRange getSourceRange() const LLVM_READONLY { 828 return SourceRange(AttrLoc, SubStmt->getLocEnd()); 829 } children()830 child_range children() { return child_range(&SubStmt, &SubStmt + 1); } 831 classof(const Stmt * T)832 static bool classof(const Stmt *T) { 833 return T->getStmtClass() == AttributedStmtClass; 834 } classof(const AttributedStmt *)835 static bool classof(const AttributedStmt *) { return true; } 836 }; 837 838 839 /// IfStmt - This represents an if/then/else. 840 /// 841 class IfStmt : public Stmt { 842 enum { VAR, COND, THEN, ELSE, END_EXPR }; 843 Stmt* SubExprs[END_EXPR]; 844 845 SourceLocation IfLoc; 846 SourceLocation ElseLoc; 847 848 public: 849 IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, 850 Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0); 851 852 /// \brief Build an empty if/then/else statement IfStmt(EmptyShell Empty)853 explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { } 854 855 /// \brief Retrieve the variable declared in this "if" statement, if any. 856 /// 857 /// In the following example, "x" is the condition variable. 858 /// \code 859 /// if (int x = foo()) { 860 /// printf("x is %d", x); 861 /// } 862 /// \endcode 863 VarDecl *getConditionVariable() const; 864 void setConditionVariable(ASTContext &C, VarDecl *V); 865 866 /// If this IfStmt has a condition variable, return the faux DeclStmt 867 /// associated with the creation of that condition variable. getConditionVariableDeclStmt()868 const DeclStmt *getConditionVariableDeclStmt() const { 869 return reinterpret_cast<DeclStmt*>(SubExprs[VAR]); 870 } 871 getCond()872 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} setCond(Expr * E)873 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } getThen()874 const Stmt *getThen() const { return SubExprs[THEN]; } setThen(Stmt * S)875 void setThen(Stmt *S) { SubExprs[THEN] = S; } getElse()876 const Stmt *getElse() const { return SubExprs[ELSE]; } setElse(Stmt * S)877 void setElse(Stmt *S) { SubExprs[ELSE] = S; } 878 getCond()879 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } getThen()880 Stmt *getThen() { return SubExprs[THEN]; } getElse()881 Stmt *getElse() { return SubExprs[ELSE]; } 882 getIfLoc()883 SourceLocation getIfLoc() const { return IfLoc; } setIfLoc(SourceLocation L)884 void setIfLoc(SourceLocation L) { IfLoc = L; } getElseLoc()885 SourceLocation getElseLoc() const { return ElseLoc; } setElseLoc(SourceLocation L)886 void setElseLoc(SourceLocation L) { ElseLoc = L; } 887 getSourceRange()888 SourceRange getSourceRange() const LLVM_READONLY { 889 if (SubExprs[ELSE]) 890 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 891 else 892 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 893 } 894 895 // Iterators over subexpressions. The iterators will include iterating 896 // over the initialization expression referenced by the condition variable. children()897 child_range children() { 898 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 899 } 900 classof(const Stmt * T)901 static bool classof(const Stmt *T) { 902 return T->getStmtClass() == IfStmtClass; 903 } classof(const IfStmt *)904 static bool classof(const IfStmt *) { return true; } 905 }; 906 907 /// SwitchStmt - This represents a 'switch' stmt. 908 /// 909 class SwitchStmt : public Stmt { 910 enum { VAR, COND, BODY, END_EXPR }; 911 Stmt* SubExprs[END_EXPR]; 912 // This points to a linked list of case and default statements. 913 SwitchCase *FirstCase; 914 SourceLocation SwitchLoc; 915 916 /// If the SwitchStmt is a switch on an enum value, this records whether 917 /// all the enum values were covered by CaseStmts. This value is meant to 918 /// be a hint for possible clients. 919 unsigned AllEnumCasesCovered : 1; 920 921 public: 922 SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond); 923 924 /// \brief Build a empty switch statement. SwitchStmt(EmptyShell Empty)925 explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { } 926 927 /// \brief Retrieve the variable declared in this "switch" statement, if any. 928 /// 929 /// In the following example, "x" is the condition variable. 930 /// \code 931 /// switch (int x = foo()) { 932 /// case 0: break; 933 /// // ... 934 /// } 935 /// \endcode 936 VarDecl *getConditionVariable() const; 937 void setConditionVariable(ASTContext &C, VarDecl *V); 938 939 /// If this SwitchStmt has a condition variable, return the faux DeclStmt 940 /// associated with the creation of that condition variable. getConditionVariableDeclStmt()941 const DeclStmt *getConditionVariableDeclStmt() const { 942 return reinterpret_cast<DeclStmt*>(SubExprs[VAR]); 943 } 944 getCond()945 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} getBody()946 const Stmt *getBody() const { return SubExprs[BODY]; } getSwitchCaseList()947 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 948 getCond()949 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} setCond(Expr * E)950 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } getBody()951 Stmt *getBody() { return SubExprs[BODY]; } setBody(Stmt * S)952 void setBody(Stmt *S) { SubExprs[BODY] = S; } getSwitchCaseList()953 SwitchCase *getSwitchCaseList() { return FirstCase; } 954 955 /// \brief Set the case list for this switch statement. 956 /// 957 /// The caller is responsible for incrementing the retain counts on 958 /// all of the SwitchCase statements in this list. setSwitchCaseList(SwitchCase * SC)959 void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; } 960 getSwitchLoc()961 SourceLocation getSwitchLoc() const { return SwitchLoc; } setSwitchLoc(SourceLocation L)962 void setSwitchLoc(SourceLocation L) { SwitchLoc = L; } 963 setBody(Stmt * S,SourceLocation SL)964 void setBody(Stmt *S, SourceLocation SL) { 965 SubExprs[BODY] = S; 966 SwitchLoc = SL; 967 } addSwitchCase(SwitchCase * SC)968 void addSwitchCase(SwitchCase *SC) { 969 assert(!SC->getNextSwitchCase() 970 && "case/default already added to a switch"); 971 SC->setNextSwitchCase(FirstCase); 972 FirstCase = SC; 973 } 974 975 /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a 976 /// switch over an enum value then all cases have been explicitly covered. setAllEnumCasesCovered()977 void setAllEnumCasesCovered() { 978 AllEnumCasesCovered = 1; 979 } 980 981 /// Returns true if the SwitchStmt is a switch of an enum value and all cases 982 /// have been explicitly covered. isAllEnumCasesCovered()983 bool isAllEnumCasesCovered() const { 984 return (bool) AllEnumCasesCovered; 985 } 986 getSourceRange()987 SourceRange getSourceRange() const LLVM_READONLY { 988 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 989 } 990 // Iterators children()991 child_range children() { 992 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 993 } 994 classof(const Stmt * T)995 static bool classof(const Stmt *T) { 996 return T->getStmtClass() == SwitchStmtClass; 997 } classof(const SwitchStmt *)998 static bool classof(const SwitchStmt *) { return true; } 999 }; 1000 1001 1002 /// WhileStmt - This represents a 'while' stmt. 1003 /// 1004 class WhileStmt : public Stmt { 1005 enum { VAR, COND, BODY, END_EXPR }; 1006 Stmt* SubExprs[END_EXPR]; 1007 SourceLocation WhileLoc; 1008 public: 1009 WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, 1010 SourceLocation WL); 1011 1012 /// \brief Build an empty while statement. WhileStmt(EmptyShell Empty)1013 explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { } 1014 1015 /// \brief Retrieve the variable declared in this "while" statement, if any. 1016 /// 1017 /// In the following example, "x" is the condition variable. 1018 /// \code 1019 /// while (int x = random()) { 1020 /// // ... 1021 /// } 1022 /// \endcode 1023 VarDecl *getConditionVariable() const; 1024 void setConditionVariable(ASTContext &C, VarDecl *V); 1025 1026 /// If this WhileStmt has a condition variable, return the faux DeclStmt 1027 /// associated with the creation of that condition variable. getConditionVariableDeclStmt()1028 const DeclStmt *getConditionVariableDeclStmt() const { 1029 return reinterpret_cast<DeclStmt*>(SubExprs[VAR]); 1030 } 1031 getCond()1032 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } getCond()1033 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} setCond(Expr * E)1034 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } getBody()1035 Stmt *getBody() { return SubExprs[BODY]; } getBody()1036 const Stmt *getBody() const { return SubExprs[BODY]; } setBody(Stmt * S)1037 void setBody(Stmt *S) { SubExprs[BODY] = S; } 1038 getWhileLoc()1039 SourceLocation getWhileLoc() const { return WhileLoc; } setWhileLoc(SourceLocation L)1040 void setWhileLoc(SourceLocation L) { WhileLoc = L; } 1041 getSourceRange()1042 SourceRange getSourceRange() const LLVM_READONLY { 1043 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 1044 } classof(const Stmt * T)1045 static bool classof(const Stmt *T) { 1046 return T->getStmtClass() == WhileStmtClass; 1047 } classof(const WhileStmt *)1048 static bool classof(const WhileStmt *) { return true; } 1049 1050 // Iterators children()1051 child_range children() { 1052 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 1053 } 1054 }; 1055 1056 /// DoStmt - This represents a 'do/while' stmt. 1057 /// 1058 class DoStmt : public Stmt { 1059 enum { BODY, COND, END_EXPR }; 1060 Stmt* SubExprs[END_EXPR]; 1061 SourceLocation DoLoc; 1062 SourceLocation WhileLoc; 1063 SourceLocation RParenLoc; // Location of final ')' in do stmt condition. 1064 1065 public: DoStmt(Stmt * body,Expr * cond,SourceLocation DL,SourceLocation WL,SourceLocation RP)1066 DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL, 1067 SourceLocation RP) 1068 : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) { 1069 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 1070 SubExprs[BODY] = body; 1071 } 1072 1073 /// \brief Build an empty do-while statement. DoStmt(EmptyShell Empty)1074 explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { } 1075 getCond()1076 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } getCond()1077 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} setCond(Expr * E)1078 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } getBody()1079 Stmt *getBody() { return SubExprs[BODY]; } getBody()1080 const Stmt *getBody() const { return SubExprs[BODY]; } setBody(Stmt * S)1081 void setBody(Stmt *S) { SubExprs[BODY] = S; } 1082 getDoLoc()1083 SourceLocation getDoLoc() const { return DoLoc; } setDoLoc(SourceLocation L)1084 void setDoLoc(SourceLocation L) { DoLoc = L; } getWhileLoc()1085 SourceLocation getWhileLoc() const { return WhileLoc; } setWhileLoc(SourceLocation L)1086 void setWhileLoc(SourceLocation L) { WhileLoc = L; } 1087 getRParenLoc()1088 SourceLocation getRParenLoc() const { return RParenLoc; } setRParenLoc(SourceLocation L)1089 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 1090 getSourceRange()1091 SourceRange getSourceRange() const LLVM_READONLY { 1092 return SourceRange(DoLoc, RParenLoc); 1093 } classof(const Stmt * T)1094 static bool classof(const Stmt *T) { 1095 return T->getStmtClass() == DoStmtClass; 1096 } classof(const DoStmt *)1097 static bool classof(const DoStmt *) { return true; } 1098 1099 // Iterators children()1100 child_range children() { 1101 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 1102 } 1103 }; 1104 1105 1106 /// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 1107 /// the init/cond/inc parts of the ForStmt will be null if they were not 1108 /// specified in the source. 1109 /// 1110 class ForStmt : public Stmt { 1111 enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR }; 1112 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 1113 SourceLocation ForLoc; 1114 SourceLocation LParenLoc, RParenLoc; 1115 1116 public: 1117 ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, 1118 Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP); 1119 1120 /// \brief Build an empty for statement. ForStmt(EmptyShell Empty)1121 explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { } 1122 getInit()1123 Stmt *getInit() { return SubExprs[INIT]; } 1124 1125 /// \brief Retrieve the variable declared in this "for" statement, if any. 1126 /// 1127 /// In the following example, "y" is the condition variable. 1128 /// \code 1129 /// for (int x = random(); int y = mangle(x); ++x) { 1130 /// // ... 1131 /// } 1132 /// \endcode 1133 VarDecl *getConditionVariable() const; 1134 void setConditionVariable(ASTContext &C, VarDecl *V); 1135 1136 /// If this ForStmt has a condition variable, return the faux DeclStmt 1137 /// associated with the creation of that condition variable. getConditionVariableDeclStmt()1138 const DeclStmt *getConditionVariableDeclStmt() const { 1139 return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]); 1140 } 1141 getCond()1142 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } getInc()1143 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } getBody()1144 Stmt *getBody() { return SubExprs[BODY]; } 1145 getInit()1146 const Stmt *getInit() const { return SubExprs[INIT]; } getCond()1147 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} getInc()1148 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } getBody()1149 const Stmt *getBody() const { return SubExprs[BODY]; } 1150 setInit(Stmt * S)1151 void setInit(Stmt *S) { SubExprs[INIT] = S; } setCond(Expr * E)1152 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } setInc(Expr * E)1153 void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } setBody(Stmt * S)1154 void setBody(Stmt *S) { SubExprs[BODY] = S; } 1155 getForLoc()1156 SourceLocation getForLoc() const { return ForLoc; } setForLoc(SourceLocation L)1157 void setForLoc(SourceLocation L) { ForLoc = L; } getLParenLoc()1158 SourceLocation getLParenLoc() const { return LParenLoc; } setLParenLoc(SourceLocation L)1159 void setLParenLoc(SourceLocation L) { LParenLoc = L; } getRParenLoc()1160 SourceLocation getRParenLoc() const { return RParenLoc; } setRParenLoc(SourceLocation L)1161 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 1162 getSourceRange()1163 SourceRange getSourceRange() const LLVM_READONLY { 1164 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 1165 } classof(const Stmt * T)1166 static bool classof(const Stmt *T) { 1167 return T->getStmtClass() == ForStmtClass; 1168 } classof(const ForStmt *)1169 static bool classof(const ForStmt *) { return true; } 1170 1171 // Iterators children()1172 child_range children() { 1173 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 1174 } 1175 }; 1176 1177 /// GotoStmt - This represents a direct goto. 1178 /// 1179 class GotoStmt : public Stmt { 1180 LabelDecl *Label; 1181 SourceLocation GotoLoc; 1182 SourceLocation LabelLoc; 1183 public: GotoStmt(LabelDecl * label,SourceLocation GL,SourceLocation LL)1184 GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL) 1185 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 1186 1187 /// \brief Build an empty goto statement. GotoStmt(EmptyShell Empty)1188 explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { } 1189 getLabel()1190 LabelDecl *getLabel() const { return Label; } setLabel(LabelDecl * D)1191 void setLabel(LabelDecl *D) { Label = D; } 1192 getGotoLoc()1193 SourceLocation getGotoLoc() const { return GotoLoc; } setGotoLoc(SourceLocation L)1194 void setGotoLoc(SourceLocation L) { GotoLoc = L; } getLabelLoc()1195 SourceLocation getLabelLoc() const { return LabelLoc; } setLabelLoc(SourceLocation L)1196 void setLabelLoc(SourceLocation L) { LabelLoc = L; } 1197 getSourceRange()1198 SourceRange getSourceRange() const LLVM_READONLY { 1199 return SourceRange(GotoLoc, LabelLoc); 1200 } classof(const Stmt * T)1201 static bool classof(const Stmt *T) { 1202 return T->getStmtClass() == GotoStmtClass; 1203 } classof(const GotoStmt *)1204 static bool classof(const GotoStmt *) { return true; } 1205 1206 // Iterators children()1207 child_range children() { return child_range(); } 1208 }; 1209 1210 /// IndirectGotoStmt - This represents an indirect goto. 1211 /// 1212 class IndirectGotoStmt : public Stmt { 1213 SourceLocation GotoLoc; 1214 SourceLocation StarLoc; 1215 Stmt *Target; 1216 public: IndirectGotoStmt(SourceLocation gotoLoc,SourceLocation starLoc,Expr * target)1217 IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc, 1218 Expr *target) 1219 : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc), 1220 Target((Stmt*)target) {} 1221 1222 /// \brief Build an empty indirect goto statement. IndirectGotoStmt(EmptyShell Empty)1223 explicit IndirectGotoStmt(EmptyShell Empty) 1224 : Stmt(IndirectGotoStmtClass, Empty) { } 1225 setGotoLoc(SourceLocation L)1226 void setGotoLoc(SourceLocation L) { GotoLoc = L; } getGotoLoc()1227 SourceLocation getGotoLoc() const { return GotoLoc; } setStarLoc(SourceLocation L)1228 void setStarLoc(SourceLocation L) { StarLoc = L; } getStarLoc()1229 SourceLocation getStarLoc() const { return StarLoc; } 1230 getTarget()1231 Expr *getTarget() { return reinterpret_cast<Expr*>(Target); } getTarget()1232 const Expr *getTarget() const {return reinterpret_cast<const Expr*>(Target);} setTarget(Expr * E)1233 void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); } 1234 1235 /// getConstantTarget - Returns the fixed target of this indirect 1236 /// goto, if one exists. 1237 LabelDecl *getConstantTarget(); getConstantTarget()1238 const LabelDecl *getConstantTarget() const { 1239 return const_cast<IndirectGotoStmt*>(this)->getConstantTarget(); 1240 } 1241 getSourceRange()1242 SourceRange getSourceRange() const LLVM_READONLY { 1243 return SourceRange(GotoLoc, Target->getLocEnd()); 1244 } 1245 classof(const Stmt * T)1246 static bool classof(const Stmt *T) { 1247 return T->getStmtClass() == IndirectGotoStmtClass; 1248 } classof(const IndirectGotoStmt *)1249 static bool classof(const IndirectGotoStmt *) { return true; } 1250 1251 // Iterators children()1252 child_range children() { return child_range(&Target, &Target+1); } 1253 }; 1254 1255 1256 /// ContinueStmt - This represents a continue. 1257 /// 1258 class ContinueStmt : public Stmt { 1259 SourceLocation ContinueLoc; 1260 public: ContinueStmt(SourceLocation CL)1261 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 1262 1263 /// \brief Build an empty continue statement. ContinueStmt(EmptyShell Empty)1264 explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { } 1265 getContinueLoc()1266 SourceLocation getContinueLoc() const { return ContinueLoc; } setContinueLoc(SourceLocation L)1267 void setContinueLoc(SourceLocation L) { ContinueLoc = L; } 1268 getSourceRange()1269 SourceRange getSourceRange() const LLVM_READONLY { 1270 return SourceRange(ContinueLoc); 1271 } 1272 classof(const Stmt * T)1273 static bool classof(const Stmt *T) { 1274 return T->getStmtClass() == ContinueStmtClass; 1275 } classof(const ContinueStmt *)1276 static bool classof(const ContinueStmt *) { return true; } 1277 1278 // Iterators children()1279 child_range children() { return child_range(); } 1280 }; 1281 1282 /// BreakStmt - This represents a break. 1283 /// 1284 class BreakStmt : public Stmt { 1285 SourceLocation BreakLoc; 1286 public: BreakStmt(SourceLocation BL)1287 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 1288 1289 /// \brief Build an empty break statement. BreakStmt(EmptyShell Empty)1290 explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { } 1291 getBreakLoc()1292 SourceLocation getBreakLoc() const { return BreakLoc; } setBreakLoc(SourceLocation L)1293 void setBreakLoc(SourceLocation L) { BreakLoc = L; } 1294 getSourceRange()1295 SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(BreakLoc); } 1296 classof(const Stmt * T)1297 static bool classof(const Stmt *T) { 1298 return T->getStmtClass() == BreakStmtClass; 1299 } classof(const BreakStmt *)1300 static bool classof(const BreakStmt *) { return true; } 1301 1302 // Iterators children()1303 child_range children() { return child_range(); } 1304 }; 1305 1306 1307 /// ReturnStmt - This represents a return, optionally of an expression: 1308 /// return; 1309 /// return 4; 1310 /// 1311 /// Note that GCC allows return with no argument in a function declared to 1312 /// return a value, and it allows returning a value in functions declared to 1313 /// return void. We explicitly model this in the AST, which means you can't 1314 /// depend on the return type of the function and the presence of an argument. 1315 /// 1316 class ReturnStmt : public Stmt { 1317 Stmt *RetExpr; 1318 SourceLocation RetLoc; 1319 const VarDecl *NRVOCandidate; 1320 1321 public: ReturnStmt(SourceLocation RL)1322 ReturnStmt(SourceLocation RL) 1323 : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { } 1324 ReturnStmt(SourceLocation RL,Expr * E,const VarDecl * NRVOCandidate)1325 ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate) 1326 : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL), 1327 NRVOCandidate(NRVOCandidate) {} 1328 1329 /// \brief Build an empty return expression. ReturnStmt(EmptyShell Empty)1330 explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { } 1331 1332 const Expr *getRetValue() const; 1333 Expr *getRetValue(); setRetValue(Expr * E)1334 void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); } 1335 getReturnLoc()1336 SourceLocation getReturnLoc() const { return RetLoc; } setReturnLoc(SourceLocation L)1337 void setReturnLoc(SourceLocation L) { RetLoc = L; } 1338 1339 /// \brief Retrieve the variable that might be used for the named return 1340 /// value optimization. 1341 /// 1342 /// The optimization itself can only be performed if the variable is 1343 /// also marked as an NRVO object. getNRVOCandidate()1344 const VarDecl *getNRVOCandidate() const { return NRVOCandidate; } setNRVOCandidate(const VarDecl * Var)1345 void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; } 1346 1347 SourceRange getSourceRange() const LLVM_READONLY; 1348 classof(const Stmt * T)1349 static bool classof(const Stmt *T) { 1350 return T->getStmtClass() == ReturnStmtClass; 1351 } classof(const ReturnStmt *)1352 static bool classof(const ReturnStmt *) { return true; } 1353 1354 // Iterators children()1355 child_range children() { 1356 if (RetExpr) return child_range(&RetExpr, &RetExpr+1); 1357 return child_range(); 1358 } 1359 }; 1360 1361 /// AsmStmt - This represents a GNU inline-assembly statement extension. 1362 /// 1363 class AsmStmt : public Stmt { 1364 SourceLocation AsmLoc, RParenLoc; 1365 StringLiteral *AsmStr; 1366 1367 bool IsSimple; 1368 bool IsVolatile; 1369 bool MSAsm; 1370 1371 unsigned NumOutputs; 1372 unsigned NumInputs; 1373 unsigned NumClobbers; 1374 1375 // FIXME: If we wanted to, we could allocate all of these in one big array. 1376 IdentifierInfo **Names; 1377 StringLiteral **Constraints; 1378 Stmt **Exprs; 1379 StringLiteral **Clobbers; 1380 1381 public: 1382 AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, 1383 bool msasm, unsigned numoutputs, unsigned numinputs, 1384 IdentifierInfo **names, StringLiteral **constraints, 1385 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 1386 StringLiteral **clobbers, SourceLocation rparenloc); 1387 1388 /// \brief Build an empty inline-assembly statement. AsmStmt(EmptyShell Empty)1389 explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty), 1390 Names(0), Constraints(0), Exprs(0), Clobbers(0) { } 1391 getAsmLoc()1392 SourceLocation getAsmLoc() const { return AsmLoc; } setAsmLoc(SourceLocation L)1393 void setAsmLoc(SourceLocation L) { AsmLoc = L; } getRParenLoc()1394 SourceLocation getRParenLoc() const { return RParenLoc; } setRParenLoc(SourceLocation L)1395 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 1396 isVolatile()1397 bool isVolatile() const { return IsVolatile; } setVolatile(bool V)1398 void setVolatile(bool V) { IsVolatile = V; } isSimple()1399 bool isSimple() const { return IsSimple; } setSimple(bool V)1400 void setSimple(bool V) { IsSimple = V; } isMSAsm()1401 bool isMSAsm() const { return MSAsm; } setMSAsm(bool V)1402 void setMSAsm(bool V) { MSAsm = V; } 1403 1404 //===--- Asm String Analysis ---===// 1405 getAsmString()1406 const StringLiteral *getAsmString() const { return AsmStr; } getAsmString()1407 StringLiteral *getAsmString() { return AsmStr; } setAsmString(StringLiteral * E)1408 void setAsmString(StringLiteral *E) { AsmStr = E; } 1409 1410 /// AsmStringPiece - this is part of a decomposed asm string specification 1411 /// (for use with the AnalyzeAsmString function below). An asm string is 1412 /// considered to be a concatenation of these parts. 1413 class AsmStringPiece { 1414 public: 1415 enum Kind { 1416 String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%". 1417 Operand // Operand reference, with optional modifier %c4. 1418 }; 1419 private: 1420 Kind MyKind; 1421 std::string Str; 1422 unsigned OperandNo; 1423 public: AsmStringPiece(const std::string & S)1424 AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {} AsmStringPiece(unsigned OpNo,char Modifier)1425 AsmStringPiece(unsigned OpNo, char Modifier) 1426 : MyKind(Operand), Str(), OperandNo(OpNo) { 1427 Str += Modifier; 1428 } 1429 isString()1430 bool isString() const { return MyKind == String; } isOperand()1431 bool isOperand() const { return MyKind == Operand; } 1432 getString()1433 const std::string &getString() const { 1434 assert(isString()); 1435 return Str; 1436 } 1437 getOperandNo()1438 unsigned getOperandNo() const { 1439 assert(isOperand()); 1440 return OperandNo; 1441 } 1442 1443 /// getModifier - Get the modifier for this operand, if present. This 1444 /// returns '\0' if there was no modifier. getModifier()1445 char getModifier() const { 1446 assert(isOperand()); 1447 return Str[0]; 1448 } 1449 }; 1450 1451 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing 1452 /// it into pieces. If the asm string is erroneous, emit errors and return 1453 /// true, otherwise return false. This handles canonicalization and 1454 /// translation of strings from GCC syntax to LLVM IR syntax, and handles 1455 //// flattening of named references like %[foo] to Operand AsmStringPiece's. 1456 unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces, 1457 ASTContext &C, unsigned &DiagOffs) const; 1458 1459 1460 //===--- Output operands ---===// 1461 getNumOutputs()1462 unsigned getNumOutputs() const { return NumOutputs; } 1463 getOutputIdentifier(unsigned i)1464 IdentifierInfo *getOutputIdentifier(unsigned i) const { 1465 return Names[i]; 1466 } 1467 getOutputName(unsigned i)1468 StringRef getOutputName(unsigned i) const { 1469 if (IdentifierInfo *II = getOutputIdentifier(i)) 1470 return II->getName(); 1471 1472 return StringRef(); 1473 } 1474 1475 /// getOutputConstraint - Return the constraint string for the specified 1476 /// output operand. All output constraints are known to be non-empty (either 1477 /// '=' or '+'). 1478 StringRef getOutputConstraint(unsigned i) const; 1479 getOutputConstraintLiteral(unsigned i)1480 const StringLiteral *getOutputConstraintLiteral(unsigned i) const { 1481 return Constraints[i]; 1482 } getOutputConstraintLiteral(unsigned i)1483 StringLiteral *getOutputConstraintLiteral(unsigned i) { 1484 return Constraints[i]; 1485 } 1486 1487 Expr *getOutputExpr(unsigned i); 1488 getOutputExpr(unsigned i)1489 const Expr *getOutputExpr(unsigned i) const { 1490 return const_cast<AsmStmt*>(this)->getOutputExpr(i); 1491 } 1492 1493 /// isOutputPlusConstraint - Return true if the specified output constraint 1494 /// is a "+" constraint (which is both an input and an output) or false if it 1495 /// is an "=" constraint (just an output). isOutputPlusConstraint(unsigned i)1496 bool isOutputPlusConstraint(unsigned i) const { 1497 return getOutputConstraint(i)[0] == '+'; 1498 } 1499 1500 /// getNumPlusOperands - Return the number of output operands that have a "+" 1501 /// constraint. 1502 unsigned getNumPlusOperands() const; 1503 1504 //===--- Input operands ---===// 1505 getNumInputs()1506 unsigned getNumInputs() const { return NumInputs; } 1507 getInputIdentifier(unsigned i)1508 IdentifierInfo *getInputIdentifier(unsigned i) const { 1509 return Names[i + NumOutputs]; 1510 } 1511 getInputName(unsigned i)1512 StringRef getInputName(unsigned i) const { 1513 if (IdentifierInfo *II = getInputIdentifier(i)) 1514 return II->getName(); 1515 1516 return StringRef(); 1517 } 1518 1519 /// getInputConstraint - Return the specified input constraint. Unlike output 1520 /// constraints, these can be empty. 1521 StringRef getInputConstraint(unsigned i) const; 1522 getInputConstraintLiteral(unsigned i)1523 const StringLiteral *getInputConstraintLiteral(unsigned i) const { 1524 return Constraints[i + NumOutputs]; 1525 } getInputConstraintLiteral(unsigned i)1526 StringLiteral *getInputConstraintLiteral(unsigned i) { 1527 return Constraints[i + NumOutputs]; 1528 } 1529 1530 Expr *getInputExpr(unsigned i); 1531 void setInputExpr(unsigned i, Expr *E); 1532 getInputExpr(unsigned i)1533 const Expr *getInputExpr(unsigned i) const { 1534 return const_cast<AsmStmt*>(this)->getInputExpr(i); 1535 } 1536 1537 void setOutputsAndInputsAndClobbers(ASTContext &C, 1538 IdentifierInfo **Names, 1539 StringLiteral **Constraints, 1540 Stmt **Exprs, 1541 unsigned NumOutputs, 1542 unsigned NumInputs, 1543 StringLiteral **Clobbers, 1544 unsigned NumClobbers); 1545 1546 //===--- Other ---===// 1547 1548 /// getNamedOperand - Given a symbolic operand reference like %[foo], 1549 /// translate this into a numeric value needed to reference the same operand. 1550 /// This returns -1 if the operand name is invalid. 1551 int getNamedOperand(StringRef SymbolicName) const; 1552 getNumClobbers()1553 unsigned getNumClobbers() const { return NumClobbers; } getClobber(unsigned i)1554 StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } getClobber(unsigned i)1555 const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } 1556 getSourceRange()1557 SourceRange getSourceRange() const LLVM_READONLY { 1558 return SourceRange(AsmLoc, RParenLoc); 1559 } 1560 classof(const Stmt * T)1561 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} classof(const AsmStmt *)1562 static bool classof(const AsmStmt *) { return true; } 1563 1564 // Input expr iterators. 1565 1566 typedef ExprIterator inputs_iterator; 1567 typedef ConstExprIterator const_inputs_iterator; 1568 begin_inputs()1569 inputs_iterator begin_inputs() { 1570 return &Exprs[0] + NumOutputs; 1571 } 1572 end_inputs()1573 inputs_iterator end_inputs() { 1574 return &Exprs[0] + NumOutputs + NumInputs; 1575 } 1576 begin_inputs()1577 const_inputs_iterator begin_inputs() const { 1578 return &Exprs[0] + NumOutputs; 1579 } 1580 end_inputs()1581 const_inputs_iterator end_inputs() const { 1582 return &Exprs[0] + NumOutputs + NumInputs; 1583 } 1584 1585 // Output expr iterators. 1586 1587 typedef ExprIterator outputs_iterator; 1588 typedef ConstExprIterator const_outputs_iterator; 1589 begin_outputs()1590 outputs_iterator begin_outputs() { 1591 return &Exprs[0]; 1592 } end_outputs()1593 outputs_iterator end_outputs() { 1594 return &Exprs[0] + NumOutputs; 1595 } 1596 begin_outputs()1597 const_outputs_iterator begin_outputs() const { 1598 return &Exprs[0]; 1599 } end_outputs()1600 const_outputs_iterator end_outputs() const { 1601 return &Exprs[0] + NumOutputs; 1602 } 1603 children()1604 child_range children() { 1605 return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); 1606 } 1607 }; 1608 1609 class SEHExceptStmt : public Stmt { 1610 SourceLocation Loc; 1611 Stmt *Children[2]; 1612 1613 enum { FILTER_EXPR, BLOCK }; 1614 1615 SEHExceptStmt(SourceLocation Loc, 1616 Expr *FilterExpr, 1617 Stmt *Block); 1618 1619 friend class ASTReader; 1620 friend class ASTStmtReader; SEHExceptStmt(EmptyShell E)1621 explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { } 1622 1623 public: 1624 static SEHExceptStmt* Create(ASTContext &C, 1625 SourceLocation ExceptLoc, 1626 Expr *FilterExpr, 1627 Stmt *Block); getSourceRange()1628 SourceRange getSourceRange() const LLVM_READONLY { 1629 return SourceRange(getExceptLoc(), getEndLoc()); 1630 } 1631 getExceptLoc()1632 SourceLocation getExceptLoc() const { return Loc; } getEndLoc()1633 SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); } 1634 getFilterExpr()1635 Expr *getFilterExpr() const { 1636 return reinterpret_cast<Expr*>(Children[FILTER_EXPR]); 1637 } 1638 getBlock()1639 CompoundStmt *getBlock() const { 1640 return llvm::cast<CompoundStmt>(Children[BLOCK]); 1641 } 1642 children()1643 child_range children() { 1644 return child_range(Children,Children+2); 1645 } 1646 classof(const Stmt * T)1647 static bool classof(const Stmt *T) { 1648 return T->getStmtClass() == SEHExceptStmtClass; 1649 } 1650 classof(SEHExceptStmt *)1651 static bool classof(SEHExceptStmt *) { return true; } 1652 1653 }; 1654 1655 class SEHFinallyStmt : public Stmt { 1656 SourceLocation Loc; 1657 Stmt *Block; 1658 1659 SEHFinallyStmt(SourceLocation Loc, 1660 Stmt *Block); 1661 1662 friend class ASTReader; 1663 friend class ASTStmtReader; SEHFinallyStmt(EmptyShell E)1664 explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { } 1665 1666 public: 1667 static SEHFinallyStmt* Create(ASTContext &C, 1668 SourceLocation FinallyLoc, 1669 Stmt *Block); 1670 getSourceRange()1671 SourceRange getSourceRange() const LLVM_READONLY { 1672 return SourceRange(getFinallyLoc(), getEndLoc()); 1673 } 1674 getFinallyLoc()1675 SourceLocation getFinallyLoc() const { return Loc; } getEndLoc()1676 SourceLocation getEndLoc() const { return Block->getLocEnd(); } 1677 getBlock()1678 CompoundStmt *getBlock() const { return llvm::cast<CompoundStmt>(Block); } 1679 children()1680 child_range children() { 1681 return child_range(&Block,&Block+1); 1682 } 1683 classof(const Stmt * T)1684 static bool classof(const Stmt *T) { 1685 return T->getStmtClass() == SEHFinallyStmtClass; 1686 } 1687 classof(SEHFinallyStmt *)1688 static bool classof(SEHFinallyStmt *) { return true; } 1689 1690 }; 1691 1692 class SEHTryStmt : public Stmt { 1693 bool IsCXXTry; 1694 SourceLocation TryLoc; 1695 Stmt *Children[2]; 1696 1697 enum { TRY = 0, HANDLER = 1 }; 1698 1699 SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try' 1700 SourceLocation TryLoc, 1701 Stmt *TryBlock, 1702 Stmt *Handler); 1703 1704 friend class ASTReader; 1705 friend class ASTStmtReader; SEHTryStmt(EmptyShell E)1706 explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { } 1707 1708 public: 1709 static SEHTryStmt* Create(ASTContext &C, 1710 bool isCXXTry, 1711 SourceLocation TryLoc, 1712 Stmt *TryBlock, 1713 Stmt *Handler); 1714 getSourceRange()1715 SourceRange getSourceRange() const LLVM_READONLY { 1716 return SourceRange(getTryLoc(), getEndLoc()); 1717 } 1718 getTryLoc()1719 SourceLocation getTryLoc() const { return TryLoc; } getEndLoc()1720 SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); } 1721 getIsCXXTry()1722 bool getIsCXXTry() const { return IsCXXTry; } 1723 getTryBlock()1724 CompoundStmt* getTryBlock() const { 1725 return llvm::cast<CompoundStmt>(Children[TRY]); 1726 } 1727 getHandler()1728 Stmt *getHandler() const { return Children[HANDLER]; } 1729 1730 /// Returns 0 if not defined 1731 SEHExceptStmt *getExceptHandler() const; 1732 SEHFinallyStmt *getFinallyHandler() const; 1733 children()1734 child_range children() { 1735 return child_range(Children,Children+2); 1736 } 1737 classof(const Stmt * T)1738 static bool classof(const Stmt *T) { 1739 return T->getStmtClass() == SEHTryStmtClass; 1740 } 1741 classof(SEHTryStmt *)1742 static bool classof(SEHTryStmt *) { return true; } 1743 }; 1744 1745 } // end namespace clang 1746 1747 #endif 1748