aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Type.h2
-rw-r--r--lib/AST/Type.cpp18
-rw-r--r--lib/Sema/SemaType.cpp6
-rw-r--r--test/SemaObjC/legacy-objc-types.m20
-rw-r--r--test/SemaObjCXX/legacy-objc-types.mm20
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);
+