- made an extra field for the deprecated attribute, so it can be used in GNU and...
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Tue, 18 Mar 2008 01:28:54 +0000 (01:28 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Tue, 18 Mar 2008 01:28:54 +0000 (01:28 +0000)
- preliminary MS type modifier parsing

[r18968]

ast.c
ast_t.h
parser.c
type_t.h

diff --git a/ast.c b/ast.c
index 3184cf6..c1d1cf6 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -23,6 +23,7 @@
 #include "symbol_t.h"
 #include "type_t.h"
 #include "parser.h"
+#include "lang_features.h"
 
 #include <assert.h>
 #include <stdio.h>
@@ -1214,10 +1215,14 @@ void print_initializer(const initializer_t *initializer)
  * Print microsoft extended declaration modifiers.
  */
 static void print_ms_modifiers(const declaration_t *declaration) {
+       if((c_mode & _MS) == 0)
+               return;
+
        decl_modifiers_t modifiers = declaration->modifiers;
 
        /* DM_FORCEINLINE handled outside. */
-       if((modifiers & ~DM_FORCEINLINE) != 0 || declaration->alignment != 0 ||
+       if((modifiers & ~DM_FORCEINLINE) != 0 ||
+           declaration->alignment != 0 || declaration->deprecated != 0 ||
            declaration->get_property_sym != NULL || declaration->put_property_sym != NULL) {
                char *next = "(";
 
@@ -1249,7 +1254,7 @@ static void print_ms_modifiers(const declaration_t *declaration) {
                if(modifiers & DM_NOINLINE) {
                        fputs(next, out); next = ", "; fputs("noinline", out);
                }
-               if(modifiers & DM_DEPRECATED) {
+               if(declaration->deprecated != 0) {
                        fputs(next, out); next = ", "; fputs("deprecated", out);
                        if(declaration->deprecated_string != NULL)
                                fprintf(out, "(\"%s\")", declaration->deprecated_string);
diff --git a/ast_t.h b/ast_t.h
index 6dfa8f0..ab1a208 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -430,9 +430,8 @@ typedef enum {
        DM_NOVTABLE         = (1 <<  8),
        DM_NORETURN         = (1 <<  9),
        DM_NOINLINE         = (1 << 10),
-       DM_DEPRECATED       = (1 << 11),
-       DM_RESTRICT         = (1 << 12),
-       DM_NOALIAS          = (1 << 13)
+       DM_RESTRICT         = (1 << 11),
+       DM_NOALIAS          = (1 << 12)
 } decl_modifier_t;
 
 typedef unsigned short decl_modifiers_t;
@@ -441,7 +440,7 @@ struct declaration_t {
        unsigned char       namespc;
        unsigned char       declared_storage_class;
        unsigned char       storage_class;
-       unsigned char       alignment;          /**< Alignmnet of the declaration, 0 for default. */
+       unsigned char       alignment;          /**< Alignment of the declaration, 0 for default. */
        decl_modifiers_t    modifiers;          /**< MS __declspec modifiers. */
        const char         *deprecated_string;  /**< MS deprecated string if any. */
        symbol_t           *get_property_sym;   /**< MS get property. */
@@ -449,6 +448,7 @@ struct declaration_t {
        unsigned int        address_taken : 1;
        unsigned int        is_inline     : 1;
        unsigned int        used          : 1;  /**< Set if the declaration is used. */
+       unsigned int        deprecated    : 1;  /**< Microsoft of GNU deprecated attribute. */
        type_t             *type;
        symbol_t           *symbol;
        source_position_t   source_position;
index 658be05..95810ad 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -53,7 +53,8 @@ struct declaration_specifiers_t {
        source_position_t  source_position;
        unsigned char      declared_storage_class;
        unsigned char      alignment;         /**< Alignment, 0 if not set. */
-       bool               is_inline;
+       unsigned int       is_inline : 1;
+       unsigned int       deprecated : 1;
        decl_modifiers_t   decl_modifiers;    /**< MS __declspec extended modifier mask */
        const char        *deprecated_string; /**< can be set if declaration was marked deprecated. */
        symbol_t          *get_property_sym;  /**< the name of the get property if set. */
@@ -939,32 +940,40 @@ static string_t parse_string_literals(void)
        return result;
 }
 
+/**
+ * Parse one GNU attribute.
+ */
+static void parse_gnu_attribute(void)
+{
+       eat(T___attribute__);
+       expect('(');
+       expect('(');
+       while(true) {
+               if(token.type != T_IDENTIFIER)
+                       break;
+               symbol_t *symbol = token.v.symbol;
+               next_token();
+               if(token.type == '(')
+                       eat_until_matching_token('(');
+               if(token.type != ',')
+                       break;
+               next_token();
+       }
+       expect(')');
+       expect(')');
+end_error:
+       return;
+}
+
+/**
+ * Parse GNU attributes.
+ */
 static void parse_attributes(void)
 {
        while(true) {
                switch(token.type) {
                case T___attribute__: {
-                       next_token();
-
-                       expect('(');
-                       int depth = 1;
-                       while(depth > 0) {
-                               switch(token.type) {
-                               case T_EOF:
-                                       errorf(HERE, "EOF while parsing attribute");
-                                       break;
-                               case '(':
-                                       next_token();
-                                       depth++;
-                                       break;
-                               case ')':
-                                       next_token();
-                                       depth--;
-                                       break;
-                               default:
-                                       next_token();
-                               }
-                       }
+                       parse_gnu_attribute();
                        break;
                }
                case T_asm:
@@ -2163,8 +2172,10 @@ static void parse_microsoft_extended_decl_modifier(declaration_specifiers_t *spe
                        expect(')');
                } else if(symbol == sym_deprecated) {
                        next_token();
-                       DET_MOD(deprecated, DM_DEPRECATED);
-               if(token.type == '(') {
+                       if(specifiers->deprecated != 0)
+                               warningf(HERE, "deprecated used more than once");
+                       specifiers->deprecated = 1;
+                       if(token.type == '(') {
                                next_token();
                                if(token.type == T_STRING_LITERAL) {
                                        specifiers->deprecated_string = token.v.string.begin;
@@ -2219,7 +2230,7 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers)
                MATCH_STORAGE_CLASS(T_auto,     STORAGE_CLASS_AUTO)
                MATCH_STORAGE_CLASS(T_register, STORAGE_CLASS_REGISTER)
 
-               case T_declspec:
+               case T__declspec:
                        next_token();
                        expect('(');
                        add_anchor_token(')');
@@ -2259,6 +2270,11 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers)
                MATCH_TYPE_QUALIFIER(T_const,    TYPE_QUALIFIER_CONST);
                MATCH_TYPE_QUALIFIER(T_restrict, TYPE_QUALIFIER_RESTRICT);
                MATCH_TYPE_QUALIFIER(T_volatile, TYPE_QUALIFIER_VOLATILE);
+               MATCH_TYPE_QUALIFIER(T__w64,     TYPE_QUALIFIER_W64);
+               MATCH_TYPE_QUALIFIER(T___ptr32,  TYPE_QUALIFIER_PTR32);
+               MATCH_TYPE_QUALIFIER(T___ptr64,  TYPE_QUALIFIER_PTR64);
+               MATCH_TYPE_QUALIFIER(T___uptr,   TYPE_QUALIFIER_UPTR);
+               MATCH_TYPE_QUALIFIER(T___sptr,   TYPE_QUALIFIER_SPTR);
 
                case T___extension__:
                        /* TODO */
@@ -2533,6 +2549,7 @@ finish_specifiers:
        }
 
        type->base.qualifiers = type_qualifiers;
+       /* FIXME: check type qualifiers here */
 
        type_t *result = typehash_insert(type);
        if(newtype && result != type) {
@@ -2554,6 +2571,12 @@ static type_qualifiers_t parse_type_qualifiers(void)
                MATCH_TYPE_QUALIFIER(T_const,    TYPE_QUALIFIER_CONST);
                MATCH_TYPE_QUALIFIER(T_restrict, TYPE_QUALIFIER_RESTRICT);
                MATCH_TYPE_QUALIFIER(T_volatile, TYPE_QUALIFIER_VOLATILE);
+               /* microsoft extended type modifiers */
+               MATCH_TYPE_QUALIFIER(T__w64,     TYPE_QUALIFIER_W64);
+               MATCH_TYPE_QUALIFIER(T___ptr32,  TYPE_QUALIFIER_PTR32);
+               MATCH_TYPE_QUALIFIER(T___ptr64,  TYPE_QUALIFIER_PTR64);
+               MATCH_TYPE_QUALIFIER(T___uptr,   TYPE_QUALIFIER_UPTR);
+               MATCH_TYPE_QUALIFIER(T___sptr,   TYPE_QUALIFIER_SPTR);
 
                default:
                        return type_qualifiers;
@@ -3010,6 +3033,7 @@ static declaration_t *parse_declarator(
        declaration_t *const declaration    = allocate_declaration_zero();
        declaration->declared_storage_class = specifiers->declared_storage_class;
        declaration->modifiers              = specifiers->decl_modifiers;
+       declaration->deprecated             = specifiers->deprecated;
        declaration->deprecated_string      = specifiers->deprecated_string;
        declaration->get_property_sym       = specifiers->get_property_sym;
        declaration->put_property_sym       = specifiers->put_property_sym;
@@ -4275,7 +4299,7 @@ static expression_t *parse_reference(void)
        declaration->used = true;
 
        /* check for deprecated functions */
-       if(declaration->modifiers & DM_DEPRECATED) {
+       if(declaration->deprecated != 0) {
                const char *prefix = "";
                if (is_type_function(declaration->type))
                        prefix = "function ";
index 5832550..2824b96 100644 (file)
--- a/type_t.h
+++ b/type_t.h
@@ -54,6 +54,12 @@ typedef enum {
        TYPE_QUALIFIER_CONST    = 1 << 0,
        TYPE_QUALIFIER_RESTRICT = 1 << 1,
        TYPE_QUALIFIER_VOLATILE = 1 << 2,
+       /* microsoft extended qualifiers */
+       TYPE_QUALIFIER_W64      = 1 << 3,
+       TYPE_QUALIFIER_PTR32    = 1 << 4,
+       TYPE_QUALIFIER_PTR64    = 1 << 5,
+       TYPE_QUALIFIER_SPTR     = 1 << 6,
+       TYPE_QUALIFIER_UPTR     = 1 << 7,
 } type_qualifier_t;
 
 typedef unsigned int type_qualifiers_t;