summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-04 18:18:31 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-04 18:18:31 +0000
commitc8be95274d615a6ca3d4b717267100531ff84ed2 (patch)
tree16207c834f17e11f4a46d55c7a35958bc7102140
parenta25ee78fc0afc78dd363037daef4245f92e23218 (diff)
downloadbcm5719-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.cpp5
-rw-r--r--clang/lib/Sema/SemaDecl.cpp6
-rw-r--r--clang/lib/Sema/SemaExpr.cpp4
-rw-r--r--clang/lib/Sema/SemaOverload.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp21
-rw-r--r--clang/test/Sema/function-redecl.c2
-rw-r--r--clang/test/SemaTemplate/instantiate-function-params.cpp12
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);
+ }
+}
OpenPOWER on IntegriCloud