- /* if absolute address given then it mark it as
- volatile */
- if (IS_ABSOLUTE(sym->etype))
- SPEC_VOLATILE(sym->etype) = 1;
-
- /* global variables declared const put into code */
- if (sym->level == 0 &&
- SPEC_SCLS(sym->etype) == S_CONSTANT)
- SPEC_SCLS(sym->etype) = S_CODE ;
-
-
- /* global variable in code space is a constant */
- if (sym->level == 0 &&
- SPEC_SCLS(sym->etype) == S_CODE)
- SPEC_CONST(sym->etype) = 1;
-
-
- /* if bit variable then no storage class can be */
- /* specified since bit is already a storage */
- if ( IS_BITVAR(sym->etype) &&
- ( SPEC_SCLS(sym->etype) != S_FIXED &&
- SPEC_SCLS(sym->etype) != S_SBIT &&
- SPEC_SCLS(sym->etype) != S_BIT )
- ) {
- werror (E_BITVAR_STORAGE,sym->name);
- SPEC_SCLS(sym->etype) = S_FIXED ;
- }
-
- /* extern variables cannot be initialized */
- if (IS_EXTERN(sym->etype) && sym->ival) {
- werror(E_EXTERN_INIT,sym->name);
- sym->ival = NULL;
- }
-
- /* if this is an automatic symbol then */
- /* storage class will be ignored and */
- /* symbol will be allocated on stack/ */
- /* data depending on flag */
- if ( sym->level &&
- (options.stackAuto || reentrant ) &&
- ( SPEC_SCLS(sym->etype) != S_AUTO &&
- SPEC_SCLS(sym->etype) != S_FIXED &&
- SPEC_SCLS(sym->etype) != S_REGISTER &&
- SPEC_SCLS(sym->etype) != S_STACK &&
- SPEC_SCLS(sym->etype) != S_XSTACK &&
- SPEC_SCLS(sym->etype) != S_CONSTANT )) {
-
- werror(E_AUTO_ASSUMED,sym->name) ;
- SPEC_SCLS(sym->etype) = S_AUTO ;
- }
-
- /* automatic symbols cannot be given */
- /* an absolute address ignore it */
- if ( sym->level &&
- SPEC_ABSA(sym->etype) &&
- (options.stackAuto || reentrant) ) {
- werror(E_AUTO_ABSA,sym->name);
- SPEC_ABSA(sym->etype) = 0 ;
- }
-
- /* arrays & pointers cannot be defined for bits */
- /* SBITS or SFRs or BIT */
- if ((IS_ARRAY(sym->type) || IS_PTR(sym->type)) &&
- ( SPEC_NOUN(sym->etype) == V_BIT ||
- SPEC_NOUN(sym->etype) == V_SBIT ||
- SPEC_SCLS(sym->etype) == S_SFR ))
- werror(E_BIT_ARRAY,sym->name);
-
- /* if this is a bit|sbit then set length & start */
- if (SPEC_NOUN(sym->etype) == V_BIT ||
- SPEC_NOUN(sym->etype) == V_SBIT ) {
- SPEC_BLEN(sym->etype) = 1 ;
- SPEC_BSTR(sym->etype) = 0 ;
- }
-
- /* variables declared in CODE space must have */
- /* initializers if not an extern */
- if (SPEC_SCLS(sym->etype) == S_CODE &&
- sym->ival == NULL &&
- !sym->level &&
- !IS_EXTERN(sym->etype))
- werror(E_CODE_NO_INIT,sym->name);
-
- /* if parameter or local variable then change */
- /* the storage class to reflect where the var will go */
- if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
- if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
- SPEC_SCLS(sym->etype) = (options.useXstack ?
- S_XSTACK : S_STACK ) ;
- else
- SPEC_SCLS(sym->etype) = (options.useXstack ?
- S_XDATA :S_DATA ) ;
+ /* arrays & pointers cannot be defined for bits */
+ /* SBITS or SFRs or BIT */
+ if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
+ (SPEC_NOUN (sym->etype) == V_BIT ||
+ SPEC_NOUN (sym->etype) == V_SBIT ||
+ SPEC_SCLS (sym->etype) == S_SFR))
+ werror (E_BIT_ARRAY, sym->name);
+
+ /* if this is a bit|sbit then set length & start */
+ if (SPEC_NOUN (sym->etype) == V_BIT ||
+ SPEC_NOUN (sym->etype) == V_SBIT)
+ {
+ SPEC_BLEN (sym->etype) = 1;
+ SPEC_BSTR (sym->etype) = 0;
+ }
+
+ /* variables declared in CODE space must have */
+ /* initializers if not an extern */
+ if (SPEC_SCLS (sym->etype) == S_CODE &&
+ sym->ival == NULL &&
+ !sym->level &&
+ port->mem.code_ro &&
+ !IS_EXTERN (sym->etype) &&
+ !funcInChain (sym->type))
+ werror (E_CODE_NO_INIT, sym->name);
+
+ /* if parameter or local variable then change */
+ /* the storage class to reflect where the var will go */
+ if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
+ !IS_STATIC(sym->etype))
+ {
+ if (options.stackAuto || (currFunc && IS_RENT (currFunc->etype)))
+ {
+ SPEC_SCLS (sym->etype) = (options.useXstack ?
+ S_XSTACK : S_STACK);
+ }
+ else
+ {
+ /* hack-o-matic! I see no reason why the useXstack option should ever
+ * control this allcoation, but the code was originally that way, and
+ * changing it for non-390 ports breaks the compiler badly.
+ */
+ bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
+ SPEC_SCLS (sym->etype) = (useXdata ?
+ S_XDATA : S_FIXED);
+ }