Implement [[deprecated]] general attribute, will mark functions as deprecated. Makin...
authorDale Weiler <killfieldengine@gmail.com>
Sun, 30 Dec 2012 06:43:07 +0000 (06:43 +0000)
committerDale Weiler <killfieldengine@gmail.com>
Sun, 30 Dec 2012 06:43:07 +0000 (06:43 +0000)
ast.h
doc/gmqcc.1
gmqcc.ini.example
opts.c
opts.def
parser.c

diff --git a/ast.h b/ast.h
index bf7f6aa3c5cb1abd81811504332456ffe880461b..049feb9223a74ad40b51a133370c84eb95cc08cf 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -144,6 +144,7 @@ typedef struct
 #define AST_FLAG_NORETURN     (1<<1)
 #define AST_FLAG_INLINE       (1<<2)
 #define AST_FLAG_INITIALIZED  (1<<3)
+#define AST_FLAG_DEPRECATED   (1<<4)
 #define AST_FLAG_TYPE_MASK (AST_FLAG_VARIADIC | AST_FLAG_NORETURN)
 
 /* Value
index 5b54510ffc5a5ca7662c5c1f69362cbc5d0a1ef4..581a8e98a2c3b6ed152c345360753c62910917b3 100644 (file)
@@ -278,6 +278,11 @@ marked \'const\'.
 .TP
 .B -Wdifferent-attributes
 Similar to the above but for attributes like "[[noreturn]]".
+.TP
+.B -Wdeprecated
+Warn when a function is marked with the attribute
+"[[deprecated]]". This flag enables a warning on calls to functions
+marked as such.
 .SH COMPILE FLAGS
 .TP
 .B -fdarkplaces-string-table-bug
index e2956dcc80a35dd687c1fd0a6d960dae4930aaa4..6d7a53f4b0f1b772866d3a5de2a79abd9dea0aff 100644 (file)
     # [[noreturn]]
     DIFFERENT_ATTRIBUTES         = true
 
+    # Warn when a function is marked with the attribute
+    # "[[deprecated]]". This flag enables a warning on calls to functions
+    # marked as such.
+    DEPRECATED                   = true
+
 # Finally these are all the optimizations, usually present via the -O
 # prefix from the command line.
 [optimizations]
diff --git a/opts.c b/opts.c
index 69cb899767576eef215bdc1b6c2f9f3aa11c00ce..35f71146629900d249fe4fb4488ee53665ddcc16 100644 (file)
--- a/opts.c
+++ b/opts.c
@@ -57,6 +57,7 @@ static void opts_setdefault() {
     opts_set(opts.warn,  WARN_RESERVED_NAMES,            true);
     opts_set(opts.warn,  WARN_UNINITIALIZED_CONSTANT,    true);
     opts_set(opts.warn,  WARN_UNINITIALIZED_GLOBAL,      false);
+    opts_set(opts.warn,  WARN_DEPRECATED,                true);
     /* flags */
     opts_set(opts.flags, ADJUST_VECTOR_FIELDS,           true);
     opts_set(opts.flags, FTEPP,                          false);
index eb76082bd12bab79e2e285d32ca7e52087cfbca8..25b2722d37e48c8520031477a365dfd719db5475 100644 (file)
--- a/opts.def
+++ b/opts.def
@@ -84,6 +84,7 @@
     GMQCC_DEFINE_FLAG(UNINITIALIZED_GLOBAL)
     GMQCC_DEFINE_FLAG(DIFFERENT_QUALIFIERS)
     GMQCC_DEFINE_FLAG(DIFFERENT_ATTRIBUTES)
+    GMQCC_DEFINE_FLAG(DEPRECATED)
 #endif
 
 #ifdef GMQCC_TYPE_OPTIMIZATIONS
index 53220b51d7cb5f7f25a32a63d2cbdb69fb5b1afc..a191c535c4ddf94d8dd3a036526466c1f9a93198 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -1373,18 +1373,29 @@ static bool parser_close_call(parser_t *parser, shunt *sy)
         return false;
     }
 
+    
     if (!fun->expression.next) {
         parseerror(parser, "could not determine function return type");
         return false;
     } else {
+        ast_value *fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
+
+        if (fun->expression.flags & AST_FLAG_DEPRECATED) {
+            if (!fval)
+                return !parsewarning(parser, WARN_DEPRECATED, "call to function (which is marked deprecated)\n"
+                                    "-> it has been declared here: %s:%i",
+                                    ast_ctx(fun).file, ast_ctx(fun).line);
+            else
+                return !parsewarning(parser, WARN_DEPRECATED, "call to `%s` (which is marked deprecated)\n"
+                                    "-> `%s` declared here: %s:%i",
+                                    fval->name, fval->name, ast_ctx(fun).file, ast_ctx(fun).line);
+        }
+
         if (vec_size(fun->expression.params) != paramcount &&
             !((fun->expression.flags & AST_FLAG_VARIADIC) &&
               vec_size(fun->expression.params) < paramcount))
         {
-            ast_value *fval;
             const char *fewmany = (vec_size(fun->expression.params) > paramcount) ? "few" : "many";
-
-            fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
             if (opts.standard == COMPILER_GMQCC)
             {
                 if (fval)
@@ -2606,6 +2617,14 @@ static bool parse_qualifiers(parser_t *parser, bool with_local, int *cvq, bool *
                     return false;
                 }
             }
+            else if (!strcmp(parser_tokval(parser), "deprecated")) {
+                flags |= AST_FLAG_DEPRECATED;
+                if (!parser_next(parser) || parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
+                    parseerror(parser, "`deprecated` attribute has no parameters, expected `]]`");
+                    *cvq = CV_WRONG;
+                    return false;
+                }
+            }
             else
             {
                 /* Skip tokens until we hit a ]] */