]> granicus.if.org Git - clang/commitdiff
When instantiating a function template declaration that was expressed
authorDouglas Gregor <dgregor@apple.com>
Wed, 22 Jun 2011 18:16:25 +0000 (18:16 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 22 Jun 2011 18:16:25 +0000 (18:16 +0000)
via a typedef of a function, make sure to synthesize parameter
declarations. Fixes PR9654 / <rdar://problem/9257497>.

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

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/instantiate-function-2.cpp

index cc66ec67593c8c67add5f55e3618902039e0b1ed..196e847728d479ebc9a44e0d0b444ddde56a7bc5 100644 (file)
@@ -1090,9 +1090,26 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
   Function->setLexicalDeclContext(LexicalDC);
 
   // Attach the parameters
-  for (unsigned P = 0; P < Params.size(); ++P)
-    if (Params[P])
-      Params[P]->setOwningFunction(Function);
+  if (isa<FunctionProtoType>(Function->getType())) {
+    // Adopt the already-instantiated parameters into our own context.
+    for (unsigned P = 0; P < Params.size(); ++P)
+      if (Params[P])
+        Params[P]->setOwningFunction(Function);
+  } else {
+    // Since we were instantiated via a typedef of a function type, create
+    // new parameters.
+    const FunctionProtoType *Proto
+      = Function->getType()->getAs<FunctionProtoType>();
+    assert(Proto && "No function prototype in template instantiation?");
+    for (FunctionProtoType::arg_type_iterator AI = Proto->arg_type_begin(),
+         AE = Proto->arg_type_end(); AI != AE; ++AI) {
+      ParmVarDecl *Param
+        = SemaRef.BuildParmVarDeclForTypedef(Function, Function->getLocation(),
+                                             *AI);
+      Param->setScopeInfo(0, Params.size());
+      Params.push_back(Param);
+    }
+  }
   Function->setParams(Params.data(), Params.size());
 
   SourceLocation InstantiateAtPOI;
index ebc0ef3a9f9616c26973bb2760ffca460fe9c99a..b4c0d9d6393cfd3b28318f20453230b2062c8e5e 100644 (file)
@@ -31,3 +31,14 @@ namespace UsedAttr {
     foo<int>(); // expected-note{{instantiation of}}
   }
 }
+
+namespace PR9654 {
+  typedef void ftype(int);
+
+  template<typename T>
+  ftype f;
+
+  void g() {
+    f<int>(0);
+  }
+}