/* */
/* */
/* */
-/* (C) 2000-2009, Ullrich von Bassewitz */
+/* (C) 2000-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
#include "litpool.h"
#include "locals.h"
#include "scanner.h"
-#include "segments.h"
#include "stackptr.h"
#include "standard.h"
#include "stmt.h"
struct Function {
struct SymEntry* FuncEntry; /* Symbol table entry */
Type* ReturnType; /* Function return type */
- struct FuncDesc* Desc; /* Function descriptor */
+ FuncDesc* Desc; /* Function descriptor */
int Reserved; /* Reserved local space */
unsigned RetLab; /* Return code label */
int TopLevelSP; /* SP at function top level */
}
-
+
+static void F_EmitDebugInfo (void)
+/* Emit debug infos for the current function */
+{
+ if (DebugInfo) {
+ /* Get the current fuction */
+ const SymEntry* Sym = CurrentFunc->FuncEntry;
+
+ /* Output info for the function itself */
+ AddTextLine ("\t.dbg\tfunc, \"%s\", \"00\", %s, \"%s\"",
+ Sym->Name,
+ (Sym->Flags & SC_EXTERN)? "extern" : "static",
+ Sym->AsmName);
+ }
+}
+
+
+
/*****************************************************************************/
-/* code */
+/* code */
/*****************************************************************************/
void NewFunc (SymEntry* Func)
/* Parse argument declarations and function body. */
{
- SymEntry* Param;
+ int C99MainFunc = 0;/* Flag for C99 main function returning int */
+ SymEntry* Param;
/* Get the function descriptor from the function entry */
FuncDesc* D = Func->V.F.Func;
if (D->ParamCount > 0 || (D->Flags & FD_VARIADIC) != 0) {
g_importmainargs ();
}
+
+ /* Determine if this is a main function in a C99 environment that
+ * returns an int.
+ */
+ if (IsTypeInt (F_GetReturnType (CurrentFunc)) &&
+ IS_Get (&Standard) == STD_C99) {
+ C99MainFunc = 1;
+ }
}
/* Allocate code and data segments for this function */
Statement (0);
}
- /* If this is not a void function, output a warning if we didn't see a
- * return statement.
+ /* If this is not a void function, and not the main function in a C99
+ * environment returning int, output a warning if we didn't see a return
+ * statement.
*/
- if (!F_HasVoidReturn (CurrentFunc) && !F_HasReturn (CurrentFunc)) {
+ if (!F_HasVoidReturn (CurrentFunc) && !F_HasReturn (CurrentFunc) && !C99MainFunc) {
Warning ("Control reaches end of non-void function");
}
+ /* If this is the main function in a C99 environment returning an int, let
+ * it always return zero. Note: Actual return statements jump to the return
+ * label defined below.
+ * The code is removed by the optimizer if unused.
+ */
+ if (C99MainFunc) {
+ g_getimmed (CF_INT | CF_CONST, 0, 0);
+ }
+
/* Output the function exit code label */
g_defcodelabel (F_GetRetLab (CurrentFunc));
/* Emit references to imports/exports */
EmitExternals ();
+ /* Emit function debug info */
+ F_EmitDebugInfo ();
+ EmitDebugInfo ();
+
/* Leave the lexical level */
LeaveFunctionLevel ();