Jonathan M Davis, el 12 de julio a las 18:12 me escribiste:
> > > When a symbol has been deprecated, -d is required to compile any code
> > > using that symbol. So, deprecation breaks code. You either have to
> > > change your code so that it doesn't use the deprecated symbol, or you
> > > have to change your build scripts to use -d. In either case, deprecating
> > > a symbol without warning is going to cause problems for anyone
> > > maintaining code which uses that symbol.
> > 
> > If you don't want your code to break when something is deprecated, you
> > should *always* compile with -d, so no, you don't have to change the
> > build system if you always have -d. Maybe all needed is just a -di (as
> > in -wi), where deprecation are informed but not treated as errors.
> > 
> > Scheduled for deprecation makes no sense, it's a user decision to use
> > deprecated code or not, and if should be a user decision if he/she wants
> > a warning about deprecated stuff or not.
> 
> Except, of course, that good cood generally won't use anything that's 
> deprecated, since the deprecated item is going to go away. The user can 
> decide 
> to use -d and use deprecated code if it makes sense for them, but that really 
> should be decided on a case-by-case basis. Most programmers won't want to use 
> -d. So, they're not going to compile with -d by default. So, deprecating 
> something will break their code. By saying that you're scheduling something 
> for deprecation, you're giving the user time to deal with the change before 
> it 
> breaks their code.
> 
> Now, I could see an argument for changing how deprecation works so that 
> deprecated has no effect unless a flag turns it on, in which case, the user 
> is 
> deciding whether they want to warned about using deprecated code. In such a 
> case, "scheduled for deprecation" isn't quite as necessary, but then you're 
> just going to break everyone's code when you remove the function (at least 
> everyone who didn't use the flag to be warned about using deprecated 
> symbols). 
> And rather than being able to then change their build scripts to use -d while 
> they fix the problem, they then _have_ to go change their code (or not 
> upgrade 
> their libraries) in order for their code to compile. But that's not how 
> deprecated works in D.

So then, why don't we fix it (patch attached, you can apply it with 'git
am file'). I think -di is the real solution to the problem. Things are
deprecated or not, and people want to be informed if they are using
something deprecated or not. Scheduled for deprecation seems to be a way
to say "show me a deprecation message", not a real "state".

> When a symbol is deprecated, it's an error to use it unless you compile with -
> d. So, there is no warning about using deprecated stuff. It's an outright 
> error. It just so happens that you can turn it off if you need to (hopefully 
> as a quick fix). And given that deprecating a symbol introduces errors into 
> the code of anyone who uses that symbol, informing people ahead of time gives 
> them the opportunity to change their code before it breaks. The result is a 
> much smoother process.

OK, then we should fix the compiler (again, patch attached). -di is the
solution. My patch doesn't change the defaults, but if people think is
better to show deprecation errors by default, it can be trivially
changed.

> 1. Something is scheduled for deprecation, so programmers then have the time 
> to figure out what they're going to do to change their code, and they have 
> time to make the changes. Nothing breaks. No one is forced to make immediate 
> changes.

This is what deprecated is for! Removing stuff breaks code, not
deprecating stuff! Deprecated really is "scheduled for removal", so
"scheduled for deprecation" is "scheduled for scheduled for removal", it
makes no sense. Fix the compiler!

> 2. The symbol is then deprecated. Anyone who did not take the time to make 
> changes as they were told that they were going to have to do then has broken 
> code, but they have the quick fix of compiling with -d if they need to. 
> They're still going to have to figure out what they're going to do about 
> changing their code, and they're forced to look at the problem at least far 
> enough to enable -d, but their code can still work with some changes to their 
> build scripts.
> 
> 3. The symbol is outright removed. Programmers have had ample time to change 
> their code, and if they haven't, they now have to. But they were told that 
> the 
> symbol was going away and had to have made changes to their build scripts to 
> even use it this long, so the developer of the library hasn't just screwed 
> them over.
> 
> The idea is to provide a smooth path for necessary changes. And just 
> deprecating something out of the blue does _not_ do that.

Unless we fix the compiler :)

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
All evidence has been buried
All tapes have been erased
But your footsteps give you away
So you're backtracking
>From 50db16202506748eb621ed391d57b91750fc408f Mon Sep 17 00:00:00 2001
From: Leandro Lucarella <[email protected]>
Date: Tue, 12 Jul 2011 17:44:50 -0300
Subject: [PATCH] Add option to show deprecated errors as warnings

