[cfe-commits] r85068 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/DeclSpec.h lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaType.cpp test/SemaCXX/new-delete.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Sun Oct 25 14:45:37 PDT 2009


Author: cornedbee
Date: Sun Oct 25 16:45:37 2009
New Revision: 85068

URL: http://llvm.org/viewvc/llvm-project?rev=85068&view=rev
Log:
Remove the Skip parameter from GetTypeForDeclarator and dependents. Take the opportunity to improve an error message and fix PR4498.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Parse/DeclSpec.h
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaCXX/new-delete.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=85068&r1=85067&r2=85068&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Oct 25 16:45:37 2009
@@ -1661,7 +1661,9 @@
 def err_new_incomplete_type : Error<
   "allocation of incomplete type %0">;
 def err_new_array_nonconst : Error<
-  "only the first dimension of an allocated array may be non-const">;
+  "only the first dimension of an allocated array may have dynamic size">;
+def err_new_paren_array_nonconst : Error<
+  "when type is in parentheses, array cannot have dynamic size">;
 def err_array_size_not_integral : Error<
   "array size expression must have integral or enumerated type, not %0">;
 def err_new_uninitialized_const : Error<

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=85068&r1=85067&r2=85068&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Sun Oct 25 16:45:37 2009
@@ -1069,6 +1069,13 @@
     return DeclTypeInfo[i];
   }
 
+  void DropFirstTypeObject()
+  {
+    assert(!DeclTypeInfo.empty() && "No type chunks to drop.");
+    DeclTypeInfo.front().destroy();
+    DeclTypeInfo.erase(DeclTypeInfo.begin());
+  }
+
   /// isFunctionDeclarator - Once this declarator is fully parsed and formed,
   /// this method returns true if the identifier is a function declarator.
   bool isFunctionDeclarator() const {

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=85068&r1=85067&r2=85068&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sun Oct 25 16:45:37 2009
@@ -468,9 +468,8 @@
                                  SourceLocation Loc, DeclarationName Entity);
   QualType GetTypeForDeclarator(Declarator &D, Scope *S,
                                 DeclaratorInfo **DInfo = 0,
-                                unsigned Skip = 0, TagDecl **OwnedDecl = 0);
-  DeclaratorInfo *GetDeclaratorInfoForDeclarator(Declarator &D, QualType T,
-                                                 unsigned Skip);
+                                TagDecl **OwnedDecl = 0);
+  DeclaratorInfo *GetDeclaratorInfoForDeclarator(Declarator &D, QualType T);
   /// \brief Create a LocInfoType to hold the given QualType and DeclaratorInfo.
   QualType CreateLocInfoType(QualType T, DeclaratorInfo *DInfo);
   DeclarationName GetNameForDeclarator(Declarator &D);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=85068&r1=85067&r2=85068&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Oct 25 16:45:37 2009
@@ -3619,8 +3619,7 @@
 
   DeclaratorInfo *DInfo = 0;
   TagDecl *OwnedDecl = 0;
-  QualType parmDeclType = GetTypeForDeclarator(D, S, &DInfo, /*Skip=*/0,
-                                               &OwnedDecl);
+  QualType parmDeclType = GetTypeForDeclarator(D, S, &DInfo, &OwnedDecl);
 
   if (getLangOptions().CPlusPlus && OwnedDecl && OwnedDecl->isDefinition()) {
     // C++ [dcl.fct]p6:

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=85068&r1=85067&r2=85068&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun Oct 25 16:45:37 2009
@@ -312,7 +312,6 @@
                   MultiExprArg ConstructorArgs,
                   SourceLocation ConstructorRParen) {
   Expr *ArraySize = 0;
-  unsigned Skip = 0;
   // If the specified type is an array, unwrap it and save the expression.
   if (D.getNumTypeObjects() > 0 &&
       D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
@@ -323,14 +322,25 @@
     if (!Chunk.Arr.NumElts)
       return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size)
         << D.getSourceRange());
+
+    if (ParenTypeId) {
+      // Can't have dynamic array size when the type-id is in parentheses.
+      Expr *NumElts = (Expr *)Chunk.Arr.NumElts;
+      if (!NumElts->isTypeDependent() && !NumElts->isValueDependent() &&
+          !NumElts->isIntegerConstantExpr(Context)) {
+        Diag(D.getTypeObject(0).Loc, diag::err_new_paren_array_nonconst)
+          << NumElts->getSourceRange();
+        return ExprError();
+      }
+    }
+
     ArraySize = static_cast<Expr*>(Chunk.Arr.NumElts);
-    Skip = 1;
+    D.DropFirstTypeObject();
   }
 
   // Every dimension shall be of constant size.
-  if (D.getNumTypeObjects() > 0 && 
-      D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
-    for (unsigned I = 1, N = D.getNumTypeObjects(); I < N; ++I) {
+  if (ArraySize) {
+    for (unsigned I = 0, N = D.getNumTypeObjects(); I < N; ++I) {
       if (D.getTypeObject(I).Kind != DeclaratorChunk::Array)
         break;
 
@@ -345,10 +355,10 @@
       }
     }
   }
-  
+
   //FIXME: Store DeclaratorInfo in CXXNew expression.
   DeclaratorInfo *DInfo = 0;
-  QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo, Skip);
+  QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo);
   if (D.isInvalidType())
     return ExprError();
 
@@ -935,7 +945,7 @@
   // FIXME: Store DeclaratorInfo in the expression.
   DeclaratorInfo *DInfo = 0;
   TagDecl *OwnedTag = 0;
