summaryrefslogtreecommitdiff
path: root/compiler/ncgobjc.pas
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2009-03-08 18:40:32 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2009-03-08 18:40:32 +0000
commit9aae3eadab826dc41149a73139a064229bab13ff (patch)
tree8372381e7dba1f88f4f6d3b13332030de3cf3245 /compiler/ncgobjc.pas
parentd391d6b4c708deb55b7e77809eb6bda8c48e6603 (diff)
downloadfpc-9aae3eadab826dc41149a73139a064229bab13ff.tar.gz
+ added {$modeswitch objectivec1}/-Mobjectivec1 mode switch to enable
the use of Objective-C 1.0 constructs. Because it is a mode switch, it can be used cumulatively with every syntax mode. Note that a {$mode xxx} statement resets all mode switches as well, so you cannot use the -Mobjectivec1 variant if you have such a statement in a unit. This modeswitch is currently only enabled for Darwin/PowerPC and Darwin/i386, as the backend support is not yet implemented for other platforms. + implemented selector() statement that can be used to create an Objective-C selector for the message with the specified *constant* name (in the future, it will also work for Objective-C method identifiers) + added SEL type to the system unit (the selector() statement returns it) + added all Objective-C segments to the assembler writers + (currently mostly dummy) objc1 unit that is automatically included if the {$modeswitch objectivec1} statement is used + some tests for the selector() statement git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@12870 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/ncgobjc.pas')
-rw-r--r--compiler/ncgobjc.pas107
1 files changed, 107 insertions, 0 deletions
diff --git a/compiler/ncgobjc.pas b/compiler/ncgobjc.pas
new file mode 100644
index 0000000000..8a8f1cd607
--- /dev/null
+++ b/compiler/ncgobjc.pas
@@ -0,0 +1,107 @@
+{
+ Copyright (c) 2009 by Jonas Maebe
+
+ This unit implements code generator support for Objective-C nodes
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+
+unit ncgobjc;
+
+{$i fpcdefs.inc}
+
+interface
+
+uses
+ nobjc;
+
+type
+ tcgobjcselectornode = class(tobjcselectornode)
+ procedure pass_generate_code; override;
+ end;
+
+implementation
+
+uses
+ globtype,cclasses,
+ aasmbase,aasmdata,aasmtai,
+ cgbase,cgutils,defutil,
+ symsym,
+ node,nld,ncon,
+ verbose;
+
+{*****************************************************************************
+ TCGOBJCSELECTORNODE
+*****************************************************************************}
+
+procedure tcgobjcselectornode.pass_generate_code;
+ var
+ reflab,
+ strlab : tasmlabel;
+ pool : THashSet;
+ entry : PHashSetItem;
+ name : string;
+ pc : pchar;
+ begin
+ if current_asmdata.ConstPools[sp_objcselector] = nil then
+ current_asmdata.ConstPools[sp_objcselector] := THashSet.Create(64, True, False);
+ pool := current_asmdata.ConstPools[sp_objcselector];
+
+ case left.nodetype of
+ loadn:
+ begin
+ name:=tprocsym(tloadnode(left).symtableentry).mangledname;
+ entry := pool.FindOrAdd(@name[1],length(name))
+ end;
+ stringconstn:
+ begin
+ entry := pool.FindOrAdd(tstringconstnode(left).value_str, tstringconstnode(left).len);
+ end;
+ else
+ internalerror(2009030701);
+ end;
+
+ { have we already generated this selector? }
+ if not assigned(entry^.Data) then
+ begin
+ { create new one
+ (no getdatalabel, because these labels have to be local)
+ }
+ current_asmdata.getlabel(reflab,alt_data);
+ current_asmdata.getlabel(strlab,alt_data);
+ entry^.Data := reflab;
+ getmem(pc,entry^.keylength+1);
+ move(entry^.key^,pc^,entry^.keylength);
+ pc[entry^.keylength]:=#0;
+ { add a pointer to the message name in the objc_message_refs section }
+ new_section(current_asmdata.asmlists[al_objc_data],sec_objc_message_refs,reflab.name,sizeof(pint));
+ current_asmdata.asmlists[al_objc_data].concat(Tai_label.Create(reflab));
+ current_asmdata.asmlists[al_objc_data].concat(Tai_const.Create_sym(strlab));
+
+ { and now add the message name to the meth_var_names }
+ new_section(current_asmdata.asmlists[al_objc_data],sec_objc_meth_var_names,strlab.name,1);
+ current_asmdata.asmlists[al_objc_data].concat(Tai_label.Create(strlab));
+ current_asmdata.asmlists[al_objc_data].concat(Tai_string.Create_pchar(pc,entry^.keylength+1));
+ end;
+ location_reset_ref(location, LOC_CREFERENCE, def_cgsize(resultdef), sizeof(pint));
+ location.reference.symbol:=tasmlabel(entry^.Data);
+ end;
+
+
+begin
+ cobjcselectornode:=tcgobjcselectornode;
+end.