r348145 - [AST][Sema] Remove CallExpr::setNumArgs

Bruno Ricci via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 3 06:54:03 PST 2018


Author: brunoricci
Date: Mon Dec  3 06:54:03 2018
New Revision: 348145

URL: http://llvm.org/viewvc/llvm-project?rev=348145&view=rev
Log:
[AST][Sema] Remove CallExpr::setNumArgs

CallExpr::setNumArgs is the only thing that prevents storing the arguments
in a trailing array. There is only 3 places in Sema where setNumArgs is called.
D54900 dealt with one of them.

This patch remove the other two calls to setNumArgs in ConvertArgumentsForCall.
To do this we do the following changes:

1.) Replace the first call to setNumArgs by an assertion since we are moving the
responsability to allocate enough space for the arguments from
Sema::ConvertArgumentsForCall to its callers
(which are Sema::BuildCallToMemberFunction, and Sema::BuildResolvedCallExpr).

2.) Add a new member function CallExpr::shrinkNumArgs, which can only be used
to drop arguments and then replace the second call to setNumArgs by
shrinkNumArgs.

3.) Add a new defaulted parameter MinNumArgs to CallExpr and its derived
classes which specifies a minimum number of argument slots to allocate.
The actual number of arguments slots allocated will be
max(number of args, MinNumArgs) with the extra args nulled. Note that
after the creation of the call expression all of the arguments will be
non-null. It is just during the creation of the call expression that some of
the last arguments can be temporarily null, until filled by default arguments.

4.) Update Sema::BuildCallToMemberFunction by passing the number of parameters
in the function prototype to the constructor of CXXMemberCallExpr. Here the
change is pretty straightforward.

5.) Update Sema::BuildResolvedCallExpr. Here the change is more complicated
since the type-checking for the function type was done after the creation of
the call expression. We need to move this before the creation of the call
expression, and then pass the number of parameters in the function prototype
(if any) to the constructor of the call expression.

6.) Update the deserialization of CallExpr and its derived classes.

Differential Revision: https://reviews.llvm.org/D54902

Reviewed By: aaron.ballman


Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=348145&r1=348144&r2=348145&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon Dec  3 06:54:03 2018
@@ -2416,11 +2416,12 @@ protected:
   // These versions of the constructor are for derived classes.
   CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
            ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t,
-           ExprValueKind VK, SourceLocation rparenloc);
+           ExprValueKind VK, SourceLocation rparenloc, unsigned MinNumArgs = 0);
   CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, ArrayRef<Expr *> args,
-           QualType t, ExprValueKind VK, SourceLocation rparenloc);
+           QualType t, ExprValueKind VK, SourceLocation rparenloc,
+           unsigned MinNumArgs = 0);
   CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
-           EmptyShell Empty);
+           unsigned NumArgs, EmptyShell Empty);
 
   Stmt *getPreArg(unsigned i) {
     assert(i < getNumPreArgs() && "Prearg access out of range!");
@@ -2438,11 +2439,14 @@ protected:
   unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
 
 public:
-  CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t,
-           ExprValueKind VK, SourceLocation rparenloc);
+  /// Build a call expression. MinNumArgs specifies the minimum number of
+  /// arguments. The actual number of arguments will be the greater of
+  /// args.size() and MinNumArgs.
+  CallExpr(const ASTContext &C, Expr *fn, ArrayRef<Expr *> args, QualType t,
+           ExprValueKind VK, SourceLocation rparenloc, unsigned MinNumArgs = 0);
 
   /// Build an empty call expression.
-  CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty);
+  CallExpr(const ASTContext &C, unsigned NumArgs, EmptyShell Empty);
 
   const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
   Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
@@ -2488,10 +2492,18 @@ public:
     SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr;
   }
 
-  /// 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.
-  void setNumArgs(const ASTContext& C, unsigned NumArgs);
+  /// Reduce the number of arguments in this call expression. This is used for
+  /// example during error recovery to drop extra arguments. There is no way
+  /// to perform the opposite because: 1.) We don't track how much storage
+  /// we have for the argument array 2.) This would potentially require growing
+  /// the argument array, something we cannot support since the arguments will
+  /// be stored in a trailing array in the future.
+  /// (TODO: update this comment when this is done).
+  void shrinkNumArgs(unsigned NewNumArgs) {
+    assert((NewNumArgs <= NumArgs) &&
+           "shrinkNumArgs cannot increase the number of arguments!");
+    NumArgs = NewNumArgs;
+  }
 
   typedef ExprIterator arg_iterator;
   typedef ConstExprIterator const_arg_iterator;

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=348145&r1=348144&r2=348145&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Mon Dec  3 06:54:03 2018
@@ -98,8 +98,10 @@ public:
     Range = getSourceRangeImpl();
   }
 
