This was originaly r183614 which was reverted in r183616.

The fix here was to change InitializeParameter() to use
ASTContext::getSignatureParameterType() to avoid errors when trying to
initialize array parameters with normal pointers.

I had to change some objc tests which were getting extra qualifiers in
diagnostics, but they looked coincidental, not intentional.

http://llvm-reviews.chandlerc.com/D957

Files:
  include/clang/Sema/Initialization.h
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaType.cpp
  test/Index/print-type.c
  test/Index/print-type.cpp
  test/Sema/function-redecl.c
  test/Sema/function.c
  test/SemaObjC/objc-literal-nsnumber.m
  test/SemaObjCXX/arc-type-conversion.mm
  test/SemaObjCXX/literals.mm
Index: include/clang/Sema/Initialization.h
===================================================================
--- include/clang/Sema/Initialization.h
+++ include/clang/Sema/Initialization.h
@@ -197,8 +197,7 @@
 
     InitializedEntity Entity;
     Entity.Kind = EK_Parameter;
-    Entity.Type =
-      Context.getVariableArrayDecayedType(Type.getUnqualifiedType());
+    Entity.Type = Context.getSignatureParameterType(Type);
     Entity.Parent = 0;
     Entity.Parameter
       = (static_cast<uintptr_t>(Consumed) | reinterpret_cast<uintptr_t>(Parm));
@@ -212,7 +211,7 @@
                                                bool Consumed) {
     InitializedEntity Entity;
     Entity.Kind = EK_Parameter;
-    Entity.Type = Context.getVariableArrayDecayedType(Type);
+    Entity.Type = Context.getSignatureParameterType(Type);
     Entity.Parent = 0;
     Entity.Parameter = (Consumed);
     return Entity;
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -5897,20 +5897,40 @@
       << DeclSpec::getSpecifierName(TSCS);
 
   // Do not allow returning a objc interface by-value.
-  if (R->getAs<FunctionType>()->getResultType()->isObjCObjectType()) {
+  bool NeedsAdjustment = false;
+  const FunctionType *FT = R->castAs<FunctionType>();
+  QualType ResultTy = FT->getResultType();
+  if (ResultTy->isObjCObjectType()) {
     Diag(D.getIdentifierLoc(),
-         diag::err_object_cannot_be_passed_returned_by_value) << 0
-    << R->getAs<FunctionType>()->getResultType()
-    << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*");
+         diag::err_object_cannot_be_passed_returned_by_value) << 0 << ResultTy
+        << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*");
+    ResultTy = Context.getObjCObjectPointerType(ResultTy);
+    NeedsAdjustment = true;
+  }
 
-    QualType T = R->getAs<FunctionType>()->getResultType();
-    T = Context.getObjCObjectPointerType(T);
-    if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(R)) {
+  // Adjust parameter types from the type as written.
+  SmallVector<QualType, 16> AdjustedParms;
+  const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT);
+  if (FPT) {
+    for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(),
+                                              E = FPT->arg_type_end();
+         I != E; ++I) {
+      AdjustedParms.push_back(Context.getAdjustedParameterType(*I));
+      NeedsAdjustment |= AdjustedParms.back() != *I;
+    }
+  }
+
+  // Skip the type recreation if it isn't needed, for performance and to avoid
+  // prematurely desugaring things like typedefs and __typeofs.
+  if (NeedsAdjustment) {
+    if (FPT) {
       FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
-      R = Context.getFunctionType(T, FPT->getArgTypes(), EPI);
+      R = Context.getFunctionType(ResultTy, AdjustedParms, EPI);
+    } else {
+      assert(isa<FunctionNoProtoType>(FT));
+      FunctionType::ExtInfo EI = FT->getExtInfo();
+      R = Context.getFunctionNoProtoType(ResultTy, EI);
     }
-    else if (isa<FunctionNoProtoType>(R))
-      R = Context.getFunctionNoProtoType(T);
   }
 
   bool isFriend = false;
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -1674,7 +1674,7 @@
   bool Invalid = false;
   for (unsigned Idx = 0, Cnt = ParamTypes.size(); Idx < Cnt; ++Idx) {
     // FIXME: Loc is too inprecise here, should use proper locations for args.
-    QualType ParamType = Context.getAdjustedParameterType(ParamTypes[Idx]);
+    QualType ParamType = ParamTypes[Idx];
     if (ParamType->isVoidType()) {
       Diag(Loc, diag::err_param_with_void_type);
       Invalid = true;
@@ -2798,13 +2798,10 @@
 
         for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
           ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
-          QualType ArgTy = Param->getType();
+          // If this is an array or function type, callers will adjust it later.
+          QualType ArgTy = Param->getTypeSourceInfo()->getType();
           assert(!ArgTy.isNull() && "Couldn't parse type?");
 
-          // Adjust the parameter type.
-          assert((ArgTy == Context.getAdjustedParameterType(ArgTy)) &&
-                 "Unadjusted type?");
-
           // 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 FunctionProtoType with an empty argument list.
Index: test/Index/print-type.c
===================================================================
--- test/Index/print-type.c
+++ test/Index/print-type.c
@@ -11,7 +11,7 @@
 typedef int __attribute__((vector_size(16))) int4_t;
 
 // RUN: c-index-test -test-print-type %s | FileCheck %s
-// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int [5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0]
+// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int [5], void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int [5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0]
 // CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1]
 // CHECK: ParmDecl=x:3:22 (Definition) [type=char *] [typekind=Pointer] [isPOD=1]
 // CHECK: ParmDecl=z:3:33 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
Index: test/Index/print-type.cpp
===================================================================
--- test/Index/print-type.cpp
+++ test/Index/print-type.cpp
@@ -62,5 +62,5 @@
 // CHECK: TypedefDecl=ArrayType:20:15 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1]
 // CHECK: FunctionTemplate=tbar:27:3 [type=T (int)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
 // CHECK: TemplateTypeParameter=T:26:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: FunctionTemplate=tbar:30:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
+// CHECK: FunctionTemplate=tbar:30:3 [type=T (int [5])] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
 // CHECK: ParmDecl=:30:11 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1]
Index: test/Sema/function-redecl.c
===================================================================
--- test/Sema/function-redecl.c
+++ test/Sema/function-redecl.c
@@ -115,6 +115,11 @@
 extern __typeof (i0) i1;
 extern __typeof (i1) i1;
 
+// Try __typeof with a parameter that needs adjustment.
+void j0 (int a0[1], ...);
+extern __typeof (j0) j1;
+extern __typeof (j1) j1;
+
 typedef int a();
 typedef int a2(int*);
 a x;
Index: test/Sema/function.c
===================================================================
--- test/Sema/function.c
+++ test/Sema/function.c
@@ -103,3 +103,8 @@
   }
   return x + 3;
 }
