Leandro Lucarella, el 13 de julio a las 01:16 me escribiste:
> Michel Fortin, el 12 de julio a las 21:40 me escribiste:
> > Le 2011-07-12 à 19:32, Leandro Lucarella a écrit :
> > 
> > > Hi, I just wanted to hand you a patch I did to add a new option to show
> > > deprecation messages as warnings (-di), following the discussion in the
> > > announcement group. I know I should probably get an account in github
> > > and do those pull requests everybody talks about, but it's too much
> > > trouble for an occasional collaboration, I hope you are willing to take
> > > a look at the patches and apply them if you like them (and if not, any
> > > feedback would be appreciated). I didn't do a lot of testing either,
> > > because is not trivial at all to set up a testing environment for the
> > > compiler, so testing would be appreciated too (I know is easy to run the
> > > test suite once you have a proper development environment set up). See
> > > the patch descriptions for more details.
> > > 
> > > I hope you find the patches useful.
> > 
> > Turned them into pull requests.
> > 
> > <https://github.com/D-Programming-Language/dmd/pull/244>
> > <https://github.com/D-Programming-Language/dmd/pull/245>
> > 
> > But then I had to close the pull request about deprecation warnings.
> > 
> > Not only it fails the test suite (I should have checked sooner), but for 
> > some strange reasons it generates errors while compiling druntime, and 
> > those errors aren't fatal as they should and thus don't prevent the build 
> > from being successful. They're also pretty strange considering the nature 
> > of the changes:
> > 
> > src/core/thread.d(3723): Error: undefined identifier ucontext_t
> > src/core/thread.d(2845): Error: undefined identifier GetSystemInfo
> > src/core/thread.d(2854): Error: undefined identifier _SC_PAGESIZE
> > src/core/thread.d(2895): Error: undefined identifier ucontext_t
> > src/core/thread.d(3199): Error: undefined identifier ucontext_t
> > src/core/thread.d(3206): Error: undefined identifier ucontext_t
> > src/core/thread.d(3302): Error: undefined identifier ucontext_t
> > src/core/thread.d(3332): Error: undefined identifier ucontext_t
> > src/core/thread.d(3370): Error: undefined identifier ucontext_t
> > src/core/thread.d(3464): Error: undefined identifier VirtualAlloc
> > src/core/thread.d(3574): Error: undefined identifier VirtualAlloc
> 
> OK, all that errors have an static if (__tratits(compiles, symbol))
> 
> I'll try to figure out what's making the mess with __traits(compiles)...

OK, I download and compiled druntime with all -d, -di and none and
couldn't reproduce this problem. I got another errors though:

src/core/runtime.d(310): Error: function core.runtime.backtrace (void**, uint) 
is not callable using argument types (void*[128u],int)
src/core/runtime.d(310): Error: cannot implicitly convert expression 
(callstack) of type void*[128u] to void**
src/core/runtime.d(311): Error: function core.runtime.backtrace_symbols_fd 
(void**, int, int) is not callable
using argument types (void*[128u],int,int)
src/core/runtime.d(311): Error: cannot implicitly convert expression 
(callstack) of type void*[128u] to void**

I fixed them by changing just one line in the patch:

--- 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.deprecation)
+#define IMPLICIT_ARRAY_TO_PTR   (global.params.deprecation != 1)
 
 /* These have default values for 32 bit code, they get
  * adjusted for 64 bit code.

The problem is, this type of deprecation can't show a warning, I guess,
because it just add or removes functions as possible candidates, I tried
to make it show a sensible warning but couldn't find a way without
getting a lot of spurious warnings, maybe someone who knows better can
fix this though. Worst case, we have to decide if -di should die with an
error of an unmatched function or if it should pass silently (what I did
in this new patch).

Also I fixed another small bug that could prevent some warnings to be
shown:

--- a/src/mars.c
+++ b/src/mars.c
@@ -159,10 +159,7 @@ 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);
+    vdeprecation(loc, format, ap);
     va_end( ap );
 }
 
Attached is the updated patch. If you can try it, it would be appreciated, and
if it's still failing, I would appreciate if you can give me detailed steps to
reproduce it.

Thanks!

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Every day 21 new born babies will be given to the wrong parents
>From 0738bd5d4b7cad0653c92e7b94310703652f3044 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          |   27 +++++++++++-
 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, 229 insertions(+), 130 deletions(-)

diff --git a/docs/man/man1/dmd.1 b/docs/man/man1/dmd.1
index b2d59b0..110ad07 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..5f88c85 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 (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..7506a43 100644
--- a/src/mars.c
+++ b/src/mars.c
@@ -155,6 +155,14 @@ void warning(Loc loc, const char *format, ...)
     va_end( ap );
 }
 
+void deprecation(Loc loc, const char *format, ...)
+{
+    va_list ap;
+    va_start(ap, format);
+    vdeprecation(loc, format, ap);
+    va_end( ap );
+}
+
 void verror(Loc loc, const char *format, va_list ap)
 {
     if (!global.gag)
@@ -208,6 +216,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 informational 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 +281,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 +381,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 +466,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..94f918b 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 != 1)
 
 /* 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

_______________________________________________
dmd-internals mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/dmd-internals

Reply via email to