From: Steve Naroff Date: Fri, 13 Jul 2007 16:58:59 +0000 (+0000) Subject: Add (explicit) AST support for implicit casts. This should simplify the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=49b4526992a8c8a6a290aa3efa9828154a24af8d;p=clang Add (explicit) AST support for implicit casts. This should simplify the code generator. Source translation tools can simply ignore this node. - Added a new Expr node, ImplicitCastExpr. - Changed UsualUnaryConversions/UsualArithmeticConversions to take references to Expr *'s. This will allow these routines to instantiate the new AST node and pass it back. - Changed all clients of UsualUnary/UsualArithmetic (lot's of diff's). - Changed some names in CheckConditionalOperands. Several variables where only distinguished by their case (e.g. Cond, cond). Yuck (what was I thinking). - Removed an old/crufty constructor in CastExpr (cleanup). This check-in does not actually create the new AST node. I wanted to separate the mechanical changes from the semantic changes. In addition, I need to coordinate with Chris, since the semantic change will break the code generator. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39814 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp index 948b20fd35..cf6aecd97f 100644 --- a/AST/StmtPrinter.cpp +++ b/AST/StmtPrinter.cpp @@ -386,6 +386,9 @@ void StmtPrinter::VisitCastExpr(CastExpr *Node) { OS << "(" << Node->getDestType().getAsString() << ")"; PrintExpr(Node->getSubExpr()); } +void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { + // No need to print anything. +} void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { PrintExpr(Node->getLHS()); OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; diff --git a/Sema/Sema.h b/Sema/Sema.h index ac85868b8e..7af13573ad 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -270,13 +270,13 @@ public: private: // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts // functions and arrays to their respective pointers (C99 6.3.2.1) - QualType UsualUnaryConversions(QualType t); + QualType UsualUnaryConversions(Expr *&expr); // UsualArithmeticConversions - performs the UsualUnaryConversions on it's // operands and then handles various conversions that are common to binary // operators (C99 6.3.1.8). If both operands aren't arithmetic, this // routine returns the first non-arithmetic type found. The client is // responsible for emitting appropriate error diagnostics. - QualType UsualArithmeticConversions(QualType &t1, QualType &t2); + QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr); // DefaultFunctionArrayConversion - converts functions and arrays // to their respective pointers (C99 6.3.2.1). If the type isn't a function // or array, this routine simply returns the input type (unmodified). @@ -302,35 +302,35 @@ private: /// or a null QualType (indicating an error diagnostic was issued). /// type checking binary operators (subroutines of ParseBinOp). - inline void InvalidOperands(SourceLocation l, Expr *lex, Expr *rex); - inline QualType CheckVectorOperands(SourceLocation l, Expr *lex, Expr *rex); + inline void InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex); + inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex); inline QualType CheckMultiplyDivideOperands( // C99 6.5.5 - Expr *lex, Expr *rex, SourceLocation OpLoc); + Expr *&lex, Expr *&rex, SourceLocation OpLoc); inline QualType CheckRemainderOperands( // C99 6.5.5 - Expr *lex, Expr *rex, SourceLocation OpLoc); + Expr *&lex, Expr *&rex, SourceLocation OpLoc); inline QualType CheckAdditionOperands( // C99 6.5.6 - Expr *lex, Expr *rex, SourceLocation OpLoc); + Expr *&lex, Expr *&rex, SourceLocation OpLoc); inline QualType CheckSubtractionOperands( // C99 6.5.6 - Expr *lex, Expr *rex, SourceLocation OpLoc); + Expr *&lex, Expr *&rex, SourceLocation OpLoc); inline QualType CheckShiftOperands( // C99 6.5.7 - Expr *lex, Expr *rex, SourceLocation OpLoc); + Expr *&lex, Expr *&rex, SourceLocation OpLoc); inline QualType CheckRelationalOperands( // C99 6.5.8 - Expr *lex, Expr *rex, SourceLocation OpLoc); + Expr *&lex, Expr *&rex, SourceLocation OpLoc); inline QualType CheckEqualityOperands( // C99 6.5.9 - Expr *lex, Expr *rex, SourceLocation OpLoc); + Expr *&lex, Expr *&rex, SourceLocation OpLoc); inline QualType CheckBitwiseOperands( // C99 6.5.[10...12] - Expr *lex, Expr *rex, SourceLocation OpLoc); + Expr *&lex, Expr *&rex, SourceLocation OpLoc); inline QualType CheckLogicalOperands( // C99 6.5.[13,14] - Expr *lex, Expr *rex, SourceLocation OpLoc); + Expr *&lex, Expr *&rex, SourceLocation OpLoc); // CheckAssignmentOperands is used for both simple and compound assignment. // For simple assignment, pass both expressions and a null converted type. // For compound assignment, pass both expressions and the converted type. inline QualType CheckAssignmentOperands( // C99 6.5.16.[1,2] Expr *lex, Expr *rex, SourceLocation OpLoc, QualType convertedType); inline QualType CheckCommaOperands( // C99 6.5.17 - Expr *lex, Expr *rex, SourceLocation OpLoc); + Expr *&lex, Expr *&rex, SourceLocation OpLoc); inline QualType CheckConditionalOperands( // C99 6.5.15 - Expr *cond, Expr *lhs, Expr *rhs, SourceLocation questionLoc); + Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc); /// type checking unary operators (subroutines of ParseUnaryOp). /// C99 6.5.3.1, 6.5.3.2, 6.5.3.4 diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 5913c6bed7..eab2bec37a 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -311,7 +311,7 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *init, assert(Init == 0 && "Can't have an initializer for a functiondecl!"); QualType R = GetTypeForDeclarator(D, S); if (R.isNull()) return 0; // FIXME: "auto func();" passes through... - + FunctionDecl::StorageClass SC; switch (D.getDeclSpec().getStorageClassSpec()) { default: assert(0 && "Unknown storage class!"); diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index c598e7cdb6..5b65f2a40c 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -375,7 +375,7 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc, Expr *funcExpr = (Expr *)Fn; assert(funcExpr && "no function call expression"); - QualType qType = UsualUnaryConversions(funcExpr->getType()); + QualType qType = UsualUnaryConversions(funcExpr); assert(!qType.isNull() && "no type for function call expression"); // C99 6.5.2.2p1 - "The expression that denotes the called function shall have @@ -482,62 +482,62 @@ ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty, } inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 - Expr *Cond, Expr *LHS, Expr *RHS, SourceLocation questionLoc) { - QualType cond = Cond->getType(); - QualType lhs = LHS->getType(); - QualType rhs = RHS->getType(); + Expr *&cond, Expr *&lex, Expr *&rex, SourceLocation questionLoc) { + QualType condT = cond->getType(); + QualType lexT = lex->getType(); + QualType rexT = rex->getType(); - assert(!cond.isNull() && "ParseConditionalOp(): no conditional type"); - assert(!lhs.isNull() && "ParseConditionalOp(): no lhs type"); - assert(!rhs.isNull() && "ParseConditionalOp(): no rhs type"); + assert(!condT.isNull() && "ParseConditionalOp(): no conditional type"); + assert(!lexT.isNull() && "ParseConditionalOp(): no lhs type"); + assert(!rexT.isNull() && "ParseConditionalOp(): no rhs type"); - cond = UsualUnaryConversions(cond); - lhs = UsualUnaryConversions(lhs); - rhs = UsualUnaryConversions(rhs); + condT = UsualUnaryConversions(cond); + lexT = UsualUnaryConversions(lex); + rexT = UsualUnaryConversions(rex); // first, check the condition. - if (!cond->isScalarType()) { // C99 6.5.15p2 - Diag(Cond->getLocStart(), diag::err_typecheck_cond_expect_scalar, - cond.getAsString()); + if (!condT->isScalarType()) { // C99 6.5.15p2 + Diag(cond->getLocStart(), diag::err_typecheck_cond_expect_scalar, + condT.getAsString()); return QualType(); } // now check the two expressions. - if (lhs->isArithmeticType() && rhs->isArithmeticType()) // C99 6.5.15p3,5 - return UsualArithmeticConversions(lhs, rhs); + if (lexT->isArithmeticType() && rexT->isArithmeticType()) // C99 6.5.15p3,5 + return UsualArithmeticConversions(lex, rex); - if ((lhs->isStructureType() && rhs->isStructureType()) || // C99 6.5.15p3 - (lhs->isUnionType() && rhs->isUnionType())) { - TagType *lTag = cast(lhs.getCanonicalType()); - TagType *rTag = cast(rhs.getCanonicalType()); + if ((lexT->isStructureType() && rexT->isStructureType()) || // C99 6.5.15p3 + (lexT->isUnionType() && rexT->isUnionType())) { + TagType *lTag = cast(lexT.getCanonicalType()); + TagType *rTag = cast(rexT.getCanonicalType()); if (lTag->getDecl()->getIdentifier() == rTag->getDecl()->getIdentifier()) - return lhs; + return lexT; else { Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands, - lhs.getAsString(), rhs.getAsString(), - LHS->getSourceRange(), RHS->getSourceRange()); + lexT.getAsString(), rexT.getAsString(), + lex->getSourceRange(), rex->getSourceRange()); return QualType(); } } - if (lhs->isPointerType() && RHS->isNullPointerConstant()) // C99 6.5.15p3 - return lhs; - if (rhs->isPointerType() && LHS->isNullPointerConstant()) - return rhs; + if (lexT->isPointerType() && rex->isNullPointerConstant()) // C99 6.5.15p3 + return lexT; + if (rexT->isPointerType() && lex->isNullPointerConstant()) + return rexT; - if (lhs->isPointerType() && rhs->isPointerType()) { // C99 6.5.15p3,6 + if (lexT->isPointerType() && rexT->isPointerType()) { // C99 6.5.15p3,6 QualType lhptee, rhptee; // get the "pointed to" type - lhptee = cast(lhs.getCanonicalType())->getPointeeType(); - rhptee = cast(rhs.getCanonicalType())->getPointeeType(); + lhptee = cast(lexT.getCanonicalType())->getPointeeType(); + rhptee = cast(rexT.getCanonicalType())->getPointeeType(); // ignore qualifiers on void (C99 6.5.15p3, clause 6) if (lhptee.getUnqualifiedType()->isVoidType() && (rhptee->isObjectType() || rhptee->isIncompleteType())) - return lhs; + return lexT; if (rhptee.getUnqualifiedType()->isVoidType() && (lhptee->isObjectType() || lhptee->isIncompleteType())) - return rhs; + return rexT; // FIXME: C99 6.5.15p6: If both operands are pointers to compatible types // *or* to differently qualified versions of compatible types, the result @@ -546,17 +546,17 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 if (!Type::typesAreCompatible(lhptee.getUnqualifiedType(), rhptee.getUnqualifiedType())) { Diag(questionLoc, diag::ext_typecheck_cond_incompatible_pointers, - lhs.getAsString(), rhs.getAsString(), - LHS->getSourceRange(), RHS->getSourceRange()); - return lhs; // FIXME: this is an _ext - is this return o.k? + lexT.getAsString(), rexT.getAsString(), + lex->getSourceRange(), rex->getSourceRange()); + return lexT; // FIXME: this is an _ext - is this return o.k? } } - if (lhs->isVoidType() && rhs->isVoidType()) // C99 6.5.15p3 - return lhs; + if (lexT->isVoidType() && rexT->isVoidType()) // C99 6.5.15p3 + return lexT; Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands, - lhs.getAsString(), rhs.getAsString(), - LHS->getSourceRange(), RHS->getSourceRange()); + lexT.getAsString(), rexT.getAsString(), + lex->getSourceRange(), rex->getSourceRange()); return QualType(); } @@ -566,8 +566,8 @@ Action::ExprResult Sema::ParseConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, ExprTy *Cond, ExprTy *LHS, ExprTy *RHS) { - QualType result = CheckConditionalOperands((Expr *)Cond, (Expr *)LHS, - (Expr *)RHS, QuestionLoc); + QualType result = CheckConditionalOperands((Expr *&)Cond, (Expr *&)LHS, + (Expr *&)RHS, QuestionLoc); if (result.isNull()) return true; return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS, result); @@ -586,7 +586,8 @@ QualType Sema::DefaultFunctionArrayConversion(QualType t) { /// sometimes surpressed. For example, the array->pointer conversion doesn't /// apply if the array is an argument to the sizeof or address (&) operators. /// In these instances, this routine should *not* be called. -QualType Sema::UsualUnaryConversions(QualType t) { +QualType Sema::UsualUnaryConversions(Expr *&expr) { + QualType t = expr->getType(); assert(!t.isNull() && "UsualUnaryConversions - missing type"); if (t->isPromotableIntegerType()) // C99 6.3.1.1p2 @@ -598,9 +599,9 @@ QualType Sema::UsualUnaryConversions(QualType t) { /// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this /// routine returns the first non-arithmetic type found. The client is /// responsible for emitting appropriate error diagnostics. -QualType Sema::UsualArithmeticConversions(QualType &lhs, QualType &rhs) { - lhs = UsualUnaryConversions(lhs); - rhs = UsualUnaryConversions(rhs); +QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr) { + QualType lhs = UsualUnaryConversions(lhsExpr); + QualType rhs = UsualUnaryConversions(rhsExpr); // If both types are identical, no conversion is needed. if (lhs == rhs) @@ -737,14 +738,14 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { return Incompatible; } -inline void Sema::InvalidOperands(SourceLocation loc, Expr *lex, Expr *rex) { +inline void Sema::InvalidOperands(SourceLocation loc, Expr *&lex, Expr *&rex) { Diag(loc, diag::err_typecheck_invalid_operands, lex->getType().getAsString(), rex->getType().getAsString(), lex->getSourceRange(), rex->getSourceRange()); } -inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *lex, - Expr *rex) { +inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *&lex, + Expr *&rex) { QualType lhsType = lex->getType(), rhsType = rex->getType(); // make sure the vector types are identical. @@ -758,13 +759,12 @@ inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *lex, } inline QualType Sema::CheckMultiplyDivideOperands( - Expr *lex, Expr *rex, SourceLocation loc) + Expr *&lex, Expr *&rex, SourceLocation loc) { - QualType lhsType = lex->getType(), rhsType = rex->getType(); - - if (lhsType->isVectorType() || rhsType->isVectorType()) + if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) return CheckVectorOperands(loc, lex, rex); - QualType resType = UsualArithmeticConversions(lhsType, rhsType); + + QualType resType = UsualArithmeticConversions(lex, rex); if (resType->isArithmeticType()) return resType; @@ -773,10 +773,9 @@ inline QualType Sema::CheckMultiplyDivideOperands( } inline QualType Sema::CheckRemainderOperands( - Expr *lex, Expr *rex, SourceLocation loc) + Expr *&lex, Expr *&rex, SourceLocation loc) { - QualType lhsType = lex->getType(), rhsType = rex->getType(); - QualType resType = UsualArithmeticConversions(lhsType, rhsType); + QualType resType = UsualArithmeticConversions(lex, rex); if (resType->isIntegerType()) return resType; @@ -785,13 +784,14 @@ inline QualType Sema::CheckRemainderOperands( } inline QualType Sema::CheckAdditionOperands( // C99 6.5.6 - Expr *lex, Expr *rex, SourceLocation loc) + Expr *&lex, Expr *&rex, SourceLocation loc) { QualType lhsType = lex->getType(), rhsType = rex->getType(); if (lhsType->isVectorType() || rhsType->isVectorType()) - return CheckVectorOperands(loc, lex, rex); - QualType resType = UsualArithmeticConversions(lhsType, rhsType); + return CheckVectorOperands(loc, lex, rex); + + QualType resType = UsualArithmeticConversions(lex, rex); // handle the common case first (both operands are arithmetic). if (resType->isArithmeticType()) @@ -805,13 +805,13 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6 } inline QualType Sema::CheckSubtractionOperands( // C99 6.5.6 - Expr *lex, Expr *rex, SourceLocation loc) + Expr *&lex, Expr *&rex, SourceLocation loc) { QualType lhsType = lex->getType(), rhsType = rex->getType(); if (lhsType->isVectorType() || rhsType->isVectorType()) return CheckVectorOperands(loc, lex, rex); - QualType resType = UsualArithmeticConversions(lhsType, rhsType); + QualType resType = UsualArithmeticConversions(lex, rex); // handle the common case first (both operands are arithmetic). if (resType->isArithmeticType()) @@ -825,12 +825,12 @@ inline QualType Sema::CheckSubtractionOperands( // C99 6.5.6 } inline QualType Sema::CheckShiftOperands( // C99 6.5.7 - Expr *lex, Expr *rex, SourceLocation loc) + Expr *&lex, Expr *&rex, SourceLocation loc) { // FIXME: Shifts don't perform usual arithmetic conversions. This is wrong // for int << longlong -> the result type should be int, not long long. QualType lhsType = lex->getType(), rhsType = rex->getType(); - QualType resType = UsualArithmeticConversions(lhsType, rhsType); + QualType resType = UsualArithmeticConversions(lex, rex); if (resType->isIntegerType()) return resType; @@ -839,10 +839,10 @@ inline QualType Sema::CheckShiftOperands( // C99 6.5.7 } inline QualType Sema::CheckRelationalOperands( // C99 6.5.8 - Expr *lex, Expr *rex, SourceLocation loc) + Expr *&lex, Expr *&rex, SourceLocation loc) { - QualType lType = UsualUnaryConversions(lex->getType()); - QualType rType = UsualUnaryConversions(rex->getType()); + QualType lType = UsualUnaryConversions(lex); + QualType rType = UsualUnaryConversions(rex); if (lType->isRealType() && rType->isRealType()) return Context.IntTy; @@ -869,10 +869,10 @@ inline QualType Sema::CheckRelationalOperands( // C99 6.5.8 } inline QualType Sema::CheckEqualityOperands( // C99 6.5.9 - Expr *lex, Expr *rex, SourceLocation loc) + Expr *&lex, Expr *&rex, SourceLocation loc) { - QualType lType = UsualUnaryConversions(lex->getType()); - QualType rType = UsualUnaryConversions(rex->getType()); + QualType lType = UsualUnaryConversions(lex); + QualType rType = UsualUnaryConversions(rex); if (lType->isArithmeticType() && rType->isArithmeticType()) return Context.IntTy; @@ -899,13 +899,13 @@ inline QualType Sema::CheckEqualityOperands( // C99 6.5.9 } inline QualType Sema::CheckBitwiseOperands( - Expr *lex, Expr *rex, SourceLocation loc) + Expr *&lex, Expr *&rex, SourceLocation loc) { QualType lhsType = lex->getType(), rhsType = rex->getType(); if (lhsType->isVectorType() || rhsType->isVectorType()) return CheckVectorOperands(loc, lex, rex); - QualType resType = UsualArithmeticConversions(lhsType, rhsType); + QualType resType = UsualArithmeticConversions(lex, rex); if (resType->isIntegerType()) return resType; @@ -914,10 +914,10 @@ inline QualType Sema::CheckBitwiseOperands( } inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] - Expr *lex, Expr *rex, SourceLocation loc) + Expr *&lex, Expr *&rex, SourceLocation loc) { - QualType lhsType = UsualUnaryConversions(lex->getType()); - QualType rhsType = UsualUnaryConversions(rex->getType()); + QualType lhsType = UsualUnaryConversions(lex); + QualType rhsType = UsualUnaryConversions(rex); if (lhsType->isScalarType() || rhsType->isScalarType()) return Context.IntTy; @@ -1007,13 +1007,14 @@ inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1 } inline QualType Sema::CheckCommaOperands( // C99 6.5.17 - Expr *lex, Expr *rex, SourceLocation loc) { - return UsualUnaryConversions(rex->getType()); + Expr *&lex, Expr *&rex, SourceLocation loc) { + return UsualUnaryConversions(rex); } +/// CheckIncrementDecrementOperand - unlike most "Check" methods, this routine +/// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions. QualType Sema::CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc) { - QualType lhsType = op->getType(), rhsType = Context.IntTy; - QualType resType = UsualArithmeticConversions(lhsType, rhsType); + QualType resType = op->getType(); assert(!resType.isNull() && "no type for increment/decrement expression"); // C99 6.5.2.4p1 @@ -1100,7 +1101,7 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { } QualType Sema::CheckIndirectionOperand(Expr *op, SourceLocation OpLoc) { - QualType qType = UsualUnaryConversions(op->getType()); + QualType qType = UsualUnaryConversions(op); assert(!qType.isNull() && "no type for * expression"); @@ -1307,13 +1308,13 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op, break; case UnaryOperator::Plus: case UnaryOperator::Minus: - resultType = UsualUnaryConversions(Input->getType()); + resultType = UsualUnaryConversions(Input); if (!resultType->isArithmeticType()) // C99 6.5.3.3p1 return Diag(OpLoc, diag::err_typecheck_unary_expr, resultType.getAsString()); break; case UnaryOperator::Not: // bitwise complement - resultType = UsualUnaryConversions(Input->getType()); + resultType = UsualUnaryConversions(Input); if (!resultType->isIntegerType()) // C99 6.5.3.3p1 return Diag(OpLoc, diag::err_typecheck_unary_expr, resultType.getAsString()); diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index fcf179e565..d5e3407f2f 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -426,6 +426,24 @@ public: static bool classof(const MemberExpr *) { return true; } }; +/// ImplicitCastExpr - Allows us to explicitly represent implicit type +/// conversions. For example: converting T[]->T*, void f()->void (*f)(), +/// float->double, short->int, etc. +/// +class ImplicitCastExpr : public Expr { + QualType Ty; + Expr *Op; +public: + ImplicitCastExpr(QualType ty, Expr *op) : + Expr(ImplicitCastExprClass, ty), Ty(ty), Op(op) {} + + virtual void visit(StmtVisitor &Visitor); + static bool classof(const Stmt *T) { + return T->getStmtClass() == ImplicitCastExprClass; + } + static bool classof(const ImplicitCastExpr *) { return true; } +}; + /// CastExpr - [C99 6.5.4] Cast Operators. /// class CastExpr : public Expr { @@ -435,9 +453,7 @@ class CastExpr : public Expr { public: CastExpr(QualType ty, Expr *op, SourceLocation l) : Expr(CastExprClass, ty), Ty(ty), Op(op), Loc(l) {} - CastExpr(StmtClass SC, QualType ty, Expr *op) : - Expr(SC, QualType()), Ty(ty), Op(op), Loc(SourceLocation()) {} - + SourceLocation getLParenLoc() const { return Loc; } QualType getDestType() const { return Ty; } diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def index 6595223a0c..221de3eb52 100644 --- a/include/clang/AST/StmtNodes.def +++ b/include/clang/AST/StmtNodes.def @@ -58,14 +58,15 @@ STMT(43, MemberExpr , Expr) STMT(44, CastExpr , Expr) STMT(45, BinaryOperator , Expr) STMT(46, ConditionalOperator , Expr) +STMT(47, ImplicitCastExpr , Expr) // GNU Extensions. -STMT(47, AddrLabel , Expr) +STMT(48, AddrLabel , Expr) // C++ Expressions. -STMT(48, CXXCastExpr , Expr) -STMT(49, CXXBoolLiteralExpr , Expr) -LAST_EXPR(49) +STMT(49, CXXCastExpr , Expr) +STMT(50, CXXBoolLiteralExpr , Expr) +LAST_EXPR(50) #undef STMT #undef FIRST_STMT