diff options
Diffstat (limited to 'include/clang/AST/StmtCXX.h')
-rw-r--r-- | include/clang/AST/StmtCXX.h | 96 |
1 files changed, 92 insertions, 4 deletions
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index 42dcf2b..a948722 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_STMTCXX_H #include "clang/AST/Stmt.h" +#include "llvm/Support/Compiler.h" namespace clang { @@ -37,7 +38,7 @@ public: CXXCatchStmt(EmptyShell Empty) : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {} - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(CatchLoc, HandlerBlock->getLocEnd()); } @@ -83,7 +84,7 @@ public: static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty, unsigned numHandlers); - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getTryLoc(), getEndLoc()); } @@ -148,7 +149,9 @@ public: DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); } - DeclStmt *getBeginEndStmt() { return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); } + DeclStmt *getBeginEndStmt() { + return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); + } Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); } Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); } DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); } @@ -187,7 +190,7 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); } static bool classof(const Stmt *T) { @@ -201,6 +204,91 @@ public: } }; +/// \brief Representation of a Microsoft __if_exists or __if_not_exists +/// statement with a dependent name. +/// +/// The __if_exists statement can be used to include a sequence of statements +/// in the program only when a particular dependent name does not exist. For +/// example: +/// +/// \code +/// template<typename T> +/// void call_foo(T &t) { +/// __if_exists (T::foo) { +/// t.foo(); // okay: only called when T::foo exists. +/// } +/// } +/// \endcode +/// +/// Similarly, the __if_not_exists statement can be used to include the +/// statements when a particular name does not exist. +/// +/// Note that this statement only captures __if_exists and __if_not_exists +/// statements whose name is dependent. All non-dependent cases are handled +/// directly in the parser, so that they don't introduce a new scope. Clang +/// introduces scopes in the dependent case to keep names inside the compound +/// statement from leaking out into the surround statements, which would +/// compromise the template instantiation model. This behavior differs from +/// Visual C++ (which never introduces a scope), but is a fairly reasonable +/// approximation of the VC++ behavior. +class MSDependentExistsStmt : public Stmt { + SourceLocation KeywordLoc; + bool IsIfExists; + NestedNameSpecifierLoc QualifierLoc; + DeclarationNameInfo NameInfo; + Stmt *SubStmt; + + friend class ASTReader; + friend class ASTStmtReader; + +public: + MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, + NestedNameSpecifierLoc QualifierLoc, + DeclarationNameInfo NameInfo, + CompoundStmt *SubStmt) + : Stmt(MSDependentExistsStmtClass), + KeywordLoc(KeywordLoc), IsIfExists(IsIfExists), + QualifierLoc(QualifierLoc), NameInfo(NameInfo), + SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { } + + /// \brief Retrieve the location of the __if_exists or __if_not_exists + /// keyword. + SourceLocation getKeywordLoc() const { return KeywordLoc; } + + /// \brief Determine whether this is an __if_exists statement. + bool isIfExists() const { return IsIfExists; } + + /// \brief Determine whether this is an __if_exists statement. + bool isIfNotExists() const { return !IsIfExists; } + + /// \brief Retrieve the nested-name-specifier that qualifies this name, if + /// any. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + + /// \brief Retrieve the name of the entity we're testing for, along with + /// location information + DeclarationNameInfo getNameInfo() const { return NameInfo; } + + /// \brief Retrieve the compound statement that will be included in the + /// program only if the existence of the symbol matches the initial keyword. + CompoundStmt *getSubStmt() const { + return reinterpret_cast<CompoundStmt *>(SubStmt); + } + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(KeywordLoc, SubStmt->getLocEnd()); + } + + child_range children() { + return child_range(&SubStmt, &SubStmt+1); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == MSDependentExistsStmtClass; + } + + static bool classof(MSDependentExistsStmt *) { return true; } +}; } // end namespace clang |