[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