When merging from a function with a prototype to a function without a
prototype, synthesize ParmVarDecls for prototype-less FunctionDecl.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64666 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 3f31a33..b194c9e 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -607,6 +607,23 @@
                                          OldProto->getTypeQuals());
       New->setType(NewQType);
       New->setInheritedPrototype();
+
+      // Synthesize a parameter for each argument type.
+      llvm::SmallVector<ParmVarDecl*, 16> Params;
+      for (FunctionTypeProto::arg_type_iterator 
+             ParamType = OldProto->arg_type_begin(), 
+             ParamEnd = OldProto->arg_type_end();
+           ParamType != ParamEnd; ++ParamType) {
+        ParmVarDecl *Param = ParmVarDecl::Create(Context, New,
+                                                 SourceLocation(), 0,
+                                                 *ParamType, VarDecl::None,
+                                                 0);
+        Param->setImplicit();
+        Params.push_back(Param);
+      }
+
+      New->setParams(Context, &Params[0], Params.size());
+
     }
 
     MergeAttributes(New, Old);
@@ -762,7 +779,9 @@
     
     // C99 6.9.1p5: If the declarator includes a parameter type list, the
     // declaration of each parameter shall include an identifier.
-    if (Param->getIdentifier() == 0 && !getLangOptions().CPlusPlus)
+    if (Param->getIdentifier() == 0 && 
+        !Param->isImplicit() &&
+        !getLangOptions().CPlusPlus)
       Diag(Param->getLocation(), diag::err_parameter_name_omitted);
   }
 
@@ -1693,10 +1712,12 @@
       llvm::SmallVector<ParmVarDecl*, 16> Params;
       for (FunctionTypeProto::arg_type_iterator ArgType = FT->arg_type_begin();
            ArgType != FT->arg_type_end(); ++ArgType) {
-        Params.push_back(ParmVarDecl::Create(Context, DC,
-                                             SourceLocation(), 0,
-                                             *ArgType, VarDecl::None,
-                                             0));
+        ParmVarDecl *Param = ParmVarDecl::Create(Context, DC,
+                                                 SourceLocation(), 0,
+                                                 *ArgType, VarDecl::None,
+                                                 0);
+        Param->setImplicit();
+        Params.push_back(Param);
       }
 
       NewFD->setParams(Context, &Params[0], Params.size());
diff --git a/test/CodeGen/functions.c b/test/CodeGen/functions.c
index 60e2b6c..83da647 100644
--- a/test/CodeGen/functions.c
+++ b/test/CodeGen/functions.c
@@ -15,3 +15,5 @@
   f();
 }
 
+int a(int);
+int a() {return 1;}