* resolve anonymous external objcclass definitions to the real type also when

a) defining a child class
     b) checking for type conversion compatibility

git-svn-id: trunk@16013 -
This commit is contained in:
Jonas Maebe 2010-09-19 16:05:32 +00:00
parent f88efa2072
commit 1c9fed7ae3
5 changed files with 58 additions and 9 deletions

1
.gitattributes vendored
View File

@ -9401,6 +9401,7 @@ tests/test/tobjc35d.pp svneol=native#text/plain
tests/test/tobjc35f.pp svneol=native#text/plain
tests/test/tobjc35g.pp svneol=native#text/plain
tests/test/tobjc35h.pp svneol=native#text/plain
tests/test/tobjc35i.pp svneol=native#text/plain
tests/test/tobjc4.pp svneol=native#text/plain
tests/test/tobjc4a.pp svneol=native#text/plain
tests/test/tobjc5.pp svneol=native#text/plain

View File

@ -1245,8 +1245,16 @@ implementation
objectdef :
begin
{ object pascal objects }
{ Objective-C classes (handle anonymous externals) }
if (def_from.typ=objectdef) and
(find_real_objcclass_definition(tobjectdef(def_from),false) =
find_real_objcclass_definition(tobjectdef(def_to),false)) then
begin
doconv:=tc_equal;
eq:=te_equal;
end
{ object pascal objects }
else if (def_from.typ=objectdef) and
(tobjectdef(def_from).is_related(tobjectdef(def_to))) then
begin
doconv:=tc_equal;

View File

@ -427,7 +427,9 @@ implementation
end
else
Message(parser_e_mix_of_classes_and_objects);
end;
end
else
childof:=find_real_objcclass_definition(childof,true);
odt_objcprotocol:
begin
if not(is_objcprotocol(childof)) then

View File

@ -223,6 +223,7 @@ interface
{*** Object Helpers ***}
function search_default_property(pd : tobjectdef) : tpropertysym;
function find_real_objcclass_definition(pd: tobjectdef; erroronfailure: boolean): tobjectdef;
{*** Macro Helpers ***}
{If called initially, the following procedures manipulate macros in }
@ -1963,13 +1964,19 @@ implementation
end;
function find_real_objcclass_definition(pd: tobjectdef): tobjectdef;
function find_real_objcclass_definition(pd: tobjectdef; erroronfailure: boolean): tobjectdef;
var
hashedid : THashedIDString;
stackitem : psymtablestackitem;
srsymtable : tsymtable;
srsym : tsym;
begin
{ not a formal definition -> return it }
if not(oo_is_formal in pd.objectoptions) then
begin
result:=pd;
exit;
end;
hashedid.id:=pd.typesym.name;
stackitem:=symtablestack.stack;
while assigned(stackitem) do
@ -1995,8 +2002,10 @@ implementation
end;
stackitem:=stackitem^.next;
end;
{ nothing found: give an error and return the original (empty) one }
Message1(sym_e_objc_formal_class_not_resolved,pd.objrealname^);
{ nothing found: optionally give an error and return the original
(empty) one }
if erroronfailure then
Message1(sym_e_objc_formal_class_not_resolved,pd.objrealname^);
result:=pd;
end;
@ -2012,7 +2021,7 @@ implementation
if assigned(classh) then
begin
if (oo_is_formal in classh.objectoptions) then
classh:=find_real_objcclass_definition(classh);
classh:=find_real_objcclass_definition(classh,true);
{ The contextclassh is used for visibility. The classh must be equal to
or be a parent of contextclassh. E.g. for inherited searches the classh is the
parent. }
@ -2077,7 +2086,7 @@ implementation
{ in case this is a formal objcclass, first find the real definition }
if assigned(classh) and
(oo_is_formal in classh.objectoptions) then
classh:=find_real_objcclass_definition(classh);
classh:=find_real_objcclass_definition(classh,true);
result:=false;
def:=nil;
while assigned(classh) do
@ -2115,7 +2124,7 @@ implementation
{ in case this is a formal objcclass, first find the real definition }
if assigned(classh) and
(oo_is_formal in classh.objectoptions) then
classh:=find_real_objcclass_definition(classh);
classh:=find_real_objcclass_definition(classh,true);
result:=false;
def:=nil;
while assigned(classh) do
@ -2376,7 +2385,7 @@ implementation
begin
{ in case this is a formal objcclass, first find the real definition }
if (oo_is_formal in pd.objectoptions) then
pd:=find_real_objcclass_definition(pd);
pd:=find_real_objcclass_definition(pd,true);
hashedid.id:=s;
orgpd:=pd;
while assigned(pd) do

29
tests/test/tobjc35i.pp Normal file
View File

@ -0,0 +1,29 @@
{ %target=darwin }
{ %cpu=powerpc,powerpc64,i386,x86_64,arm }
{ %norun }
{ Written by Jonas Maebe in 2010, released into the public domain }
{$mode objfpc}
{$modeswitch objectivec1}
// will refer to the real NSObject in objcbase
procedure mytest(a: NSObject);
begin
end;
// define external incomplete version
type
NSObject = objcclass; external;
// NSObject should still resolve to the full definition in objcbase
MyObject = objcclass(NSObject)
end;
var
// refers to external incomplete version
a: NSObject;
begin
// compiler should treat external and real type as compatible
mytest(a);
end.