Great. We should forewarn our runtime folks about this. Please CC them in radar.
- Fariborz On Jun 18, 2013, at 3:41 PM, Eli Friedman <[email protected]> wrote: > Author: efriedma > Date: Tue Jun 18 17:41:37 2013 > New Revision: 184250 > > URL: http://llvm.org/viewvc/llvm-project?rev=184250&view=rev > Log: > Introduce a new mangling for protocol-qualified ObjC types in C++. This > allows > to provide proper overloading, and also prevents mangling conflicts with > template arguments of protocol-qualified type. > > This is a non-backward-compatible mangling change, but per discussion with > John, the benefits outweigh this cost. > > Fixes <rdar://problem/14074822>. > > > Removed: > cfe/trunk/test/SemaObjCXX/overload-1.mm > Modified: > cfe/trunk/lib/AST/ItaniumMangle.cpp > cfe/trunk/lib/Sema/SemaOverload.cpp > cfe/trunk/test/CodeGenObjCXX/catch-id-type.mm > cfe/trunk/test/CodeGenObjCXX/mangle.mm > cfe/trunk/test/CodeGenObjCXX/rtti.mm > cfe/trunk/test/SemaObjCXX/overload.mm > > Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=184250&r1=184249&r2=184250&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original) > +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Tue Jun 18 17:41:37 2013 > @@ -2164,8 +2164,19 @@ void CXXNameMangler::mangleType(const Ob > } > > void CXXNameMangler::mangleType(const ObjCObjectType *T) { > - // We don't allow overloading by different protocol qualification, > - // so mangling them isn't necessary. > + if (!T->qual_empty()) { > + // Mangle protocol qualifiers. > + SmallString<64> QualStr; > + llvm::raw_svector_ostream QualOS(QualStr); > + QualOS << "objcproto"; > + ObjCObjectType::qual_iterator i = T->qual_begin(), e = T->qual_end(); > + for ( ; i != e; ++i) { > + StringRef name = (*i)->getName(); > + QualOS << name.size() << name; > + } > + QualOS.flush(); > + Out << 'U' << QualStr.size() << QualStr; > + } > mangleType(T->getBaseType()); > } > > > Modified: cfe/trunk/lib/Sema/SemaOverload.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=184250&r1=184249&r2=184250&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) > +++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Jun 18 17:41:37 2013 > @@ -2603,48 +2603,15 @@ void Sema::HandleFunctionTypeMismatch(Pa > > /// FunctionArgTypesAreEqual - This routine checks two function proto types > /// for equality of their argument types. Caller has already checked that > -/// they have same number of arguments. This routine assumes that Objective-C > -/// pointer types which only differ in their protocol qualifiers are equal. > -/// If the parameters are different, ArgPos will have the parameter index > -/// of the first different parameter. > +/// they have same number of arguments. If the parameters are different, > +/// ArgPos will have the parameter index of the first different parameter. > bool Sema::FunctionArgTypesAreEqual(const FunctionProtoType *OldType, > const FunctionProtoType *NewType, > unsigned *ArgPos) { > - if (!getLangOpts().ObjC1) { > - for (FunctionProtoType::arg_type_iterator O = OldType->arg_type_begin(), > - N = NewType->arg_type_begin(), > - E = OldType->arg_type_end(); O && (O != E); ++O, ++N) { > - if (!Context.hasSameType(*O, *N)) { > - if (ArgPos) *ArgPos = O - OldType->arg_type_begin(); > - return false; > - } > - } > - return true; > - } > - > for (FunctionProtoType::arg_type_iterator O = OldType->arg_type_begin(), > N = NewType->arg_type_begin(), > E = OldType->arg_type_end(); O && (O != E); ++O, ++N) { > - QualType ToType = (*O); > - QualType FromType = (*N); > - if (!Context.hasSameType(ToType, FromType)) { > - if (const PointerType *PTTo = ToType->getAs<PointerType>()) { > - if (const PointerType *PTFr = FromType->getAs<PointerType>()) > - if ((PTTo->getPointeeType()->isObjCQualifiedIdType() && > - PTFr->getPointeeType()->isObjCQualifiedIdType()) || > - (PTTo->getPointeeType()->isObjCQualifiedClassType() && > - PTFr->getPointeeType()->isObjCQualifiedClassType())) > - continue; > - } > - else if (const ObjCObjectPointerType *PTTo = > - ToType->getAs<ObjCObjectPointerType>()) { > - if (const ObjCObjectPointerType *PTFr = > - FromType->getAs<ObjCObjectPointerType>()) > - if (Context.hasSameUnqualifiedType( > - PTTo->getObjectType()->getBaseType(), > - PTFr->getObjectType()->getBaseType())) > - continue; > - } > + if (!Context.hasSameType(*O, *N)) { > if (ArgPos) *ArgPos = O - OldType->arg_type_begin(); > return false; > } > > Modified: cfe/trunk/test/CodeGenObjCXX/catch-id-type.mm > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/catch-id-type.mm?rev=184250&r1=184249&r2=184250&view=diff > ============================================================================== > --- cfe/trunk/test/CodeGenObjCXX/catch-id-type.mm (original) > +++ cfe/trunk/test/CodeGenObjCXX/catch-id-type.mm Tue Jun 18 17:41:37 2013 > @@ -31,7 +31,7 @@ id FUNC() { > catch( id error ) > { > // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 > (...)* @__gxx_personality_v0 to i8*) > - // CHECK-NEXT: catch i8* bitcast ({ i8*, i8*, i32, i8* }* > @_ZTIP4INTF to i8*) > + // CHECK-NEXT: catch i8* bitcast ({ i8*, i8*, i32, i8* }* > @_ZTIPU11objcproto1P4INTF to i8*) > // CHECK-NEXT: catch i8* bitcast ({ i8*, i8*, i32, i8* }* > @_ZTIP11objc_object to i8*) > // CHECK-NEXT: catch i8* bitcast ({ i8*, i8*, i32, i8* }* > @_ZTIP10objc_class to i8*) > error = error; > > Modified: cfe/trunk/test/CodeGenObjCXX/mangle.mm > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/mangle.mm?rev=184250&r1=184249&r2=184250&view=diff > ============================================================================== > --- cfe/trunk/test/CodeGenObjCXX/mangle.mm (original) > +++ cfe/trunk/test/CodeGenObjCXX/mangle.mm Tue Jun 18 17:41:37 2013 > @@ -78,3 +78,23 @@ void test2(Test2 *t) { > Test2Template<decltype(t.dimension)> t1; > Test2Template<decltype(t->alt_axis)> t2; > } > + > +@protocol P; > +void overload1(A<P>*) {} > +// CHECK: define void @_Z9overload1PU11objcproto1P1A > +void overload1(const A<P>*) {} > +// CHECK: define void @_Z9overload1PKU11objcproto1P1A > +void overload1(A<P>**) {} > +// CHECK: define void @_Z9overload1PPU11objcproto1P1A > +void overload1(A<P>*const*) {} > +// CHECK: define void @_Z9overload1PKPU11objcproto1P1A > +void overload1(A<P>***) {} > +// CHECK: define void @_Z9overload1PPPU11objcproto1P1A > +void overload1(void (f)(A<P>*)) {} > +// CHECK: define void @_Z9overload1PFvPU11objcproto1P1AE > + > +template<typename T> struct X { void f(); }; > +template<> void X<A*>::f() {} > +// CHECK: define void @_ZN1XIP1AE1fEv > +template<> void X<A<P>*>::f() {} > +// CHECK: define void @_ZN1XIPU11objcproto1P1AE1fEv > > Modified: cfe/trunk/test/CodeGenObjCXX/rtti.mm > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/rtti.mm?rev=184250&r1=184249&r2=184250&view=diff > ============================================================================== > --- cfe/trunk/test/CodeGenObjCXX/rtti.mm (original) > +++ cfe/trunk/test/CodeGenObjCXX/rtti.mm Tue Jun 18 17:41:37 2013 > @@ -38,14 +38,14 @@ int main() { > const std::type_info &t5 = typeid(c); > const std::type_info &t6 = typeid(*c); > > - // CHECK: store {{.*}} @_ZTIP11objc_object > - // CHECK: store {{.*}} @_ZTI11objc_object > + // CHECK: store {{.*}} @_ZTIPU11objcproto1P11objc_object > + // CHECK: store {{.*}} @_ZTIU11objcproto1P11objc_object > id<P> i2 = 0; > const std::type_info &t7 = typeid(i2); > const std::type_info &t8 = typeid(*i2); > > - // CHECK: store {{.*}} @_ZTIP10objc_class > - // CHECK: store {{.*}} @_ZTI10objc_class > + // CHECK: store {{.*}} @_ZTIPU11objcproto1P10objc_class > + // CHECK: store {{.*}} @_ZTIU11objcproto1P10objc_class > Class<P> c2 = 0; > const std::type_info &t9 = typeid(c2); > const std::type_info &t10 = typeid(*c2); > > Removed: cfe/trunk/test/SemaObjCXX/overload-1.mm > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/overload-1.mm?rev=184249&view=auto > ============================================================================== > --- cfe/trunk/test/SemaObjCXX/overload-1.mm (original) > +++ cfe/trunk/test/SemaObjCXX/overload-1.mm (removed) > @@ -1,25 +0,0 @@ > -// RUN: %clang_cc1 -fsyntax-only -verify %s > - > -@protocol Proto1 @end > - > -@protocol Proto2 @end > - > -void f(id<Proto1> *) { } // expected-note {{previous definition > is here}} > - > -void f(id<Proto1, Proto2> *) { } // expected-error {{conflicting types > for 'f'}} > - > -void f(Class<Proto1> *) { } // expected-note {{previous definition > is here}} > - > -void f(Class<Proto1, Proto2> *) { } // expected-error {{conflicting types > for 'f'}} > - > -@interface I @end > - > -void f(I<Proto1> *) { } // expected-note {{previous definition > is here}} > - > -void f(I<Proto1, Proto2> *) { } // expected-error {{conflicting > types for 'f'}} > - > -@interface I1 @end > - > -void f1(I<Proto1> *) { } > - > -void f1(I1<Proto1, Proto2> *) { } > > Modified: cfe/trunk/test/SemaObjCXX/overload.mm > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/overload.mm?rev=184250&r1=184249&r2=184250&view=diff > ============================================================================== > --- cfe/trunk/test/SemaObjCXX/overload.mm (original) > +++ cfe/trunk/test/SemaObjCXX/overload.mm Tue Jun 18 17:41:37 2013 > @@ -60,9 +60,8 @@ void test2(A** ap) { > bp = ap; // expected-warning{{incompatible pointer types assigning to 'B > **' from 'A **'}} > } > > -// FIXME: we should either allow overloading here or give a better diagnostic > -int& cv(A*); // expected-note {{previous declaration}} expected-note 2 {{not > viable}} > -float& cv(const A*); // expected-error {{cannot be overloaded}} > +int& cv(A*); > +float& cv(const A*); > > int& cv2(void*); > float& cv2(const void*); > @@ -70,22 +69,20 @@ float& cv2(const void*); > void cv_test(A* a, B* b, const A* ac, const B* bc) { > int &i1 = cv(a); > int &i2 = cv(b); > - float &f1 = cv(ac); // expected-error {{no matching function}} > - float &f2 = cv(bc); // expected-error {{no matching function}} > + float &f1 = cv(ac); > + float &f2 = cv(bc); > int& i3 = cv2(a); > float& f3 = cv2(ac); > } > > -// We agree with GCC that these can't be overloaded. > -int& qualid(id<P0>); // expected-note {{previous declaration}} expected-note > {{not viable}} > -float& qualid(id<P1>); // expected-error {{cannot be overloaded}} > +int& qualid(id<P0>); > +float& qualid(id<P1>); > > void qualid_test(A *a, B *b, C *c) { > int& i1 = qualid(a); > int& i2 = qualid(b); > > - // This doesn't work only because the overload was rejected above. > - float& f1 = qualid(c); // expected-error {{no matching function}} > + float& f1 = qualid(c); > > id<P0> p1 = 0; > p1 = 0; > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
