Stmt.h revision fe795956194141c91ae555985c9b930595bff43f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file was developed by Chris Lattner and is distributed under 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the University of Illinois Open Source License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file defines the Stmt interface and subclasses. 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#ifndef LLVM_CLANG_AST_STMT_H 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define LLVM_CLANG_AST_STMT_H 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "clang/Basic/SourceLocation.h" 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "clang/AST/StmtIterator.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "llvm/ADT/SmallVector.h" 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "llvm/ADT/iterator" 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "llvm/Bitcode/SerializationFwd.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <iosfwd> 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace clang { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Expr; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class Decl; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class ScopedDecl; 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) class IdentifierInfo; 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch class SourceManager; 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch class SwitchStmt; 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch class PrinterHelper; 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/// Stmt - This represents one statement. 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/// 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Stmt { 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)public: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum StmtClass { 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define STMT(N, CLASS, PARENT) CLASS##Class = N, 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define FIRST_STMT(N) firstStmtConstant = N, 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define LAST_STMT(N) lastStmtConstant = N, 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define FIRST_EXPR(N) firstExprConstant = N, 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define LAST_EXPR(N) lastExprConstant = N 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "clang/AST/StmtNodes.def" 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)private: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StmtClass sClass; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stmt(StmtClass SC) : sClass(SC) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~Stmt() {} 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch StmtClass getStmtClass() const { return sClass; } 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char *getStmtClassName() const; 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /// SourceLocation tokens are not useful in isolation - they are low level 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// value objects created/interpreted by SourceManager. We assume AST 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /// clients will have a pointer to the respective SourceManager. 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual SourceRange getSourceRange() const = 0; 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SourceLocation getLocStart() const { return getSourceRange().getBegin(); } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // global temp stats (until we have a per-module visitor) 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static void addStmtClass(const StmtClass s); 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static bool CollectingStats(bool enable=false); 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static void PrintStats(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /// dump - This does a local dump of the specified AST fragment. It dumps the 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /// specified node and a few nodes underneath it, but not the whole subtree. 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /// This is useful in a debugger. 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void dump() const; 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void dump(SourceManager &SM) const; 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void dumpAll() const; 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void dumpAll(SourceManager &SM) const; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /// back to its original source language syntax. 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void dumpPretty() const; 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void printPretty(std::ostream &OS, PrinterHelper* = NULL) const; 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /// works on systems with GraphViz (Mac OS X) or dot+gv installed. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void viewAST() const; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Implement isa<T> support. 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static bool classof(const Stmt *) { return true; } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// contain implicit control-flow in the order their subexpressions 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// are evaluated. This predicate returns true if this statement has 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// such implicit control-flow. Such statements are also specially handled 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// within CFGs. 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool hasImplicitControlFlow() const; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Child Iterators: All subclasses must implement child_begin and child_end 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// to permit easy iteration over the substatements/subexpessions of an 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// AST node. This permits easy iteration over all nodes in the AST. 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) typedef StmtIterator child_iterator; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef ConstStmtIterator const_child_iterator; 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) typedef std::reverse_iterator<child_iterator> 10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) reverse_child_iterator; 10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) typedef std::reverse_iterator<const_child_iterator> 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const_reverse_child_iterator; 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual child_iterator child_begin() = 0; 11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual child_iterator child_end() = 0; 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const_child_iterator child_begin() const { 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return const_child_iterator(const_cast<Stmt*>(this)->child_begin()); 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const_child_iterator child_end() const { 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return const_child_iterator(const_cast<Stmt*>(this)->child_end()); 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) reverse_child_iterator child_rbegin() { 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return reverse_child_iterator(child_end()); 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reverse_child_iterator child_rend() { 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return reverse_child_iterator(child_begin()); 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const_reverse_child_iterator child_rbegin() const { 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return const_reverse_child_iterator(child_end()); 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const_reverse_child_iterator child_rend() const { 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return const_reverse_child_iterator(child_begin()); 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/// DeclStmt - Adaptor class for mixing declarations with statements and 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// expressions. For example, CompoundStmt mixes statements, expressions 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// and declarations (variables, types). Another example is ForStmt, where 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/// the first statement can be an expression or a declaration. 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)/// 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class DeclStmt : public Stmt { 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedDecl *TheDecl; 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)public: 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DeclStmt(ScopedDecl *D) : Stmt(DeclStmtClass), TheDecl(D) {} 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ScopedDecl *getDecl() const { return TheDecl; } 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScopedDecl *getDecl() { return TheDecl; } 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual SourceRange getSourceRange() const { return SourceRange(); } 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static bool classof(const Stmt *T) { 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return T->getStmtClass() == DeclStmtClass; 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static bool classof(const DeclStmt *) { return true; } 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Iterators 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual child_iterator child_begin(); 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual child_iterator child_end(); 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/// NullStmt - This is the null statement ";": C99 6.8.3p3. 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class NullStmt : public Stmt { 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SourceLocation SemiLoc; 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)public: 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SourceLocation getSemiLoc() const { return SemiLoc; } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool classof(const Stmt *T) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return T->getStmtClass() == NullStmtClass; 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static bool classof(const NullStmt *) { return true; } 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Iterators 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual child_iterator child_begin(); 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual child_iterator child_end(); 1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}; 1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/// CompoundStmt - This represents a group of statements like { stmt stmt }. 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass CompoundStmt : public Stmt { 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci llvm::SmallVector<Stmt*, 16> Body; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SourceLocation LBracLoc, RBracLoc; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompoundStmt(Stmt **StmtStart, unsigned NumStmts, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SourceLocation LB, SourceLocation RB) 191 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts), 192 LBracLoc(LB), RBracLoc(RB) {} 193 194 bool body_empty() const { return Body.empty(); } 195 196 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 197 body_iterator body_begin() { return Body.begin(); } 198 body_iterator body_end() { return Body.end(); } 199 Stmt *body_back() { return Body.back(); } 200 201 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 202 const_body_iterator body_begin() const { return Body.begin(); } 203 const_body_iterator body_end() const { return Body.end(); } 204 const Stmt *body_back() const { return Body.back(); } 205 206 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 207 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 208 reverse_body_iterator body_rend() { return Body.rend(); } 209 210 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 211 const_reverse_body_iterator; 212 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 213 const_reverse_body_iterator body_rend() const { return Body.rend(); } 214 215 void push_back(Stmt *S) { Body.push_back(S); } 216 217 virtual SourceRange getSourceRange() const { 218 return SourceRange(LBracLoc, RBracLoc); 219 } 220 221 SourceLocation getLBracLoc() const { return LBracLoc; } 222 SourceLocation getRBracLoc() const { return RBracLoc; } 223 224 static bool classof(const Stmt *T) { 225 return T->getStmtClass() == CompoundStmtClass; 226 } 227 static bool classof(const CompoundStmt *) { return true; } 228 229 // Iterators 230 virtual child_iterator child_begin(); 231 virtual child_iterator child_end(); 232}; 233 234// SwitchCase is the base class for CaseStmt and DefaultStmt, 235class SwitchCase : public Stmt { 236 // A pointer to the following CaseStmt or DefaultStmt class, 237 // used by SwitchStmt. 238 SwitchCase *NextSwitchCase; 239protected: 240 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 241 242public: 243 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 244 245 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 246 247 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 248 249 virtual Stmt* v_getSubStmt() = 0; 250 Stmt *getSubStmt() { return v_getSubStmt(); } 251 252 virtual SourceRange getSourceRange() const { return SourceRange(); } 253 254 static bool classof(const Stmt *T) { 255 return T->getStmtClass() == CaseStmtClass || 256 T->getStmtClass() == DefaultStmtClass; 257 } 258 static bool classof(const SwitchCase *) { return true; } 259}; 260 261class CaseStmt : public SwitchCase { 262 enum { SUBSTMT, LHS, RHS, END_EXPR }; 263 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 264 // GNU "case 1 ... 4" extension 265 SourceLocation CaseLoc; 266public: 267 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc) 268 : SwitchCase(CaseStmtClass) { 269 SubExprs[SUBSTMT] = substmt; 270 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 271 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 272 CaseLoc = caseLoc; 273 } 274 275 SourceLocation getCaseLoc() const { return CaseLoc; } 276 277 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 278 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 279 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 280 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 281 const Expr *getLHS() const { 282 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 283 } 284 const Expr *getRHS() const { 285 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 286 } 287 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 288 289 virtual SourceRange getSourceRange() const { 290 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 291 } 292 static bool classof(const Stmt *T) { 293 return T->getStmtClass() == CaseStmtClass; 294 } 295 static bool classof(const CaseStmt *) { return true; } 296 297 // Iterators 298 virtual child_iterator child_begin(); 299 virtual child_iterator child_end(); 300}; 301 302class DefaultStmt : public SwitchCase { 303 Stmt* SubStmt; 304 SourceLocation DefaultLoc; 305public: 306 DefaultStmt(SourceLocation DL, Stmt *substmt) : 307 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 308 309 Stmt *getSubStmt() { return SubStmt; } 310 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 311 const Stmt *getSubStmt() const { return SubStmt; } 312 313 SourceLocation getDefaultLoc() const { return DefaultLoc; } 314 315 virtual SourceRange getSourceRange() const { 316 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 317 } 318 static bool classof(const Stmt *T) { 319 return T->getStmtClass() == DefaultStmtClass; 320 } 321 static bool classof(const DefaultStmt *) { return true; } 322 323 // Iterators 324 virtual child_iterator child_begin(); 325 virtual child_iterator child_end(); 326}; 327 328class LabelStmt : public Stmt { 329 IdentifierInfo *Label; 330 Stmt *SubStmt; 331 SourceLocation IdentLoc; 332public: 333 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 334 : Stmt(LabelStmtClass), Label(label), 335 SubStmt(substmt), IdentLoc(IL) {} 336 337 SourceLocation getIdentLoc() const { return IdentLoc; } 338 IdentifierInfo *getID() const { return Label; } 339 const char *getName() const; 340 Stmt *getSubStmt() { return SubStmt; } 341 const Stmt *getSubStmt() const { return SubStmt; } 342 343 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 344 void setSubStmt(Stmt *SS) { SubStmt = SS; } 345 346 virtual SourceRange getSourceRange() const { 347 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 348 } 349 static bool classof(const Stmt *T) { 350 return T->getStmtClass() == LabelStmtClass; 351 } 352 static bool classof(const LabelStmt *) { return true; } 353 354 // Iterators 355 virtual child_iterator child_begin(); 356 virtual child_iterator child_end(); 357}; 358 359 360/// IfStmt - This represents an if/then/else. 361/// 362class IfStmt : public Stmt { 363 enum { COND, THEN, ELSE, END_EXPR }; 364 Stmt* SubExprs[END_EXPR]; 365 SourceLocation IfLoc; 366public: 367 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 368 : Stmt(IfStmtClass) { 369 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 370 SubExprs[THEN] = then; 371 SubExprs[ELSE] = elsev; 372 IfLoc = IL; 373 } 374 375 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 376 const Stmt *getThen() const { return SubExprs[THEN]; } 377 const Stmt *getElse() const { return SubExprs[ELSE]; } 378 379 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 380 Stmt *getThen() { return SubExprs[THEN]; } 381 Stmt *getElse() { return SubExprs[ELSE]; } 382 383 virtual SourceRange getSourceRange() const { 384 if (SubExprs[ELSE]) 385 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 386 else 387 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 388 } 389 390 static bool classof(const Stmt *T) { 391 return T->getStmtClass() == IfStmtClass; 392 } 393 static bool classof(const IfStmt *) { return true; } 394 395 // Iterators 396 virtual child_iterator child_begin(); 397 virtual child_iterator child_end(); 398}; 399 400/// SwitchStmt - This represents a 'switch' stmt. 401/// 402class SwitchStmt : public Stmt { 403 enum { COND, BODY, END_EXPR }; 404 Stmt* SubExprs[END_EXPR]; 405 // This points to a linked list of case and default statements. 406 SwitchCase *FirstCase; 407 SourceLocation SwitchLoc; 408public: 409 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 410 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 411 SubExprs[BODY] = NULL; 412 } 413 414 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 415 const Stmt *getBody() const { return SubExprs[BODY]; } 416 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 417 418 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 419 Stmt *getBody() { return SubExprs[BODY]; } 420 SwitchCase *getSwitchCaseList() { return FirstCase; } 421 422 void setBody(Stmt *S, SourceLocation SL) { 423 SubExprs[BODY] = S; 424 SwitchLoc = SL; 425 } 426 void addSwitchCase(SwitchCase *SC) { 427 if (FirstCase) 428 SC->setNextSwitchCase(FirstCase); 429 430 FirstCase = SC; 431 } 432 virtual SourceRange getSourceRange() const { 433 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 434 } 435 static bool classof(const Stmt *T) { 436 return T->getStmtClass() == SwitchStmtClass; 437 } 438 static bool classof(const SwitchStmt *) { return true; } 439 440 // Iterators 441 virtual child_iterator child_begin(); 442 virtual child_iterator child_end(); 443}; 444 445 446/// WhileStmt - This represents a 'while' stmt. 447/// 448class WhileStmt : public Stmt { 449 enum { COND, BODY, END_EXPR }; 450 Stmt* SubExprs[END_EXPR]; 451 SourceLocation WhileLoc; 452public: 453 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 454 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 455 SubExprs[BODY] = body; 456 WhileLoc = WL; 457 } 458 459 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 460 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 461 Stmt *getBody() { return SubExprs[BODY]; } 462 const Stmt *getBody() const { return SubExprs[BODY]; } 463 464 virtual SourceRange getSourceRange() const { 465 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 466 } 467 static bool classof(const Stmt *T) { 468 return T->getStmtClass() == WhileStmtClass; 469 } 470 static bool classof(const WhileStmt *) { return true; } 471 472 // Iterators 473 virtual child_iterator child_begin(); 474 virtual child_iterator child_end(); 475}; 476 477/// DoStmt - This represents a 'do/while' stmt. 478/// 479class DoStmt : public Stmt { 480 enum { COND, BODY, END_EXPR }; 481 Stmt* SubExprs[END_EXPR]; 482 SourceLocation DoLoc; 483public: 484 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 485 : Stmt(DoStmtClass), DoLoc(DL) { 486 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 487 SubExprs[BODY] = body; 488 DoLoc = DL; 489 } 490 491 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 492 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 493 Stmt *getBody() { return SubExprs[BODY]; } 494 const Stmt *getBody() const { return SubExprs[BODY]; } 495 496 virtual SourceRange getSourceRange() const { 497 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 498 } 499 static bool classof(const Stmt *T) { 500 return T->getStmtClass() == DoStmtClass; 501 } 502 static bool classof(const DoStmt *) { return true; } 503 504 // Iterators 505 virtual child_iterator child_begin(); 506 virtual child_iterator child_end(); 507}; 508 509 510/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 511/// the init/cond/inc parts of the ForStmt will be null if they were not 512/// specified in the source. 513/// 514class ForStmt : public Stmt { 515 enum { INIT, COND, INC, BODY, END_EXPR }; 516 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 517 SourceLocation ForLoc; 518public: 519 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 520 : Stmt(ForStmtClass) { 521 SubExprs[INIT] = Init; 522 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 523 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 524 SubExprs[BODY] = Body; 525 ForLoc = FL; 526 } 527 528 Stmt *getInit() { return SubExprs[INIT]; } 529 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 530 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 531 Stmt *getBody() { return SubExprs[BODY]; } 532 533 const Stmt *getInit() const { return SubExprs[INIT]; } 534 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 535 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 536 const Stmt *getBody() const { return SubExprs[BODY]; } 537 538 virtual SourceRange getSourceRange() const { 539 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 540 } 541 static bool classof(const Stmt *T) { 542 return T->getStmtClass() == ForStmtClass; 543 } 544 static bool classof(const ForStmt *) { return true; } 545 546 // Iterators 547 virtual child_iterator child_begin(); 548 virtual child_iterator child_end(); 549}; 550 551/// GotoStmt - This represents a direct goto. 552/// 553class GotoStmt : public Stmt { 554 LabelStmt *Label; 555 SourceLocation GotoLoc; 556 SourceLocation LabelLoc; 557public: 558 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 559 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 560 561 LabelStmt *getLabel() const { return Label; } 562 563 virtual SourceRange getSourceRange() const { 564 return SourceRange(GotoLoc, LabelLoc); 565 } 566 static bool classof(const Stmt *T) { 567 return T->getStmtClass() == GotoStmtClass; 568 } 569 static bool classof(const GotoStmt *) { return true; } 570 571 // Iterators 572 virtual child_iterator child_begin(); 573 virtual child_iterator child_end(); 574}; 575 576/// IndirectGotoStmt - This represents an indirect goto. 577/// 578class IndirectGotoStmt : public Stmt { 579 Expr *Target; 580public: 581 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 582 583 Expr *getTarget() { return Target; } 584 const Expr *getTarget() const { return Target; } 585 586 virtual SourceRange getSourceRange() const { return SourceRange(); } 587 588 static bool classof(const Stmt *T) { 589 return T->getStmtClass() == IndirectGotoStmtClass; 590 } 591 static bool classof(const IndirectGotoStmt *) { return true; } 592 593 // Iterators 594 virtual child_iterator child_begin(); 595 virtual child_iterator child_end(); 596}; 597 598 599/// ContinueStmt - This represents a continue. 600/// 601class ContinueStmt : public Stmt { 602 SourceLocation ContinueLoc; 603public: 604 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 605 606 virtual SourceRange getSourceRange() const { 607 return SourceRange(ContinueLoc); 608 } 609 static bool classof(const Stmt *T) { 610 return T->getStmtClass() == ContinueStmtClass; 611 } 612 static bool classof(const ContinueStmt *) { return true; } 613 614 // Iterators 615 virtual child_iterator child_begin(); 616 virtual child_iterator child_end(); 617}; 618 619/// BreakStmt - This represents a break. 620/// 621class BreakStmt : public Stmt { 622 SourceLocation BreakLoc; 623public: 624 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 625 626 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 627 628 static bool classof(const Stmt *T) { 629 return T->getStmtClass() == BreakStmtClass; 630 } 631 static bool classof(const BreakStmt *) { return true; } 632 633 // Iterators 634 virtual child_iterator child_begin(); 635 virtual child_iterator child_end(); 636}; 637 638 639/// ReturnStmt - This represents a return, optionally of an expression. 640/// 641class ReturnStmt : public Stmt { 642 Expr *RetExpr; 643 SourceLocation RetLoc; 644public: 645 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 646 RetExpr(E), RetLoc(RL) {} 647 648 const Expr *getRetValue() const { return RetExpr; } 649 Expr *getRetValue() { return RetExpr; } 650 651 virtual SourceRange getSourceRange() const; 652 653 static bool classof(const Stmt *T) { 654 return T->getStmtClass() == ReturnStmtClass; 655 } 656 static bool classof(const ReturnStmt *) { return true; } 657 658 // Iterators 659 virtual child_iterator child_begin(); 660 virtual child_iterator child_end(); 661}; 662 663/// AsmStmt - This represents a GNU inline-assembly statement extension. 664/// 665class AsmStmt : public Stmt { 666 SourceLocation AsmLoc, RParenLoc; 667 // FIXME: This doesn't capture most of the interesting pieces. 668public: 669 AsmStmt(SourceLocation asmloc, SourceLocation rparenloc) 670 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {} 671 672 virtual SourceRange getSourceRange() const { 673 return SourceRange(AsmLoc, RParenLoc); 674 } 675 676 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 677 static bool classof(const AsmStmt *) { return true; } 678 679 virtual child_iterator child_begin(); 680 virtual child_iterator child_end(); 681}; 682 683 684} // end namespace clang 685 686//===----------------------------------------------------------------------===// 687// For Stmt serialization. 688//===----------------------------------------------------------------------===// 689 690namespace llvm { 691 692template<> struct SerializeTrait<clang::Stmt> { 693 static void Emit(Serializer& S, clang::Stmt& stmt); 694 static clang::Stmt* Materialize(Deserializer& D); 695}; 696 697} // end namespace llvm 698 699#endif 700