-  QualType Ty = GetTypeForDeclarator(D, S, &DInfo, /*Skip=*/0, &OwnedTag);
+  QualType Ty = GetTypeForDeclarator(D, S, &DInfo, &OwnedTag);
 
   if (Ty->isFunctionType()) { // The declarator shall not specify a function...
     // We exit without creating a CXXConditionDeclExpr because a FunctionDecl

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=85068&r1=85067&r2=85068&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Sun Oct 25 16:45:37 2009
@@ -52,9 +52,9 @@
 
 /// isOmittedBlockReturnType - Return true if this declarator is missing a
 /// return type because this is a omitted return type on a block literal. 
-static bool isOmittedBlockReturnType(const Declarator &D, unsigned Skip) {
+static bool isOmittedBlockReturnType(const Declarator &D) {
   if (D.getContext() != Declarator::BlockLiteralContext ||
-      Skip != 0 || D.getDeclSpec().hasTypeSpecifier())
+      D.getDeclSpec().hasTypeSpecifier())
     return false;
   
   if (D.getNumTypeObjects() == 0)
@@ -72,8 +72,7 @@
 /// \param D  the declarator containing the declaration specifier.
 /// \returns The type described by the declaration specifiers.  This function
 /// never returns null.
-static QualType ConvertDeclSpecToType(Declarator &TheDeclarator, unsigned Skip,
-                                      Sema &TheSema) {
+static QualType ConvertDeclSpecToType(Declarator &TheDeclarator, Sema &TheSema){
   // FIXME: Should move the logic from DeclSpec::Finish to here for validity
   // checking.
   const DeclSpec &DS = TheDeclarator.getDeclSpec();
@@ -135,7 +134,7 @@
     
     // If this is a missing declspec in a block literal return context, then it
     // is inferred from the return statements inside the block.
-    if (isOmittedBlockReturnType(TheDeclarator, Skip)) {
+    if (isOmittedBlockReturnType(TheDeclarator)) {
       Result = Context.DependentTy;
       break;
     }
@@ -852,14 +851,13 @@
 }
 
 /// GetTypeForDeclarator - Convert the type for the specified
-/// declarator to Type instances. Skip the outermost Skip type
-/// objects.
+/// declarator to Type instances.
 ///
 /// If OwnedDecl is non-NULL, and this declarator's decl-specifier-seq
 /// owns the declaration of a type (e.g., the definition of a struct
 /// type), then *OwnedDecl will receive the owned declaration.
 QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
-                                    DeclaratorInfo **DInfo, unsigned Skip,
+                                    DeclaratorInfo **DInfo,
                                     TagDecl **OwnedDecl) {
   // Determine the type of the declarator. Not all forms of declarator
   // have a type.
@@ -870,7 +868,7 @@
   case Declarator::DK_Normal:
   case Declarator::DK_Operator:
   case Declarator::DK_TemplateId:
-    T = ConvertDeclSpecToType(D, Skip, *this);
+    T = ConvertDeclSpecToType(D, *this);
     
     if (!D.isInvalidType() && OwnedDecl && D.getDeclSpec().isTypeSpecOwned())
       *OwnedDecl = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
@@ -937,8 +935,8 @@
   // Walk the DeclTypeInfo, building the recursive type as we go.
   // DeclTypeInfos are ordered from the identifier out, which is
   // opposite of what we want :).
-  for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) {
-    DeclaratorChunk &DeclType = D.getTypeObject(e-i-1+Skip);
+  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
+    DeclaratorChunk &DeclType = D.getTypeObject(e-i-1);
     switch (DeclType.Kind) {
     default: assert(0 && "Unknown decltype!");
     case DeclaratorChunk::BlockPointer:
@@ -1235,7 +1233,7 @@
     if (D.isInvalidType())
       *DInfo = 0;
     else
-      *DInfo = GetDeclaratorInfoForDeclarator(D, T, Skip);
+      *DInfo = GetDeclaratorInfoForDeclarator(D, T);
   }
 
   return T;
@@ -1377,11 +1375,11 @@
 ///
 /// \param T QualType referring to the type as written in source code.
 DeclaratorInfo *
-Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip) {
+Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T) {
   DeclaratorInfo *DInfo = Context.CreateDeclaratorInfo(T);
   UnqualTypeLoc CurrTL = DInfo->getTypeLoc().getUnqualifiedLoc();
 
-  for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) {
+  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
     DeclaratorLocFiller(D.getTypeObject(i)).Visit(CurrTL);
     CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
   }
@@ -1474,7 +1472,7 @@
 
   DeclaratorInfo *DInfo = 0;
   TagDecl *OwnedTag = 0;
-  QualType T = GetTypeForDeclarator(D, S, &DInfo, /*Skip=*/0, &OwnedTag);
+  QualType T = GetTypeForDeclarator(D, S, &DInfo, &OwnedTag);
   if (D.isInvalidType())
     return true;
 

Modified: cfe/trunk/test/SemaCXX/new-delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/new-delete.cpp?rev=85068&r1=85067&r2=85068&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/new-delete.cpp (original)
+++ cfe/trunk/test/SemaCXX/new-delete.cpp Sun Oct 25 16:45:37 2009
@@ -58,6 +58,7 @@
   (void)new int[1.1]; // expected-error {{array size expression must have integral or enumerated type, not 'double'}}
   (void)new int[1][i]; // expected-error {{only the first dimension}}
   (void)new (int[1][i]); // expected-error {{only the first dimension}}
+  (void)new (int[i]); // expected-error {{when type is in parentheses}}
   (void)new int(*(S*)0); // expected-error {{incompatible type initializing}}
   (void)new int(1, 2); // expected-error {{initializer of a builtin type can only take one argument}}
   (void)new S(1); // expected-error {{no matching constructor}}





More information about the cfe-commits mailing list