diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/Expr.h | 18 | ||||
-rw-r--r-- | clang/include/clang/Frontend/PCHBitCodes.h | 4 | ||||
-rw-r--r-- | clang/lib/AST/Expr.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHReader.cpp | 29 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHWriter.cpp | 22 | ||||
-rw-r--r-- | clang/test/PCH/exprs.c | 6 | ||||
-rw-r--r-- | clang/test/PCH/exprs.h | 11 |
7 files changed, 88 insertions, 7 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 7dd78342067..41776be8132 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -970,6 +970,9 @@ public: CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t, SourceLocation rparenloc); + /// \brief Build an empty call expression. + CallExpr(ASTContext &C, EmptyShell Empty); + ~CallExpr() {} void Destroy(ASTContext& C); @@ -992,18 +995,12 @@ public: return cast<Expr>(SubExprs[Arg+ARGS_START]); } - // FIXME: Why is this needed? Why not just create the CallExpr with the - // corect number of arguments? It makes the ASTs less brittle. /// setArg - Set the specified argument. void setArg(unsigned Arg, Expr *ArgExpr) { assert(Arg < NumArgs && "Arg access out of range!"); SubExprs[Arg+ARGS_START] = ArgExpr; } - // FIXME: It would be great to just get rid of this. There is only one - // callee of this method, and it probably could be refactored to not use - // this method and instead just create a CallExpr with the right number of - // arguments. /// setNumArgs - This changes the number of arguments present in this call. /// Any orphaned expressions are deleted by this, and any new operands are set /// to null. @@ -1026,6 +1023,7 @@ public: unsigned isBuiltinCall(ASTContext &Context) const; SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(getCallee()->getLocStart(), RParenLoc); @@ -1071,6 +1069,9 @@ public: : Expr(MemberExprClass, ty), Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow) {} + /// \brief Build an empty member reference expression. + explicit MemberExpr(EmptyShell Empty) : Expr(MemberExprClass, Empty) { } + void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast<Expr>(Base); } @@ -1080,11 +1081,14 @@ public: /// a CXXMethodDecl. NamedDecl *getMemberDecl() const { return MemberDecl; } void setMemberDecl(NamedDecl *D) { MemberDecl = D; } + bool isArrow() const { return IsArrow; } - + void setArrow(bool A) { IsArrow = A; } + /// getMemberLoc - Return the location of the "member", in X->F, it is the /// location of 'F'. SourceLocation getMemberLoc() const { return MemberLoc; } + void setMemberLoc(SourceLocation L) { MemberLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(getBase()->getLocStart(), MemberLoc); diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index 279e4fc2dfa..252811bd59f 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -391,6 +391,10 @@ namespace clang { EXPR_UNARY_OPERATOR, /// \brief A SizefAlignOfExpr record. EXPR_SIZEOF_ALIGN_OF, + /// \brief A CallExpr record. + EXPR_CALL, + /// \brief A MemberExpr record. + EXPR_MEMBER, /// \brief A BinaryOperator record. EXPR_BINARY_OPERATOR, /// \brief An ImplicitCastExpr record. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 53633977e98..99e07c4b8ab 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -186,6 +186,11 @@ CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, RParenLoc = rparenloc; } +CallExpr::CallExpr(ASTContext &C, EmptyShell Empty) + : Expr(CallExprClass, Empty), SubExprs(0), NumArgs(0) { + SubExprs = new (C) Stmt*[1]; +} + void CallExpr::Destroy(ASTContext& C) { DestroyChildren(C); if (SubExprs) C.Deallocate(SubExprs); diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 2da21023c77..083d0d6082d 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -245,6 +245,8 @@ namespace { unsigned VisitParenExpr(ParenExpr *E); unsigned VisitUnaryOperator(UnaryOperator *E); unsigned VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); + unsigned VisitCallExpr(CallExpr *E); + unsigned VisitMemberExpr(MemberExpr *E); unsigned VisitCastExpr(CastExpr *E); unsigned VisitBinaryOperator(BinaryOperator *E); unsigned VisitImplicitCastExpr(ImplicitCastExpr *E); @@ -348,6 +350,25 @@ unsigned PCHStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { return E->isArgumentType()? 0 : 1; } +unsigned PCHStmtReader::VisitCallExpr(CallExpr *E) { + VisitExpr(E); + E->setNumArgs(Reader.getContext(), Record[Idx++]); + E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setCallee(ExprStack[ExprStack.size() - E->getNumArgs() - 1]); + for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) + E->setArg(I, ExprStack[ExprStack.size() - N + I]); + return E->getNumArgs() + 1; +} + +unsigned PCHStmtReader::VisitMemberExpr(MemberExpr *E) { + VisitExpr(E); + E->setBase(ExprStack.back()); + E->setMemberDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++]))); + E->setMemberLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setArrow(Record[Idx++]); + return 1; +} + unsigned PCHStmtReader::VisitCastExpr(CastExpr *E) { VisitExpr(E); E->setSubExpr(ExprStack.back()); @@ -1703,6 +1724,14 @@ Expr *PCHReader::ReadExpr() { E = new (Context) SizeOfAlignOfExpr(Empty); break; + case pch::EXPR_CALL: + E = new (Context) CallExpr(Context, Empty); + break; + + case pch::EXPR_MEMBER: + E = new (Context) MemberExpr(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 69b070f79c0..6c3056a1bb7 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -453,6 +453,8 @@ namespace { void VisitParenExpr(ParenExpr *E); void VisitUnaryOperator(UnaryOperator *E); void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); + void VisitCallExpr(CallExpr *E); + void VisitMemberExpr(MemberExpr *E); void VisitCastExpr(CastExpr *E); void VisitBinaryOperator(BinaryOperator *E); void VisitImplicitCastExpr(ImplicitCastExpr *E); @@ -550,6 +552,26 @@ void PCHStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { Code = pch::EXPR_SIZEOF_ALIGN_OF; } +void PCHStmtWriter::VisitCallExpr(CallExpr *E) { + VisitExpr(E); + Record.push_back(E->getNumArgs()); + Writer.AddSourceLocation(E->getRParenLoc(), Record); + Writer.WriteSubExpr(E->getCallee()); + for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end(); + Arg != ArgEnd; ++Arg) + Writer.WriteSubExpr(*Arg); + Code = pch::EXPR_CALL; +} + +void PCHStmtWriter::VisitMemberExpr(MemberExpr *E) { + VisitExpr(E); + Writer.WriteSubExpr(E->getBase()); + Writer.AddDeclRef(E->getMemberDecl(), Record); + Writer.AddSourceLocation(E->getMemberLoc(), Record); + Record.push_back(E->isArrow()); + Code = pch::EXPR_MEMBER; +} + 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 e41c93f21da..7337c4c41f1 100644 --- a/clang/test/PCH/exprs.c +++ b/clang/test/PCH/exprs.c @@ -36,6 +36,12 @@ typeof(sizeof(float)) size_t_value; typeof_sizeof *size_t_ptr = &size_t_value; typeof_sizeof2 *size_t_ptr2 = &size_t_value; +// CallExpr +call_returning_double *double_ptr2 = &floating; + +// MemberExpr +member_ref_double *double_ptr3 = &floating; + // BinaryOperator add_result *int_ptr5 = &integer; diff --git a/clang/test/PCH/exprs.h b/clang/test/PCH/exprs.h index 73e15fb5a9f..918ca817bb0 100644 --- a/clang/test/PCH/exprs.h +++ b/clang/test/PCH/exprs.h @@ -26,6 +26,17 @@ typedef typeof(-Enumerator) negate_enum; typedef typeof(sizeof(int)) typeof_sizeof; typedef typeof(sizeof(Enumerator)) typeof_sizeof2; +// CallExpr +double dplus(double x, double y); +double d0, d1; +typedef typeof((&dplus)(d0, d1)) call_returning_double; + +// MemberExpr +struct S { + double x; +}; +typedef typeof(((struct S*)0)->x) member_ref_double; + // BinaryOperator typedef typeof(i + Enumerator) add_result; |