diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index ba26ef3e9020..6cd377b9c589 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1228,10 +1228,15 @@ protected: ExplicitCastExpr(StmtClass SC, QualType exprTy, Expr *op, QualType writtenTy) : CastExpr(SC, exprTy, op), TypeAsWritten(writtenTy) {} + /// \brief Construct an empty explicit cast. + ExplicitCastExpr(StmtClass SC, EmptyShell Shell) + : CastExpr(SC, Shell) { } + public: /// getTypeAsWritten - Returns the type that this expression is /// casting to, as written in the source code. QualType getTypeAsWritten() const { return TypeAsWritten; } + void setTypeAsWritten(QualType T) { TypeAsWritten = T; } static bool classof(const Stmt *T) { StmtClass SC = T->getStmtClass(); @@ -1257,9 +1262,16 @@ public: ExplicitCastExpr(CStyleCastExprClass, exprTy, op, writtenTy), LPLoc(l), RPLoc(r) {} + /// \brief Construct an empty C-style explicit cast. + explicit CStyleCastExpr(EmptyShell Shell) + : ExplicitCastExpr(CStyleCastExprClass, Shell) { } + SourceLocation getLParenLoc() const { return LPLoc; } + void setLParenLoc(SourceLocation L) { LPLoc = L; } + SourceLocation getRParenLoc() const { return RPLoc; } - + void setRParenLoc(SourceLocation L) { RPLoc = L; } + virtual SourceRange getSourceRange() const { return SourceRange(LPLoc, getSubExpr()->getSourceRange().getEnd()); } @@ -1333,10 +1345,21 @@ public: "Use ArithAssignBinaryOperator for compound assignments"); } + /// \brief Construct an empty binary operator. + explicit BinaryOperator(EmptyShell Empty) + : Expr(BinaryOperatorClass, Empty), Opc(Comma) { } + SourceLocation getOperatorLoc() const { return OpLoc; } + void setOperatorLoc(SourceLocation L) { OpLoc = L; } + Opcode getOpcode() const { return Opc; } + void setOpcode(Opcode O) { Opc = O; } + Expr *getLHS() const { return cast(SubExprs[LHS]); } + void setLHS(Expr *E) { SubExprs[LHS] = E; } Expr *getRHS() const { return cast(SubExprs[RHS]); } + void setRHS(Expr *E) { SubExprs[RHS] = E; } + virtual SourceRange getSourceRange() const { return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd()); } diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index f8af0208b050..bac81ece23a1 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -385,8 +385,12 @@ namespace clang { EXPR_CHARACTER_LITERAL, /// \brief A ParenExpr record. EXPR_PAREN, + /// \brief A BinaryOperator record. + EXPR_BINARY_OPERATOR, /// \brief An ImplicitCastExpr record. - EXPR_IMPLICIT_CAST + EXPR_IMPLICIT_CAST, + /// \brief A CStyleCastExpr record. + EXPR_CSTYLE_CAST }; /// @} } diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 056c5d50d9bd..69745ce7a316 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -239,7 +239,10 @@ namespace { unsigned VisitCharacterLiteral(CharacterLiteral *E); unsigned VisitParenExpr(ParenExpr *E); unsigned VisitCastExpr(CastExpr *E); + unsigned VisitBinaryOperator(BinaryOperator *E); unsigned VisitImplicitCastExpr(ImplicitCastExpr *E); + unsigned VisitExplicitCastExpr(ExplicitCastExpr *E); + unsigned VisitCStyleCastExpr(CStyleCastExpr *E); }; } @@ -301,12 +304,34 @@ unsigned PCHStmtReader::VisitCastExpr(CastExpr *E) { return 1; } +unsigned PCHStmtReader::VisitBinaryOperator(BinaryOperator *E) { + VisitExpr(E); + E->setLHS(ExprStack.end()[-2]); + E->setRHS(ExprStack.end()[-1]); + E->setOpcode((BinaryOperator::Opcode)Record[Idx++]); + E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 2; +} + unsigned PCHStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); E->setLvalueCast(Record[Idx++]); return 1; } +unsigned PCHStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) { + VisitCastExpr(E); + E->setTypeAsWritten(Reader.GetType(Record[Idx++])); + return 1; +} + +unsigned PCHStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) { + VisitExplicitCastExpr(E); + E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 1; +} + // FIXME: use the diagnostics machinery static bool Error(const char *Str) { std::fprintf(stderr, "%s\n", Str); @@ -1618,9 +1643,17 @@ Expr *PCHReader::ReadExpr() { E = new (Context) ParenExpr(Empty); break; + case pch::EXPR_BINARY_OPERATOR: + E = new (Context) BinaryOperator(Empty); + break; + case pch::EXPR_IMPLICIT_CAST: E = new (Context) ImplicitCastExpr(Empty); break; + + case pch::EXPR_CSTYLE_CAST: + E = new (Context) CStyleCastExpr(Empty); + break; } // We hit an EXPR_STOP, so we're done with this expression. diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index ca76243977e5..1dcf9d651f6a 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -451,7 +451,10 @@ namespace { void VisitCharacterLiteral(CharacterLiteral *E); void VisitParenExpr(ParenExpr *E); void VisitCastExpr(CastExpr *E); + void VisitBinaryOperator(BinaryOperator *E); void VisitImplicitCastExpr(ImplicitCastExpr *E); + void VisitExplicitCastExpr(ExplicitCastExpr *E); + void VisitCStyleCastExpr(CStyleCastExpr *E); }; } @@ -511,12 +514,33 @@ void PCHStmtWriter::VisitCastExpr(CastExpr *E) { Writer.WriteSubExpr(E->getSubExpr()); } +void PCHStmtWriter::VisitBinaryOperator(BinaryOperator *E) { + VisitExpr(E); + Writer.WriteSubExpr(E->getLHS()); + Writer.WriteSubExpr(E->getRHS()); + Record.push_back(E->getOpcode()); // FIXME: stable encoding + Writer.AddSourceLocation(E->getOperatorLoc(), Record); + Code = pch::EXPR_BINARY_OPERATOR; +} + void PCHStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); Record.push_back(E->isLvalueCast()); Code = pch::EXPR_IMPLICIT_CAST; } +void PCHStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) { + VisitCastExpr(E); + Writer.AddTypeRef(E->getTypeAsWritten(), Record); +} + +void PCHStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) { + VisitExplicitCastExpr(E); + Writer.AddSourceLocation(E->getLParenLoc(), Record); + Writer.AddSourceLocation(E->getRParenLoc(), Record); + Code = pch::EXPR_CSTYLE_CAST; +} + //===----------------------------------------------------------------------===// // PCHWriter Implementation //===----------------------------------------------------------------------===// diff --git a/clang/test/PCH/exprs.c b/clang/test/PCH/exprs.c index faab79dfe3ff..b76a0e630082 100644 --- a/clang/test/PCH/exprs.c +++ b/clang/test/PCH/exprs.c @@ -17,8 +17,14 @@ enum_decl_ref *enum_ptr1 = &integer; integer_literal *int_ptr2 = &integer; long_literal *long_ptr1 = &long_integer; -// FloatingLiteral +// FloatingLiteral + ParenExpr floating_literal *double_ptr = &floating; // CharacterLiteral char_literal *int_ptr3 = &integer; + +// BinaryOperator +add_result *int_ptr4 = &integer; + +// CStyleCastExpr +void_ptr vp1 = &integer; diff --git a/clang/test/PCH/exprs.h b/clang/test/PCH/exprs.h index 5dcb26fbe3d7..60b1f2e3c7e9 100644 --- a/clang/test/PCH/exprs.h +++ b/clang/test/PCH/exprs.h @@ -10,9 +10,15 @@ typedef typeof(Enumerator) enum_decl_ref; typedef typeof(17) integer_literal; typedef typeof(17l) long_literal; -// FloatingLiteral +// FloatingLiteral and ParenExpr typedef typeof((42.5)) floating_literal; // CharacterLiteral typedef typeof('a') char_literal; +// BinaryOperator +typedef typeof(i + Enumerator) add_result; + +// CStyleCastExpr +typedef typeof((void *)0) void_ptr; +