aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-lex.c')
-rw-r--r--gcc/c-lex.c209
1 files changed, 200 insertions, 9 deletions
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index f5425ce49e9..d2ced37a639 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -39,7 +39,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "intl.h"
#include "tm_p.h"
#include "splay-tree.h"
+/* APPLE LOCAL 4133801 */
+#include "langhooks.h"
#include "debug.h"
+/* APPLE LOCAL AltiVec */
+#include "../libcpp/internal.h"
/* We may keep statistics about how long which files took to compile. */
static int header_time, body_time;
@@ -64,6 +68,18 @@ int c_lex_string_translate = 1;
unmolested (no concatenation, no translation). */
bool c_lex_return_raw_strings = false;
+/* APPLE LOCAL begin CW asm blocks */
+/* This points to the token that we're going to save briefly while
+ returning EOL/BOL tokens. (This is global but static instead
+ static in c_lex() so as to avoid pointless init in non-asm
+ case.) */
+static const cpp_token *cw_asm_saved_token = NULL;
+/* This tracks recursion in c_lex calls. Lexer recursion can happen
+ in pragma processing for instance, but we don't any of the asm
+ special handling to be active then. */
+static int c_lex_depth;
+/* APPLE LOCAL end CW asm blocks */
+
static tree interpret_integer (const cpp_token *, unsigned int);
static tree interpret_float (const cpp_token *, unsigned int);
static enum integer_type_kind narrowest_unsigned_type
@@ -188,7 +204,8 @@ cb_ident (cpp_reader * ARG_UNUSED (pfile),
{
/* Convert escapes in the string. */
cpp_string cstr = { 0, 0 };
- if (cpp_interpret_string (pfile, str, 1, &cstr, false))
+ /* APPLE LOCAL pascal strings */
+ if (cpp_interpret_string (pfile, str, 1, &cstr, false, false))
{
ASM_OUTPUT_IDENT (asm_out_file, (const char *) cstr.text);
free ((void *) cstr.text);
@@ -238,7 +255,8 @@ fe_file_change (const struct line_map *new_map)
input_line = included_at;
push_srcloc (new_map->to_file, 1);
#endif
- (*debug_hooks->start_source_file) (included_at, new_map->to_file);
+ /* APPLE LOCAL 4133801 */
+ lang_hooks.start_source_file (included_at, new_map->to_file);
#ifndef NO_IMPLICIT_EXTERN_C
if (c_header_level)
++c_header_level;
@@ -261,8 +279,8 @@ fe_file_change (const struct line_map *new_map)
}
#endif
pop_srcloc ();
-
- (*debug_hooks->end_source_file) (new_map->to_line);
+ /* APPLE LOCAL 4133801 */
+ lang_hooks.end_source_file (new_map->to_line, new_map->to_file);
}
update_header_times (new_map->to_file);
@@ -337,12 +355,101 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
static bool no_more_pch;
const cpp_token *tok;
enum cpp_ttype type;
+ /* APPLE LOCAL CW asm blocks C++ */
+ const cpp_token *lasttok;
+ /* APPLE LOCAL begin CW asm blocks */
+ /* Make a local copy of the flag for efficiency, since the compiler can't
+ figure that it won't change during a compilation. */
+ int flag_cw_asm_blocks_local = flag_cw_asm_blocks;
+ if (flag_cw_asm_blocks_local)
+ ++c_lex_depth;
+ /* APPLE LOCAL end CW asm blocks */
timevar_push (TV_CPP);
retry:
+ /* APPLE LOCAL begin CW asm blocks */
+ if (cw_asm_at_bol)
+ {
+ cw_asm_at_bol = 0;
+ --c_lex_depth;
+ timevar_pop (TV_CPP);
+ return CPP_BOL;
+ }
+ /* If there's a token we saved while returning the special BOL
+ token, return it now. */
+ if (cw_asm_saved_token)
+ {
+ tok = cw_asm_saved_token;
+ type = tok->type;
+ cw_asm_saved_token = NULL;
+ goto bypass;
+ }
+ /* APPLE LOCAL end CW asm blocks */
tok = cpp_get_token (parse_in);
type = tok->type;
+ /* APPLE LOCAL begin CW asm blocks */
+ /* This test should be as efficient as possible, because it affects
+ all lexing with or without CW asm enabled. */
+ if (flag_cw_asm_blocks_local && cw_asm_state != cw_asm_none && c_lex_depth == 1
+ && type != CPP_PADDING)
+ {
+ /* "}" switches us out of our special mode. */
+ if (tok->type == CPP_CLOSE_BRACE && cw_asm_state >= cw_asm_decls)
+ {
+ cw_asm_state = cw_asm_none;
+ cw_asm_saved_token = tok;
+ cw_asm_at_bol = 0;
+ --c_lex_depth;
+ timevar_pop (TV_CPP);
+ return CPP_EOL;
+ }
+
+ /* This is tricky. We're only ready to start parsing assembly
+ instructions if we're in the asm block, we're not in the
+ middle of parsing a C decl, and the next token is plausibly
+ the beginning of an asm line. This works because if we have
+ a "typedef int nop", a nop at the beginning of a line should
+ be taken as an instruction rather than a declaration of type
+ nop. (Doesn't have to go this way, but it's how CW works.)
+ We're not quite as good as CW yet, because CW knows about the
+ complete list of valid opcodes, and will try to take anything
+ as a decl that is not in the opcode list. */
+ if (cw_asm_state == cw_asm_decls
+ && !cw_asm_in_decl)
+ {
+ if ((tok->flags & BOL)
+ && (tok->type == CPP_ATSIGN
+ || tok->type == CPP_DOT
+ || (tok->type == CPP_NAME
+ && (*value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node)))
+ && !cw_asm_typename_or_reserved (*value))))
+ {
+ cw_asm_state = cw_asm_asm;
+ inside_cw_asm_block = 1;
+ cw_asm_at_bol = 1;
+ clear_cw_asm_labels ();
+ }
+ else
+ {
+ cw_asm_in_decl = 1;
+ }
+ }
+ /* If we're in the asm block, save the token at the beginning of the
+ line and return a beginning-of-line token instead. */
+ if (cw_asm_state == cw_asm_asm && (tok->flags & BOL))
+ {
+ cw_asm_saved_token = tok;
+ cw_asm_at_bol = !cw_asm_at_bol;
+ --c_lex_depth;
+ /* In between lines, return first the EOL. */
+ timevar_pop (TV_CPP);
+ return (cw_asm_at_bol ? CPP_EOL : CPP_BOL);
+ }
+ }
+ bypass:
+ /* APPLE LOCAL end CW asm blocks */
+
retry_after_at:
switch (type)
{
@@ -379,6 +486,16 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
break;
case CPP_ATSIGN:
+ /* APPLE LOCAL begin CW asm blocks */
+ if (cw_asm_state >= cw_asm_decls)
+ {
+ /* Return the @-sign verbatim. */
+ *value = NULL_TREE;
+ break;
+ }
+ lasttok = tok;
+ /* APPLE LOCAL end CW asm blocks */
+
/* An @ may give the next token special significance in Objective-C. */
if (c_dialect_objc ())
{
@@ -407,20 +524,51 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
/* FALLTHROUGH */
default:
+ /* APPLE LOCAL begin CW asm blocks C++ */
+ if (flag_cw_asm_blocks_local)
+ {
+ /* This is necessary for C++, as we don't have the tight
+ integration between the lexer and the parser... */
+ cw_asm_saved_token = tok;
+ /* Return the @-sign verbatim. */
+ *value = NULL;
+ tok = lasttok;
+ type = tok->type;
+ break;
+ }
+ /* APPLE LOCAL end CW asm blocks C++ */
+
/* ... or not. */
error ("%Hstray %<@%> in program", &atloc);
goto retry_after_at;
}
break;
}
-
+ /* APPLE LOCAL begin CW asm blocks C++ */
+ if (flag_cw_asm_blocks_local)
+ {
+ do
+ tok = cpp_get_token (parse_in);
+ while (tok->type == CPP_PADDING);
+ /* This is necessary for C++, as we don't have the tight
+ integration between the lexer and the parser... */
+ cw_asm_saved_token = tok;
+ /* Return the @-sign verbatim. */
+ *value = NULL;
+ tok = lasttok;
+ type = tok->type;
+ break;
+ }
+ /* APPLE LOCAL end CW asm blocks C++ */
+
/* FALLTHROUGH */
case CPP_HASH:
case CPP_PASTE:
{
unsigned char name[4];
- *cpp_spell_token (parse_in, tok, name) = 0;
+ /* APPLE LOCAL mainline UCNs 2005-04-17 3892809 */
+ *cpp_spell_token (parse_in, tok, name, false) = 0;
error ("stray %qs in program", name);
}
@@ -459,6 +607,26 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
*value = build_string (tok->val.str.len, (char *) tok->val.str.text);
break;
+ /* APPLE LOCAL begin CW asm blocks */
+ case CPP_MULT:
+ if (inside_cw_asm_block)
+ {
+ /* Check and replace use of '*' with '.' if '*' is followed by '-'
+ or '+'. This is to allow "b *+8" which is disallwed by darwin's
+ assembler but nevertheless is needed to be compatible with CW tools. */
+ lasttok = tok;
+ do
+ tok = cpp_get_token (parse_in);
+ while (tok->type == CPP_PADDING);
+ cw_asm_saved_token = tok;
+ if (tok->type == CPP_PLUS || tok->type == CPP_MINUS)
+ type = CPP_DOT;
+ tok = lasttok;
+ }
+ *value = NULL_TREE;
+ break;
+ /* APPLE LOCAL end CW asm blocks */
+
/* These tokens should not be visible outside cpplib. */
case CPP_HEADER_NAME:
case CPP_COMMENT:
@@ -473,6 +641,11 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
if (cpp_flags)
*cpp_flags = tok->flags;
+ /* APPLE LOCAL begin CW asm blocks */
+ if (flag_cw_asm_blocks_local)
+ --c_lex_depth;
+ /* APPLE LOCAL end CW asm blocks */
+
if (!no_more_pch)
{
no_more_pch = true;
@@ -713,6 +886,8 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
tree value;
bool wide = false;
size_t concats = 0;
+ /* APPLE LOCAL pascal strings */
+ bool pascal_p = false;
struct obstack str_ob;
cpp_string istr;
@@ -723,6 +898,11 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
if (tok->type == CPP_WSTRING)
wide = true;
+ /* APPLE LOCAL begin pascal strings */
+ else if (CPP_OPTION (parse_in, pascal_strings)
+ && str.text[1] == '\\' && str.text[2] == 'p')
+ pascal_p = true;
+ /* APPLE LOCAL end pascal strings */
retry:
tok = cpp_get_token (parse_in);
@@ -762,12 +942,18 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
if (concats)
strs = (cpp_string *) obstack_finish (&str_ob);
+ /* APPLE LOCAL begin pascal strings */
+ if (wide || objc_string)
+ pascal_p = false;
+ /* APPLE LOCAL end pascal strings */
+
if (concats && !objc_string && warn_traditional && !in_system_header)
warning ("traditional C rejects string constant concatenation");
if ((c_lex_string_translate
? cpp_interpret_string : cpp_interpret_string_notranslate)
- (parse_in, strs, concats + 1, &istr, wide))
+ /* APPLE LOCAL pascal strings */
+ (parse_in, strs, concats + 1, &istr, wide, pascal_p))
{
value = build_string (istr.len, (char *) istr.text);
free ((void *) istr.text);
@@ -776,7 +962,8 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
{
int xlated = cpp_interpret_string_notranslate (parse_in, strs,
concats + 1,
- &istr, wide);
+ /* APPLE LOCAL pascal strings */
+ &istr, wide, false);
/* Assume that, if we managed to translate the string above,
then the untranslated parsing will always succeed. */
gcc_assert (xlated);
@@ -808,7 +995,11 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
value = build_string (1, "");
}
- TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node;
+ /* APPLE LOCAL begin pascal strings */
+ TREE_TYPE (value) = wide ? wchar_array_type_node
+ : pascal_p ? pascal_string_type_node
+ : char_array_type_node;
+ /* APPLE LOCAL end pascal strings */
*valp = fix_string_type (value);
if (concats)