diff options
-rw-r--r-- | Driver/RewriteObjC.cpp | 71 | ||||
-rw-r--r-- | include/clang/AST/Expr.h | 84 | ||||
-rw-r--r-- | include/clang/AST/ExprCXX.h | 150 | ||||
-rw-r--r-- | include/clang/AST/StmtNodes.def | 59 | ||||
-rw-r--r-- | include/clang/Parse/Action.h | 12 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 6 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 21 | ||||
-rw-r--r-- | lib/AST/StmtDumper.cpp | 14 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 27 | ||||
-rw-r--r-- | lib/AST/StmtSerialization.cpp | 57 | ||||
-rw-r--r-- | lib/Analysis/Environment.cpp | 2 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 5 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 12 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 37 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 38 | ||||
-rw-r--r-- | test/SemaCXX/return-stack-addr.cpp | 1 |
19 files changed, 413 insertions, 197 deletions
diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp index 37d416ac97..00604726fa 100644 --- a/Driver/RewriteObjC.cpp +++ b/Driver/RewriteObjC.cpp @@ -1057,8 +1057,8 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation(), II); assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); - CastExpr *castExpr = new ExplicitCastExpr(castT, IV->getBase(), - SourceLocation()); + CastExpr *castExpr = new ExplicitCCastExpr(castT, IV->getBase(), castT, + SourceLocation()); // Don't forget the parens to enforce the proper binding. ParenExpr *PE = new ParenExpr(IV->getBase()->getLocStart(), IV->getBase()->getLocEnd(), @@ -1099,8 +1099,8 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation(), II); assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); - CastExpr *castExpr = new ExplicitCastExpr(castT, IV->getBase(), - SourceLocation()); + CastExpr *castExpr = new ExplicitCCastExpr(castT, IV->getBase(), castT, + SourceLocation()); // Don't forget the parens to enforce the proper binding. ParenExpr *PE = new ParenExpr(IV->getBase()->getLocStart(), IV->getBase()->getLocEnd(), castExpr); @@ -1238,7 +1238,7 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { } } - if (ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(S)) + if (ExplicitCCastExpr *CE = dyn_cast<ExplicitCCastExpr>(S)) RewriteObjCQualifiedInterfaceTypes(CE); if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || @@ -1559,8 +1559,10 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) { buf += " _rethrow = objc_exception_extract(&_stack);\n"; buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n"; buf += " objc_sync_exit("; - Expr *syncExpr = new ExplicitCastExpr(Context->getObjCIdType(), - S->getSynchExpr(), SourceLocation()); + Expr *syncExpr = new ExplicitCCastExpr(Context->getObjCIdType(), + S->getSynchExpr(), + Context->getObjCIdType(), + SourceLocation()); std::string syncExprBufS; llvm::raw_string_ostream syncExprBuf(syncExprBufS); syncExpr->printPretty(syncExprBuf); @@ -2186,7 +2188,8 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { Context->getPointerType(DRE->getType()), SourceLocation()); // cast to NSConstantString * - CastExpr *cast = new ExplicitCastExpr(Exp->getType(), Unop, SourceLocation()); + CastExpr *cast = new ExplicitCCastExpr(Exp->getType(), Unop, + Exp->getType(), SourceLocation()); ReplaceStmt(Exp, cast); delete Exp; return cast; @@ -2321,9 +2324,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { &ClsExprs[0], ClsExprs.size()); // To turn off a warning, type-cast to 'id' - InitExprs.push_back( - new ExplicitCastExpr(Context->getObjCIdType(), - Cls, SourceLocation())); // set 'super class', using objc_getClass(). + InitExprs.push_back( // set 'super class', using objc_getClass(). + new ExplicitCCastExpr(Context->getObjCIdType(), + Cls, Context->getObjCIdType(), + SourceLocation())); // struct objc_super QualType superType = getSuperStructType(); Expr *SuperRep; @@ -2372,10 +2376,11 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { llvm::SmallVector<Expr*, 4> InitExprs; InitExprs.push_back( - new ExplicitCastExpr(Context->getObjCIdType(), + new ExplicitCCastExpr(Context->getObjCIdType(), new DeclRefExpr(CurMethodDef->getSelfDecl(), Context->getObjCIdType(), - SourceLocation()), + SourceLocation()), + Context->getObjCIdType(), SourceLocation())); // set the 'receiver'. llvm::SmallVector<Expr*, 8> ClsExprs; @@ -2389,8 +2394,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { ClsExprs.size()); // To turn off a warning, type-cast to 'id' InitExprs.push_back( - new ExplicitCastExpr(Context->getObjCIdType(), - Cls, SourceLocation())); // set 'super class', using objc_getClass(). + // set 'super class', using objc_getClass(). + new ExplicitCCastExpr(Context->getObjCIdType(), + Cls, Context->getObjCIdType(), SourceLocation())); // struct objc_super QualType superType = getSuperStructType(); Expr *SuperRep; @@ -2417,10 +2423,11 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { } else { // Remove all type-casts because it may contain objc-style types; e.g. // Foo<Proto> *. - while (ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(recExpr)) + while (ExplicitCCastExpr *CE = dyn_cast<ExplicitCCastExpr>(recExpr)) recExpr = CE->getSubExpr(); - recExpr = new ExplicitCastExpr(Context->getObjCIdType(), recExpr, - SourceLocation()); + recExpr = new ExplicitCCastExpr(Context->getObjCIdType(), recExpr, + Context->getObjCIdType(), + SourceLocation()); MsgExprs.push_back(recExpr); } } @@ -2441,17 +2448,19 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { // Make all implicit casts explicit...ICE comes in handy:-) if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) { // Reuse the ICE type, it is exactly what the doctor ordered. - userExpr = new ExplicitCastExpr(ICE->getType()->isObjCQualifiedIdType() + QualType type = ICE->getType()->isObjCQualifiedIdType() ? Context->getObjCIdType() - : ICE->getType(), userExpr, SourceLocation()); + : ICE->getType(); + userExpr = new ExplicitCCastExpr(type, userExpr, type, SourceLocation()); } // Make id<P...> cast into an 'id' cast. - else if (ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(userExpr)) { + else if (ExplicitCCastExpr *CE = dyn_cast<ExplicitCCastExpr>(userExpr)) { if (CE->getType()->isObjCQualifiedIdType()) { - while ((CE = dyn_cast<ExplicitCastExpr>(userExpr))) + while ((CE = dyn_cast<ExplicitCCastExpr>(userExpr))) userExpr = CE->getSubExpr(); - userExpr = new ExplicitCastExpr(Context->getObjCIdType(), - userExpr, SourceLocation()); + userExpr = new ExplicitCCastExpr(Context->getObjCIdType(), + userExpr, Context->getObjCIdType(), + SourceLocation()); } } MsgExprs.push_back(userExpr); @@ -2494,8 +2503,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { // If we don't do this cast, we get the following bizarre warning/note: // xx.m:13: warning: function called through a non-compatible type // xx.m:13: note: if this code is reached, the program will abort - cast = new ExplicitCastExpr(Context->getPointerType(Context->VoidTy), DRE, - SourceLocation()); + cast = new ExplicitCCastExpr(Context->getPointerType(Context->VoidTy), DRE, + Context->getPointerType(Context->VoidTy), + SourceLocation()); // Now do the "normal" pointer to function cast. QualType castType = Context->getFunctionType(returnType, @@ -2503,7 +2513,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { // If we don't have a method decl, force a variadic cast. Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0); castType = Context->getPointerType(castType); - cast = new ExplicitCastExpr(castType, cast, SourceLocation()); + cast = new ExplicitCCastExpr(castType, cast, castType, SourceLocation()); // Don't forget the parens to enforce the proper binding. ParenExpr *PE = new ParenExpr(SourceLocation(), SourceLocation(), cast); @@ -2522,14 +2532,15 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { DeclRefExpr *STDRE = new DeclRefExpr(MsgSendStretFlavor, msgSendType, SourceLocation()); // Need to cast objc_msgSend_stret to "void *" (see above comment). - cast = new ExplicitCastExpr(Context->getPointerType(Context->VoidTy), STDRE, - SourceLocation()); + cast = new ExplicitCCastExpr(Context->getPointerType(Context->VoidTy), STDRE, + Context->getPointerType(Context->VoidTy), + SourceLocation()); // Now do the "normal" pointer to function cast. castType = Context->getFunctionType(returnType, &ArgTypes[0], ArgTypes.size(), Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0); castType = Context->getPointerType(castType); - cast = new ExplicitCastExpr(castType, cast, SourceLocation()); + cast = new ExplicitCCastExpr(castType, cast, castType, SourceLocation()); // Don't forget the parens to enforce the proper binding. PE = new ParenExpr(SourceLocation(), SourceLocation(), cast); diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 28edccee53..70a768171e 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -771,12 +771,10 @@ public: static CompoundLiteralExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; -/// CastExpr - Base class for Cast Operators (explicit, implicit, etc.). -/// Classes that derive from CastExpr are: -/// -/// ImplicitCastExpr -/// ExplicitCastExpr -/// +/// CastExpr - Base class for type casts, including both implicit +/// casts (ImplicitCastExpr) and explicit casts that have some +/// representation in the source code (ExplicitCastExpr's derived +/// classes). class CastExpr : public Expr { Stmt *Op; protected: @@ -791,6 +789,12 @@ public: switch (T->getStmtClass()) { case ImplicitCastExprClass: case ExplicitCastExprClass: + case ExplicitCCastExprClass: + case CXXNamedCastExprClass: + case CXXStaticCastExprClass: + case CXXDynamicCastExprClass: + case CXXReinterpretCastExprClass: + case CXXConstCastExprClass: case CXXFunctionalCastExprClass: return true; default: @@ -804,9 +808,10 @@ public: virtual child_iterator child_end(); }; -/// ImplicitCastExpr - Allows us to explicitly represent implicit type -/// conversions. For example: converting T[]->T*, void f()->void (*f)(), -/// float->double, short->int, etc. +/// ImplicitCastExpr - Allows us to explicitly represent implicit type +/// conversions, which have no direct representation in the original +/// source code. For example: converting T[]->T*, void f()->void +/// (*f)(), float->double, short->int, etc. /// class ImplicitCastExpr : public CastExpr { public: @@ -826,13 +831,62 @@ public: static ImplicitCastExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; -/// ExplicitCastExpr - [C99 6.5.4] Cast Operators. +/// ExplicitCastExpr - An explicit cast written in the source +/// code. +/// +/// This class is effectively an abstract class, because it provides +/// the basic representation of an explicitly-written cast without +/// specifying which kind of cast (C cast, functional cast, static +/// cast, etc.) was written; specific derived classes represent the +/// particular style of cast and its location information. /// +/// Unlike implicit casts, explicit cast nodes have two different +/// types: the type that was written into the source code, and the +/// actual type of the expression as determined by semantic +/// analysis. These types may differ slightly. For example, in C++ one +/// can cast to a reference type, which indicates that the resulting +/// expression will be an lvalue. The reference type, however, will +/// not be used as the type of the expression. class ExplicitCastExpr : public CastExpr { + /// TypeAsWritten - The type that this expression is casting to, as + /// written in the source code. + QualType TypeAsWritten; + +protected: + ExplicitCastExpr(StmtClass SC, QualType exprTy, Expr *op, QualType writtenTy) : + CastExpr(SC, exprTy, op), TypeAsWritten(writtenTy) {} + +public: + /// getTypeAsWritten - Returns the type that this expression is + /// casting to, as written in the source code. + QualType getTypeAsWritten() const { return TypeAsWritten; } + + static bool classof(const Stmt *T) { + switch (T->getStmtClass()) { + case ExplicitCastExprClass: + case ExplicitCCastExprClass: + case CXXFunctionalCastExprClass: + case CXXStaticCastExprClass: + case CXXDynamicCastExprClass: + case CXXReinterpretCastExprClass: + case CXXConstCastExprClass: + return true; + default: + return false; + } + } + static bool classof(const ExplicitCastExpr *) { return true; } +}; + +/// ExplicitCCastExpr - An explicit cast in C (C99 6.5.4) or a C-style +/// cast in C++ (C++ [expr.cast]), which uses the syntax +/// (Type)expr. For example: @c (int)f. +class ExplicitCCastExpr : public ExplicitCastExpr { SourceLocation Loc; // the location of the left paren public: - ExplicitCastExpr(QualType ty, Expr *op, SourceLocation l) : - CastExpr(ExplicitCastExprClass, ty, op), Loc(l) {} + ExplicitCCastExpr(QualType exprTy, Expr *op, QualType writtenTy, + SourceLocation l) : + ExplicitCastExpr(ExplicitCCastExprClass, exprTy, op, writtenTy), Loc(l) {} SourceLocation getLParenLoc() const { return Loc; } @@ -840,12 +894,12 @@ public: return SourceRange(Loc, getSubExpr()->getSourceRange().getEnd()); } static bool classof(const Stmt *T) { - return T->getStmtClass() == ExplicitCastExprClass; + return T->getStmtClass() == ExplicitCCastExprClass; } - static bool classof(const ExplicitCastExpr *) { return true; } + static bool classof(const ExplicitCCastExpr *) { return true; } virtual void EmitImpl(llvm::Serializer& S) const; - static ExplicitCastExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); + static ExplicitCCastExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; class BinaryOperator : public Expr { diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 915c9e000f..ef5f95d09c 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -23,54 +23,112 @@ namespace clang { // C++ Expressions. //===--------------------------------------------------------------------===// -/// CXXCastExpr - [C++ 5.2.7, 5.2.9, 5.2.10, 5.2.11] C++ Cast Operators. -/// -class CXXCastExpr : public Expr { -public: - enum Opcode { - DynamicCast, - StaticCast, - ReinterpretCast, - ConstCast - }; +/// CXXNamedCastExpr - Abstract class common to all of the C++ "named" +/// casts, @c static_cast, @c dynamic_cast, @c reinterpret_cast, or @c +/// const_cast. +/// +/// This abstract class is inherited by all of the classes +/// representing "named" casts, e.g., CXXStaticCastExpr, +/// CXXDynamicCastExpr, CXXReinterpretCastExpr, and CXXConstCastExpr. +class CXXNamedCastExpr : public ExplicitCastExpr { private: - QualType Ty; - Opcode Opc; - Stmt *Op; SourceLocation Loc; // the location of the casting op + +protected: + CXXNamedCastExpr(StmtClass SC, QualType ty, Expr *op, QualType writtenTy, + SourceLocation l) + : ExplicitCastExpr(SC, ty, op, writtenTy), Loc(l) {} + public: - CXXCastExpr(Opcode op, QualType ty, Expr *expr, SourceLocation l) - : Expr(CXXCastExprClass, ty), Ty(ty), Opc(op), Op(expr), Loc(l) {} - - QualType getDestType() const { return Ty; } - Expr *getSubExpr() const { return cast<Expr>(Op); } - - Opcode getOpcode() const { return Opc; } - - /// getOpcodeStr - Turn an Opcode enum value into the string it represents, - /// e.g. "reinterpret_cast". - static const char *getOpcodeStr(Opcode Op) { - // FIXME: move out of line. - switch (Op) { - default: assert(0 && "Not a C++ cast expression"); - case CXXCastExpr::ConstCast: return "const_cast"; - case CXXCastExpr::DynamicCast: return "dynamic_cast"; - case CXXCastExpr::ReinterpretCast: return "reinterpret_cast"; - case CXXCastExpr::StaticCast: return "static_cast"; - } - } - + const char *getCastName() const; + virtual SourceRange getSourceRange() const { return SourceRange(Loc, getSubExpr()->getSourceRange().getEnd()); } static bool classof(const Stmt *T) { - return T->getStmtClass() == CXXCastExprClass; + switch (T->getStmtClass()) { + case CXXNamedCastExprClass: + case CXXStaticCastExprClass: + case CXXDynamicCastExprClass: + case CXXReinterpretCastExprClass: + case CXXConstCastExprClass: + return true; + default: + return false; + } } - static bool classof(const CXXCastExpr *) { return true; } + static bool classof(const CXXNamedCastExpr *) { return true; } - // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + virtual void EmitImpl(llvm::Serializer& S) const; + static CXXNamedCastExpr *CreateImpl(llvm::Deserializer& D, ASTContext& C, + StmtClass SC); +}; + +/// CXXStaticCastExpr - A C++ @c static_cast expression (C++ [expr.static.cast]). +/// +/// This expression node represents a C++ static cast, e.g., +/// @c static_cast<int>(1.0). +class CXXStaticCastExpr : public CXXNamedCastExpr { +public: + CXXStaticCastExpr(QualType ty, Expr *op, QualType writtenTy, SourceLocation l) + : CXXNamedCastExpr(CXXStaticCastExprClass, ty, op, writtenTy, l) {} + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXStaticCastExprClass; + } + static bool classof(const CXXStaticCastExpr *) { return true; } +}; + +/// CXXDynamicCastExpr - A C++ @c dynamic_cast expression +/// (C++ [expr.dynamic.cast]), which may perform a run-time check to +/// determine how to perform the type cast. +/// +/// This expression node represents a dynamic cast, e.g., +/// @c dynamic_cast<Derived*>(BasePtr). +class CXXDynamicCastExpr : public CXXNamedCastExpr { +public: + CXXDynamicCastExpr(QualType ty, Expr *op, QualType writtenTy, SourceLocation l) + : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, op, writtenTy, l) {} + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXDynamicCastExprClass; + } + static bool classof(const CXXDynamicCastExpr *) { return true; } +}; + +/// CXXReinterpretCastExpr - A C++ @c reinterpret_cast expression (C++ +/// [expr.reinterpret.cast]), which provides a differently-typed view +/// of a value but performs no actual work at run time. +/// +/// This expression node represents a reinterpret cast, e.g., +/// @c reinterpret_cast<int>(VoidPtr). +class CXXReinterpretCastExpr : public CXXNamedCastExpr { +public: + CXXReinterpretCastExpr(QualType ty, Expr *op, QualType writtenTy, + SourceLocation l) + : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, op, writtenTy, l) {} + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXReinterpretCastExprClass; + } + static bool classof(const CXXReinterpretCastExpr *) { return true; } +}; + +/// CXXConstCastExpr - A C++ @c const_cast expression (C++ [expr.const.cast]), +/// which can remove type qualifiers but does not change the underlying value. +/// +/// This expression node represents a const cast, e.g., +/// @c const_cast<char*>(PtrToConstChar). +class CXXConstCastExpr : public CXXNamedCastExpr { +public: + CXXConstCastExpr(QualType ty, Expr *op, QualType writtenTy, + SourceLocation l) + : CXXNamedCastExpr(CXXConstCastExprClass, ty, op, writtenTy, l) {} + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXConstCastExprClass; + } + static bool classof(const CXXConstCastExpr *) { return true; } }; /// CXXBoolLiteralExpr - [C++ 2.13.5] C++ Boolean Literal. @@ -170,17 +228,17 @@ public: ASTContext& C); }; -/// CXXFunctionalCastExpr - [C++ 5.2.3p1] Explicit type conversion -/// (functional notation). -/// Example: "x = int(0.5);" -/// -class CXXFunctionalCastExpr : public CastExpr { +/// CXXFunctionalCastExpr - Represents an explicit C++ type conversion +/// that uses "functional" notion (C++ [expr.type.conv]). Example: @c +/// x = int(0.5); +class CXXFunctionalCastExpr : public ExplicitCastExpr { SourceLocation TyBeginLoc; SourceLocation RParenLoc; public: - CXXFunctionalCastExpr(QualType ty, SourceLocation tyBeginLoc, Expr *castExpr, + CXXFunctionalCastExpr(QualType ty, QualType writtenTy, + SourceLocation tyBeginLoc, Expr *castExpr, SourceLocation rParenLoc) : - CastExpr(CXXFunctionalCastExprClass, ty, castExpr), + ExplicitCastExpr(CXXFunctionalCastExprClass, ty, castExpr, writtenTy), TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {} SourceLocation getTypeBeginLoc() const { return TyBeginLoc; } diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def index ed8861ba99..a79639eac0 100644 --- a/include/clang/AST/StmtNodes.def +++ b/include/clang/AST/StmtNodes.def @@ -77,42 +77,47 @@ STMT(47, CompoundAssignOperator, BinaryOperator) STMT(48, ConditionalOperator , Expr) STMT(49, ImplicitCastExpr , CastExpr) STMT(50, ExplicitCastExpr , CastExpr) -STMT(51, CompoundLiteralExpr , Expr) -STMT(52, ExtVectorElementExpr , Expr) -STMT(53, InitListExpr , Expr) -STMT(54, VAArgExpr , Expr) +STMT(51, ExplicitCCastExpr , ExplicitCastExpr) +STMT(52, CompoundLiteralExpr , Expr) +STMT(53, ExtVectorElementExpr , Expr) +STMT(54, InitListExpr , Expr) +STMT(55, VAArgExpr , Expr) // GNU Extensions. -STMT(55, AddrLabelExpr , Expr) -STMT(56, StmtExpr , Expr) -STMT(57, TypesCompatibleExpr , Expr) -STMT(58, ChooseExpr , Expr) +STMT(56, AddrLabelExpr , Expr) +STMT(57, StmtExpr , Expr) +STMT(58, TypesCompatibleExpr , Expr) +STMT(59, ChooseExpr , Expr) // C++ Expressions. -STMT(60, CXXCastExpr , Expr) -STMT(61, CXXBoolLiteralExpr , Expr) -STMT(62, CXXThrowExpr , Expr) -STMT(63, CXXDefaultArgExpr , Expr) -STMT(64, CXXFunctionalCastExpr, CastExpr) -STMT(65, CXXZeroInitValueExpr , Expr) -STMT(66, CXXConditionDeclExpr , DeclRefExpr) +STMT(60, CXXNamedCastExpr , ExplicitCastExpr) +STMT(61, CXXStaticCastExpr , CXXNamedCastExpr) +STMT(62, CXXDynamicCastExpr , CXXNamedCastExpr) +STMT(63, CXXReinterpretCastExpr , CXXNamedCastExpr) +STMT(64, CXXConstCastExpr , CXXNamedCastExpr) +STMT(65, CXXBoolLiteralExpr , Expr) +STMT(66, CXXThrowExpr , Expr) +STMT(67, CXXDefaultArgExpr , Expr) +STMT(68, CXXFunctionalCastExpr , Expr) +STMT(69, CXXZeroInitValueExpr , Expr) +STMT(70, CXXConditionDeclExpr , DeclRefExpr) // Obj-C Expressions. -STMT(70, ObjCStringLiteral , Expr) -STMT(71, ObjCEncodeExpr , Expr) -STMT(72, ObjCMessageExpr , Expr) -STMT(73, ObjCSelectorExpr , Expr) -STMT(74, ObjCProtocolExpr , Expr) -STMT(75, ObjCIvarRefExpr , Expr) -STMT(76, ObjCPropertyRefExpr , Expr) +STMT(80, ObjCStringLiteral , Expr) +STMT(81, ObjCEncodeExpr , Expr) +STMT(82, ObjCMessageExpr , Expr) +STMT(83, ObjCSelectorExpr , Expr) +STMT(84, ObjCProtocolExpr , Expr) +STMT(85, ObjCIvarRefExpr , Expr) +STMT(86, ObjCPropertyRefExpr , Expr) // Clang Extensions. -STMT(77, OverloadExpr , Expr) -STMT(78, ShuffleVectorExpr , Expr) -STMT(79, BlockExpr , Expr) -STMT(80, BlockDeclRefExpr , Expr) +STMT(90, OverloadExpr , Expr) +STMT(91, ShuffleVectorExpr , Expr) +STMT(92, BlockExpr , Expr) +STMT(93, BlockDeclRefExpr , Expr) -LAST_EXPR(80) +LAST_EXPR(93) #undef STMT #undef FIRST_STMT diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 63f5be704a..8c414e49ae 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -593,12 +593,12 @@ public: //===------------------------- C++ Expressions --------------------------===// - /// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's. - virtual ExprResult ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind, - SourceLocation LAngleBracketLoc, TypeTy *Ty, - SourceLocation RAngleBracketLoc, - SourceLocation LParenLoc, ExprTy *Op, - SourceLocation RParenLoc) { + /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's. + virtual ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, + SourceLocation LAngleBracketLoc, TypeTy *Ty, + SourceLocation RAngleBracketLoc, + SourceLocation LParenLoc, ExprTy *Op, + SourceLocation RParenLoc) { return 0; } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 61ea005793..1380264e0e 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -304,7 +304,7 @@ bool Expr::hasLocalSideEffect() const { return E->hasLocalSideEffect(); return false; } - case ExplicitCastExprClass: + case ExplicitCCastExprClass: case CXXFunctionalCastExprClass: // If this is a cast to void, check the operand. Otherwise, the result of // the cast is unused. @@ -628,7 +628,7 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { return true; } case ImplicitCastExprClass: - case ExplicitCastExprClass: + case ExplicitCCastExprClass: case CXXFunctionalCastExprClass: { const Expr *SubExpr = cast<CastExpr>(this)->getSubExpr(); SourceLocation CastLoc = getLocStart(); @@ -946,7 +946,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, break; } case ImplicitCastExprClass: - case ExplicitCastExprClass: + case ExplicitCCastExprClass: case CXXFunctionalCastExprClass: { const Expr *SubExpr = cast<CastExpr>(this)->getSubExpr(); SourceLocation CastLoc = getLocStart(); diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 0c374ff5cc..82626d864a 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -25,10 +25,6 @@ void CXXConditionDeclExpr::Destroy(ASTContext& C) { //===----------------------------------------------------------------------===// -// CXXCastExpr -Stmt::child_iterator CXXCastExpr::child_begin() { return &Op; } -Stmt::child_iterator CXXCastExpr::child_end() { return &Op+1; } - // CXXBoolLiteralExpr Stmt::child_iterator CXXBoolLiteralExpr::child_begin() { return child_iterator(); @@ -67,3 +63,20 @@ Stmt::child_iterator CXXConditionDeclExpr::child_begin() { Stmt::child_iterator CXXConditionDeclExpr::child_end() { return child_iterator(); } + +//===----------------------------------------------------------------------===// +// Named casts +//===----------------------------------------------------------------------===// + +/// getCastName - Get the name of the C++ cast being used, e.g., +/// "static_cast", "dynamic_cast", "reinterpret_cast", or +/// "const_cast". The returned pointer must not be freed. +const char *CXXNamedCastExpr::getCastName() const { + switch (getStmtClass()) { + case CXXStaticCastExprClass: return "static_cast"; + case CXXDynamicCastExprClass: return "dynamic_cast"; + case CXXReinterpretCastExprClass: return "reinterpret_cast"; + case CXXConstCastExprClass: return "const_cast"; + default: return "<invalid cast>"; + } +} diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp index 666cad6260..349b6fb6e3 100644 --- a/lib/AST/StmtDumper.cpp +++ b/lib/AST/StmtDumper.cpp @@ -128,8 +128,9 @@ namespace { void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node); // C++ - void VisitCXXCastExpr(CXXCastExpr *Node); + void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node); + void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node); // ObjC void VisitObjCEncodeExpr(ObjCEncodeExpr *Node); @@ -406,9 +407,10 @@ void StmtDumper::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) { // C++ Expressions //===----------------------------------------------------------------------===// -void StmtDumper::VisitCXXCastExpr(CXXCastExpr *Node) { +void StmtDumper::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { DumpExpr(Node); - fprintf(F, " %s", CXXCastExpr::getOpcodeStr(Node->getOpcode())); + fprintf(F, " %s<%s>", Node->getCastName(), + Node->getTypeAsWritten().getAsString().c_str()); } void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { @@ -416,6 +418,12 @@ void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { fprintf(F, " %s", Node->getValue() ? "true" : "false"); } +void StmtDumper::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { + DumpExpr(Node); + fprintf(F, " functional cast to %s", + Node->getTypeAsWritten().getAsString().c_str()); +} + //===----------------------------------------------------------------------===// // Obj-C Expressions //===----------------------------------------------------------------------===// diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index ba67a97deb..fb6fba399e 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -707,7 +707,10 @@ void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { void StmtPrinter::VisitCastExpr(CastExpr *) { assert(0 && "CastExpr is an abstract class"); } -void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *Node) { +void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) { + assert(0 && "ExplicitCastExpr is an abstract class"); +} +void StmtPrinter::VisitExplicitCCastExpr(ExplicitCCastExpr *Node) { OS << "(" << Node->getType().getAsString() << ")"; PrintExpr(Node->getSubExpr()); } @@ -809,13 +812,29 @@ void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { // C++ -void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) { - OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<'; - OS << Node->getDestType().getAsString() << ">("; +void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { + OS << Node->getCastName() << '<'; + OS << Node->getTypeAsWritten().getAsString() << ">("; PrintExpr(Node->getSubExpr()); OS << ")"; } +void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { + VisitCXXNamedCastExpr(Node); +} + +void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { + VisitCXXNamedCastExpr(Node); +} + +void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { + VisitCXXNamedCastExpr(Node); +} + +void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { + VisitCXXNamedCastExpr(Node); +} + void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { OS << (Node->getValue() ? "true" : "false"); } diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp index decd9a76c9..bf7cbc5e7b 100644 --- a/lib/AST/StmtSerialization.cpp +++ b/lib/AST/StmtSerialization.cpp @@ -106,8 +106,8 @@ Stmt* Stmt::Create(Deserializer& D, ASTContext& C) { case ImplicitCastExprClass: return ImplicitCastExpr::CreateImpl(D, C); - case ExplicitCastExprClass: - return ExplicitCastExpr::CreateImpl(D, C); + case ExplicitCCastExprClass: + return ExplicitCCastExpr::CreateImpl(D, C); case IndirectGotoStmtClass: return IndirectGotoStmt::CreateImpl(D, C); @@ -201,6 +201,18 @@ Stmt* Stmt::Create(Deserializer& D, ASTContext& C) { case CXXFunctionalCastExprClass: return CXXFunctionalCastExpr::CreateImpl(D, C); + case CXXStaticCastExprClass: + return CXXStaticCastExpr::CreateImpl(D, C, SC); + + case CXXDynamicCastExprClass: + return CXXDynamicCastExpr::CreateImpl(D, C, SC); + + case CXXReinterpretCastExprClass: + return CXXReinterpretCastExpr::CreateImpl(D, C, SC); + + case CXXConstCastExprClass: + return CXXConstCastExpr::CreateImpl(D, C, SC); + case CXXZeroInitValueExprClass: return CXXZeroInitValueExpr::CreateImpl(D, C); } @@ -364,19 +376,20 @@ CaseStmt* CaseStmt::CreateImpl(Deserializer& D, ASTContext& C) { return stmt; } -void ExplicitCastExpr::EmitImpl(Serializer& S) const { +void ExplicitCCastExpr::EmitImpl(Serializer& S) const { S.Emit(getType()); + S.Emit(getTypeAsWritten()); S.Emit(Loc); S.EmitOwnedPtr(getSubExpr()); } -ExplicitCastExpr* ExplicitCastExpr::CreateImpl(Deserializer& D, ASTContext& C) { +ExplicitCCastExpr* ExplicitCCastExpr::CreateImpl(Deserializer& D, ASTContext& C) { QualType t = QualType::ReadVal(D); + QualType writtenTy = QualType::ReadVal(D); SourceLocation Loc = SourceLocation::ReadVal(D); Expr* Op = D.ReadOwnedPtr<Expr>(C); - return new ExplicitCastExpr(t,Op,Loc); + return new ExplicitCCastExpr(t,Op,writtenTy,Loc); } - void CharacterLiteral::EmitImpl(Serializer& S) const { S.Emit(Value); @@ -1270,6 +1283,7 @@ CXXDefaultArgExpr *CXXDefaultArgExpr::CreateImpl(Deserializer& D, ASTContext& C) void CXXFunctionalCastExpr::EmitImpl(Serializer& S) const { S.Emit(getType()); + S.Emit(getTypeAsWritten()); S.Emit(TyBeginLoc); S.Emit(RParenLoc); S.EmitOwnedPtr(getSubExpr()); @@ -1278,10 +1292,39 @@ void CXXFunctionalCastExpr::EmitImpl(Serializer& S) const { CXXFunctionalCastExpr * CXXFunctionalCastExpr::CreateImpl(Deserializer& D, ASTContext& C) { QualType Ty = QualType::ReadVal(D); + QualType WrittenTy = QualType::ReadVal(D); SourceLocation TyBeginLoc = SourceLocation::ReadVal(D); SourceLocation RParenLoc = SourceLocation::ReadVal(D); Expr* SubExpr = D.ReadOwnedPtr<Expr>(C); - return new CXXFunctionalCastExpr(Ty, TyBeginLoc, SubExpr, RParenLoc); + return new CXXFunctionalCastExpr(Ty, WrittenTy, TyBeginLoc, SubExpr, RParenLoc); +} + +void CXXNamedCastExpr::EmitImpl(Serializer& S) const { + S.Emit(getType()); + S.Emit(getTypeAsWritten()); + S.Emit(Loc); + S.EmitOwnedPtr(getSubExpr()); +} + +CXXNamedCastExpr * +CXXNamedCastExpr::CreateImpl(Deserializer& D, ASTContext& C, StmtClass SC) { + QualType Ty = QualType::ReadVal(D); + QualType WrittenTy = QualType::ReadVal(D); + SourceLocation Loc = SourceLocation::ReadVal(D); + Expr* SubExpr = D.ReadOwnedPtr<Expr>(C); + switch (SC) { + case CXXStaticCastExprClass: + return new CXXStaticCastExpr(Ty, SubExpr, WrittenTy, Loc); + case CXXDynamicCastExprClass: + return new CXXDynamicCastExpr(Ty, SubExpr, WrittenTy, Loc); + case CXXReinterpretCastExprClass: + return new CXXReinterpretCastExpr(Ty, SubExpr, WrittenTy, Loc); + case CXXConstCastExprClass: + return new CXXConstCastExpr(Ty, SubExpr, WrittenTy, Loc); + default: + assert(false && "Unknown cast type!"); + return 0; + } } void CXXZeroInitValueExpr::EmitImpl(Serializer& S) const { diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp index f220ee7a12..a5f158c5d6 100644 --- a/lib/Analysis/Environment.cpp +++ b/lib/Analysis/Environment.cpp @@ -47,7 +47,7 @@ SVal Environment::GetSVal(Expr* E, BasicValueFactory& BasicVals) const { // subexpression that has a value. case Stmt::ImplicitCastExprClass: - case Stmt::ExplicitCastExprClass: { + case Stmt::ExplicitCCastExprClass: { CastExpr* C = cast<CastExpr>(E); QualType CT = C->getType(); QualType ST = C->getSubExpr()->getType(); diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 2a74311cd9..282a08c21a 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -345,7 +345,7 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) { break; case Stmt::ImplicitCastExprClass: - case Stmt::ExplicitCastExprClass: { + case Stmt::ExplicitCCastExprClass: { CastExpr* C = cast<CastExpr>(S); VisitCast(C, C->getSubExpr(), Pred, Dst); break; @@ -1445,6 +1445,9 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){ QualType T = CastE->getType(); QualType ExTy = Ex->getType(); + if (const ExplicitCastExpr *ExCast = dyn_cast_or_null<ExplicitCastExpr>(CastE)) + T = ExCast->getTypeAsWritten(); + if (ExTy->isArrayType() || ExTy->isFunctionType() || T->isReferenceType()) VisitLValue(Ex, Pred, S1); else diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 8b4db30950..2b9ab55032 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -61,9 +61,9 @@ Parser::ExprResult Parser::ParseCXXCasts() { ExprResult Result = ParseSimpleParenExpression(RParenLoc); if (!Result.isInvalid) - Result = Actions.ActOnCXXCasts(OpLoc, Kind, - LAngleBracketLoc, CastTy, RAngleBracketLoc, - LParenLoc, Result.Val, RParenLoc); + Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, + LAngleBracketLoc, CastTy, RAngleBracketLoc, + LParenLoc, Result.Val, RParenLoc); return Result; } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index a2872a2c1a..f84b5c5e71 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -695,12 +695,12 @@ public: SourceLocation *CommaLocs, SourceLocation RParenLoc); - /// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's. - virtual ExprResult ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind, - SourceLocation LAngleBracketLoc, TypeTy *Ty, - SourceLocation RAngleBracketLoc, - SourceLocation LParenLoc, ExprTy *E, - SourceLocation RParenLoc); + /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's. + virtual ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, + SourceLocation LAngleBracketLoc, TypeTy *Ty, + SourceLocation RAngleBracketLoc, + SourceLocation LParenLoc, ExprTy *E, + SourceLocation RParenLoc); // Helpers for ActOnCXXCasts bool CastsAwayConstness(QualType SrcType, QualType DestType); diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 27f3abe68a..3365992ff6 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -736,12 +736,11 @@ Sema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, } // Perform checking for stack values returned by reference. else if (lhsType->isReferenceType()) { - // Check for an implicit cast to a reference. - if (ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(RetValExp)) - if (DeclRefExpr *DR = EvalVal(I->getSubExpr())) - Diag(DR->getLocStart(), diag::warn_ret_stack_ref, - DR->getDecl()->getIdentifier()->getName(), - RetValExp->getSourceRange()); + // Check for a reference to the stack + if (DeclRefExpr *DR = EvalVal(RetValExp)) + Diag(DR->getLocStart(), diag::warn_ret_stack_ref, + DR->getDecl()->getIdentifier()->getName(), + RetValExp->getSourceRange()); } } @@ -826,9 +825,9 @@ static DeclRefExpr* EvalAddr(Expr *E) { // For casts, we need to handle conversions from arrays to // pointer values, and pointer-to-pointer conversions. - case Stmt::ExplicitCastExprClass: - case Stmt::ImplicitCastExprClass: { - + case Stmt::ImplicitCastExprClass: + case Stmt::ExplicitCCastExprClass: + case Stmt::CXXFunctionalCastExprClass: { Expr* SubExpr = cast<CastExpr>(E)->getSubExpr(); QualType T = SubExpr->getType(); @@ -844,21 +843,21 @@ static DeclRefExpr* EvalAddr(Expr *E) { // C++ casts. For dynamic casts, static casts, and const casts, we // are always converting from a pointer-to-pointer, so we just blow - // through the cast. In the case the dynamic cast doesn't fail - // (and return NULL), we take the conservative route and report cases + // through the cast. In the case the dynamic cast doesn't fail (and + // return NULL), we take the conservative route and report cases // where we return the address of a stack variable. For Reinterpre - case Stmt::CXXCastExprClass: { - CXXCastExpr *C = cast<CXXCastExpr>(E); - - if (C->getOpcode() == CXXCastExpr::ReinterpretCast) { - Expr *S = C->getSubExpr(); + // FIXME: The comment about is wrong; we're not always converting + // from pointer to pointer. I'm guessing that this code should also + // handle references to objects. + case Stmt::CXXStaticCastExprClass: + case Stmt::CXXDynamicCastExprClass: + case Stmt::CXXConstCastExprClass: + case Stmt::CXXReinterpretCastExprClass: { + Expr *S = cast<CXXNamedCastExpr>(E)->getSubExpr(); if (S->getType()->isPointerType() || S->getType()->isBlockPointerType()) return EvalAddr(S); else return NULL; - } - else - return EvalAddr(C->getSubExpr()); } // Everything else: we simply don't reason about them. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 624c576103..7b88ec2c16 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1060,7 +1060,7 @@ bool Sema::CheckAddressConstantExpression(const Expr* Init) { CheckArithmeticConstantExpression(IExp); } case Expr::ImplicitCastExprClass: - case Expr::ExplicitCastExprClass: { + case Expr::ExplicitCCastExprClass: { const Expr* SubExpr = cast<CastExpr>(Init)->getSubExpr(); if (Init->getStmtClass() == Expr::ImplicitCastExprClass) { // Check for implicit promotion @@ -1190,7 +1190,7 @@ static const Expr* FindExpressionBaseAddress(const Expr* E) { // if we don't, we'll figure it out later return 0; } - case Expr::ExplicitCastExprClass: { + case Expr::ExplicitCCastExprClass: { const Expr* SubExpr = cast<CastExpr>(E)->getSubExpr(); // Check for pointer->pointer cast @@ -1310,7 +1310,7 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) { return true; } case Expr::ImplicitCastExprClass: - case Expr::ExplicitCastExprClass: { + case Expr::ExplicitCCastExprClass: { const Expr *SubExpr = cast<CastExpr>(Init)->getSubExpr(); if (SubExpr->getType()->isArithmeticType()) return CheckArithmeticConstantExpression(SubExpr); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index d1be2a4a27..a73f0dde0a 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1333,7 +1333,7 @@ ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty, if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), castType, castExpr)) return true; - return new ExplicitCastExpr(castType, castExpr, LParenLoc); + return new ExplicitCCastExpr(castType, castExpr, castType, LParenLoc); } /// Note that lex is not null here, even if this is the gnu "x ?: y" extension. diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index fa81f118c7..34eff25b4c 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -21,36 +21,39 @@ #include "llvm/Support/Debug.h" using namespace clang; -/// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's. +/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's. Action::ExprResult -Sema::ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind, - SourceLocation LAngleBracketLoc, TypeTy *Ty, - SourceLocation RAngleBracketLoc, - SourceLocation LParenLoc, ExprTy *E, - SourceLocation RParenLoc) { - CXXCastExpr::Opcode Op; +Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, + SourceLocation LAngleBracketLoc, TypeTy *Ty, + SourceLocation RAngleBracketLoc, + SourceLocation LParenLoc, ExprTy *E, + SourceLocation RParenLoc) { Expr *Ex = (Expr*)E; QualType DestType = QualType::getFromOpaquePtr(Ty); switch (Kind) { default: assert(0 && "Unknown C++ cast!"); + case tok::kw_const_cast: - Op = CXXCastExpr::ConstCast; CheckConstCast(OpLoc, Ex, DestType); - break; + return new CXXConstCastExpr(DestType.getNonReferenceType(), Ex, + DestType, OpLoc); + case tok::kw_dynamic_cast: - Op = CXXCastExpr::DynamicCast; - break; + return new CXXDynamicCastExpr(DestType.getNonReferenceType(), Ex, + DestType, OpLoc); + case tok::kw_reinterpret_cast: - Op = CXXCastExpr::ReinterpretCast; CheckReinterpretCast(OpLoc, Ex, DestType); - break; + return new CXXReinterpretCastExpr(DestType.getNonReferenceType(), Ex, + DestType, OpLoc); + case tok::kw_static_cast: - Op = CXXCastExpr::StaticCast; - break; + return new CXXStaticCastExpr(DestType.getNonReferenceType(), Ex, + DestType, OpLoc); } - return new CXXCastExpr(Op, DestType, Ex, OpLoc); + return true; } /// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid. @@ -437,7 +440,8 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, if (NumExprs == 1) { if (CheckCastTypes(TypeRange, Ty, Exprs[0])) return true; - return new CXXFunctionalCastExpr(Ty, TyBeginLoc, Exprs[0], RParenLoc); + return new CXXFunctionalCastExpr(Ty.getNonReferenceType(), Ty, TyBeginLoc, + Exprs[0], RParenLoc); } // C++ 5.2.3p1: diff --git a/test/SemaCXX/return-stack-addr.cpp b/test/SemaCXX/return-stack-addr.cpp index da68c8d77a..9eadac7edd 100644 --- a/test/SemaCXX/return-stack-addr.cpp +++ b/test/SemaCXX/return-stack-addr.cpp @@ -1,6 +1,5 @@ // RUN: clang -fsyntax-only -verify %s - int* ret_local() { int x = 1; return &x; // expected-warning {{address of stack memory}} |