-  explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty)
-      : CallExpr(C, CXXOperatorCallExprClass, Empty) {}
+  explicit CXXOperatorCallExpr(ASTContext &C, unsigned NumArgs,
+                               EmptyShell Empty)
+      : CallExpr(C, CXXOperatorCallExprClass, /*NumPreArgs=*/0, NumArgs,
+                 Empty) {}
 
   /// Returns the kind of overloaded operator that this
   /// expression refers to.
@@ -163,12 +165,13 @@ public:
 /// the object argument).
 class CXXMemberCallExpr : public CallExpr {
 public:
-  CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args,
-                    QualType t, ExprValueKind VK, SourceLocation RP)
-      : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {}
+  CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr *> args, QualType t,
+                    ExprValueKind VK, SourceLocation RP,
+                    unsigned MinNumArgs = 0)
+      : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP, MinNumArgs) {}
 
-  CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
-      : CallExpr(C, CXXMemberCallExprClass, Empty) {}
+  CXXMemberCallExpr(ASTContext &C, unsigned NumArgs, EmptyShell Empty)
+      : CallExpr(C, CXXMemberCallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
 
   /// Retrieves the implicit object argument for the member call.
   ///
@@ -206,12 +209,14 @@ private:
 
 public:
   CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
-                     ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
-                     SourceLocation RP)
-      : CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP) {}
-
-  CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty)
-      : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) {}
+                     ArrayRef<Expr *> args, QualType t, ExprValueKind VK,
+                     SourceLocation RP, unsigned MinNumArgs = 0)
+      : CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP,
+                 MinNumArgs) {}
+
+  CUDAKernelCallExpr(ASTContext &C, unsigned NumArgs, EmptyShell Empty)
+      : CallExpr(C, CUDAKernelCallExprClass, /*NumPreArgs=*/END_PREARG, NumArgs,
+                 Empty) {}
 
   const CallExpr *getConfig() const {
     return cast_or_null<CallExpr>(getPreArg(CONFIG));
@@ -488,8 +493,10 @@ public:
       : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc),
         UDSuffixLoc(SuffixLoc) {}
 
-  explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty)
-      : CallExpr(C, UserDefinedLiteralClass, Empty) {}
+  explicit UserDefinedLiteral(const ASTContext &C, unsigned NumArgs,
+                              EmptyShell Empty)
+      : CallExpr(C, UserDefinedLiteralClass, /*NumPreArgs=*/0, NumArgs,
+                 Empty) {}
 
   /// The kind of literal operator which is invoked.
   enum LiteralOperatorKind {

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=348145&r1=348144&r2=348145&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Mon Dec  3 06:54:03 2018
@@ -1222,14 +1222,17 @@ OverloadedOperatorKind UnaryOperator::ge
 
 CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
                    ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t,
-                   ExprValueKind VK, SourceLocation rparenloc)
+                   ExprValueKind VK, SourceLocation rparenloc,
+                   unsigned MinNumArgs)
     : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent(),
            fn->isValueDependent(), fn->isInstantiationDependent(),
            fn->containsUnexpandedParameterPack()),
