]> granicus.if.org Git - clang/commitdiff
Store the source range of a CXXOperatorCallExpr in the Expr object instead of
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 30 Apr 2012 22:12:22 +0000 (22:12 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 30 Apr 2012 22:12:22 +0000 (22:12 +0000)
calculating it recursively.

boost::assign::tuple_list_of uses the trick of chaining call operator expressions in order to declare a "list of tuples", e.g:
    std::vector<tuple> v = boost::assign::tuple_list_of(1, "foo")(2, "bar")(3, "qqq");

Due to CXXOperatorCallExpr calculating its source range recursively we would get
significant slowdowns with a large number of chained call operator expressions and the
potential for stack overflow.

rdar://11350116

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155848 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprCXX.h
lib/AST/ExprCXX.cpp
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterStmt.cpp

index b69693d7c6a3bf0cfbb084ca0d01ab144612b264..8d7b8c6791b0365768517dca9ca1f2a1316abd41 100644 (file)
@@ -50,14 +50,18 @@ class TemplateArgumentListInfo;
 class CXXOperatorCallExpr : public CallExpr {
   /// \brief The overloaded operator.
   OverloadedOperatorKind Operator;
+  SourceRange Range;
 
+  SourceRange getSourceRangeImpl() const LLVM_READONLY;
 public:
   CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
                       Expr **args, unsigned numargs, QualType t,
                       ExprValueKind VK, SourceLocation operatorloc)
     : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, numargs, t, VK,
                operatorloc),
-      Operator(Op) {}
+      Operator(Op) {
+    Range = getSourceRangeImpl();
+  }
   explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
     CallExpr(C, CXXOperatorCallExprClass, Empty) { }
 
@@ -65,7 +69,6 @@ public:
   /// getOperator - Returns the kind of overloaded operator that this
   /// expression refers to.
   OverloadedOperatorKind getOperator() const { return Operator; }
-  void setOperator(OverloadedOperatorKind Kind) { Operator = Kind; }
 
   /// getOperatorLoc - Returns the location of the operator symbol in
   /// the expression. When @c getOperator()==OO_Call, this is the
@@ -74,12 +77,15 @@ public:
   /// bracket.
   SourceLocation getOperatorLoc() const { return getRParenLoc(); }
 
-  SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const { return Range; }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXOperatorCallExprClass;
   }
   static bool classof(const CXXOperatorCallExpr *) { return true; }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
 };
 
 /// CXXMemberCallExpr - Represents a call to a member function that
index 8cf519c93dc2b9c4340b03bcb76775c695504666..8fbe72108b95c832f3b3d6f98432a2bac3f07090 100644 (file)
@@ -415,7 +415,7 @@ SourceRange CXXConstructExpr::getSourceRange() const {
   return SourceRange(Loc, End);
 }
 
-SourceRange CXXOperatorCallExpr::getSourceRange() const {
+SourceRange CXXOperatorCallExpr::getSourceRangeImpl() const {
   OverloadedOperatorKind Kind = getOperator();
   if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
     if (getNumArgs() == 1)
@@ -438,7 +438,7 @@ SourceRange CXXOperatorCallExpr::getSourceRange() const {
     return SourceRange(getArg(0)->getSourceRange().getBegin(),
                        getArg(1)->getSourceRange().getEnd());
   } else {
-    return SourceRange();
+    return getOperatorLoc();
   }
 }
 
index 73b5ab7ec6d1cbb342618a1c63ad48b588c1a3f8..9eda98cbc8ac639670b5a549d2bf24fa672a6f7f 100644 (file)
@@ -1074,7 +1074,8 @@ void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
 
 void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   VisitCallExpr(E);
-  E->setOperator((OverloadedOperatorKind)Record[Idx++]);
+  E->Operator = (OverloadedOperatorKind)Record[Idx++];
+  E->Range = Reader.ReadSourceRange(F, Record, Idx);
 }
 
 void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
index 89436157df98be7c6e77330c9da282ee50bca615..4f25e707c19d195d95415a5c2a1a6a786bbcca4b 100644 (file)
@@ -1045,6 +1045,7 @@ void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
 void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   VisitCallExpr(E);
   Record.push_back(E->getOperator());
+  Writer.AddSourceRange(E->Range, Record);
   Code = serialization::EXPR_CXX_OPERATOR_CALL;
 }