The new option -di treats deprecation errors as informational warnings,
just like -wi show warnings as informational messages without triggering
errors.

The deprecation option uses the same mechanism as warnings use, so the
same counter (globals.warnings) is shared for both regular and deprecation
warnings (when -di is in use). Some methods that print there own errors
now use the global function error() to print them. There is a particular
case in the Lexer where errors are not triggered but counted, in that case
the same is done with deprecation warnings, asuming it was intended
behaviour.
---
 docs/man/man1/dmd.1 |    3 +
 src/dsymbol.c       |  119 ++++++++++++++++++++++++++-------------------------
 src/dsymbol.h       |    4 ++
 src/expression.c    |   27 ++++++++---
 src/expression.h    |    1 +
 src/iasm.c          |    4 +-
 src/lexer.c         |   98 ++++++++++++++++++++++++++++-------------
 src/lexer.h         |    2 +
 src/mars.c          |   30 ++++++++++++-
 src/mars.h          |   13 ++++--
 src/module.c        |    4 +-
 src/mtype.c         |   18 ++++----
 src/parse.c         |   20 ++++----
 src/statement.c     |   12 ++++-
 src/statement.h     |    1 +
 src/toobj.c         |    6 +-
 16 files changed, 232 insertions(+), 130 deletions(-)

diff --git a/docs/man/man1/dmd.1 b/docs/man/man1/dmd.1
index 9d438e7..b3fa335 100644
--- a/docs/man/man1/dmd.1
+++ b/docs/man/man1/dmd.1
@@ -43,6 +43,9 @@ Write documentation file to
 .IP -d
 Allow deprecated features.
 
+.IP -di
+Show use of deprecated features as warnings.
+
 .IP -debug
 Compile in debug code
 
diff --git a/src/dsymbol.c b/src/dsymbol.c
index e20d289..dafecb6 100644
--- a/src/dsymbol.c
+++ b/src/dsymbol.c
@@ -195,11 +195,8 @@ const char *Dsymbol::toPrettyChars()
     return s;
 }
 
-char *Dsymbol::locToChars()
+Loc& Dsymbol::getLoc()
 {
-    OutBuffer buf;
-    char *p;
-
     if (!loc.filename)  // avoid bug 5861.
     {
         Module *m = getModule();
@@ -207,7 +204,12 @@ char *Dsymbol::locToChars()
         if (m && m->srcfile)
             loc.filename = m->srcfile->toChars();
     }
-    return loc.toChars();
+    return loc;
+}
+
+char *Dsymbol::locToChars()
+{
+    return getLoc().toChars();
 }
 
 const char *Dsymbol::kind()
@@ -527,70 +529,71 @@ int Dsymbol::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
     return 0;
 }
 
-void Dsymbol::error(const char *format, ...)
+char *Dsymbol::genMsg(const char *format)
 {
-    //printf("Dsymbol::error()\n");
-    if (!global.gag)
+    const char* kind = this->kind();
+    const char* name;
+    size_t len = strlen(format);
+    if (!isAnonymous())
     {
-        char *p = locToChars();
-
-        if (*p)
-            fprintf(stdmsg, "%s: ", p);
-        mem.free(p);
-
-        fprintf(stdmsg, "Error: ");
-        if (isAnonymous())
-            fprintf(stdmsg, "%s ", kind());
-        else
-            fprintf(stdmsg, "%s %s ", kind(), toPrettyChars());
-
-        va_list ap;
-        va_start(ap, format);
-        vfprintf(stdmsg, format, ap);
-        va_end(ap);
-
-        fprintf(stdmsg, "\n");
-        fflush(stdmsg);
-//halt();
+        name = toPrettyChars();
+        len += strlen(name) + 1; // +1 for a space
+    }
+    len += strlen(kind) + 1; // +1 for a space
+    char *s = (char *)mem.malloc(len + 1); // +1 for \0
+    strcpy(s, kind);
+    strcat(s, " ");
+    if (!isAnonymous()) {
+        strcat(s, name);
+        strcat(s, " ");
     }
-    global.errors++;
+    strcat(s, format);
+    return s;
+}
 
-    //fatal();
+void Dsymbol::error(const char *format, ...)
+{
+    char *s = genMsg(format);
+    va_list ap;
+    va_start(ap, format);
+    ::verror(getLoc(), s, ap);
+    va_end(ap);
+    mem.free(s);
 }
 
 void Dsymbol::error(Loc loc, const char *format, ...)
 {
-    if (!global.gag)
-    {
-        char *p = loc.toChars();
-        if (!*p)
-            p = locToChars();
-
-        if (*p)
-            fprintf(stdmsg, "%s: ", p);
-        mem.free(p);
-
-        fprintf(stdmsg, "Error: ");
-        fprintf(stdmsg, "%s %s ", kind(), toPrettyChars());
-
-        va_list ap;
-        va_start(ap, format);
-        vfprintf(stdmsg, format, ap);
-        va_end(ap);
-
-        fprintf(stdmsg, "\n");
-        fflush(stdmsg);
-//halt();
-    }
+    char *s = genMsg(format);
+    va_list ap;
+    va_start(ap, format);
+    ::verror(loc, s, ap);
+    va_end(ap);
+    mem.free(s);
+}
 
-    global.errors++;
+void Dsymbol::deprecation(const char *format, ...)
+{
+    char *s = genMsg(format);
+    va_list ap;
+    va_start(ap, format);
+    ::vdeprecation(getLoc(), s, ap);
+    va_end(ap);
+    mem.free(s);
+}
 
-    //fatal();
+void Dsymbol::deprecation(Loc loc, const char *format, ...)
+{
+    char *s = genMsg(format);
+    va_list ap;
+    va_start(ap, format);
+    ::vdeprecation(loc, s, ap);
+    va_end(ap);
+    mem.free(s);
 }
 
 void Dsymbol::checkDeprecated(Loc loc, Scope *sc)
 {
-    if (!global.params.useDeprecated && isDeprecated())
+    if (global.params.deprecation && isDeprecated())
     {
         // Don't complain if we're inside a deprecated symbol's scope
         for (Dsymbol *sp = sc->parent; sp; sp = sp->parent)
@@ -608,7 +611,7 @@ void Dsymbol::checkDeprecated(Loc loc, Scope *sc)
                 goto L1;
         }
 
-        error(loc, "is deprecated");
+        deprecation(loc, "is deprecated");
     }
 
   L1:
@@ -1109,8 +1112,8 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
     {   VarDeclaration **pvar;
         Expression *ce;
 
-        if (ident == Id::length && !global.params.useDeprecated)
-            error("using 'length' inside [ ] is deprecated, use '$' instead");
+        if (ident == Id::length && global.params.deprecation)
+            deprecation("using 'length' inside [ ] is deprecated, use '$' instead");
 
     L1:
 
diff --git a/src/dsymbol.h b/src/dsymbol.h
index 065a337..2c24f3e 100644
--- a/src/dsymbol.h
+++ b/src/dsymbol.h
@@ -123,11 +123,15 @@ struct Dsymbol : Object
     Dsymbol();
     Dsymbol(Identifier *);
     char *toChars();
+    Loc& getLoc();
     char *locToChars();
     int equals(Object *o);
     int isAnonymous();
+    char *genMsg(const char *format);
     void error(Loc loc, const char *format, ...);
     void error(const char *format, ...);
+    void deprecation(Loc loc, const char *format, ...);
+    void deprecation(const char *format, ...);
     void checkDeprecated(Loc loc, Scope *sc);
     Module *getModule();
     Dsymbol *pastMixin();
diff --git a/src/expression.c b/src/expression.c
index 04acefa..678cf47 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1058,6 +1058,17 @@ void Expression::warning(const char *format, ...)
     }
 }
 
+void Expression::deprecation(const char *format, ...)
+{
+    if (type != Type::terror)
+    {
+        va_list ap;
+        va_start(ap, format);
+        ::vdeprecation(loc, format, ap);
+        va_end( ap );
+    }
+}
+
 void Expression::rvalue()
 {
     if (type && type->toBasetype()->ty == Tvoid)
@@ -4928,7 +4939,7 @@ Expression *DeclarationExp::semantic(Scope *sc)
                 error("declaration %s is already defined in another scope in %s",
                     s->toPrettyChars(), sc->func->toChars());
             }