-      NumArgs(args.size()) {
-
+      RParenLoc(rparenloc) {
+  NumArgs = std::max<unsigned>(args.size(), MinNumArgs);
   unsigned NumPreArgs = preargs.size();
-  SubExprs = new (C) Stmt *[args.size()+PREARGS_START+NumPreArgs];
+  CallExprBits.NumPreArgs = NumPreArgs;
+
+  SubExprs = new (C) Stmt *[NumArgs + PREARGS_START + NumPreArgs];
   SubExprs[FN] = fn;
   for (unsigned i = 0; i != NumPreArgs; ++i) {
     updateDependenciesFromArg(preargs[i]);
@@ -1239,32 +1242,33 @@ CallExpr::CallExpr(const ASTContext &C,
     updateDependenciesFromArg(args[i]);
     SubExprs[i+PREARGS_START+NumPreArgs] = args[i];
   }
-
-  CallExprBits.NumPreArgs = NumPreArgs;
-  RParenLoc = rparenloc;
+  for (unsigned i = args.size(); i != NumArgs; ++i) {
+    SubExprs[i + PREARGS_START + NumPreArgs] = nullptr;
+  }
 }
 
 CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
                    ArrayRef<Expr *> args, QualType t, ExprValueKind VK,
-                   SourceLocation rparenloc)
-    : CallExpr(C, SC, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc) {}
+                   SourceLocation rparenloc, unsigned MinNumArgs)
+    : CallExpr(C, SC, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc,
+               MinNumArgs) {}
 
 CallExpr::CallExpr(const ASTContext &C, Expr *fn, ArrayRef<Expr *> args,
-                   QualType t, ExprValueKind VK, SourceLocation rparenloc)
-    : CallExpr(C, CallExprClass, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc) {
-}
-
-CallExpr::CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty)
-    : CallExpr(C, SC, /*NumPreArgs=*/0, Empty) {}
+                   QualType t, ExprValueKind VK, SourceLocation rparenloc,
+                   unsigned MinNumArgs)
+    : CallExpr(C, CallExprClass, fn, ArrayRef<Expr *>(), args, t, VK,
+               rparenloc, MinNumArgs) {}
 
 CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
-                   EmptyShell Empty)
-  : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) {
-  // FIXME: Why do we allocate this?
-  SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs]();
+                   unsigned NumArgs, EmptyShell Empty)
+    : Expr(SC, Empty), NumArgs(NumArgs) {
   CallExprBits.NumPreArgs = NumPreArgs;
+  SubExprs = new (C) Stmt *[NumArgs + PREARGS_START + NumPreArgs];
 }
 
+CallExpr::CallExpr(const ASTContext &C, unsigned NumArgs, EmptyShell Empty)
+    : CallExpr(C, CallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
+
 void CallExpr::updateDependenciesFromArg(Expr *Arg) {
   if (Arg->isTypeDependent())
     ExprBits.TypeDependent = true;
@@ -1308,35 +1312,6 @@ Decl *Expr::getReferencedDeclOfCallee()
   return nullptr;
 }
 
-/// 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.
-void CallExpr::setNumArgs(const ASTContext& C, unsigned NumArgs) {
-  // No change, just return.
-  if (NumArgs == getNumArgs()) return;
-
-  // If shrinking # arguments, just delete the extras and forgot them.
-  if (NumArgs < getNumArgs()) {
-    this->NumArgs = NumArgs;
-    return;
-  }
-
-  // Otherwise, we are growing the # arguments.  New an bigger argument array.
-  unsigned NumPreArgs = getNumPreArgs();
-  Stmt **NewSubExprs = new (C) Stmt*[NumArgs+PREARGS_START+NumPreArgs];
-  // Copy over args.
-  for (unsigned i = 0; i != getNumArgs()+PREARGS_START+NumPreArgs; ++i)
-    NewSubExprs[i] = SubExprs[i];
-  // Null out new args.
-  for (unsigned i = getNumArgs()+PREARGS_START+NumPreArgs;
-       i != NumArgs+PREARGS_START+NumPreArgs; ++i)
-    NewSubExprs[i] = nullptr;
-
-  if (SubExprs) C.Deallocate(SubExprs);
-  SubExprs = NewSubExprs;
-  this->NumArgs = NumArgs;
-}
-
 /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID. If
 /// not, return 0.
 unsigned CallExpr::getBuiltinCallee() const {

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=348145&r1=348144&r2=348145&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Dec  3 06:54:03 2018
@@ -4872,7 +4872,10 @@ Sema::ConvertArgumentsForCall(CallExpr *
 
       return true;
     }
-    Call->setNumArgs(Context, NumParams);
+    // We reserve space for the default arguments when we create
+    // the call expression, before calling ConvertArgumentsForCall.
+    assert((Call->getNumArgs() == NumParams) &&
+           "We should have reserved space for the default arguments before!");
   }
 
   // If too many are passed and not variadic, error on the extras and drop
@@ -4913,7 +4916,7 @@ Sema::ConvertArgumentsForCall(CallExpr *
         Diag(FDecl->getBeginLoc(), diag::note_callee_decl) << FDecl;
 
       // This deletes the extra arguments.
-      Call->setNumArgs(Context, NumParams);
+      Call->shrinkNumArgs(NumParams);
       return true;
     }
   }
