#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
.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
# [[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]
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);
GMQCC_DEFINE_FLAG(UNINITIALIZED_GLOBAL)
GMQCC_DEFINE_FLAG(DIFFERENT_QUALIFIERS)
GMQCC_DEFINE_FLAG(DIFFERENT_ATTRIBUTES)
+ GMQCC_DEFINE_FLAG(DEPRECATED)
#endif
#ifdef GMQCC_TYPE_OPTIMIZATIONS
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)
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 ]] */