[cfe-commits] r39235 - in /cfe/cfe/trunk: AST/Type.cpp Parse/ParseDecl.cpp include/clang/Basic/DiagnosticKinds.def
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:41:41 PDT 2007
Author: sabre
Date: Wed Jul 11 11:41:41 2007
New Revision: 39235
URL: http://llvm.org/viewvc/llvm-project?rev=39235&view=rev
Log:
Handle void correctly in the argument list for a function. For:
X = sizeof(int (void a));
X = sizeof(int (int, void));
X = sizeof(int (void, ...));
We now emit:
t.c:6:24: error: void argument may not have a name
X = sizeof(int (void a));
^
t.c:7:24: error: 'void' must be the first and only parameter if specified
X = sizeof(int (int, void));
^
t.c:8:19: error: 'void' must be the first and only parameter if specified
X = sizeof(int (void, ...));
^
And we pretty print this correctly (even though void isn't stored in the
arg list of the function type):
X = sizeof(int (void));
However, this approach will have to change to handle typedefs of void.
Modified:
cfe/cfe/trunk/AST/Type.cpp
cfe/cfe/trunk/Parse/ParseDecl.cpp
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39235&r1=39234&r2=39235&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:41:41 2007
@@ -125,6 +125,9 @@
if (getNumArgs())
S += ", ";
S += "...";
+ } else if (getNumArgs() == 0) {
+ // Do not emit int() if we have a proto, emit 'int(void)'.
+ S += "void";
}
S += ")";
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39235&r1=39234&r2=39235&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:41:41 2007
@@ -1021,9 +1021,26 @@
}
- // FIXME: If this is 'void', validate it's ok, then break out of the loop
- // it must be 'int foo(void)'. Break from loop to prevent trouble with
- // things like 'int foo(void, ...)' or 'int foo(void, int)'.
+ // 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.
@@ -1049,9 +1066,10 @@
}
// Remember that we parsed a function type, and remember the attributes.
- D.AddTypeInfo(DeclaratorChunk::getFunction(HasPrototype, IsVariadic,
- &ParamInfo[0], ParamInfo.size(),
- StartLoc));
+ if (!ErrorEmitted)
+ D.AddTypeInfo(DeclaratorChunk::getFunction(HasPrototype, IsVariadic,
+ &ParamInfo[0], ParamInfo.size(),
+ StartLoc));
// If we have the closing ')', eat it and we're done.
if (Tok.getKind() == tok::r_paren) {
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39235&r1=39234&r2=39235&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:41:41 2007
@@ -393,6 +393,11 @@
DIAG(err_invalid_storage_class_in_func_decl, ERROR,
"invalid storage class specifier in function declarator")
+DIAG(err_void_param_with_identifier, ERROR,
+ "void argument may not have a name")
+DIAG(err_void_only_param, ERROR,
+ "'void' must be the first and only parameter if specified")
+
DIAG(err_unexpected_typedef, ERROR,
"unexpected type name '%s': expected expression")
DIAG(err_undeclared_var_use, ERROR,
More information about the cfe-commits
mailing list