@@ -5580,16 +5583,50 @@ Sema::BuildResolvedCallExpr(Expr *Fn, Na
     return ExprError();
   Fn = Result.get();
 
-  // Make the call expr early, before semantic checks.  This guarantees cleanup
-  // of arguments and function on error.
+  // Check for a valid function type, but only if it is not a builtin which
+  // requires custom type checking. These will be handled by
+  // CheckBuiltinFunctionCall below just after creation of the call expression.
+  const FunctionType *FuncT = nullptr;
+  if (!BuiltinID || !Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) {
+   retry:
+    if (const PointerType *PT = Fn->getType()->getAs<PointerType>()) {
+      // C99 6.5.2.2p1 - "The expression that denotes the called function shall
+      // have type pointer to function".
+      FuncT = PT->getPointeeType()->getAs<FunctionType>();
+      if (!FuncT)
+        return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
+                           << Fn->getType() << Fn->getSourceRange());
+    } else if (const BlockPointerType *BPT =
+                 Fn->getType()->getAs<BlockPointerType>()) {
+      FuncT = BPT->getPointeeType()->castAs<FunctionType>();
+    } else {
+      // Handle calls to expressions of unknown-any type.
+      if (Fn->getType() == Context.UnknownAnyTy) {
+        ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn);
+        if (rewrite.isInvalid()) return ExprError();
+        Fn = rewrite.get();
+        goto retry;
+      }
+
+    return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
+      << Fn->getType() << Fn->getSourceRange());
+    }
+  }
+
+  // Get the number of parameters in the function prototype, if any.
+  // We will allocate space for max(Args.size(), NumParams) arguments
+  // in the call expression.
+  const auto *Proto = dyn_cast_or_null<FunctionProtoType>(FuncT);
+  unsigned NumParams = Proto ? Proto->getNumParams() : 0;
+
   CallExpr *TheCall;
   if (Config)
-    TheCall =
-        new (Context) CUDAKernelCallExpr(Context, Fn, cast<CallExpr>(Config),
-                                         Args, ResultTy, VK_RValue, RParenLoc);
+    TheCall = new (Context)
+        CUDAKernelCallExpr(Context, Fn, cast<CallExpr>(Config), Args, ResultTy,
+                           VK_RValue, RParenLoc, NumParams);
   else
     TheCall = new (Context)
-        CallExpr(Context, Fn, Args, ResultTy, VK_RValue, RParenLoc);
+        CallExpr(Context, Fn, Args, ResultTy, VK_RValue, RParenLoc, NumParams);
 
   if (!getLangOpts().CPlusPlus) {
     // C cannot always handle TypoExpr nodes in builtin calls and direct
@@ -5600,39 +5637,16 @@ Sema::BuildResolvedCallExpr(Expr *Fn, Na
     if (!Result.isUsable()) return ExprError();
     TheCall = dyn_cast<CallExpr>(Result.get());
     if (!TheCall) return Result;
-    Args = llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs());
+    // TheCall at this point has max(Args.size(), NumParams) arguments,
+    // with extra arguments nulled. We don't want to introduce nulled
+    // arguments in Args and so we only take the first Args.size() arguments.
+    Args = llvm::makeArrayRef(TheCall->getArgs(), Args.size());
   }
 
-  // Bail out early if calling a builtin with custom typechecking.
+  // Bail out early if calling a builtin with custom type checking.
   if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID))
     return CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall);
 
