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
This commit is contained in:
Chris Lattner 2007-11-14 06:34:38 +00:00
parent a77e74edba
commit 07b201d9c0
3 changed files with 16 additions and 11 deletions

View File

@ -224,7 +224,8 @@ private:
DeclTy **Elements, unsigned NumElements); DeclTy **Elements, unsigned NumElements);
private: private:
/// Subroutines of ActOnDeclarator()... /// 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); TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, ScopedDecl *Old);
FunctionDecl *MergeFunctionDecl(FunctionDecl *New, ScopedDecl *Old); FunctionDecl *MergeFunctionDecl(FunctionDecl *New, ScopedDecl *Old);
VarDecl *MergeVarDecl(VarDecl *New, ScopedDecl *Old); VarDecl *MergeVarDecl(VarDecl *New, ScopedDecl *Old);

View File

@ -572,8 +572,11 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
ScopedDecl *New; ScopedDecl *New;
bool InvalidDecl = false; bool InvalidDecl = false;
QualType R = GetTypeForDeclarator(D, S);
assert(!R.isNull() && "GetTypeForDeclarator() returned null type");
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) { if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
TypedefDecl *NewTD = ParseTypedefDecl(S, D, LastDeclarator); TypedefDecl *NewTD = ParseTypedefDecl(S, D, R, LastDeclarator);
if (!NewTD) return 0; if (!NewTD) return 0;
// Handle attributes prior to checking for duplicates in MergeVarDecl // Handle attributes prior to checking for duplicates in MergeVarDecl
@ -595,10 +598,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
InvalidDecl = true; InvalidDecl = true;
} }
} }
} else if (D.isFunctionDeclarator()) { } else if (R.getTypePtr()->isFunctionType()) {
QualType R = GetTypeForDeclarator(D, S);
assert(!R.isNull() && "GetTypeForDeclarator() returned null type");
FunctionDecl::StorageClass SC = FunctionDecl::None; FunctionDecl::StorageClass SC = FunctionDecl::None;
switch (D.getDeclSpec().getStorageClassSpec()) { switch (D.getDeclSpec().getStorageClassSpec()) {
default: assert(0 && "Unknown storage class!"); default: assert(0 && "Unknown storage class!");
@ -628,8 +628,6 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
} }
New = NewFD; New = NewFD;
} else { } else {
QualType R = GetTypeForDeclarator(D, S);
assert(!R.isNull() && "GetTypeForDeclarator() returned null type");
if (R.getTypePtr()->isObjcInterfaceType()) { if (R.getTypePtr()->isObjcInterfaceType()) {
Diag(D.getIdentifierLoc(), diag::err_statically_allocated_object, Diag(D.getIdentifierLoc(), diag::err_statically_allocated_object,
D.getIdentifier()->getName()); 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) { ScopedDecl *LastDeclarator) {
assert(D.getIdentifier() && "Wrong callback for declspec without declarator"); assert(D.getIdentifier() && "Wrong callback for declspec without declarator");
QualType T = GetTypeForDeclarator(D, S);
assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
// Scope manipulation handled by caller. // Scope manipulation handled by caller.

View File

@ -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;
}