]> git.sur5r.net Git - cc65/commitdiff
Fixed the existing but unused attribute parsing code. Added
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 18 Oct 2009 18:31:02 +0000 (18:31 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 18 Oct 2009 18:31:02 +0000 (18:31 +0000)
__attribute__((noexit)) that may be used to mark functions that won't return.
Added this attribute to the exit() function in stdlib.h.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4372 b7a2c559-68d2-44c3-8de9-860c34a00d81

include/stdlib.h
src/cc65/compile.c
src/cc65/declare.c
src/cc65/declare.h
src/cc65/declattr.c
src/cc65/declattr.h
src/cc65/expr.c
src/cc65/symentry.c
src/cc65/symentry.h
src/cc65/symtab.c

index a58d29c876e24b9795ebcafd4162067ee6e42ede..e938e8a3a0af64e7e3a54b38e443c8fdef21f799 100644 (file)
@@ -109,7 +109,7 @@ int __fastcall__ atexit (void (*exitfunc) (void));
 void* __fastcall__ bsearch (const void* key, const void* base, size_t n,
                            size_t size, int (*cmp) (const void*, const void*));
 div_t __fastcall__ div (int numer, int denom);
-void __fastcall__ exit (int ret);
+void __fastcall__ exit (int ret) __attribute__ ((noreturn));
 char* __fastcall__ getenv (const char* name);
 void __fastcall__ qsort (void* base, size_t count, size_t size,
                         int (*compare) (const void*, const void*));
index c5024fb828db8c819d7336d29665dddcf9c72e3e..7144edb814913b4004de26811f79ca7bf7e3a3b7 100644 (file)
@@ -83,7 +83,6 @@ static void Parse (void)
     while (CurTok.Tok != TOK_CEOF) {
 
        DeclSpec        Spec;
-       Declaration     Decl;
 
        /* Check for empty statements */
        if (CurTok.Tok == TOK_SEMI) {
@@ -128,6 +127,8 @@ static void Parse (void)
        comma = 0;
                while (1) {
 
+            Declaration         Decl;
+
            /* Read the next declaration */
            ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
            if (Decl.Ident[0] == '\0') {
@@ -168,6 +169,9 @@ static void Parse (void)
            /* Add an entry to the symbol table */
            Entry = AddGlobalSym (Decl.Ident, Decl.Type, Decl.StorageClass);
 
+            /* Add declaration attributes */
+            SymUseAttributes (Entry, &Decl);
+
            /* Reserve storage for the variable if we need to */
                    if (Decl.StorageClass & SC_STORAGE) {
 
@@ -334,7 +338,7 @@ void Compile (const char* FileName)
     strftime (TimeStr, sizeof (TimeStr), "\"%H:%M:%S\"", TM);
     DefineTextMacro ("__DATE__", DateStr);
     DefineTextMacro ("__TIME__", TimeStr);
-                    
+
     /* Other standard macros */
     /* DefineNumericMacro ("__STDC__", 1);      <- not now */
     DefineNumericMacro ("__STDC_HOSTED__", 1);
index 40235ea8427e10c0b1ad21d73393f066e04c68fa..8cb2e5ee63186540f7332ba9f438b22b375f245b 100644 (file)
@@ -249,9 +249,10 @@ static void InitDeclSpec (DeclSpec* D)
 static void InitDeclaration (Declaration* D)
 /* Initialize the Declaration struct for use */
 {
-    D->Ident[0]  = '\0';
-    D->Type[0].C = T_END;
-    D->Index     = 0;
+    D->Ident[0]   = '\0';
+    D->Type[0].C  = T_END;
+    D->Index      = 0;
+    D->Attributes = 0;
 }
 
 
@@ -1123,7 +1124,6 @@ static void ParseAnsiParamList (FuncDesc* F)
 
        DeclSpec        Spec;
        Declaration     Decl;
-       DeclAttr        Attr;
 
        /* Allow an ellipsis as last parameter */
        if (CurTok.Tok == TOK_ELLIPSIS) {
@@ -1161,8 +1161,8 @@ static void ParseAnsiParamList (FuncDesc* F)
            Decl.StorageClass &= ~SC_DEF;
        }
 
-       /* Parse an attribute ### */
-       ParseAttribute (&Decl, &Attr);
+       /* Parse attributes for this parameter */
+       ParseAttribute (&Decl);
 
        /* Create a symbol table entry */
        AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0);
@@ -1195,8 +1195,7 @@ static void ParseAnsiParamList (FuncDesc* F)
        /* Print an error if we have unnamed parameters and cc65 extensions
          * are disabled.
         */
-               if (IS_Get (&Standard) != STD_CC65 &&
-            (F->Flags & FD_UNNAMED_PARAMS) != 0) {
+               if (IS_Get (&Standard) != STD_CC65 && (F->Flags & FD_UNNAMED_PARAMS)) {
            Error ("Parameter name omitted");
        }
     }
@@ -1204,7 +1203,7 @@ static void ParseAnsiParamList (FuncDesc* F)
 
 
 
-static FuncDesc* ParseFuncDecl (void)
+static FuncDesc* ParseFuncDecl (Declaration* D)
 /* Parse the argument list of a function. */
 {
     unsigned Offs;
@@ -1238,8 +1237,24 @@ static FuncDesc* ParseFuncDecl (void)
 
     /* Parse params */
     if ((F->Flags & FD_OLDSTYLE) == 0) {
+
        /* New style function */
        ParseAnsiParamList (F);
+
+        /* Allow attributes */
+        ParseAttribute (D);
+
+        /* Check if this is a function definition */
+        if (CurTok.Tok == TOK_LCURLY) {
+            /* Print an error if we have unnamed parameters and cc65 extensions
+             * are disabled.
+             */
+            if (IS_Get (&Standard) != STD_CC65 &&
+                (F->Flags & FD_UNNAMED_PARAMS)) {
+                Error ("Parameter name omitted");
+            }
+        }
+
     } else {
        /* Old style function */
        ParseOldStyleParamList (F);
@@ -1344,7 +1359,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
                    NextToken ();
 
            /* Parse the function declaration */
-                   F = ParseFuncDecl ();
+                   F = ParseFuncDecl (D);
 
             /* We cannot specify fastcall for variadic functions */
             if ((F->Flags & FD_VARIADIC) && (Qualifiers & T_QUAL_FASTCALL)) {
index eac2897d9d6bd22237f47998ea181b7802b425b6..96cdc40d92e605af4e1fc05328bf8ca8268bc763 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2008 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -38,6 +38,9 @@
 
 
 
+/* common */
+#include "coll.h"
+
 /* cc65 */
 #include "scanner.h"
 #include "symtab.h"
@@ -58,9 +61,9 @@
 /* Result of ParseDeclSpec */
 typedef struct DeclSpec DeclSpec;
 struct DeclSpec {
-    unsigned   StorageClass;           /* One of the SC_xxx flags      */
+    unsigned   StorageClass;           /* One of the SC_xxx flags      */
     Type               Type[MAXTYPELEN];       /* Type of the declaration spec */
-    unsigned   Flags;                  /* Bitmapped flags              */
+    unsigned   Flags;                  /* Bitmapped flags              */
 };
 
 /* Result of ParseDecl */
@@ -68,14 +71,15 @@ typedef struct Declaration Declaration;
 struct Declaration {
     unsigned    StorageClass;           /* A set of SC_xxx flags */
     Type       Type[MAXTYPELEN];       /* The type */
-    ident      Ident;                  /* The identifier if any, else empty */
+    ident      Ident;                  /* The identifier, if any*/
+    Collection* Attributes;             /* Attributes if any */
 
     /* Working variables */
-    unsigned   Index;                  /* Used to build Type */
+    unsigned   Index;              /* Used to build Type */
 };
 
 /* Modes for ParseDecl */
-typedef enum {                                                   
+typedef enum {
     DM_NEED_IDENT,                      /* We must have an identifier */
     DM_NO_IDENT,                        /* We won't read an identifier */
     DM_ACCEPT_IDENT,                    /* We will accept an id if there is one */
index 3ac3e147974fb15987bb56fd0da81be94d694819..91c7682e214d0b6b9027429b08f8a2eef0c926e4 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2002 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 #include <string.h>
 
+/* common */
+#include "xmalloc.h"
+
 /* cc65 */
+#include "declare.h"
+#include "declattr.h"
 #include "error.h"
 #include "scanner.h"
 #include "symtab.h"
 #include "typecmp.h"
-#include "declattr.h"
 
 
 
 
 
 /* Forwards for attribute handlers */
-static void AliasAttr (const Declaration* D, DeclAttr* A);
-static void UnusedAttr (const Declaration* D, DeclAttr* A);
-static void ZeroPageAttr (const Declaration* D, DeclAttr* A);
+static void NoReturnAttr (Declaration* D);
 
 
 
 /* Attribute table */
 typedef struct AttrDesc AttrDesc;
 struct AttrDesc {
-    const char Name[12];
-    void       (*Handler) (const Declaration*, DeclAttr*);
+    const char Name[15];
+    void       (*Handler) (Declaration*);
 };
-static const AttrDesc AttrTable [atCount] = {
-    { "alias",         AliasAttr       },
-    { "unused",                UnusedAttr      },
-    { "zeropage",              ZeroPageAttr    },
+static const AttrDesc AttrTable [] = {
+    { "__noreturn__",   NoReturnAttr    },
+    { "noreturn",       NoReturnAttr    },
 };
 
 
 
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                              Struct DeclAttr                              */
+/*****************************************************************************/
+
+
+
+static DeclAttr* NewDeclAttr (DeclAttrType AttrType)
+/* Create a new DeclAttr struct and return it */
+{
+    /* Allocate memory */
+    DeclAttr* A = xmalloc (sizeof (DeclAttr));
+
+    /* Initialize the fields */
+    A->AttrType = AttrType;
+
+    /* Return the new struct */
+    return A;
+}
+
+
+
+/*****************************************************************************/
+/*                             Helper functions                              */
 /*****************************************************************************/
 
 
@@ -85,7 +107,7 @@ static const AttrDesc* FindAttribute (const char* Attr)
     unsigned A;
 
     /* For now do a linear search */
-    for (A = 0; A < atCount; ++A) {
+    for (A = 0; A < sizeof (AttrTable) / sizeof (AttrTable[0]); ++A) {
                if (strcmp (Attr, AttrTable[A].Name) == 0) {
            /* Found */
                    return AttrTable + A;
@@ -98,72 +120,54 @@ static const AttrDesc* FindAttribute (const char* Attr)
 
 
 
-static void AliasAttr (const Declaration* D, DeclAttr* A)
-/* Handle the "alias" attribute */
+static void ErrorSkip (void)
 {
-    SymEntry* Sym;
+    /* List of tokens to skip */
+    static const token_t SkipList[] = { TOK_RPAREN, TOK_SEMI };
 
-    /* Comma expected */
-    ConsumeComma ();
+    /* Skip until closing brace or semicolon */
+    SkipTokens (SkipList, sizeof (SkipList) / sizeof (SkipList[0]));
 
-    /* The next identifier is the name of the alias symbol */
-    if (CurTok.Tok != TOK_IDENT) {
-               Error ("Identifier expected");
-       return;
+    /* If we have a closing brace, read it, otherwise bail out */
+    if (CurTok.Tok == TOK_RPAREN) {
+        /* Read the two closing braces */
+        ConsumeRParen ();
+        ConsumeRParen ();
     }
+}
 
-    /* Lookup the symbol for this name, it must exist */
-    Sym = FindSym (CurTok.Ident);
-    if (Sym == 0) {
-       Error ("Unknown identifier: `%s'", CurTok.Ident);
-       NextToken ();
-       return;
-    }
 
-    /* Since we have the symbol entry now, skip the name */
-    NextToken ();
 
-    /* Check if the types of the symbols are identical */
-    if (TypeCmp (D->Type, Sym->Type) < TC_EQUAL) {
-       /* Types are not identical */
-       Error ("Incompatible types");
-       return;
+static void AddAttr (Declaration* D, DeclAttr* A)
+/* Add an attribute to a declaration */
+{
+    /* Allocate the list if necessary, the add the attribute */
+    if (D->Attributes == 0) {
+        D->Attributes = NewCollection ();
     }
-
-    /* Attribute is verified, set the stuff in the attribute description */
-    A->AttrType = atAlias;
-    A->V.Sym   = Sym;
+    CollAppend (D->Attributes, A);
 }
 
 
 
-static void UnusedAttr (const Declaration* D attribute ((unused)), DeclAttr* A)
-/* Handle the "unused" attribute */
-{
-    /* No parameters */
-    A->AttrType = atUnused;
-}
+/*****************************************************************************/
+/*                          Attribute handling code                          */
+/*****************************************************************************/
 
 
 
-static void ZeroPageAttr (const Declaration* D attribute ((unused)), DeclAttr* A)
-/* Handle the "zeropage" attribute */
+void NoReturnAttr (Declaration* D)
+/* Parse the "noreturn" attribute */
 {
-    /* No parameters */
-    A->AttrType = atZeroPage;
+    /* Add the noreturn attribute */
+    AddAttr (D, NewDeclAttr (atNoReturn));
 }
 
 
 
-void ParseAttribute (const Declaration* D, DeclAttr* A)
+void ParseAttribute (Declaration* D)
 /* Parse an additional __attribute__ modifier */
 {
-    ident          AttrName;
-    const AttrDesc* Attr;
-
-    /* Initialize the attribute description with "no attribute" */
-    A->AttrType = atNone;
-
     /* Do we have an attribute? */
     if (CurTok.Tok != TOK_ATTRIBUTE) {
        /* No attribute, bail out */
@@ -177,45 +181,59 @@ void ParseAttribute (const Declaration* D, DeclAttr* A)
     ConsumeLParen ();
     ConsumeLParen ();
 
-    /* Identifier follows */
-    if (CurTok.Tok != TOK_IDENT) {
-               Error ("Identifier expected");
-       /* We should *really* try to recover here, but for now: */
-       return;
-    }
+    /* Read a list of attributes */
+    while (1) {
 
-    /* Map the attribute name to its id, then skip the identifier */
-    strcpy (AttrName, CurTok.Ident);
-    Attr = FindAttribute (AttrName);
-    NextToken ();
+        ident           AttrName;
+        const AttrDesc* Attr = 0;
 
-    /* Did we find a valid attribute? */
-    if (Attr) {
+        /* Identifier follows */
+        if (CurTok.Tok != TOK_IDENT) {
 
-       /* Call the handler */
-       Attr->Handler (D, A);
+            /* No attribute name */
+            Error ("Attribute name expected");
 
-       /* Read the two closing braces */
-       ConsumeRParen ();
-       ConsumeRParen ();
+            /* Skip until end of attribute */
+            ErrorSkip ();
 
-    } else {
-       /* List of tokens to skip */
-       static const token_t SkipList[] = { TOK_LPAREN, TOK_SEMI };
+            /* Bail out */
+            return;
+        }
 
-       /* Attribute not known, maybe typo */
-       Error ("Illegal attribute: `%s'", AttrName);
+        /* Map the attribute name to its id, then skip the identifier */
+        strcpy (AttrName, CurTok.Ident);
+        Attr = FindAttribute (AttrName);
+        NextToken ();
 
-       /* Skip until closing brace or semicolon */
-       SkipTokens (SkipList, sizeof (SkipList) / sizeof (SkipList[0]));
+        /* Did we find a valid attribute? */
+        if (Attr) {
 
-       /* If we have a closing brace, read it, otherwise bail out */
-       if (CurTok.Tok == TOK_LPAREN) {
-           /* Read the two closing braces */
-           ConsumeRParen ();
-           ConsumeRParen ();
-       }
+            /* Call the handler */
+            Attr->Handler (D);
+
+        } else {
+            /* Attribute not known, maybe typo */
+            Error ("Illegal attribute: `%s'", AttrName);
+
+            /* Skip until end of attribute */
+            ErrorSkip ();
+
+            /* Bail out */
+            return;
+        }
+
+        /* If a comma follows, there's a next attribute. Otherwise this is the
+         * end of the attribute list.
+         */
+        if (CurTok.Tok != TOK_COMMA) {
+            break;
+        }
+        NextToken ();
     }
+
+    /* The declaration is terminated with two closing braces */
+    ConsumeRParen ();
+    ConsumeRParen ();
 }
 
 
index cef08b30f5661e535871702c5dc04c8b4f215c54..976de35ce840d1c38c14eb41daad7be079cf1f32 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2002 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 
-#include "declare.h"
-
-
-
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                  Data                                    */
 /*****************************************************************************/
 
 
 
+/* Forward */
+struct Declaration;
+
 /* Supported attribute types */
 typedef enum {
-    atNone     = -1,           /* No attribute */
-    atAlias,                   /* Alias declaration */
-    atUnused,                  /* Variable is unused */
-    atZeroPage,                        /* Zero page symbol */
+    atNone     = -1,           /* No attribute */
+    atNoReturn,                        /* Function does not return */
 
-    atCount                    /* Number of attributes */
-} attrib_t;
+    atCount                    /* Number of attributes */
+} DeclAttrType;
 
 /* An actual attribute description */
 typedef struct DeclAttr DeclAttr;
 struct DeclAttr {
-    attrib_t                   AttrType;       /* Type of attribute */
-
-    union {
-       struct SymEntry*        Sym;            /* Symbol for alias */
-    } V;
+    DeclAttrType                AttrType;       /* Type of attribute */
 };
 
 
 
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                                  Code                                    */
 /*****************************************************************************/
 
 
 
-void ParseAttribute (const Declaration* D, DeclAttr* A);
+void ParseAttribute (struct Declaration* D);
 /* Parse an additional __attribute__ modifier */
 
 
index 0a036b24d034e1db44db8bce9b1266382fc76886..8b5069b34739cff38e7771698e9e6c3f0d8f80b8 100644 (file)
@@ -486,6 +486,12 @@ static void FunctionCall (ExprDesc* Expr)
        }
 
     } else {
+        /* Check function attributes */
+        if (Expr->Sym && SymGetAttribute (Expr->Sym, atNoReturn)) {
+            /* For now, handle as if a return statement was encountered */
+            F_ReturnFound (CurrentFunc);
+        }
+
         /* Check for known standard functions and inline them */
         if (Expr->Name != 0) {
             int StdFunc = FindStdFunc ((const char*) Expr->Name);
index 718cd470e7e0489caca3274cd8c06ff938645940..6ad4a5cfcb051a389ee831f4ef4d008986fa080e 100644 (file)
@@ -40,6 +40,8 @@
 
 /* cc65 */
 #include "anonname.h"
+#include "declare.h"
+#include "error.h"
 #include "symentry.h"
 
 
@@ -67,6 +69,7 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags)
     E->Owner   = 0;
     E->Flags   = Flags;
     E->Type    = 0;
+    E->Attr     = 0;
     E->AsmName  = 0;
     memcpy (E->Name, Name, Len+1);
 
@@ -150,6 +153,49 @@ void DumpSymEntry (FILE* F, const SymEntry* E)
 
 
 
+const DeclAttr* SymGetAttribute (const SymEntry* Sym, DeclAttrType AttrType)
+/* Return an attribute for this symbol or NULL if the attribute does not exist */
+{
+    /* Beware: We may not even have a collection */
+    if (Sym->Attr) {
+        unsigned I;
+        for (I = 0; I < CollCount (Sym->Attr); ++I) {
+
+            /* Get the next attribute */
+            const DeclAttr* A = CollConstAt (Sym->Attr, I);
+
+            /* If this is the one we're searching for, return it */
+            if (A->AttrType == AttrType) {
+                return A;
+            }
+        }
+    }
+
+    /* Not found */
+    return 0;
+}
+
+
+
+void SymUseAttributes (SymEntry* Sym, struct Declaration* D)
+/* Use the attributes from the declaration for this symbol */
+{
+    /* We cannot specify attributes twice */
+    if ((Sym->Flags & SC_HAVEATTR) != 0) {
+        if (D->Attributes != 0) {
+            Error ("Attributes must be specified in the first declaration");
+        }
+        return;
+    }
+
+    /* Move the attributes */
+    Sym->Attr = D->Attributes;
+    D->Attributes = 0;
+    Sym->Flags |= SC_HAVEATTR;
+}
+
+
+
 void CvtRegVarToAuto (SymEntry* Sym)
 /* Convert a register variable to an auto variable */
 {
index 11d2921316b7d4412486a8ccee7c28038a06e43d..06e5a0e871b3f305c9e94a78d0c73285ac5bd8d8 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2009 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2000-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 #include <stdio.h>
 
 /* common */
+#include "coll.h"
 #include "inline.h"
 
 /* cc65 */
 #include "datatype.h"
+#include "declattr.h"
 
 
 
@@ -65,31 +67,33 @@ struct Segments;
 
 
 /* Storage classes and flags */
-#define SC_AUTO        0x0001U
-#define SC_REGISTER            0x0002U /* Register variable, is in static storage */
-#define SC_STATIC      0x0004U
-#define SC_EXTERN      0x0008U
+#define SC_AUTO        0x0001U         /* Auto variable */
+#define SC_REGISTER            0x0002U         /* Register variable */
+#define SC_STATIC      0x0004U         /* Static */
+#define SC_EXTERN      0x0008U         /* Extern linkage */
 
-#define SC_ENUM                0x0030U /* An enum (numeric constant) */
-#define SC_CONST       0x0020U /* A numeric constant with a type */
-#define SC_LABEL               0x0040U /* A goto label */
-#define SC_PARAM               0x0080U /* This is a function parameter */
-#define SC_FUNC                0x0100U /* Function entry */
+#define SC_ENUM                0x0030U         /* An enum */
+#define SC_CONST       0x0020U         /* A numeric constant with a type */
+#define SC_LABEL               0x0040U         /* A goto label */
+#define SC_PARAM               0x0080U         /* A function parameter */
+#define SC_FUNC                0x0100U         /* A function */
 
-#define SC_DEFTYPE      0x0200U /* Parameter has default type (=int, old style) */
-#define SC_STORAGE             0x0400U /* Symbol with associated storage */
-#define SC_DEFAULT             0x0800U /* Flag: default storage class was used */
+#define SC_DEFTYPE      0x0200U         /* Parameter has default type (=int, old style) */
+#define SC_STORAGE             0x0400U         /* Symbol with associated storage */
+#define SC_DEFAULT             0x0800U         /* Flag: default storage class was used */
 
-#define SC_DEF         0x1000U /* Symbol is defined */
-#define SC_REF                 0x2000U /* Symbol is referenced */
+#define SC_DEF         0x1000U         /* Symbol is defined */
+#define SC_REF                 0x2000U         /* Symbol is referenced */
 
-#define SC_TYPE                0x4000U /* This is a type, struct, typedef, etc. */
-#define SC_STRUCT              0x4001U /* Struct or union */
-#define SC_STRUCTFIELD  0x4002U        /* Struct or union field */
-#define SC_BITFIELD     0x4004U /* A bit-field inside a struct or union */
-#define SC_TYPEDEF             0x4008U /* A typedef */
+#define SC_TYPE                0x4000U         /* This is a type, struct, typedef, etc. */
+#define SC_STRUCT              0x4001U         /* Struct or union */
+#define SC_STRUCTFIELD  0x4002U                /* Struct or union field */
+#define SC_BITFIELD     0x4004U         /* A bit-field inside a struct or union */
+#define SC_TYPEDEF             0x4008U         /* A typedef */
 
-#define SC_ZEROPAGE    0x8000U /* Symbol marked as zeropage */
+#define SC_ZEROPAGE    0x8000U         /* Symbol marked as zeropage */
+
+#define SC_HAVEATTR     0x10000U        /* Symbol has attributes */
 
 
 
@@ -103,6 +107,7 @@ struct SymEntry {
     struct SymTable*           Owner;    /* Symbol table the symbol is in */
     unsigned                           Flags;    /* Symbol flags */
     Type*                              Type;     /* Symbol type */
+    Collection*                 Attr;     /* Attribute list if any */
     char*                       AsmName;  /* Assembler name if any */
 
     /* Data that differs for the different symbol types */
@@ -226,6 +231,12 @@ INLINE const char* SymGetAsmName (const SymEntry* Sym)
 #  define SymGetAsmName(Sym)      ((Sym)->AsmName)
 #endif
 
+const DeclAttr* SymGetAttribute (const SymEntry* Sym, DeclAttrType AttrType);
+/* Return an attribute for this symbol or NULL if the attribute does not exist */
+
+void SymUseAttributes (SymEntry* Sym, struct Declaration* D);
+/* Use the attributes from the declaration for this symbol */
+
 void CvtRegVarToAuto (SymEntry* Sym);
 /* Convert a register variable to an auto variable */
 
index dc246ef4b87f52d7b48c612490f0903cfea581a7..1b938200f7f1d857b41cbe0c12a024125e87bf88 100644 (file)
@@ -181,7 +181,7 @@ static void CheckSymTable (SymTable* Tab)
                    /* Undefined label */
                    Error ("Undefined label: `%s'", Entry->Name);
                } else if (!SymIsRef (Entry)) {
-                   /* Defined but not used */ 
+                   /* Defined but not used */
                     if (IS_Get (&WarnUnusedLabel)) {
                        Warning ("`%s' is defined but never used", Entry->Name);
                     }
@@ -768,7 +768,7 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
                TypeCmp (T + 1, EType + 1) < TC_EQUAL) {
                /* Types not identical: Conflicting types */
                Error ("Conflicting types for `%s'", Name);
-               return Entry;
+               return Entry;
            } else {
                /* Check if we have a size in the existing definition */
                if (ESize == UNSPECIFIED) {
@@ -781,7 +781,7 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
            /* New type must be identical */
            if (TypeCmp (EType, T) < TC_EQUAL) {
                Error ("Conflicting types for `%s'", Name);
-               return Entry;
+               return Entry;
            }
 
            /* In case of a function, use the new type descriptor, since it
@@ -791,9 +791,9 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
              * empty parameter list.
             */
            if (IsFunc) {
-               /* Get the function descriptor from the new type */
-               FuncDesc* F = GetFuncDesc (T);
-               /* Use this new function descriptor if it doesn't contain
+               /* Get the function descriptor from the new type */
+               FuncDesc* F = GetFuncDesc (T);
+               /* Use this new function descriptor if it doesn't contain
                  * an empty parameter list.
                  */
                 if ((F->Flags & FD_EMPTY) == 0) {