- retry:
-  const FunctionType *FuncT;
-  if (const PointerType *PT = Fn->getType()->getAs<PointerType>()) {
-    // C99 6.5.2.2p1 - "The expression that denotes the called function shall
-    // have type pointer to function".
-    FuncT = PT->getPointeeType()->getAs<FunctionType>();
-    if (!FuncT)
-      return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
-                         << Fn->getType() << Fn->getSourceRange());
-  } else if (const BlockPointerType *BPT =
-               Fn->getType()->getAs<BlockPointerType>()) {
-    FuncT = BPT->getPointeeType()->castAs<FunctionType>();
-  } else {
-    // Handle calls to expressions of unknown-any type.
-    if (Fn->getType() == Context.UnknownAnyTy) {
-      ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn);
-      if (rewrite.isInvalid()) return ExprError();
-      Fn = rewrite.get();
-      TheCall->setCallee(Fn);
-      goto retry;
-    }
-
-    return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
-      << Fn->getType() << Fn->getSourceRange());
-  }
-
   if (getLangOpts().CUDA) {
     if (Config) {
       // CUDA: Kernel calls must be to global functions
@@ -5661,7 +5675,6 @@ Sema::BuildResolvedCallExpr(Expr *Fn, Na
   TheCall->setType(FuncT->getCallResultType(Context));
   TheCall->setValueKind(Expr::getValueKindForType(FuncT->getReturnType()));
 
-  const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT);
   if (Proto) {
     if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, RParenLoc,
                                 IsExecConfig))

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=348145&r1=348144&r2=348145&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Dec  3 06:54:03 2018
@@ -12836,7 +12836,8 @@ Sema::BuildCallToMemberFunction(Scope *S
 
     CXXMemberCallExpr *call
       = new (Context) CXXMemberCallExpr(Context, MemExprE, Args,
-                                        resultType, valueKind, RParenLoc);
+                                        resultType, valueKind, RParenLoc,
+                                        proto->getNumParams());
 
     if (CheckCallReturnType(proto->getReturnType(), op->getRHS()->getBeginLoc(),
                             call, nullptr))
@@ -12986,9 +12987,11 @@ Sema::BuildCallToMemberFunction(Scope *S
   ResultType = ResultType.getNonLValueExprType(Context);
 
   assert(Method && "Member call to something that isn't a method?");
+  const auto *Proto = Method->getType()->getAs<FunctionProtoType>();
   CXXMemberCallExpr *TheCall =
     new (Context) CXXMemberCallExpr(Context, MemExprE, Args,
-                                    ResultType, VK, RParenLoc);
+                                    ResultType, VK, RParenLoc,
+                                    Proto->getNumParams());
 
   // Check for a valid return type.
   if (CheckCallReturnType(Method->getReturnType(), MemExpr->getMemberLoc(),
@@ -13008,8 +13011,6 @@ Sema::BuildCallToMemberFunction(Scope *S
   }
 
   // Convert the rest of the arguments
-  const FunctionProtoType *Proto =
-    Method->getType()->getAs<FunctionProtoType>();
   if (ConvertArgumentsForCall(TheCall, MemExpr, Method, Proto, Args,
                               RParenLoc))
     return ExprError();

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=348145&r1=348144&r2=348145&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Dec  3 06:54:03 2018
@@ -731,10 +731,11 @@ void ASTStmtReader::VisitOMPArraySection
 
 void ASTStmtReader::VisitCallExpr(CallExpr *E) {
   VisitExpr(E);
-  E->setNumArgs(Record.getContext(), Record.readInt());
+  unsigned NumArgs = Record.readInt();
+  assert((NumArgs == E->getNumArgs()) && "Wrong NumArgs!");
   E->setRParenLoc(ReadSourceLocation());
   E->setCallee(Record.readSubExpr());
-  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+  for (unsigned I = 0; I != NumArgs; ++I)
     E->setArg(I, Record.readSubExpr());
 }
 
@@ -2479,7 +2480,9 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
       break;
 
     case EXPR_CALL:
-      S = new (Context) CallExpr(Context, Stmt::CallExprClass, Empty);
+      S = new (Context) CallExpr(
+          Context, /* NumArgs=*/Record[ASTStmtReader::NumExprFields + 0],
+          Empty);
       break;
 
     case EXPR_MEMBER: {
@@ -3069,11 +3072,15 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
     }
 
     case EXPR_CXX_OPERATOR_CALL:
-      S = new (Context) CXXOperatorCallExpr(Context, Empty);
+      S = new (Context) CXXOperatorCallExpr(
+          Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields + 0],
+          Empty);
       break;
 
     case EXPR_CXX_MEMBER_CALL:
-      S = new (Context) CXXMemberCallExpr(Context, Empty);
+      S = new (Context) CXXMemberCallExpr(
+          Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields + 0],
+          Empty);
       break;
 
     case EXPR_CXX_CONSTRUCT:
@@ -3113,7 +3120,8 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
       break;
 
     case EXPR_USER_DEFINED_LITERAL:
-      S = new (Context) UserDefinedLiteral(Context, Empty);
+      S = new (Context) UserDefinedLiteral(
+          Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields + 0], Empty);
       break;
 
     case EXPR_CXX_STD_INITIALIZER_LIST:
@@ -3283,7 +3291,8 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
       break;
 
     case EXPR_CUDA_KERNEL_CALL:
-      S = new (Context) CUDAKernelCallExpr(Context, Empty);
+      S = new (Context) CUDAKernelCallExpr(
+          Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields + 0], Empty);
       break;
 
     case EXPR_ASTYPE:




More information about the cfe-commits mailing list