mirror of git://gcc.gnu.org/git/gcc.git
compiler: Error if name defined in both package and file blocks.
From-SVN: r194685
This commit is contained in:
parent
9f9957da5e
commit
5c167ca0a2
|
|
@ -29,6 +29,7 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int, int pointer_size)
|
||||||
package_(NULL),
|
package_(NULL),
|
||||||
functions_(),
|
functions_(),
|
||||||
globals_(new Bindings(NULL)),
|
globals_(new Bindings(NULL)),
|
||||||
|
file_block_names_(),
|
||||||
imports_(),
|
imports_(),
|
||||||
imported_unsafe_(false),
|
imported_unsafe_(false),
|
||||||
packages_(),
|
packages_(),
|
||||||
|
|
@ -1243,6 +1244,33 @@ Gogo::define_global_names()
|
||||||
else if (no->is_unknown())
|
else if (no->is_unknown())
|
||||||
no->unknown_value()->set_real_named_object(global_no);
|
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.
|
// Clear out names in file scope.
|
||||||
|
|
@ -1250,7 +1278,7 @@ Gogo::define_global_names()
|
||||||
void
|
void
|
||||||
Gogo::clear_file_scope()
|
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.
|
// Warn about packages which were imported but not used.
|
||||||
bool quiet = saw_errors();
|
bool quiet = saw_errors();
|
||||||
|
|
@ -4855,7 +4883,7 @@ Bindings::Bindings(Bindings* enclosing)
|
||||||
// Clear imports.
|
// Clear imports.
|
||||||
|
|
||||||
void
|
void
|
||||||
Bindings::clear_file_scope()
|
Bindings::clear_file_scope(Gogo* gogo)
|
||||||
{
|
{
|
||||||
Contour::iterator p = this->bindings_.begin();
|
Contour::iterator p = this->bindings_.begin();
|
||||||
while (p != this->bindings_.end())
|
while (p != this->bindings_.end())
|
||||||
|
|
@ -4875,7 +4903,10 @@ Bindings::clear_file_scope()
|
||||||
if (keep)
|
if (keep)
|
||||||
++p;
|
++p;
|
||||||
else
|
else
|
||||||
p = this->bindings_.erase(p);
|
{
|
||||||
|
gogo->add_file_block_name(p->second->name(), p->second->location());
|
||||||
|
p = this->bindings_.erase(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -377,6 +377,11 @@ class Gogo
|
||||||
void
|
void
|
||||||
add_named_object(Named_object*);
|
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
|
// Mark all local variables in current bindings as used. This is
|
||||||
// used when there is a parse error to avoid useless errors.
|
// used when there is a parse error to avoid useless errors.
|
||||||
void
|
void
|
||||||
|
|
@ -678,6 +683,10 @@ class Gogo
|
||||||
// This is used for initialization dependency analysis.
|
// This is used for initialization dependency analysis.
|
||||||
typedef std::map<Variable*, Named_object*> Var_deps;
|
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.
|
// Type used to queue writing a type specific function.
|
||||||
struct Specific_type_function
|
struct Specific_type_function
|
||||||
{
|
{
|
||||||
|
|
@ -710,6 +719,8 @@ class Gogo
|
||||||
// The global binding contour. This includes the builtin functions
|
// The global binding contour. This includes the builtin functions
|
||||||
// and the package we are compiling.
|
// and the package we are compiling.
|
||||||
Bindings* globals_;
|
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.
|
// Mapping from import file names to packages.
|
||||||
Imports imports_;
|
Imports imports_;
|
||||||
// Whether the magic unsafe package was imported.
|
// Whether the magic unsafe package was imported.
|
||||||
|
|
@ -2265,7 +2276,7 @@ class Bindings
|
||||||
|
|
||||||
// Clear all names in file scope from the bindings.
|
// Clear all names in file scope from the bindings.
|
||||||
void
|
void
|
||||||
clear_file_scope();
|
clear_file_scope(Gogo*);
|
||||||
|
|
||||||
// Look up a name in this binding contour and in any enclosing
|
// Look up a name in this binding contour and in any enclosing
|
||||||
// binding contours. This returns NULL if the name is not found.
|
// binding contours. This returns NULL if the name is not found.
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type image interface {
|
type timage interface {
|
||||||
Image
|
Image
|
||||||
Opaque() bool
|
Opaque() bool
|
||||||
Set(int, int, color.Color)
|
Set(int, int, color.Color)
|
||||||
|
|
@ -24,7 +24,7 @@ func cmp(t *testing.T, cm color.Model, c0, c1 color.Color) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImage(t *testing.T) {
|
func TestImage(t *testing.T) {
|
||||||
testImage := []image{
|
testImage := []timage{
|
||||||
NewRGBA(Rect(0, 0, 10, 10)),
|
NewRGBA(Rect(0, 0, 10, 10)),
|
||||||
NewRGBA64(Rect(0, 0, 10, 10)),
|
NewRGBA64(Rect(0, 0, 10, 10)),
|
||||||
NewNRGBA(Rect(0, 0, 10, 10)),
|
NewNRGBA(Rect(0, 0, 10, 10)),
|
||||||
|
|
@ -52,11 +52,11 @@ func TestImage(t *testing.T) {
|
||||||
t.Errorf("%T: at (6, 3), want a non-zero color, got %v", m, m.At(6, 3))
|
t.Errorf("%T: at (6, 3), want a non-zero color, got %v", m, m.At(6, 3))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !m.SubImage(Rect(6, 3, 7, 4)).(image).Opaque() {
|
if !m.SubImage(Rect(6, 3, 7, 4)).(timage).Opaque() {
|
||||||
t.Errorf("%T: at (6, 3) was not opaque", m)
|
t.Errorf("%T: at (6, 3) was not opaque", m)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
m = m.SubImage(Rect(3, 2, 9, 8)).(image)
|
m = m.SubImage(Rect(3, 2, 9, 8)).(timage)
|
||||||
if !Rect(3, 2, 9, 8).Eq(m.Bounds()) {
|
if !Rect(3, 2, 9, 8).Eq(m.Bounds()) {
|
||||||
t.Errorf("%T: sub-image want bounds %v, got %v", m, Rect(3, 2, 9, 8), m.Bounds())
|
t.Errorf("%T: sub-image want bounds %v, got %v", m, Rect(3, 2, 9, 8), m.Bounds())
|
||||||
continue
|
continue
|
||||||
|
|
@ -97,7 +97,7 @@ func Test16BitsPerColorChannel(t *testing.T) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
testImage := []image{
|
testImage := []timage{
|
||||||
NewRGBA64(Rect(0, 0, 10, 10)),
|
NewRGBA64(Rect(0, 0, 10, 10)),
|
||||||
NewNRGBA64(Rect(0, 0, 10, 10)),
|
NewNRGBA64(Rect(0, 0, 10, 10)),
|
||||||
NewAlpha16(Rect(0, 0, 10, 10)),
|
NewAlpha16(Rect(0, 0, 10, 10)),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue