diff --git a/.gitattributes b/.gitattributes index 704f7b79e2..5a1f5355cb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8206,6 +8206,18 @@ tests/test/tobjc2.pp svneol=native#text/plain tests/test/tobjc3.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 +tests/test/tobjc5a.pp svneol=native#text/plain +tests/test/tobjc6.pp svneol=native#text/plain +tests/test/tobjc7.pp svneol=native#text/plain +tests/test/tobjc7a.pp svneol=native#text/plain +tests/test/tobjc7b.pp svneol=native#text/plain +tests/test/tobjc7c.pp svneol=native#text/plain +tests/test/tobjc8.pp svneol=native#text/plain +tests/test/tobjc8a.pp svneol=native#text/plain +tests/test/tobjc9.pp svneol=native#text/plain +tests/test/tobjc9a.pp svneol=native#text/plain +tests/test/tobjc9b.pp svneol=native#text/plain tests/test/tobject1.pp svneol=native#text/plain tests/test/tobject2.pp svneol=native#text/plain tests/test/tobject3.pp svneol=native#text/plain diff --git a/compiler/dbgdwarf.pas b/compiler/dbgdwarf.pas index a324b8c785..ca2aa29101 100644 --- a/compiler/dbgdwarf.pas +++ b/compiler/dbgdwarf.pas @@ -3023,7 +3023,8 @@ implementation current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(def_dwarf_class_struct_lab(def),0)); doappend; end; - odt_objcclass: + odt_objcclass, + odt_objcprotocol: begin // Objective-C class: plain pointer for now append_entry(DW_TAG_pointer_type,false,[]); diff --git a/compiler/defcmp.pas b/compiler/defcmp.pas index 85e7691ad7..322096f885 100644 --- a/compiler/defcmp.pas +++ b/compiler/defcmp.pas @@ -277,7 +277,7 @@ implementation objectdef: begin if (m_delphi in current_settings.modeswitches) and - is_class_or_interface_or_dispinterface(def_from) and + is_class_or_interface_or_dispinterface_or_objc(def_from) and (cdo_explicit in cdoptions) then begin eq:=te_convert_l1; @@ -1113,7 +1113,7 @@ implementation can be assigned to void pointers, but it is less preferred than assigning to a related objectdef } if ( - is_class_or_interface_or_dispinterface(def_from) or + is_class_or_interface_or_dispinterface_or_objc(def_from) or (def_from.typ=classrefdef) ) and (tpointerdef(def_to).pointeddef.typ=orddef) and @@ -1122,11 +1122,11 @@ implementation doconv:=tc_equal; eq:=te_convert_l2; end - else if is_objcclass(def_from) and + else if is_objc_class_or_protocol(def_from) and (def_to=objc_idtype) then begin doconv:=tc_equal; - eq:=te_convert_l1; + eq:=te_convert_l2; end; end; end; @@ -1230,7 +1230,7 @@ implementation end else { Class/interface specific } - if is_class_or_interface_or_dispinterface(def_to) then + if is_class_or_interface_or_dispinterface_or_objc(def_to) then begin { void pointer also for delphi mode } if (m_delphi in current_settings.modeswitches) and @@ -1247,9 +1247,19 @@ implementation doconv:=tc_equal; eq:=te_convert_l1; end - { classes can be assigned to interfaces } - else if is_interface(def_to) and - is_class(def_from) and + { All Objective-C classes are compatible with ID } + else if is_objcclass(def_to) and + (def_from=objc_idtype) then + begin + doconv:=tc_equal; + eq:=te_convert_l2; + end + { classes can be assigned to interfaces + (same with objcclass and objcprotocol) } + else if ((is_interface(def_to) and + is_class(def_from)) or + (is_objcprotocol(def_to) and + is_objcclass(def_from))) and assigned(tobjectdef(def_from).ImplementedInterfaces) then begin { we've to search in parent classes as well } @@ -1258,7 +1268,11 @@ implementation begin if hobjdef.find_implemented_interface(tobjectdef(def_to))<>nil then begin - doconv:=tc_class_2_intf; + if is_interface(def_to) then + doconv:=tc_class_2_intf + else + { for Objective-C, we don't have to do anything special } + doconv:=tc_equal; { don't prefer this over objectdef->objectdef } eq:=te_convert_l2; break; @@ -1288,14 +1302,7 @@ implementation doconv:=tc_int_2_int; eq:=te_convert_l1; end; - end - else if is_objcclass(def_to) and - (def_from=objc_idtype) then - begin - { All Objective-C classes are compatible with ID } - doconv:=tc_equal; - eq:=te_convert_l1; - end; + end; end; classrefdef : @@ -1693,8 +1700,8 @@ implementation (equal_defs(parentretdef,childretdef)) or ((parentretdef.typ=objectdef) and (childretdef.typ=objectdef) and - is_class_or_interface(parentretdef) and - is_class_or_interface(childretdef) and + is_class_or_interface_or_objc(parentretdef) and + is_class_or_interface_or_objc(childretdef) and (tobjectdef(childretdef).is_related(tobjectdef(parentretdef)))) end; diff --git a/compiler/defutil.pas b/compiler/defutil.pas index 8aa9c15c32..6a592041b4 100644 --- a/compiler/defutil.pas +++ b/compiler/defutil.pas @@ -970,7 +970,7 @@ implementation end; objectdef : begin - if is_class_or_interface(def) then + if is_class_or_interface_or_objc(def) then result := OS_ADDR else result:=int_cgsize(def.size); diff --git a/compiler/htypechk.pas b/compiler/htypechk.pas index 2c6f321230..a490bae54f 100644 --- a/compiler/htypechk.pas +++ b/compiler/htypechk.pas @@ -218,7 +218,7 @@ implementation pointerdef : begin if ((rd.typ in [orddef,enumdef,pointerdef,classrefdef,procvardef]) or - is_class_or_interface(rd)) then + is_class_or_interface_or_objc(rd)) then begin allowed:=false; exit; @@ -280,7 +280,7 @@ implementation begin { <> and = are defined for classes } if (treetyp in [equaln,unequaln]) and - is_class_or_interface(ld) then + is_class_or_interface_or_objc(ld) then begin allowed:=false; exit; @@ -842,7 +842,7 @@ implementation end; subscriptn : begin - if is_class_or_interface(tunarynode(p).left.resultdef) then + if is_class_or_interface_or_objc(tunarynode(p).left.resultdef) then newstate := vs_read; p:=tunarynode(p).left; end; @@ -996,7 +996,7 @@ implementation pointerdef : gotpointer:=true; objectdef : - gotclass:=is_class_or_interface(hp.resultdef); + gotclass:=is_class_or_interface_or_objc(hp.resultdef); recorddef : gotrecord:=true; classrefdef : @@ -1113,7 +1113,7 @@ implementation pointerdef : gotpointer:=true; objectdef : - gotclass:=is_class_or_interface(hp.resultdef); + gotclass:=is_class_or_interface_or_objc(hp.resultdef); classrefdef : gotclass:=true; arraydef : @@ -1210,7 +1210,7 @@ implementation { a class/interface access is an implicit } { dereferencing } hp:=tsubscriptnode(hp).left; - if is_class_or_interface(hp.resultdef) then + if is_class_or_interface_or_objc(hp.resultdef) then gotderef:=true; end; muln, @@ -1299,7 +1299,7 @@ implementation pointerdef : gotpointer:=true; objectdef : - gotclass:=is_class_or_interface(hp.resultdef); + gotclass:=is_class_or_interface_or_objc(hp.resultdef); recorddef, { handle record like class it needs a subscription } classrefdef : gotclass:=true; diff --git a/compiler/msg/errore.msg b/compiler/msg/errore.msg index d84a75ea33..cde666cd9b 100644 --- a/compiler/msg/errore.msg +++ b/compiler/msg/errore.msg @@ -366,7 +366,7 @@ scan_w_multiple_main_name_overrides=02086_W_Overriding name of "main" procedure # # Parser # -# 03256 is the last used one +# 03261 is the last used one # % \section{Parser messages} % This section lists all parser messages. The parser takes care of the @@ -911,12 +911,12 @@ parser_e_no_con_des_in_interfaces=03171_E_Con- and destructors aren't allowed in % Constructor and destructor declarations aren't allowed in interfaces. % In the most cases method \var{QueryInterface} of \var{IUnknown} can % be used to create a new interface. -parser_e_no_access_specifier_in_interfaces=03172_E_Access specifiers can't be used in INTERFACES +parser_e_no_access_specifier_in_interfaces=03172_E_Access specifiers can't be used in INTERFACEs and OBJCPROTOCOLs % The access specifiers \var{public}, \var{private}, \var{protected} and -% \var{published} can't be used in interfaces because all methods -% of an interface must be public. -parser_e_no_vars_in_interfaces=03173_E_An interface can't contain fields -% Declarations of fields aren't allowed in interfaces. An interface +% \var{published} can't be used in interfaces and Objective-C protocols because all methods +% of an interface/protocol must be public. +parser_e_no_vars_in_interfaces=03173_E_An interface or Objective-C protocol cannot contain fields +% Declarations of fields are not allowed in interfaces and Objective-C protocols. An interface/protocol % can contain only methods and properties with method read/write specifiers. parser_e_no_local_proc_external=03174_E_Can't declare local procedure as EXTERNAL % Declaring local procedures as external is not possible. Local procedures @@ -1203,12 +1203,30 @@ parser_h_no_objc_parent=03256_H_Defining a new Objective-C root class. To derive % root classes in Objective-C. For example, in the Cocoa framework both NSObject and NSProxy are root classes. % Therefore, you have to explicitly define a parent class (such as NSObject) if you want to derive your % Objective-C class from it. +parser_e_no_objc_published=03257_E_Objective-C classes cannot have published sections. +% In Object Pascal, ``published'' determines whether or not RTTI is generated. Since the Objective-C runtime always needs +% RTTI for everything, this specified does not make sense for Objective-C classes. +parser_f_need_objc=03258_F_This module requires an Objective-C mode switch to be compiled +% This error indicates the use of Objective-C language features without an Objective-C mode switch +% active. Enable one via the -M command line switch, or the {\$modeswitch x} directive. +parser_e_must_use_override_objc=03259_E_Inherited methods can only be overridden in Objective-C, add ``override''. +parser_h_should_use_override_objc=03260_H_Inherited methods can only be overridden in Objective-C, add ``override''. +% It is not possible to ``reintroduce'' methods in Objective-C like in Object Pascal. Methods with the same +% name always map to the same virtual method entry. In order to make this clear in the source code, +% the compiler always requires the ``override'' directive to be specified when implementing overriding +% Objective-C methods in Pascal. If the implementation is external, this rule is relaxed because Objective-C +% does not have any ``override''-style keyword (since it's the default and only behaviour in that language), +% which makes it hard for automated header conversion tools to include it everywhere. +parser_e_objc_message_name_changed=03261_E_Message name "$1" in inherited class is different from message name "$2" in current class. +% An overriding Objective-C method cannot have a different message name than an inherited method. The reason +% is that these message names uniquely define the message to the Objective-C runtime, which means that +% giving them a different message name breaks the ``override'' semantics. % \end{description} # # Type Checking # -# 04087 is the last used one +# 04088 is the last used one # % \section{Type checking errors} % This section lists all errors that can occur when type checking is @@ -1506,6 +1524,8 @@ type_e_no_type_info=04087_E_No type info available for this type % Type information is not generated for some types, such as enumerations with gaps % in their value range (this includes enumerations whose lower bound is different % from zero). +type_e_protocol_type_expected=04088_E_Objective-C protocol type expected, but got "$1" +% The compiler expected a protocol type name, but found something else. % \end{description} # # Symtable diff --git a/compiler/msgidx.inc b/compiler/msgidx.inc index 103e7aa41a..ad18544648 100644 --- a/compiler/msgidx.inc +++ b/compiler/msgidx.inc @@ -344,6 +344,11 @@ const parser_e_message_string_too_long=03254; parser_e_objc_message_name_too_long=03255; parser_h_no_objc_parent=03256; + parser_e_no_objc_published=03257; + parser_f_need_objc=03258; + parser_e_must_use_override_objc=03259; + parser_h_should_use_override_objc=03260; + parser_e_objc_message_name_changed=03261; type_e_mismatch=04000; type_e_incompatible_types=04001; type_e_not_equal_types=04002; @@ -422,6 +427,7 @@ const type_e_expected_objc_method_but_got=04085; type_e_expected_objc_method=04086; type_e_no_type_info=04087; + type_e_protocol_type_expected=04088; sym_e_id_not_found=05000; sym_f_internal_error_in_symtablestack=05001; sym_e_duplicate_id=05002; @@ -794,9 +800,9 @@ const option_info=11024; option_help_pages=11025; - MsgTxtSize = 51955; + MsgTxtSize = 52451; MsgIdxMax : array[1..20] of longint=( - 24,87,257,88,65,51,108,22,202,62, + 24,87,262,89,65,51,108,22,202,62, 47,20,1,1,1,1,1,1,1,1 ); diff --git a/compiler/msgtxt.inc b/compiler/msgtxt.inc index ad9dc2cd0a..c4bb815a20 100644 --- a/compiler/msgtxt.inc +++ b/compiler/msgtxt.inc @@ -1,7 +1,7 @@ {$ifdef Delphi} -const msgtxt : array[0..000216] of string[240]=( +const msgtxt : array[0..000218] of string[240]=( {$else Delphi} -const msgtxt : array[0..000216,1..240] of char=( +const msgtxt : array[0..000218,1..240] of char=( {$endif Delphi} '01000_T_Compiler: $1'#000+ '01001_D_Compiler OS: $1'#000+ @@ -293,468 +293,479 @@ const msgtxt : array[0..000216,1..240] of char=( '03169_E_interface identifier expected'#000+ '03170_E_Type "$1" can'#039't be used as array index type'#000+ '03171_E_Con- and destructors aren'#039't allowed in interfaces'#000+ - '03172_E_Access spec','ifiers can'#039't be used in INTERFACES'#000+ - '03173_E_An interface can'#039't contain fields'#000+ + '03172_E_Access spec','ifiers can'#039't be used in INTERFACEs and OBJCPR'+ + 'OTOCOLs'#000+ + '03173_E_An interface or Objective-C protocol cannot contain fields'#000+ '03174_E_Can'#039't declare local procedure as EXTERNAL'#000+ '03175_W_Some fields coming before "$1" weren'#039't initialized'#000+ - '03176_E_Some fields coming before "$1" weren'#039't initial','ized'#000+ + '03176_E_Som','e fields coming before "$1" weren'#039't initialized'#000+ '03177_W_Some fields coming after "$1" weren'#039't initialized'#000+ '03178_E_VarArgs directive (or '#039'...'#039' in MacPas) without CDecl/C'+ 'PPDecl/MWPascal and External'#000+ - '03179_E_Self must be a normal (call-by-value) parameter'#000+ - '03180_E_Interface "$1" has no ','interface identification'#000+ + '03179_E_Self must be a normal (call-by-valu','e) parameter'#000+ + '03180_E_Interface "$1" has no interface identification'#000+ '03181_E_Unknown class field or method identifier "$1"'#000+ '03182_W_Overriding calling convention "$1" with "$2"'#000+ - '03183_E_Typed constants of the type "procedure of object" can only be '+ - 'initialized with NIL'#000+ - '03184_E_Default v','alue can only be assigned to one parameter'#000+ + '03183_E_Typed constants of the type "procedure of object" can onl','y b'+ + 'e initialized with NIL'#000+ + '03184_E_Default value can only be assigned to one parameter'#000+ '03185_E_Default parameter required for "$1"'#000+ '03186_W_Use of unsupported feature!'#000+ '03187_H_C arrays are passed by reference'#000+ - '03188_E_C array of const must be the last argument'#000+ - '03189_H_Type "$1" redefin','ition'#000+ + '03188_E_C array of const must be ','the last argument'#000+ + '03189_H_Type "$1" redefinition'#000+ '03190_W_cdecl'#039'ared functions have no high parameter'#000+ '03191_W_cdecl'#039'ared functions do not support open strings'#000+ '03192_E_Cannot initialize variables declared as threadvar'#000+ - '03193_E_Message directive is only allowed in Classes'#000+ - '03194_E_Proced','ure or Function expected'#000+ + '03193_E_Message directiv','e is only allowed in Classes'#000+ + '03194_E_Procedure or Function expected'#000+ '03195_W_Calling convention directive ignored: "$1"'#000+ '03196_E_REINTRODUCE can'#039't be used in objects'#000+ '03197_E_Each argument must have its own location'#000+ - '03198_E_Each argument must have an explicit location'#000+ - '03199_E_Unknown a','rgument location'#000+ + '03198_E_Each argument must ','have an explicit location'#000+ + '03199_E_Unknown argument location'#000+ '03200_E_32 Bit-Integer or pointer variable expected'#000+ '03201_E_Goto statements aren'#039't allowed between different procedure'+ 's'#000+ - '03202_F_Procedure too complex, it requires too many registers'#000+ + '03202_F_Procedure too complex, it requires too many register','s'#000+ '03203_E_Illegal expression'#000+ - '03204_E_Invali','d integer expression'#000+ + '03204_E_Invalid integer expression'#000+ '03205_E_Illegal qualifier'#000+ '03206_E_High range limit < low range limit'#000+ '03207_E_Exit'#039's parameter must be the name of the procedure it is u'+ 'sed in'#000+ - '03208_E_Illegal assignment to for-loop variable "$1"'#000+ - '03209_E_Can'#039't declare lo','cal variable as EXTERNAL'#000+ + '03208_E_Illegal assignment to for-','loop variable "$1"'#000+ + '03209_E_Can'#039't declare local variable as EXTERNAL'#000+ '03210_E_Procedure is already declared EXTERNAL'#000+ '03211_W_Implicit uses of Variants unit'#000+ '03212_E_Class and static methods can'#039't be used in INTERFACES'#000+ - '03213_E_Overflow in arithmetic operation'#000+ - '03214_E_Protected or privat','e expected'#000+ + '03213_E_Overflow in arith','metic operation'#000+ + '03214_E_Protected or private expected'#000+ '03215_E_SLICE can'#039't be used outside of parameter list'#000+ '03216_E_A DISPINTERFACE can'#039't have a parent class'#000+ '03217_E_A DISPINTERFACE needs a guid'#000+ - '03218_W_Overridden methods must have a related return type. This code '+ - 'may crash, it depe','nds on a Delphi parser bug ("$2" is overridden by '+ + '03218_W_Overridden methods must have a relate','d return type. This cod'+ + 'e may crash, it depends on a Delphi parser bug ("$2" is overridden by '+ '"$1" which has another return type)'#000+ '03219_E_Dispatch IDs must be ordinal constants'#000+ '03220_E_The range of the array is too large'#000+ - '03221_E_The address cannot be taken of bit packed array element','s and'+ + '03221_E_The address ','cannot be taken of bit packed array elements and'+ ' record fields'#000+ '03222_E_Dynamic arrays cannot be packed'#000+ '03223_E_Bit packed array elements and record fields cannot be used as '+ 'loop variables'#000+ '03224_E_VAR and TYPE are allowed only in generics'#000+ - '03225_E_This type can'#039't be a generic'#000+ - '03226_W_','Don'#039't load LINEINFO unit manually, Use the -gl compiler '+ - 'switch instead'#000+ + '03','225_E_This type can'#039't be a generic'#000+ + '03226_W_Don'#039't load LINEINFO unit manually, Use the -gl compiler sw'+ + 'itch instead'#000+ '03227_E_No function result type specified for function "$1"'#000+ '03228_E_Specialization is only supported for generic types'#000+ - '03229_E_Generics can'#039't be used as parameters when ','specializing g'+ + '03229_E','_Generics can'#039't be used as parameters when specializing g'+ 'enerics'#000+ '03230_E_Constants of objects containing a VMT aren'#039't allowed'#000+ '03231_E_Taking the address of labels defined outside the current scope'+ ' isn'#039't allowed'#000+ - '03233_E_Cannot initialize variables declared as external'#000+ - '03234_E_Illegal',' function result type'#000+ + '03233_E_Cannot initialize var','iables declared as external'#000+ + '03234_E_Illegal function result type'#000+ '03235_E_No common type possible between "$1" and "$2"'#000+ '03236_E_Generics without specialization can not be used as a type for '+ 'a variable'#000+ - '03237_W_Register list is ignored for pure assembler routines'#000+ - '03238_E_Implements pro','perty must have class or interface type'#000+ + '03237_W_Register list is ignored for pur','e assembler routines'#000+ + '03238_E_Implements property must have class or interface type'#000+ '03239_E_Implements-property must implement interface of correct type, '+ 'found "$1" expected "$2"'#000+ '03240_E_Implements-property must have read specifier'#000+ - '03241_E_Implements-property must not have write-spec','ifier'#000+ + '03241_E_I','mplements-property must not have write-specifier'#000+ '03242_E_Implements-property must not have stored-specifier'#000+ '03243_E_Implements-property used on unimplemented interface: "$1"'#000+ '03244_E_Floating point not supported for this target'#000+ - '03245_E_Class "$1" does not implement interface "$2"'#000+ - '032','46_E_Type used by implements must be an interface'#000+ + '03245_E_Class',' "$1" does not implement interface "$2"'#000+ + '03246_E_Type used by implements must be an interface'#000+ '03247_E_Variables cannot be exported with a different name on this tar'+ 'get, add the name to the declaration using the "export" directive (var'+ - 'iable name: $1, declared export name: $2)'#000+ - '03248_E_','Weak external symbols are not supported for the current targ'+ - 'et'#000+ + 'iable n','ame: $1, declared export name: $2)'#000+ + '03248_E_Weak external symbols are not supported for the current target'+ + #000+ '03249_E_Forward type definition does not match'#000+ '03250_N_Virtual method "$1" has a lower visibility ($2) than parent cl'+ 'ass $3 ($4)'#000+ - '03251_E_Fields cannot appear after a method or p','roperty definition, '+ + '03251','_E_Fields cannot appear after a method or property definition, '+ 'start a new visibility section first'#000+ '03252_E_Objective-C messages require their Objective-C selector name t'+ 'o be specified using the "message" directive.'#000+ - '03253_E_Objective-C does not have formal constructors nor destructo','r'+ + '03253_E_Objective-C does',' not have formal constructors nor destructor'+ 's. Use the alloc, initXXX and dealloc messages.'#000+ '03254_E_Message name is too long (max. 255 characters)'#000+ '03255_E_Objective-C message symbol name for "$1" is too long'#000+ - '03256_H_Defining a new Objective-C root class. To derive from another '+ - 'root ','class (e.g., NSObject), specify it as the parent class.'#000+ + '03256_H_Defining a new Objective','-C root class. To derive from anothe'+ + 'r root class (e.g., NSObject), specify it as the parent class.'#000+ + '03257_E_Objective-C classes cannot have published sections.'#000+ + '03258_F_This module requires an Objective-C mode switch to be compiled'+ + #000+ + '03259_E_In','herited methods can only be overridden in Objective-C, add'+ + ' ``override'#039#039'.'#000+ + '03260_H_Inherited methods can only be overridden in Objective-C, add `'+ + '`override'#039#039'.'#000+ + '03261_E_Message name "$1" in inherited class is different from message'+ + ' name "$2" in ','current class.'#000+ '04000_E_Type mismatch'#000+ '04001_E_Incompatible types: got "$1" expected "$2"'#000+ '04002_E_Type mismatch between "$1" and "$2"'#000+ '04003_E_Type identifier expected'#000+ - '04004_E_Variable identifier expect','ed'#000+ - '04005_E_Integer expression expected, but got "$1"'#000+ + '04004_E_Variable identifier expected'#000+ + '04005_E_Integer expression expected, b','ut got "$1"'#000+ '04006_E_Boolean expression expected, but got "$1"'#000+ '04007_E_Ordinal expression expected'#000+ '04008_E_pointer type expected, but got "$1"'#000+ '04009_E_class type expected, but got "$1"'#000+ - '04011_E_Can'#039't e','valuate constant expression'#000+ - '04012_E_Set elements are not compatible'#000+ + '04011_E_Can'#039't evaluate constant expression'#000+ + '04012_E_Set e','lements are not compatible'#000+ '04013_E_Operation not implemented for sets'#000+ '04014_W_Automatic type conversion from floating type to COMP which is '+ 'an integer type'#000+ - '04015_H_use DIV instead to get an integer r','esult'#000+ - '04016_E_string types doesn'#039't match, because of $V+ mode'#000+ + '04015_H_use DIV instead to get an integer result'#000+ + '04016_E_string types doesn'#039't match,',' because of $V+ mode'#000+ '04017_E_succ or pred on enums with assignments not possible'#000+ '04018_E_Can'#039't read or write variables of this type'#000+ '04019_E_Can'#039't use readln or writeln on typed file'#000+ - '04020_E_Can'#039't use',' read or write on untyped file.'#000+ - '04021_E_Type conflict between set elements'#000+ + '04020_E_Can'#039't use read or write on untyped file.'#000+ + '04021_E_T','ype conflict between set elements'#000+ '04022_W_lo/hi(dword/qword) returns the upper/lower word/dword'#000+ '04023_E_Integer or real expression expected'#000+ '04024_E_Wrong type "$1" in array constructor'#000+ - '04025_E_Incomp','atible type for arg no. $1: Got "$2", expected "$3"'#000+ + '04025_E_Incompatible type for arg no. $1: Got "$2", exp','ected "$3"'#000+ '04026_E_Method (variable) and Procedure (variable) are not compatible'#000+ '04027_E_Illegal constant passed to internal math function'#000+ '04028_E_Can'#039't take the address of constant expressions'#000+ - '04029','_E_Argument can'#039't be assigned to'#000+ - '04030_E_Can'#039't assign local procedure/function to procedure variabl'+ - 'e'#000+ + '04029_E_Argument can'#039't be assigned to'#000+ + '04030_E_','Can'#039't assign local procedure/function to procedure varia'+ + 'ble'#000+ '04031_E_Can'#039't assign values to an address'#000+ '04032_E_Can'#039't assign values to const variable'#000+ '04033_E_Array type required'#000+ - '04034_E_interface type ','expected, but got "$1"'#000+ - '04035_H_Mixing signed expressions and longwords gives a 64bit result'#000+ + '04034_E_interface type expected, but got "$1"'#000+ + '04035_H_Mixing sig','ned expressions and longwords gives a 64bit result'+ + #000+ '04036_W_Mixing signed expressions and cardinals here may cause a range'+ ' check error'#000+ '04037_E_Typecast has different size ($1 -> $2) in assignment'#000+ - '0403','8_E_enums with assignments can'#039't be used as array index'#000+ + '04038_E_enums with assignments can'#039't be used ','as array index'#000+ '04039_E_Class or Object types "$1" and "$2" are not related'#000+ '04040_W_Class types "$1" and "$2" are not related'#000+ '04041_E_Class or interface type expected, but got "$1"'#000+ - '04042_E_Type "$1" i','s not completely defined'#000+ - '04043_W_String literal has more characters than short string length'#000+ + '04042_E_Type "$1" is not completely defined'#000+ + '04043_W_String l','iteral has more characters than short string length'#000+ '04044_W_Comparison is always false due to range of values'#000+ '04045_W_Comparison is always true due to range of values'#000+ - '04046_W_Constructing a class "$1','" with abstract method "$2"'#000+ - '04047_H_The left operand of the IN operator should be byte sized'#000+ + '04046_W_Constructing a class "$1" with abstract method "$2"'#000+ + '04047_H_The l','eft operand of the IN operator should be byte sized'#000+ '04048_W_Type size mismatch, possible loss of data / range check error'#000+ '04049_H_Type size mismatch, possible loss of data / range check error'#000+ - '04050_E','_The address of an abstract method can'#039't be taken'#000+ + '04050_E_The address of an abstract method can'#039't ','be taken'#000+ '04051_E_Assignments to formal parameters and open arrays are not possi'+ 'ble'#000+ '04052_E_Constant Expression expected'#000+ '04053_E_Operation "$1" not supported for types "$2" and "$3"'#000+ - '04054_E_Illegal ty','pe conversion: "$1" to "$2"'#000+ - '04055_H_Conversion between ordinals and pointers is not portable'#000+ + '04054_E_Illegal type conversion: "$1" to "$2"'#000+ + '04055_H_Conve','rsion between ordinals and pointers is not portable'#000+ '04056_W_Conversion between ordinals and pointers is not portable'#000+ '04057_E_Can'#039't determine which overloaded function to call'#000+ - '04058_E_Illegal counter ','variable'#000+ - '04059_W_Converting constant real value to double for C variable argume'+ - 'nt, add explicit typecast to prevent this.'#000+ + '04058_E_Illegal counter variable'#000+ + '04059_W_Converting constant real',' value to double for C variable argu'+ + 'ment, add explicit typecast to prevent this.'#000+ '04060_E_Class or COM interface type expected, but got "$1"'#000+ '04061_E_Constant packed arrays are not yet supported'#000+ - '04062_','E_Incompatible type for arg no. $1: Got "$2" expected "(Bit)Pa'+ + '04062_E_Incompatible type for arg no. $1: Got "','$2" expected "(Bit)Pa'+ 'cked Array"'#000+ '04063_E_Incompatible type for arg no. $1: Got "$2" expected "(not pack'+ 'ed) Array"'#000+ '04064_E_Elements of packed arrays cannot be of a type which need to be'+ ' initialised'#000+ - '04','065_E_Constant packed records and objects are not yet supported'#000+ + '04065_E_Constant packed records and objects',' are not yet supported'#000+ '04066_W_Arithmetic "$1" on untyped pointer is unportable to {$T+}, sug'+ 'gest typecast'#000+ '04076_E_Can'#039't take address of a subroutine marked as local'#000+ - '04077_E_Can'#039't export subroutine m','arked as local from a unit'#000+ - '04078_E_Type is not automatable: "$1"'#000+ + '04077_E_Can'#039't export subroutine marked as local from a unit'#000+ + '04078_E_Type i','s not automatable: "$1"'#000+ '04079_H_Converting the operands to "$1" before doing the add could pre'+ 'vent overflow errors.'#000+ '04080_H_Converting the operands to "$1" before doing the subtract coul'+ - 'd prevent ove','rflow errors.'#000+ - '04081_H_Converting the operands to "$1" before doing the multiply coul'+ 'd prevent overflow errors.'#000+ + '04081_H_Converting the oper','ands to "$1" before doing the multiply co'+ + 'uld prevent overflow errors.'#000+ '04082_W_Converting pointers to signed integers may result in wrong com'+ - 'parison results and range errors, use an unsigned type inst','ead.'#000+ - '04083_E_Interface type $1 has no valid GUID'#000+ + 'parison results and range errors, use an unsigned type instead.'#000+ + '04083_E_Interface type $1 has no val','id GUID'#000+ '04084_E_Invalid selector name'#000+ '04085_E_Expected Objective-C method, but got $1'#000+ '04086_E_Expected Objective-C method or constant method name'#000+ '04087_E_No type info available for this type'#000+ - '05000_E_','Identifier not found "$1"'#000+ + '04088_E_Objective-C protocol type expected, but g','ot "$1"'#000+ + '05000_E_Identifier not found "$1"'#000+ '05001_F_Internal Error in SymTableStack()'#000+ '05002_E_Duplicate identifier "$1"'#000+ '05003_H_Identifier already defined in $1 at line $2'#000+ '05004_E_Unknown identifier "$1"'#000+ - '05005_E_Forward declaration not solved "$1"'#000+ - '05007_E_Er','ror in type definition'#000+ + '05005_E_Forward declaration not solved',' "$1"'#000+ + '05007_E_Error in type definition'#000+ '05009_E_Forward type not resolved "$1"'#000+ '05010_E_Only static variables can be used in static methods or outside'+ ' methods'#000+ '05012_F_record or class type expected'#000+ - '05013_E_Instances of classes or objects with an abstract meth','od are '+ + '05013_E_Instances of classes or objects with ','an abstract method are '+ 'not allowed'#000+ '05014_W_Label not defined "$1"'#000+ '05015_E_Label used but not defined "$1"'#000+ '05016_E_Illegal label declaration'#000+ '05017_E_GOTO and LABEL are not supported (use switch -Sg)'#000+ '05018_E_Label not found'#000+ - '05019_E_identifier isn'#039't a label'#000+ - '0','5020_E_label already defined'#000+ + '05019_E_identifier',' isn'#039't a label'#000+ + '05020_E_label already defined'#000+ '05021_E_illegal type declaration of set elements'#000+ '05022_E_Forward class definition not resolved "$1"'#000+ '05023_H_Unit "$1" not used in $2'#000+ '05024_H_Parameter "$1" not used'#000+ - '05025_N_Local variable "$1" not used'#000+ - '05026_H_V','alue parameter "$1" is assigned but never used'#000+ + '05025_N_Local variable "$1" no','t used'#000+ + '05026_H_Value parameter "$1" is assigned but never used'#000+ '05027_N_Local variable "$1" is assigned but never used'#000+ '05028_H_Local $1 "$2" is not used'#000+ '05029_N_Private field "$1.$2" is never used'#000+ - '05030_N_Private field "$1.$2" is assigned but never used'#000+ - '050','31_N_Private method "$1.$2" never used'#000+ + '05030_N_Private field "$1.$2" is assigned bu','t never used'#000+ + '05031_N_Private method "$1.$2" never used'#000+ '05032_E_Set type expected'#000+ '05033_W_Function result does not seem to be set'#000+ '05034_W_Type "$1" is not aligned correctly in current record for C'#000+ - '05035_E_Unknown record field identifier "$1"'#000+ - '05036_W_Local v','ariable "$1" does not seem to be initialized'#000+ + '05035_E_Unknown record field identifier "$1"',#000+ + '05036_W_Local variable "$1" does not seem to be initialized'#000+ '05037_W_Variable "$1" does not seem to be initialized'#000+ '05038_E_identifier idents no member "$1"'#000+ '05039_H_Found declaration: $1'#000+ '05040_E_Data element too large'#000+ - '05042_E_No matching implementation for ','interface method "$1" found'#000+ + '05042_E_No matching imp','lementation for interface method "$1" found'#000+ '05043_W_Symbol "$1" is deprecated'#000+ '05044_W_Symbol "$1" is not portable'#000+ '05055_W_Symbol "$1" is not implemented'#000+ '05056_E_Can'#039't create unique type from this type'#000+ - '05057_H_Local variable "$1" does not seem to be initial','ized'#000+ + '05057_H_Local variable "$1" does not se','em to be initialized'#000+ '05058_H_Variable "$1" does not seem to be initialized'#000+ '05059_W_Function result variable does not seem to initialized'#000+ '05060_H_Function result variable does not seem to be initialized'#000+ - '05061_W_Variable "$1" read but nowhere assigned'#000+ - '05062_','H_Found abstract method: $1'#000+ + '05061_W_Variable "$1" read but nowhere',' assigned'#000+ + '05062_H_Found abstract method: $1'#000+ '05063_W_Symbol "$1" is experimental'#000+ '05064_W_Forward declaration "$1" not resolved, assumed external'#000+ '06009_E_Parameter list size exceeds 65535 bytes'#000+ '06012_E_File types must be var parameters'#000+ - '06013_E_The use of a f','ar pointer isn'#039't allowed there'#000+ + '06013_','E_The use of a far pointer isn'#039't allowed there'#000+ '06015_E_EXPORT declared functions can'#039't be called'#000+ '06016_W_Possible illegal call of constructor or destructor'#000+ '06017_N_Inefficient code'#000+ '06018_W_unreachable code'#000+ - '06020_E_Abstract methods can'#039't be called directly'#000, + '06020_E_Abstract methods can'#039't be ','called directly'#000+ '06027_DL_Register $1 weight $2 $3'#000+ '06029_DL_Stack frame is omitted'#000+ '06031_E_Object or class methods can'#039't be inline.'#000+ '06032_E_Procvar calls cannot be inline.'#000+ '06033_E_No code for inline procedure stored'#000+ - '06035_E_Element zero of an ansi/wide- or ','longstring can'#039't be acc'+ + '06035_E_Element zero of a','n ansi/wide- or longstring can'#039't be acc'+ 'essed, use (set)length instead'#000+ '06037_E_Constructors or destructors can not be called inside a '#039'wi'+ 'th'#039' clause'#000+ '06038_E_Cannot call message handler methods directly'#000+ - '06039_E_Jump in or outside of an exception block'#000+ - '06040_E','_Control flow statements aren'#039't allowed in a finally bloc'+ - 'k'#000+ + '06039_E_Jump in or outside of an excepti','on block'#000+ + '06040_E_Control flow statements aren'#039't allowed in a finally block'#000+ '06041_W_Parameters size exceeds limit for certain cpu'#039's'#000+ '06042_W_Local variable size exceed limit for certain cpu'#039's'#000+ - '06043_E_Local variables size exceeds supported limit'#000+ - '06044_E_BREAK',' not allowed'#000+ + '06043_E_Local variables size exceeds supported lim','it'#000+ + '06044_E_BREAK not allowed'#000+ '06045_E_CONTINUE not allowed'#000+ '06046_F_Unknown compilerproc "$1". Check if you use the correct run ti'+ 'me library.'#000+ '06047_F_Cannot find system type "$1". Check if you use the correct run'+ ' time library.'#000+ - '06048_H_Inherited call to abstr','act method ignored'#000+ + '06048_H_Inherit','ed call to abstract method ignored'#000+ '06049_E_Goto label "$1" not defined or optimized away'#000+ '06050_F_Cannot find type "$1" in unit "$2". Check if you use the corre'+ 'ct run time library.'#000+ '07000_DL_Starting $1 styled assembler parsing'#000+ - '07001_DL_Finished $1 styled as','sembler parsing'#000+ + '07001_DL_Finis','hed $1 styled assembler parsing'#000+ '07002_E_Non-label pattern contains @'#000+ '07004_E_Error building record offset'#000+ '07005_E_OFFSET used without identifier'#000+ '07006_E_TYPE used without identifier'#000+ '07007_E_Cannot use local variable or parameters here'#000+ - '07008_E_need to use O','FFSET here'#000+ + '07008','_E_need to use OFFSET here'#000+ '07009_E_need to use $ here'#000+ '07010_E_Cannot use multiple relocatable symbols'#000+ '07011_E_Relocatable symbol can only be added'#000+ '07012_E_Invalid constant expression'#000+ '07013_E_Relocatable symbol is not allowed'#000+ - '07014_E_Invalid reference synta','x'#000+ + '07014_E_Invalid',' reference syntax'#000+ '07015_E_You can not reach $1 from that code'#000+ '07016_E_Local symbols/labels aren'#039't allowed as references'#000+ '07017_E_Invalid base and index register usage'#000+ '07018_W_Possible error in object field handling'#000+ - '07019_E_Wrong scale factor specified'#000+ - '07020','_E_Multiple index register usage'#000+ + '07019_E_Wrong scale factor',' specified'#000+ + '07020_E_Multiple index register usage'#000+ '07021_E_Invalid operand type'#000+ '07022_E_Invalid string as opcode operand: $1'#000+ '07023_W_@CODE and @DATA not supported'#000+ '07024_E_Null label references are not allowed'#000+ - '07025_E_Divide by zero in asm evaluator'#000+ - '07026_E_I','llegal expression'#000+ + '07025_E_Divide by zero in asm eva','luator'#000+ + '07026_E_Illegal expression'#000+ '07027_E_escape sequence ignored: $1'#000+ '07028_E_Invalid symbol reference'#000+ '07029_W_Fwait can cause emulation problems with emu387'#000+ '07030_W_$1 without operand translated into $1P'#000+ - '07031_W_ENTER instruction is not supported by Linux',' kernel'#000+ + '07031_W_ENTER instruction is not su','pported by Linux kernel'#000+ '07032_W_Calling an overload function in assembler'#000+ '07033_E_Unsupported symbol type for operand'#000+ '07034_E_Constant value out of bounds'#000+ '07035_E_Error converting decimal $1'#000+ '07036_E_Error converting octal $1'#000+ - '07037_E_Error converting binary',' $1'#000+ + '07037_E_Error c','onverting binary $1'#000+ '07038_E_Error converting hexadecimal $1'#000+ '07039_H_$1 translated to $2'#000+ '07040_W_$1 is associated to an overloaded function'#000+ '07041_E_Cannot use SELF outside a method'#000+ '07042_E_Cannot use OLDEBP outside a nested procedure'#000+ - '07043_W_Procedures can'#039,'t return any value in asm code'#000+ + '07043_W','_Procedures can'#039't return any value in asm code'#000+ '07044_E_SEG not supported'#000+ '07045_E_Size suffix and destination or source size do not match'#000+ '07046_W_Size suffix and destination or source size do not match'#000+ '07047_E_Assembler syntax error'#000+ - '07048_E_Invalid combinat','ion of opcode and operands'#000+ + '07048_E_','Invalid combination of opcode and operands'#000+ '07049_E_Assembler syntax error in operand'#000+ '07050_E_Assembler syntax error in constant'#000+ '07051_E_Invalid String expression'#000+ '07052_W_constant with symbol $1 for address which is not on a pointer'#000+ - '07053_E_Unrecognized opc','ode $1'#000+ + '07053_E_','Unrecognized opcode $1'#000+ '07054_E_Invalid or missing opcode'#000+ '07055_E_Invalid combination of prefix and opcode: $1'#000+ '07056_E_Invalid combination of override and opcode: $1'#000+ '07057_E_Too many operands on line'#000+ '07058_W_NEAR ignored'#000+ - '07059_W_FAR ignored'#000+ - '07060_E_Duplicat','e local symbol $1'#000+ + '07059_W_FAR ignored'#000, + '07060_E_Duplicate local symbol $1'#000+ '07061_E_Undefined local symbol $1'#000+ '07062_E_Unknown label identifier $1'#000+ '07063_E_Invalid register name'#000+ '07064_E_Invalid floating point register name'#000+ '07066_W_Modulo not supported'#000+ - '07067_E_Invalid floating point constant $1'#000+ - '07068','_E_Invalid floating point expression'#000+ + '07067_E_Invalid floating point c','onstant $1'#000+ + '07068_E_Invalid floating point expression'#000+ '07069_E_Wrong symbol type'#000+ '07070_E_Cannot index a local var or parameter with a register'#000+ '07071_E_Invalid segment override expression'#000+ '07072_W_Identifier $1 supposed external'#000+ - '07073_E_Strings not allowed as ','constants'#000+ + '07073_E_Strings',' not allowed as constants'#000+ '07074_No type of variable specified'#000+ '07075_E_assembler code not returned to text section'#000+ '07076_E_Not a directive or local symbol $1'#000+ '07077_E_Using a defined name as a local label'#000+ - '07078_E_Dollar token is used without an identifier'#000+ - '07','079_W_32bit constant created for address'#000+ + '07078_E_Dollar token is used without ','an identifier'#000+ + '07079_W_32bit constant created for address'#000+ '07080_N_.align is target specific, use .balign or .p2align'#000+ '07081_E_Can'#039't access fields directly for parameters'#000+ '07082_E_Can'#039't access fields of objects/classes directly'#000+ - '07083_E_No size specified and un','able to determine the size of the op'+ + '07083_E_No size ','specified and unable to determine the size of the op'+ 'erands'#000+ '07084_E_Cannot use RESULT in this function'#000+ '07086_W_"$1" without operand translated into "$1 %st,%st(1)"'#000+ '07087_W_"$1 %st(n)" translated into "$1 %st,%st(n)"'#000+ - '07088_W_"$1 %st(n)" translated into "$1 %','st(n),%st"'#000+ + '07088_W_"$1 %st(n)" trans','lated into "$1 %st(n),%st"'#000+ '07089_E_Char < not allowed here'#000+ '07090_E_Char > not allowed here'#000+ '07093_W_ALIGN not supported'#000+ '07094_E_Inc and Dec cannot be together'#000+ '07095_E_Invalid reglist for movem'#000+ '07096_E_Reglist invalid for opcode'#000+ - '07097_E_Higher cpu mode requi','red ($1)'#000+ + '07097_E_Highe','r cpu mode required ($1)'#000+ '07098_W_No size specified and unable to determine the size of the oper'+ 'ands, using DWORD as default'#000+ '07099_E_Syntax error while trying to parse a shifter operand'#000+ - '07100_E_Address of packed component is not at a byte boundary'#000+ - '07101_W_N','o size specified and unable to determine the size of the op'+ - 'erands, using BYTE as default'#000+ + '07100_E_Address of packed component is not at a byte bo','undary'#000+ + '07101_W_No size specified and unable to determine the size of the oper'+ + 'ands, using BYTE as default'#000+ '07102_W_Use of +offset(%ebp) for parameters invalid here'#000+ '07103_W_Use of +offset(%ebp) is not compatible with regcall convention'+ #000+ - '07104_W_Use of -offset(','%ebp) is not recommended for local variable a'+ + '07104_W','_Use of -offset(%ebp) is not recommended for local variable a'+ 'ccess'#000+ '07105_W_Use of -offset(%esp), access may cause a crash or value may be'+ ' lost'#000+ '07106_E_VMTOffset must be used in combination with a virtual method, a'+ 'nd "$1" is not virtual'#000+ - '07107_E_Generating P','IC, but reference is not PIC-safe'#000+ + '0710','7_E_Generating PIC, but reference is not PIC-safe'#000+ '08000_F_Too many assembler files'#000+ '08001_F_Selected assembler output not supported'#000+ '08002_F_Comp not supported'#000+ '08003_F_Direct not support for binary writers'#000+ - '08004_E_Allocating of data is only allowed in bss se','ction'#000+ + '08004_E_Allocating of data is only a','llowed in bss section'#000+ '08005_F_No binary writer selected'#000+ '08006_E_Asm: Opcode $1 not in table'#000+ '08007_E_Asm: $1 invalid combination of opcode and operands'#000+ '08008_E_Asm: 16 Bit references not supported'#000+ '08009_E_Asm: Invalid effective address'#000+ - '08010_E_Asm: Immediat','e or reference expected'#000+ + '08010','_E_Asm: Immediate or reference expected'#000+ '08011_E_Asm: $1 value exceeds bounds $2'#000+ '08012_E_Asm: Short jump is out of range $1'#000+ '08013_E_Asm: Undefined label $1'#000+ '08014_E_Asm: Comp type not supported for this target'#000+ - '08015_E_Asm: Extended type not supported for thi','s target'#000+ + '08015_E_Asm: Extended type not s','upported for this target'#000+ '08016_E_Asm: Duplicate label $1'#000+ '08017_E_Asm: Redefined label $1'#000+ '08018_E_Asm: First defined here'#000+ '08019_E_Asm: Invalid register $1'#000+ '08020_E_Asm: 16 or 32 Bit references not supported'#000+ - '08021_E_Asm: 64 Bit operands not supported'#000+ - '09000_W_','Source operating system redefined'#000+ + '08021_E_Asm: 64 Bit operands not su','pported'#000+ + '09000_W_Source operating system redefined'#000+ '09001_I_Assembling (pipe) $1'#000+ '09002_E_Can'#039't create assembler file: $1'#000+ '09003_E_Can'#039't create object file: $1'#000+ '09004_E_Can'#039't create archive file: $1'#000+ - '09005_E_Assembler $1 not found, switching to external assembli','ng'#000+ + '09005_E_Assembler $1 not found, switching to e','xternal assembling'#000+ '09006_T_Using assembler: $1'#000+ '09007_E_Error while assembling exitcode $1'#000+ '09008_E_Can'#039't call the assembler, error $1 switching to external a'+ 'ssembling'#000+ '09009_I_Assembling $1'#000+ '09010_I_Assembling with smartlinking $1'#000+ - '09011_W_Object $1 not found,',' Linking may fail !'#000+ + '09011_W_Obje','ct $1 not found, Linking may fail !'#000+ '09012_W_Library $1 not found, Linking may fail !'#000+ '09013_E_Error while linking'#000+ '09014_E_Can'#039't call the linker, switching to external linking'#000+ '09015_I_Linking $1'#000+ - '09016_E_Util $1 not found, switching to external linking'#000+ - '09017_','T_Using util $1'#000+ + '09016_E_Util $1 not found, switching to externa','l linking'#000+ + '09017_T_Using util $1'#000+ '09018_E_Creation of Executables not supported'#000+ '09019_E_Creation of Dynamic/Shared Libraries not supported'#000+ '09020_I_Closing script $1'#000+ '09021_E_resource compiler "$1" not found, switching to external mode'#000+ - '09022_I_Compiling resour','ce $1'#000+ + '09022_I_','Compiling resource $1'#000+ '09023_T_unit $1 can'#039't be statically linked, switching to smart lin'+ 'king'#000+ '09024_T_unit $1 can'#039't be smart linked, switching to static linking'+ #000+ '09025_T_unit $1 can'#039't be shared linked, switching to static linkin'+ 'g'#000+ - '09026_E_unit $1 can'#039't be sma','rt or static linked'#000+ + '09026_E_unit',' $1 can'#039't be smart or static linked'#000+ '09027_E_unit $1 can'#039't be shared or static linked'#000+ '09028_D_Calling resource compiler "$1" with "$2" as command line'#000+ '09029_E_Error while compiling resources'#000+ - '09030_E_Can'#039't call the resource compiler "$1", switching to extern', - 'al mode'#000+ + '09030_E_Can'#039't call the resource compiler "$1", swi','tching to exte'+ + 'rnal mode'#000+ '09031_E_Can'#039't open resource file "$1"'#000+ '09032_E_Can'#039't write resource file "$1"'#000+ '09128_F_Can'#039't post process executable $1'#000+ '09129_F_Can'#039't open executable $1'#000+ '09130_X_Size of Code: $1 bytes'#000+ - '09131_X_Size of initialized data: $1 bytes'#000+ - '09132_X','_Size of uninitialized data: $1 bytes'#000+ + '09131_X_Size of initialized data: ','$1 bytes'#000+ + '09132_X_Size of uninitialized data: $1 bytes'#000+ '09133_X_Stack space reserved: $1 bytes'#000+ '09134_X_Stack space committed: $1 bytes'#000+ '09200_F_Executable image size is too big for $1 target.'#000+ - '09201_W_Object file "$1" contains 32-bit absolute relocation to sym','b'+ + '09201_W_Object file "$1" contains 32-bit absolute r','elocation to symb'+ 'ol "$2".'#000+ '10000_T_Unitsearch: $1'#000+ '10001_T_PPU Loading $1'#000+ @@ -764,151 +775,151 @@ const msgtxt : array[0..000216,1..240] of char=( '10005_U_PPU Time: $1'#000+ '10006_U_PPU File too short'#000+ '10007_U_PPU Invalid Header (no PPU at the begin)'#000+ - '10008_U_PPU Invalid Vers','ion $1'#000+ + '10008_U_','PPU Invalid Version $1'#000+ '10009_U_PPU is compiled for another processor'#000+ '10010_U_PPU is compiled for an other target'#000+ '10011_U_PPU Source: $1'#000+ '10012_U_Writing $1'#000+ '10013_F_Can'#039't Write PPU-File'#000+ '10014_F_Error reading PPU-File'#000+ - '10015_F_unexpected end of PPU-File'#000+ - '10016_','F_Invalid PPU-File entry: $1'#000+ + '10015_F_unexpected end of',' PPU-File'#000+ + '10016_F_Invalid PPU-File entry: $1'#000+ '10017_F_PPU Dbx count problem'#000+ '10018_E_Illegal unit name: $1'#000+ '10019_F_Too much units'#000+ '10020_F_Circular unit reference between $1 and $2'#000+ '10021_F_Can'#039't compile unit $1, no sources available'#000+ - '10022_F_Can'#039't find unit $1',' used by $2'#000+ + '10022_F_Ca','n'#039't find unit $1 used by $2'#000+ '10023_W_Unit $1 was not found but $2 exists'#000+ '10024_F_Unit $1 searched but $2 found'#000+ '10025_W_Compiling the system unit requires the -Us switch'#000+ '10026_F_There were $1 errors compiling module, stopping'#000+ - '10027_U_Load from $1 ($2) unit $','3'#000+ + '10027_U_Load fro','m $1 ($2) unit $3'#000+ '10028_U_Recompiling $1, checksum changed for $2'#000+ '10029_U_Recompiling $1, source found only'#000+ '10030_U_Recompiling unit, static lib is older than ppufile'#000+ '10031_U_Recompiling unit, shared lib is older than ppufile'#000+ - '10032_U_Recompiling unit, obj ','and asm are older than ppufile'#000+ + '10032_U_Recomp','iling unit, obj and asm are older than ppufile'#000+ '10033_U_Recompiling unit, obj is older than asm'#000+ '10034_U_Parsing interface of $1'#000+ '10035_U_Parsing implementation of $1'#000+ '10036_U_Second load for unit $1'#000+ '10037_U_PPU Check file $1 time $2'#000+ - '10040_W_Can'#039't recompile un','it $1, but found modifed include files'+ + '10040_W_Ca','n'#039't recompile unit $1, but found modifed include files'+ #000+ '10041_U_File $1 is newer than PPU file $2'#000+ '10042_U_Trying to use a unit which was compiled with a different FPU m'+ 'ode'#000+ '10043_U_Loading interface units from $1'#000+ - '10044_U_Loading implementation units from $1'#000, + '10044_U_Loading implementatio','n units from $1'#000+ '10045_U_Interface CRC changed for unit $1'#000+ '10046_U_Implementation CRC changed for unit $1'#000+ '10047_U_Finished compiling unit $1'#000+ '10048_U_Add dependency of $1 to $2'#000+ '10049_U_No reload, is caller: $1'#000+ - '10050_U_No reload, already in second compile: $1',#000+ + '10050_U_No reload, already in se','cond compile: $1'#000+ '10051_U_Flag for reload: $1'#000+ '10052_U_Forced reloading'#000+ '10053_U_Previous state of $1: $2'#000+ '10054_U_Already compiling $1, setting second compile'#000+ '10055_U_Loading unit $1'#000+ '10056_U_Finished loading unit $1'#000+ - '10057_U_Registering new unit $1'#000+ - '10058_U_Re-','resolving unit $1'#000+ + '10057_U_Registering new uni','t $1'#000+ + '10058_U_Re-resolving unit $1'#000+ '10059_U_Skipping re-resolving unit $1, still loading used units'#000+ '10060_U_Unloading resource unit $1 (not needed)'#000+ '10061_E_Unit $1 was compiled using a different whole program optimizat'+ - 'ion feedback input ($2, $3); recompile i','t without wpo or use the sam'+ + 'ion feedback input ($2, ','$3); recompile it without wpo or use the sam'+ 'e wpo feedback input file for this compilation invocation'#000+ '11000_O_$1 [options] [options]'#000+ '11001_W_Only one source file supported'#000+ '11002_W_DEF file can be created only for OS/2'#000+ - '11003_E_nested response fi','les are not supported'#000+ + '11003_E_ne','sted response files are not supported'#000+ '11004_F_No source file name in command line'#000+ '11005_N_No option inside $1 config file'#000+ '11006_E_Illegal parameter: $1'#000+ '11007_H_-? writes help pages'#000+ '11008_F_Too many config files nested'#000+ - '11009_F_Unable to open file $1'#000+ - '11010_D','_Reading further options from $1'#000+ + '11009_F_Unable to open',' file $1'#000+ + '11010_D_Reading further options from $1'#000+ '11011_W_Target is already set to: $1'#000+ '11012_W_Shared libs not supported on DOS platform, reverting to static'+ #000+ '11013_F_In options file $1 at line $2 too many \var{\#IF(N)DEFs} encou'+ 'ntered'#000+ - '11014_F_In options fil','e $1 at line $2 unexpected \var{\#ENDIFs} enco'+ + '11014_','F_In options file $1 at line $2 unexpected \var{\#ENDIFs} enco'+ 'untered'#000+ '11015_F_Open conditional at the end of the options file'#000+ '11016_W_Debug information generation is not supported by this executab'+ 'le'#000+ '11017_H_Try recompiling with -dGDB'#000+ - '11018_W_You are using ','the obsolete switch $1'#000+ + '11018_','W_You are using the obsolete switch $1'#000+ '11019_W_You are using the obsolete switch $1, please use $2'#000+ '11020_N_Switching assembler to default source writing assembler'#000+ '11021_W_Assembler output selected "$1" is not compatible with "$2"'#000+ - '11022_W_"$1" assembler use',' forced'#000+ + '11022_W_"$','1" assembler use forced'#000+ '11026_T_Reading options from file $1'#000+ '11027_T_Reading options from environment $1'#000+ '11028_D_Handling option "$1"'#000+ '11029_O_*** press enter ***'#000+ '11030_H_Start of reading config file $1'#000+ - '11031_H_End of reading config file $1'#000+ - '11032_D_interpre','ting option "$1"'#000+ + '11031_H_End of reading config file $1'#000, + '11032_D_interpreting option "$1"'#000+ '11036_D_interpreting firstpass option "$1"'#000+ '11033_D_interpreting file option "$1"'#000+ '11034_D_Reading config file "$1"'#000+ '11035_D_found source file name "$1"'#000+ '11039_E_Unknown code page'#000+ - '11040_F_Config file $1 is a directory'#000+ - '11041_W_A','ssembler output selected "$1" cannot generate debug info, d'+ - 'ebugging disabled'#000+ + '11040_F_Config file $1 is a dir','ectory'#000+ + '11041_W_Assembler output selected "$1" cannot generate debug info, deb'+ + 'ugging disabled'#000+ '11042_W_Use of ppc386.cfg is deprecated, please use fpc.cfg instead'#000+ '11043_F_In options file $1 at line $2 \var{\#ELSE} directive without \'+ - 'var{\#IF(N)DEF} found'#000+ - '110','44_F_Option "$1" is not, or not yet, supported on the current tar'+ - 'get platform'#000+ + 'var{\#IF(','N)DEF} found'#000+ + '11044_F_Option "$1" is not, or not yet, supported on the current targe'+ + 't platform'#000+ '11045_F_The feature "$1" is not, or not yet, supported on the selected'+ ' target platform'#000+ - '11046_N_DWARF debug information cannot be used with smart linking on t'+ - 'his t','arget, switching to static linking'#000+ + '11046_N_DWARF debug information cannot be used with smart l','inking on'+ + ' this target, switching to static linking'#000+ '12000_F_Cannot open whole program optimization feedback file "$1"'#000+ '12001_D_Processing whole program optimization information in wpo feedb'+ 'ack file "$1"'#000+ - '12002_D_Finished processing the whole program optimizat','ion informati'+ + '12002_D_Finished processing the whole p','rogram optimization informati'+ 'on in wpo feedback file "$1"'#000+ '12003_E_Expected section header, but got "$2" at line $1 of wpo feedba'+ 'ck file'#000+ '12004_W_No handler registered for whole program optimization section "'+ - '$2" at line $1 of wpo feedback file, ignoring'#000+ - '1200','5_D_Found whole program optimization section "$1" with informati'+ - 'on about "$2"'#000+ + '$2" at line $1 of wpo feedback fil','e, ignoring'#000+ + '12005_D_Found whole program optimization section "$1" with information'+ + ' about "$2"'#000+ '12006_F_The selected whole program optimizations require a previously '+ 'generated feedback file (use -Fw to specify)'#000+ - '12007_E_No collected information necessary to p','erform "$1" whole pro'+ + '12007_E_No collected informatio','n necessary to perform "$1" whole pro'+ 'gram optimization found'#000+ '12008_F_Specify a whole program optimization feedback file to store th'+ 'e generated info in (using -FW)'#000+ '12009_E_Not generating any whole program optimization information, yet'+ - ' a feedback file was sp','ecified (using -FW)'#000+ + ' a feed','back file was specified (using -FW)'#000+ '12010_E_Not performing any whole program optimizations, yet an input f'+ 'eedback file was specified (using -Fw)'#000+ '12011_D_Skipping whole program optimization section "$1", because not '+ - 'needed by the requested optimizations'#000+ - '120','12_W_Overriding previously read information for "$1" from feedbac'+ - 'k input file using information in section "$2"'#000+ + 'needed by the requested o','ptimizations'#000+ + '12012_W_Overriding previously read information for "$1" from feedback '+ + 'input file using information in section "$2"'#000+ '12013_E_Cannot extract symbol liveness information from program when s'+ 'tripping symbols, use -Xs-'#000+ - '12014_E_Cannot extract symbol l','iveness information from program when'+ + '12014_E_Cannot ','extract symbol liveness information from program when'+ ' when not linking'#000+ '12015_F_Cannot find "$1" or "$2" to extract symbol liveness informatio'+ 'n from linked program'#000+ '12016_E_Error during reading symbol liveness information produced by "'+ '$1"'#000+ - '12017_F_Error execu','ting "$1" (exitcode: $2) to extract symbol inform'+ + '120','17_F_Error executing "$1" (exitcode: $2) to extract symbol inform'+ 'ation from linked program'#000+ '12018_E_Collection of symbol liveness information can only help when u'+ 'sing smart linking, use -CX -XX'#000+ - '12019_E_Cannot create specified whole program optimisation feed','back '+ + '12019_E_Cannot create specified whole program o','ptimisation feedback '+ 'file "$1"'#000+ '11023_Free Pascal Compiler version $FPCFULLVERSION [$FPCDATE] for $FPC'+ 'CPU'#010+ @@ -916,7 +927,7 @@ const msgtxt : array[0..000216,1..240] of char=( '11024_Free Pascal Compiler version $FPCVERSION'#010+ #010+ 'Compiler Date : $FPCDATE'#010+ - 'Compiler CPU Target: $FPCCPU'#010, + 'Compiler CPU ','Target: $FPCCPU'#010+ #010+ 'Supported targets:'#010+ ' $OSTARGETS'#010+ @@ -933,7 +944,7 @@ const msgtxt : array[0..000216,1..240] of char=( 'Supported Optimizations:'#010+ ' $OPTIMIZATIONS'#010+ #010+ - 'Supported Whole Pr','ogram Optimizations:'#010+ + 'Su','pported Whole Program Optimizations:'#010+ ' All'#010+ ' $WPOPTIMIZATIONS'#010+ #010+ @@ -943,69 +954,69 @@ const msgtxt : array[0..000216,1..240] of char=( 'This program comes under the GNU General Public Licence'#010+ 'For more information read COPYING.FPC'#010+ #010+ - 'Report bugs, suggestions, etc. to:'#010+ - ' ',' http://bugs.freepascal.org'#010+ + 'Report bugs, suggestions, etc','. to:'#010+ + ' http://bugs.freepascal.org'#010+ 'or'#010+ ' bugs@freepascal.org'#000+ '11025_**0*_Put + after a boolean switch option to enable it, - to disa'+ 'ble it'#010+ '**1a_The compiler doesn'#039't delete the generated assembler file'#010+ - '**2al_List sourcecode lines',' in assembler file'#010+ + '**2al_List ','sourcecode lines in assembler file'#010+ '**2an_List node info in assembler file'#010+ '*L2ap_Use pipes instead of creating temporary assembler files'#010+ '**2ar_List register allocation/release info in assembler file'#010+ - '**2at_List temp allocation/release info in assembler file'#010, + '**2at_List temp allocation/release info in',' assembler file'#010+ '**1A_Output format:'#010+ '**2Adefault_Use default assembler'#010+ '3*2Aas_Assemble using GNU AS'#010+ '3*2Anasmcoff_COFF (Go32v2) file using Nasm'#010+ '3*2Anasmelf_ELF32 (Linux) file using Nasm'#010+ '3*2Anasmwin32_Win32 object file using Nasm'#010+ - '3*2Anasmwdosx_Win32/WDOSX ','object file using Nasm'#010+ + '3*2Anasmwd','osx_Win32/WDOSX object file using Nasm'#010+ '3*2Awasm_Obj file using Wasm (Watcom)'#010+ '3*2Anasmobj_Obj file using Nasm'#010+ '3*2Amasm_Obj file using Masm (Microsoft)'#010+ '3*2Atasm_Obj file using Tasm (Borland)'#010+ '3*2Aelf_ELF (Linux) using internal writer'#010+ - '3*2Acoff_COFF (Go32v2) us','ing internal writer'#010+ + '3*2Acoff_','COFF (Go32v2) using internal writer'#010+ '3*2Apecoff_PE-COFF (Win32) using internal writer'#010+ '4*2Aas_Assemble using GNU AS'#010+ '6*2Aas_Unix o-file using GNU AS'#010+ '6*2Agas_GNU Motorola assembler'#010+ '6*2Amit_MIT Syntax (old GAS)'#010+ - '6*2Amot_Standard Motorola assembler'#010+ - 'A*2Aas_Assembl','e using GNU AS'#010+ + '6*2Amot_Standard Motorola assemble','r'#010+ + 'A*2Aas_Assemble using GNU AS'#010+ 'P*2Aas_Assemble using GNU AS'#010+ 'S*2Aas_Assemble using GNU AS'#010+ '**1b_Generate browser info'#010+ '**2bl_Generate local symbol info'#010+ '**1B_Build all modules'#010+ '**1C_Code generation options:'#010+ - '**2Ca_Select ABI, see fpc -i for possible values',#010+ + '**2Ca_Select ABI, see fpc -i for',' possible values'#010+ '**2Cb_Generate big-endian code'#010+ '**2Cc_Set default calling convention to '#010+ '**2CD_Create also dynamic library (not supported)'#010+ '**2Ce_Compilation with emulated floating point opcodes'#010+ - '**2Cf_Select fpu instruction set to use, see fpc -i f','or possible '+ + '**2Cf_Select fpu instruction set to u','se, see fpc -i for possible '+ 'values'#010+ '**2CF_Minimal floating point constant precision (default, 32, 64)'#010+ '**2Cg_Generate PIC code'#010+ '**2Ch_ bytes heap (between 1023 and 67107840)'#010+ '**2Ci_IO-checking'#010+ '**2Cn_Omit linking stage'#010+ - '**2Co_Check overflow of integer o','perations'#010+ + '**2Co_Check overf','low of integer operations'#010+ '**2CO_Check for possible overflow of integer operations'#010+ '**2Cp_Select instruction set, see fpc -i for possible values'#010+ '**2CP=_ packing settings'#010+ - '**3CPPACKSET=_ set allocation: 0, 1 or DEFAULT or NORMAL, 2, 4 '+ - 'and 8'#010+ - '**2','Cr_Range checking'#010+ + '**3CPPACKSET=_ set allocation: 0, 1 or DEFAULT or NORMAL',', 2, '+ + '4 and 8'#010+ + '**2Cr_Range checking'#010+ '**2CR_Verify object method call validity'#010+ '**2Cs_Set stack checking size to '#010+ '**2Ct_Stack checking (for testing only, see manual)'#010+ '**2CX_Create also smartlinked library'#010+ '**1d_Defines the symbol '#010+ - '**1D_Generate a DEF ','file'#010+ + '**1D','_Generate a DEF file'#010+ '**2Dd_Set description to '#010+ '**2Dv_Set DLL version to '#010+ '*O2Dw_PM application'#010+ @@ -1013,120 +1024,121 @@ const msgtxt : array[0..000216,1..240] of char=( '**1E_Same as -Cn'#010+ '**1fPIC_Same as -Cg'#010+ '**1F_Set file names and paths:'#010+ - '**2Fa[,y]_(for a program) load units and ','[y] before uses is p'+ + '**2Fa[,y]_(for a program) loa','d units and [y] before uses is p'+ 'arsed'#010+ '**2Fc_Set input codepage to '#010+ '**2FC_Set RC compiler binary name to '#010+ '**2Fd_Disable the compiler'#039's internal directory cache'#010+ - '**2FD_Set the directory where to search for compiler utilities'#010+ - '**2Fe_Redire','ct error output to '#010+ + '**2FD_Set the directory where to search for compiler utilities',#010+ + '**2Fe_Redirect error output to '#010+ '**2Ff_Add to framework path (Darwin only)'#010+ '**2FE_Set exe/unit output path to '#010+ '**2Fi_Add to include path'#010+ '**2Fl_Add to library path'#010+ '**2FL_Use as dynamic linker'#010+ - '**2Fm_Load unicode conv','ersion table from .txt in the compiler '+ + '**2Fm_L','oad unicode conversion table from .txt in the compiler '+ 'dir'#010+ '**2Fo_Add to object path'#010+ '**2Fr_Load error message file '#010+ '**2FR_Set resource (.res) linker to '#010+ '**2Fu_Add to unit path'#010+ - '**2FU_Set unit output path to , overrides -FE'#010, + '**2FU_Set unit output path to ',', overrides -FE'#010+ '**2FW_Store generated whole-program optimization feedback in '#010+ '**2Fw_Load previously stored whole-program optimization feedback fr'+ 'om '#010+ '*g1g_Generate debug information (default format for target)'#010+ - '*g2gc_Generate checks for pointers'#010, + '*g2gc_Generate chec','ks for pointers'#010+ '*g2gh_Use heaptrace unit (for memory leak/corruption debugging)'#010+ '*g2gl_Use line info unit (show more info with backtraces)'#010+ '*g2go_Set debug information options'#010+ - '*g3godwarfsets_ Enable DWARF set debug information (breaks gdb < 6.5)'#010+ - '*g3gostab','sabsincludes_ Store absolute/full include file paths in Sta'+ - 'bs'#010+ + '*g3godwarfsets_ Enable DWARF set debug information (breaks gdb ','< 6.5'+ + ')'#010+ + '*g3gostabsabsincludes_ Store absolute/full include file paths in Stabs'+ + #010+ '*g2gp_Preserve case in stabs symbol names'#010+ '*g2gs_Generate Stabs debug information'#010+ '*g2gt_Trash local variables (to detect uninitialized uses)'#010+ - '*g2gv_Generates programs traceable wit','h Valgrind'#010+ + '*g2gv_Generates progra','ms traceable with Valgrind'#010+ '*g2gw_Generate DWARFv2 debug information (same as -gw2)'#010+ '*g2gw2_Generate DWARFv2 debug information'#010+ '*g2gw3_Generate DWARFv3 debug information'#010+ '**1i_Information'#010+ '**2iD_Return compiler date'#010+ - '**2iV_Return short compiler version'#010+ - '**2iW_Ret','urn full compiler version'#010+ + '**2iV_Return short compiler v','ersion'#010+ + '**2iW_Return full compiler version'#010+ '**2iSO_Return compiler OS'#010+ '**2iSP_Return compiler host processor'#010+ '**2iTO_Return target OS'#010+ '**2iTP_Return target processor'#010+ '**1I_Add to include path'#010+ '**1k_Pass to the linker'#010+ - '**1l_Write logo'#010+ - '**1M_Set lang','uage mode to '#010+ + '**1l_Write logo'#010, + '**1M_Set language mode to '#010+ '**2Mfpc_Free Pascal dialect (default)'#010+ '**2Mobjfpc_FPC mode with Object Pascal support'#010+ '**2Mdelphi_Delphi 7 compatibility mode'#010+ '**2Mtp_TP/BP 7.0 compatibility mode'#010+ - '**2Mmacpas_Macintosh Pascal dialects compatibility mode'#010+ - '**1n_Do',' not read the default config files'#010+ + '**2Mmacpas_Macintosh Pascal dialects compatibil','ity mode'#010+ + '**1n_Do not read the default config files'#010+ '**1N_Node tree optimizations'#010+ '**2Nu_Unroll loops'#010+ '**1o_Change the name of the executable produced to '#010+ '**1O_Optimizations:'#010+ '**2O-_Disable optimizations'#010+ - '**2O1_Level 1 optimizations (quick and debugg','er friendly)'#010+ + '**2O1_Level 1 optimizations (','quick and debugger friendly)'#010+ '**2O2_Level 2 optimizations (-O1 + quick optimizations)'#010+ '**2O3_Level 3 optimizations (-O2 + slow optimizations)'#010+ '**2Oa=_Set alignment'#010+ '**2Oo[NO]_Enable or disable optimizations, see fpc -i for possible '+ - 'values'#010+ - '**2Op_Set',' target cpu for optimizing, see fpc -i for possible valu'+ - 'es'#010+ + 'val','ues'#010+ + '**2Op_Set target cpu for optimizing, see fpc -i for possible values'+ + #010+ '**2OW_Generate whole-program optimization feedback for optimization'+ ' , see fpc -i for possible values'#010+ - '**2Ow_Perform whole-program optimization , see fpc -i for possib'+ - 'le v','alues'#010+ + '**2Ow_Perform whole-program optimization , see fpc -','i for poss'+ + 'ible values'#010+ '**2Os_Optimize for size rather than speed'#010+ '**1pg_Generate profile code for gprof (defines FPC_PROFILE)'#010+ '**1R_Assembler reading style:'#010+ '**2Rdefault_Use default assembler for target'#010+ '3*2Ratt_Read AT&T style assembler'#010+ - '3*2Rintel_Read Intel',' style assembler'#010+ + '3*2R','intel_Read Intel style assembler'#010+ '6*2RMOT_Read motorola style assembler'#010+ '**1S_Syntax options:'#010+ '**2S2_Same as -Mobjfpc'#010+ '**2Sc_Support operators like C (*=,+=,/= and -=)'#010+ '**2Sa_Turn on assertions'#010+ '**2Sd_Same as -Mdelphi'#010+ - '**2Se_Error options. is a combinat','ion of the following:'#010+ + '**2Se_Error options. <','x> is a combination of the following:'#010+ '**3*_ : Compiler halts after the errors (default is 1)'#010+ '**3*_w : Compiler also halts after warnings'#010+ '**3*_n : Compiler also halts after notes'#010+ '**3*_h : Compiler also halts after hints'#010+ - '**2Sg_Enable LABEL and GOTO (d','efault in -Mtp and -Mdelphi)'#010+ + '**2Sg_Enable L','ABEL and GOTO (default in -Mtp and -Mdelphi)'#010+ '**2Sh_Use ansistrings by default instead of shortstrings'#010+ '**2Si_Turn on inlining of procedures/functions declared as "inline"'#010+ '**2Sk_Load fpcylix unit'#010+ '**2SI_Set interface style to '#010+ - '**3SIcom_COM compatible in','terface (default)'#010+ + '**3SIcom_C','OM compatible interface (default)'#010+ '**3SIcorba_CORBA compatible interface'#010+ '**2Sm_Support macros like C (global)'#010+ '**2So_Same as -Mtp'#010+ '**2Ss_Constructor name must be init (destructor must be done)'#010+ '**2St_Allow static keyword in objects'#010+ - '**2Sx_Enable exception keywo','rds (default in Delphi/ObjFPC modes)'#010+ + '**2Sx_Enable',' exception keywords (default in Delphi/ObjFPC modes)'#010+ '**1s_Do not call assembler and linker'#010+ '**2sh_Generate script to link on host'#010+ '**2st_Generate script to link on target'#010+ '**2sr_Skip register allocation phase (use with -alr)'#010+ - '**1T_Target operating system:'#010+ - '3','*2Temx_OS/2 via EMX (including EMX/RSX extender)'#010+ + '**1T_Target ope','rating system:'#010+ + '3*2Temx_OS/2 via EMX (including EMX/RSX extender)'#010+ '3*2Tfreebsd_FreeBSD'#010+ '3*2Tgo32v2_Version 2 of DJ Delorie DOS extender'#010+ '3*2Tlinux_Linux'#010+ '3*2Tnetbsd_NetBSD'#010+ '3*2Tnetware_Novell Netware Module (clib)'#010+ - '3*2Tnetwlibc_Novell Netware Module (libc)'#010+ - '3*2Top','enbsd_OpenBSD'#010+ + '3*2Tnetwlibc_Novell Netware Modu','le (libc)'#010+ + '3*2Topenbsd_OpenBSD'#010+ '3*2Tos2_OS/2 / eComStation'#010+ '3*2Tsunos_SunOS/Solaris'#010+ '3*2Tsymbian_Symbian OS'#010+ @@ -1135,7 +1147,7 @@ const msgtxt : array[0..000216,1..240] of char=( '3*2Twin32_Windows 32 Bit'#010+ '3*2Twince_Windows CE'#010+ '4*2Tlinux_Linux'#010+ - '6*2Tamiga_Commodore',' Amiga'#010+ + '6*2','Tamiga_Commodore Amiga'#010+ '6*2Tatari_Atari ST/STe/TT'#010+ '6*2Tlinux_Linux/m68k'#010+ '6*2Tmacos_Macintosh m68k (not supported)'#010+ @@ -1144,86 +1156,86 @@ const msgtxt : array[0..000216,1..240] of char=( 'A*2Twince_Windows CE'#010+ 'P*2Tamiga_AmigaOS on PowerPC'#010+ 'P*2Tdarwin_Darwin and Mac OS X on PowerPC'#010+ - 'P*2Tlinux_Linux on ','PowerPC'#010+ + 'P*2','Tlinux_Linux on PowerPC'#010+ 'P*2Tmacos_Mac OS (classic) on PowerPC'#010+ 'P*2Tmorphos_MorphOS'#010+ 'S*2Tlinux_Linux'#010+ '**1u_Undefines the symbol '#010+ '**1U_Unit options:'#010+ '**2Un_Do not check where the unit name matches the file name'#010+ - '**2Ur_Generate release unit files (never auto','matically recompiled)'#010+ + '**2Ur_Generate release unit f','iles (never automatically recompiled)'#010+ '**2Us_Compile a system unit'#010+ '**1v_Be verbose. is a combination of the following letters:'#010+ '**2*_e : Show errors (default) 0 : Show nothing (except errors)'#010+ - '**2*_w : Show warnings u : Show unit in','fo'#010+ + '**2*_w : Show warnings ','u : Show unit info'#010+ '**2*_n : Show notes t : Show tried/used files'#010+ '**2*_h : Show hints c : Show conditionals'#010+ '**2*_i : Show general info d : Show debug info'#010+ - '**2*_l : Show linenumbers r : Rhide/GCC compati','bility mod'+ + '**2*_l : Show linenumbers r : R','hide/GCC compatibility mod'+ 'e'#010+ '**2*_s : Show time stamps q : Show message numbers'#010+ '**2*_a : Show everything x : Executable info (Win32 only)'#010+ '**2*_b : Write file names messages p : Write tree.log with parse tre'+ 'e'#010+ - '**2*_ with full path ',' v : Write fpcdebug.txt with'#010+ + '**2*_ ',' with full path v : Write fpcdebug.txt with'#010+ '**2*_ lots of debugging info'#010+ '**2*_m, : Don'#039't show messages numbered and '#010+ '3*1W_Target-specific options (targets)'#010+ - 'A*1W_Target-specific options (tar','gets)'#010+ + 'A*1W_Target-speci','fic options (targets)'#010+ 'P*1W_Target-specific options (targets)'#010+ 'p*1W_Target-specific options (targets)'#010+ '3*2Wb_Create a bundle instead of a library (Darwin)'#010+ 'P*2Wb_Create a bundle instead of a library (Darwin)'#010+ - 'p*2Wb_Create a bundle instead of a library (Da','rwin)'#010+ + 'p*2Wb_Create a bundle instead ','of a library (Darwin)'#010+ '3*2WB_Create a relocatable image (Windows)'#010+ 'A*2WB_Create a relocatable image (Windows, Symbian)'#010+ '3*2WC_Specify console type application (EMX, OS/2, Windows)'#010+ 'A*2WC_Specify console type application (Windows)'#010+ - 'P*2WC_Specify console type app','lication (Classic Mac OS)'#010+ + 'P*2WC_Specify ','console type application (Classic Mac OS)'#010+ '3*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+ 'A*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+ '3*2We_Use external resources (Darwin)'#010+ - 'P*2We_Use external resources (Darwin)'#010+ - 'p*2We_Use exte','rnal resources (Darwin)'#010+ + 'P*2We_Use external resources (Darwin',')'#010+ + 'p*2We_Use external resources (Darwin)'#010+ '3*2WF_Specify full-screen type application (EMX, OS/2)'#010+ '3*2WG_Specify graphic type application (EMX, OS/2, Windows)'#010+ 'A*2WG_Specify graphic type application (Windows)'#010+ - 'P*2WG_Specify graphic type application (Classic Mac ','OS)'#010+ + 'P*2WG_Specify graphic type applicati','on (Classic Mac OS)'#010+ '3*2Wi_Use internal resources (Darwin)'#010+ 'P*2Wi_Use internal resources (Darwin)'#010+ 'p*2Wi_Use internal resources (Darwin)'#010+ '3*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+ - 'A*2WN_Do not generate relocation code, needed for de','bugging (Windows'+ + 'A*2WN_Do not generate relocation cod','e, needed for debugging (Windows'+ ')'#010+ '3*2WR_Generate relocation code (Windows)'#010+ 'A*2WR_Generate relocation code (Windows)'#010+ 'P*2WT_Specify MPW tool type application (Classic Mac OS)'#010+ '3*2WX_Enable executable stack (Linux)'#010+ - 'A*2WX_Enable executable stack (Linux)'#010+ - 'p*2WX_E','nable executable stack (Linux)'#010+ + 'A*2WX_Enable executable stack',' (Linux)'#010+ + 'p*2WX_Enable executable stack (Linux)'#010+ 'P*2WX_Enable executable stack (Linux)'#010+ '**1X_Executable options:'#010+ '**2Xc_Pass --shared/-dynamic to the linker (BeOS, Darwin, FreeBSD, Lin'+ 'ux)'#010+ - '**2Xd_Do not use standard library search path (needed for cross compil'+ - 'e)',#010+ + '**2Xd_Do not use standard library search path (needed fo','r cross comp'+ + 'ile)'#010+ '**2Xe_Use external linker'#010+ '**2Xg_Create debuginfo in a separate file and add a debuglink section '+ 'to executable'#010+ '**2XD_Try to link units dynamically (defines FPC_LINK_DYNAMIC)'#010+ '**2Xi_Use internal linker'#010+ - '**2Xm_Generate link map'#010+ - '**2XM_Se','t the name of the '#039'main'#039' program routine (default'+ - ' is '#039'main'#039')'#010+ + '**2Xm_Generate link',' map'#010+ + '**2XM_Set the name of the '#039'main'#039' program routine (default i'+ + 's '#039'main'#039')'#010+ '**2XP_Prepend the binutils names with the prefix '#010+ '**2Xr_Set library search path to (needed for cross compile) (Be'+ 'OS, Linux)'#010+ - '**2XR_Prepend to all linker search ','paths (BeOS, Darwin, FreeB'+ + '**2XR_Prepend to al','l linker search paths (BeOS, Darwin, FreeB'+ 'SD, Linux, Mac OS, Solaris)'#010+ '**2Xs_Strip all symbols from executable'#010+ '**2XS_Try to link units statically (default, defines FPC_LINK_STATIC)'#010+ - '**2Xt_Link with static libraries (-static is passed to linker)'#010+ - '**2XX_Try to ','smartlink units (defines FPC_LINK_SMART)'#010+ + '**2Xt_Link with static libraries (-static is passed to linke','r)'#010+ + '**2XX_Try to smartlink units (defines FPC_LINK_SMART)'#010+ '**1*_'#010+ '**1?_Show this help'#010+ '**1h_Shows this help without waiting' diff --git a/compiler/nadd.pas b/compiler/nadd.pas index 2feb86df2d..7f83a8ff0f 100644 --- a/compiler/nadd.pas +++ b/compiler/nadd.pas @@ -1560,18 +1560,18 @@ implementation end { class or interface equation } - else if is_class_or_interface(rd) or is_class_or_interface(ld) then + else if is_class_or_interface_or_objc(rd) or is_class_or_interface_or_objc(ld) then begin if (nodetype in [equaln,unequaln]) then begin - if is_class_or_interface(rd) and is_class_or_interface(ld) then + if is_class_or_interface_or_objc(rd) and is_class_or_interface_or_objc(ld) then begin if tobjectdef(rd).is_related(tobjectdef(ld)) then inserttypeconv(right,left.resultdef) else inserttypeconv(left,right.resultdef); end - else if is_class_or_interface(rd) then + else if is_class_or_interface_or_objc(rd) then inserttypeconv(left,right.resultdef) else inserttypeconv(right,left.resultdef); @@ -1595,7 +1595,7 @@ implementation end { allows comperasion with nil pointer } - else if is_class_or_interface(rd) or (rd.typ=classrefdef) then + else if is_class_or_interface_or_objc(rd) or (rd.typ=classrefdef) then begin if (nodetype in [equaln,unequaln]) then inserttypeconv(left,right.resultdef) @@ -1603,7 +1603,7 @@ implementation CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),ld.typename,rd.typename); end - else if is_class_or_interface(ld) or (ld.typ=classrefdef) then + else if is_class_or_interface_or_objc(ld) or (ld.typ=classrefdef) then begin if (nodetype in [equaln,unequaln]) then inserttypeconv(right,left.resultdef) @@ -2671,7 +2671,7 @@ implementation expectloc:=LOC_FLAGS; end - else if is_class_or_interface(ld) then + else if is_class_or_interface_or_objc(ld) then begin expectloc:=LOC_FLAGS; end diff --git a/compiler/ncgmem.pas b/compiler/ncgmem.pas index 2a6dcc69a0..b5549b7354 100644 --- a/compiler/ncgmem.pas +++ b/compiler/ncgmem.pas @@ -273,9 +273,8 @@ implementation if codegenerror then exit; paraloc1.init; - { classes and interfaces must be dereferenced implicit } - if is_class_or_interface(left.resultdef) or - is_objcclass(left.resultdef) then + { classes and interfaces must be dereferenced implicitly } + if is_class_or_interface_or_objc(left.resultdef) then begin { the contents of a class are aligned to a sizeof(pointer) } location_reset_ref(location,LOC_REFERENCE,def_cgsize(resultdef),sizeof(pint)); diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index a9f02b0d56..5cd9ecf4a3 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -2867,7 +2867,8 @@ implementation { test validity of VMT } if not(is_interface(objdef)) and - not(is_cppclass(objdef)) then + not(is_cppclass(objdef)) and + not(is_objc_class_or_protocol(objdef)) then cg.g_maybe_testvmt(list,vmtreg,objdef); end; diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index 0f185f0598..b00597d8c5 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -1793,8 +1793,8 @@ implementation make_not_regable(left,[ra_addr_regable]); { class/interface to class/interface, with checkobject support } - if is_class_or_interface(resultdef) and - is_class_or_interface(left.resultdef) then + if is_class_or_interface_or_objc(resultdef) and + is_class_or_interface_or_objc(left.resultdef) then begin { check if the types are related } if not(nf_internal in flags) and @@ -1815,7 +1815,9 @@ implementation end; { Add runtime check? } - if (cs_check_object in current_settings.localswitches) and + if not is_objc_class_or_protocol(resultdef) and + not is_objc_class_or_protocol(left.resultdef) and + (cs_check_object in current_settings.localswitches) and not(nf_internal in flags) then begin { we can translate the typeconvnode to 'as' when @@ -1866,7 +1868,7 @@ implementation { however, there are some exceptions } (not(resultdef.typ in [arraydef,recorddef,setdef,stringdef, filedef,variantdef,objectdef]) or - is_class_or_interface(resultdef) or + is_class_or_interface_or_objc(resultdef) or { the softfloat code generates casts to record } (nf_internal in flags) )) diff --git a/compiler/nmem.pas b/compiler/nmem.pas index 2e06a16fc6..4440c384a3 100644 --- a/compiler/nmem.pas +++ b/compiler/nmem.pas @@ -629,8 +629,8 @@ implementation if codegenerror then exit; - { classes must be dereferenced implicit } - if is_class_or_interface(left.resultdef) then + { classes must be dereferenced implicitly } + if is_class_or_interface_or_objc(left.resultdef) then expectloc:=LOC_REFERENCE else begin diff --git a/compiler/nobj.pas b/compiler/nobj.pas index b08bd5b3a2..68f8d41d8f 100644 --- a/compiler/nobj.pas +++ b/compiler/nobj.pas @@ -39,6 +39,7 @@ interface _Class : tobjectdef; function is_new_vmt_entry(pd:tprocdef):boolean; procedure add_new_vmt_entry(pd:tprocdef); + function check_msg_str(vmtpd, pd: tprocdef):boolean; function intf_search_procdef_by_name(proc: tprocdef;const name: string): tprocdef; procedure intf_get_procdefs(ImplIntf:TImplementedInterface;IntfDef:TObjectDef); procedure intf_get_procdefs_recursive(ImplIntf:TImplementedInterface;IntfDef:TObjectDef); @@ -47,7 +48,8 @@ interface public constructor create(c:tobjectdef); destructor destroy;override; - procedure generate_vmt; + procedure generate_vmt; + procedure build_interface_mappings; end; type @@ -179,9 +181,49 @@ implementation end; + function TVMTBuilder.check_msg_str(vmtpd, pd: tprocdef): boolean; + begin + result:=true; + if not(is_objc_class_or_protocol(_class)) then + begin + { the only requirement for normal methods is that both either + have a message string or not (the value is irrelevant) } + if ((pd.procoptions * [po_msgstr]) <> (vmtpd.procoptions * [po_msgstr])) then + begin + MessagePos1(pd.fileinfo,parser_e_header_dont_match_forward,pd.fullprocname(false)); + tprocsym(vmtpd.procsym).write_parameter_lists(pd); + result:=false; + end + end + else + begin + { the compiler should have ensured that the protocol or parent + class method has a message name specified } + if not(po_msgstr in vmtpd.procoptions) then + internalerror(2009070601); + if not(po_msgstr in pd.procoptions) then + begin + { copy the protocol's/parent class' message name to the one in + the class if none has been specified there } + include(pd.procoptions,po_msgstr); + pd.messageinf.str:=stringdup(vmtpd.messageinf.str^); + end + else + begin + { if both have a message name, make sure they are equal } + if (vmtpd.messageinf.str^<>pd.messageinf.str^) then + begin + MessagePos2(pd.fileinfo,parser_e_objc_message_name_changed,vmtpd.messageinf.str^,pd.messageinf.str^); + result:=false; + end; + end; + end; + end; + + function TVMTBuilder.is_new_vmt_entry(pd:tprocdef):boolean; const - po_comp = [po_classmethod,po_virtualmethod,po_staticmethod,po_interrupt,po_iocheck,po_msgstr,po_msgint, + po_comp = [po_classmethod,po_virtualmethod,po_staticmethod,po_interrupt,po_iocheck,po_msgint, po_exports,po_varargs,po_explicitparaloc,po_nostackframe]; var i : longint; @@ -233,7 +275,7 @@ implementation ( not(po_virtualmethod in pd.procoptions) or { new one has not override } - (is_class_or_interface(_class) and not(po_overridingmethod in pd.procoptions)) + (is_class_or_interface_or_objc(_class) and not(po_overridingmethod in pd.procoptions)) ) then begin if ( @@ -242,7 +284,31 @@ implementation ) then begin if not(po_reintroduce in pd.procoptions) then - MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname(false)); + if not(is_objc_class_or_protocol(_class)) then + MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname(false)) + else + begin + { In Objective-C, you cannot create a new VMT entry to + start a new inheritance tree. We therefore give an + error when the class is implemented in Pascal, to + avoid confusion due to things working differently + with Object Pascal classes. + + In case of external classes, we only give a hint, + because requiring override everywhere may make + automated header translation tools too complex. } + if not(oo_is_external in _class.objectoptions) then + MessagePos1(pd.fileinfo,parser_e_must_use_override_objc,pd.fullprocname(false)) + { there may be a lot of these in auto-translated + heaeders, so only calculate the fullprocname if + the hint will be shown } + else if CheckVerbosity(V_Hint) then + MessagePos1(pd.fileinfo,parser_h_should_use_override_objc,pd.fullprocname(false)); + { no new entry, but copy the message name if any from + the procdef in the parent class } + check_msg_str(vmtpd,pd); + exit; + end; { disable/hide old VMT entry } vmtentry^.visibility:=vis_hidden; end; @@ -275,6 +341,8 @@ implementation tprocsym(vmtpd.procsym).write_parameter_lists(pd); end; + check_msg_str(vmtpd,pd); + { Give a note if the new visibility is lower. For a higher visibility update the vmt info } if vmtentry^.visibility>pd.visibility then @@ -301,10 +369,12 @@ implementation begin if not(po_reintroduce in pd.procoptions) then begin - if not is_object(_class) then + if not is_object(_class) and + not is_objc_class_or_protocol(_class) then MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname(false)) else - { objects don't allow starting a new virtual tree } + { objects don't allow starting a new virtual tree + and neither does Objective-C } MessagePos1(pd.fileinfo,parser_e_header_dont_match_forward,vmtpd.fullprocname(false)); end; { disable/hide old VMT entry } @@ -320,7 +390,7 @@ implementation function TVMTBuilder.intf_search_procdef_by_name(proc: tprocdef;const name: string): tprocdef; const - po_comp = [po_classmethod,po_staticmethod,po_interrupt,po_iocheck,po_msgstr,po_msgint, + po_comp = [po_classmethod,po_staticmethod,po_interrupt,po_iocheck,po_msgint, po_exports,po_varargs,po_explicitparaloc,po_nostackframe]; var implprocdef : Tprocdef; @@ -346,7 +416,8 @@ implementation (compare_defs(proc.returndef,implprocdef.returndef,nothingn)>=te_equal) and (proc.proccalloption=implprocdef.proccalloption) and (proc.proctypeoption=implprocdef.proctypeoption) and - ((proc.procoptions*po_comp)=((implprocdef.procoptions+[po_virtualmethod])*po_comp)) then + ((proc.procoptions*po_comp)=((implprocdef.procoptions+[po_virtualmethod])*po_comp)) and + check_msg_str(proc,implprocdef) then begin result:=implprocdef; exit; @@ -386,9 +457,32 @@ implementation implprocdef:=intf_search_procdef_by_name(tprocdef(def),tprocdef(def).procsym.name); { Add procdef to the implemented interface } if assigned(implprocdef) then - ImplIntf.AddImplProc(implprocdef) + begin + if (implprocdef._class.objecttype<>odt_objcclass) then + ImplIntf.AddImplProc(implprocdef) + else + begin + { If no message name has been specified for the method + in the objcclass, copy it from the protocol + definition. } + if not(po_msgstr in tprocdef(def).procoptions) then + begin + include(tprocdef(def).procoptions,po_msgstr); + implprocdef.messageinf.str:=stringdup(tprocdef(def).messageinf.str^); + end + else + begin + { If a message name has been specified in the + objcclass, it has to match the message name in the + protocol definition. } + if (implprocdef.messageinf.str^<>tprocdef(def).messageinf.str^) then + MessagePos2(implprocdef.fileinfo,parser_e_objc_message_name_changed,tprocdef(def).messageinf.str^,implprocdef.messageinf.str^); + end; + end; + end else - if ImplIntf.IType=etStandard then + if (ImplIntf.IType=etStandard) and + not(tprocdef(def).optional) then Message1(sym_e_no_matching_implementation_found,tprocdef(def).fullprocname(false)); end; end; @@ -545,7 +639,6 @@ implementation var i : longint; def : tdef; - ImplIntf : TImplementedInterface; old_current_objectdef : tobjectdef; begin old_current_objectdef:=current_objectdef; @@ -574,7 +667,25 @@ implementation add_new_vmt_entry(tprocdef(def)); end; end; + build_interface_mappings; + if assigned(_class.ImplementedInterfaces) and + not(is_objc_class_or_protocol(_class)) then + begin + { Optimize interface tables to reuse wrappers } + intf_optimize_vtbls; + { Allocate interface tables } + intf_allocate_vtbls; + end; + current_objectdef:=old_current_objectdef; + end; + + + procedure TVMTBuilder.build_interface_mappings; + var + ImplIntf : TImplementedInterface; + i: longint; + begin { Find Procdefs implementing the interfaces } if assigned(_class.ImplementedInterfaces) then begin @@ -584,13 +695,7 @@ implementation ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]); intf_get_procdefs_recursive(ImplIntf,ImplIntf.IntfDef); end; - { Optimize interface tables to reuse wrappers } - intf_optimize_vtbls; - { Allocate interface tables } - intf_allocate_vtbls; end; - - current_objectdef:=old_current_objectdef; end; diff --git a/compiler/nutils.pas b/compiler/nutils.pas index 9f87a0dd79..0cb3b7c079 100644 --- a/compiler/nutils.pas +++ b/compiler/nutils.pas @@ -658,7 +658,7 @@ implementation end; subscriptn: begin - if is_class_or_interface(tunarynode(p).left.resultdef) then + if is_class_or_interface_or_objc(tunarynode(p).left.resultdef) then inc(result); if (result = NODE_COMPLEXITY_INF) then exit; diff --git a/compiler/pdecl.pas b/compiler/pdecl.pas index a125e722ee..6bf1b28757 100644 --- a/compiler/pdecl.pas +++ b/compiler/pdecl.pas @@ -278,19 +278,30 @@ implementation procedure types_dec; - procedure finish_objc_class(od: tobjectdef); + procedure get_objc_class_or_protocol_external_status(od: tobjectdef); begin { Objective-C classes can be external -> all messages inside are external (defined at the class level instead of per method, so that you cannot define some methods as external and some not) } - if (token = _ID) and - (idtoken = _EXTERNAL) then + if (token=_ID) and + (idtoken=_EXTERNAL) then begin consume(_EXTERNAL); + if (token=_ID) and + (idtoken=_NAME) then + begin + consume(_NAME); + od.objextname:=stringdup(get_stringconst); + end + else + od.objextname:=stringdup(od.objrealname^); consume(_SEMICOLON); od.make_all_methods_external; - end; + include(od.objectoptions,oo_is_external); + end + else { or also allow "public name 'x'"? } + od.objextname:=stringdup(od.objrealname^); end; @@ -380,7 +391,7 @@ implementation (token=_DISPINTERFACE) or (token=_OBJCCLASS)) and (assigned(ttypesym(sym).typedef)) and - is_class_or_interface_or_dispinterface(ttypesym(sym).typedef) and + is_class_or_interface_or_dispinterface_or_objc(ttypesym(sym).typedef) and (oo_is_forward in tobjectdef(ttypesym(sym).typedef).objectoptions) then begin case token of @@ -395,6 +406,8 @@ implementation objecttype:=odt_dispinterface; _OBJCCLASS : objecttype:=odt_objcclass; + _OBJCPROTOCOL : + objecttype:=odt_objcprotocol; else internalerror(200811072); end; @@ -432,7 +445,7 @@ implementation hdef:=tstoreddef(hdef).getcopy; { fix name, it is used e.g. for tables } - if is_class_or_interface_or_dispinterface(hdef) then + if is_class_or_interface_or_dispinterface_or_objc(hdef) then with tobjectdef(hdef) do begin stringdispose(objname); @@ -489,21 +502,33 @@ implementation end; objectdef : begin + try_consume_hintdirective(newtype.symoptions); + consume(_SEMICOLON); + + { we have to know whether the class or protocol is + external before the vmt is built, because some errors/ + hints depend on this } + if is_objc_class_or_protocol(hdef) then + get_objc_class_or_protocol_external_status(tobjectdef(hdef)); + { Build VMT indexes, skip for type renaming and forward classes } if (hdef.typesym=newtype) and not(oo_is_forward in tobjectdef(hdef).objectoptions) and - not(df_generic in hdef.defoptions) and - not is_objcclass(hdef) then + not(df_generic in hdef.defoptions) then begin vmtbuilder:=TVMTBuilder.Create(tobjectdef(hdef)); vmtbuilder.generate_vmt; vmtbuilder.free; end; - try_consume_hintdirective(newtype.symoptions); - consume(_SEMICOLON); - if is_objcclass(hdef) then - finish_objc_class(tobjectdef(hdef)); + { In case of an objcclass, verify that all methods have a message + name set. We only check this now, because message names can be set + during the protocol (interface) mapping. At the same time, set the + mangled names. + } + if is_objc_class_or_protocol(hdef) then + tobjectdef(hdef).check_and_finish_messages; + end; recorddef : begin diff --git a/compiler/pdecobj.pas b/compiler/pdecobj.pas index b071d08926..18c6a8314b 100644 --- a/compiler/pdecobj.pas +++ b/compiler/pdecobj.pas @@ -160,6 +160,23 @@ implementation end; + procedure setobjcclassmethodoptions; + var + i : longint; + def : tdef; + begin + for i:=0 to current_objectdef.symtable.DefList.count-1 do + begin + def:=tdef(current_objectdef.symtable.DefList[i]); + if assigned(def) and + (def.typ=procdef) then + begin + include(tprocdef(def).procoptions,po_virtualmethod); + end; + end; + end; + + procedure handleImplementedInterface(intfdef : tobjectdef); begin if not is_interface(intfdef) then @@ -180,7 +197,23 @@ implementation end; - procedure readImplementedInterfaces; + procedure handleImplementedProtocol(intfdef : tobjectdef); + begin + if not is_objcprotocol(intfdef) then + begin + Message1(type_e_protocol_type_expected,intfdef.typename); + exit; + end; + if current_objectdef.find_implemented_interface(intfdef)<>nil then + Message1(sym_e_duplicate_id,intfdef.objname^) + else + begin + current_objectdef.ImplementedInterfaces.Add(TImplementedInterface.Create(intfdef)); + end; + end; + + + procedure readImplementedInterfacesAndProtocols(intf: boolean); var hdef : tdef; begin @@ -189,10 +222,16 @@ implementation id_type(hdef,false); if (hdef.typ<>objectdef) then begin - Message1(type_e_interface_type_expected,hdef.typename); + if intf then + Message1(type_e_interface_type_expected,hdef.typename) + else + Message1(type_e_protocol_type_expected,hdef.typename); continue; end; - handleImplementedInterface(tobjectdef(hdef)); + if intf then + handleImplementedInterface(tobjectdef(hdef)) + else + handleImplementedProtocol(tobjectdef(hdef)); end; end; @@ -274,6 +313,18 @@ implementation Message(parser_e_mix_of_classes_and_objects); odt_objcclass: if not(is_objcclass(childof)) then + begin + if is_objcprotocol(childof) then + begin + intfchildof:=childof; + childof:=nil; + CGMessage(parser_h_no_objc_parent); + end + else + Message(parser_e_mix_of_classes_and_objects); + end; + odt_objcprotocol: + if not(is_objcprotocol(childof)) then Message(parser_e_mix_of_classes_and_objects); odt_object: if not(is_object(childof)) then @@ -325,11 +376,14 @@ implementation if hasparentdefined then begin - if current_objectdef.objecttype=odt_class then + if current_objectdef.objecttype in [odt_class,odt_objcclass] then begin if assigned(intfchildof) then - handleImplementedInterface(intfchildof); - readImplementedInterfaces; + if current_objectdef.objecttype=odt_class then + handleImplementedInterface(intfchildof) + else + handleImplementedProtocol(intfchildof); + readImplementedInterfacesAndProtocols(current_objectdef.objecttype=odt_class); end; consume(_RKLAMMER); end; @@ -374,14 +428,12 @@ implementation procedure chkobjc(pd: tprocdef); begin - if is_objcclass(pd._class) then + if is_objc_class_or_protocol(pd._class) then begin { none of the explicit calling conventions should be allowed } if (po_hascallingconvention in pd.procoptions) then internalerror(2009032501); pd.proccalloption:=pocall_cdecl; - if not(po_msgstr in pd.procoptions) then - Message(parser_e_objc_requires_msgstr); include(pd.procoptions,po_objc); end; end; @@ -450,11 +502,19 @@ implementation end; _ID : begin - case idtoken of + if is_objcprotocol(current_objectdef) and + ((idtoken=_REQUIRED) or + (idtoken=_OPTIONAL)) then + begin + current_objectdef.symtable.currentlyoptional:=(idtoken=_OPTIONAL); + consume(idtoken) + end + else case idtoken of _PRIVATE : begin - if is_interface(current_objectdef) then - Message(parser_e_no_access_specifier_in_interfaces); + if is_interface(current_objectdef) or + is_objcprotocol(current_objectdef) then + Message(parser_e_no_access_specifier_in_interfaces); consume(_PRIVATE); current_objectdef.symtable.currentvisibility:=vis_private; include(current_objectdef.objectoptions,oo_has_private); @@ -462,7 +522,8 @@ implementation end; _PROTECTED : begin - if is_interface(current_objectdef) then + if is_interface(current_objectdef) or + is_objcprotocol(current_objectdef) then Message(parser_e_no_access_specifier_in_interfaces); consume(_PROTECTED); current_objectdef.symtable.currentvisibility:=vis_protected; @@ -471,7 +532,8 @@ implementation end; _PUBLIC : begin - if is_interface(current_objectdef) then + if is_interface(current_objectdef) or + is_objcprotocol(current_objectdef) then Message(parser_e_no_access_specifier_in_interfaces); consume(_PUBLIC); current_objectdef.symtable.currentvisibility:=vis_public; @@ -482,15 +544,21 @@ implementation { we've to check for a pushlished section in non- } { publishable classes later, if a real declaration } { this is the way, delphi does it } - if is_interface(current_objectdef) then + if is_interface(current_objectdef) or + is_objcprotocol(current_objectdef) then Message(parser_e_no_access_specifier_in_interfaces); + { Objective-C classes do not support "published", + as basically everything is published. } + if is_objc_class_or_protocol(current_objectdef) then + Message(parser_e_no_objc_published); consume(_PUBLISHED); current_objectdef.symtable.currentvisibility:=vis_published; fields_allowed:=true; end; _STRICT : begin - if is_interface(current_objectdef) then + if is_interface(current_objectdef) or + is_objcprotocol(current_objectdef) then Message(parser_e_no_access_specifier_in_interfaces); consume(_STRICT); if token=_ID then @@ -520,7 +588,8 @@ implementation begin if object_member_blocktype=bt_general then begin - if is_interface(current_objectdef) then + if is_interface(current_objectdef) or + is_objcprotocol(current_objectdef) then Message(parser_e_no_vars_in_interfaces); if (current_objectdef.symtable.currentvisibility=vis_published) and @@ -601,7 +670,7 @@ implementation Message(parser_e_no_con_des_in_interfaces); { Objective-C does not know the concept of a constructor } - if is_objcclass(current_objectdef) then + if is_objc_class_or_protocol(current_objectdef) then Message(parser_e_objc_no_constructor_destructor); oldparse_only:=parse_only; @@ -639,7 +708,7 @@ implementation Message(parser_w_destructor_should_be_public); { Objective-C does not know the concept of a destructor } - if is_objcclass(current_objectdef) then + if is_objc_class_or_protocol(current_objectdef) then Message(parser_e_objc_no_constructor_destructor); oldparse_only:=parse_only; @@ -727,6 +796,14 @@ implementation class_tobject:=current_objectdef; end; end; + if (current_module.modulename^='OBJCBASE') then + begin + case current_objectdef.objecttype of + odt_objcclass: + if (current_objectdef.objname^='Protocol') then + objc_protocoltype:=current_objectdef; + end; + end; end; { set published flag in $M+ mode, it can also be inherited and will @@ -772,8 +849,11 @@ implementation not(oo_has_constructor in current_objectdef.objectoptions) then Message1(parser_w_virtual_without_constructor,current_objectdef.objrealname^); - if is_interface(current_objectdef) then - setinterfacemethodoptions; + if is_interface(current_objectdef) or + is_objcprotocol(current_objectdef) then + setinterfacemethodoptions + else if is_objcclass(current_objectdef) then + setobjcclassmethodoptions; { return defined objectdef } result:=current_objectdef; diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas index 6e8bc728ee..821dae25b5 100644 --- a/compiler/pdecsub.pas +++ b/compiler/pdecsub.pas @@ -40,7 +40,8 @@ interface pd_notprocvar, { directive can not be used procvar declaration } pd_dispinterface,{ directive can be used with dispinterface methods } pd_cppobject, { directive can be used with cppclass } - pd_objcclass { directive can be used with objcclass } + pd_objcclass, { directive can be used with objcclass } + pd_objcprot { directive can be used with objcprotocol } ); tpdflags=set of tpdflag; @@ -160,7 +161,7 @@ implementation vsp : tvarspez; begin if (pd.typ=procdef) and - is_objcclass(tprocdef(pd)._class) then + is_objc_class_or_protocol(tprocdef(pd)._class) then begin { insert Objective-C self and selector parameters } vs:=tparavarsym.create('$msgsel',paranr_vmt,vs_value,objc_seltype,[vo_is_msgsel,vo_is_hidden_para]); @@ -883,6 +884,7 @@ implementation { symbol options that need to be kept per procdef } pd.fileinfo:=procstartfilepos; pd.visibility:=symtablestack.top.currentvisibility; + pd.optional:=symtablestack.top.currentlyoptional; { parse parameters } if token=_LKLAMMER then @@ -932,6 +934,7 @@ implementation if is_interface(aclass) then Message(parser_e_no_static_method_in_interfaces) else + { class methods are also allowed for Objective-C protocols } isclassmethod:=true; end; case token of @@ -1329,7 +1332,7 @@ procedure pd_override(pd:tabstractprocdef); begin if pd.typ<>procdef then internalerror(2003042611); - if not(is_class_or_interface(tprocdef(pd)._class)) then + if not(is_class_or_interface_or_objc(tprocdef(pd)._class)) then Message(parser_e_no_object_override); end; @@ -1348,10 +1351,10 @@ begin if pd.typ<>procdef then internalerror(2003042613); if not is_class(tprocdef(pd)._class) and - not is_objcclass(tprocdef(pd)._class) then + not is_objc_class_or_protocol(tprocdef(pd)._class) then Message(parser_e_msg_only_for_classes); { check parameter type } - if not is_objcclass(tprocdef(pd)._class) then + if not is_objc_class_or_protocol(tprocdef(pd)._class) then begin paracnt:=0; pd.parast.SymList.ForEachCall(@check_msg_para,@paracnt); @@ -1365,11 +1368,6 @@ begin if (tstringconstnode(pt).len>255) then Message(parser_e_message_string_too_long); tprocdef(pd).messageinf.str:=stringdup(tstringconstnode(pt).value_str); - { the message string is the last part we need to set the mangled name - for an Objective-C message - } - if is_objcclass(tprocdef(pd)._class) then - tprocdef(pd).setmangledname(tprocdef(pd).objcmangledname); end else if is_constintnode(pt) and @@ -1855,7 +1853,7 @@ const mutexclpo : [po_external,po_exports] ),( idtok:_MESSAGE; - pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass]; + pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass, pd_objcprot]; handler : @pd_message; pocall : pocall_none; pooption : []; { can be po_msgstr or po_msgint } @@ -1900,7 +1898,7 @@ const mutexclpo : [] ),( idtok:_OVERRIDE; - pd_flags : [pd_interface,pd_object,pd_notobjintf]; + pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass]; handler : @pd_override; pocall : pocall_none; pooption : [po_overridingmethod,po_virtualmethod]; @@ -2013,7 +2011,7 @@ const mutexclpo : [po_assembler,po_external,po_virtualmethod] ),( idtok:_VARARGS; - pd_flags : [pd_interface,pd_implemen,pd_procvar,pd_objcclass]; + pd_flags : [pd_interface,pd_implemen,pd_procvar,pd_objcclass, pd_objcprot]; handler : nil; pocall : pocall_none; pooption : [po_varargs]; @@ -2110,7 +2108,7 @@ const begin { parsing a procvar type the name can be any next variable !! } - if ((pdflags * [pd_procvar,pd_object,pd_objcclass])=[]) and + if ((pdflags * [pd_procvar,pd_object,pd_objcclass,pd_objcprot])=[]) and not(idtoken=_PROPERTY) then Message1(parser_w_unknown_proc_directive_ignored,name); exit; @@ -2178,6 +2176,12 @@ const if is_objcclass(tprocdef(pd)._class) and not(pd_objcclass in proc_direcdata[p].pd_flags) then exit; + + { check if method and directive not for objcprotocol } + if is_objcprotocol(tprocdef(pd)._class) and + not(pd_objcprot in proc_direcdata[p].pd_flags) then + exit; + end; { consume directive, and turn flag on } diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas index be236f907e..09dffc02c1 100644 --- a/compiler/pexpr.pas +++ b/compiler/pexpr.pas @@ -370,11 +370,12 @@ implementation ttypenode(p1).allowed:=true; { Allow classrefdef, which is required for Typeof(self) in static class methods } - if (p1.resultdef.typ = objectdef) or - (assigned(current_procinfo) and - ((po_classmethod in current_procinfo.procdef.procoptions) or - (po_staticmethod in current_procinfo.procdef.procoptions)) and - (p1.resultdef.typ=classrefdef)) then + if not(is_objc_class_or_protocol(p1.resultdef)) and + ((p1.resultdef.typ = objectdef) or + (assigned(current_procinfo) and + ((po_classmethod in current_procinfo.procdef.procoptions) or + (po_staticmethod in current_procinfo.procdef.procoptions)) and + (p1.resultdef.typ=classrefdef))) then statement_syssym:=geninlinenode(in_typeof_x,false,p1) else begin @@ -488,7 +489,7 @@ implementation procvardef, classrefdef : ; objectdef : - if not is_class_or_interface(p1.resultdef) then + if not is_class_or_interface_or_objc(p1.resultdef) then begin Message(parser_e_illegal_parameter_list); err:=true; diff --git a/compiler/pstatmnt.pas b/compiler/pstatmnt.pas index b96184a9d0..6d29868565 100644 --- a/compiler/pstatmnt.pas +++ b/compiler/pstatmnt.pas @@ -536,7 +536,7 @@ implementation typecheckpass(p); end; { classes and interfaces have implicit dereferencing } - hasimplicitderef:=is_class_or_interface(p.resultdef) or + hasimplicitderef:=is_class_or_interface_or_objc(p.resultdef) or (p.resultdef.typ = classrefdef); if hasimplicitderef then hdef:=p.resultdef diff --git a/compiler/ptconst.pas b/compiler/ptconst.pas index 6b689a7b96..9a4c807e50 100644 --- a/compiler/ptconst.pas +++ b/compiler/ptconst.pas @@ -1223,7 +1223,7 @@ implementation end; { only allow nil for class and interface } - if is_class_or_interface(def) then + if is_class_or_interface_or_objc(def) then begin n:=comp_expr(true); if n.nodetype<>niln then diff --git a/compiler/ptype.pas b/compiler/ptype.pas index 5ec91e2810..5d9fafda7a 100644 --- a/compiler/ptype.pas +++ b/compiler/ptype.pas @@ -302,7 +302,7 @@ implementation { Reparse the original type definition } if not err then begin - { Firsta new typesym so we can reuse this specialization and + { First a new typesym so we can reuse this specialization and references to this specialization can be handled } srsym:=ttypesym.create(specializename,generrordef); specializest.insert(srsym); @@ -357,7 +357,7 @@ implementation (current_objectdef.objname^=pattern) and ( (testcurobject=2) or - is_class_or_interface(current_objectdef) + is_class_or_interface_or_objc(current_objectdef) )then begin consume(_ID); @@ -542,7 +542,7 @@ implementation (current_objectdef.objname^=pattern) and ( (testcurobject=2) or - is_class_or_interface(current_objectdef) + is_class_or_interface_or_objc(current_objectdef) )then begin consume(_ID); @@ -989,6 +989,9 @@ implementation end; _OBJCCLASS : begin + if not(m_objectivec1 in current_settings.modeswitches) then + Message(parser_f_need_objc); + consume(token); def:=object_dec(odt_objcclass,name,genericdef,genericlist,nil); end; @@ -1004,6 +1007,14 @@ implementation else {it_interfacecorba} def:=object_dec(odt_interfacecorba,name,genericdef,genericlist,nil); end; + _OBJCPROTOCOL : + begin + if not(m_objectivec1 in current_settings.modeswitches) then + Message(parser_f_need_objc); + + consume(token); + def:=object_dec(odt_objcprotocol,name,genericdef,genericlist,nil); + end; _OBJECT : begin consume(token); @@ -1105,7 +1116,7 @@ implementation if ( assigned(def.typesym) and (st.symtabletype=globalsymtable) and - not is_objcclass(def) + not is_objc_class_or_protocol(def) ) or def.needs_inittable or (ds_init_table_used in def.defstates) then @@ -1114,7 +1125,7 @@ implementation if ( assigned(def.typesym) and (st.symtabletype=globalsymtable) and - not is_objcclass(def) + not is_objc_class_or_protocol(def) ) or (ds_rtti_table_used in def.defstates) then RTTIWriter.write_rtti(def,fullrtti); diff --git a/compiler/symbase.pas b/compiler/symbase.pas index c6719e13d8..27c0d5eaba 100644 --- a/compiler/symbase.pas +++ b/compiler/symbase.pas @@ -96,6 +96,7 @@ interface moduleid : longint; refcount : smallint; currentvisibility : tvisibility; + currentlyoptional : boolean; { level of symtable, used for nested procedures } symtablelevel : byte; symtabletype : TSymtabletype; @@ -222,6 +223,7 @@ implementation SymList:=TFPHashObjectList.Create(true); refcount:=1; currentvisibility:=vis_public; + currentlyoptional:=false; end; diff --git a/compiler/symconst.pas b/compiler/symconst.pas index e6b6e19b0f..ff45b43460 100644 --- a/compiler/symconst.pas +++ b/compiler/symconst.pas @@ -290,7 +290,8 @@ type odt_interfacecorba, odt_cppclass, odt_dispinterface, - odt_objcclass + odt_objcclass, + odt_objcprotocol ); { Variations in interfaces implementation } @@ -317,7 +318,9 @@ type oo_has_msgint, oo_can_have_published,{ the class has rtti, i.e. you can publish properties } oo_has_default_property, - oo_has_valid_guid + oo_has_valid_guid, + oo_is_external, { the class is externally implemented (objcclass, cppclass) } + oo_is_anonymous { the class is only formally defined in this module (objcclass x = class; external;) } ); tobjectoptions=set of tobjectoption; diff --git a/compiler/symdef.pas b/compiler/symdef.pas index 7f3923a229..0ab97ff225 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -241,7 +241,9 @@ interface childofderef : tderef; objname, - objrealname : pshortstring; + objrealname, + { for Objective-C: protocols and classes can have the same name there } + objextname : pshortstring; objectoptions : tobjectoptions; { to be able to have a variable vmt position } { and no vmt field for objects without virtuals } @@ -301,7 +303,9 @@ interface procedure register_maybe_created_object_type; procedure register_created_classref_type; procedure register_vmt_call(index:longint); + { ObjC } procedure make_all_methods_external; + procedure check_and_finish_messages; end; tclassrefdef = class(tabstractpointerdef) @@ -488,7 +492,9 @@ interface { true if the procedure is declared in the interface } interfacedef : boolean; { true if the procedure has a forward declaration } - hasforward : boolean; + hasforward, + { true if the procedure is an optional method in an Objective-C protocol } + optional : boolean; { import info } import_dll, import_name : pshortstring; @@ -669,6 +675,8 @@ interface objc_superclasstype, objc_idtype, objc_seltype : tpointerdef; + { base type of @protocol(protocolname) Objective-C statements } + objc_protocoltype : tobjectdef; const {$ifdef i386} @@ -720,9 +728,13 @@ interface function is_cppclass(def: tdef): boolean; function is_objcclass(def: tdef): boolean; function is_objcclassref(def: tdef): boolean; + function is_objcprotocol(def: tdef): boolean; + function is_objc_class_or_protocol(def: tdef): boolean; function is_class_or_interface(def: tdef): boolean; + function is_class_or_interface_or_objc(def: tdef): boolean; function is_class_or_interface_or_object(def: tdef): boolean; function is_class_or_interface_or_dispinterface(def: tdef): boolean; + function is_class_or_interface_or_dispinterface_or_objc(def: tdef): boolean; procedure loadobjctypes; @@ -1118,7 +1130,7 @@ implementation procvardef : is_intregable:=not(po_methodpointer in tprocvardef(self).procoptions); objectdef: - is_intregable:=(is_class(self) or is_interface(self)) and not needs_inittable; + is_intregable:=(is_class_or_interface_or_objc(self)) and not needs_inittable; setdef: is_intregable:=is_smallset(self); recorddef: @@ -2937,6 +2949,7 @@ implementation forwarddef:=true; interfacedef:=false; hasforward:=false; + optional:=false; _class := nil; import_dll:=nil; import_name:=nil; @@ -2965,6 +2978,7 @@ implementation ppufile.getposinfo(fileinfo); visibility:=tvisibility(ppufile.getbyte); ppufile.getsmallset(symoptions); + optional:=boolean(ppufile.getbyte); {$ifdef powerpc} { library symbol for AmigaOS/MorphOS } ppufile.getderef(libsymderef); @@ -3102,6 +3116,7 @@ implementation ppufile.putposinfo(fileinfo); ppufile.putbyte(byte(visibility)); ppufile.putsmallset(symoptions); + ppufile.putbyte(byte(optional)); {$ifdef powerpc} { library symbol for AmigaOS/MorphOS } ppufile.putderef(libsymderef); @@ -3516,7 +3531,7 @@ implementation if not (po_msgstr in procoptions) then internalerror(2009030901); { we may very well need longer strings to handle these... } - if ((255-length(tobjectdef(procsym.owner.defowner).objrealname^) + if ((255-length(tobjectdef(procsym.owner.defowner).objextname^) -length('+[ ]')-length(messageinf.str^)) < 0) then Message1(parser_e_objc_message_name_too_long,messageinf.str^); if not(po_classmethod in procoptions) then @@ -3711,7 +3726,7 @@ implementation if objecttype in [odt_interfacecorba,odt_interfacecom,odt_dispinterface] then prepareguid; { setup implemented interfaces } - if objecttype in [odt_class,odt_interfacecorba] then + if objecttype in [odt_class,odt_interfacecorba,odt_objcclass] then ImplementedInterfaces:=TFPObjectList.Create(true) else ImplementedInterfaces:=nil; @@ -3731,6 +3746,10 @@ implementation objecttype:=tobjecttyp(ppufile.getbyte); objrealname:=stringdup(ppufile.getstring); objname:=stringdup(upper(objrealname^)); + objextname:=stringdup(ppufile.getstring); + { only used for external Objective-C classes/protocols } + if (objextname^='') then + stringdispose(objextname); symtable:=tObjectSymtable.create(self,objrealname^,0); tObjectSymtable(symtable).datasize:=ppufile.getaint; tObjectSymtable(symtable).fieldalignment:=ppufile.getbyte; @@ -3761,7 +3780,7 @@ implementation end; { load implemented interfaces } - if objecttype in [odt_class,odt_interfacecorba] then + if objecttype in [odt_class,odt_interfacecorba,odt_objcclass] then begin ImplementedInterfaces:=TFPObjectList.Create(true); implintfcount:=ppufile.getlongint; @@ -3792,6 +3811,10 @@ implementation (objecttype=odt_interfacecom) and (objname^='IUNKNOWN') then interface_iunknown:=self; + if (childof=nil) and + (objecttype=odt_objcclass) and + (objname^='PROTOCOL') then + objc_protocoltype:=self; writing_class_record_dbginfo:=false; end; @@ -3805,6 +3828,7 @@ implementation end; stringdispose(objname); stringdispose(objrealname); + stringdispose(objextname); stringdispose(iidstr); if assigned(ImplementedInterfaces) then begin @@ -3843,6 +3867,8 @@ implementation tobjectdef(result).objname:=stringdup(objname^); if assigned(objrealname) then tobjectdef(result).objrealname:=stringdup(objrealname^); + if assigned(objextname) then + tobjectdef(result).objextname:=stringdup(objextname^); tobjectdef(result).objectoptions:=objectoptions; include(tobjectdef(result).defoptions,df_copied_def); tobjectdef(result).vmt_offset:=vmt_offset; @@ -3875,6 +3901,10 @@ implementation inherited ppuwrite(ppufile); ppufile.putbyte(byte(objecttype)); ppufile.putstring(objrealname^); + if assigned(objextname) then + ppufile.putstring(objextname^) + else + ppufile.putstring(''); ppufile.putaint(tObjectSymtable(symtable).datasize); ppufile.putbyte(tObjectSymtable(symtable).fieldalignment); ppufile.putbyte(tObjectSymtable(symtable).recordalignment); @@ -4113,7 +4143,7 @@ implementation procedure tobjectdef.check_forwards; begin - if not(objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface]) then + if not(objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcprotocol]) then tstoredsymtable(symtable).check_forwards; if (oo_is_forward in objectoptions) then begin @@ -4179,7 +4209,7 @@ implementation function tobjectdef.size : aint; begin - if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcclass] then + if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcclass,odt_objcprotocol] then result:=sizeof(pint) else result:=tObjectSymtable(symtable).datasize; @@ -4188,7 +4218,7 @@ implementation function tobjectdef.alignment:shortint; begin - if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcclass] then + if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcclass,odt_objcprotocol] then alignment:=sizeof(pint) else alignment:=tObjectSymtable(symtable).recordalignment; @@ -4202,7 +4232,8 @@ implementation odt_class: { the +2*sizeof(pint) is size and -size } vmtmethodoffset:=(index+10)*sizeof(pint)+2*sizeof(pint); - odt_objcclass: + odt_objcclass, + odt_objcprotocol: vmtmethodoffset:=0; odt_interfacecom,odt_interfacecorba: vmtmethodoffset:=index*sizeof(pint); @@ -4237,7 +4268,8 @@ implementation odt_object: needs_inittable:=tObjectSymtable(symtable).needs_init_final; odt_cppclass, - odt_objcclass: + odt_objcclass, + odt_objcprotocol: needs_inittable:=false; else internalerror(200108267); @@ -4346,6 +4378,29 @@ implementation end; + procedure check_and_finish_msg(data: tobject; arg: pointer); + var + def: tdef absolute data; + begin + if (def.typ = procdef) then + begin + { we have to wait until now to set the mangled name because it + depends on the (possibly external) class name, which is defined + at the very end. } + if (po_msgstr in tprocdef(def).procoptions) then + tprocdef(def).setmangledname(tprocdef(def).objcmangledname) + else + MessagePos(tprocdef(def).fileinfo,parser_e_objc_requires_msgstr) + end; + end; + + + procedure tobjectdef.check_and_finish_messages; + begin + self.symtable.DefList.foreachcall(@check_and_finish_msg,nil); + end; + + {**************************************************************************** TImplementedInterface ****************************************************************************} @@ -4644,6 +4699,24 @@ implementation end; + function is_objcprotocol(def: tdef): boolean; + begin + result:= + assigned(def) and + (def.typ=objectdef) and + (tobjectdef(def).objecttype=odt_objcprotocol); + end; + + + function is_objc_class_or_protocol(def: tdef): boolean; + begin + result:= + assigned(def) and + (def.typ=objectdef) and + (tobjectdef(def).objecttype in [odt_objcclass,odt_objcprotocol]); + end; + + function is_class_or_interface(def: tdef): boolean; begin result:= @@ -4653,6 +4726,15 @@ implementation end; + function is_class_or_interface_or_objc(def: tdef): boolean; + begin + result:= + assigned(def) and + (def.typ=objectdef) and + (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_objcclass,odt_objcprotocol]); + end; + + function is_class_or_interface_or_object(def: tdef): boolean; begin result:= @@ -4671,6 +4753,15 @@ implementation end; + function is_class_or_interface_or_dispinterface_or_objc(def: tdef): boolean; + begin + result:= + assigned(def) and + (def.typ=objectdef) and + (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcclass,odt_objcprotocol]); + end; + + procedure loadobjctypes; begin objc_metaclasstype:=tpointerdef(search_named_unit_globaltype('OBJC1','POBJC_CLASS').typedef); diff --git a/compiler/symtable.pas b/compiler/symtable.pas index 53d3e2780b..0f9d1bdfac 100644 --- a/compiler/symtable.pas +++ b/compiler/symtable.pas @@ -195,7 +195,7 @@ interface function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean; function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean; function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean; - function searchsym_in_named_module(const unitname, symname: TIDString; out srsym: tsym; out srsymtable: tsymtable): boolean; + function searchsym_in_named_module(const unitname, symname: TIDString; out srsym: tsym; out srsymtable: tsymtable): boolean; function searchsym_in_class(classh,contextclassh:tobjectdef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean; function searchsym_in_class_by_msgint(classh:tobjectdef;msgid:longint;out srdef : tdef;out srsym:tsym;out srsymtable:TSymtable):boolean; function searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string;out srsym:tsym;out srsymtable:TSymtable):boolean; diff --git a/compiler/tokens.pas b/compiler/tokens.pas index 32f55894e4..0fdcd80894 100644 --- a/compiler/tokens.pas +++ b/compiler/tokens.pas @@ -205,12 +205,14 @@ type _LOCATION, _MWPASCAL, _OPERATOR, + _OPTIONAL, _OVERLOAD, _OVERRIDE, _PLATFORM, _PROPERTY, _READONLY, _REGISTER, + _REQUIRED, _REQUIRES, _RESIDENT, _SAFECALL, @@ -244,6 +246,7 @@ type _EXPERIMENTAL, _FINALIZATION, _NOSTACKFRAME, + _OBJCPROTOCOL, _WEAKEXTERNAL, _DISPINTERFACE, _UNIMPLEMENTED, @@ -458,12 +461,14 @@ const (str:'LOCATION' ;special:false;keyword:m_none;op:NOTOKEN), (str:'MWPASCAL' ;special:false;keyword:m_none;op:NOTOKEN), (str:'OPERATOR' ;special:false;keyword:m_fpc;op:NOTOKEN), + (str:'OPTIONAL' ;special:false;keyword:m_none;op:NOTOKEN), { optional methods in an Objective-C protocol } (str:'OVERLOAD' ;special:false;keyword:m_none;op:NOTOKEN), (str:'OVERRIDE' ;special:false;keyword:m_none;op:NOTOKEN), (str:'PLATFORM' ;special:false;keyword:m_none;op:NOTOKEN), (str:'PROPERTY' ;special:false;keyword:m_property;op:NOTOKEN), (str:'READONLY' ;special:false;keyword:m_none;op:NOTOKEN), (str:'REGISTER' ;special:false;keyword:m_none;op:NOTOKEN), + (str:'REQUIRED' ;special:false;keyword:m_none;op:NOTOKEN), { required methods in an Objective-C protocol } (str:'REQUIRES' ;special:false;keyword:m_none;op:NOTOKEN), (str:'RESIDENT' ;special:false;keyword:m_none;op:NOTOKEN), (str:'SAFECALL' ;special:false;keyword:m_none;op:NOTOKEN), @@ -497,6 +502,7 @@ const (str:'EXPERIMENTAL' ;special:false;keyword:m_all;op:NOTOKEN), (str:'FINALIZATION' ;special:false;keyword:m_initfinal;op:NOTOKEN), (str:'NOSTACKFRAME' ;special:false;keyword:m_none;op:NOTOKEN), + (str:'OBJCPROTOCOL' ;special:false;keyword:m_objectivec1;op:NOTOKEN), { Objective-C protocol } (str:'WEAKEXTERNAL' ;special:false;keyword:m_none;op:NOTOKEN), (str:'DISPINTERFACE' ;special:false;keyword:m_class;op:NOTOKEN), (str:'UNIMPLEMENTED' ;special:false;keyword:m_all;op:NOTOKEN), diff --git a/rtl/inc/objc1.pp b/rtl/inc/objc1.pp index 70491621c2..a008886940 100644 --- a/rtl/inc/objc1.pp +++ b/rtl/inc/objc1.pp @@ -44,6 +44,7 @@ type _class: pobjc_class; end; id = ^objc_object; + pobjc_object = id; _fpc_objc_sel_type = record end; diff --git a/rtl/inc/objcbase.pp b/rtl/inc/objcbase.pp index 63c21f2578..6adc704967 100644 --- a/rtl/inc/objcbase.pp +++ b/rtl/inc/objcbase.pp @@ -33,15 +33,15 @@ type NSCoder = objcclass; external; } - NSObject = objcclass - strict protected - isa: pobjc_class; - public - { NSObject protocol } + Protocol = objcclass + end; external; + + NSObjectProtocol = objcprotocol function isEqual_(obj: id): boolean; message 'isEqual:'; function hash: cuint; message 'hash'; -// implemented as class method instead? -// function superclass: pobjc_class; + + function superclass: pobjc_class; message 'superclass'; + function _class: pobjc_class; message 'class'; { "self" is both a hidden parameter to each method, and a method of NSObject and thereby of each subclass as well } @@ -56,8 +56,7 @@ type function isKindOfClass_(aClass: pobjc_class): boolean; message 'isKindOfClass:'; function isMemberOfClass_(aClass: pobjc_class): boolean; message 'isMemberOfClass:'; -// implemented as class method instead? -// function conformsToProtocol(aProtocol: pobjc_protocal): boolean; + function conformsToProtocol_(aProtocol: Protocol): boolean; message 'conformsToProtocol:'; function respondsToSelector_(aSelector: SEL): boolean; message 'respondsToSelector:'; @@ -66,8 +65,51 @@ type function autorelease: id; message 'autorelease'; function retainCount: cint; message 'retainCount'; -// implemented as class method instead? -// function description: NSString; + function description: {NSString} id; message 'description'; + end; external name 'NSObject'; + + + NSObject = objcclass(NSObjectProtocol) + strict protected + isa: pobjc_class; + public + { NSObjectProtocol -- the message names are copied from the protocol + definition by the compiler, but you can still repeat them if you want } + function isEqual_(obj: id): boolean; + function hash: cuint; + + function superclass: pobjc_class; + function _class: pobjc_class; + { "self" is both a hidden parameter to each method, and a method of + NSObject and thereby of each subclass as well + } + function self: id; + function zone: id; { NSZone } + + function performSelector_(aSelector: SEL): id; + function performSelector_withObject_(aSelector: SEL; obj: id): id; + function performSelector_withObject_withObject(aSelector: SEL; obj1, obj2: id): id; + + function isProxy: boolean; + + function isKindOfClass_(aClass: pobjc_class): boolean; + function isMemberOfClass_(aClass: pobjc_class): boolean; + function conformsToProtocol_(aProtocol: Protocol): boolean; + + function respondsToSelector_(aSelector: SEL): boolean; + + function retain: id; + procedure release; { oneway } + function autorelease: id; + function retainCount: cint; + + function description: {NSString} id; + + { NSObject class } + { "class" prefix to method name to avoid name collision with NSObjectProtocol } + class function classIsEqual_(obj: id): boolean; message 'isEqual:'; + { "class" prefix to method name to avoid name collision with NSObjectProtocol } + class function classHash: cuint; message 'hash'; { NSObject methods } @@ -80,6 +122,7 @@ type class function allocWithZone_(_zone: id {NSZone}): id; message 'allocWithZone:'; class function alloc: id; message 'alloc'; procedure dealloc; message 'dealloc'; + { if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 } procedure finalize; message 'finalize'; { endif } @@ -90,11 +133,14 @@ type class function copyWithZone_(_zone: id {NSZone}): id; message 'copyWithZone:'; class function mutableCopyWithZone_(_zone: id {NSZone}): id; message 'mutableCopyWithZone:'; - class function superclass: pobjc_class; message 'superclass'; - class function _class: pobjc_class; message 'class'; + { "class" prefix to method name to avoid name collision with NSObjectProtocol } + class function classSuperclass: pobjc_class; message 'superclass'; + { "class" prefix to method name to avoid name collision with NSObjectProtocol } + class function classClass: pobjc_class; message 'class'; class procedure poseAsClass_(aClass: pobjc_class); message 'poseAsClass:'; class function instancesRespondToSelector_(aSelector: SEL): boolean; message 'instancesRespondToSelector:'; - class function conformsToProtocol_(aProtocol: pobjc_protocal): boolean; message 'conformsToProtocol:'; + { "class" prefix to method name to avoid name collision with NSObjectProtocol } + class function classConformsToProtocol_(aProtocol: Protocol): boolean; message 'conformsToProtocol:'; function methodForSelector_(aSelector: SEL): IMP; message 'methodForSelector:'; class function instanceMethodForSelector_(aSelector: SEL): IMP; message 'instanceMethodForSelector:'; class function version: cint; message 'version'; @@ -103,7 +149,7 @@ type procedure forwardInvocation_(anInvocation: id {NSInvocation}); message 'forwardInvocation:'; function methodSignatureForSelector_(aSelector: SEL): id {NSMethodSignature}; message 'methodSignatureForSelector:'; - class function description: id {NSString}; message 'description'; + class function classDescription: id {NSString}; message 'description'; function classForCoder: pobjc_class; message 'classForCoder'; function replacementObjectForCoder_(aCoder: id {NSCoder}): id; message 'replacementObjectForCoder:'; diff --git a/tests/test/tobjc3.pp b/tests/test/tobjc3.pp index 80a347ccdd..d0f0264478 100644 --- a/tests/test/tobjc3.pp +++ b/tests/test/tobjc3.pp @@ -11,5 +11,16 @@ type ta = objcclass end; external; +var + a: ta; + b: nsobject; + c: id; begin + { avoid hints about unused types/variables/units } + a:=nil; + if (a<>nil) then + exit; + c:=nil; + b:=c; + b.isEqual_(b); end. diff --git a/tests/test/tobjc4.pp b/tests/test/tobjc4.pp index ffaeb84fb4..07ee3aeec3 100644 --- a/tests/test/tobjc4.pp +++ b/tests/test/tobjc4.pp @@ -7,7 +7,7 @@ type ta = objcclass { no constructors in Objective-C } - constructor create; + constructor create; message 'create'; end; external; begin diff --git a/tests/test/tobjc4a.pp b/tests/test/tobjc4a.pp index d7d7650fe3..60cb2e850a 100644 --- a/tests/test/tobjc4a.pp +++ b/tests/test/tobjc4a.pp @@ -7,7 +7,7 @@ type ta = objcclass { no destructors in Objective-C } - destructor done; + destructor done; message 'done'; end; external; begin diff --git a/tests/test/tobjc5.pp b/tests/test/tobjc5.pp new file mode 100644 index 0000000000..2a466d1656 --- /dev/null +++ b/tests/test/tobjc5.pp @@ -0,0 +1,14 @@ +{ %fail } +{ %target=darwin } +{ %cpu=powerpc,i386 } + +{$modeswitch objectivec1} + +type + ta = objcclass + { needs message name specification } + procedure test; + end; external; + +begin +end. diff --git a/tests/test/tobjc5a.pp b/tests/test/tobjc5a.pp new file mode 100644 index 0000000000..056299f048 --- /dev/null +++ b/tests/test/tobjc5a.pp @@ -0,0 +1,14 @@ +{ %fail } +{ %target=darwin } +{ %cpu=powerpc,i386 } + +{$modeswitch objectivec1} + +type + ta = objcprotocol + { needs message name specification } + procedure test; + end; external; + +begin +end. diff --git a/tests/test/tobjc6.pp b/tests/test/tobjc6.pp new file mode 100644 index 0000000000..42bc7d5aee --- /dev/null +++ b/tests/test/tobjc6.pp @@ -0,0 +1,14 @@ +{ %target=darwin } +{ %cpu=powerpc,i386 } + +{$mode objfpc} +{$modeswitch objectivec1} + +type + ta = objcclass; + + ta = objcclass + end; + +begin +end. diff --git a/tests/test/tobjc7.pp b/tests/test/tobjc7.pp new file mode 100644 index 0000000000..7c6d9fb5b5 --- /dev/null +++ b/tests/test/tobjc7.pp @@ -0,0 +1,23 @@ +{ %target=darwin } +{ %cpu=powerpc,i386 } +{ %norun } +{ %recompile } + +{$mode objfpc} +{$modeswitch objectivec1} + +uses + uobjc7; + +type + tobjcclass = objcclass(tobjcprot) + procedure isrequired; + procedure alsorequired; +{ fake external name to avoid linking errors once we + add external references in all cases to ensure that + all necessary libraries are linked, like gcc does } + end; external name 'NSObject'; + + +begin +end. diff --git a/tests/test/tobjc7a.pp b/tests/test/tobjc7a.pp new file mode 100644 index 0000000000..b39f9dd559 --- /dev/null +++ b/tests/test/tobjc7a.pp @@ -0,0 +1,22 @@ +{ %target=darwin } +{ %cpu=powerpc,i386 } +{ %fail } + + +{$mode objfpc} +{$modeswitch objectivec1} + +uses + uobjc7; + +type + tobjcclass = objcclass(tobjcprot) + procedure alsorequired; +{ fake external name to avoid linking errors once we + add external references in all cases to ensure that + all necessary libraries are linked, like gcc does } + end; external name 'NSObject'; + + +begin +end. diff --git a/tests/test/tobjc7b.pp b/tests/test/tobjc7b.pp new file mode 100644 index 0000000000..322f0b5ce4 --- /dev/null +++ b/tests/test/tobjc7b.pp @@ -0,0 +1,21 @@ +{ %target=darwin } +{ %cpu=powerpc,i386 } +{ %fail } + +{$mode objfpc} +{$modeswitch objectivec1} + +uses + uobjc7; + +type + tobjcclass = objcclass(tobjcprot) + procedure isrequired; +{ fake external name to avoid linking errors once we + add external references in all cases to ensure that + all necessary libraries are linked, like gcc does } + end; external name 'NSObject'; + + +begin +end. diff --git a/tests/test/tobjc7c.pp b/tests/test/tobjc7c.pp new file mode 100644 index 0000000000..f62c2c060f --- /dev/null +++ b/tests/test/tobjc7c.pp @@ -0,0 +1,23 @@ +{ %target=darwin } +{ %cpu=powerpc,i386 } +{ %norun } + +{$mode objfpc} +{$modeswitch objectivec1} + +uses + uobjc7; + +type + tobjcclass = objcclass(tobjcprot) + procedure isrequired; + procedure isoptional; + procedure alsorequired; +{ fake external name to avoid linking errors once we + add external references in all cases to ensure that + all necessary libraries are linked, like gcc does } + end; external name 'NSObject'; + + +begin +end. diff --git a/tests/test/tobjc8.pp b/tests/test/tobjc8.pp new file mode 100644 index 0000000000..a9b844aa6c --- /dev/null +++ b/tests/test/tobjc8.pp @@ -0,0 +1,24 @@ +{ %target=darwin } +{ %cpu=powerpc,i386 } +{ %opt=-vh -Seh } +{ %fail } + +{$mode objfpc} +{$modeswitch objectivec1} + +uses + ctypes; + +type + TMyTestClass = objcclass(NSObject) + { should give a hint because of a missing 'override' } + function hash: cuint; + end; external name 'NSZone'; + +var + a: id; +begin + { avoid warnings/hints about unused types/variables } + a:=TMyTestClass.alloc; + tmytestclass(a).Retain; +end. diff --git a/tests/test/tobjc8a.pp b/tests/test/tobjc8a.pp new file mode 100644 index 0000000000..13eed2a27e --- /dev/null +++ b/tests/test/tobjc8a.pp @@ -0,0 +1,24 @@ +{ %target=darwin } +{ %cpu=powerpc,i386 } +{ %opt=-vh -Seh } +{ %norun } + +{$mode objfpc} +{$modeswitch objectivec1} + +uses + ctypes; + +type + TMyTestClass = objcclass(NSObject) + { should not give a hint, since we have 'override' } + function hash: cuint; override; + end; external name 'NSZone'; + +var + a: id; +begin + { avoid warnings/hints about unused types/variables } + a:=TMyTestClass.alloc; + tmytestclass(a).Retain; +end. diff --git a/tests/test/tobjc9.pp b/tests/test/tobjc9.pp new file mode 100644 index 0000000000..9538025d29 --- /dev/null +++ b/tests/test/tobjc9.pp @@ -0,0 +1,16 @@ +{ %target=darwin } +{ %cpu=powerpc,i386 } +{ %norun } + +{$mode objfpc} +{$modeswitch objectivec1} + +uses + ctypes; + +var + a: NSObjectProtocol; + b: NSObject; +begin + a:=b; +end. diff --git a/tests/test/tobjc9a.pp b/tests/test/tobjc9a.pp new file mode 100644 index 0000000000..406460a523 --- /dev/null +++ b/tests/test/tobjc9a.pp @@ -0,0 +1,16 @@ +{ %target=darwin } +{ %cpu=powerpc,i386 } +{ %fail } + +{$mode objfpc} +{$modeswitch objectivec1} + +uses + ctypes; + +var + a: NSObjectProtocol; + b: NSObject; +begin + b:=a; +end. diff --git a/tests/test/tobjc9b.pp b/tests/test/tobjc9b.pp new file mode 100644 index 0000000000..9538025d29 --- /dev/null +++ b/tests/test/tobjc9b.pp @@ -0,0 +1,16 @@ +{ %target=darwin } +{ %cpu=powerpc,i386 } +{ %norun } + +{$mode objfpc} +{$modeswitch objectivec1} + +uses + ctypes; + +var + a: NSObjectProtocol; + b: NSObject; +begin + a:=b; +end.