[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