aboutsummaryrefslogtreecommitdiff
path: root/gas/expr.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-08-21 16:42:14 +0100
committerNick Clifton <nickc@redhat.com>2015-08-21 16:42:14 +0100
commitd02603dc201f80cd9d2a1f4b1a16110b1e04222b (patch)
treeb55476923d8bde556b6b3421345bde8e4562ad97 /gas/expr.c
parent40045d91812b25c88c8275b8c08d27c234b68ba8 (diff)
downloadgdb-d02603dc201f80cd9d2a1f4b1a16110b1e04222b.zip
gdb-d02603dc201f80cd9d2a1f4b1a16110b1e04222b.tar.gz
gdb-d02603dc201f80cd9d2a1f4b1a16110b1e04222b.tar.bz2
Allow symbol and label names to be enclosed in double quotes.
gas PR gas/18581 * expr.c (get_symbol_end): Rename to get_symbol_name. Add a return parameter pointing to the start of the symbol. Allow symbol names enclosed in double quotes. (restore_line_pointer): New function. Replace the NUL character inserted into the input stream with the given character. If the character was a double quote, advance the input pointer. * expr.h (get_symbol_end): Delete. (get_symbol_name): Add prototype. (restore_line_pointer): Prototype. * read.h (SKIP_WHITESPACE_AFTER_NAME): New macro. * doc/as.texinfo (Symbol Intro): Document that symbol names can now be enclosed in double quotes. * cond.c (s_ifdef): Replace get_symbol_end with get_symbol_name. Use restore_line_pointer to replace the NUL in the input stream. Use SKIP_WHITESPACE_AFTER_NAME to skip past the end of a symbol. Check for the use of double quoted symbol names. * expr.c: Likewise. * config/obj-aout.c: Likewise. * config/obj-coff-seh.c: Likewise. * config/obj-coff.c: Likewise. * config/obj-elf.c: Likewise. * config/obj-evax.c: Likewise. * config/obj-macho.c: Likewise. * config/obj-som.c: Likewise. * config/tc-alpha.c: Likewise. * config/tc-arc.c: Likewise. * config/tc-arm.c: Likewise. * config/tc-dlx.c: Likewise. * config/tc-h8300.c: Likewise. * config/tc-hppa.c: Likewise. * config/tc-i370.c: Likewise. * config/tc-i386-intel.c: Likewise. * config/tc-i386.c: Likewise. * config/tc-i960.c: Likewise. * config/tc-ia64.c: Likewise. * config/tc-iq2000.c: Likewise. * config/tc-m32r.c: Likewise. * config/tc-m68hc11.c: Likewise. * config/tc-m68k.c: Likewise. * config/tc-microblaze.c: Likewise. * config/tc-mips.c: Likewise. * config/tc-mmix.c: Likewise. * config/tc-mn10200.c: Likewise. * config/tc-mn10300.c: Likewise. * config/tc-nios2.c: Likewise. * config/tc-ppc.c: Likewise. * config/tc-s390.c: Likewise. * config/tc-score.c: Likewise. * config/tc-score7.c: Likewise. * config/tc-sparc.c: Likewise. * config/tc-tic4x.c: Likewise. * config/tc-tic54x.c: Likewise. * config/tc-tic6x.c: Likewise. * config/tc-tilegx.c: Likewise. * config/tc-tilepro.c: Likewise. * config/tc-v850.c: Likewise. * config/tc-xtensa.c: Likewise. * config/tc-z80.c: Likewise. * dw2gencfi.c: Likewise. * dwarf2dbgc.: Likewise. * ecoff.c: Likewise. * read.c: Likewise. * stabs.c: Likewise. tests PR gas/18581 * gas/all/byte.d: Disable this test. Quoted expressions are now allowed in .byte directives. * gas/all/quoted-sym-names.s: New test. * gas/all/quoted-sym-names.d: Expected output. * gas/all/gas.exp: Run the new test.
Diffstat (limited to 'gas/expr.c')
-rw-r--r--gas/expr.c78
1 files changed, 54 insertions, 24 deletions
diff --git a/gas/expr.c b/gas/expr.c
index f8acd41..a523b11 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -1142,8 +1142,7 @@ operand (expressionS *expressionP, enum expr_mode mode)
++input_line_pointer;
SKIP_WHITESPACE ();
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (& name);
buf = (char *) xmalloc (strlen (name) + 10);
if (start)
@@ -1158,7 +1157,7 @@ operand (expressionS *expressionP, enum expr_mode mode)
expressionP->X_add_number = 0;
*input_line_pointer = c;
- SKIP_WHITESPACE ();
+ SKIP_WHITESPACE_AFTER_NAME ();
if (*input_line_pointer != ')')
as_bad (_("syntax error in .startof. or .sizeof."));
else
@@ -1214,13 +1213,13 @@ operand (expressionS *expressionP, enum expr_mode mode)
#if defined(md_need_index_operator) || defined(TC_M68K)
de_fault:
#endif
- if (is_name_beginner (c)) /* Here if did not begin with a digit. */
+ if (is_name_beginner (c) || c == '"') /* Here if did not begin with a digit. */
{
/* Identifier begins here.
This is kludged for speed, so code is repeated. */
isname:
- name = --input_line_pointer;
- c = get_symbol_end ();
+ -- input_line_pointer;
+ c = get_symbol_name (&name);
#ifdef md_operator
{
@@ -1229,15 +1228,15 @@ operand (expressionS *expressionP, enum expr_mode mode)
switch (op)
{
case O_uminus:
- *input_line_pointer = c;
+ restore_line_pointer (c);
c = '-';
goto unary;
case O_bit_not:
- *input_line_pointer = c;
+ restore_line_pointer (c);
c = '~';
goto unary;
case O_logical_not:
- *input_line_pointer = c;
+ restore_line_pointer (c);
c = '!';
goto unary;
case O_illegal:
@@ -1246,9 +1245,10 @@ operand (expressionS *expressionP, enum expr_mode mode)
default:
break;
}
+
if (op != O_absent && op != O_illegal)
{
- *input_line_pointer = c;
+ restore_line_pointer (c);
expr (9, expressionP, mode);
expressionP->X_add_symbol = make_expr_symbol (expressionP);
expressionP->X_op_symbol = NULL;
@@ -1266,7 +1266,7 @@ operand (expressionS *expressionP, enum expr_mode mode)
entering it in the symbol table. */
if (md_parse_name (name, expressionP, mode, &c))
{
- *input_line_pointer = c;
+ restore_line_pointer (c);
break;
}
#endif
@@ -1286,10 +1286,9 @@ operand (expressionS *expressionP, enum expr_mode mode)
|| name[1] == 'T');
*input_line_pointer = c;
- SKIP_WHITESPACE ();
+ SKIP_WHITESPACE_AFTER_NAME ();
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (& name);
buf = (char *) xmalloc (strlen (name) + 10);
if (start)
@@ -1304,8 +1303,7 @@ operand (expressionS *expressionP, enum expr_mode mode)
expressionP->X_add_number = 0;
*input_line_pointer = c;
- SKIP_WHITESPACE ();
-
+ SKIP_WHITESPACE_AFTER_NAME ();
break;
}
#endif
@@ -1333,7 +1331,8 @@ operand (expressionS *expressionP, enum expr_mode mode)
expressionP->X_add_symbol = symbolP;
expressionP->X_add_number = 0;
}
- *input_line_pointer = c;
+
+ restore_line_pointer (c);
}
else
{
@@ -1589,8 +1588,8 @@ operatorf (int *num_chars)
#ifdef md_operator
if (is_name_beginner (c))
{
- char *name = input_line_pointer;
- char ec = get_symbol_end ();
+ char *name;
+ char ec = get_symbol_name (& name);
ret = md_operator (name, 2, &ec);
switch (ret)
@@ -2318,19 +2317,22 @@ resolve_expression (expressionS *expressionP)
expr.c is just a branch office read.c anyway, and putting it
here lessens the crowd at read.c.
- Assume input_line_pointer is at start of symbol name.
+ Assume input_line_pointer is at start of symbol name, or the
+ start of a double quote enclosed symbol name.
Advance input_line_pointer past symbol name.
- Turn that character into a '\0', returning its former value.
+ Turn that character into a '\0', returning its former value,
+ which may be the closing double quote.
This allows a string compare (RMS wants symbol names to be strings)
- of the symbol name.
+ of the symbol name.
There will always be a char following symbol name, because all good
lines end in end-of-line. */
char
-get_symbol_end (void)
+get_symbol_name (char ** ilp_return)
{
char c;
+ * ilp_return = input_line_pointer;
/* We accept \001 in a name in case this is being called with a
constructed string. */
if (is_name_beginner (c = *input_line_pointer++) || c == '\001')
@@ -2341,8 +2343,36 @@ get_symbol_end (void)
if (is_name_ender (c))
c = *input_line_pointer++;
}
+ else if (c == '"')
+ {
+ bfd_boolean backslash_seen;
+
+ * ilp_return = input_line_pointer;
+ do
+ {
+ backslash_seen = c == '\\';
+ c = * input_line_pointer ++;
+ }
+ while (c != 0 && (c != '"' || backslash_seen));
+
+ if (c == 0)
+ as_warn (_("missing closing '\"'"));
+ }
*--input_line_pointer = 0;
- return (c);
+ return c;
+}
+
+/* Replace the NUL character pointed to by input_line_pointer
+ with C. If C is \" then advance past it. Return the character
+ now pointed to by input_line_pointer. */
+
+char
+restore_line_pointer (char c)
+{
+ * input_line_pointer = c;
+ if (c == '"')
+ c = * ++ input_line_pointer;
+ return c;
}
unsigned int