Stmt.h revision 63c00d7f35fa060c0a446c9df3a4402d9c7757fe
1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===// 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// The LLVM Compiler Infrastructure 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// This file is distributed under the University of Illinois Open Source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// License. See LICENSE.TXT for details. 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===----------------------------------------------------------------------===// 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// This file defines the Stmt interface and subclasses. 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===----------------------------------------------------------------------===// 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 14026d1ce6fc5608190aa5fd48f51278c60515c093pbos@webrtc.org#ifndef LLVM_CLANG_AST_STMT_H 15026d1ce6fc5608190aa5fd48f51278c60515c093pbos@webrtc.org#define LLVM_CLANG_AST_STMT_H 16026d1ce6fc5608190aa5fd48f51278c60515c093pbos@webrtc.org 17026d1ce6fc5608190aa5fd48f51278c60515c093pbos@webrtc.org#include "llvm/Support/Casting.h" 18acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.org#include "llvm/Support/raw_ostream.h" 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "clang/Basic/SourceLocation.h" 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "clang/AST/PrettyPrinter.h" 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "clang/AST/StmtIterator.h" 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "clang/AST/DeclGroup.h" 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "llvm/ADT/SmallVector.h" 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "clang/AST/ASTContext.h" 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string> 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgusing llvm::dyn_cast_or_null; 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace llvm { 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class FoldingSetNodeID; 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace clang { 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class ASTContext; 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class Expr; 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class Decl; 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class ParmVarDecl; 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class QualType; 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class IdentifierInfo; 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class SourceManager; 403bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org class StringLiteral; 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class SwitchStmt; 423bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //===----------------------------------------------------------------------===// 443bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org // ExprIterator - Iterators for iterating over Stmt* arrays that contain 453bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org // only Expr*. This is needed because AST nodes use Stmt* arrays to store 463bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org // references to children (to be compatible with StmtIterator). 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //===----------------------------------------------------------------------===// 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class Stmt; 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class Expr; 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class ExprIterator { 533bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org Stmt** I; 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 553bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org ExprIterator(Stmt** i) : I(i) {} 563bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org ExprIterator() : I(0) {} 573bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org ExprIterator& operator++() { ++I; return *this; } 583bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org ExprIterator operator-(size_t i) { return I-i; } 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ExprIterator operator+(size_t i) { return I+i; } 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Expr* operator[](size_t idx); 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // FIXME: Verify that this will correctly return a signed distance. 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org signed operator-(const ExprIterator& R) const { return I - R.I; } 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Expr* operator*() const; 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Expr* operator->() const; 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool operator==(const ExprIterator& R) const { return I == R.I; } 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool operator!=(const ExprIterator& R) const { return I != R.I; } 673bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org bool operator>(const ExprIterator& R) const { return I > R.I; } 683bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org bool operator>=(const ExprIterator& R) const { return I >= R.I; } 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }; 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class ConstExprIterator { 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Stmt * const *I; 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ConstExprIterator(const Stmt * const *i) : I(i) {} 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ConstExprIterator() : I(0) {} 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ConstExprIterator& operator++() { ++I; return *this; } 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ConstExprIterator operator+(size_t i) const { return I+i; } 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ConstExprIterator operator-(size_t i) const { return I-i; } 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Expr * operator[](size_t idx) const; 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org signed operator-(const ConstExprIterator& R) const { return I - R.I; } 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Expr * operator*() const; 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Expr * operator->() const; 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool operator==(const ConstExprIterator& R) const { return I == R.I; } 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool operator!=(const ConstExprIterator& R) const { return I != R.I; } 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool operator>(const ConstExprIterator& R) const { return I > R.I; } 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool operator>=(const ConstExprIterator& R) const { return I >= R.I; } 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }; 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===----------------------------------------------------------------------===// 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// AST classes for statements. 913bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org//===----------------------------------------------------------------------===// 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// Stmt - This represents one statement. 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass Stmt { 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic: 973bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org enum StmtClass { 983bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org NoStmtClass = 0, 993bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org#define STMT(CLASS, PARENT) CLASS##Class, 1003bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org#define STMT_RANGE(BASE, FIRST, LAST) \ 1013bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class, 102ba47616ee5a8d8a4d94e160b64b79a56845e291bandrew@webrtc.org#define LAST_STMT_RANGE(BASE, FIRST, LAST) \ 1033bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class 1043bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org#define ABSTRACT_STMT(STMT) 1053bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org#include "clang/AST/StmtNodes.inc" 1063bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org }; 1073bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org 1083bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org // Make vanilla 'new' and 'delete' illegal for Stmts. 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgprotected: 1103bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org void* operator new(size_t bytes) throw() { 1113bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org assert(0 && "Stmts cannot be allocated with regular 'new'."); 1123bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org return 0; 1133bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org } 1143bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org void operator delete(void* data) throw() { 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(0 && "Stmts cannot be released with regular 'delete'."); 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 118acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.org class StmtBitfields { 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class Stmt; 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief The statement class. 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned sClass : 8; 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }; 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum { NumStmtBits = 8 }; 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class CompoundStmtBitfields { 1273bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org friend class CompoundStmt; 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned : NumStmtBits; 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned NumStmts : 32 - NumStmtBits; 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }; 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class LabelStmtBitfields { 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class LabelStmt; 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned : NumStmtBits; 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned Used : 1; 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned HasUnusedAttr : 1; 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }; 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class ExprBitfields { 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class Expr; 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class DeclRefExpr; // computeDependence 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class InitListExpr; // ctor 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class DesignatedInitExpr; // ctor 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class BlockDeclRefExpr; // ctor 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class ASTStmtReader; // deserialization 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class CXXNewExpr; // ctor 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class DependentScopeDeclRefExpr; // ctor 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class CXXConstructExpr; // ctor 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class CallExpr; // ctor 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class OffsetOfExpr; // ctor 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class ObjCMessageExpr; // ctor 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class ShuffleVectorExpr; // ctor 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class ParenListExpr; // ctor 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class CXXUnresolvedConstructExpr; // ctor 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class CXXDependentScopeMemberExpr; // ctor 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class OverloadExpr; // ctor 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned : NumStmtBits; 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned ValueKind : 2; 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned ObjectKind : 2; 1639787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org unsigned TypeDependent : 1; 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned ValueDependent : 1; 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned ContainsUnexpandedParameterPack : 1; 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }; 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum { NumExprBits = 15 }; 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class CastExprBitfields { 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class CastExpr; 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned : NumExprBits; 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned Kind : 6; 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned BasePathSize : 32 - 6 - NumExprBits; 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }; 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org class CallExprBitfields { 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class CallExpr; 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned : NumExprBits; 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 18165952712c5e04c3a301a15ce7acfe8999a3686cafbarchard@google.com unsigned NumPreArgs : 1; 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }; 1839787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org union { 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // FIXME: this is wasteful on 64-bit platforms. 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void *Aligner; 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StmtBitfields StmtBits; 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CompoundStmtBitfields CompoundStmtBits; 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LabelStmtBitfields LabelStmtBits; 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ExprBitfields ExprBits; 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CastExprBitfields CastExprBits; 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CallExprBitfields CallExprBits; 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }; 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class ASTStmtReader; 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic: 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Only allow allocation of Stmts using the allocator in ASTContext 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // or by doing a placement new. 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void* operator new(size_t bytes, ASTContext& C, 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned alignment = 8) throw() { 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ::operator new(bytes, C, alignment); 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 205acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.org 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void* operator new(size_t bytes, ASTContext* C, 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned alignment = 8) throw() { 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ::operator new(bytes, *C, alignment); 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void* operator new(size_t bytes, void* mem) throw() { 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return mem; 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2159787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org void operator delete(void*, ASTContext&, unsigned) throw() { } 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void operator delete(void*, ASTContext*, unsigned) throw() { } 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void operator delete(void*, std::size_t) throw() { } 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void operator delete(void*, void*) throw() { } 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic: 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief A placeholder type used to construct an empty shell of a 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// type, that will be filled in later (e.g., by some 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// de-serialization). 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org struct EmptyShell { }; 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgprotected: 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief Construct an empty statement. 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org explicit Stmt(StmtClass SC, EmptyShell) { 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StmtBits.sClass = SC; 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic: 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Stmt(StmtClass SC) { 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StmtBits.sClass = SC; 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StmtClass getStmtClass() const { 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return static_cast<StmtClass>(StmtBits.sClass); 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const char *getStmtClassName() const; 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// SourceLocation tokens are not useful in isolation - they are low level 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// value objects created/interpreted by SourceManager. We assume AST 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// clients will have a pointer to the respective SourceManager. 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceRange getSourceRange() const; 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation getLocStart() const { return getSourceRange().getBegin(); } 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // global temp stats (until we have a per-module visitor) 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static void addStmtClass(const StmtClass s); 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static bool CollectingStats(bool Enable = false); 2559787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org static void PrintStats(); 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// dump - This does a local dump of the specified AST fragment. It dumps the 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// specified node and a few nodes underneath it, but not the whole subtree. 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// This is useful in a debugger. 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void dump() const; 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void dump(SourceManager &SM) const; 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void dump(llvm::raw_ostream &OS, SourceManager &SM) const; 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void dumpAll() const; 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void dumpAll(SourceManager &SM) const; 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// back to its original source language syntax. 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void dumpPretty(ASTContext& Context) const; 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper, 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const PrintingPolicy &Policy, 273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned Indentation = 0) const { 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation); 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void printPretty(llvm::raw_ostream &OS, ASTContext &Context, 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PrinterHelper *Helper, 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const PrintingPolicy &Policy, 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned Indentation = 0) const; 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// works on systems with GraphViz (Mac OS X) or dot+gv installed. 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void viewAST() const; 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Implement isa<T> support. 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static bool classof(const Stmt *) { return true; } 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// contain implicit control-flow in the order their subexpressions 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// are evaluated. This predicate returns true if this statement has 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// such implicit control-flow. Such statements are also specially handled 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// within CFGs. 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool hasImplicitControlFlow() const; 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// Child Iterators: All subclasses must implement 'children' 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// to permit easy iteration over the substatements/subexpessions of an 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// AST node. This permits easy iteration over all nodes in the AST. 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef StmtIterator child_iterator; 299acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.org typedef ConstStmtIterator const_child_iterator; 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef StmtRange child_range; 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef ConstStmtRange const_child_range; 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org child_range children(); 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const_child_range children() const { 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return const_cast<Stmt*>(this)->children(); 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3099787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org child_iterator child_begin() { return children().first; } 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org child_iterator child_end() { return children().second; } 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const_child_iterator child_begin() const { return children().first; } 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const_child_iterator child_end() const { return children().second; } 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief Produce a unique representation of the given statement. 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief ID once the profiling operation is complete, will contain 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// the unique representation of the given statement. 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief Context the AST context in which the statement resides 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief Canonical whether the profile should be based on the canonical 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// representation of this statement (e.g., where non-type template 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// parameters are identified by index/level rather than their 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// declaration pointers) or the exact representation of the statement as 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// written in the source. 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool Canonical); 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// DeclStmt - Adaptor class for mixing declarations with statements and 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// expressions. For example, CompoundStmt mixes statements, expressions 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// and declarations (variables, types). Another example is ForStmt, where 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// the first statement can be an expression or a declaration. 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass DeclStmt : public Stmt { 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DeclGroupRef DG; 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation StartLoc, EndLoc; 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic: 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DeclStmt(DeclGroupRef dg, SourceLocation startLoc, 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg), 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StartLoc(startLoc), EndLoc(endLoc) {} 3449787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief Build an empty declaration statement. 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { } 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// isSingleDecl - This method returns true if this DeclStmt refers 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// to a single Decl. 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool isSingleDecl() const { 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return DG.isSingleDecl(); 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Decl *getSingleDecl() const { return DG.getSingleDecl(); } 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Decl *getSingleDecl() { return DG.getSingleDecl(); } 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const DeclGroupRef getDeclGroup() const { return DG; } 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DeclGroupRef getDeclGroup() { return DG; } 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void setDeclGroup(DeclGroupRef DGR) { DG = DGR; } 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation getStartLoc() const { return StartLoc; } 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void setStartLoc(SourceLocation L) { StartLoc = L; } 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation getEndLoc() const { return EndLoc; } 3649787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org void setEndLoc(SourceLocation L) { EndLoc = L; } 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceRange getSourceRange() const { 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return SourceRange(StartLoc, EndLoc); 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static bool classof(const Stmt *T) { 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return T->getStmtClass() == DeclStmtClass; 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static bool classof(const DeclStmt *) { return true; } 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Iterators over subexpressions. 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org child_range children() { 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return child_range(child_iterator(DG.begin(), DG.end()), 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org child_iterator(DG.end(), DG.end())); 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef DeclGroupRef::iterator decl_iterator; 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef DeclGroupRef::const_iterator const_decl_iterator; 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org decl_iterator decl_begin() { return DG.begin(); } 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org decl_iterator decl_end() { return DG.end(); } 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const_decl_iterator decl_begin() const { return DG.begin(); } 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const_decl_iterator decl_end() const { return DG.end(); } 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// NullStmt - This is the null statement ";": C99 6.8.3p3. 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass NullStmt : public Stmt { 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation SemiLoc; 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief Whether the null statement was preceded by an empty macro, e.g: 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// @code 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// #define CALL(x) 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// CALL(0); 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// @endcode 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool LeadingEmptyMacro; 4019787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.orgpublic: 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org NullStmt(SourceLocation L, bool LeadingEmptyMacro = false) 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : Stmt(NullStmtClass), SemiLoc(L), LeadingEmptyMacro(LeadingEmptyMacro) {} 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief Build an empty null statement. 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) { } 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation getSemiLoc() const { return SemiLoc; } 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void setSemiLoc(SourceLocation L) { SemiLoc = L; } 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool hasLeadingEmptyMacro() const { return LeadingEmptyMacro; } 4129787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org 4139787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org SourceRange getSourceRange() const { return SourceRange(SemiLoc); } 4149787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static bool classof(const Stmt *T) { 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return T->getStmtClass() == NullStmtClass; 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static bool classof(const NullStmt *) { return true; } 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org child_range children() { return child_range(); } 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class ASTStmtReader; 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org friend class ASTStmtWriter; 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// CompoundStmt - This represents a group of statements like { stmt stmt }. 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass CompoundStmt : public Stmt { 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Stmt** Body; 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation LBracLoc, RBracLoc; 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic: 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned NumStmts, 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation LB, SourceLocation RB) 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : Stmt(CompoundStmtClass), LBracLoc(LB), RBracLoc(RB) { 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CompoundStmtBits.NumStmts = NumStmts; 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (NumStmts == 0) { 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Body = 0; 4393bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org return; 4403bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org } 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Body = new (C) Stmt*[NumStmts]; 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(Body, StmtStart, NumStmts * sizeof(*Body)); 4443bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org } 445ba47616ee5a8d8a4d94e160b64b79a56845e291bandrew@webrtc.org 4463bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org // \brief Build an empty compound statement. 4473bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org explicit CompoundStmt(EmptyShell Empty) 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : Stmt(CompoundStmtClass, Empty), Body(0) { 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CompoundStmtBits.NumStmts = 0; 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 4513bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org 4523bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts); 4533bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org 4543bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org bool body_empty() const { return CompoundStmtBits.NumStmts == 0; } 4553bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org unsigned size() const { return CompoundStmtBits.NumStmts; } 4563bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org 4573bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org typedef Stmt** body_iterator; 4583bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org body_iterator body_begin() { return Body; } 4593bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org body_iterator body_end() { return Body + size(); } 4603bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org Stmt *body_back() { return !body_empty() ? Body[size()-1] : 0; } 461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void setLastStmt(Stmt *S) { 463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(!body_empty() && "setLastStmt"); 464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Body[size()-1] = S; 4653bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org } 4663bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org 467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef Stmt* const * const_body_iterator; 468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const_body_iterator body_begin() const { return Body; } 469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const_body_iterator body_end() const { return Body + size(); } 470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Stmt *body_back() const { return !body_empty() ? Body[size()-1] : 0; } 471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef std::reverse_iterator<body_iterator> reverse_body_iterator; 473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org reverse_body_iterator body_rbegin() { 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return reverse_body_iterator(body_end()); 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org reverse_body_iterator body_rend() { 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return reverse_body_iterator(body_begin()); 478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef std::reverse_iterator<const_body_iterator> 481 const_reverse_body_iterator; 482 483 const_reverse_body_iterator body_rbegin() const { 484 return const_reverse_body_iterator(body_end()); 485 } 486 487 const_reverse_body_iterator body_rend() const { 488 return const_reverse_body_iterator(body_begin()); 489 } 490 491 SourceRange getSourceRange() const { 492 return SourceRange(LBracLoc, RBracLoc); 493 } 494 495 SourceLocation getLBracLoc() const { return LBracLoc; } 496 void setLBracLoc(SourceLocation L) { LBracLoc = L; } 497 SourceLocation getRBracLoc() const { return RBracLoc; } 498 void setRBracLoc(SourceLocation L) { RBracLoc = L; } 499 500 static bool classof(const Stmt *T) { 501 return T->getStmtClass() == CompoundStmtClass; 502 } 503 static bool classof(const CompoundStmt *) { return true; } 504 505 // Iterators 506 child_range children() { 507 return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts); 508 } 509}; 510 511// SwitchCase is the base class for CaseStmt and DefaultStmt, 512class SwitchCase : public Stmt { 513protected: 514 // A pointer to the following CaseStmt or DefaultStmt class, 515 // used by SwitchStmt. 516 SwitchCase *NextSwitchCase; 517 518 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 519 520public: 521 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 522 523 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 524 525 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 526 527 Stmt *getSubStmt(); 528 529 SourceRange getSourceRange() const { return SourceRange(); } 530 531 static bool classof(const Stmt *T) { 532 return T->getStmtClass() == CaseStmtClass || 533 T->getStmtClass() == DefaultStmtClass; 534 } 535 static bool classof(const SwitchCase *) { return true; } 536}; 537 538class CaseStmt : public SwitchCase { 539 enum { SUBSTMT, LHS, RHS, END_EXPR }; 540 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 541 // GNU "case 1 ... 4" extension 542 SourceLocation CaseLoc; 543 SourceLocation EllipsisLoc; 544 SourceLocation ColonLoc; 545public: 546 CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc, 547 SourceLocation ellipsisLoc, SourceLocation colonLoc) 548 : SwitchCase(CaseStmtClass) { 549 SubExprs[SUBSTMT] = 0; 550 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 551 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 552 CaseLoc = caseLoc; 553 EllipsisLoc = ellipsisLoc; 554 ColonLoc = colonLoc; 555 } 556 557 /// \brief Build an empty switch case statement. 558 explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { } 559 560 SourceLocation getCaseLoc() const { return CaseLoc; } 561 void setCaseLoc(SourceLocation L) { CaseLoc = L; } 562 SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 563 void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; } 564 SourceLocation getColonLoc() const { return ColonLoc; } 565 void setColonLoc(SourceLocation L) { ColonLoc = L; } 566 567 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 568 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 569 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 570 571 const Expr *getLHS() const { 572 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 573 } 574 const Expr *getRHS() const { 575 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 576 } 577 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 578 579 void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; } 580 void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); } 581 void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); } 582 583 584 SourceRange getSourceRange() const { 585 // Handle deeply nested case statements with iteration instead of recursion. 586 const CaseStmt *CS = this; 587 while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt())) 588 CS = CS2; 589 590 return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd()); 591 } 592 static bool classof(const Stmt *T) { 593 return T->getStmtClass() == CaseStmtClass; 594 } 595 static bool classof(const CaseStmt *) { return true; } 596 597 // Iterators 598 child_range children() { 599 return child_range(&SubExprs[0], &SubExprs[END_EXPR]); 600 } 601}; 602 603class DefaultStmt : public SwitchCase { 604 Stmt* SubStmt; 605 SourceLocation DefaultLoc; 606 SourceLocation ColonLoc; 607public: 608 DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) : 609 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL), 610 ColonLoc(CL) {} 611 612 /// \brief Build an empty default statement. 613 explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { } 614 615 Stmt *getSubStmt() { return SubStmt; } 616 const Stmt *getSubStmt() const { return SubStmt; } 617 void setSubStmt(Stmt *S) { SubStmt = S; } 618 619 SourceLocation getDefaultLoc() const { return DefaultLoc; } 620 void setDefaultLoc(SourceLocation L) { DefaultLoc = L; } 621 SourceLocation getColonLoc() const { return ColonLoc; } 622 void setColonLoc(SourceLocation L) { ColonLoc = L; } 623 624 SourceRange getSourceRange() const { 625 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 626 } 627 static bool classof(const Stmt *T) { 628 return T->getStmtClass() == DefaultStmtClass; 629 } 630 static bool classof(const DefaultStmt *) { return true; } 631 632 // Iterators 633 child_range children() { return child_range(&SubStmt, &SubStmt+1); } 634}; 635 636class LabelStmt : public Stmt { 637 IdentifierInfo *Label; 638 Stmt *SubStmt; 639 SourceLocation IdentLoc; 640public: 641 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt, 642 bool hasUnusedAttr = false) 643 : Stmt(LabelStmtClass), Label(label), SubStmt(substmt), IdentLoc(IL) { 644 LabelStmtBits.Used = false; 645 LabelStmtBits.HasUnusedAttr = hasUnusedAttr; 646 } 647 648 // \brief Build an empty label statement. 649 explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { } 650 651 SourceLocation getIdentLoc() const { return IdentLoc; } 652 IdentifierInfo *getID() const { return Label; } 653 void setID(IdentifierInfo *II) { Label = II; } 654 const char *getName() const; 655 Stmt *getSubStmt() { return SubStmt; } 656 const Stmt *getSubStmt() const { return SubStmt; } 657 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 658 void setSubStmt(Stmt *SS) { SubStmt = SS; } 659 660 /// \brief Whether this label was used. 661 bool isUsed(bool CheckUnusedAttr = true) const { 662 return LabelStmtBits.Used || 663 (CheckUnusedAttr && LabelStmtBits.HasUnusedAttr); 664 } 665 void setUsed(bool U = true) { LabelStmtBits.Used = U; } 666 667 bool HasUnusedAttribute() const { return LabelStmtBits.HasUnusedAttr; } 668 void setUnusedAttribute(bool U) { LabelStmtBits.HasUnusedAttr = U; } 669 670 SourceRange getSourceRange() const { 671 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 672 } 673 child_range children() { return child_range(&SubStmt, &SubStmt+1); } 674 675 static bool classof(const Stmt *T) { 676 return T->getStmtClass() == LabelStmtClass; 677 } 678 static bool classof(const LabelStmt *) { return true; } 679}; 680 681 682/// IfStmt - This represents an if/then/else. 683/// 684class IfStmt : public Stmt { 685 enum { VAR, COND, THEN, ELSE, END_EXPR }; 686 Stmt* SubExprs[END_EXPR]; 687 688 SourceLocation IfLoc; 689 SourceLocation ElseLoc; 690 691public: 692 IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, 693 Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0); 694 695 /// \brief Build an empty if/then/else statement 696 explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { } 697 698 /// \brief Retrieve the variable declared in this "if" statement, if any. 699 /// 700 /// In the following example, "x" is the condition variable. 701 /// \code 702 /// if (int x = foo()) { 703 /// printf("x is %d", x); 704 /// } 705 /// \endcode 706 VarDecl *getConditionVariable() const; 707 void setConditionVariable(ASTContext &C, VarDecl *V); 708 709 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 710 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } 711 const Stmt *getThen() const { return SubExprs[THEN]; } 712 void setThen(Stmt *S) { SubExprs[THEN] = S; } 713 const Stmt *getElse() const { return SubExprs[ELSE]; } 714 void setElse(Stmt *S) { SubExprs[ELSE] = S; } 715 716 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 717 Stmt *getThen() { return SubExprs[THEN]; } 718 Stmt *getElse() { return SubExprs[ELSE]; } 719 720 SourceLocation getIfLoc() const { return IfLoc; } 721 void setIfLoc(SourceLocation L) { IfLoc = L; } 722 SourceLocation getElseLoc() const { return ElseLoc; } 723 void setElseLoc(SourceLocation L) { ElseLoc = L; } 724 725 SourceRange getSourceRange() const { 726 if (SubExprs[ELSE]) 727 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 728 else 729 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 730 } 731 732 // Iterators over subexpressions. The iterators will include iterating 733 // over the initialization expression referenced by the condition variable. 734 child_range children() { 735 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 736 } 737 738 static bool classof(const Stmt *T) { 739 return T->getStmtClass() == IfStmtClass; 740 } 741 static bool classof(const IfStmt *) { return true; } 742}; 743 744/// SwitchStmt - This represents a 'switch' stmt. 745/// 746class SwitchStmt : public Stmt { 747 enum { VAR, COND, BODY, END_EXPR }; 748 Stmt* SubExprs[END_EXPR]; 749 // This points to a linked list of case and default statements. 750 SwitchCase *FirstCase; 751 SourceLocation SwitchLoc; 752 753 /// If the SwitchStmt is a switch on an enum value, this records whether 754 /// all the enum values were covered by CaseStmts. This value is meant to 755 /// be a hint for possible clients. 756 unsigned AllEnumCasesCovered : 1; 757 758public: 759 SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond); 760 761 /// \brief Build a empty switch statement. 762 explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { } 763 764 /// \brief Retrieve the variable declared in this "switch" statement, if any. 765 /// 766 /// In the following example, "x" is the condition variable. 767 /// \code 768 /// switch (int x = foo()) { 769 /// case 0: break; 770 /// // ... 771 /// } 772 /// \endcode 773 VarDecl *getConditionVariable() const; 774 void setConditionVariable(ASTContext &C, VarDecl *V); 775 776 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 777 const Stmt *getBody() const { return SubExprs[BODY]; } 778 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 779 780 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 781 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } 782 Stmt *getBody() { return SubExprs[BODY]; } 783 void setBody(Stmt *S) { SubExprs[BODY] = S; } 784 SwitchCase *getSwitchCaseList() { return FirstCase; } 785 786 /// \brief Set the case list for this switch statement. 787 /// 788 /// The caller is responsible for incrementing the retain counts on 789 /// all of the SwitchCase statements in this list. 790 void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; } 791 792 SourceLocation getSwitchLoc() const { return SwitchLoc; } 793 void setSwitchLoc(SourceLocation L) { SwitchLoc = L; } 794 795 void setBody(Stmt *S, SourceLocation SL) { 796 SubExprs[BODY] = S; 797 SwitchLoc = SL; 798 } 799 void addSwitchCase(SwitchCase *SC) { 800 assert(!SC->getNextSwitchCase() && "case/default already added to a switch"); 801 SC->setNextSwitchCase(FirstCase); 802 FirstCase = SC; 803 } 804 805 /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a 806 /// switch over an enum value then all cases have been explicitly covered. 807 void setAllEnumCasesCovered() { 808 AllEnumCasesCovered = 1; 809 } 810 811 /// Returns true if the SwitchStmt is a switch of an enum value and all cases 812 /// have been explicitly covered. 813 bool isAllEnumCasesCovered() const { 814 return (bool) AllEnumCasesCovered; 815 } 816 817 SourceRange getSourceRange() const { 818 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 819 } 820 // Iterators 821 child_range children() { 822 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 823 } 824 825 static bool classof(const Stmt *T) { 826 return T->getStmtClass() == SwitchStmtClass; 827 } 828 static bool classof(const SwitchStmt *) { return true; } 829}; 830 831 832/// WhileStmt - This represents a 'while' stmt. 833/// 834class WhileStmt : public Stmt { 835 enum { VAR, COND, BODY, END_EXPR }; 836 Stmt* SubExprs[END_EXPR]; 837 SourceLocation WhileLoc; 838public: 839 WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, 840 SourceLocation WL); 841 842 /// \brief Build an empty while statement. 843 explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { } 844 845 /// \brief Retrieve the variable declared in this "while" statement, if any. 846 /// 847 /// In the following example, "x" is the condition variable. 848 /// \code 849 /// while (int x = random()) { 850 /// // ... 851 /// } 852 /// \endcode 853 VarDecl *getConditionVariable() const; 854 void setConditionVariable(ASTContext &C, VarDecl *V); 855 856 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 857 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 858 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 859 Stmt *getBody() { return SubExprs[BODY]; } 860 const Stmt *getBody() const { return SubExprs[BODY]; } 861 void setBody(Stmt *S) { SubExprs[BODY] = S; } 862 863 SourceLocation getWhileLoc() const { return WhileLoc; } 864 void setWhileLoc(SourceLocation L) { WhileLoc = L; } 865 866 SourceRange getSourceRange() const { 867 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 868 } 869 static bool classof(const Stmt *T) { 870 return T->getStmtClass() == WhileStmtClass; 871 } 872 static bool classof(const WhileStmt *) { return true; } 873 874 // Iterators 875 child_range children() { 876 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 877 } 878}; 879 880/// DoStmt - This represents a 'do/while' stmt. 881/// 882class DoStmt : public Stmt { 883 enum { BODY, COND, END_EXPR }; 884 Stmt* SubExprs[END_EXPR]; 885 SourceLocation DoLoc; 886 SourceLocation WhileLoc; 887 SourceLocation RParenLoc; // Location of final ')' in do stmt condition. 888 889public: 890 DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL, 891 SourceLocation RP) 892 : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) { 893 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 894 SubExprs[BODY] = body; 895 } 896 897 /// \brief Build an empty do-while statement. 898 explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { } 899 900 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 901 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 902 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 903 Stmt *getBody() { return SubExprs[BODY]; } 904 const Stmt *getBody() const { return SubExprs[BODY]; } 905 void setBody(Stmt *S) { SubExprs[BODY] = S; } 906 907 SourceLocation getDoLoc() const { return DoLoc; } 908 void setDoLoc(SourceLocation L) { DoLoc = L; } 909 SourceLocation getWhileLoc() const { return WhileLoc; } 910 void setWhileLoc(SourceLocation L) { WhileLoc = L; } 911 912 SourceLocation getRParenLoc() const { return RParenLoc; } 913 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 914 915 SourceRange getSourceRange() const { 916 return SourceRange(DoLoc, RParenLoc); 917 } 918 static bool classof(const Stmt *T) { 919 return T->getStmtClass() == DoStmtClass; 920 } 921 static bool classof(const DoStmt *) { return true; } 922 923 // Iterators 924 child_range children() { 925 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 926 } 927}; 928 929 930/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 931/// the init/cond/inc parts of the ForStmt will be null if they were not 932/// specified in the source. 933/// 934class ForStmt : public Stmt { 935 enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR }; 936 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 937 SourceLocation ForLoc; 938 SourceLocation LParenLoc, RParenLoc; 939 940public: 941 ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, 942 Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP); 943 944 /// \brief Build an empty for statement. 945 explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { } 946 947 Stmt *getInit() { return SubExprs[INIT]; } 948 949 /// \brief Retrieve the variable declared in this "for" statement, if any. 950 /// 951 /// In the following example, "y" is the condition variable. 952 /// \code 953 /// for (int x = random(); int y = mangle(x); ++x) { 954 /// // ... 955 /// } 956 /// \endcode 957 VarDecl *getConditionVariable() const; 958 void setConditionVariable(ASTContext &C, VarDecl *V); 959 960 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 961 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 962 Stmt *getBody() { return SubExprs[BODY]; } 963 964 const Stmt *getInit() const { return SubExprs[INIT]; } 965 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 966 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 967 const Stmt *getBody() const { return SubExprs[BODY]; } 968 969 void setInit(Stmt *S) { SubExprs[INIT] = S; } 970 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 971 void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } 972 void setBody(Stmt *S) { SubExprs[BODY] = S; } 973 974 SourceLocation getForLoc() const { return ForLoc; } 975 void setForLoc(SourceLocation L) { ForLoc = L; } 976 SourceLocation getLParenLoc() const { return LParenLoc; } 977 void setLParenLoc(SourceLocation L) { LParenLoc = L; } 978 SourceLocation getRParenLoc() const { return RParenLoc; } 979 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 980 981 SourceRange getSourceRange() const { 982 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 983 } 984 static bool classof(const Stmt *T) { 985 return T->getStmtClass() == ForStmtClass; 986 } 987 static bool classof(const ForStmt *) { return true; } 988 989 // Iterators 990 child_range children() { 991 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); 992 } 993}; 994 995/// GotoStmt - This represents a direct goto. 996/// 997class GotoStmt : public Stmt { 998 LabelStmt *Label; 999 SourceLocation GotoLoc; 1000 SourceLocation LabelLoc; 1001public: 1002 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 1003 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 1004 1005 /// \brief Build an empty goto statement. 1006 explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { } 1007 1008 LabelStmt *getLabel() const { return Label; } 1009 void setLabel(LabelStmt *S) { Label = S; } 1010 1011 SourceLocation getGotoLoc() const { return GotoLoc; } 1012 void setGotoLoc(SourceLocation L) { GotoLoc = L; } 1013 SourceLocation getLabelLoc() const { return LabelLoc; } 1014 void setLabelLoc(SourceLocation L) { LabelLoc = L; } 1015 1016 SourceRange getSourceRange() const { 1017 return SourceRange(GotoLoc, LabelLoc); 1018 } 1019 static bool classof(const Stmt *T) { 1020 return T->getStmtClass() == GotoStmtClass; 1021 } 1022 static bool classof(const GotoStmt *) { return true; } 1023 1024 // Iterators 1025 child_range children() { return child_range(); } 1026}; 1027 1028/// IndirectGotoStmt - This represents an indirect goto. 1029/// 1030class IndirectGotoStmt : public Stmt { 1031 SourceLocation GotoLoc; 1032 SourceLocation StarLoc; 1033 Stmt *Target; 1034public: 1035 IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc, 1036 Expr *target) 1037 : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc), 1038 Target((Stmt*)target) {} 1039 1040 /// \brief Build an empty indirect goto statement. 1041 explicit IndirectGotoStmt(EmptyShell Empty) 1042 : Stmt(IndirectGotoStmtClass, Empty) { } 1043 1044 void setGotoLoc(SourceLocation L) { GotoLoc = L; } 1045 SourceLocation getGotoLoc() const { return GotoLoc; } 1046 void setStarLoc(SourceLocation L) { StarLoc = L; } 1047 SourceLocation getStarLoc() const { return StarLoc; } 1048 1049 Expr *getTarget() { return reinterpret_cast<Expr*>(Target); } 1050 const Expr *getTarget() const {return reinterpret_cast<const Expr*>(Target);} 1051 void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); } 1052 1053 /// getConstantTarget - Returns the fixed target of this indirect 1054 /// goto, if one exists. 1055 LabelStmt *getConstantTarget(); 1056 const LabelStmt *getConstantTarget() const { 1057 return const_cast<IndirectGotoStmt*>(this)->getConstantTarget(); 1058 } 1059 1060 SourceRange getSourceRange() const { 1061 return SourceRange(GotoLoc, Target->getLocEnd()); 1062 } 1063 1064 static bool classof(const Stmt *T) { 1065 return T->getStmtClass() == IndirectGotoStmtClass; 1066 } 1067 static bool classof(const IndirectGotoStmt *) { return true; } 1068 1069 // Iterators 1070 child_range children() { return child_range(&Target, &Target+1); } 1071}; 1072 1073 1074/// ContinueStmt - This represents a continue. 1075/// 1076class ContinueStmt : public Stmt { 1077 SourceLocation ContinueLoc; 1078public: 1079 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 1080 1081 /// \brief Build an empty continue statement. 1082 explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { } 1083 1084 SourceLocation getContinueLoc() const { return ContinueLoc; } 1085 void setContinueLoc(SourceLocation L) { ContinueLoc = L; } 1086 1087 SourceRange getSourceRange() const { 1088 return SourceRange(ContinueLoc); 1089 } 1090 1091 static bool classof(const Stmt *T) { 1092 return T->getStmtClass() == ContinueStmtClass; 1093 } 1094 static bool classof(const ContinueStmt *) { return true; } 1095 1096 // Iterators 1097 child_range children() { return child_range(); } 1098}; 1099 1100/// BreakStmt - This represents a break. 1101/// 1102class BreakStmt : public Stmt { 1103 SourceLocation BreakLoc; 1104public: 1105 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 1106 1107 /// \brief Build an empty break statement. 1108 explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { } 1109 1110 SourceLocation getBreakLoc() const { return BreakLoc; } 1111 void setBreakLoc(SourceLocation L) { BreakLoc = L; } 1112 1113 SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 1114 1115 static bool classof(const Stmt *T) { 1116 return T->getStmtClass() == BreakStmtClass; 1117 } 1118 static bool classof(const BreakStmt *) { return true; } 1119 1120 // Iterators 1121 child_range children() { return child_range(); } 1122}; 1123 1124 1125/// ReturnStmt - This represents a return, optionally of an expression: 1126/// return; 1127/// return 4; 1128/// 1129/// Note that GCC allows return with no argument in a function declared to 1130/// return a value, and it allows returning a value in functions declared to 1131/// return void. We explicitly model this in the AST, which means you can't 1132/// depend on the return type of the function and the presence of an argument. 1133/// 1134class ReturnStmt : public Stmt { 1135 Stmt *RetExpr; 1136 SourceLocation RetLoc; 1137 const VarDecl *NRVOCandidate; 1138 1139public: 1140 ReturnStmt(SourceLocation RL) 1141 : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { } 1142 1143 ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate) 1144 : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL), 1145 NRVOCandidate(NRVOCandidate) {} 1146 1147 /// \brief Build an empty return expression. 1148 explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { } 1149 1150 const Expr *getRetValue() const; 1151 Expr *getRetValue(); 1152 void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); } 1153 1154 SourceLocation getReturnLoc() const { return RetLoc; } 1155 void setReturnLoc(SourceLocation L) { RetLoc = L; } 1156 1157 /// \brief Retrieve the variable that might be used for the named return 1158 /// value optimization. 1159 /// 1160 /// The optimization itself can only be performed if the variable is 1161 /// also marked as an NRVO object. 1162 const VarDecl *getNRVOCandidate() const { return NRVOCandidate; } 1163 void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; } 1164 1165 SourceRange getSourceRange() const; 1166 1167 static bool classof(const Stmt *T) { 1168 return T->getStmtClass() == ReturnStmtClass; 1169 } 1170 static bool classof(const ReturnStmt *) { return true; } 1171 1172 // Iterators 1173 child_range children() { 1174 if (RetExpr) return child_range(&RetExpr, &RetExpr+1); 1175 return child_range(); 1176 } 1177}; 1178 1179/// AsmStmt - This represents a GNU inline-assembly statement extension. 1180/// 1181class AsmStmt : public Stmt { 1182 SourceLocation AsmLoc, RParenLoc; 1183 StringLiteral *AsmStr; 1184 1185 bool IsSimple; 1186 bool IsVolatile; 1187 bool MSAsm; 1188 1189 unsigned NumOutputs; 1190 unsigned NumInputs; 1191 unsigned NumClobbers; 1192 1193 // FIXME: If we wanted to, we could allocate all of these in one big array. 1194 IdentifierInfo **Names; 1195 StringLiteral **Constraints; 1196 Stmt **Exprs; 1197 StringLiteral **Clobbers; 1198 1199public: 1200 AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, 1201 bool msasm, unsigned numoutputs, unsigned numinputs, 1202 IdentifierInfo **names, StringLiteral **constraints, 1203 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 1204 StringLiteral **clobbers, SourceLocation rparenloc); 1205 1206 /// \brief Build an empty inline-assembly statement. 1207 explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty), 1208 Names(0), Constraints(0), Exprs(0), Clobbers(0) { } 1209 1210 SourceLocation getAsmLoc() const { return AsmLoc; } 1211 void setAsmLoc(SourceLocation L) { AsmLoc = L; } 1212 SourceLocation getRParenLoc() const { return RParenLoc; } 1213 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 1214 1215 bool isVolatile() const { return IsVolatile; } 1216 void setVolatile(bool V) { IsVolatile = V; } 1217 bool isSimple() const { return IsSimple; } 1218 void setSimple(bool V) { IsSimple = V; } 1219 bool isMSAsm() const { return MSAsm; } 1220 void setMSAsm(bool V) { MSAsm = V; } 1221 1222 //===--- Asm String Analysis ---===// 1223 1224 const StringLiteral *getAsmString() const { return AsmStr; } 1225 StringLiteral *getAsmString() { return AsmStr; } 1226 void setAsmString(StringLiteral *E) { AsmStr = E; } 1227 1228 /// AsmStringPiece - this is part of a decomposed asm string specification 1229 /// (for use with the AnalyzeAsmString function below). An asm string is 1230 /// considered to be a concatenation of these parts. 1231 class AsmStringPiece { 1232 public: 1233 enum Kind { 1234 String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%". 1235 Operand // Operand reference, with optional modifier %c4. 1236 }; 1237 private: 1238 Kind MyKind; 1239 std::string Str; 1240 unsigned OperandNo; 1241 public: 1242 AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {} 1243 AsmStringPiece(unsigned OpNo, char Modifier) 1244 : MyKind(Operand), Str(), OperandNo(OpNo) { 1245 Str += Modifier; 1246 } 1247 1248 bool isString() const { return MyKind == String; } 1249 bool isOperand() const { return MyKind == Operand; } 1250 1251 const std::string &getString() const { 1252 assert(isString()); 1253 return Str; 1254 } 1255 1256 unsigned getOperandNo() const { 1257 assert(isOperand()); 1258 return OperandNo; 1259 } 1260 1261 /// getModifier - Get the modifier for this operand, if present. This 1262 /// returns '\0' if there was no modifier. 1263 char getModifier() const { 1264 assert(isOperand()); 1265 return Str[0]; 1266 } 1267 }; 1268 1269 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing 1270 /// it into pieces. If the asm string is erroneous, emit errors and return 1271 /// true, otherwise return false. This handles canonicalization and 1272 /// translation of strings from GCC syntax to LLVM IR syntax, and handles 1273 //// flattening of named references like %[foo] to Operand AsmStringPiece's. 1274 unsigned AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces, 1275 ASTContext &C, unsigned &DiagOffs) const; 1276 1277 1278 //===--- Output operands ---===// 1279 1280 unsigned getNumOutputs() const { return NumOutputs; } 1281 1282 IdentifierInfo *getOutputIdentifier(unsigned i) const { 1283 return Names[i]; 1284 } 1285 1286 llvm::StringRef getOutputName(unsigned i) const { 1287 if (IdentifierInfo *II = getOutputIdentifier(i)) 1288 return II->getName(); 1289 1290 return llvm::StringRef(); 1291 } 1292 1293 /// getOutputConstraint - Return the constraint string for the specified 1294 /// output operand. All output constraints are known to be non-empty (either 1295 /// '=' or '+'). 1296 llvm::StringRef getOutputConstraint(unsigned i) const; 1297 1298 const StringLiteral *getOutputConstraintLiteral(unsigned i) const { 1299 return Constraints[i]; 1300 } 1301 StringLiteral *getOutputConstraintLiteral(unsigned i) { 1302 return Constraints[i]; 1303 } 1304 1305 Expr *getOutputExpr(unsigned i); 1306 1307 const Expr *getOutputExpr(unsigned i) const { 1308 return const_cast<AsmStmt*>(this)->getOutputExpr(i); 1309 } 1310 1311 /// isOutputPlusConstraint - Return true if the specified output constraint 1312 /// is a "+" constraint (which is both an input and an output) or false if it 1313 /// is an "=" constraint (just an output). 1314 bool isOutputPlusConstraint(unsigned i) const { 1315 return getOutputConstraint(i)[0] == '+'; 1316 } 1317 1318 /// getNumPlusOperands - Return the number of output operands that have a "+" 1319 /// constraint. 1320 unsigned getNumPlusOperands() const; 1321 1322 //===--- Input operands ---===// 1323 1324 unsigned getNumInputs() const { return NumInputs; } 1325 1326 IdentifierInfo *getInputIdentifier(unsigned i) const { 1327 return Names[i + NumOutputs]; 1328 } 1329 1330 llvm::StringRef getInputName(unsigned i) const { 1331 if (IdentifierInfo *II = getInputIdentifier(i)) 1332 return II->getName(); 1333 1334 return llvm::StringRef(); 1335 } 1336 1337 /// getInputConstraint - Return the specified input constraint. Unlike output 1338 /// constraints, these can be empty. 1339 llvm::StringRef getInputConstraint(unsigned i) const; 1340 1341 const StringLiteral *getInputConstraintLiteral(unsigned i) const { 1342 return Constraints[i + NumOutputs]; 1343 } 1344 StringLiteral *getInputConstraintLiteral(unsigned i) { 1345 return Constraints[i + NumOutputs]; 1346 } 1347 1348 Expr *getInputExpr(unsigned i); 1349 1350 const Expr *getInputExpr(unsigned i) const { 1351 return const_cast<AsmStmt*>(this)->getInputExpr(i); 1352 } 1353 1354 void setOutputsAndInputsAndClobbers(ASTContext &C, 1355 IdentifierInfo **Names, 1356 StringLiteral **Constraints, 1357 Stmt **Exprs, 1358 unsigned NumOutputs, 1359 unsigned NumInputs, 1360 StringLiteral **Clobbers, 1361 unsigned NumClobbers); 1362 1363 //===--- Other ---===// 1364 1365 /// getNamedOperand - Given a symbolic operand reference like %[foo], 1366 /// translate this into a numeric value needed to reference the same operand. 1367 /// This returns -1 if the operand name is invalid. 1368 int getNamedOperand(llvm::StringRef SymbolicName) const; 1369 1370 unsigned getNumClobbers() const { return NumClobbers; } 1371 StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } 1372 const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } 1373 1374 SourceRange getSourceRange() const { 1375 return SourceRange(AsmLoc, RParenLoc); 1376 } 1377 1378 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 1379 static bool classof(const AsmStmt *) { return true; } 1380 1381 // Input expr iterators. 1382 1383 typedef ExprIterator inputs_iterator; 1384 typedef ConstExprIterator const_inputs_iterator; 1385 1386 inputs_iterator begin_inputs() { 1387 return &Exprs[0] + NumOutputs; 1388 } 1389 1390 inputs_iterator end_inputs() { 1391 return &Exprs[0] + NumOutputs + NumInputs; 1392 } 1393 1394 const_inputs_iterator begin_inputs() const { 1395 return &Exprs[0] + NumOutputs; 1396 } 1397 1398 const_inputs_iterator end_inputs() const { 1399 return &Exprs[0] + NumOutputs + NumInputs; 1400 } 1401 1402 // Output expr iterators. 1403 1404 typedef ExprIterator outputs_iterator; 1405 typedef ConstExprIterator const_outputs_iterator; 1406 1407 outputs_iterator begin_outputs() { 1408 return &Exprs[0]; 1409 } 1410 outputs_iterator end_outputs() { 1411 return &Exprs[0] + NumOutputs; 1412 } 1413 1414 const_outputs_iterator begin_outputs() const { 1415 return &Exprs[0]; 1416 } 1417 const_outputs_iterator end_outputs() const { 1418 return &Exprs[0] + NumOutputs; 1419 } 1420 1421 child_range children() { 1422 return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); 1423 } 1424}; 1425 1426} // end namespace clang 1427 1428#endif 1429