[cfe-commits] r89781 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/CodeGenCXX/new.cpp

Fariborz Jahanian fjahanian at apple.com
Tue Nov 24 10:29:37 PST 2009


Author: fjahanian
Date: Tue Nov 24 12:29:37 2009
New Revision: 89781

URL: http://llvm.org/viewvc/llvm-project?rev=89781&view=rev
Log:
Refactor collection of call arguments in common code.
Add support for variadic collection functions. More to do
here.


Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/CodeGenCXX/new.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=89781&r1=89780&r2=89781&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Nov 24 12:29:37 2009
@@ -1514,6 +1514,14 @@
                                Expr **Args, unsigned NumArgs,
                                SourceLocation RParenLoc);
 
+  bool GatherArgumentsForCall(SourceLocation CallLoc,
+                              FunctionDecl *FDecl,
+                              const FunctionProtoType *Proto,
+                              unsigned FirstProtoArg,
+                              Expr **Args, unsigned NumArgs,
+                              llvm::SmallVector<Expr *, 8> &AllArgs,
+                              Expr *Fn = 0);
+
   void DeconstructCallFunction(Expr *FnExpr,
                                llvm::SmallVectorImpl<NamedDecl*>& Fns,
                                DeclarationName &Name,

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=89781&r1=89780&r2=89781&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov 24 12:29:37 2009
@@ -2520,17 +2520,14 @@
   // C99 6.5.2.2p7 - the arguments are implicitly converted, as if by
   // assignment, to the types of the corresponding parameter, ...
   unsigned NumArgsInProto = Proto->getNumArgs();
-  unsigned NumArgsToCheck = NumArgs;
   bool Invalid = false;
-
+   
   // If too few arguments are available (and we don't have default
   // arguments for the remaining parameters), don't make the call.
   if (NumArgs < NumArgsInProto) {
     if (!FDecl || NumArgs < FDecl->getMinRequiredArguments())
       return Diag(RParenLoc, diag::err_typecheck_call_too_few_args)
         << Fn->getType()->isBlockPointerType() << Fn->getSourceRange();
-    // Use default arguments for missing arguments
-    NumArgsToCheck = NumArgsInProto;
     Call->setNumArgs(Context, NumArgsInProto);
   }
 
@@ -2545,25 +2542,49 @@
                        Args[NumArgs-1]->getLocEnd());
       // This deletes the extra arguments.
       Call->setNumArgs(Context, NumArgsInProto);
-      Invalid = true;
+      return true;
     }
-    NumArgsToCheck = NumArgsInProto;
   }
+  llvm::SmallVector<Expr *, 8> AllArgs;
+  Invalid = GatherArgumentsForCall(Call->getSourceRange().getBegin(), FDecl,
+                                   Proto, 0, Args, NumArgs, AllArgs, Fn);
+  if (Invalid)
+    return true;
+  unsigned TotalNumArgs = AllArgs.size();
+  for (unsigned i = 0; i < TotalNumArgs; ++i)
+    Call->setArg(i, AllArgs[i]);
+  
+  return false;
+}
 
+bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
+                                  FunctionDecl *FDecl,
+                                  const FunctionProtoType *Proto,
+                                  unsigned FirstProtoArg,
+                                  Expr **Args, unsigned NumArgs,
+                                  llvm::SmallVector<Expr *, 8> &AllArgs,
+                                  Expr *Fn) {
+  unsigned NumArgsInProto = Proto->getNumArgs();
+  unsigned NumArgsToCheck = NumArgs;
+  bool Invalid = false;
+  if (NumArgs != NumArgsInProto)
+    // Use default arguments for missing arguments
+    NumArgsToCheck = NumArgsInProto;
+  unsigned ArgIx = 0;
   // Continue to check argument types (even if we have too few/many args).
-  for (unsigned i = 0; i != NumArgsToCheck; i++) {
+  for (unsigned i = FirstProtoArg; i != NumArgsToCheck; i++) {
     QualType ProtoArgType = Proto->getArgType(i);
-
+    
     Expr *Arg;
-    if (i < NumArgs) {
-      Arg = Args[i];
-
+    if (ArgIx < NumArgs) {
+      Arg = Args[ArgIx++];
+      
       if (RequireCompleteType(Arg->getSourceRange().getBegin(),
                               ProtoArgType,
                               PDiag(diag::err_call_incomplete_argument)
-                                << Arg->getSourceRange()))
+                              << Arg->getSourceRange()))
         return true;
-
+      
       // Pass the argument.
       if (PerformCopyInitialization(Arg, ProtoArgType, "passing"))
         return true;
@@ -2572,35 +2593,33 @@
         Arg = MaybeBindToTemporary(Arg).takeAs<Expr>();
     } else {
       ParmVarDecl *Param = FDecl->getParamDecl(i);
-
+      
       OwningExprResult ArgExpr =
-        BuildCXXDefaultArgExpr(Call->getSourceRange().getBegin(),
-                               FDecl, Param);
+        BuildCXXDefaultArgExpr(CallLoc, FDecl, Param);
       if (ArgExpr.isInvalid())
         return true;
-
+      
       Arg = ArgExpr.takeAs<Expr>();
     }
-
-    Call->setArg(i, Arg);
+    AllArgs.push_back(Arg);
   }
-
+  
   // If this is a variadic call, handle args passed through "...".
   if (Proto->isVariadic()) {
     VariadicCallType CallType = VariadicFunction;
-    if (Fn->getType()->isBlockPointerType())
-      CallType = VariadicBlock; // Block
-    else if (isa<MemberExpr>(Fn))
-      CallType = VariadicMethod;
-
+    if (Fn) {
+      if (Fn->getType()->isBlockPointerType())
+        CallType = VariadicBlock; // Block
+      else if (isa<MemberExpr>(Fn))
+        CallType = VariadicMethod;
+    }
     // Promote the arguments (C99 6.5.2.2p7).
-    for (unsigned i = NumArgsInProto; i < NumArgs; i++) {
+    for (unsigned i = ArgIx; i < NumArgs; i++) {
       Expr *Arg = Args[i];
       Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType);
-      Call->setArg(i, Arg);
+      AllArgs.push_back(Arg);
     }
   }
-
   return Invalid;
 }
 

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=89781&r1=89780&r2=89781&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Nov 24 12:29:37 2009
@@ -402,30 +402,17 @@
                               UseGlobal, AllocType, ArraySize, PlaceArgs,
                               NumPlaceArgs, OperatorNew, OperatorDelete))
     return ExprError();
-  llvm::SmallVector<Expr *, 4> AllPlaceArgs;
+  llvm::SmallVector<Expr *, 8> AllPlaceArgs;
   if (OperatorNew) {
     // Add default arguments, if any.
     const FunctionProtoType *Proto = 
       OperatorNew->getType()->getAs<FunctionProtoType>();
-    unsigned NumArgsInProto = Proto->getNumArgs();
-    for (unsigned i = 1; i != NumArgsInProto; i++) {
-      QualType ProtoArgType = Proto->getArgType(i);
-    
-      Expr *Arg;
-      if (i <= NumPlaceArgs) {
-        AllPlaceArgs.push_back(PlaceArgs[i-1]);
-        continue;
-      }
-      ParmVarDecl *Param = OperatorNew->getParamDecl(i);
-    
-      OwningExprResult ArgExpr =
-        BuildCXXDefaultArgExpr(StartLoc, OperatorNew, Param);
-      if (ArgExpr.isInvalid())
-        return ExprError();
+    bool Invalid = GatherArgumentsForCall(PlacementLParen, OperatorNew,
+                                          Proto, 1, PlaceArgs, NumPlaceArgs, 
+                                          AllPlaceArgs);
+    if (Invalid)
+      return ExprError();
     
-      Arg = ArgExpr.takeAs<Expr>();
-      AllPlaceArgs.push_back(Arg);
-    }
     NumPlaceArgs = AllPlaceArgs.size();
     if (NumPlaceArgs > 0)
       PlaceArgs = &AllPlaceArgs[0];
@@ -630,7 +617,9 @@
     // The first argument is size_t, and the first parameter must be size_t,
     // too. This is checked on declaration and can be assumed. (It can't be
     // asserted on, though, since invalid decls are left in there.)
-    for (unsigned i = 0; i < NumArgs; ++i) {
+    // Whatch out for variadic allocator function.
+    unsigned NumArgsInFnDecl = FnDecl->getNumParams();
+    for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) {
       // FIXME: Passing word to diagnostic.
       if (PerformCopyInitialization(Args[i],
                                     FnDecl->getParamDecl(i)->getType(),

Modified: cfe/trunk/test/CodeGenCXX/new.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/new.cpp?rev=89781&r1=89780&r2=89781&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/new.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/new.cpp Tue Nov 24 12:29:37 2009
@@ -79,3 +79,14 @@
   new bool(true);  
   new (&b) bool(true);
 }
+
+struct A {
+  void* operator new(__typeof(sizeof(int)), int, float, ...);
+  A();
+};
+
+A* t10() {
+   // CHECK: @_ZN1AnwEmifz
+  return new(1, 2, 3.45, 100) A;
+}
+





More information about the cfe-commits mailing list