diff options
Diffstat (limited to 'gcc/c-lex.c')
-rw-r--r-- | gcc/c-lex.c | 189 |
1 files changed, 184 insertions, 5 deletions
diff --git a/gcc/c-lex.c b/gcc/c-lex.c index f5425ce49e9..b2727f62d15 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -40,6 +40,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "tm_p.h" #include "splay-tree.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 +66,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 +202,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); @@ -337,12 +352,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; + 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 +483,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 ()) { @@ -394,6 +508,10 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags) case CPP_STRING: case CPP_WSTRING: + /* APPLE LOCAL begin CW asm blocks */ + if (flag_cw_asm_blocks_local) + --c_lex_depth; + /* APPLE LOCAL end CW asm blocks */ type = lex_string (tok, value, true); break; @@ -401,19 +519,53 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags) *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node)); if (objc_is_reserved_word (*value)) { + /* APPLE LOCAL begin CW asm blocks */ + if (flag_cw_asm_blocks_local) + --c_lex_depth; + /* APPLE LOCAL end CW asm blocks */ type = CPP_AT_NAME; break; } /* 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: @@ -449,6 +601,10 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags) case CPP_WSTRING: if (!c_lex_return_raw_strings) { + /* APPLE LOCAL begin CW asm blocks */ + if (flag_cw_asm_blocks_local) + --c_lex_depth; + /* APPLE LOCAL end CW asm blocks */ type = lex_string (tok, value, false); break; } @@ -473,6 +629,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 +874,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 +886,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 +930,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 +950,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 +983,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) |