]> git.sur5r.net Git - cc65/blobdiff - src/cc65/declare.c
Restructured search path handling.
[cc65] / src / cc65 / declare.c
index 29103dbb12f6519f5538581a972a6defc1106228..587d7ce74b34a2ab84cf0fb83ae0e1d4b2069dbe 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2008 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -185,6 +185,17 @@ static TypeCode OptionalQualifiers (TypeCode Allowed)
                 }
                 break;
 
+            case TOK_CDECL:
+                if (Allowed & T_QUAL_CDECL) {
+                    if (Q & T_QUAL_CDECL) {
+                        DuplicateQualifier ("cdecl");
+                    }
+                    Q |= T_QUAL_CDECL;
+                } else {
+                    goto Done;
+                }
+                break;
+
            default:
                goto Done;
 
@@ -208,6 +219,19 @@ Done:
             Q &= ~T_QUAL_ADDRSIZE;
     }
 
+    /* We cannot have more than one calling convention specifier */
+    switch (Q & T_QUAL_CCONV) {
+
+        case T_QUAL_NONE:
+        case T_QUAL_FASTCALL:
+        case T_QUAL_CDECL:
+            break;
+
+        default:
+            Error ("Cannot specify more than one calling convention qualifier");
+            Q &= ~T_QUAL_CCONV;
+    }
+
     /* Return the qualifiers read */
     return Q;
 }
@@ -249,9 +273,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;
 }
 
 
@@ -294,7 +319,7 @@ static void FixQualifiers (Type* DataType)
     while (T->C != T_END) {
         if (IsTypeArray (T)) {
             /* Extract any type qualifiers */
-            Q |= T->C & T_MASK_QUAL;
+            Q |= GetQualifier (T);
             T->C = UnqualifiedType (T->C);
         } else {
             /* Add extracted type qualifiers here */
@@ -723,8 +748,8 @@ static SymEntry* ParseStructDecl (const char* Name)
             }
 
             /* Add a field entry to the table */
-            if (FieldWidth > 0) {                  
-                /* Add full byte from the bit offset to the variable offset. 
+            if (FieldWidth > 0) {
+                /* Add full byte from the bit offset to the variable offset.
                  * This simplifies handling he bit-field as a char type
                  * in expressions.
                  */
@@ -738,7 +763,9 @@ static SymEntry* ParseStructDecl (const char* Name)
                 }
             } else {
                 AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
-                StructSize += CheckedSizeOf (Decl.Type);
+                if (!FlexibleMember) {
+                    StructSize += CheckedSizeOf (Decl.Type);
+                }
             }
 
 NextMember: if (CurTok.Tok != TOK_COMMA) {
@@ -1121,7 +1148,7 @@ static void ParseAnsiParamList (FuncDesc* F)
 
        DeclSpec        Spec;
        Declaration     Decl;
-       DeclAttr        Attr;
+        SymEntry*       Sym;
 
        /* Allow an ellipsis as last parameter */
        if (CurTok.Tok == TOK_ELLIPSIS) {
@@ -1159,11 +1186,21 @@ 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);
+        Sym = AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0);
+
+        /* Add attributes if we have any */
+        SymUseAttr (Sym, &Decl);
+
+        /* If the parameter is a struct or union, emit a warning */
+        if (IsClassStruct (Decl.Type)) {
+            if (IS_Get (&WarnStructParam)) {
+                Warning ("Passing struct by value for parameter `%s'", Decl.Ident);
+            }
+        }
 
        /* Count arguments */
                ++F->ParamCount;
@@ -1180,17 +1217,6 @@ 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) != 0) {
-           Error ("Parameter name omitted");
-       }
-    }
 }
 
 
@@ -1229,8 +1255,10 @@ static FuncDesc* ParseFuncDecl (void)
 
     /* Parse params */
     if ((F->Flags & FD_OLDSTYLE) == 0) {
+
        /* New style function */
        ParseAnsiParamList (F);
+
     } else {
        /* Old style function */
        ParseOldStyleParamList (F);
@@ -1401,6 +1429,9 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
     if (Qualifiers & T_QUAL_FASTCALL) {
         Error ("Invalid `__fastcall__' qualifier");
     }
+    if (Qualifiers & T_QUAL_CDECL) {
+        Error ("Invalid `__cdecl__' qualifier");
+    }
 }
 
 
@@ -1457,6 +1488,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)) {
 
@@ -1756,12 +1790,12 @@ static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers)
 
     /* Special handling for a character array initialized by a literal */
     if (IsTypeChar (ElementType) &&
-        (CurTok.Tok == TOK_SCONST ||
-        (CurTok.Tok == TOK_LCURLY && NextTok.Tok == TOK_SCONST))) {
+        (CurTok.Tok == TOK_SCONST || CurTok.Tok == TOK_WCSCONST ||
+        (CurTok.Tok == TOK_LCURLY &&
+         (NextTok.Tok == TOK_SCONST || NextTok.Tok == TOK_WCSCONST)))) {
 
         /* Char array initialized by string constant */
         int NeedParen;
-        const char* Str;
 
         /* If we initializer is enclosed in brackets, remember this fact and
          * skip the opening bracket.
@@ -1771,16 +1805,13 @@ static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers)
             NextToken ();
         }
 
-        /* Get the initializer string and its size */
-        Str = GetLiteral (CurTok.IVal);
-        Count = GetLiteralPoolOffs () - CurTok.IVal;
-
         /* Translate into target charset */
-        TranslateLiteralPool (CurTok.IVal);
+        TranslateLiteral (CurTok.SVal);
 
         /* If the array is one too small for the string literal, omit the
          * trailing zero.
          */
+        Count = GetLiteralSize (CurTok.SVal);
         if (ElementCount != UNSPECIFIED &&
             ElementCount != FLEXIBLE    &&
             Count        == ElementCount + 1) {
@@ -1789,10 +1820,9 @@ static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers)
         }
 
         /* Output the data */
-        g_defbytes (Str, Count);
+        g_defbytes (GetLiteralStr (CurTok.SVal), Count);
 
-        /* Remove string from pool */
-        ResetLiteralPoolOffs (CurTok.IVal);
+        /* Skip the string */
         NextToken ();
 
         /* If the initializer was enclosed in curly braces, we need a closing