diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 0e86a4c1424657c5bc32e5408c532e58033c345f..8e5117b63a2d10b1ac8105e7699828d89ed9acf5 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -704,12 +704,20 @@ public: input->isValueDependent()), Val(input), Opc(opc), Loc(l) {} + /// \brief Build an empty unary operator. + explicit UnaryOperator(EmptyShell Empty) + : Expr(UnaryOperatorClass, Empty), Opc(AddrOf) { } + Opcode getOpcode() const { return Opc; } + void setOpcode(Opcode O) { Opc = O; } + Expr *getSubExpr() const { return cast(Val); } - + void setSubExpr(Expr *E) { Val = E; } + /// getOperatorLoc - Return the location of the operator. SourceLocation getOperatorLoc() const { return Loc; } - + void setOperatorLoc(SourceLocation L) { Loc = L; } + /// isPostfix - Return true if this is a postfix operation, like x++. static bool isPostfix(Opcode Op) { return Op == PostInc || Op == PostDec; @@ -793,9 +801,15 @@ public: Argument.Ex = E; } + /// \brief Construct an empty sizeof/alignof expression. + explicit SizeOfAlignOfExpr(EmptyShell Empty) + : Expr(SizeOfAlignOfExprClass, Empty) { } + virtual void Destroy(ASTContext& C); bool isSizeOf() const { return isSizeof; } + void setSizeof(bool S) { isSizeof = S; } + bool isArgumentType() const { return isType; } QualType getArgumentType() const { assert(isArgumentType() && "calling getArgumentType() when arg is expr"); @@ -808,7 +822,13 @@ public: const Expr *getArgumentExpr() const { return const_cast(this)->getArgumentExpr(); } - + + void setArgument(Expr *E) { Argument.Ex = E; isType = false; } + void setArgument(QualType T) { + Argument.Ty = T.getAsOpaquePtr(); + isType = true; + } + /// Gets the argument type, or the type of the argument expression, whichever /// is appropriate. QualType getTypeOfArgument() const { @@ -816,6 +836,10 @@ public: } SourceLocation getOperatorLoc() const { return OpLoc; } + void setOperatorLoc(SourceLocation L) { OpLoc = L; } + + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(OpLoc, RParenLoc); diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index bac81ece23a197757d2dc487f668713ab4727dd0..faec40be2df154cc4a31f0a7d7168ef73f54d21c 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -385,6 +385,10 @@ namespace clang { EXPR_CHARACTER_LITERAL, /// \brief A ParenExpr record. EXPR_PAREN, + /// \brief A UnaryOperator record. + EXPR_UNARY_OPERATOR, + /// \brief A SizefAlignOfExpr record. + EXPR_SIZEOF_ALIGN_OF, /// \brief A BinaryOperator record. EXPR_BINARY_OPERATOR, /// \brief An ImplicitCastExpr record. diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index ad3c2e55a9906457cd19e3b5772eb7f1fd919339..96c383b49f31f88bb37ac94f6c45156225082ff7 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -238,6 +238,8 @@ namespace { unsigned VisitFloatingLiteral(FloatingLiteral *E); unsigned VisitCharacterLiteral(CharacterLiteral *E); unsigned VisitParenExpr(ParenExpr *E); + unsigned VisitUnaryOperator(UnaryOperator *E); + unsigned VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); unsigned VisitCastExpr(CastExpr *E); unsigned VisitBinaryOperator(BinaryOperator *E); unsigned VisitImplicitCastExpr(ImplicitCastExpr *E); @@ -298,6 +300,28 @@ unsigned PCHStmtReader::VisitParenExpr(ParenExpr *E) { return 1; } +unsigned PCHStmtReader::VisitUnaryOperator(UnaryOperator *E) { + VisitExpr(E); + E->setSubExpr(ExprStack.back()); + E->setOpcode((UnaryOperator::Opcode)Record[Idx++]); + E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 1; +} + +unsigned PCHStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { + VisitExpr(E); + E->setSizeof(Record[Idx++]); + if (Record[Idx] == 0) { + E->setArgument(ExprStack.back()); + ++Idx; + } else { + E->setArgument(Reader.GetType(Record[Idx++])); + } + E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return E->isArgumentType()? 0 : 1; +} + unsigned PCHStmtReader::VisitCastExpr(CastExpr *E) { VisitExpr(E); E->setSubExpr(ExprStack.back()); @@ -1640,6 +1664,14 @@ Expr *PCHReader::ReadExpr() { E = new (Context) ParenExpr(Empty); break; + case pch::EXPR_UNARY_OPERATOR: + E = new (Context) UnaryOperator(Empty); + break; + + case pch::EXPR_SIZEOF_ALIGN_OF: + E = new (Context) SizeOfAlignOfExpr(Empty); + break; + case pch::EXPR_BINARY_OPERATOR: E = new (Context) BinaryOperator(Empty); break; diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 1dcf9d651f6a87cece52fab36b3cc8fba9b79b0a..dc23fb9d81659f0941ba8ba8fae8b47f1b02a888 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -450,6 +450,8 @@ namespace { void VisitFloatingLiteral(FloatingLiteral *E); void VisitCharacterLiteral(CharacterLiteral *E); void VisitParenExpr(ParenExpr *E); + void VisitUnaryOperator(UnaryOperator *E); + void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); void VisitCastExpr(CastExpr *E); void VisitBinaryOperator(BinaryOperator *E); void VisitImplicitCastExpr(ImplicitCastExpr *E); @@ -509,6 +511,28 @@ void PCHStmtWriter::VisitParenExpr(ParenExpr *E) { Code = pch::EXPR_PAREN; } +void PCHStmtWriter::VisitUnaryOperator(UnaryOperator *E) { + VisitExpr(E); + Writer.WriteSubExpr(E->getSubExpr()); + Record.push_back(E->getOpcode()); // FIXME: stable encoding + Writer.AddSourceLocation(E->getOperatorLoc(), Record); + Code = pch::EXPR_UNARY_OPERATOR; +} + +void PCHStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { + VisitExpr(E); + Record.push_back(E->isSizeOf()); + if (E->isArgumentType()) + Writer.AddTypeRef(E->getArgumentType(), Record); + else { + Record.push_back(0); + Writer.WriteSubExpr(E->getArgumentExpr()); + } + Writer.AddSourceLocation(E->getOperatorLoc(), Record); + Writer.AddSourceLocation(E->getRParenLoc(), Record); + Code = pch::EXPR_SIZEOF_ALIGN_OF; +} + void PCHStmtWriter::VisitCastExpr(CastExpr *E) { VisitExpr(E); Writer.WriteSubExpr(E->getSubExpr()); diff --git a/clang/test/PCH/exprs.c b/clang/test/PCH/exprs.c index b76a0e6300823b8061b80dac862cea782f3bb1ff..94625deb4c657cc9453ffcd177e735b62722a1be 100644 --- a/clang/test/PCH/exprs.c +++ b/clang/test/PCH/exprs.c @@ -23,8 +23,16 @@ floating_literal *double_ptr = &floating; // CharacterLiteral char_literal *int_ptr3 = &integer; +// UnaryOperator +negate_enum *int_ptr4 = &integer; + +// SizeOfAlignOfExpr +typeof(sizeof(float)) size_t_value; +typeof_sizeof *size_t_ptr = &size_t_value; +typeof_sizeof2 *size_t_ptr2 = &size_t_value; + // BinaryOperator -add_result *int_ptr4 = &integer; +add_result *int_ptr5 = &integer; // CStyleCastExpr void_ptr vp1 = &integer; diff --git a/clang/test/PCH/exprs.h b/clang/test/PCH/exprs.h index 60b1f2e3c7e981fd6ae7a6db82a43f3086f31416..49966a3c46fe5ff2ffb27221deb2ba9db939777f 100644 --- a/clang/test/PCH/exprs.h +++ b/clang/test/PCH/exprs.h @@ -16,6 +16,13 @@ typedef typeof((42.5)) floating_literal; // CharacterLiteral typedef typeof('a') char_literal; +// UnaryOperator +typedef typeof(-Enumerator) negate_enum; + +// SizeOfAlignOfExpr +typedef typeof(sizeof(int)) typeof_sizeof; +typedef typeof(sizeof(Enumerator)) typeof_sizeof2; + // BinaryOperator typedef typeof(i + Enumerator) add_result;