-            else if (!global.params.useDeprecated)
+            else if (global.params.deprecation)
             {   // Disallow shadowing
 
                 for (Scope *scx = sc->enclosing; scx && scx->func == sc->func; scx = scx->enclosing)
@@ -4938,7 +4949,7 @@ Expression *DeclarationExp::semantic(Scope *sc)
                         (s2 = scx->scopesym->symtab->lookup(s->ident)) != NULL &&
                         s != s2)
                     {
-                        error("shadowing declaration %s is deprecated", s->toPrettyChars());
+                        deprecation("shadowing declaration %s is deprecated", s->toPrettyChars());
                     }
                 }
             }
@@ -5314,8 +5325,8 @@ Expression *IsExp::semantic(Scope *sc)
                 break;
 
             case TOKinvariant:
-                if (!global.params.useDeprecated)
-                    error("use of 'invariant' rather than 'immutable' is deprecated");
+                if (global.params.deprecation)
+                    deprecation("use of 'invariant' rather than 'immutable' is deprecated");
             case TOKimmutable:
                 if (!targ->isImmutable())
                     goto Lno;
@@ -8150,8 +8161,8 @@ Expression *DeleteExp::semantic(Scope *sc)
         IndexExp *ae = (IndexExp *)(e1);
         Type *tb1 = ae->e1->type->toBasetype();
         if (tb1->ty == Taarray)
-        {   if (!global.params.useDeprecated)
-                error("delete aa[key] deprecated, use aa.remove(key)");
+        {   if (global.params.deprecation)
+                deprecation("delete aa[key] deprecated, use aa.remove(key)");
         }
     }
 
