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!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44100 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/Sema.h b/Sema/Sema.h
index 40b966e..8b470fe 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -224,7 +224,8 @@
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/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 1540b7c..36813ba 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -572,8 +572,11 @@
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 @@
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 @@
}
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 @@
}
-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/test/Sema/typedef-prototype.c b/test/Sema/typedef-prototype.c
new file mode 100644
index 0000000..e646604
--- /dev/null
+++ b/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;
+}