]> granicus.if.org Git - clang/commitdiff
When instantiating a function that was declared via a typedef, e.g.,
authorDouglas Gregor <dgregor@apple.com>
Tue, 4 May 2010 18:18:31 +0000 (18:18 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 4 May 2010 18:18:31 +0000 (18:18 +0000)
    typedef int functype(int, int);
    functype func;

also instantiate the synthesized function parameters for the resulting
function declaration.

With this change, Boost.Wave builds and passes all of its regression
tests.

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

lib/CodeGen/CGDebugInfo.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaOverload.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/Sema/function-redecl.c
test/SemaTemplate/instantiate-function-params.cpp

index 4963e73fe464428618c89a3143d40dd6b0ab3206..48ae5113b3af5a29ca1e9ff0dc260600d1957e4f 100644 (file)
@@ -495,7 +495,10 @@ CollectRecordFields(const RecordDecl *RD, llvm::DIFile Unit,
 llvm::DIType
 CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
                                    llvm::DIFile Unit) {
-  llvm::DIType FnTy = getOrCreateType(Method->getType(), Unit);
+  llvm::DIType FnTy
+    = getOrCreateType(QualType(Method->getType()->getAs<FunctionProtoType>(),
+                               0),
+                      Unit);
   
   // Static methods do not need "this" pointer argument.
   if (Method->isStatic())
index 0e839a9d2d69fa339fe34eb8dcf2603217008625..a802679b26e1e82fd6a8818a5cc050b174a49df5 100644 (file)
@@ -3243,8 +3243,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
          AE = FT->arg_type_end(); AI != AE; ++AI) {
       ParmVarDecl *Param = ParmVarDecl::Create(Context, NewFD,
-                                               SourceLocation(), 0,
-                                               *AI, /*TInfo=*/0,
+                                               D.getIdentifierLoc(), 0,
+                                               *AI, 
+                                         Context.getTrivialTypeSourceInfo(*AI, 
+                                                          D.getIdentifierLoc()),
                                                VarDecl::None,
                                                VarDecl::None, 0);
       Param->setImplicit();
index c4ab03facb528d609727b862a08f24237c965c25..869d6df2f0949b78cd0ac373abddac70a01031c9 100644 (file)
@@ -3565,8 +3565,8 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
     if (BinaryOperator *BO = dyn_cast<BinaryOperator>(NakedFn)) {
       if (BO->getOpcode() == BinaryOperator::PtrMemD ||
           BO->getOpcode() == BinaryOperator::PtrMemI) {
-        if (const FunctionProtoType *FPT =
-              dyn_cast<FunctionProtoType>(BO->getType())) {
+        if (const FunctionProtoType *FPT
+                                = BO->getType()->getAs<FunctionProtoType>()) {
           QualType ResultTy = FPT->getResultType().getNonReferenceType();
 
           ExprOwningPtr<CXXMemberCallExpr>
index 21f2a51040ecaa0d2240b2e7a12c3ffb66531a94..b87fa7d51ea189a829fb0c51e48c61bbb77f3845 100644 (file)
@@ -6513,7 +6513,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
   MemExpr->setBase(ObjectArg);
 
   // Convert the rest of the arguments
-  const FunctionProtoType *Proto = cast<FunctionProtoType>(Method->getType());
+  const FunctionProtoType *Proto = Method->getType()->getAs<FunctionProtoType>();
   if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs,
                               RParenLoc))
     return ExprError();
index 8b851b21eacd79c5fe94de74694ce650b7c33522..da8480633d5b283935e42159bdc8b5ca46c7aa07 100644 (file)
@@ -1169,6 +1169,27 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
     return 0;
   QualType T = TInfo->getType();
 
+  // \brief If the type of this function is not *directly* a function
+  // type, then we're instantiating the a function that was declared
+  // via a typedef, e.g.,
+  //
+  //   typedef int functype(int, int);
+  //   functype func;
+  //
+  // In this case, we'll just go instantiate the ParmVarDecls that we
+  // synthesized in the method declaration.
+  if (!isa<FunctionProtoType>(T)) {
+    assert(!Params.size() && "Instantiating type could not yield parameters");
+    for (unsigned I = 0, N = D->getNumParams(); I != N; ++I) {
+      ParmVarDecl *P = SemaRef.SubstParmVarDecl(D->getParamDecl(I), 
+                                                TemplateArgs);
+      if (!P)
+        return 0;
+
+      Params.push_back(P);
+    }
+  }
+
   NestedNameSpecifier *Qualifier = D->getQualifier();
   if (Qualifier) {
     Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
index b8a64af96bcf6c1ba8162e8d9dc651d35ab9c2c6..633ad214236a28129e0680580a3776416673539d 100644 (file)
@@ -120,7 +120,7 @@ extern __typeof (i1) i1;
 typedef int a();
 typedef int a2(int*);
 a x;
-a2 x2;
+a2 x2; // expected-note{{passing argument to parameter here}}
 void test_x() {
   x(5);
   x2(5); // expected-warning{{incompatible integer to pointer conversion passing 'int' to parameter of type 'int *'}}
index 45de3425d2a206f8b067754abe6d051abc77f7f2..54847e419086ec4edca7b8a4f39b9699ff55efbd 100644 (file)
@@ -76,3 +76,15 @@ namespace PR6990 {
   {
   };
 }
+
+namespace InstantiateFunctionTypedef {
+  template<typename T>
+  struct X {
+    typedef int functype(int, int);
+    functype func;
+  };
+
+  void f(X<int> x) {
+    (void)x.func(1, 2);
+  }
+}