From: Douglas Gregor Date: Wed, 15 Apr 2009 22:40:36 +0000 (+0000) Subject: PCH support for CompoundAssignOperator and ConditionalOperator X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ad90e96fb7eed26d5217dd06ba50ecbbbebb59e6;p=clang PCH support for CompoundAssignOperator and ConditionalOperator git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69237 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 2311b9cb44..5634bf4d62 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1469,6 +1469,9 @@ protected: SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; } + + BinaryOperator(StmtClass SC, EmptyShell Empty) + : Expr(SC, Empty), Opc(MulAssign) { } }; /// CompoundAssignOperator - For compound assignments (e.g. +=), we keep @@ -1492,12 +1495,19 @@ public: "Only should be used for compound assignments"); } + /// \brief Build an empty compound assignment operator expression. + explicit CompoundAssignOperator(EmptyShell Empty) + : BinaryOperator(CompoundAssignOperatorClass, Empty) { } + // The two computation types are the type the LHS is converted // to for the computation and the type of the result; the two are // distinct in a few cases (specifically, int+=ptr and ptr-=ptr). QualType getComputationLHSType() const { return ComputationLHSType; } + void setComputationLHSType(QualType T) { ComputationLHSType = T; } + QualType getComputationResultType() const { return ComputationResultType; } - + void setComputationResultType(QualType T) { ComputationResultType = T; } + static bool classof(const CompoundAssignOperator *) { return true; } static bool classof(const Stmt *S) { return S->getStmtClass() == CompoundAssignOperatorClass; @@ -1529,9 +1539,14 @@ public: SubExprs[RHS] = rhs; } + /// \brief Build an empty conditional operator. + explicit ConditionalOperator(EmptyShell Empty) + : Expr(ConditionalOperatorClass, Empty) { } + // getCond - Return the expression representing the condition for // the ?: operator. Expr *getCond() const { return cast(SubExprs[COND]); } + void setCond(Expr *E) { SubExprs[COND] = E; } // getTrueExpr - Return the subexpression representing the value of the ?: // expression if the condition evaluates to true. In most cases this value @@ -1548,7 +1563,10 @@ public: Expr *getFalseExpr() const { return cast(SubExprs[RHS]); } Expr *getLHS() const { return cast_or_null(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(getCond()->getLocStart(), getRHS()->getLocEnd()); diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index b9ad1b5b89..a944f09bcb 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -411,6 +411,10 @@ namespace clang { EXPR_MEMBER, /// \brief A BinaryOperator record. EXPR_BINARY_OPERATOR, + /// \brief A CompoundAssignOperator record. + EXPR_COMPOUND_ASSIGN_OPERATOR, + /// \brief A ConditionOperator record. + EXPR_CONDITIONAL_OPERATOR, /// \brief An ImplicitCastExpr record. EXPR_IMPLICIT_CAST, /// \brief A CStyleCastExpr record. diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 042e56626e..f9290bac73 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -252,6 +252,8 @@ namespace { unsigned VisitMemberExpr(MemberExpr *E); unsigned VisitCastExpr(CastExpr *E); unsigned VisitBinaryOperator(BinaryOperator *E); + unsigned VisitCompoundAssignOperator(CompoundAssignOperator *E); + unsigned VisitConditionalOperator(ConditionalOperator *E); unsigned VisitImplicitCastExpr(ImplicitCastExpr *E); unsigned VisitExplicitCastExpr(ExplicitCastExpr *E); unsigned VisitCStyleCastExpr(CStyleCastExpr *E); @@ -401,6 +403,21 @@ unsigned PCHStmtReader::VisitBinaryOperator(BinaryOperator *E) { return 2; } +unsigned PCHStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) { + VisitBinaryOperator(E); + E->setComputationLHSType(Reader.GetType(Record[Idx++])); + E->setComputationResultType(Reader.GetType(Record[Idx++])); + return 2; +} + +unsigned PCHStmtReader::VisitConditionalOperator(ConditionalOperator *E) { + VisitExpr(E); + E->setCond(ExprStack[ExprStack.size() - 3]); + E->setLHS(ExprStack[ExprStack.size() - 2]); + E->setRHS(ExprStack[ExprStack.size() - 1]); + return 3; +} + unsigned PCHStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); E->setLvalueCast(Record[Idx++]); @@ -1917,6 +1934,14 @@ Expr *PCHReader::ReadExpr() { E = new (Context) BinaryOperator(Empty); break; + case pch::EXPR_COMPOUND_ASSIGN_OPERATOR: + E = new (Context) CompoundAssignOperator(Empty); + break; + + case pch::EXPR_CONDITIONAL_OPERATOR: + E = new (Context) ConditionalOperator(Empty); + break; + case pch::EXPR_IMPLICIT_CAST: E = new (Context) ImplicitCastExpr(Empty); break; diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index a5eba4e67c..0321e4c40b 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -459,6 +459,8 @@ namespace { void VisitMemberExpr(MemberExpr *E); void VisitCastExpr(CastExpr *E); void VisitBinaryOperator(BinaryOperator *E); + void VisitCompoundAssignOperator(CompoundAssignOperator *E); + void VisitConditionalOperator(ConditionalOperator *E); void VisitImplicitCastExpr(ImplicitCastExpr *E); void VisitExplicitCastExpr(ExplicitCastExpr *E); void VisitCStyleCastExpr(CStyleCastExpr *E); @@ -602,6 +604,21 @@ void PCHStmtWriter::VisitBinaryOperator(BinaryOperator *E) { Code = pch::EXPR_BINARY_OPERATOR; } +void PCHStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { + VisitBinaryOperator(E); + Writer.AddTypeRef(E->getComputationLHSType(), Record); + Writer.AddTypeRef(E->getComputationResultType(), Record); + Code = pch::EXPR_COMPOUND_ASSIGN_OPERATOR; +} + +void PCHStmtWriter::VisitConditionalOperator(ConditionalOperator *E) { + VisitExpr(E); + Writer.WriteSubExpr(E->getCond()); + Writer.WriteSubExpr(E->getLHS()); + Writer.WriteSubExpr(E->getRHS()); + Code = pch::EXPR_CONDITIONAL_OPERATOR; +} + void PCHStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); Record.push_back(E->isLvalueCast()); diff --git a/test/PCH/exprs.c b/test/PCH/exprs.c index dd4333c93d..49f74dd91a 100644 --- a/test/PCH/exprs.c +++ b/test/PCH/exprs.c @@ -52,5 +52,11 @@ member_ref_double *double_ptr3 = &floating; // BinaryOperator add_result *int_ptr5 = &integer; +// CompoundAssignOperator +addeq_result *int_ptr6 = &integer; + +// ConditionalOperator +conditional_operator *double_ptr4 = &floating; + // CStyleCastExpr void_ptr vp1 = &integer; diff --git a/test/PCH/exprs.h b/test/PCH/exprs.h index 0c09e8fcbb..016c4c6bee 100644 --- a/test/PCH/exprs.h +++ b/test/PCH/exprs.h @@ -47,6 +47,12 @@ typedef typeof(((struct S*)0)->x) member_ref_double; // BinaryOperator typedef typeof(i + Enumerator) add_result; +// CompoundAssignOperator +typedef typeof(i += Enumerator) addeq_result; + +// ConditionalOperator +typedef typeof(i? : d0) conditional_operator; + // CStyleCastExpr typedef typeof((void *)0) void_ptr;