diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-21 22:23:23 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-21 22:23:23 +0000 |
commit | a1fe65730fa6c21d9597f45a651d25f232655e8f (patch) | |
tree | cf96cd27ec81f37394a138f6e77fc0e662004482 /gcc | |
parent | 5c197b30ff9cf6d1cdca4d96084f2385be44ccf3 (diff) | |
download | gcc-a1fe65730fa6c21d9597f45a651d25f232655e8f.tar.gz |
compiler: Error if name defined in both package and file blocks.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194685 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 37 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 13 |
2 files changed, 46 insertions, 4 deletions
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 41f9665e724..735b4c81204 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -29,6 +29,7 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int, int pointer_size) package_(NULL), functions_(), globals_(new Bindings(NULL)), + file_block_names_(), imports_(), imported_unsafe_(false), packages_(), @@ -1243,6 +1244,33 @@ Gogo::define_global_names() else if (no->is_unknown()) no->unknown_value()->set_real_named_object(global_no); } + + // Give an error if any name is defined in both the package block + // and the file block. For example, this can happen if one file + // imports "fmt" and another file defines a global variable fmt. + for (Bindings::const_declarations_iterator p = + this->package_->bindings()->begin_declarations(); + p != this->package_->bindings()->end_declarations(); + ++p) + { + if (p->second->is_unknown() + && p->second->unknown_value()->real_named_object() == NULL) + { + // No point in warning about an undefined name, as we will + // get other errors later anyhow. + continue; + } + File_block_names::const_iterator pf = + this->file_block_names_.find(p->second->name()); + if (pf != this->file_block_names_.end()) + { + std::string n = p->second->message_name(); + error_at(p->second->location(), + "%qs defined as both imported name and global name", + n.c_str()); + inform(pf->second, "%qs imported here", n.c_str()); + } + } } // Clear out names in file scope. @@ -1250,7 +1278,7 @@ Gogo::define_global_names() void Gogo::clear_file_scope() { - this->package_->bindings()->clear_file_scope(); + this->package_->bindings()->clear_file_scope(this); // Warn about packages which were imported but not used. bool quiet = saw_errors(); @@ -4855,7 +4883,7 @@ Bindings::Bindings(Bindings* enclosing) // Clear imports. void -Bindings::clear_file_scope() +Bindings::clear_file_scope(Gogo* gogo) { Contour::iterator p = this->bindings_.begin(); while (p != this->bindings_.end()) @@ -4875,7 +4903,10 @@ Bindings::clear_file_scope() if (keep) ++p; else - p = this->bindings_.erase(p); + { + gogo->add_file_block_name(p->second->name(), p->second->location()); + p = this->bindings_.erase(p); + } } } diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index cffdd219118..f96ffcdfdb9 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -377,6 +377,11 @@ class Gogo void add_named_object(Named_object*); + // Add an identifier to the list of names seen in the file block. + void + add_file_block_name(const std::string& name, Location location) + { this->file_block_names_[name] = location; } + // Mark all local variables in current bindings as used. This is // used when there is a parse error to avoid useless errors. void @@ -678,6 +683,10 @@ class Gogo // This is used for initialization dependency analysis. typedef std::map<Variable*, Named_object*> Var_deps; + // Type used to map identifiers in the file block to the location + // where they were defined. + typedef Unordered_map(std::string, Location) File_block_names; + // Type used to queue writing a type specific function. struct Specific_type_function { @@ -710,6 +719,8 @@ class Gogo // The global binding contour. This includes the builtin functions // and the package we are compiling. Bindings* globals_; + // The list of names we have seen in the file block. + File_block_names file_block_names_; // Mapping from import file names to packages. Imports imports_; // Whether the magic unsafe package was imported. @@ -2265,7 +2276,7 @@ class Bindings // Clear all names in file scope from the bindings. void - clear_file_scope(); + clear_file_scope(Gogo*); // Look up a name in this binding contour and in any enclosing // binding contours. This returns NULL if the name is not found. |