From: Sebastian Redl Date: Fri, 10 Sep 2010 20:55:43 +0000 (+0000) Subject: Define and implement CXXNoexceptExpr. Create it in Sema. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2e156225a29407a50dd19041aa5750171ad44ea3;p=clang Define and implement CXXNoexceptExpr. Create it in Sema. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113623 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index adeb572637..4f84ed5b62 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -2431,6 +2431,39 @@ public: virtual child_iterator child_end(); }; +/// \brief Represents a C++0x noexcept expression (C++ [expr.unary.noexcept]). +/// +/// The noexcept expression tests whether a given expression might throw. Its +/// result is a boolean constant. +class CXXNoexceptExpr : public Expr { + bool Value : 1; + Stmt *Operand; + SourceRange Range; + +public: + CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val, + SourceLocation Keyword, SourceLocation RParen) + : Expr(CXXNoexceptExprClass, Ty, /*TypeDependent*/false, + /*ValueDependent*/Val == CT_Dependent), + Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) + { } + + Expr *getOperand() const { return static_cast(Operand); } + + virtual SourceRange getSourceRange() const { return Range; } + + bool getValue() const { return Value; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXNoexceptExprClass; + } + static bool classof(const CXXNoexceptExpr *) { return true; } + + // Iterators + virtual child_iterator child_begin(); + virtual child_iterator child_end(); +}; + inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() { if (isa(this)) return cast(this)->getExplicitTemplateArgs(); diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 2e9587f1bc..d971fb7c36 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1844,6 +1844,7 @@ DEF_TRAVERSE_STMT(ConditionalOperator, { }) DEF_TRAVERSE_STMT(UnaryOperator, { }) DEF_TRAVERSE_STMT(BinaryOperator, { }) DEF_TRAVERSE_STMT(CompoundAssignOperator, { }) +DEF_TRAVERSE_STMT(CXXNoexceptExpr, { }) // These literals (all of them) do not need any action. DEF_TRAVERSE_STMT(IntegerLiteral, { }) diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 7778a6d1db..94702841d3 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -110,6 +110,7 @@ def CXXDependentScopeMemberExpr : DStmt; def OverloadExpr : DStmt; def UnresolvedLookupExpr : DStmt; def UnresolvedMemberExpr : DStmt; +def CXXNoexceptExpr : DStmt; // Obj-C Expressions. def ObjCStringLiteral : DStmt; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index f6a2801d54..c98b140e23 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2251,6 +2251,8 @@ public: ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, Expr *Operand, SourceLocation RParen); + ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, + SourceLocation RParen); /// ActOnUnaryTypeTrait - Parsed one of the unary type trait support /// pseudo-functions. diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 42f8b7e3ab..fd22db277b 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -1040,3 +1040,10 @@ Stmt::child_iterator UnresolvedMemberExpr::child_end() { return child_iterator(&Base); return child_iterator(&Base + 1); } + +Stmt::child_iterator CXXNoexceptExpr::child_begin() { + return child_iterator(&Operand); +} +Stmt::child_iterator CXXNoexceptExpr::child_end() { + return child_iterator(&Operand + 1); +} diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 7736581738..165dd4d0c0 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2441,6 +2441,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::CXXScalarValueInitExprClass: case Expr::TypesCompatibleExprClass: case Expr::UnaryTypeTraitExprClass: + case Expr::CXXNoexceptExprClass: return NoDiag(); case Expr::CallExprClass: case Expr::CXXOperatorCallExprClass: { diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 88e047ddc3..2fc08dabf8 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -1235,6 +1235,12 @@ void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { << E->getQueriedType().getAsString(Policy) << ")"; } +void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { + OS << "noexcept("; + PrintExpr(E->getOperand()); + OS << ")"; +} + // Obj-C void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index 843248cc0b..607cf213db 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -830,6 +830,10 @@ void StmtProfiler::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *S) { VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs()); } +void StmtProfiler::VisitCXXNoexceptExpr(CXXNoexceptExpr *S) { + VisitExpr(S); +} + void StmtProfiler::VisitObjCStringLiteral(ObjCStringLiteral *S) { VisitExpr(S); } diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index a70a52d94e..1cf3211b70 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -1618,7 +1618,8 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { case Expr::TypesCompatibleExprClass: case Expr::UnaryTypeTraitExprClass: case Expr::VAArgExprClass: - case Expr::CXXUuidofExprClass: { + case Expr::CXXUuidofExprClass: + case Expr::CXXNoexceptExprClass: { // As bad as this diagnostic is, it's better than crashing. Diagnostic &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error, diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 7c9baa756b..8e29caa6a1 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -3114,15 +3114,21 @@ CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp, return CE; } -ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, - Expr *Operand, SourceLocation RParen) { +ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, + SourceLocation RParen) { // C++ [expr.unary.noexcept]p1: // The noexcept operator determines whether the evaluation of its operand, // which is an unevaluated operand, can throw an exception. ExprEvalContexts.back().Context = Unevaluated; -//return Owned(new (Context) CXXNoexceptExpr(KeyLoc, LParen, Operand, RParen)); - return ExprError(); + return Owned(new (Context) CXXNoexceptExpr(Context.BoolTy, Operand, + Operand->CanThrow(Context), + KeyLoc, RParen)); +} + +ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation, + Expr *Operand, SourceLocation RParen) { + return BuildCXXNoexceptExpr(KeyLoc, Operand, RParen); } ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) { diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 7f3450b22b..765ce0f5e8 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1773,6 +1773,14 @@ public: R, TemplateArgs); } + /// \brief Build a new noexcept expression. + /// + /// By default, performs semantic analysis to build the new expression. + /// Subclasses may override this routine to provide different behavior. + ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) { + return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd()); + } + /// \brief Build a new Objective-C @encode expression. /// /// By default, performs semantic analysis to build the new expression. @@ -5975,6 +5983,19 @@ TreeTransform::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) ? &TransArgs : 0)); } +template +ExprResult +TreeTransform::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) { + ExprResult SubExpr = getDerived().TransformExpr(E->getOperand()); + if (SubExpr.isInvalid()) + return ExprError(); + + if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand()) + return SemaRef.Owned(E->Retain()); + + return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get()); +} + template ExprResult TreeTransform::TransformObjCStringLiteral(ObjCStringLiteral *E) { diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index 6e5f61f449..e8c14d2592 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -145,6 +145,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) { case Stmt::CXXUnresolvedConstructExprClass: case Stmt::CXXDependentScopeMemberExprClass: case Stmt::UnresolvedMemberExprClass: + case Stmt::CXXNoexceptExprClass: case Stmt::ObjCStringLiteralClass: case Stmt::ObjCEncodeExprClass: case Stmt::ObjCSelectorExprClass: