diff options
-rw-r--r-- | include/clang/AST/Type.h | 2 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 6 | ||||
-rw-r--r-- | test/SemaObjC/legacy-objc-types.m | 20 | ||||
-rw-r--r-- | test/SemaObjCXX/legacy-objc-types.mm | 20 |
5 files changed, 65 insertions, 1 deletions
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 92e62a58d4..e643843a20 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -932,7 +932,9 @@ public: bool isObjCQualifiedClassType() const; // Class<foo> bool isObjCObjectOrInterfaceType() const; bool isObjCIdType() const; // id + bool isLegacyObjCIdType(ASTContext &) const; // struct_object * bool isObjCClassType() const; // Class + bool isLegacyObjCClassType(ASTContext &) const; // struct_class * bool isObjCSelType() const; // Class bool isObjCBuiltinType() const; // 'id' or 'Class' bool isTemplateTypeParmType() const; // C++ template type parameter diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 8e6aa23618..114c9ac7df 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -470,6 +470,24 @@ bool Type::isIntegralOrEnumerationType() const { return false; } +bool Type::isLegacyObjCIdType(ASTContext &Ctx) const { + if (const PointerType *PTTo = getAs<PointerType>()) { + QualType PointeeTy = PTTo->getPointeeType(); + if (const RecordType *RTy = PointeeTy->getAs<RecordType>()) + return RTy->getDecl()->getIdentifier() == &Ctx.Idents.get("objc_object"); + } + return false; +} + +bool Type::isLegacyObjCClassType(ASTContext &Ctx) const { + if (const PointerType *PTTo = getAs<PointerType>()) { + QualType PointeeTy = PTTo->getPointeeType(); + if (const RecordType *RTy = PointeeTy->getAs<RecordType>()) + return RTy->getDecl()->getIdentifier() == &Ctx.Idents.get("objc_class"); + } + return false; +} + bool Type::isEnumeralType() const { if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) return TT->getDecl()->isEnum(); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index aa30b5c2da..06d8b3d4f6 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1274,8 +1274,12 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S, if (BTy->getKind() == BuiltinType::Float) ArgTy = Context.DoubleTy; } + } else if (getLangOptions().ObjC1) { + if (ArgTy->isLegacyObjCIdType(Context)) + ArgTy = Context.getObjCIdType(); + else if (ArgTy->isLegacyObjCClassType(Context)) + ArgTy = Context.getObjCClassType(); } - ArgTys.push_back(ArgTy); } diff --git a/test/SemaObjC/legacy-objc-types.m b/test/SemaObjC/legacy-objc-types.m new file mode 100644 index 0000000000..dbe32e64a2 --- /dev/null +++ b/test/SemaObjC/legacy-objc-types.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar:// 8400356 + +struct objc_object; + +void f(id ptr) { } // expected-note {{previous definition is here}} +void f(struct objc_object* ptr) { } // expected-error {{redefinition of 'f'}} + +struct objc_class; + +void g(Class ptr) {} // expected-note {{previous definition is here}} +void g(struct objc_class* ptr) { } // expected-error {{redefinition of 'g'}} + +void h(Class ptr, struct objc_object* ptr1) {} // expected-note {{previous definition is here}} +void h(struct objc_class* ptr, id ptr1) {} // expected-error {{redefinition of 'h'}} + +void i(Class ptr, struct objc_object* ptr1); +void i(struct objc_class* ptr, id ptr1) {} +void i(struct objc_class* ptr, struct objc_object* ptr1); + diff --git a/test/SemaObjCXX/legacy-objc-types.mm b/test/SemaObjCXX/legacy-objc-types.mm new file mode 100644 index 0000000000..56ee97fca2 --- /dev/null +++ b/test/SemaObjCXX/legacy-objc-types.mm @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar:// 8400356 + +struct objc_object; + +void f(id ptr) { } // expected-note {{previous definition is here}} +void f(objc_object* ptr) { } // expected-error {{redefinition of 'f'}} + +struct objc_class; + +void g(Class ptr) {} // expected-note {{previous definition is here}} +void g(objc_class* ptr) { } // expected-error {{redefinition of 'g'}} + +void h(Class ptr, objc_object* ptr1) {} // expected-note {{previous definition is here}} +void h(objc_class* ptr, id ptr1) {} // expected-error {{redefinition of 'h'}} + +void i(Class ptr, objc_object* ptr1); +void i(objc_class* ptr, id ptr1) {} +void i(objc_class* ptr, objc_object* ptr1); + |