1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-25 17:29:50 +00:00

Changed handling of attributes to a more generic form (it's allowed in each

declaration now) and added a new attribute "unused" to flag unused parameters,
variables or functions that shouldn't be warned about.


git-svn-id: svn://svn.cc65.org/cc65/trunk@4373 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2009-10-18 21:42:59 +00:00
parent 5a00b38aab
commit a5a9700d19
5 changed files with 42 additions and 41 deletions

View File

@ -1124,6 +1124,7 @@ static void ParseAnsiParamList (FuncDesc* F)
DeclSpec Spec;
Declaration Decl;
SymEntry* Sym;
/* Allow an ellipsis as last parameter */
if (CurTok.Tok == TOK_ELLIPSIS) {
@ -1165,7 +1166,10 @@ static void ParseAnsiParamList (FuncDesc* F)
ParseAttribute (&Decl);
/* Create a symbol table entry */
AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0);
Sym = AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0);
/* Add attributes if we have any */
SymUseAttributes (Sym, &Decl);
/* If the parameter is a struct or union, emit a warning */
if (IsClassStruct (Decl.Type)) {
@ -1189,21 +1193,11 @@ static void ParseAnsiParamList (FuncDesc* F)
* the breaks above bail out without checking.
*/
ConsumeRParen ();
/* 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");
}
}
}
static FuncDesc* ParseFuncDecl (Declaration* D)
static FuncDesc* ParseFuncDecl (void)
/* Parse the argument list of a function. */
{
unsigned Offs;
@ -1241,20 +1235,6 @@ static FuncDesc* ParseFuncDecl (Declaration* D)
/* 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);
@ -1359,7 +1339,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
NextToken ();
/* Parse the function declaration */
F = ParseFuncDecl (D);
F = ParseFuncDecl ();
/* We cannot specify fastcall for variadic functions */
if ((F->Flags & FD_VARIADIC) && (Qualifiers & T_QUAL_FASTCALL)) {
@ -1481,6 +1461,9 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
D->StorageClass |= SC_FUNC;
}
/* Parse attributes for this declaration */
ParseAttribute (D);
/* Check several things for function or function pointer types */
if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) {

View File

@ -56,6 +56,7 @@
/* Forwards for attribute handlers */
static void NoReturnAttr (Declaration* D);
static void UnusedAttr (Declaration* D);
@ -67,7 +68,9 @@ struct AttrDesc {
};
static const AttrDesc AttrTable [] = {
{ "__noreturn__", NoReturnAttr },
{ "__unused__", UnusedAttr },
{ "noreturn", NoReturnAttr },
{ "unused", UnusedAttr },
};
@ -156,7 +159,7 @@ static void AddAttr (Declaration* D, DeclAttr* A)
void NoReturnAttr (Declaration* D)
static void NoReturnAttr (Declaration* D)
/* Parse the "noreturn" attribute */
{
/* Add the noreturn attribute */
@ -165,6 +168,15 @@ void NoReturnAttr (Declaration* D)
static void UnusedAttr (Declaration* D)
/* Parse the "unused" attribute */
{
/* Add the noreturn attribute */
AddAttr (D, NewDeclAttr (atUnused));
}
void ParseAttribute (Declaration* D)
/* Parse an additional __attribute__ modifier */
{

View File

@ -49,10 +49,8 @@ struct Declaration;
/* Supported attribute types */
typedef enum {
atNone = -1, /* No attribute */
atNoReturn, /* Function does not return */
atCount /* Number of attributes */
atUnused, /* Symbol is unused - don't warn */
} DeclAttrType;
/* An actual attribute description */

View File

@ -380,17 +380,24 @@ void NewFunc (SymEntry* Func)
/* Reenter the lexical level */
ReenterFunctionLevel (D);
/* Check if the function header contains unnamed parameters. These are
* only allowed in cc65 mode.
*/
if ((D->Flags & FD_UNNAMED_PARAMS) != 0 && (IS_Get (&Standard) != STD_CC65)) {
Error ("Parameter name omitted");
}
/* Declare two special functions symbols: __fixargs__ and __argsize__.
* The latter is different depending on the type of the function (variadic
* or not).
*/
AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);
if (D->Flags & FD_VARIADIC) {
/* Variadic function. The variable must be const. */
static const Type T[] = { TYPE(T_UCHAR | T_QUAL_CONST), TYPE(T_END) };
AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0);
/* Variadic function. The variable must be const. */
static const Type T[] = { TYPE(T_UCHAR | T_QUAL_CONST), TYPE(T_END) };
AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0);
} else {
/* Non variadic */
/* Non variadic */
AddConstSym ("__argsize__", type_uchar, SC_DEF | SC_CONST, D->ParamSize);
}
@ -435,13 +442,13 @@ void NewFunc (SymEntry* Func)
/* If this is a fastcall function, push the last parameter onto the stack */
if (IsQualFastcall (Func->Type) && D->ParamCount > 0) {
unsigned Flags;
unsigned Flags;
/* Fastcall functions may never have an ellipsis or the compiler is buggy */
CHECK ((D->Flags & FD_VARIADIC) == 0);
/* Fastcall functions may never have an ellipsis or the compiler is buggy */
CHECK ((D->Flags & FD_VARIADIC) == 0);
/* Generate the push */
if (IsTypeFunc (D->LastParam->Type)) {
/* Generate the push */
if (IsTypeFunc (D->LastParam->Type)) {
/* Pointer to function */
Flags = CF_PTR;
} else {

View File

@ -162,7 +162,8 @@ static void CheckSymTable (SymTable* Tab)
* defined but not used.
*/
if (((Flags & SC_AUTO) || (Flags & SC_STATIC)) && (Flags & SC_EXTERN) == 0) {
if (SymIsDef (Entry) && !SymIsRef (Entry)) {
if (SymIsDef (Entry) && !SymIsRef (Entry) &&
SymGetAttribute (Entry, atUnused) == 0) {
if (Flags & SC_PARAM) {
if (IS_Get (&WarnUnusedParam)) {
Warning ("Parameter `%s' is never used", Entry->Name);