@@ -9305,8 +9316,8 @@ Expression *AssignExp::semantic(Scope *sc)
                 if (search_function(ad, id))
                 {   Expression *e = new DotIdExp(loc, ae->e1, id);
 
-                    if (1 || !global.params.useDeprecated)
-                    {   error("operator [] assignment overload with opIndex(i, value) illegal, use opIndexAssign(value, i)");
+                    if (1 || !global.params.deprecation)
+                    {   deprecation("operator [] assignment overload with opIndex(i, value) illegal, use opIndexAssign(value, i)");
                         return new ErrorExp();
                     }
 
diff --git a/src/expression.h b/src/expression.h
index 026cdb0..7004dc3 100644
--- a/src/expression.h
+++ b/src/expression.h
@@ -105,6 +105,7 @@ struct Expression : Object
     virtual void dump(int indent);
     void error(const char *format, ...);
     void warning(const char *format, ...);
+    void deprecation(const char *format, ...);
     virtual void rvalue();
 
     static Expression *combine(Expression *e1, Expression *e2);
diff --git a/src/iasm.c b/src/iasm.c
index cf65a8e..91da7b7 100644
--- a/src/iasm.c
+++ b/src/iasm.c
@@ -3968,8 +3968,8 @@ STATIC OPND *asm_una_exp()
                     // Check for offset keyword
                     if (asmtok->ident == Id::offset)
                     {
-                        if (!global.params.useDeprecated)
-                            error(asmstate.loc, "offset deprecated, use offsetof");
+                        if (global.params.deprecation)
+                            deprecation(asmstate.loc, "offset deprecated, use offsetof");
                         goto Loffset;
                     }
                     if (asmtok->ident == Id::offsetof)
diff --git a/src/lexer.c b/src/lexer.c
index 02a6509..5f1e445 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -300,48 +300,84 @@ Lexer::Lexer(Module *mod,
 
 void Lexer::error(const char *format, ...)
 {
-    if (mod && !global.gag)
+    if (mod)
     {
-        char *p = loc.toChars();
-        if (*p)
-            fprintf(stdmsg, "%s: ", p);
-        mem.free(p);
-
         va_list ap;
         va_start(ap, format);
-        vfprintf(stdmsg, format, ap);
+        ::verror(loc, format, ap);
         va_end(ap);
 
-        fprintf(stdmsg, "\n");
-        fflush(stdmsg);
-
         if (global.errors >= 20)        // moderate blizzard of cascading messages
             fatal();
     }
-    global.errors++;
+    else
+        global.errors++;
 }
 
 void Lexer::error(Loc loc, const char *format, ...)
 {
-    if (mod && !global.gag)
+    if (mod)
     {
-        char *p = loc.toChars();
-        if (*p)
-            fprintf(stdmsg, "%s: ", p);
-        mem.free(p);
+        va_list ap;
+        va_start(ap, format);
+        ::verror(loc, format, ap);
+        va_end(ap);
 
+        if (global.errors >= 20)        // moderate blizzard of cascading messages
+            fatal();
+    }
+    else
+        global.errors++;
+}
+
+void Lexer::deprecation(const char *format, ...)
+{
+    if (mod)
+    {
         va_list ap;
         va_start(ap, format);
-        vfprintf(stdmsg, format, ap);
+        ::vdeprecation(loc, format, ap);
         va_end(ap);
 
-        fprintf(stdmsg, "\n");
-        fflush(stdmsg);
+        if (global.params.deprecation > 1 &&
+                global.warnings >= 20)  // moderate blizzard of cascading messages
+            fatal();
+        else if (global.params.deprecation == 1 &&
+                global.errors >= 20)    // moderate blizzard of cascading messages
+            fatal();
+    }
+    else
+    {
+        if (global.params.deprecation > 1)
+            global.warnings++;
+        else
+            global.errors++;
+    }
+}
+
+void Lexer::deprecation(Loc loc, const char *format, ...)
+{
+    if (mod)
+    {
+        va_list ap;
+        va_start(ap, format);
+        ::vdeprecation(loc, format, ap);
+        va_end(ap);
 
-        if (global.errors >= 20)        // moderate blizzard of cascading messages
+        if (global.params.deprecation > 1 &&
+                global.warnings >= 20)  // moderate blizzard of cascading messages
+            fatal();
+        else if (global.params.deprecation == 1 &&
+                global.errors >= 20)    // moderate blizzard of cascading messages
             fatal();
     }
-    global.errors++;
+    else
+    {
+        if (global.params.deprecation > 1)
+            global.warnings++;
+        else
+            global.errors++;
+    }
 }
 
 TOK Lexer::nextToken()
@@ -624,8 +660,8 @@ void Lexer::scan(Token *t)
                 t->postfix = 0;
                 t->value = TOKstring;
 #if DMDV2
-                if (!global.params.useDeprecated)
-                    error("Escape String literal %.*s is deprecated, use double quoted string literal \"%.*s\" instead", p - pstart, pstart, p - pstart, pstart);
+                if (global.params.deprecation)
+                    deprecation("Escape String literal %.*s is deprecated, use double quoted string literal \"%.*s\" instead", p - pstart, pstart, p - pstart, pstart);
 #endif
                 return;
             }
@@ -2274,8 +2310,8 @@ done:
                 goto L1;
 
             case 'l':
-                if (1 || !global.params.useDeprecated)
-                    error("'l' suffix is deprecated, use 'L' instead");
+                if (1 || global.params.deprecation)
+                    deprecation("'l' suffix is deprecated, use 'L' instead");
             case 'L':
                 f = FLAGS_long;
             L1:
@@ -2290,8 +2326,8 @@ done:
         break;
     }
 
-    if (state == STATE_octal && n >= 8 && !global.params.useDeprecated)
-        error("octal literals 0%llo%.*s are deprecated, use std.conv.octal!%llo%.*s instead",
+    if (state == STATE_octal && n >= 8 && global.params.deprecation)
+        deprecation("octal literals 0%llo%.*s are deprecated, use std.conv.octal!%llo%.*s instead",
                 n, p - psuffix, psuffix, n, p - psuffix, psuffix);
 
     switch (flags)
@@ -2522,8 +2558,8 @@ done:
             break;
 
         case 'l':
-            if (!global.params.useDeprecated)
-                error("'l' suffix is deprecated, use 'L' instead");
+            if (global.params.deprecation)
+                deprecation("'l' suffix is deprecated, use 'L' instead");
         case 'L':
             result = TOKfloat80v;
             p++;
@@ -2531,8 +2567,8 @@ done:
     }
     if (*p == 'i' || *p == 'I')
     {
-        if (!global.params.useDeprecated && *p == 'I')
-            error("'I' suffix is deprecated, use 'i' instead");
+        if (global.params.deprecation && *p == 'I')
+            deprecation("'I' suffix is deprecated, use 'i' instead");
         p++;
         switch (result)
         {
diff --git a/src/lexer.h b/src/lexer.h
index b7811ca..24d1c87 100644
--- a/src/lexer.h
+++ b/src/lexer.h
@@ -302,6 +302,8 @@ struct Lexer
     TOK inreal(Token *t);
     void error(const char *format, ...);
     void error(Loc loc, const char *format, ...);
+    void deprecation(const char *format, ...);
+    void deprecation(Loc loc, const char *format, ...);
     void pragma();
     unsigned decodeUTF();
     void getDocComment(Token *t, unsigned lineComment);
diff --git a/src/mars.c b/src/mars.c
index 82f3ad3..82e8eb2 100644
--- a/src/mars.c
+++ b/src/mars.c
@@ -155,6 +155,17 @@ void warning(Loc loc, const char *format, ...)
     va_end( ap );
 }
 
+void deprecation(Loc loc, const char *format, ...)
+{
+    va_list ap;
+    va_start(ap, format);
+    if (global.params.deprecation > 1)
+        vwarning(loc, format, ap);
+    else
+        verror(loc, format, ap);
+    va_end( ap );
+}
+
 void verror(Loc loc, const char *format, va_list ap)
 {
     if (!global.gag)
@@ -208,6 +219,19 @@ void vwarning(Loc loc, const char *format, va_list ap)
     }
 }
 
+void vdeprecation(Loc loc, const char *format, va_list ap)
+{
+    if (global.params.deprecation > 1)
+    {
+        char oldw = global.params.warnings;
+        global.params.warnings = 2; // activate warnings temporarly
+        vwarning(loc, format, ap);
+        global.params.warnings = oldw;
+    }
+    else
+        verror(loc, format, ap);
+}
+
 /***************************************
  * Call this after printing out fatal error messages to clean up and exit
  * the compiler.
@@ -260,6 +284,7 @@ Usage:\n\
   -Dddocdir      write documentation file to docdir directory\n\
   -Dffilename    write documentation file to filename\n\
   -d             allow deprecated features\n\
+  -di            show use of deprecated features as warnings\n\
   -debug         compile in debug code\n\
   -debug=level   compile in debug code <= level\n\
   -debug=ident   compile in debug code identified by ident\n\
@@ -359,6 +384,7 @@ int main(int argc, char *argv[])
     global.params.obj = 1;
     global.params.Dversion = 2;
     global.params.quiet = 1;
+    global.params.deprecation = 1; // deprecated features are errors
 
     global.params.linkswitches = new Array();
     global.params.libfiles = new Array();
@@ -443,7 +469,9 @@ int main(int argc, char *argv[])
         if (*p == '-')
         {
             if (strcmp(p + 1, "d") == 0)
-                global.params.useDeprecated = 1;
+                global.params.deprecation = 0;
+            else if (strcmp(p + 1, "di") == 0)
+                global.params.deprecation = 2;
             else if (strcmp(p + 1, "c") == 0)
                 global.params.link = 0;
             else if (strcmp(p + 1, "cov") == 0)
diff --git a/src/mars.h b/src/mars.h
index d2533ce..2db1de6 100644
--- a/src/mars.h
+++ b/src/mars.h
@@ -146,7 +146,9 @@ struct Param
     char isOPenBSD;     // generate code for OpenBSD
     char isSolaris;     // generate code for Solaris
     char scheduler;     // which scheduler to use
-    char useDeprecated; // allow use of deprecated features
+    char deprecation;   // 0: sillently allow use of deprecated features
+                        // 1: use of deprecated features as errors
+                        // 2: informational warnings (no errors)
     char useAssert;     // generate runtime code for assert()'s
     char useInvariants; // generate class invariant checks
     char useIn;         // generate precondition checks
@@ -247,9 +249,10 @@ struct Global
     const char *version;
 
     Param params;
-    unsigned errors;    // number of errors reported so far
-    unsigned warnings;  // number of warnings reported so far
-    unsigned gag;       // !=0 means gag reporting of errors & warnings
+    unsigned errors;        // number of errors reported so far
+    unsigned warnings;      // number of warnings reported so far
+    unsigned deprecations;  // number of deprecations reported so far
+    unsigned gag;           // !=0 means gag reporting of errors & warnings
 
     Global();
 };
@@ -389,8 +392,10 @@ typedef uint64_t StorageClass;
 
 void warning(Loc loc, const char *format, ...);
 void error(Loc loc, const char *format, ...);
+void deprecation(Loc loc, const char *format, ...);
 void verror(Loc loc, const char *format, va_list);
 void vwarning(Loc loc, const char *format, va_list);
+void vdeprecation(Loc loc, const char *format, va_list);
 void fatal();
 void err_nomem();
 int runLINK();
diff --git a/src/module.c b/src/module.c
index 1d46f57..851b424 100644
--- a/src/module.c
+++ b/src/module.c
@@ -128,8 +128,8 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
         if (srcfilename->equalsExt("html") ||
             srcfilename->equalsExt("htm")  ||
             srcfilename->equalsExt("xhtml"))
-        {   if (!global.params.useDeprecated)
-                error("html source files is deprecated %s", srcfilename->toChars());
+        {   if (global.params.deprecation)
+                deprecation("html source files is deprecated %s", srcfilename->toChars());
             isHtml = 1;
         }
         else
diff --git a/src/mtype.c b/src/mtype.c
index ebb46fb..903ab8f 100644
--- a/src/mtype.c
+++ b/src/mtype.c
@@ -56,7 +56,7 @@ FuncDeclaration *hasThis(Scope *sc);
 #define LOGDEFAULTINIT  0       // log ::defaultInit()
 
 // Allow implicit conversion of T[] to T*
-#define IMPLICIT_ARRAY_TO_PTR   global.params.useDeprecated
+#define IMPLICIT_ARRAY_TO_PTR   (!global.params.deprecation)
 
 /* These have default values for 32 bit code, they get
  * adjusted for 64 bit code.
@@ -1699,8 +1699,8 @@ Expression *Type::getProperty(Loc loc, Identifier *ident)
     }
     else if (ident == Id::typeinfo)
     {
-        if (!global.params.useDeprecated)
-            error(loc, ".typeinfo deprecated, use typeid(type)");
+        if (global.params.deprecation)
+            deprecation(loc, ".typeinfo deprecated, use typeid(type)");
         e = getTypeInfo(NULL);
     }
     else if (ident == Id::init)
@@ -1768,8 +1768,8 @@ Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident)
     {
         if (ident == Id::offset)
         {
-            if (!global.params.useDeprecated)
-                error(e->loc, ".offset deprecated, use .offsetof");
+            if (global.params.deprecation)
+                deprecation(e->loc, ".offset deprecated, use .offsetof");
             goto Loffset;
         }
         else if (ident == Id::offsetof)
@@ -1818,8 +1818,8 @@ Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident)
     }
     if (ident == Id::typeinfo)
     {
-        if (!global.params.useDeprecated)
-            error(e->loc, ".typeinfo deprecated, use typeid(type)");
+        if (global.params.deprecation)
+            deprecation(e->loc, ".typeinfo deprecated, use typeid(type)");
         e = getTypeInfo(sc);
     }
     else if (ident == Id::stringof)
@@ -7542,8 +7542,8 @@ L1:
 
         if (ident == Id::typeinfo)
         {
-            if (!global.params.useDeprecated)
-                error(e->loc, ".typeinfo deprecated, use typeid(type)");
+            if (global.params.deprecation)
+                deprecation(e->loc, ".typeinfo deprecated, use typeid(type)");
             return getTypeInfo(sc);
         }
         if (ident == Id::outer && sym->vthis)
diff --git a/src/parse.c b/src/parse.c
index fd7a2f6..9ece86f 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -668,8 +668,8 @@ StorageClass Parser::parsePostfix()
         {
             case TOKconst:              stc |= STCconst;                break;
             case TOKinvariant:
-                if (!global.params.useDeprecated)
-                    error("use of 'invariant' rather than 'immutable' is deprecated");
+                if (global.params.deprecation)
+                    deprecation("use of 'invariant' rather than 'immutable' is deprecated");
             case TOKimmutable:          stc |= STCimmutable;            break;
             case TOKshared:             stc |= STCshared;               break;
             case TOKwild:               stc |= STCwild;                 break;
@@ -2337,8 +2337,8 @@ Type *Parser::parseBasicType()
             break;
 
         case TOKinvariant:
-            if (!global.params.useDeprecated)
-                error("use of 'invariant' rather than 'immutable' is deprecated");
+            if (global.params.deprecation)
+                deprecation("use of 'invariant' rather than 'immutable' is deprecated");
         case TOKimmutable:
             // invariant(type)
             nextToken();
@@ -2503,9 +2503,9 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters *
                  * although the D style would be:
                  *  int[]*[3] ident
                  */
-                if (!global.params.useDeprecated)
+                if (global.params.deprecation)
                 {
-                    error("C-style function pointer and pointer to array syntax is deprecated. Use 'function' to declare function pointers");
+                    deprecation("C-style function pointer and pointer to array syntax is deprecated. Use 'function' to declare function pointers");
                 }
                 nextToken();
                 ts = parseDeclarator(t, pident);
@@ -3792,8 +3792,8 @@ Statement *Parser::parseStatement(int flags)
                     arg = new Parameter(0, NULL, token.ident, NULL);
                     nextToken();
                     nextToken();
-                    if (1 || !global.params.useDeprecated)
-                        error("if (v; e) is deprecated, use if (auto v = e)");
+                    if (1 || global.params.deprecation)
+                        deprecation("if (v; e) is deprecated, use if (auto v = e)");
                 }
             }
 
