aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/go-gcc.cc
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2016-11-22 22:28:05 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-11-22 22:28:05 +0000
commitf3878205ddc2970e384ffaed3a95362763eee9fe (patch)
tree3f3e5efdd02fec9f6bb7a55785fb00da33b93a4a /gcc/go/go-gcc.cc
parent7e98cccbd85a0bc5ec6b7edf0017d98c2e96aef5 (diff)
downloadgcc-f3878205ddc2970e384ffaed3a95362763eee9fe.zip
gcc-f3878205ddc2970e384ffaed3a95362763eee9fe.tar.gz
gcc-f3878205ddc2970e384ffaed3a95362763eee9fe.tar.bz2
compiler: relocate ID encoding utilities to gofrontend
Relocate the code that encodes/sanitizes identifiers to make them assembler-friendly, moving it from the back end to the front end; the decisions about when to encode an identifier and the calls to the encoding helpers now take place entirely in gofrontend. Reviewed-on: https://go-review.googlesource.com/33424 * go-gcc.cc (char_needs_encoding): Remove. (needs_encoding, fetch_utf8_char, encode_id): Remove. (Gcc_backend::global_variable): Add asm_name parameter. Don't compute asm_name here. (Gcc_backend::implicit_variable): Likewise. (Gcc_backend::implicit_variable_reference): Likewise. (Gcc_backend::immutable_struct): Likewise. (Gcc_backend::immutable_struct_reference): Likewise. * Make-lang.in (GO_OBJS): Add go/go-encode-id.o. From-SVN: r242726
Diffstat (limited to 'gcc/go/go-gcc.cc')
-rw-r--r--gcc/go/go-gcc.cc171
1 files changed, 36 insertions, 135 deletions
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 619499e..dc00413 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -412,9 +412,8 @@ class Gcc_backend : public Backend
{ return new Bvariable(error_mark_node); }
Bvariable*
- global_variable(const std::string& package_name,
- const std::string& pkgpath,
- const std::string& name,
+ global_variable(const std::string& var_name,
+ const std::string& asm_name,
Btype* btype,
bool is_external,
bool is_hidden,
@@ -440,25 +439,27 @@ class Gcc_backend : public Backend
Location, Bstatement**);
Bvariable*
- implicit_variable(const std::string&, Btype*, bool, bool, bool,
- int64_t);
+ implicit_variable(const std::string&, const std::string&, Btype*,
+ bool, bool, bool, int64_t);
void
implicit_variable_set_init(Bvariable*, const std::string&, Btype*,
bool, bool, bool, Bexpression*);
Bvariable*
- implicit_variable_reference(const std::string&, Btype*);
+ implicit_variable_reference(const std::string&, const std::string&, Btype*);
Bvariable*
- immutable_struct(const std::string&, bool, bool, Btype*, Location);
+ immutable_struct(const std::string&, const std::string&,
+ bool, bool, Btype*, Location);
void
immutable_struct_set_init(Bvariable*, const std::string&, bool, bool, Btype*,
Location, Bexpression*);
Bvariable*
- immutable_struct_reference(const std::string&, Btype*, Location);
+ immutable_struct_reference(const std::string&, const std::string&,
+ Btype*, Location);
// Labels.
@@ -550,102 +551,6 @@ get_identifier_from_string(const std::string& str)
return get_identifier_with_length(str.data(), str.length());
}
-// Return whether the character c is OK to use in the assembler.
-
-static bool
-char_needs_encoding(char c)
-{
- switch (c)
- {
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
- case 's': case 't': case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case '_': case '.': case '$': case '/':
- return false;
- default:
- return true;
- }
-}
-
-// Return whether the identifier needs to be translated because it
-// contains non-ASCII characters.
-
-static bool
-needs_encoding(const std::string& str)
-{
- for (std::string::const_iterator p = str.begin();
- p != str.end();
- ++p)
- if (char_needs_encoding(*p))
- return true;
- return false;
-}
-
-// Pull the next UTF-8 character out of P and store it in *PC. Return
-// the number of bytes read.
-
-static size_t
-fetch_utf8_char(const char* p, unsigned int* pc)
-{
- unsigned char c = *p;
- if ((c & 0x80) == 0)
- {
- *pc = c;
- return 1;
- }
- size_t len = 0;
- while ((c & 0x80) != 0)
- {
- ++len;
- c <<= 1;
- }
- unsigned int rc = *p & ((1 << (7 - len)) - 1);
- for (size_t i = 1; i < len; i++)
- {
- unsigned int u = p[i];
- rc <<= 6;
- rc |= u & 0x3f;
- }
- *pc = rc;
- return len;
-}
-
-// Encode an identifier using ASCII characters.
-
-static std::string
-encode_id(const std::string id)
-{
- std::string ret;
- const char* p = id.c_str();
- const char* pend = p + id.length();
- while (p < pend)
- {
- unsigned int c;
- size_t len = fetch_utf8_char(p, &c);
- if (len == 1 && !char_needs_encoding(c))
- ret += c;
- else
- {
- ret += "$U";
- char buf[30];
- snprintf(buf, sizeof buf, "%x", c);
- ret += buf;
- ret += "$";
- }
- p += len;
- }
- return ret;
-}
-
// Define the built-in functions that are exposed to GCCGo.
Gcc_backend::Gcc_backend()
@@ -2580,9 +2485,8 @@ Gcc_backend::non_zero_size_type(tree type)
// Make a global variable.
Bvariable*
-Gcc_backend::global_variable(const std::string& package_name,
- const std::string& pkgpath,
- const std::string& name,
+Gcc_backend::global_variable(const std::string& var_name,
+ const std::string& asm_name,
Btype* btype,
bool is_external,
bool is_hidden,
@@ -2598,9 +2502,6 @@ Gcc_backend::global_variable(const std::string& package_name,
if ((is_external || !is_hidden) && int_size_in_bytes(type_tree) == 0)
type_tree = this->non_zero_size_type(type_tree);
- std::string var_name(package_name);
- var_name.push_back('.');
- var_name.append(name);
tree decl = build_decl(location.gcc_location(), VAR_DECL,
get_identifier_from_string(var_name),
type_tree);
@@ -2611,17 +2512,12 @@ Gcc_backend::global_variable(const std::string& package_name,
if (!is_hidden)
{
TREE_PUBLIC(decl) = 1;
-
- std::string asm_name(pkgpath);
- asm_name.push_back('.');
- asm_name.append(name);
- if (needs_encoding(asm_name))
- asm_name = encode_id(asm_name);
SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
}
- else if (needs_encoding(var_name))
- SET_DECL_ASSEMBLER_NAME(decl,
- get_identifier_from_string(encode_id(var_name)));
+ else
+ {
+ SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
+ }
TREE_USED(decl) = 1;
@@ -2814,8 +2710,9 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
// generating GC root variables and storing the values of a slice initializer.
Bvariable*
-Gcc_backend::implicit_variable(const std::string& name, Btype* type,
- bool is_hidden, bool is_constant,
+Gcc_backend::implicit_variable(const std::string& name,
+ const std::string& asm_name,
+ Btype* type, bool is_hidden, bool is_constant,
bool is_common, int64_t alignment)
{
tree type_tree = type->get_tree();
@@ -2857,8 +2754,8 @@ Gcc_backend::implicit_variable(const std::string& name, Btype* type,
SET_DECL_ALIGN(decl, alignment * BITS_PER_UNIT);
DECL_USER_ALIGN(decl) = 1;
}
- if (needs_encoding(name))
- SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(encode_id(name)));
+ if (! asm_name.empty())
+ SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
go_preserve_from_gc(decl);
return new Bvariable(decl);
@@ -2899,7 +2796,9 @@ Gcc_backend::implicit_variable_set_init(Bvariable* var, const std::string&,
// Return a reference to an implicit variable defined in another package.
Bvariable*
-Gcc_backend::implicit_variable_reference(const std::string& name, Btype* btype)
+Gcc_backend::implicit_variable_reference(const std::string& name,
+ const std::string& asm_name,
+ Btype* btype)
{
tree type_tree = btype->get_tree();
if (type_tree == error_mark_node)
@@ -2911,8 +2810,8 @@ Gcc_backend::implicit_variable_reference(const std::string& name, Btype* btype)
TREE_PUBLIC(decl) = 1;
TREE_STATIC(decl) = 1;
DECL_ARTIFICIAL(decl) = 1;
- if (needs_encoding(name))
- SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(encode_id(name)));
+ if (! asm_name.empty())
+ SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
go_preserve_from_gc(decl);
return new Bvariable(decl);
}
@@ -2920,7 +2819,9 @@ Gcc_backend::implicit_variable_reference(const std::string& name, Btype* btype)
// Create a named immutable initialized data structure.
Bvariable*
-Gcc_backend::immutable_struct(const std::string& name, bool is_hidden,
+Gcc_backend::immutable_struct(const std::string& name,
+ const std::string& asm_name,
+ bool is_hidden,
bool is_common, Btype* btype, Location location)
{
tree type_tree = btype->get_tree();
@@ -2937,8 +2838,8 @@ Gcc_backend::immutable_struct(const std::string& name, bool is_hidden,
DECL_ARTIFICIAL(decl) = 1;
if (!is_hidden)
TREE_PUBLIC(decl) = 1;
- if (needs_encoding(name))
- SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(encode_id(name)));
+ if (! asm_name.empty())
+ SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
// When the initializer for one immutable_struct refers to another,
// it needs to know the visibility of the referenced struct so that
@@ -2998,7 +2899,9 @@ Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
// defined in another package.
Bvariable*
-Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
+Gcc_backend::immutable_struct_reference(const std::string& name,
+ const std::string& asm_name,
+ Btype* btype,
Location location)
{
tree type_tree = btype->get_tree();
@@ -3013,8 +2916,8 @@ Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
DECL_ARTIFICIAL(decl) = 1;
TREE_PUBLIC(decl) = 1;
DECL_EXTERNAL(decl) = 1;
- if (needs_encoding(name))
- SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(encode_id(name)));
+ if (! asm_name.empty())
+ SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
go_preserve_from_gc(decl);
return new Bvariable(decl);
}
@@ -3104,10 +3007,8 @@ Gcc_backend::function(Btype* fntype, const std::string& name,
return this->error_function();
tree decl = build_decl(location.gcc_location(), FUNCTION_DECL, id, functype);
- if (!asm_name.empty())
+ if (! asm_name.empty())
SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
- else if (needs_encoding(name))
- SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(encode_id(name)));
if (is_visible)
TREE_PUBLIC(decl) = 1;
if (is_declaration)