]> granicus.if.org Git - clang/commitdiff
Patch to implement new-operators with default args.
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 19 Nov 2009 18:39:40 +0000 (18:39 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 19 Nov 2009 18:39:40 +0000 (18:39 +0000)
Fixes pr5547.

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

lib/Sema/SemaExprCXX.cpp
test/CodeGenCXX/new-with-default-arg.cpp [new file with mode: 0644]

index 462bf13540eb0bf4ce7d2f675f351b71537a9da0..209d3069cafeb4fab3ba27e3f9d742a1f5e3864e 100644 (file)
@@ -326,7 +326,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
   QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo);
   if (D.isInvalidType())
     return ExprError();
-
+    
   return BuildCXXNew(StartLoc, UseGlobal,
                      PlacementLParen,
                      move(PlacementArgs),
@@ -394,7 +394,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
   FunctionDecl *OperatorDelete = 0;
   Expr **PlaceArgs = (Expr**)PlacementArgs.get();
   unsigned NumPlaceArgs = PlacementArgs.size();
-    
+  
   if (!AllocType->isDependentType() &&
       !Expr::hasAnyTypeDependentArguments(PlaceArgs, NumPlaceArgs) &&
       FindAllocationFunctions(StartLoc,
@@ -402,7 +402,35 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                               UseGlobal, AllocType, ArraySize, PlaceArgs,
                               NumPlaceArgs, OperatorNew, OperatorDelete))
     return ExprError();
-
+  llvm::SmallVector<Expr *, 4> 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();
+    
+      Arg = ArgExpr.takeAs<Expr>();
+      AllPlaceArgs.push_back(Arg);
+    }
+    NumPlaceArgs = AllPlaceArgs.size();
+    if (NumPlaceArgs > 0)
+      PlaceArgs = &AllPlaceArgs[0];
+  }
+  
   bool Init = ConstructorLParen.isValid();
   // --- Choosing a constructor ---
   // C++ 5.3.4p15
diff --git a/test/CodeGenCXX/new-with-default-arg.cpp b/test/CodeGenCXX/new-with-default-arg.cpp
new file mode 100644 (file)
index 0000000..b73b7f0
--- /dev/null
@@ -0,0 +1,33 @@
+// RUN: clang-cc -emit-llvm -o - %s
+// pr5547
+
+struct A {
+  void* operator new(__typeof(sizeof(int)));
+  A();
+};
+
+A* x() {
+  return new A;
+}
+
+struct B {
+  void* operator new(__typeof(sizeof(int)), int = 1, int = 4);
+  B(float);
+};
+
+B* y() {
+  new (3,4) B(1);
+  return new(1) B(2);
+}
+
+struct C {
+  void* operator new(__typeof(sizeof(int)), int, int = 4);
+  C();
+};
+
+C* z() {
+  new (3,4) C;
+  return new(1) C;
+}
+
+