diff options
Diffstat (limited to 'include/clang/AST/Stmt.h')
-rw-r--r-- | include/clang/AST/Stmt.h | 223 |
1 files changed, 162 insertions, 61 deletions
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 2a6fd6b..84bdfb8 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -20,8 +20,9 @@ #include "clang/AST/StmtIterator.h" #include "clang/AST/DeclGroup.h" #include "clang/AST/ASTContext.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" #include <string> namespace llvm { @@ -39,11 +40,11 @@ namespace clang { class StringLiteral; class SwitchStmt; - //===----------------------------------------------------------------------===// + //===--------------------------------------------------------------------===// // ExprIterator - Iterators for iterating over Stmt* arrays that contain // only Expr*. This is needed because AST nodes use Stmt* arrays to store // references to children (to be compatible with StmtIterator). - //===----------------------------------------------------------------------===// + //===--------------------------------------------------------------------===// class Stmt; class Expr; @@ -141,11 +142,14 @@ protected: friend class CallExpr; // ctor friend class OffsetOfExpr; // ctor friend class ObjCMessageExpr; // ctor + friend class ObjCArrayLiteral; // ctor + friend class ObjCDictionaryLiteral; // ctor friend class ShuffleVectorExpr; // ctor friend class ParenListExpr; // ctor friend class CXXUnresolvedConstructExpr; // ctor friend class CXXDependentScopeMemberExpr; // ctor friend class OverloadExpr; // ctor + friend class PseudoObjectExpr; // ctor friend class AtomicExpr; // ctor unsigned : NumStmtBits; @@ -158,15 +162,39 @@ protected: }; enum { NumExprBits = 16 }; + class CharacterLiteralBitfields { + friend class CharacterLiteral; + unsigned : NumExprBits; + + unsigned Kind : 2; + }; + + class FloatingLiteralBitfields { + friend class FloatingLiteral; + unsigned : NumExprBits; + + unsigned IsIEEE : 1; // Distinguishes between PPC128 and IEEE128. + unsigned IsExact : 1; + }; + + class UnaryExprOrTypeTraitExprBitfields { + friend class UnaryExprOrTypeTraitExpr; + unsigned : NumExprBits; + + unsigned Kind : 2; + unsigned IsType : 1; // true if operand is a type, false if an expression. + }; + class DeclRefExprBitfields { friend class DeclRefExpr; friend class ASTStmtReader; // deserialization unsigned : NumExprBits; unsigned HasQualifier : 1; - unsigned HasExplicitTemplateArgs : 1; + unsigned HasTemplateKWAndArgsInfo : 1; unsigned HasFoundDecl : 1; unsigned HadMultipleCandidates : 1; + unsigned RefersToEnclosingLocal : 1; }; class CastExprBitfields { @@ -184,6 +212,27 @@ protected: unsigned NumPreArgs : 1; }; + class ExprWithCleanupsBitfields { + friend class ExprWithCleanups; + friend class ASTStmtReader; // deserialization + + unsigned : NumExprBits; + + unsigned NumObjects : 32 - NumExprBits; + }; + + class PseudoObjectExprBitfields { + friend class PseudoObjectExpr; + friend class ASTStmtReader; // deserialization + + unsigned : NumExprBits; + + // These don't need to be particularly wide, because they're + // strictly limited by the forms of expressions we permit. + unsigned NumSubExprs : 8; + unsigned ResultIndex : 32 - 8 - NumExprBits; + }; + class ObjCIndirectCopyRestoreExprBitfields { friend class ObjCIndirectCopyRestoreExpr; unsigned : NumExprBits; @@ -191,6 +240,38 @@ protected: unsigned ShouldCopy : 1; }; + class InitListExprBitfields { + friend class InitListExpr; + + unsigned : NumExprBits; + + /// Whether this initializer list originally had a GNU array-range + /// designator in it. This is a temporary marker used by CodeGen. + unsigned HadArrayRangeDesignator : 1; + + /// Whether this initializer list initializes a std::initializer_list + /// object. + unsigned InitializesStdInitializerList : 1; + }; + + class TypeTraitExprBitfields { + friend class TypeTraitExpr; + friend class ASTStmtReader; + friend class ASTStmtWriter; + + unsigned : NumExprBits; + + /// \brief The kind of type trait, which is a value of a TypeTrait enumerator. + unsigned Kind : 8; + + /// \brief If this expression is not value-dependent, this indicates whether + /// the trait evaluated true or false. + unsigned Value : 1; + + /// \brief The number of arguments to this type trait. + unsigned NumArgs : 32 - 8 - 1 - NumExprBits; + }; + union { // FIXME: this is wasteful on 64-bit platforms. void *Aligner; @@ -198,13 +279,21 @@ protected: StmtBitfields StmtBits; CompoundStmtBitfields CompoundStmtBits; ExprBitfields ExprBits; + CharacterLiteralBitfields CharacterLiteralBits; + FloatingLiteralBitfields FloatingLiteralBits; + UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits; DeclRefExprBitfields DeclRefExprBits; CastExprBitfields CastExprBits; CallExprBitfields CallExprBits; + ExprWithCleanupsBitfields ExprWithCleanupsBits; + PseudoObjectExprBitfields PseudoObjectExprBits; ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits; + InitListExprBitfields InitListExprBits; + TypeTraitExprBitfields TypeTraitExprBits; }; friend class ASTStmtReader; + friend class ASTStmtWriter; public: // Only allow allocation of Stmts using the allocator in ASTContext @@ -234,20 +323,24 @@ public: /// de-serialization). struct EmptyShell { }; +private: + /// \brief Whether statistic collection is enabled. + static bool StatisticsEnabled; + protected: /// \brief Construct an empty statement. explicit Stmt(StmtClass SC, EmptyShell) { StmtBits.sClass = SC; - if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); + if (StatisticsEnabled) Stmt::addStmtClass(SC); } public: Stmt(StmtClass SC) { StmtBits.sClass = SC; - if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); + if (StatisticsEnabled) Stmt::addStmtClass(SC); } - StmtClass getStmtClass() const { + StmtClass getStmtClass() const { return static_cast<StmtClass>(StmtBits.sClass); } const char *getStmtClassName() const; @@ -255,21 +348,20 @@ public: /// SourceLocation tokens are not useful in isolation - they are low level /// value objects created/interpreted by SourceManager. We assume AST /// clients will have a pointer to the respective SourceManager. - SourceRange getSourceRange() const; - - SourceLocation getLocStart() const { return getSourceRange().getBegin(); } - SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } + SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY; + SourceLocation getLocEnd() const LLVM_READONLY; // global temp stats (until we have a per-module visitor) static void addStmtClass(const StmtClass s); - static bool CollectingStats(bool Enable = false); + static void EnableStatistics(); static void PrintStats(); /// dump - This does a local dump of the specified AST fragment. It dumps the /// specified node and a few nodes underneath it, but not the whole subtree. /// This is useful in a debugger. - void dump() const; - void dump(SourceManager &SM) const; + LLVM_ATTRIBUTE_USED void dump() const; + LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const; void dump(raw_ostream &OS, SourceManager &SM) const; /// dumpAll - This does a dump of the specified AST fragment and all subtrees. @@ -384,7 +476,7 @@ public: SourceLocation getEndLoc() const { return EndLoc; } void setEndLoc(SourceLocation L) { EndLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(StartLoc, EndLoc); } @@ -433,7 +525,7 @@ public: bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; } - SourceRange getSourceRange() const { return SourceRange(SemiLoc); } + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(SemiLoc); } static bool classof(const Stmt *T) { return T->getStmtClass() == NullStmtClass; @@ -483,7 +575,7 @@ public: body_iterator body_begin() { return Body; } body_iterator body_end() { return Body + size(); } Stmt *body_back() { return !body_empty() ? Body[size()-1] : 0; } - + void setLastStmt(Stmt *S) { assert(!body_empty() && "setLastStmt"); Body[size()-1] = S; @@ -513,7 +605,7 @@ public: return const_reverse_body_iterator(body_begin()); } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(LBracLoc, RBracLoc); } @@ -531,7 +623,7 @@ public: child_range children() { return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts); } - + const_child_range children() const { return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts); } @@ -558,7 +650,7 @@ public: return const_cast<SwitchCase*>(this)->getSubStmt(); } - SourceRange getSourceRange() const { return SourceRange(); } + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); } static bool classof(const Stmt *T) { return T->getStmtClass() == CaseStmtClass || @@ -613,7 +705,7 @@ public: void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { // Handle deeply nested case statements with iteration instead of recursion. const CaseStmt *CS = this; while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt())) @@ -653,7 +745,7 @@ public: SourceLocation getColonLoc() const { return ColonLoc; } void setColonLoc(SourceLocation L) { ColonLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(DefaultLoc, SubStmt->getLocEnd()); } static bool classof(const Stmt *T) { @@ -665,7 +757,7 @@ public: child_range children() { return child_range(&SubStmt, &SubStmt+1); } }; - + /// LabelStmt - Represents a label, which has a substatement. For example: /// foo: return; /// @@ -690,7 +782,7 @@ public: void setIdentLoc(SourceLocation L) { IdentLoc = L; } void setSubStmt(Stmt *SS) { SubStmt = SS; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(IdentLoc, SubStmt->getLocEnd()); } child_range children() { return child_range(&SubStmt, &SubStmt+1); } @@ -710,11 +802,11 @@ class IfStmt : public Stmt { SourceLocation IfLoc; SourceLocation ElseLoc; - + public: - IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, + IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0); - + /// \brief Build an empty if/then/else statement explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { } @@ -728,13 +820,13 @@ public: /// \endcode VarDecl *getConditionVariable() const; void setConditionVariable(ASTContext &C, VarDecl *V); - + /// If this IfStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. const DeclStmt *getConditionVariableDeclStmt() const { return reinterpret_cast<DeclStmt*>(SubExprs[VAR]); } - + const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } const Stmt *getThen() const { return SubExprs[THEN]; } @@ -751,7 +843,7 @@ public: SourceLocation getElseLoc() const { return ElseLoc; } void setElseLoc(SourceLocation L) { ElseLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { if (SubExprs[ELSE]) return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); else @@ -801,7 +893,7 @@ public: /// \endcode VarDecl *getConditionVariable() const; void setConditionVariable(ASTContext &C, VarDecl *V); - + /// If this SwitchStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. const DeclStmt *getConditionVariableDeclStmt() const { @@ -832,7 +924,8 @@ public: SwitchLoc = SL; } void addSwitchCase(SwitchCase *SC) { - assert(!SC->getNextSwitchCase() && "case/default already added to a switch"); + assert(!SC->getNextSwitchCase() + && "case/default already added to a switch"); SC->setNextSwitchCase(FirstCase); FirstCase = SC; } @@ -849,7 +942,7 @@ public: return (bool) AllEnumCasesCovered; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); } // Iterators @@ -871,7 +964,7 @@ class WhileStmt : public Stmt { Stmt* SubExprs[END_EXPR]; SourceLocation WhileLoc; public: - WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, + WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL); /// \brief Build an empty while statement. @@ -904,7 +997,7 @@ public: SourceLocation getWhileLoc() const { return WhileLoc; } void setWhileLoc(SourceLocation L) { WhileLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); } static bool classof(const Stmt *T) { @@ -953,7 +1046,7 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(DoLoc, RParenLoc); } static bool classof(const Stmt *T) { @@ -979,14 +1072,14 @@ class ForStmt : public Stmt { SourceLocation LParenLoc, RParenLoc; public: - ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, + ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP); /// \brief Build an empty for statement. explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { } Stmt *getInit() { return SubExprs[INIT]; } - + /// \brief Retrieve the variable declared in this "for" statement, if any. /// /// In the following example, "y" is the condition variable. @@ -997,7 +1090,7 @@ public: /// \endcode VarDecl *getConditionVariable() const; void setConditionVariable(ASTContext &C, VarDecl *V); - + /// If this ForStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. const DeclStmt *getConditionVariableDeclStmt() const { @@ -1025,7 +1118,7 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); } static bool classof(const Stmt *T) { @@ -1060,7 +1153,7 @@ public: SourceLocation getLabelLoc() const { return LabelLoc; } void setLabelLoc(SourceLocation L) { LabelLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(GotoLoc, LabelLoc); } static bool classof(const Stmt *T) { @@ -1104,7 +1197,7 @@ public: return const_cast<IndirectGotoStmt*>(this)->getConstantTarget(); } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(GotoLoc, Target->getLocEnd()); } @@ -1131,7 +1224,7 @@ public: SourceLocation getContinueLoc() const { return ContinueLoc; } void setContinueLoc(SourceLocation L) { ContinueLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(ContinueLoc); } @@ -1157,7 +1250,7 @@ public: SourceLocation getBreakLoc() const { return BreakLoc; } void setBreakLoc(SourceLocation L) { BreakLoc = L; } - SourceRange getSourceRange() const { return SourceRange(BreakLoc); } + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(BreakLoc); } static bool classof(const Stmt *T) { return T->getStmtClass() == BreakStmtClass; @@ -1182,7 +1275,7 @@ class ReturnStmt : public Stmt { Stmt *RetExpr; SourceLocation RetLoc; const VarDecl *NRVOCandidate; - + public: ReturnStmt(SourceLocation RL) : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { } @@ -1208,8 +1301,8 @@ public: /// also marked as an NRVO object. const VarDecl *getNRVOCandidate() const { return NRVOCandidate; } void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; } - - SourceRange getSourceRange() const; + + SourceRange getSourceRange() const LLVM_READONLY; static bool classof(const Stmt *T) { return T->getStmtClass() == ReturnStmtClass; @@ -1242,16 +1335,16 @@ class AsmStmt : public Stmt { StringLiteral **Constraints; Stmt **Exprs; StringLiteral **Clobbers; - + public: - AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, + AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, bool msasm, unsigned numoutputs, unsigned numinputs, IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, StringLiteral **clobbers, SourceLocation rparenloc); /// \brief Build an empty inline-assembly statement. - explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty), + explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty), Names(0), Constraints(0), Exprs(0), Clobbers(0) { } SourceLocation getAsmLoc() const { return AsmLoc; } @@ -1333,7 +1426,7 @@ public: StringRef getOutputName(unsigned i) const { if (IdentifierInfo *II = getOutputIdentifier(i)) return II->getName(); - + return StringRef(); } @@ -1394,7 +1487,7 @@ public: Expr *getInputExpr(unsigned i); void setInputExpr(unsigned i, Expr *E); - + const Expr *getInputExpr(unsigned i) const { return const_cast<AsmStmt*>(this)->getInputExpr(i); } @@ -1404,7 +1497,7 @@ public: StringLiteral **Constraints, Stmt **Exprs, unsigned NumOutputs, - unsigned NumInputs, + unsigned NumInputs, StringLiteral **Clobbers, unsigned NumClobbers); @@ -1419,7 +1512,7 @@ public: StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(AsmLoc, RParenLoc); } @@ -1490,15 +1583,20 @@ public: SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block); - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getExceptLoc(), getEndLoc()); } SourceLocation getExceptLoc() const { return Loc; } SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); } - Expr *getFilterExpr() const { return reinterpret_cast<Expr*>(Children[FILTER_EXPR]); } - CompoundStmt *getBlock() const { return llvm::cast<CompoundStmt>(Children[BLOCK]); } + Expr *getFilterExpr() const { + return reinterpret_cast<Expr*>(Children[FILTER_EXPR]); + } + + CompoundStmt *getBlock() const { + return llvm::cast<CompoundStmt>(Children[BLOCK]); + } child_range children() { return child_range(Children,Children+2); @@ -1528,7 +1626,7 @@ public: SourceLocation FinallyLoc, Stmt *Block); - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getFinallyLoc(), getEndLoc()); } @@ -1572,7 +1670,7 @@ public: Stmt *TryBlock, Stmt *Handler); - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getTryLoc(), getEndLoc()); } @@ -1580,7 +1678,11 @@ public: SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); } bool getIsCXXTry() const { return IsCXXTry; } - CompoundStmt* getTryBlock() const { return llvm::cast<CompoundStmt>(Children[TRY]); } + + CompoundStmt* getTryBlock() const { + return llvm::cast<CompoundStmt>(Children[TRY]); + } + Stmt *getHandler() const { return Children[HANDLER]; } /// Returns 0 if not defined @@ -1596,7 +1698,6 @@ public: } static bool classof(SEHTryStmt *) { return true; } - }; } // end namespace clang |