[cfe-commits] r39236 - in /cfe/cfe/trunk: AST/SemaType.cpp AST/Type.cpp Parse/ParseDecl.cpp Sema/SemaType.cpp include/clang/AST/Type.h test/Sema/void_arg.c
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:41:42 PDT 2007
Author: sabre
Date: Wed Jul 11 11:41:42 2007
New Revision: 39236
URL: http://llvm.org/viewvc/llvm-project?rev=39236&view=rev
Log:
move void argument checking from the parser to the semantic analysis stage.
This allows us to handle typedefs of void correctly. This implements
clang/test/Sema/void_arg.c
Added:
cfe/cfe/trunk/test/Sema/void_arg.c (with props)
Modified:
cfe/cfe/trunk/AST/SemaType.cpp
cfe/cfe/trunk/AST/Type.cpp
cfe/cfe/trunk/Parse/ParseDecl.cpp
cfe/cfe/trunk/Sema/SemaType.cpp
cfe/cfe/trunk/include/clang/AST/Type.h
Modified: cfe/cfe/trunk/AST/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaType.cpp?rev=39236&r1=39235&r2=39236&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaType.cpp (original)
+++ cfe/cfe/trunk/AST/SemaType.cpp Wed Jul 11 11:41:42 2007
@@ -137,12 +137,36 @@
// Otherwise, we have a function with an argument list that is
// potentially variadic.
SmallVector<TypeRef, 16> ArgTys;
+
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
- if (FTI.ArgInfo[i].TypeInfo == 0)
+ TypeRef ArgTy = TypeRef::getFromOpaquePtr(FTI.ArgInfo[i].TypeInfo);
+ if (ArgTy.isNull())
return TypeRef(); // Error occurred parsing argument type.
- ArgTys.push_back(TypeRef::getFromOpaquePtr(FTI.ArgInfo[i].TypeInfo));
+
+ // Look for 'void'. void is allowed only as a single argument to a
+ // function with no other parameters (C99 6.7.5.3p10). We record
+ // int(void) as a FunctionTypeProto with an empty argument list.
+ if (ArgTy->isVoidType()) {
+ // If this is something like 'float(int, void)', reject it.
+ if (FTI.NumArgs != 1 || FTI.isVariadic) {
+ Diag(DeclType.Loc, diag::err_void_only_param);
+ return TypeRef();
+ }
+ // Reject 'int(void abc)'.
+ if (FTI.ArgInfo[i].Ident) {
+ Diag(FTI.ArgInfo[i].IdentLoc,
+ diag::err_void_param_with_identifier);
+ return TypeRef();
+ }
+
+ // Do not add 'void' to the ArgTys list.
+ break;
+ }
+
+ ArgTys.push_back(ArgTy);
}
- T = Context.getFunctionType(T, &ArgTys[0], FTI.NumArgs, FTI.isVariadic);
+ T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
+ FTI.isVariadic);
}
break;
}
Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39236&r1=39235&r2=39236&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:41:42 2007
@@ -20,6 +20,14 @@
Type::~Type() {}
+/// isVoidType - Helper method to determine if this is the 'void' type.
+bool Type::isVoidType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(getCanonicalType())) {
+ // FIXME: USE ENUMS!
+ return !strcmp(BT->getName(), "void");
+ }
+ return false;
+}
//===----------------------------------------------------------------------===//
// Type Printing
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39236&r1=39235&r2=39236&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:41:42 2007
@@ -1020,28 +1020,6 @@
DS.ClearStorageClassSpecs();
}
-
- // Look for 'void'. void is allowed only as a single argument to a
- // function with no other parameters (C99 6.7.5.3p10).
- if (ParmDecl.getNumTypeObjects() == 0 && // not void*.
- DS.getTypeSpecType() == DeclSpec::TST_void) {
- if (ParmDecl.getIdentifier()) {
- Diag(ParmDecl.getIdentifierLoc(),
- diag::err_void_param_with_identifier);
- ErrorEmitted = true;
- }
- if (!ErrorEmitted &&
- (!ParamInfo.empty() || Tok.getKind() != tok::r_paren)) {
- Diag(DS.getTypeSpecTypeLoc(), diag::err_void_only_param);
- ErrorEmitted = true;
- }
-
- // We know now that we either emitted an error or that the next token
- // is a ')'. Exit this loop with an empty ParamInfo list, instead of
- // adding void explicitly to the list.
- break;
- }
-
// Inform the actions module about the parameter declarator, so it gets
// added to the current scope.
Action::TypeResult ParamTy =
Modified: cfe/cfe/trunk/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaType.cpp?rev=39236&r1=39235&r2=39236&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaType.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaType.cpp Wed Jul 11 11:41:42 2007
@@ -137,12 +137,36 @@
// Otherwise, we have a function with an argument list that is
// potentially variadic.
SmallVector<TypeRef, 16> ArgTys;
+
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
- if (FTI.ArgInfo[i].TypeInfo == 0)
+ TypeRef ArgTy = TypeRef::getFromOpaquePtr(FTI.ArgInfo[i].TypeInfo);
+ if (ArgTy.isNull())
return TypeRef(); // Error occurred parsing argument type.
- ArgTys.push_back(TypeRef::getFromOpaquePtr(FTI.ArgInfo[i].TypeInfo));
+
+ // Look for 'void'. void is allowed only as a single argument to a
+ // function with no other parameters (C99 6.7.5.3p10). We record
+ // int(void) as a FunctionTypeProto with an empty argument list.
+ if (ArgTy->isVoidType()) {
+ // If this is something like 'float(int, void)', reject it.
+ if (FTI.NumArgs != 1 || FTI.isVariadic) {
+ Diag(DeclType.Loc, diag::err_void_only_param);
+ return TypeRef();
+ }
+ // Reject 'int(void abc)'.
+ if (FTI.ArgInfo[i].Ident) {
+ Diag(FTI.ArgInfo[i].IdentLoc,
+ diag::err_void_param_with_identifier);
+ return TypeRef();
+ }
+
+ // Do not add 'void' to the ArgTys list.
+ break;
+ }
+
+ ArgTys.push_back(ArgTy);
}
- T = Context.getFunctionType(T, &ArgTys[0], FTI.NumArgs, FTI.isVariadic);
+ T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
+ FTI.isVariadic);
}
break;
}
Modified: cfe/cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Type.h?rev=39236&r1=39235&r2=39236&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:41:42 2007
@@ -167,6 +167,10 @@
bool isCanonical() const { return CanonicalType == this; }
Type *getCanonicalType() const { return CanonicalType; }
+ /// isVoidType - Helper method to determine if this is the 'void' type.
+ bool isVoidType() const;
+
+
virtual void getAsString(std::string &InnerString) const = 0;
static bool classof(const Type *) { return true; }
@@ -179,6 +183,8 @@
public:
BuiltinType(const char *name) : Type(Builtin, 0), Name(name) {}
+ const char *getName() const { return Name; }
+
virtual void getAsString(std::string &InnerString) const;
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
Added: cfe/cfe/trunk/test/Sema/void_arg.c
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/test/Sema/void_arg.c?rev=39236&view=auto
==============================================================================
--- cfe/cfe/trunk/test/Sema/void_arg.c (added)
+++ cfe/cfe/trunk/test/Sema/void_arg.c Wed Jul 11 11:41:42 2007
@@ -0,0 +1,21 @@
+/* RUN: clang -parse-ast %s 2>&1 | grep '6 diagnostics'
+ */
+
+typedef void Void;
+
+void foo() {
+ int X;
+
+ X = sizeof(int (void a));
+ X = sizeof(int (int, void));
+ X = sizeof(int (void, ...));
+
+ X = sizeof(int (Void a));
+ X = sizeof(int (int, Void));
+ X = sizeof(int (Void, ...));
+
+ // Accept these.
+ X = sizeof(int (void));
+ X = sizeof(int (Void));
+}
+
Propchange: cfe/cfe/trunk/test/Sema/void_arg.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/cfe/trunk/test/Sema/void_arg.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
More information about the cfe-commits
mailing list