diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-05-04 18:18:31 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-05-04 18:18:31 +0000 |
commit | c8be95274d615a6ca3d4b717267100531ff84ed2 (patch) | |
tree | 16207c834f17e11f4a46d55c7a35958bc7102140 | |
parent | a25ee78fc0afc78dd363037daef4245f92e23218 (diff) | |
download | bcm5719-llvm-c8be95274d615a6ca3d4b717267100531ff84ed2.tar.gz bcm5719-llvm-c8be95274d615a6ca3d4b717267100531ff84ed2.zip |
When instantiating a function that was declared via a typedef, e.g.,
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.
llvm-svn: 103025
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 21 | ||||
-rw-r--r-- | clang/test/Sema/function-redecl.c | 2 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-function-params.cpp | 12 |
7 files changed, 45 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 4963e73fe46..48ae5113b3a 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -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()) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0e839a9d2d6..a802679b26e 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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(); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c4ab03facb5..869d6df2f09 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -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> diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 21f2a51040e..b87fa7d51ea 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -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(); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8b851b21eac..da8480633d5 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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, diff --git a/clang/test/Sema/function-redecl.c b/clang/test/Sema/function-redecl.c index b8a64af96bc..633ad214236 100644 --- a/clang/test/Sema/function-redecl.c +++ b/clang/test/Sema/function-redecl.c @@ -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 *'}} diff --git a/clang/test/SemaTemplate/instantiate-function-params.cpp b/clang/test/SemaTemplate/instantiate-function-params.cpp index 45de3425d2a..54847e41908 100644 --- a/clang/test/SemaTemplate/instantiate-function-params.cpp +++ b/clang/test/SemaTemplate/instantiate-function-params.cpp @@ -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); + } +} |