From 07b201d9c060d07a8f6dd55aed160aa5ec1fbc3a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 14 Nov 2007 06:34:38 +0000 Subject: [PATCH] implement test/Sema/typedef-prototype.c, allowing code to declare a function with a typedef: typedef int unary_int_func(int arg); unary_int_func add_one; This patch contributed by Seo Sanghyeon! llvm-svn: 44100 --- clang/Sema/Sema.h | 3 ++- clang/Sema/SemaDecl.cpp | 16 ++++++---------- clang/test/Sema/typedef-prototype.c | 8 ++++++++ 3 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 clang/test/Sema/typedef-prototype.c diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h index 40b966e52b67..8b470fe5c6c7 100644 --- a/clang/Sema/Sema.h +++ b/clang/Sema/Sema.h @@ -224,7 +224,8 @@ private: DeclTy **Elements, unsigned NumElements); private: /// Subroutines of ActOnDeclarator()... - TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, ScopedDecl *LastDecl); + TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T, + ScopedDecl *LastDecl); TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, ScopedDecl *Old); FunctionDecl *MergeFunctionDecl(FunctionDecl *New, ScopedDecl *Old); VarDecl *MergeVarDecl(VarDecl *New, ScopedDecl *Old); diff --git a/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp index 1540b7caae45..36813bafca0d 100644 --- a/clang/Sema/SemaDecl.cpp +++ b/clang/Sema/SemaDecl.cpp @@ -572,8 +572,11 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { ScopedDecl *New; bool InvalidDecl = false; + QualType R = GetTypeForDeclarator(D, S); + assert(!R.isNull() && "GetTypeForDeclarator() returned null type"); + if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) { - TypedefDecl *NewTD = ParseTypedefDecl(S, D, LastDeclarator); + TypedefDecl *NewTD = ParseTypedefDecl(S, D, R, LastDeclarator); if (!NewTD) return 0; // Handle attributes prior to checking for duplicates in MergeVarDecl @@ -595,10 +598,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { InvalidDecl = true; } } - } else if (D.isFunctionDeclarator()) { - QualType R = GetTypeForDeclarator(D, S); - assert(!R.isNull() && "GetTypeForDeclarator() returned null type"); - + } else if (R.getTypePtr()->isFunctionType()) { FunctionDecl::StorageClass SC = FunctionDecl::None; switch (D.getDeclSpec().getStorageClassSpec()) { default: assert(0 && "Unknown storage class!"); @@ -628,8 +628,6 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { } New = NewFD; } else { - QualType R = GetTypeForDeclarator(D, S); - assert(!R.isNull() && "GetTypeForDeclarator() returned null type"); if (R.getTypePtr()->isObjcInterfaceType()) { Diag(D.getIdentifierLoc(), diag::err_statically_allocated_object, D.getIdentifier()->getName()); @@ -1041,11 +1039,9 @@ ScopedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, } -TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, +TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, ScopedDecl *LastDeclarator) { assert(D.getIdentifier() && "Wrong callback for declspec without declarator"); - - QualType T = GetTypeForDeclarator(D, S); assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); // Scope manipulation handled by caller. diff --git a/clang/test/Sema/typedef-prototype.c b/clang/test/Sema/typedef-prototype.c new file mode 100644 index 000000000000..e646604ae389 --- /dev/null +++ b/clang/test/Sema/typedef-prototype.c @@ -0,0 +1,8 @@ +// RUN: clang -fsyntax-only -verify %s + +typedef int unary_int_func(int arg); +unary_int_func add_one; + +int add_one(int arg) { + return arg + 1; +}