@@ -4159,8 +4159,8 @@ Statement *Parser::parseStatement(int flags)
             nextToken();
             s = parseStatement(PSsemi | PScurlyscope);
 #if DMDV2
-            if (!global.params.useDeprecated)
-                error("volatile statements deprecated; used synchronized statements instead");
+            if (global.params.deprecation)
+                deprecation("volatile statements deprecated; used synchronized statements instead");
 #endif
             s = new VolatileStatement(loc, s);
             break;
diff --git a/src/statement.c b/src/statement.c
index d1218a0..dd2228a 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -116,6 +116,14 @@ void Statement::warning(const char *format, ...)
     va_end( ap );
 }
 
+void Statement::deprecation(const char *format, ...)
+{
+    va_list ap;
+    va_start(ap, format);
+    ::vdeprecation(loc, format, ap);
+    va_end( ap );
+}
+
 int Statement::hasBreak()
 {
     //printf("Statement::hasBreak()\n");
@@ -2858,8 +2866,8 @@ Statement *SwitchStatement::semantic(Scope *sc)
     if (!sc->sw->sdefault && !isFinal)
     {   hasNoDefault = 1;
 
-        if (!global.params.useDeprecated)
-           error("non-final switch statement without a default is deprecated");
+        if (global.params.deprecation)
+           deprecation("non-final switch statement without a default is deprecated");
 
         // Generate runtime error if the default is hit
         Statements *a = new Statements();
diff --git a/src/statement.h b/src/statement.h
index 7fb02bb..e338415 100644
--- a/src/statement.h
+++ b/src/statement.h
@@ -92,6 +92,7 @@ struct Statement : Object
 
     void error(const char *format, ...);
     void warning(const char *format, ...);
+    void deprecation(const char *format, ...);
     virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     int incontract;
     virtual ScopeStatement *isScopeStatement() { return NULL; }
diff --git a/src/toobj.c b/src/toobj.c
index 4c698df..cd9ae20 100644
--- a/src/toobj.c
+++ b/src/toobj.c
@@ -810,13 +810,13 @@ void ClassDeclaration::toObjFile(int multiobj)
                         continue;
                     if (fd->leastAsSpecialized(fd2) || fd2->leastAsSpecialized(fd))
                     {
-                        if (!global.params.useDeprecated)
+                        if (global.params.deprecation)
                         {
                             TypeFunction *tf = (TypeFunction *)fd->type;
                             if (tf->ty == Tfunction)
-                                error("use of %s%s hidden by %s is deprecated\n", fd->toPrettyChars(), Parameter::argsTypesToChars(tf->parameters, tf->varargs), toChars());
+                                deprecation("use of %s%s hidden by %s is deprecated\n", fd->toPrettyChars(), Parameter::argsTypesToChars(tf->parameters, tf->varargs), toChars());
                             else
-                                error("use of %s hidden by %s is deprecated\n", fd->toPrettyChars(), toChars());
+                                deprecation("use of %s hidden by %s is deprecated\n", fd->toPrettyChars(), toChars());
                         }
                         s = rtlsym[RTLSYM_DHIDDENFUNC];
                         break;
-- 
1.7.5.4

Reply via email to