+
+void t22(void (*take_array(int array[1]))) {
+  int arr[1];
+  take_array(arr);
+}
Index: test/SemaObjC/objc-literal-nsnumber.m
===================================================================
--- test/SemaObjC/objc-literal-nsnumber.m
+++ test/SemaObjC/objc-literal-nsnumber.m
@@ -68,11 +68,11 @@
   NSDictionary *dictionary = @{@"name" : NSUserName(),
                                @"date" : [NSDate date],
                                @"name2" : @"other",
-                               NSObject.nsobject : @"nsobject" }; // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'const id<NSCopying>'}}
+                               NSObject.nsobject : @"nsobject" }; // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'id<NSCopying>'}}
   NSDictionary *dictionary2 = @{@"name" : Int()}; // expected-error {{collection element of type 'int' is not an Objective-C object}}
 
   NSObject *o;
-  NSDictionary *dictionary3 = @{o : o, // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'const id<NSCopying>'}}
+  NSDictionary *dictionary3 = @{o : o, // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'id<NSCopying>'}}
                                @"date" : [NSDate date] };
   return dictionary3;
 }
Index: test/SemaObjCXX/arc-type-conversion.mm
===================================================================
--- test/SemaObjCXX/arc-type-conversion.mm
+++ test/SemaObjCXX/arc-type-conversion.mm
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -fblocks %s
 // rdar://8843600
 
-void * cvt(id arg) // expected-note{{candidate function not viable: cannot convert argument of incomplete type 'void *' to '__strong id'}}
+void * cvt(id arg) // expected-note{{candidate function not viable: cannot convert argument of incomplete type 'void *' to 'id'}}
 {
   void* voidp_val;
   (void)(int*)arg; // expected-error {{cast of an Objective-C pointer to 'int *' is disallowed with ARC}}
Index: test/SemaObjCXX/literals.mm
===================================================================
--- test/SemaObjCXX/literals.mm
+++ test/SemaObjCXX/literals.mm
@@ -121,7 +121,7 @@
   };
 
   id dict2 = @{ 
-    object : @"object" // expected-error{{cannot initialize a parameter of type 'const id<NSCopying>' with an rvalue of type 'NSObject *'}}
+    object : @"object" // expected-error{{cannot initialize a parameter of type 'id<NSCopying>' with an rvalue of type 'NSObject *'}}
   }; 
 }
 
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to