From 5a00b38aab6542dfa74c1be66839c57c24e81d77 Mon Sep 17 00:00:00 2001 From: uz Date: Sun, 18 Oct 2009 18:31:02 +0000 Subject: [PATCH] Fixed the existing but unused attribute parsing code. Added __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 | 2 +- src/cc65/compile.c | 8 +- src/cc65/declare.c | 35 +++++--- src/cc65/declare.h | 22 +++-- src/cc65/declattr.c | 198 ++++++++++++++++++++++++-------------------- src/cc65/declattr.h | 37 ++++----- src/cc65/expr.c | 6 ++ src/cc65/symentry.c | 46 ++++++++++ src/cc65/symentry.h | 59 +++++++------ src/cc65/symtab.c | 12 +-- 10 files changed, 261 insertions(+), 164 deletions(-) diff --git a/include/stdlib.h b/include/stdlib.h index a58d29c87..e938e8a3a 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -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*)); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index c5024fb82..7144edb81 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -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); diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 40235ea84..8cb2e5ee6 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -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)) { diff --git a/src/cc65/declare.h b/src/cc65/declare.h index eac2897d9..96cdc40d9 100644 --- a/src/cc65/declare.h +++ b/src/cc65/declare.h @@ -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 */ diff --git a/src/cc65/declattr.c b/src/cc65/declattr.c index 3ac3e1479..91c7682e2 100644 --- a/src/cc65/declattr.c +++ b/src/cc65/declattr.c @@ -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 */ @@ -35,12 +35,16 @@ #include +/* 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" @@ -51,28 +55,46 @@ /* 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 (); } diff --git a/src/cc65/declattr.h b/src/cc65/declattr.h index cef08b30f..976de35ce 100644 --- a/src/cc65/declattr.h +++ b/src/cc65/declattr.h @@ -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 */ @@ -38,45 +38,38 @@ -#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 */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0a036b24d..8b5069b34 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -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); diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index 718cd470e..6ad4a5cfc 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -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 */ { diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 11d292131..06e5a0e87 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -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 */ @@ -41,10 +41,12 @@ #include /* 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 */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index dc246ef4b..1b938200f 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -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) { -- 2.39.5