+2007-04-02  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/4090
+       * ldexp.h (node_type): Add lineno.
+       * ldexp.c: Include "ldlex.h".
+       (exp_intop): Set the lineno field from lineno.
+       (exp_bigintop): Likewise.
+       (exp_relop): Likewise.
+       (exp_nameop): Likewise.
+       (exp_binop): Set the lineno field from lineno of lhs.
+       (exp_trinop): Likewise.
+       (exp_unop): Set the lineno field from lineno of child.
+       (exp_assop): Set the lineno field from lineno of src.
+       (exp_provide): Likewise.
+       (exp_assert): Set the lineno field from lineno of exp.
+       (exp_get_abs_int): Set lineno from lineno of nonconstant
+       expression when report problem.
+
 2007-03-29  Richard Sandiford  <richard@codesourcery.com>
            Daniel Jacobowitz  <dan@codesourcery.com>
 
 
 #include "ldmain.h"
 #include "ldmisc.h"
 #include "ldexp.h"
+#include "ldlex.h"
 #include <ldgram.h>
 #include "ldlang.h"
 #include "libiberty.h"
 {
   etree_type *new = stat_alloc (sizeof (new->value));
   new->type.node_code = INT;
+  new->type.lineno = lineno;
   new->value.value = value;
   new->value.str = NULL;
   new->type.node_class = etree_value;
 {
   etree_type *new = stat_alloc (sizeof (new->value));
   new->type.node_code = INT;
+  new->type.lineno = lineno;
   new->value.value = value;
   new->value.str = str;
   new->type.node_class = etree_value;
 {
   etree_type *new = stat_alloc (sizeof (new->rel));
   new->type.node_code = REL;
+  new->type.lineno = lineno;
   new->type.node_class = etree_rel;
   new->rel.section = section;
   new->rel.value = value;
   etree_type value, *new;
 
   value.type.node_code = code;
+  value.type.lineno = lhs->type.lineno;
   value.binary.lhs = lhs;
   value.binary.rhs = rhs;
   value.type.node_class = etree_binary;
   etree_type value, *new;
 
   value.type.node_code = code;
+  value.type.lineno = lhs->type.lineno;
   value.trinary.lhs = lhs;
   value.trinary.cond = cond;
   value.trinary.rhs = rhs;
   etree_type value, *new;
 
   value.unary.type.node_code = code;
+  value.unary.type.lineno = child->type.lineno;
   value.unary.child = child;
   value.unary.type.node_class = etree_unary;
   exp_fold_tree_no_dot (&value);
   etree_type value, *new;
 
   value.name.type.node_code = code;
+  value.name.type.lineno = lineno;
   value.name.name = name;
   value.name.type.node_class = etree_name;
 
 
   new = stat_alloc (sizeof (new->assign));
   new->type.node_code = code;
+  new->type.lineno = src->type.lineno;
   new->type.node_class = etree_assign;
   new->assign.src = src;
   new->assign.dst = dst;
 
   n = stat_alloc (sizeof (n->assign));
   n->assign.type.node_code = '=';
+  n->assign.type.lineno = src->type.lineno;
   n->assign.type.node_class = etree_provide;
   n->assign.src = src;
   n->assign.dst = dst;
 
   n = stat_alloc (sizeof (n->assert_s));
   n->assert_s.type.node_code = '!';
+  n->assert_s.type.lineno = exp->type.lineno;
   n->assert_s.type.node_class = etree_assert;
   n->assert_s.child = exp;
   n->assert_s.message = message;
          return expld.result.value;
        }
       else if (name != NULL && expld.phase != lang_mark_phase_enum)
-       einfo (_("%F%S nonconstant expression for %s\n"), name);
+       {
+         lineno = tree->type.lineno;
+         einfo (_("%F%S: nonconstant expression for %s\n"), name);
+       }
     }
   return def;
 }