compiler: Define and use backend-independent Location class.

From Sanjoy Das.

	* go-location.h: New file.
	* go-linemap.cc: New file.
	* go-gcc.cc: Change all uses of source_location to Location.
	* Make-lang.in (GO_OBJS): Add go/go-linemap.o.
	(GO_LINEMAP_H): New variable.
	(GO_LEX_H): Use $(GO_LINEMAP_H).
	(GO_GOGO_H, GO_TYPES_H, GO_IMPORT_H): Likewise.
	(go/go-linemap.o): New target.

Co-Authored-By: Ian Lance Taylor <iant@google.com>

From-SVN: r181813
This commit is contained in:
Sanjoy Das 2011-11-29 19:10:50 +00:00 committed by Ian Lance Taylor
parent 09ad58e618
commit 8afa2bfbdc
29 changed files with 1543 additions and 1102 deletions

View File

@ -1,3 +1,15 @@
2011-11-29 Sanjoy Das <thedigitalangel@gmail.com>
Ian Lance Taylor <iant@google.com>
* go-location.h: New file.
* go-linemap.cc: New file.
* go-gcc.cc: Change all uses of source_location to Location.
* Make-lang.in (GO_OBJS): Add go/go-linemap.o.
(GO_LINEMAP_H): New variable.
(GO_LEX_H): Use $(GO_LINEMAP_H).
(GO_GOGO_H, GO_TYPES_H, GO_IMPORT_H): Likewise.
(go/go-linemap.o): New target.
2011-11-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2011-11-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* Make-lang.in (gospec.o): Pass SHLIB instead of SHLIB_LINK. * Make-lang.in (gospec.o): Pass SHLIB instead of SHLIB_LINK.

View File

@ -54,6 +54,7 @@ GO_OBJS = \
go/go-dump.o \ go/go-dump.o \
go/go-gcc.o \ go/go-gcc.o \
go/go-lang.o \ go/go-lang.o \
go/go-linemap.o \
go/go-optimize.o \ go/go-optimize.o \
go/go.o \ go/go.o \
go/gogo-tree.o \ go/gogo-tree.o \
@ -217,14 +218,15 @@ GO_SYSTEM_H = go/go-system.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(DIAGNOSTIC_CORE_H) $(INPUT_H) intl.h $(DIAGNOSTIC_CORE_H) $(INPUT_H) intl.h
GO_C_H = go/go-c.h $(MACHMODE_H) GO_C_H = go/go-c.h $(MACHMODE_H)
GO_LEX_H = go/gofrontend/lex.h go/gofrontend/operator.h GO_LINEMAP_H = go/gofrontend/go-linemap.h $(GO_SYSTEM_H) go/go-location.h
GO_LEX_H = go/gofrontend/lex.h go/gofrontend/operator.h $(GO_LINEMAP_H)
GO_PARSE_H = go/gofrontend/parse.h GO_PARSE_H = go/gofrontend/parse.h
GO_GOGO_H = go/gofrontend/gogo.h GO_GOGO_H = go/gofrontend/gogo.h $(GO_LINEMAP_H)
GO_TYPES_H = go/gofrontend/types.h GO_TYPES_H = go/gofrontend/types.h $(GO_LINEMAP_H)
GO_STATEMENTS_H = go/gofrontend/statements.h go/gofrontend/operator.h GO_STATEMENTS_H = go/gofrontend/statements.h go/gofrontend/operator.h
GO_EXPRESSIONS_H = go/gofrontend/expressions.h go/gofrontend/operator.h GO_EXPRESSIONS_H = go/gofrontend/expressions.h go/gofrontend/operator.h
GO_EXPORT_H = go/gofrontend/export.h go/gofrontend/string-dump.h GO_EXPORT_H = go/gofrontend/export.h go/gofrontend/string-dump.h
GO_IMPORT_H = go/gofrontend/import.h $(GO_EXPORT_H) GO_IMPORT_H = go/gofrontend/import.h $(GO_EXPORT_H) $(GO_LINEMAP_H)
GO_RUNTIME_H = go/gofrontend/runtime.h go/gofrontend/runtime.def GO_RUNTIME_H = go/gofrontend/runtime.h go/gofrontend/runtime.def
GO_AST_DUMP_H = go/gofrontend/ast-dump.h go/gofrontend/string-dump.h GO_AST_DUMP_H = go/gofrontend/ast-dump.h go/gofrontend/string-dump.h
@ -247,6 +249,9 @@ go/go-gcc.o: go/go-gcc.cc $(GO_SYSTEM_H) $(TREE_H) tree-iterator.h \
go/gofrontend/backend.h go/gofrontend/backend.h
$(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION) $(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)
go/go-linemap.o: go/go-linemap.cc $(GO_SYSTEM_H) $(GO_LINEMAP_H)
$(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)
go/%.o: go/gofrontend/%.cc go/%.o: go/gofrontend/%.cc
$(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION) $(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)

View File

@ -156,7 +156,7 @@ class Gcc_backend : public Backend
function_type(const Btyped_identifier&, function_type(const Btyped_identifier&,
const std::vector<Btyped_identifier>&, const std::vector<Btyped_identifier>&,
const std::vector<Btyped_identifier>&, const std::vector<Btyped_identifier>&,
source_location); const Location);
Btype* Btype*
struct_type(const std::vector<Btyped_identifier>&); struct_type(const std::vector<Btyped_identifier>&);
@ -165,7 +165,7 @@ class Gcc_backend : public Backend
array_type(Btype*, Bexpression*); array_type(Btype*, Bexpression*);
Btype* Btype*
placeholder_pointer_type(const std::string&, source_location, bool); placeholder_pointer_type(const std::string&, Location, bool);
bool bool
set_placeholder_pointer_type(Btype*, Btype*); set_placeholder_pointer_type(Btype*, Btype*);
@ -174,20 +174,20 @@ class Gcc_backend : public Backend
set_placeholder_function_type(Btype*, Btype*); set_placeholder_function_type(Btype*, Btype*);
Btype* Btype*
placeholder_struct_type(const std::string&, source_location); placeholder_struct_type(const std::string&, Location);
bool bool
set_placeholder_struct_type(Btype* placeholder, set_placeholder_struct_type(Btype* placeholder,
const std::vector<Btyped_identifier>&); const std::vector<Btyped_identifier>&);
Btype* Btype*
placeholder_array_type(const std::string&, source_location); placeholder_array_type(const std::string&, Location);
bool bool
set_placeholder_array_type(Btype*, Btype*, Bexpression*); set_placeholder_array_type(Btype*, Btype*, Bexpression*);
Btype* Btype*
named_type(const std::string&, Btype*, source_location); named_type(const std::string&, Btype*, Location);
Btype* Btype*
circular_pointer_type(Btype*, bool); circular_pointer_type(Btype*, bool);
@ -213,21 +213,21 @@ class Gcc_backend : public Backend
init_statement(Bvariable* var, Bexpression* init); init_statement(Bvariable* var, Bexpression* init);
Bstatement* Bstatement*
assignment_statement(Bexpression* lhs, Bexpression* rhs, source_location); assignment_statement(Bexpression* lhs, Bexpression* rhs, Location);
Bstatement* Bstatement*
return_statement(Bfunction*, const std::vector<Bexpression*>&, return_statement(Bfunction*, const std::vector<Bexpression*>&,
source_location); Location);
Bstatement* Bstatement*
if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block, if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
source_location); Location);
Bstatement* Bstatement*
switch_statement(Bexpression* value, switch_statement(Bexpression* value,
const std::vector<std::vector<Bexpression*> >& cases, const std::vector<std::vector<Bexpression*> >& cases,
const std::vector<Bstatement*>& statements, const std::vector<Bstatement*>& statements,
source_location); Location);
Bstatement* Bstatement*
compound_statement(Bstatement*, Bstatement*); compound_statement(Bstatement*, Bstatement*);
@ -239,7 +239,7 @@ class Gcc_backend : public Backend
Bblock* Bblock*
block(Bfunction*, Bblock*, const std::vector<Bvariable*>&, block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
source_location, source_location); Location, Location);
void void
block_add_statements(Bblock*, const std::vector<Bstatement*>&); block_add_statements(Bblock*, const std::vector<Bstatement*>&);
@ -260,46 +260,46 @@ class Gcc_backend : public Backend
Btype* btype, Btype* btype,
bool is_external, bool is_external,
bool is_hidden, bool is_hidden,
source_location location); Location location);
void void
global_variable_set_init(Bvariable*, Bexpression*); global_variable_set_init(Bvariable*, Bexpression*);
Bvariable* Bvariable*
local_variable(Bfunction*, const std::string&, Btype*, bool, local_variable(Bfunction*, const std::string&, Btype*, bool,
source_location); Location);
Bvariable* Bvariable*
parameter_variable(Bfunction*, const std::string&, Btype*, bool, parameter_variable(Bfunction*, const std::string&, Btype*, bool,
source_location); Location);
Bvariable* Bvariable*
temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool, temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
source_location, Bstatement**); Location, Bstatement**);
Bvariable* Bvariable*
immutable_struct(const std::string&, bool, Btype*, source_location); immutable_struct(const std::string&, bool, Btype*, Location);
void void
immutable_struct_set_init(Bvariable*, const std::string&, bool, Btype*, immutable_struct_set_init(Bvariable*, const std::string&, bool, Btype*,
source_location, Bexpression*); Location, Bexpression*);
Bvariable* Bvariable*
immutable_struct_reference(const std::string&, Btype*, source_location); immutable_struct_reference(const std::string&, Btype*, Location);
// Labels. // Labels.
Blabel* Blabel*
label(Bfunction*, const std::string& name, source_location); label(Bfunction*, const std::string& name, Location);
Bstatement* Bstatement*
label_definition_statement(Blabel*); label_definition_statement(Blabel*);
Bstatement* Bstatement*
goto_statement(Blabel*, source_location); goto_statement(Blabel*, Location);
Bexpression* Bexpression*
label_address(Blabel*, source_location); label_address(Blabel*, Location);
private: private:
// Make a Bexpression from a tree. // Make a Bexpression from a tree.
@ -432,7 +432,7 @@ Btype*
Gcc_backend::function_type(const Btyped_identifier& receiver, Gcc_backend::function_type(const Btyped_identifier& receiver,
const std::vector<Btyped_identifier>& parameters, const std::vector<Btyped_identifier>& parameters,
const std::vector<Btyped_identifier>& results, const std::vector<Btyped_identifier>& results,
source_location location) Location location)
{ {
tree args = NULL_TREE; tree args = NULL_TREE;
tree* pp = &args; tree* pp = &args;
@ -482,8 +482,8 @@ Gcc_backend::function_type(const Btyped_identifier& receiver,
if (field_type_tree == error_mark_node) if (field_type_tree == error_mark_node)
return this->error_type(); return this->error_type();
gcc_assert(TYPE_SIZE(field_type_tree) != NULL_TREE); gcc_assert(TYPE_SIZE(field_type_tree) != NULL_TREE);
tree field = build_decl(location, FIELD_DECL, name_tree, tree field = build_decl(location.gcc_location(), FIELD_DECL,
field_type_tree); name_tree, field_type_tree);
DECL_CONTEXT(field) = result; DECL_CONTEXT(field) = result;
*pp = field; *pp = field;
pp = &DECL_CHAIN(field); pp = &DECL_CHAIN(field);
@ -526,7 +526,8 @@ Gcc_backend::fill_in_struct(Btype* fill,
tree type_tree = p->btype->get_tree(); tree type_tree = p->btype->get_tree();
if (type_tree == error_mark_node) if (type_tree == error_mark_node)
return this->error_type(); return this->error_type();
tree field = build_decl(p->location, FIELD_DECL, name_tree, type_tree); tree field = build_decl(p->location.gcc_location(), FIELD_DECL, name_tree,
type_tree);
DECL_CONTEXT(field) = fill_tree; DECL_CONTEXT(field) = fill_tree;
*pp = field; *pp = field;
pp = &DECL_CHAIN(field); pp = &DECL_CHAIN(field);
@ -587,12 +588,12 @@ Gcc_backend::fill_in_array(Btype* fill, Btype* element_type,
Btype* Btype*
Gcc_backend::placeholder_pointer_type(const std::string& name, Gcc_backend::placeholder_pointer_type(const std::string& name,
source_location location, bool) Location location, bool)
{ {
tree ret = build_variant_type_copy(ptr_type_node); tree ret = build_variant_type_copy(ptr_type_node);
if (!name.empty()) if (!name.empty())
{ {
tree decl = build_decl(location, TYPE_DECL, tree decl = build_decl(location.gcc_location(), TYPE_DECL,
get_identifier_from_string(name), get_identifier_from_string(name),
ret); ret);
TYPE_NAME(ret) = decl; TYPE_NAME(ret) = decl;
@ -633,10 +634,10 @@ Gcc_backend::set_placeholder_function_type(Btype* placeholder, Btype* ft)
Btype* Btype*
Gcc_backend::placeholder_struct_type(const std::string& name, Gcc_backend::placeholder_struct_type(const std::string& name,
source_location location) Location location)
{ {
tree ret = make_node(RECORD_TYPE); tree ret = make_node(RECORD_TYPE);
tree decl = build_decl(location, TYPE_DECL, tree decl = build_decl(location.gcc_location(), TYPE_DECL,
get_identifier_from_string(name), get_identifier_from_string(name),
ret); ret);
TYPE_NAME(ret) = decl; TYPE_NAME(ret) = decl;
@ -660,10 +661,10 @@ Gcc_backend::set_placeholder_struct_type(
Btype* Btype*
Gcc_backend::placeholder_array_type(const std::string& name, Gcc_backend::placeholder_array_type(const std::string& name,
source_location location) Location location)
{ {
tree ret = make_node(ARRAY_TYPE); tree ret = make_node(ARRAY_TYPE);
tree decl = build_decl(location, TYPE_DECL, tree decl = build_decl(location.gcc_location(), TYPE_DECL,
get_identifier_from_string(name), get_identifier_from_string(name),
ret); ret);
TYPE_NAME(ret) = decl; TYPE_NAME(ret) = decl;
@ -687,13 +688,13 @@ Gcc_backend::set_placeholder_array_type(Btype* placeholder,
Btype* Btype*
Gcc_backend::named_type(const std::string& name, Btype* btype, Gcc_backend::named_type(const std::string& name, Btype* btype,
source_location location) Location location)
{ {
tree type = btype->get_tree(); tree type = btype->get_tree();
if (type == error_mark_node) if (type == error_mark_node)
return this->error_type(); return this->error_type();
type = build_variant_type_copy(type); type = build_variant_type_copy(type);
tree decl = build_decl(location, TYPE_DECL, tree decl = build_decl(location.gcc_location(), TYPE_DECL,
get_identifier_from_string(name), get_identifier_from_string(name),
type); type);
TYPE_NAME(type) = decl; TYPE_NAME(type) = decl;
@ -757,13 +758,14 @@ Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
Bstatement* Bstatement*
Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs, Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
source_location location) Location location)
{ {
tree lhs_tree = lhs->get_tree(); tree lhs_tree = lhs->get_tree();
tree rhs_tree = rhs->get_tree(); tree rhs_tree = rhs->get_tree();
if (lhs_tree == error_mark_node || rhs_tree == error_mark_node) if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
return this->error_statement(); return this->error_statement();
return this->make_statement(fold_build2_loc(location, MODIFY_EXPR, return this->make_statement(fold_build2_loc(location.gcc_location(),
MODIFY_EXPR,
void_type_node, void_type_node,
lhs_tree, rhs_tree)); lhs_tree, rhs_tree));
} }
@ -773,7 +775,7 @@ Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
Bstatement* Bstatement*
Gcc_backend::return_statement(Bfunction* bfunction, Gcc_backend::return_statement(Bfunction* bfunction,
const std::vector<Bexpression*>& vals, const std::vector<Bexpression*>& vals,
source_location location) Location location)
{ {
tree fntree = bfunction->get_tree(); tree fntree = bfunction->get_tree();
if (fntree == error_mark_node) if (fntree == error_mark_node)
@ -783,15 +785,18 @@ Gcc_backend::return_statement(Bfunction* bfunction,
return this->error_statement(); return this->error_statement();
tree ret; tree ret;
if (vals.empty()) if (vals.empty())
ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, NULL_TREE); ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
NULL_TREE);
else if (vals.size() == 1) else if (vals.size() == 1)
{ {
tree val = vals.front()->get_tree(); tree val = vals.front()->get_tree();
if (val == error_mark_node) if (val == error_mark_node)
return this->error_statement(); return this->error_statement();
tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node, tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
result, vals.front()->get_tree()); void_type_node, result,
ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, set); vals.front()->get_tree());
ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
void_type_node, set);
} }
else else
{ {
@ -808,20 +813,23 @@ Gcc_backend::return_statement(Bfunction* bfunction,
p++, field = DECL_CHAIN(field)) p++, field = DECL_CHAIN(field))
{ {
gcc_assert(field != NULL_TREE); gcc_assert(field != NULL_TREE);
tree ref = fold_build3_loc(location, COMPONENT_REF, TREE_TYPE(field), tree ref = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
rettmp, field, NULL_TREE); TREE_TYPE(field), rettmp, field,
NULL_TREE);
tree val = (*p)->get_tree(); tree val = (*p)->get_tree();
if (val == error_mark_node) if (val == error_mark_node)
return this->error_statement(); return this->error_statement();
tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node, tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
void_type_node,
ref, (*p)->get_tree()); ref, (*p)->get_tree());
append_to_statement_list(set, &stmt_list); append_to_statement_list(set, &stmt_list);
} }
gcc_assert(field == NULL_TREE); gcc_assert(field == NULL_TREE);
tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node, tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
void_type_node,
result, rettmp); result, rettmp);
tree ret_expr = fold_build1_loc(location, RETURN_EXPR, void_type_node, tree ret_expr = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
set); void_type_node, set);
append_to_statement_list(ret_expr, &stmt_list); append_to_statement_list(ret_expr, &stmt_list);
ret = stmt_list; ret = stmt_list;
} }
@ -832,7 +840,7 @@ Gcc_backend::return_statement(Bfunction* bfunction,
Bstatement* Bstatement*
Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block, Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
Bblock* else_block, source_location location) Bblock* else_block, Location location)
{ {
tree cond_tree = condition->get_tree(); tree cond_tree = condition->get_tree();
tree then_tree = then_block->get_tree(); tree then_tree = then_block->get_tree();
@ -841,8 +849,8 @@ Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
|| then_tree == error_mark_node || then_tree == error_mark_node
|| else_tree == error_mark_node) || else_tree == error_mark_node)
return this->error_statement(); return this->error_statement();
tree ret = build3_loc(location, COND_EXPR, void_type_node, cond_tree, tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
then_tree, else_tree); cond_tree, then_tree, else_tree);
return this->make_statement(ret); return this->make_statement(ret);
} }
@ -853,7 +861,7 @@ Gcc_backend::switch_statement(
Bexpression* value, Bexpression* value,
const std::vector<std::vector<Bexpression*> >& cases, const std::vector<std::vector<Bexpression*> >& cases,
const std::vector<Bstatement*>& statements, const std::vector<Bstatement*>& statements,
source_location switch_location) Location switch_location)
{ {
gcc_assert(cases.size() == statements.size()); gcc_assert(cases.size() == statements.size());
@ -866,8 +874,8 @@ Gcc_backend::switch_statement(
if (pc->empty()) if (pc->empty())
{ {
source_location loc = (*ps != NULL source_location loc = (*ps != NULL
? EXPR_LOCATION((*ps)->get_tree()) ? EXPR_LOCATION((*ps)->get_tree())
: UNKNOWN_LOCATION); : UNKNOWN_LOCATION);
tree label = create_artificial_label(loc); tree label = create_artificial_label(loc);
tree c = build_case_label(NULL_TREE, NULL_TREE, label); tree c = build_case_label(NULL_TREE, NULL_TREE, label);
append_to_statement_list(c, &stmt_list); append_to_statement_list(c, &stmt_list);
@ -900,8 +908,8 @@ Gcc_backend::switch_statement(
tree tv = value->get_tree(); tree tv = value->get_tree();
if (tv == error_mark_node) if (tv == error_mark_node)
return this->error_statement(); return this->error_statement();
tree t = build3_loc(switch_location, SWITCH_EXPR, void_type_node, tree t = build3_loc(switch_location.gcc_location(), SWITCH_EXPR,
tv, stmt_list, NULL_TREE); void_type_node, tv, stmt_list, NULL_TREE);
return this->make_statement(t); return this->make_statement(t);
} }
@ -948,8 +956,8 @@ Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
Bblock* Bblock*
Gcc_backend::block(Bfunction* function, Bblock* enclosing, Gcc_backend::block(Bfunction* function, Bblock* enclosing,
const std::vector<Bvariable*>& vars, const std::vector<Bvariable*>& vars,
source_location start_location, Location start_location,
source_location) Location)
{ {
tree block_tree = make_node(BLOCK); tree block_tree = make_node(BLOCK);
if (enclosing == NULL) if (enclosing == NULL)
@ -1010,8 +1018,9 @@ Gcc_backend::block(Bfunction* function, Bblock* enclosing,
TREE_USED(block_tree) = 1; TREE_USED(block_tree) = 1;
tree bind_tree = build3_loc(start_location, BIND_EXPR, void_type_node, tree bind_tree = build3_loc(start_location.gcc_location(), BIND_EXPR,
BLOCK_VARS(block_tree), NULL_TREE, block_tree); void_type_node, BLOCK_VARS(block_tree),
NULL_TREE, block_tree);
TREE_SIDE_EFFECTS(bind_tree) = 1; TREE_SIDE_EFFECTS(bind_tree) = 1;
return new Bblock(bind_tree); return new Bblock(bind_tree);
@ -1057,7 +1066,7 @@ Gcc_backend::global_variable(const std::string& package_name,
Btype* btype, Btype* btype,
bool is_external, bool is_external,
bool is_hidden, bool is_hidden,
source_location location) Location location)
{ {
tree type_tree = btype->get_tree(); tree type_tree = btype->get_tree();
if (type_tree == error_mark_node) if (type_tree == error_mark_node)
@ -1066,7 +1075,7 @@ Gcc_backend::global_variable(const std::string& package_name,
std::string var_name(package_name); std::string var_name(package_name);
var_name.push_back('.'); var_name.push_back('.');
var_name.append(name); var_name.append(name);
tree decl = build_decl(location, VAR_DECL, tree decl = build_decl(location.gcc_location(), VAR_DECL,
get_identifier_from_string(var_name), get_identifier_from_string(var_name),
type_tree); type_tree);
if (is_external) if (is_external)
@ -1109,12 +1118,12 @@ Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
Bvariable* Bvariable*
Gcc_backend::local_variable(Bfunction* function, const std::string& name, Gcc_backend::local_variable(Bfunction* function, const std::string& name,
Btype* btype, bool is_address_taken, Btype* btype, bool is_address_taken,
source_location location) Location location)
{ {
tree type_tree = btype->get_tree(); tree type_tree = btype->get_tree();
if (type_tree == error_mark_node) if (type_tree == error_mark_node)
return this->error_variable(); return this->error_variable();
tree decl = build_decl(location, VAR_DECL, tree decl = build_decl(location.gcc_location(), VAR_DECL,
get_identifier_from_string(name), get_identifier_from_string(name),
type_tree); type_tree);
DECL_CONTEXT(decl) = function->get_tree(); DECL_CONTEXT(decl) = function->get_tree();
@ -1130,12 +1139,12 @@ Gcc_backend::local_variable(Bfunction* function, const std::string& name,
Bvariable* Bvariable*
Gcc_backend::parameter_variable(Bfunction* function, const std::string& name, Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
Btype* btype, bool is_address_taken, Btype* btype, bool is_address_taken,
source_location location) Location location)
{ {
tree type_tree = btype->get_tree(); tree type_tree = btype->get_tree();
if (type_tree == error_mark_node) if (type_tree == error_mark_node)
return this->error_variable(); return this->error_variable();
tree decl = build_decl(location, PARM_DECL, tree decl = build_decl(location.gcc_location(), PARM_DECL,
get_identifier_from_string(name), get_identifier_from_string(name),
type_tree); type_tree);
DECL_CONTEXT(decl) = function->get_tree(); DECL_CONTEXT(decl) = function->get_tree();
@ -1153,7 +1162,7 @@ Bvariable*
Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock, Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
Btype* btype, Bexpression* binit, Btype* btype, Bexpression* binit,
bool is_address_taken, bool is_address_taken,
source_location location, Location location,
Bstatement** pstatement) Bstatement** pstatement)
{ {
tree type_tree = btype->get_tree(); tree type_tree = btype->get_tree();
@ -1171,7 +1180,7 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
else else
{ {
gcc_assert(bblock != NULL); gcc_assert(bblock != NULL);
var = build_decl(location, VAR_DECL, var = build_decl(location.gcc_location(), VAR_DECL,
create_tmp_var_name("GOTMP"), create_tmp_var_name("GOTMP"),
type_tree); type_tree);
DECL_ARTIFICIAL(var) = 1; DECL_ARTIFICIAL(var) = 1;
@ -1199,12 +1208,14 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
} }
if (init_tree != NULL_TREE) if (init_tree != NULL_TREE)
DECL_INITIAL(var) = fold_convert_loc(location, type_tree, init_tree); DECL_INITIAL(var) = fold_convert_loc(location.gcc_location(), type_tree,
init_tree);
if (is_address_taken) if (is_address_taken)
TREE_ADDRESSABLE(var) = 1; TREE_ADDRESSABLE(var) = 1;
*pstatement = this->make_statement(build1_loc(location, DECL_EXPR, *pstatement = this->make_statement(build1_loc(location.gcc_location(),
DECL_EXPR,
void_type_node, var)); void_type_node, var));
return new Bvariable(var); return new Bvariable(var);
} }
@ -1213,13 +1224,13 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
Bvariable* Bvariable*
Gcc_backend::immutable_struct(const std::string& name, bool, Btype* btype, Gcc_backend::immutable_struct(const std::string& name, bool, Btype* btype,
source_location location) Location location)
{ {
tree type_tree = btype->get_tree(); tree type_tree = btype->get_tree();
if (type_tree == error_mark_node) if (type_tree == error_mark_node)
return this->error_variable(); return this->error_variable();
gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE); gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
tree decl = build_decl(location, VAR_DECL, tree decl = build_decl(location.gcc_location(), VAR_DECL,
get_identifier_from_string(name), get_identifier_from_string(name),
build_qualified_type(type_tree, TYPE_QUAL_CONST)); build_qualified_type(type_tree, TYPE_QUAL_CONST));
TREE_STATIC(decl) = 1; TREE_STATIC(decl) = 1;
@ -1241,7 +1252,7 @@ Gcc_backend::immutable_struct(const std::string& name, bool, Btype* btype,
void void
Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&, Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
bool is_common, Btype*, bool is_common, Btype*,
source_location, Location,
Bexpression* initializer) Bexpression* initializer)
{ {
tree decl = var->get_tree(); tree decl = var->get_tree();
@ -1268,13 +1279,13 @@ Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
Bvariable* Bvariable*
Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype, Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
source_location location) Location location)
{ {
tree type_tree = btype->get_tree(); tree type_tree = btype->get_tree();
if (type_tree == error_mark_node) if (type_tree == error_mark_node)
return this->error_variable(); return this->error_variable();
gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE); gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
tree decl = build_decl(location, VAR_DECL, tree decl = build_decl(location.gcc_location(), VAR_DECL,
get_identifier_from_string(name), get_identifier_from_string(name),
build_qualified_type(type_tree, TYPE_QUAL_CONST)); build_qualified_type(type_tree, TYPE_QUAL_CONST));
TREE_READONLY(decl) = 1; TREE_READONLY(decl) = 1;
@ -1290,15 +1301,16 @@ Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
Blabel* Blabel*
Gcc_backend::label(Bfunction* function, const std::string& name, Gcc_backend::label(Bfunction* function, const std::string& name,
source_location location) Location location)
{ {
tree decl; tree decl;
if (name.empty()) if (name.empty())
decl = create_artificial_label(location); decl = create_artificial_label(location.gcc_location());
else else
{ {
tree id = get_identifier_from_string(name); tree id = get_identifier_from_string(name);
decl = build_decl(location, LABEL_DECL, id, void_type_node); decl = build_decl(location.gcc_location(), LABEL_DECL, id,
void_type_node);
DECL_CONTEXT(decl) = function->get_tree(); DECL_CONTEXT(decl) = function->get_tree();
} }
return new Blabel(decl); return new Blabel(decl);
@ -1318,23 +1330,25 @@ Gcc_backend::label_definition_statement(Blabel* label)
// Make a goto statement. // Make a goto statement.
Bstatement* Bstatement*
Gcc_backend::goto_statement(Blabel* label, source_location location) Gcc_backend::goto_statement(Blabel* label, Location location)
{ {
tree lab = label->get_tree(); tree lab = label->get_tree();
tree ret = fold_build1_loc(location, GOTO_EXPR, void_type_node, lab); tree ret = fold_build1_loc(location.gcc_location(), GOTO_EXPR, void_type_node,
lab);
return this->make_statement(ret); return this->make_statement(ret);
} }
// Get the address of a label. // Get the address of a label.
Bexpression* Bexpression*
Gcc_backend::label_address(Blabel* label, source_location location) Gcc_backend::label_address(Blabel* label, Location location)
{ {
tree lab = label->get_tree(); tree lab = label->get_tree();
TREE_USED(lab) = 1; TREE_USED(lab) = 1;
TREE_ADDRESSABLE(lab) = 1; TREE_ADDRESSABLE(lab) = 1;
tree ret = fold_convert_loc(location, ptr_type_node, tree ret = fold_convert_loc(location.gcc_location(), ptr_type_node,
build_fold_addr_expr_loc(location, lab)); build_fold_addr_expr_loc(location.gcc_location(),
lab));
return this->make_expression(ret); return this->make_expression(ret);
} }

126
gcc/go/go-linemap.cc Normal file
View File

@ -0,0 +1,126 @@
// go-linemap.cc -- GCC implementation of Linemap.
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "go-linemap.h"
// This class implements the Linemap interface defined by the
// frontend.
class Gcc_linemap : public Linemap
{
public:
Gcc_linemap()
: Linemap(),
in_file_(false)
{ }
void
start_file(const char* file_name, unsigned int line_begin);
void
start_line(unsigned int line_number, unsigned int line_size);
Location
get_location(unsigned int column);
void
stop();
protected:
Location
get_predeclared_location();
Location
get_unknown_location();
bool
is_predeclared(Location);
bool
is_unknown(Location);
private:
// Whether we are currently reading a file.
bool in_file_;
};
Linemap* Linemap::instance_ = NULL;
// Start getting locations from a new file.
void
Gcc_linemap::start_file(const char *file_name, unsigned line_begin)
{
if (this->in_file_)
linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
linemap_add(line_table, LC_ENTER, 0, file_name, line_begin);
this->in_file_ = true;
}
// Stop getting locations.
void
Gcc_linemap::stop()
{
linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
this->in_file_ = false;
}
// Start a new line.
void
Gcc_linemap::start_line(unsigned lineno, unsigned linesize)
{
linemap_line_start(line_table, lineno, linesize);
}
// Get a location.
Location
Gcc_linemap::get_location(unsigned column)
{
return Location(linemap_position_for_column(line_table, column));
}
// Get the unknown location.
Location
Gcc_linemap::get_unknown_location()
{
return Location(UNKNOWN_LOCATION);
}
// Get the predeclared location.
Location
Gcc_linemap::get_predeclared_location()
{
return Location(BUILTINS_LOCATION);
}
// Return whether a location is the predeclared location.
bool
Gcc_linemap::is_predeclared(Location loc)
{
return loc.gcc_location() == BUILTINS_LOCATION;
}
// Return whether a location is the unknown location.
bool
Gcc_linemap::is_unknown(Location loc)
{
return loc.gcc_location() == UNKNOWN_LOCATION;
}
// Return the Linemap to use for the gcc backend.
Linemap*
go_get_linemap()
{
return new Gcc_linemap;
}

45
gcc/go/go-location.h Normal file
View File

@ -0,0 +1,45 @@
// go-location.h -- GCC specific Location declaration. -*- C++ -*-
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#ifndef GO_LOCATION_H
#define GO_LOCATION_H
#include "go-system.h"
// A location in an input source file.
class Location
{
public:
Location()
: gcc_loc_(UNKNOWN_LOCATION)
{ }
explicit Location(source_location loc)
: gcc_loc_(loc)
{ }
source_location
gcc_location() const
{ return this->gcc_loc_; }
// Temporary hack till error_at and warning_at can deal with a Location.
operator source_location() const
{ return this->gcc_loc_; }
private:
source_location gcc_loc_;
};
// The Go frontend requires the ability to compare Locations.
inline bool
operator<(Location loca, Location locb)
{
return loca.gcc_location() < locb.gcc_location();
}
#endif // !defined(GO_LOCATION_H)

View File

@ -46,14 +46,14 @@ class Backend
{ {
std::string name; std::string name;
Btype* btype; Btype* btype;
source_location location; Location location;
Btyped_identifier() Btyped_identifier()
: name(), btype(NULL), location(UNKNOWN_LOCATION) : name(), btype(NULL), location(UNKNOWN_LOCATION)
{ } { }
Btyped_identifier(const std::string& a_name, Btype* a_btype, Btyped_identifier(const std::string& a_name, Btype* a_btype,
source_location a_location) Location a_location)
: name(a_name), btype(a_btype), location(a_location) : name(a_name), btype(a_btype), location(a_location)
{ } { }
}; };
@ -100,7 +100,7 @@ class Backend
function_type(const Btyped_identifier& receiver, function_type(const Btyped_identifier& receiver,
const std::vector<Btyped_identifier>& parameters, const std::vector<Btyped_identifier>& parameters,
const std::vector<Btyped_identifier>& results, const std::vector<Btyped_identifier>& results,
source_location location) = 0; Location location) = 0;
// Get a struct type. // Get a struct type.
virtual Btype* virtual Btype*
@ -121,7 +121,7 @@ class Backend
// parameter to set_placeholder_pointer_type or // parameter to set_placeholder_pointer_type or
// set_placeholder_function_type. // set_placeholder_function_type.
virtual Btype* virtual Btype*
placeholder_pointer_type(const std::string& name, source_location, placeholder_pointer_type(const std::string& name, Location,
bool for_function) = 0; bool for_function) = 0;
// Fill in a placeholder pointer type as a pointer. This takes a // Fill in a placeholder pointer type as a pointer. This takes a
@ -141,7 +141,7 @@ class Backend
// Create a placeholder struct type. This is used for a named // Create a placeholder struct type. This is used for a named
// struct type, as with placeholder_pointer_type. // struct type, as with placeholder_pointer_type.
virtual Btype* virtual Btype*
placeholder_struct_type(const std::string& name, source_location) = 0; placeholder_struct_type(const std::string& name, Location) = 0;
// Fill in a placeholder struct type. This takes a type returned by // Fill in a placeholder struct type. This takes a type returned by
// placeholder_struct_type and arranges for it to become a real // placeholder_struct_type and arranges for it to become a real
@ -156,7 +156,7 @@ class Backend
// type, as with placeholder_pointer_type, to handle cases like // type, as with placeholder_pointer_type, to handle cases like
// type A []*A. // type A []*A.
virtual Btype* virtual Btype*
placeholder_array_type(const std::string& name, source_location) = 0; placeholder_array_type(const std::string& name, Location) = 0;
// Fill in a placeholder array type. This takes a type returned by // Fill in a placeholder array type. This takes a type returned by
// placeholder_array_type and arranges for it to become a real array // placeholder_array_type and arranges for it to become a real array
@ -172,7 +172,7 @@ class Backend
// placeholder_array_type.. (It may be called for a pointer, // placeholder_array_type.. (It may be called for a pointer,
// struct, or array type in a case like "type P *byte; type Q P".) // struct, or array type in a case like "type P *byte; type Q P".)
virtual Btype* virtual Btype*
named_type(const std::string& name, Btype*, source_location) = 0; named_type(const std::string& name, Btype*, Location) = 0;
// Create a marker for a circular pointer type. Go pointer and // Create a marker for a circular pointer type. Go pointer and
// function types can refer to themselves in ways that are not // function types can refer to themselves in ways that are not
@ -227,18 +227,18 @@ class Backend
// Create an assignment statement. // Create an assignment statement.
virtual Bstatement* virtual Bstatement*
assignment_statement(Bexpression* lhs, Bexpression* rhs, assignment_statement(Bexpression* lhs, Bexpression* rhs,
source_location) = 0; Location) = 0;
// Create a return statement, passing the representation of the // Create a return statement, passing the representation of the
// function and the list of values to return. // function and the list of values to return.
virtual Bstatement* virtual Bstatement*
return_statement(Bfunction*, const std::vector<Bexpression*>&, return_statement(Bfunction*, const std::vector<Bexpression*>&,
source_location) = 0; Location) = 0;
// Create an if statement. ELSE_BLOCK may be NULL. // Create an if statement. ELSE_BLOCK may be NULL.
virtual Bstatement* virtual Bstatement*
if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block, if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
source_location) = 0; Location) = 0;
// Create a switch statement where the case values are constants. // Create a switch statement where the case values are constants.
// CASES and STATEMENTS must have the same number of entries. If // CASES and STATEMENTS must have the same number of entries. If
@ -251,7 +251,7 @@ class Backend
switch_statement(Bexpression* value, switch_statement(Bexpression* value,
const std::vector<std::vector<Bexpression*> >& cases, const std::vector<std::vector<Bexpression*> >& cases,
const std::vector<Bstatement*>& statements, const std::vector<Bstatement*>& statements,
source_location) = 0; Location) = 0;
// Create a single statement from two statements. // Create a single statement from two statements.
virtual Bstatement* virtual Bstatement*
@ -276,7 +276,7 @@ class Backend
virtual Bblock* virtual Bblock*
block(Bfunction* function, Bblock* enclosing, block(Bfunction* function, Bblock* enclosing,
const std::vector<Bvariable*>& vars, const std::vector<Bvariable*>& vars,
source_location start_location, source_location end_location) = 0; Location start_location, Location end_location) = 0;
// Add the statements to a block. The block is created first. Then // Add the statements to a block. The block is created first. Then
// the statements are created. Then the statements are added to the // the statements are created. Then the statements are added to the
@ -313,7 +313,7 @@ class Backend
Btype* btype, Btype* btype,
bool is_external, bool is_external,
bool is_hidden, bool is_hidden,
source_location location) = 0; Location location) = 0;
// A global variable will 1) be initialized to zero, or 2) be // A global variable will 1) be initialized to zero, or 2) be
// initialized to a constant value, or 3) be initialized in the init // initialized to a constant value, or 3) be initialized in the init
@ -335,7 +335,7 @@ class Backend
// init_statement to set the initial value. // init_statement to set the initial value.
virtual Bvariable* virtual Bvariable*
local_variable(Bfunction* function, const std::string& name, Btype* type, local_variable(Bfunction* function, const std::string& name, Btype* type,
bool is_address_taken, source_location location) = 0; bool is_address_taken, Location location) = 0;
// Create a function parameter. This is an incoming parameter, not // Create a function parameter. This is an incoming parameter, not
// a result parameter (result parameters are treated as local // a result parameter (result parameters are treated as local
@ -343,7 +343,7 @@ class Backend
virtual Bvariable* virtual Bvariable*
parameter_variable(Bfunction* function, const std::string& name, parameter_variable(Bfunction* function, const std::string& name,
Btype* type, bool is_address_taken, Btype* type, bool is_address_taken,
source_location location) = 0; Location location) = 0;
// Create a temporary variable. A temporary variable has no name, // Create a temporary variable. A temporary variable has no name,
// just a type. We pass in FUNCTION and BLOCK in case they are // just a type. We pass in FUNCTION and BLOCK in case they are
@ -358,7 +358,7 @@ class Backend
// *PSTATEMENT to a statement which initializes the variable. // *PSTATEMENT to a statement which initializes the variable.
virtual Bvariable* virtual Bvariable*
temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression* init, temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression* init,
bool address_is_taken, source_location location, bool address_is_taken, Location location,
Bstatement** pstatement) = 0; Bstatement** pstatement) = 0;
// Create a named immutable initialized data structure. This is // Create a named immutable initialized data structure. This is
@ -384,7 +384,7 @@ class Backend
// set_immutable_struct_initializer. // set_immutable_struct_initializer.
virtual Bvariable* virtual Bvariable*
immutable_struct(const std::string& name, bool is_common, Btype* type, immutable_struct(const std::string& name, bool is_common, Btype* type,
source_location) = 0; Location) = 0;
// Set the initial value of a variable created by immutable_struct. // Set the initial value of a variable created by immutable_struct.
// The NAME, IS_COMMON, TYPE, and location parameters are the same // The NAME, IS_COMMON, TYPE, and location parameters are the same
@ -395,7 +395,7 @@ class Backend
// immutable_struct. // immutable_struct.
virtual void virtual void
immutable_struct_set_init(Bvariable*, const std::string& name, immutable_struct_set_init(Bvariable*, const std::string& name,
bool is_common, Btype* type, source_location, bool is_common, Btype* type, Location,
Bexpression* initializer) = 0; Bexpression* initializer) = 0;
// Create a reference to a named immutable initialized data // Create a reference to a named immutable initialized data
@ -405,7 +405,7 @@ class Backend
// corresponds to an extern const global variable in C. // corresponds to an extern const global variable in C.
virtual Bvariable* virtual Bvariable*
immutable_struct_reference(const std::string& name, Btype* type, immutable_struct_reference(const std::string& name, Btype* type,
source_location) = 0; Location) = 0;
// Labels. // Labels.
@ -413,7 +413,7 @@ class Backend
// created by the frontend for a loop construct. The location is // created by the frontend for a loop construct. The location is
// where the the label is defined. // where the the label is defined.
virtual Blabel* virtual Blabel*
label(Bfunction*, const std::string& name, source_location) = 0; label(Bfunction*, const std::string& name, Location) = 0;
// Create a statement which defines a label. This statement will be // Create a statement which defines a label. This statement will be
// put into the codestream at the point where the label should be // put into the codestream at the point where the label should be
@ -423,13 +423,13 @@ class Backend
// Create a goto statement to a label. // Create a goto statement to a label.
virtual Bstatement* virtual Bstatement*
goto_statement(Blabel*, source_location) = 0; goto_statement(Blabel*, Location) = 0;
// Create an expression for the address of a label. This is used to // Create an expression for the address of a label. This is used to
// get the return address of a deferred function which may call // get the return address of a deferred function which may call
// recover. // recover.
virtual Bexpression* virtual Bexpression*
label_address(Blabel*, source_location) = 0; label_address(Blabel*, Location) = 0;
}; };
// The backend interface has to define this function. // The backend interface has to define this function.

View File

@ -189,8 +189,8 @@ Dataflow::Compare_vars::operator()(const Named_object* no1,
return false; return false;
// We can have two different variables with the same name. // We can have two different variables with the same name.
source_location loc1 = no1->location(); Location loc1 = no1->location();
source_location loc2 = no2->location(); Location loc2 = no2->location();
if (loc1 < loc2) if (loc1 < loc2)
return false; return false;
if (loc1 > loc2) if (loc1 > loc2)

View File

@ -279,7 +279,7 @@ Export::write_type(const Type* type)
if (named_type != NULL) if (named_type != NULL)
{ {
// The builtin types should have been predefined. // The builtin types should have been predefined.
go_assert(named_type->location() != BUILTINS_LOCATION go_assert(!Linemap::is_predeclared_location(named_type->location())
|| (named_type->named_object()->package()->name() || (named_type->named_object()->package()->name()
== "unsafe")); == "unsafe"));
named_object = named_type->named_object(); named_object = named_type->named_object();

File diff suppressed because it is too large Load Diff

View File

@ -98,81 +98,81 @@ class Expression
EXPRESSION_LABEL_ADDR EXPRESSION_LABEL_ADDR
}; };
Expression(Expression_classification, source_location); Expression(Expression_classification, Location);
virtual ~Expression(); virtual ~Expression();
// Make an error expression. This is used when a parse error occurs // Make an error expression. This is used when a parse error occurs
// to prevent cascading errors. // to prevent cascading errors.
static Expression* static Expression*
make_error(source_location); make_error(Location);
// Make an expression which is really a type. This is used during // Make an expression which is really a type. This is used during
// parsing. // parsing.
static Expression* static Expression*
make_type(Type*, source_location); make_type(Type*, Location);
// Make a unary expression. // Make a unary expression.
static Expression* static Expression*
make_unary(Operator, Expression*, source_location); make_unary(Operator, Expression*, Location);
// Make a binary expression. // Make a binary expression.
static Expression* static Expression*
make_binary(Operator, Expression*, Expression*, source_location); make_binary(Operator, Expression*, Expression*, Location);
// Make a reference to a constant in an expression. // Make a reference to a constant in an expression.
static Expression* static Expression*
make_const_reference(Named_object*, source_location); make_const_reference(Named_object*, Location);
// Make a reference to a variable in an expression. // Make a reference to a variable in an expression.
static Expression* static Expression*
make_var_reference(Named_object*, source_location); make_var_reference(Named_object*, Location);
// Make a reference to a temporary variable. Temporary variables // Make a reference to a temporary variable. Temporary variables
// are always created by a single statement, which is what we use to // are always created by a single statement, which is what we use to
// refer to them. // refer to them.
static Temporary_reference_expression* static Temporary_reference_expression*
make_temporary_reference(Temporary_statement*, source_location); make_temporary_reference(Temporary_statement*, Location);
// Make a sink expression--a reference to the blank identifier _. // Make a sink expression--a reference to the blank identifier _.
static Expression* static Expression*
make_sink(source_location); make_sink(Location);
// Make a reference to a function in an expression. // Make a reference to a function in an expression.
static Expression* static Expression*
make_func_reference(Named_object*, Expression* closure, source_location); make_func_reference(Named_object*, Expression* closure, Location);
// Make a reference to an unknown name. In a correct program this // Make a reference to an unknown name. In a correct program this
// will always be lowered to a real const/var/func reference. // will always be lowered to a real const/var/func reference.
static Expression* static Expression*
make_unknown_reference(Named_object*, source_location); make_unknown_reference(Named_object*, Location);
// Make a constant bool expression. // Make a constant bool expression.
static Expression* static Expression*
make_boolean(bool val, source_location); make_boolean(bool val, Location);
// Make a constant string expression. // Make a constant string expression.
static Expression* static Expression*
make_string(const std::string&, source_location); make_string(const std::string&, Location);
// Make a constant integer expression. TYPE should be NULL for an // Make a constant integer expression. TYPE should be NULL for an
// abstract type. // abstract type.
static Expression* static Expression*
make_integer(const mpz_t*, Type*, source_location); make_integer(const mpz_t*, Type*, Location);
// Make a constant float expression. TYPE should be NULL for an // Make a constant float expression. TYPE should be NULL for an
// abstract type. // abstract type.
static Expression* static Expression*
make_float(const mpfr_t*, Type*, source_location); make_float(const mpfr_t*, Type*, Location);
// Make a constant complex expression. TYPE should be NULL for an // Make a constant complex expression. TYPE should be NULL for an
// abstract type. // abstract type.
static Expression* static Expression*
make_complex(const mpfr_t* real, const mpfr_t* imag, Type*, source_location); make_complex(const mpfr_t* real, const mpfr_t* imag, Type*, Location);
// Make a nil expression. // Make a nil expression.
static Expression* static Expression*
make_nil(source_location); make_nil(Location);
// Make an iota expression. This is used for the predeclared // Make an iota expression. This is used for the predeclared
// constant iota. // constant iota.
@ -182,7 +182,7 @@ class Expression
// Make a call expression. // Make a call expression.
static Call_expression* static Call_expression*
make_call(Expression* func, Expression_list* args, bool is_varargs, make_call(Expression* func, Expression_list* args, bool is_varargs,
source_location); Location);
// Make a reference to a specific result of a call expression which // Make a reference to a specific result of a call expression which
// returns a tuple. // returns a tuple.
@ -192,7 +192,7 @@ class Expression
// Make an expression which is a method bound to its first // Make an expression which is a method bound to its first
// parameter. // parameter.
static Bound_method_expression* static Bound_method_expression*
make_bound_method(Expression* object, Named_object* method, source_location); make_bound_method(Expression* object, Named_object* method, Location);
// Make an index or slice expression. This is a parser expression // Make an index or slice expression. This is a parser expression
// which represents LEFT[START:END]. END may be NULL, meaning an // which represents LEFT[START:END]. END may be NULL, meaning an
@ -201,84 +201,84 @@ class Expression
// string index, or a map index. // string index, or a map index.
static Expression* static Expression*
make_index(Expression* left, Expression* start, Expression* end, make_index(Expression* left, Expression* start, Expression* end,
source_location); Location);
// Make an array index expression. END may be NULL, in which case // Make an array index expression. END may be NULL, in which case
// this is an lvalue. // this is an lvalue.
static Expression* static Expression*
make_array_index(Expression* array, Expression* start, Expression* end, make_array_index(Expression* array, Expression* start, Expression* end,
source_location); Location);
// Make a string index expression. END may be NULL. This is never // Make a string index expression. END may be NULL. This is never
// an lvalue. // an lvalue.
static Expression* static Expression*
make_string_index(Expression* string, Expression* start, Expression* end, make_string_index(Expression* string, Expression* start, Expression* end,
source_location); Location);
// Make a map index expression. This is an lvalue. // Make a map index expression. This is an lvalue.
static Map_index_expression* static Map_index_expression*
make_map_index(Expression* map, Expression* val, source_location); make_map_index(Expression* map, Expression* val, Location);
// Make a selector. This is a parser expression which represents // Make a selector. This is a parser expression which represents
// LEFT.NAME. At parse time we may not know the type of the left // LEFT.NAME. At parse time we may not know the type of the left
// hand side. // hand side.
static Expression* static Expression*
make_selector(Expression* left, const std::string& name, source_location); make_selector(Expression* left, const std::string& name, Location);
// Make a reference to a field in a struct. // Make a reference to a field in a struct.
static Field_reference_expression* static Field_reference_expression*
make_field_reference(Expression*, unsigned int field_index, source_location); make_field_reference(Expression*, unsigned int field_index, Location);
// Make a reference to a field of an interface, with an associated // Make a reference to a field of an interface, with an associated
// object. // object.
static Expression* static Expression*
make_interface_field_reference(Expression*, const std::string&, make_interface_field_reference(Expression*, const std::string&,
source_location); Location);
// Make an allocation expression. // Make an allocation expression.
static Expression* static Expression*
make_allocation(Type*, source_location); make_allocation(Type*, Location);
// Make a type guard expression. // Make a type guard expression.
static Expression* static Expression*
make_type_guard(Expression*, Type*, source_location); make_type_guard(Expression*, Type*, Location);
// Make a type cast expression. // Make a type cast expression.
static Expression* static Expression*
make_cast(Type*, Expression*, source_location); make_cast(Type*, Expression*, Location);
// Make an unsafe type cast expression. This is only used when // Make an unsafe type cast expression. This is only used when
// passing parameter to builtin functions that are part of the Go // passing parameter to builtin functions that are part of the Go
// runtime. // runtime.
static Expression* static Expression*
make_unsafe_cast(Type*, Expression*, source_location); make_unsafe_cast(Type*, Expression*, Location);
// Make a composite literal. The DEPTH parameter is how far down we // Make a composite literal. The DEPTH parameter is how far down we
// are in a list of composite literals with omitted types. // are in a list of composite literals with omitted types.
static Expression* static Expression*
make_composite_literal(Type*, int depth, bool has_keys, Expression_list*, make_composite_literal(Type*, int depth, bool has_keys, Expression_list*,
source_location); Location);
// Make a struct composite literal. // Make a struct composite literal.
static Expression* static Expression*
make_struct_composite_literal(Type*, Expression_list*, source_location); make_struct_composite_literal(Type*, Expression_list*, Location);
// Make a slice composite literal. // Make a slice composite literal.
static Expression* static Expression*
make_slice_composite_literal(Type*, Expression_list*, source_location); make_slice_composite_literal(Type*, Expression_list*, Location);
// Take a composite literal and allocate it on the heap. // Take a composite literal and allocate it on the heap.
static Expression* static Expression*
make_heap_composite(Expression*, source_location); make_heap_composite(Expression*, Location);
// Make a receive expression. VAL is NULL for a unary receive. // Make a receive expression. VAL is NULL for a unary receive.
static Receive_expression* static Receive_expression*
make_receive(Expression* channel, source_location); make_receive(Expression* channel, Location);
// Make an expression which evaluates to the address of the type // Make an expression which evaluates to the address of the type
// descriptor for TYPE. // descriptor for TYPE.
static Expression* static Expression*
make_type_descriptor(Type* type, source_location); make_type_descriptor(Type* type, Location);
// Make an expression which evaluates to some characteristic of a // Make an expression which evaluates to some characteristic of a
// type. These are only used for type descriptors, so there is no // type. These are only used for type descriptors, so there is no
@ -306,12 +306,12 @@ class Expression
// Make an expression which evaluates to the address of the map // Make an expression which evaluates to the address of the map
// descriptor for TYPE. // descriptor for TYPE.
static Expression* static Expression*
make_map_descriptor(Map_type* type, source_location); make_map_descriptor(Map_type* type, Location);
// Make an expression which evaluates to the address of an unnamed // Make an expression which evaluates to the address of an unnamed
// label. // label.
static Expression* static Expression*
make_label_addr(Label*, source_location); make_label_addr(Label*, Location);
// Return the expression classification. // Return the expression classification.
Expression_classification Expression_classification
@ -319,7 +319,7 @@ class Expression
{ return this->classification_; } { return this->classification_; }
// Return the location of the expression. // Return the location of the expression.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -602,7 +602,7 @@ class Expression
// assignment. // assignment.
static tree static tree
convert_for_assignment(Translate_context*, Type* lhs_type, Type* rhs_type, convert_for_assignment(Translate_context*, Type* lhs_type, Type* rhs_type,
tree rhs_tree, source_location location); tree rhs_tree, Location location);
// Return a tree converting a value of one interface type to another // Return a tree converting a value of one interface type to another
// interface type. If FOR_TYPE_GUARD is true this is for a type // interface type. If FOR_TYPE_GUARD is true this is for a type
@ -610,14 +610,14 @@ class Expression
static tree static tree
convert_interface_to_interface(Translate_context*, Type* lhs_type, convert_interface_to_interface(Translate_context*, Type* lhs_type,
Type* rhs_type, tree rhs_tree, Type* rhs_type, tree rhs_tree,
bool for_type_guard, source_location); bool for_type_guard, Location);
// Return a tree implementing the comparison LHS_TREE OP RHS_TREE. // Return a tree implementing the comparison LHS_TREE OP RHS_TREE.
// TYPE is the type of both sides. // TYPE is the type of both sides.
static tree static tree
comparison_tree(Translate_context*, Operator op, Type* left_type, comparison_tree(Translate_context*, Operator op, Type* left_type,
tree left_tree, Type* right_type, tree right_tree, tree left_tree, Type* right_type, tree right_tree,
source_location); Location);
// Return a tree for the multi-precision integer VAL in TYPE. // Return a tree for the multi-precision integer VAL in TYPE.
static tree static tree
@ -647,7 +647,7 @@ class Expression
// BOUND_TYPE. If SOFAR is not NULL, it is or'red into the result. // BOUND_TYPE. If SOFAR is not NULL, it is or'red into the result.
// The return value may be NULL if SOFAR is NULL. // The return value may be NULL if SOFAR is NULL.
static tree static tree
check_bounds(tree val, tree bound_type, tree sofar, source_location); check_bounds(tree val, tree bound_type, tree sofar, Location);
// Dump an expression to a dump constext. // Dump an expression to a dump constext.
void void
@ -785,20 +785,20 @@ class Expression
static tree static tree
convert_type_to_interface(Translate_context*, Type*, Type*, tree, convert_type_to_interface(Translate_context*, Type*, Type*, tree,
source_location); Location);
static tree static tree
get_interface_type_descriptor(Translate_context*, Type*, tree, get_interface_type_descriptor(Translate_context*, Type*, tree,
source_location); Location);
static tree static tree
convert_interface_to_type(Translate_context*, Type*, Type*, tree, convert_interface_to_type(Translate_context*, Type*, Type*, tree,
source_location); Location);
// The expression classification. // The expression classification.
Expression_classification classification_; Expression_classification classification_;
// The location in the input file. // The location in the input file.
source_location location_; Location location_;
}; };
// A list of Expressions. // A list of Expressions.
@ -900,7 +900,7 @@ class Parser_expression : public Expression
{ {
public: public:
Parser_expression(Expression_classification classification, Parser_expression(Expression_classification classification,
source_location location) Location location)
: Expression(classification, location) : Expression(classification, location)
{ } { }
@ -929,7 +929,7 @@ class Parser_expression : public Expression
class Var_expression : public Expression class Var_expression : public Expression
{ {
public: public:
Var_expression(Named_object* variable, source_location location) Var_expression(Named_object* variable, Location location)
: Expression(EXPRESSION_VAR_REFERENCE, location), : Expression(EXPRESSION_VAR_REFERENCE, location),
variable_(variable) variable_(variable)
{ } { }
@ -977,7 +977,7 @@ class Temporary_reference_expression : public Expression
{ {
public: public:
Temporary_reference_expression(Temporary_statement* statement, Temporary_reference_expression(Temporary_statement* statement,
source_location location) Location location)
: Expression(EXPRESSION_TEMPORARY_REFERENCE, location), : Expression(EXPRESSION_TEMPORARY_REFERENCE, location),
statement_(statement), is_lvalue_(false) statement_(statement), is_lvalue_(false)
{ } { }
@ -1026,7 +1026,7 @@ class Temporary_reference_expression : public Expression
class String_expression : public Expression class String_expression : public Expression
{ {
public: public:
String_expression(const std::string& val, source_location location) String_expression(const std::string& val, Location location)
: Expression(EXPRESSION_STRING, location), : Expression(EXPRESSION_STRING, location),
val_(val), type_(NULL) val_(val), type_(NULL)
{ } { }
@ -1086,7 +1086,7 @@ class Binary_expression : public Expression
{ {
public: public:
Binary_expression(Operator op, Expression* left, Expression* right, Binary_expression(Operator op, Expression* left, Expression* right,
source_location location) Location location)
: Expression(EXPRESSION_BINARY, location), : Expression(EXPRESSION_BINARY, location),
op_(op), left_(left), right_(right) op_(op), left_(left), right_(right)
{ } { }
@ -1112,7 +1112,7 @@ class Binary_expression : public Expression
// if this could be done, false if not. // if this could be done, false if not.
static bool static bool
eval_integer(Operator op, Type* left_type, mpz_t left_val, eval_integer(Operator op, Type* left_type, mpz_t left_val,
Type* right_type, mpz_t right_val, source_location, Type* right_type, mpz_t right_val, Location,
mpz_t val); mpz_t val);
// Apply binary opcode OP to LEFT_VAL and RIGHT_VAL, setting VAL. // Apply binary opcode OP to LEFT_VAL and RIGHT_VAL, setting VAL.
@ -1120,7 +1120,7 @@ class Binary_expression : public Expression
static bool static bool
eval_float(Operator op, Type* left_type, mpfr_t left_val, eval_float(Operator op, Type* left_type, mpfr_t left_val,
Type* right_type, mpfr_t right_val, mpfr_t val, Type* right_type, mpfr_t right_val, mpfr_t val,
source_location); Location);
// Apply binary opcode OP to LEFT_REAL/LEFT_IMAG and // Apply binary opcode OP to LEFT_REAL/LEFT_IMAG and
// RIGHT_REAL/RIGHT_IMAG, setting REAL/IMAG. Return true if this // RIGHT_REAL/RIGHT_IMAG, setting REAL/IMAG. Return true if this
@ -1128,7 +1128,7 @@ class Binary_expression : public Expression
static bool static bool
eval_complex(Operator op, Type* left_type, mpfr_t left_real, eval_complex(Operator op, Type* left_type, mpfr_t left_real,
mpfr_t left_imag, Type* right_type, mpfr_t right_real, mpfr_t left_imag, Type* right_type, mpfr_t right_real,
mpfr_t right_imag, mpfr_t real, mpfr_t imag, source_location); mpfr_t right_imag, mpfr_t real, mpfr_t imag, Location);
// Compare integer constants according to OP. // Compare integer constants according to OP.
static bool static bool
@ -1149,7 +1149,7 @@ class Binary_expression : public Expression
// Report an error if OP can not be applied to TYPE. Return whether // Report an error if OP can not be applied to TYPE. Return whether
// it can. // it can.
static bool static bool
check_operator_type(Operator op, Type* type, source_location); check_operator_type(Operator op, Type* type, Location);
protected: protected:
int int
@ -1214,7 +1214,7 @@ class Call_expression : public Expression
{ {
public: public:
Call_expression(Expression* fn, Expression_list* args, bool is_varargs, Call_expression(Expression* fn, Expression_list* args, bool is_varargs,
source_location location) Location location)
: Expression(EXPRESSION_CALL, location), : Expression(EXPRESSION_CALL, location),
fn_(fn), args_(args), type_(NULL), results_(NULL), tree_(NULL), fn_(fn), args_(args), type_(NULL), results_(NULL), tree_(NULL),
is_varargs_(is_varargs), are_hidden_fields_ok_(false), is_varargs_(is_varargs), are_hidden_fields_ok_(false),
@ -1352,7 +1352,7 @@ class Call_expression : public Expression
private: private:
bool bool
check_argument_type(int, const Type*, const Type*, source_location, bool); check_argument_type(int, const Type*, const Type*, Location, bool);
tree tree
interface_method_function(Translate_context*, interface_method_function(Translate_context*,
@ -1397,7 +1397,7 @@ class Func_expression : public Expression
{ {
public: public:
Func_expression(Named_object* function, Expression* closure, Func_expression(Named_object* function, Expression* closure,
source_location location) Location location)
: Expression(EXPRESSION_FUNC_REFERENCE, location), : Expression(EXPRESSION_FUNC_REFERENCE, location),
function_(function), closure_(closure) function_(function), closure_(closure)
{ } { }
@ -1461,7 +1461,7 @@ class Func_expression : public Expression
class Unknown_expression : public Parser_expression class Unknown_expression : public Parser_expression
{ {
public: public:
Unknown_expression(Named_object* named_object, source_location location) Unknown_expression(Named_object* named_object, Location location)
: Parser_expression(EXPRESSION_UNKNOWN_REFERENCE, location), : Parser_expression(EXPRESSION_UNKNOWN_REFERENCE, location),
named_object_(named_object), is_composite_literal_key_(false) named_object_(named_object), is_composite_literal_key_(false)
{ } { }
@ -1512,7 +1512,7 @@ class Index_expression : public Parser_expression
{ {
public: public:
Index_expression(Expression* left, Expression* start, Expression* end, Index_expression(Expression* left, Expression* start, Expression* end,
source_location location) Location location)
: Parser_expression(EXPRESSION_INDEX, location), : Parser_expression(EXPRESSION_INDEX, location),
left_(left), start_(start), end_(end), is_lvalue_(false) left_(left), start_(start), end_(end), is_lvalue_(false)
{ } { }
@ -1574,7 +1574,7 @@ class Map_index_expression : public Expression
{ {
public: public:
Map_index_expression(Expression* map, Expression* index, Map_index_expression(Expression* map, Expression* index,
source_location location) Location location)
: Expression(EXPRESSION_MAP_INDEX, location), : Expression(EXPRESSION_MAP_INDEX, location),
map_(map), index_(index), is_lvalue_(false), map_(map), index_(index), is_lvalue_(false),
is_in_tuple_assignment_(false) is_in_tuple_assignment_(false)
@ -1682,7 +1682,7 @@ class Bound_method_expression : public Expression
{ {
public: public:
Bound_method_expression(Expression* expr, Named_object* method, Bound_method_expression(Expression* expr, Named_object* method,
source_location location) Location location)
: Expression(EXPRESSION_BOUND_METHOD, location), : Expression(EXPRESSION_BOUND_METHOD, location),
expr_(expr), expr_type_(NULL), method_(method) expr_(expr), expr_type_(NULL), method_(method)
{ } { }
@ -1753,7 +1753,7 @@ class Field_reference_expression : public Expression
{ {
public: public:
Field_reference_expression(Expression* expr, unsigned int field_index, Field_reference_expression(Expression* expr, unsigned int field_index,
source_location location) Location location)
: Expression(EXPRESSION_FIELD_REFERENCE, location), : Expression(EXPRESSION_FIELD_REFERENCE, location),
expr_(expr), field_index_(field_index) expr_(expr), field_index_(field_index)
{ } { }
@ -1824,7 +1824,7 @@ class Interface_field_reference_expression : public Expression
public: public:
Interface_field_reference_expression(Expression* expr, Interface_field_reference_expression(Expression* expr,
const std::string& name, const std::string& name,
source_location location) Location location)
: Expression(EXPRESSION_INTERFACE_FIELD_REFERENCE, location), : Expression(EXPRESSION_INTERFACE_FIELD_REFERENCE, location),
expr_(expr), name_(name) expr_(expr), name_(name)
{ } { }
@ -1890,7 +1890,7 @@ class Interface_field_reference_expression : public Expression
class Type_guard_expression : public Expression class Type_guard_expression : public Expression
{ {
public: public:
Type_guard_expression(Expression* expr, Type* type, source_location location) Type_guard_expression(Expression* expr, Type* type, Location location)
: Expression(EXPRESSION_TYPE_GUARD, location), : Expression(EXPRESSION_TYPE_GUARD, location),
expr_(expr), type_(type) expr_(expr), type_(type)
{ } { }
@ -1945,7 +1945,7 @@ class Type_guard_expression : public Expression
class Receive_expression : public Expression class Receive_expression : public Expression
{ {
public: public:
Receive_expression(Expression* channel, source_location location) Receive_expression(Expression* channel, Location location)
: Expression(EXPRESSION_RECEIVE, location), : Expression(EXPRESSION_RECEIVE, location),
channel_(channel), for_select_(false) channel_(channel), for_select_(false)
{ } { }

View File

@ -0,0 +1,131 @@
// go-linemap.h -- interface to location tracking -*- C++ -*-
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#ifndef GO_LINEMAP_H
#define GO_LINEMAP_H
#include "go-system.h"
// The backend must define a type named Location which holds
// information about a location in a source file. The only thing the
// frontend does with instances of Location is pass them back to the
// backend interface. The Location type must be assignable, and it
// must be comparable: i.e., it must support operator= and operator<.
// The type is normally passed by value rather than by reference, and
// it should support that efficiently. The type should be defined in
// "go-location.h".
#include "go-location.h"
// The Linemap class is a pure abstract interface, plus some static
// convenience functions. The backend must implement the interface.
class Linemap
{
public:
Linemap()
{
// Only one instance of Linemap is allowed to exist.
go_assert(Linemap::instance_ == NULL);
Linemap::instance_ = this;
}
virtual
~Linemap() { Linemap::instance_ = NULL; }
// Subsequent Location values will come from the file named
// FILE_NAME, starting at LINE_BEGIN. Normally LINE_BEGIN will be
// 0, but it will be non-zero if the Go source has a //line comment.
virtual void
start_file(const char* file_name, unsigned int line_begin) = 0;
// Subsequent Location values will come from the line LINE_NUMBER,
// in the current file. LINE_SIZE is the size of the line in bytes.
// This will normally be called for every line in a source file.
virtual void
start_line(unsigned int line_number, unsigned int line_size) = 0;
// Get a Location representing column position COLUMN on the current
// line in the current file.
virtual Location
get_location(unsigned int column) = 0;
// Stop generating Location values. This will be called after all
// input files have been read, in case any cleanup is required.
virtual void
stop() = 0;
protected:
// Return a special Location used for predeclared identifiers. This
// Location should be different from that for any actual source
// file. This location will be used for various different types,
// functions, and objects created by the frontend.
virtual Location
get_predeclared_location() = 0;
// Return a special Location which indicates that no actual location
// is known. This is used for undefined objects and for errors.
virtual Location
get_unknown_location() = 0;
// Return whether the argument is the Location returned by
// get_predeclared_location.
virtual bool
is_predeclared(Location) = 0;
// Return whether the argument is the Location returned by
// get_unknown_location.
virtual bool
is_unknown(Location) = 0;
// The single existing instance of Linemap.
static Linemap *instance_;
public:
// Following are convenience static functions, which allow us to
// access some virtual functions without explicitly passing around
// an instance of Linemap.
// Return the special Location used for predeclared identifiers.
static Location
predeclared_location()
{
go_assert(Linemap::instance_ != NULL);
return Linemap::instance_->get_predeclared_location();
}
// Return the special Location used when no location is known.
static Location
unknown_location()
{
go_assert(Linemap::instance_ != NULL);
return Linemap::instance_->get_unknown_location();
}
// Return whether the argument is the special location used for
// predeclared identifiers.
static bool
is_predeclared_location(Location loc)
{
go_assert(Linemap::instance_ != NULL);
return Linemap::instance_->is_predeclared(loc);
}
// Return whether the argument is the special location used when no
// location is known.
static bool
is_unknown_location(Location loc)
{
go_assert(Linemap::instance_ != NULL);
return Linemap::instance_->is_unknown(loc);
}
};
// The backend interface must define this function. It should return
// a fully implemented instance of Linemap.
extern Linemap* go_get_linemap();
#endif // !defined(GO_LINEMAP_H)

View File

@ -28,7 +28,8 @@ void
go_create_gogo(int int_type_size, int pointer_size) go_create_gogo(int int_type_size, int pointer_size)
{ {
go_assert(::gogo == NULL); go_assert(::gogo == NULL);
::gogo = new Gogo(go_get_backend(), int_type_size, pointer_size); Linemap* linemap = go_get_linemap();
::gogo = new Gogo(go_get_backend(), linemap, int_type_size, pointer_size);
if (!unique_prefix.empty()) if (!unique_prefix.empty())
::gogo->set_unique_prefix(unique_prefix); ::gogo->set_unique_prefix(unique_prefix);
@ -64,6 +65,7 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
bool only_check_syntax, bool require_return_statement) bool only_check_syntax, bool require_return_statement)
{ {
go_assert(filename_count > 0); go_assert(filename_count > 0);
for (unsigned int i = 0; i < filename_count; ++i) for (unsigned int i = 0; i < filename_count; ++i)
{ {
if (i > 0) if (i > 0)
@ -80,7 +82,7 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
fatal_error("cannot open %s: %m", filename); fatal_error("cannot open %s: %m", filename);
} }
Lex lexer(filename, file); Lex lexer(filename, file, ::gogo->linemap());
Parse parse(&lexer, ::gogo); Parse parse(&lexer, ::gogo);
parse.program(); parse.program();
@ -89,6 +91,8 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
fclose(file); fclose(file);
} }
::gogo->linemap()->stop();
::gogo->clear_file_scope(); ::gogo->clear_file_scope();
// If the global predeclared names are referenced but not defined, // If the global predeclared names are referenced but not defined,

View File

@ -336,8 +336,9 @@ Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc,
rest_of_decl_compilation(decl, 1, 0); rest_of_decl_compilation(decl, 1, 0);
static tree register_gc_fndecl; static tree register_gc_fndecl;
tree call = Gogo::call_builtin(&register_gc_fndecl, BUILTINS_LOCATION, tree call = Gogo::call_builtin(&register_gc_fndecl,
"__go_register_gc_roots", Linemap::predeclared_location(),
"__go_register_gc_roots",
1, 1,
void_type_node, void_type_node,
build_pointer_type(root_list_type), build_pointer_type(root_list_type),
@ -746,8 +747,9 @@ Gogo::write_globals()
else if (is_sink) else if (is_sink)
var_init_tree = init; var_init_tree = init;
else else
var_init_tree = fold_build2_loc(no->location(), MODIFY_EXPR, var_init_tree = fold_build2_loc(no->location().gcc_location(),
void_type_node, vec[i], init); MODIFY_EXPR, void_type_node,
vec[i], init);
} }
else else
{ {
@ -843,7 +845,7 @@ Named_object::get_id(Gogo* gogo)
&& !this->func_declaration_value()->asm_name().empty()) && !this->func_declaration_value()->asm_name().empty())
decl_name = this->func_declaration_value()->asm_name(); decl_name = this->func_declaration_value()->asm_name();
else if (this->is_type() else if (this->is_type()
&& this->type_value()->location() == BUILTINS_LOCATION) && Linemap::is_predeclared_location(this->type_value()->location()))
{ {
// We don't need the package name for builtin types. // We don't need the package name for builtin types.
decl_name = Gogo::unpack_hidden_name(this->name_); decl_name = Gogo::unpack_hidden_name(this->name_);
@ -920,8 +922,8 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
decl = error_mark_node; decl = error_mark_node;
else if (INTEGRAL_TYPE_P(TREE_TYPE(expr_tree))) else if (INTEGRAL_TYPE_P(TREE_TYPE(expr_tree)))
{ {
decl = build_decl(named_constant->location(), CONST_DECL, decl = build_decl(named_constant->location().gcc_location(),
name, TREE_TYPE(expr_tree)); CONST_DECL, name, TREE_TYPE(expr_tree));
DECL_INITIAL(decl) = expr_tree; DECL_INITIAL(decl) = expr_tree;
TREE_CONSTANT(decl) = 1; TREE_CONSTANT(decl) = 1;
TREE_READONLY(decl) = 1; TREE_READONLY(decl) = 1;
@ -958,9 +960,12 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
// descriptor, even though we don't do anything with it. // descriptor, even though we don't do anything with it.
if (this->package_ == NULL) if (this->package_ == NULL)
{ {
named_type->type_descriptor_pointer(gogo, BUILTINS_LOCATION); named_type->
type_descriptor_pointer(gogo,
Linemap::predeclared_location());
Type* pn = Type::make_pointer_type(named_type); Type* pn = Type::make_pointer_type(named_type);
pn->type_descriptor_pointer(gogo, BUILTINS_LOCATION); pn->type_descriptor_pointer(gogo,
Linemap::predeclared_location());
} }
} }
} }
@ -989,7 +994,8 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
else else
push_cfun(DECL_STRUCT_FUNCTION(decl)); push_cfun(DECL_STRUCT_FUNCTION(decl));
cfun->function_end_locus = func->block()->end_location(); cfun->function_end_locus =
func->block()->end_location().gcc_location();
current_function_decl = decl; current_function_decl = decl;
@ -1091,8 +1097,9 @@ Variable::get_init_block(Gogo* gogo, Named_object* function, tree var_decl)
this->location()); this->location());
if (val == error_mark_node) if (val == error_mark_node)
return error_mark_node; return error_mark_node;
tree set = fold_build2_loc(this->location(), MODIFY_EXPR, tree set = fold_build2_loc(this->location().gcc_location(),
void_type_node, var_decl, val); MODIFY_EXPR, void_type_node, var_decl,
val);
append_to_statement_list(set, &statements); append_to_statement_list(set, &statements);
} }
} }
@ -1116,7 +1123,8 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no, tree id)
// want the real function type for a function declaration. // want the real function type for a function declaration.
go_assert(POINTER_TYPE_P(functype)); go_assert(POINTER_TYPE_P(functype));
functype = TREE_TYPE(functype); functype = TREE_TYPE(functype);
tree decl = build_decl(this->location(), FUNCTION_DECL, id, functype); tree decl = build_decl(this->location().gcc_location(), FUNCTION_DECL,
id, functype);
this->fndecl_ = decl; this->fndecl_ = decl;
@ -1146,8 +1154,9 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no, tree id)
// Why do we have to do this in the frontend? // Why do we have to do this in the frontend?
tree restype = TREE_TYPE(functype); tree restype = TREE_TYPE(functype);
tree resdecl = build_decl(this->location(), RESULT_DECL, NULL_TREE, tree resdecl =
restype); build_decl(this->location().gcc_location(), RESULT_DECL, NULL_TREE,
restype);
DECL_ARTIFICIAL(resdecl) = 1; DECL_ARTIFICIAL(resdecl) = 1;
DECL_IGNORED_P(resdecl) = 1; DECL_IGNORED_P(resdecl) = 1;
DECL_CONTEXT(resdecl) = decl; DECL_CONTEXT(resdecl) = decl;
@ -1233,7 +1242,8 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no, tree id)
// want the real function type for a function declaration. // want the real function type for a function declaration.
go_assert(POINTER_TYPE_P(functype)); go_assert(POINTER_TYPE_P(functype));
functype = TREE_TYPE(functype); functype = TREE_TYPE(functype);
decl = build_decl(this->location(), FUNCTION_DECL, id, functype); decl = build_decl(this->location().gcc_location(), FUNCTION_DECL, id,
functype);
TREE_PUBLIC(decl) = 1; TREE_PUBLIC(decl) = 1;
DECL_EXTERNAL(decl) = 1; DECL_EXTERNAL(decl) = 1;
@ -1292,7 +1302,8 @@ Function::make_receiver_parm_decl(Gogo* gogo, Named_object* no, tree var_decl)
no->location()); no->location());
space = save_expr(space); space = save_expr(space);
space = fold_convert(build_pointer_type(val_type), space); space = fold_convert(build_pointer_type(val_type), space);
tree spaceref = build_fold_indirect_ref_loc(no->location(), space); tree spaceref = build_fold_indirect_ref_loc(no->location().gcc_location(),
space);
TREE_THIS_NOTRAP(spaceref) = 1; TREE_THIS_NOTRAP(spaceref) = 1;
tree set = fold_build2_loc(loc, MODIFY_EXPR, void_type_node, tree set = fold_build2_loc(loc, MODIFY_EXPR, void_type_node,
spaceref, init); spaceref, init);
@ -1314,7 +1325,7 @@ Function::copy_parm_to_heap(Gogo* gogo, Named_object* no, tree var_decl)
if (var_decl == error_mark_node) if (var_decl == error_mark_node)
return error_mark_node; return error_mark_node;
go_assert(TREE_CODE(var_decl) == VAR_DECL); go_assert(TREE_CODE(var_decl) == VAR_DECL);
source_location loc = DECL_SOURCE_LOCATION(var_decl); Location loc(DECL_SOURCE_LOCATION(var_decl));
std::string name = IDENTIFIER_POINTER(DECL_NAME(var_decl)); std::string name = IDENTIFIER_POINTER(DECL_NAME(var_decl));
name += ".param"; name += ".param";
@ -1324,7 +1335,7 @@ Function::copy_parm_to_heap(Gogo* gogo, Named_object* no, tree var_decl)
go_assert(POINTER_TYPE_P(type)); go_assert(POINTER_TYPE_P(type));
type = TREE_TYPE(type); type = TREE_TYPE(type);
tree parm_decl = build_decl(loc, PARM_DECL, id, type); tree parm_decl = build_decl(loc.gcc_location(), PARM_DECL, id, type);
DECL_CONTEXT(parm_decl) = current_function_decl; DECL_CONTEXT(parm_decl) = current_function_decl;
DECL_ARG_TYPE(parm_decl) = type; DECL_ARG_TYPE(parm_decl) = type;
@ -1332,7 +1343,7 @@ Function::copy_parm_to_heap(Gogo* gogo, Named_object* no, tree var_decl)
tree space = gogo->allocate_memory(no->var_value()->type(), size, loc); tree space = gogo->allocate_memory(no->var_value()->type(), size, loc);
space = save_expr(space); space = save_expr(space);
space = fold_convert(TREE_TYPE(var_decl), space); space = fold_convert(TREE_TYPE(var_decl), space);
tree spaceref = build_fold_indirect_ref_loc(loc, space); tree spaceref = build_fold_indirect_ref_loc(loc.gcc_location(), space);
TREE_THIS_NOTRAP(spaceref) = 1; TREE_THIS_NOTRAP(spaceref) = 1;
tree init = build2(COMPOUND_EXPR, TREE_TYPE(space), tree init = build2(COMPOUND_EXPR, TREE_TYPE(space),
build2(MODIFY_EXPR, void_type_node, spaceref, parm_decl), build2(MODIFY_EXPR, void_type_node, spaceref, parm_decl),
@ -1415,13 +1426,13 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
} }
else else
{ {
source_location loc = (*p)->location(); Location loc = (*p)->location();
tree type_tree = type_to_tree(type->get_backend(gogo)); tree type_tree = type_to_tree(type->get_backend(gogo));
tree space = gogo->allocate_memory(type, tree space = gogo->allocate_memory(type,
TYPE_SIZE_UNIT(type_tree), TYPE_SIZE_UNIT(type_tree),
loc); loc);
tree ptr_type_tree = build_pointer_type(type_tree); tree ptr_type_tree = build_pointer_type(type_tree);
init = fold_convert_loc(loc, ptr_type_tree, space); init = fold_convert_loc(loc.gcc_location(), ptr_type_tree, space);
} }
if (var_decl != error_mark_node) if (var_decl != error_mark_node)
@ -1486,7 +1497,8 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
// function. // function.
if (defer_init != NULL_TREE && defer_init != error_mark_node) if (defer_init != NULL_TREE && defer_init != error_mark_node)
{ {
SET_EXPR_LOCATION(defer_init, this->block_->start_location()); SET_EXPR_LOCATION(defer_init,
this->block_->start_location().gcc_location());
append_to_statement_list(defer_init, &init); append_to_statement_list(defer_init, &init);
// Clean up the defer stack when we leave the function. // Clean up the defer stack when we leave the function.
@ -1524,7 +1536,7 @@ void
Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function, Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
tree *except, tree *fini) tree *except, tree *fini)
{ {
source_location end_loc = this->block_->end_location(); Location end_loc = this->block_->end_location();
// Add an exception handler. This is used if a panic occurs. Its // Add an exception handler. This is used if a panic occurs. Its
// purpose is to stop the stack unwinding if a deferred function // purpose is to stop the stack unwinding if a deferred function
@ -1545,9 +1557,10 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
if (retval == NULL_TREE) if (retval == NULL_TREE)
set = NULL_TREE; set = NULL_TREE;
else else
set = fold_build2_loc(end_loc, MODIFY_EXPR, void_type_node, set = fold_build2_loc(end_loc.gcc_location(), MODIFY_EXPR, void_type_node,
DECL_RESULT(this->fndecl_), retval); DECL_RESULT(this->fndecl_), retval);
tree ret_stmt = fold_build1_loc(end_loc, RETURN_EXPR, void_type_node, set); tree ret_stmt = fold_build1_loc(end_loc.gcc_location(), RETURN_EXPR,
void_type_node, set);
append_to_statement_list(ret_stmt, &stmt_list); append_to_statement_list(ret_stmt, &stmt_list);
go_assert(*except == NULL_TREE); go_assert(*except == NULL_TREE);
@ -1564,9 +1577,9 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
stmt_list = NULL; stmt_list = NULL;
tree label = create_artificial_label(end_loc); tree label = create_artificial_label(end_loc.gcc_location());
tree define_label = fold_build1_loc(end_loc, LABEL_EXPR, void_type_node, tree define_label = fold_build1_loc(end_loc.gcc_location(), LABEL_EXPR,
label); void_type_node, label);
append_to_statement_list(define_label, &stmt_list); append_to_statement_list(define_label, &stmt_list);
call = Runtime::make_call(Runtime::UNDEFER, end_loc, 1, call = Runtime::make_call(Runtime::UNDEFER, end_loc, 1,
@ -1580,7 +1593,8 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
if (undefer == error_mark_node || defer == error_mark_node) if (undefer == error_mark_node || defer == error_mark_node)
return; return;
tree jump = fold_build1_loc(end_loc, GOTO_EXPR, void_type_node, label); tree jump = fold_build1_loc(end_loc.gcc_location(), GOTO_EXPR, void_type_node,
label);
tree catch_body = build2(COMPOUND_EXPR, void_type_node, defer, jump); tree catch_body = build2(COMPOUND_EXPR, void_type_node, defer, jump);
catch_body = build2(CATCH_EXPR, void_type_node, NULL, catch_body); catch_body = build2(CATCH_EXPR, void_type_node, NULL, catch_body);
tree try_catch = build2(TRY_CATCH_EXPR, void_type_node, undefer, catch_body); tree try_catch = build2(TRY_CATCH_EXPR, void_type_node, undefer, catch_body);
@ -1598,15 +1612,16 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
// variable to true if we are returning from this function. // variable to true if we are returning from this function.
retval = this->return_value(gogo, named_function, end_loc, retval = this->return_value(gogo, named_function, end_loc,
&stmt_list); &stmt_list);
set = fold_build2_loc(end_loc, MODIFY_EXPR, void_type_node, set = fold_build2_loc(end_loc.gcc_location(), MODIFY_EXPR, void_type_node,
DECL_RESULT(this->fndecl_), retval); DECL_RESULT(this->fndecl_), retval);
ret_stmt = fold_build1_loc(end_loc, RETURN_EXPR, void_type_node, set); ret_stmt = fold_build1_loc(end_loc.gcc_location(), RETURN_EXPR,
void_type_node, set);
Expression* ref = Expression* ref =
Expression::make_temporary_reference(this->defer_stack_, end_loc); Expression::make_temporary_reference(this->defer_stack_, end_loc);
tree tref = ref->get_tree(&context); tree tref = ref->get_tree(&context);
tree s = build3_loc(end_loc, COND_EXPR, void_type_node, tref, tree s = build3_loc(end_loc.gcc_location(), COND_EXPR, void_type_node,
ret_stmt, NULL_TREE); tref, ret_stmt, NULL_TREE);
append_to_statement_list(s, &stmt_list); append_to_statement_list(s, &stmt_list);
@ -1623,7 +1638,7 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
tree tree
Function::return_value(Gogo* gogo, Named_object* named_function, Function::return_value(Gogo* gogo, Named_object* named_function,
source_location location, tree* stmt_list) const Location location, tree* stmt_list) const
{ {
const Typed_identifier_list* results = this->type_->results(); const Typed_identifier_list* results = this->type_->results();
if (results == NULL || results->empty()) if (results == NULL || results->empty())
@ -1644,7 +1659,7 @@ Function::return_value(Gogo* gogo, Named_object* named_function,
named_function); named_function);
tree ret = var_to_tree(bvar); tree ret = var_to_tree(bvar);
if (this->results_->front()->result_var_value()->is_in_heap()) if (this->results_->front()->result_var_value()->is_in_heap())
ret = build_fold_indirect_ref_loc(location, ret); ret = build_fold_indirect_ref_loc(location.gcc_location(), ret);
return ret; return ret;
} }
else else
@ -1662,8 +1677,9 @@ Function::return_value(Gogo* gogo, Named_object* named_function,
Bvariable* bvar = no->get_backend_variable(gogo, named_function); Bvariable* bvar = no->get_backend_variable(gogo, named_function);
tree val = var_to_tree(bvar); tree val = var_to_tree(bvar);
if (no->result_var_value()->is_in_heap()) if (no->result_var_value()->is_in_heap())
val = build_fold_indirect_ref_loc(location, val); val = build_fold_indirect_ref_loc(location.gcc_location(), val);
tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node, tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
void_type_node,
build3(COMPONENT_REF, TREE_TYPE(field), build3(COMPONENT_REF, TREE_TYPE(field),
retval, field, NULL_TREE), retval, field, NULL_TREE),
val); val);
@ -1762,7 +1778,7 @@ go_type_for_mode(enum machine_mode mode, int unsignedp)
// type TYPE. // type TYPE.
tree tree
Gogo::allocate_memory(Type* type, tree size, source_location location) Gogo::allocate_memory(Type* type, tree size, Location location)
{ {
// If the package imports unsafe, then it may play games with // If the package imports unsafe, then it may play games with
// pointers that look like integers. // pointers that look like integers.
@ -2028,7 +2044,8 @@ Gogo::interface_method_table_for_type(const Interface_type* interface,
td_type = type; td_type = type;
else else
td_type = Type::make_pointer_type(type); td_type = Type::make_pointer_type(type);
tree tdp = td_type->type_descriptor_pointer(this, BUILTINS_LOCATION); tree tdp = td_type->type_descriptor_pointer(this,
Linemap::predeclared_location());
elt->value = fold_convert(const_ptr_type_node, tdp); elt->value = fold_convert(const_ptr_type_node, tdp);
size_t i = 1; size_t i = 1;
@ -2105,7 +2122,7 @@ Gogo::mark_fndecl_as_builtin_library(tree fndecl)
// Build a call to a builtin function. // Build a call to a builtin function.
tree tree
Gogo::call_builtin(tree* pdecl, source_location location, const char* name, Gogo::call_builtin(tree* pdecl, Location location, const char* name,
int nargs, tree rettype, ...) int nargs, tree rettype, ...)
{ {
if (rettype == error_mark_node) if (rettype == error_mark_node)
@ -2151,10 +2168,10 @@ Gogo::call_builtin(tree* pdecl, source_location location, const char* name,
tree fnptr = build_fold_addr_expr(*pdecl); tree fnptr = build_fold_addr_expr(*pdecl);
if (CAN_HAVE_LOCATION_P(fnptr)) if (CAN_HAVE_LOCATION_P(fnptr))
SET_EXPR_LOCATION(fnptr, location); SET_EXPR_LOCATION(fnptr, location.gcc_location());
tree ret = build_call_array(rettype, fnptr, nargs, args); tree ret = build_call_array(rettype, fnptr, nargs, args);
SET_EXPR_LOCATION(ret, location); SET_EXPR_LOCATION(ret, location.gcc_location());
delete[] types; delete[] types;
delete[] args; delete[] args;
@ -2165,7 +2182,7 @@ Gogo::call_builtin(tree* pdecl, source_location location, const char* name,
// Build a call to the runtime error function. // Build a call to the runtime error function.
tree tree
Gogo::runtime_error(int code, source_location location) Gogo::runtime_error(int code, Location location)
{ {
static tree runtime_error_fndecl; static tree runtime_error_fndecl;
tree ret = Gogo::call_builtin(&runtime_error_fndecl, tree ret = Gogo::call_builtin(&runtime_error_fndecl,
@ -2190,7 +2207,7 @@ Gogo::runtime_error(int code, source_location location)
tree tree
Gogo::receive_from_channel(tree type_tree, tree channel, bool for_select, Gogo::receive_from_channel(tree type_tree, tree channel, bool for_select,
source_location location) Location location)
{ {
if (type_tree == error_mark_node || channel == error_mark_node) if (type_tree == error_mark_node || channel == error_mark_node)
return error_mark_node; return error_mark_node;
@ -2218,9 +2235,9 @@ Gogo::receive_from_channel(tree type_tree, tree channel, bool for_select,
TREE_NOTHROW(receive_small_fndecl) = 0; TREE_NOTHROW(receive_small_fndecl) = 0;
int bitsize = GET_MODE_BITSIZE(TYPE_MODE(type_tree)); int bitsize = GET_MODE_BITSIZE(TYPE_MODE(type_tree));
tree int_type_tree = go_type_for_size(bitsize, 1); tree int_type_tree = go_type_for_size(bitsize, 1);
return fold_convert_loc(location, type_tree, return fold_convert_loc(location.gcc_location(), type_tree,
fold_convert_loc(location, int_type_tree, fold_convert_loc(location.gcc_location(),
call)); int_type_tree, call));
} }
else else
{ {
@ -2228,7 +2245,7 @@ Gogo::receive_from_channel(tree type_tree, tree channel, bool for_select,
DECL_IGNORED_P(tmp) = 0; DECL_IGNORED_P(tmp) = 0;
TREE_ADDRESSABLE(tmp) = 1; TREE_ADDRESSABLE(tmp) = 1;
tree make_tmp = build1(DECL_EXPR, void_type_node, tmp); tree make_tmp = build1(DECL_EXPR, void_type_node, tmp);
SET_EXPR_LOCATION(make_tmp, location); SET_EXPR_LOCATION(make_tmp, location.gcc_location());
tree tmpaddr = build_fold_addr_expr(tmp); tree tmpaddr = build_fold_addr_expr(tmp);
tmpaddr = fold_convert(ptr_type_node, tmpaddr); tmpaddr = fold_convert(ptr_type_node, tmpaddr);
static tree receive_big_fndecl; static tree receive_big_fndecl;
@ -2284,7 +2301,7 @@ Gogo::trampoline_type_tree()
// Make a trampoline which calls FNADDR passing CLOSURE. // Make a trampoline which calls FNADDR passing CLOSURE.
tree tree
Gogo::make_trampoline(tree fnaddr, tree closure, source_location location) Gogo::make_trampoline(tree fnaddr, tree closure, Location location)
{ {
tree trampoline_type = Gogo::trampoline_type_tree(); tree trampoline_type = Gogo::trampoline_type_tree();
tree trampoline_size = TYPE_SIZE_UNIT(trampoline_type); tree trampoline_size = TYPE_SIZE_UNIT(trampoline_type);
@ -2302,8 +2319,8 @@ Gogo::make_trampoline(tree fnaddr, tree closure, source_location location)
size_type_node, size_type_node,
trampoline_size, trampoline_size,
ptr_type_node, ptr_type_node,
fold_convert_loc(location, ptr_type_node, fold_convert_loc(location.gcc_location(),
closure)); ptr_type_node, closure));
if (x == error_mark_node) if (x == error_mark_node)
return error_mark_node; return error_mark_node;

View File

@ -21,8 +21,10 @@
// Class Gogo. // Class Gogo.
Gogo::Gogo(Backend* backend, int int_type_size, int pointer_size) Gogo::Gogo(Backend* backend, Linemap* linemap, int int_type_size,
int pointer_size)
: backend_(backend), : backend_(backend),
linemap_(linemap),
package_(NULL), package_(NULL),
functions_(), functions_(),
globals_(new Bindings(NULL)), globals_(new Bindings(NULL)),
@ -38,7 +40,7 @@ Gogo::Gogo(Backend* backend, int int_type_size, int pointer_size)
interface_types_(), interface_types_(),
named_types_are_converted_(false) named_types_are_converted_(false)
{ {
const source_location loc = BUILTINS_LOCATION; const Location loc = Linemap::predeclared_location();
Named_type* uint8_type = Type::make_integer_type("uint8", true, 8, Named_type* uint8_type = Type::make_integer_type("uint8", true, 8,
RUNTIME_TYPE_KIND_UINT8); RUNTIME_TYPE_KIND_UINT8);
@ -245,7 +247,7 @@ Gogo::package_name() const
void void
Gogo::set_package_name(const std::string& package_name, Gogo::set_package_name(const std::string& package_name,
source_location location) Location location)
{ {
if (this->package_ != NULL && this->package_->name() != package_name) if (this->package_ != NULL && this->package_->name() != package_name)
{ {
@ -270,10 +272,10 @@ Gogo::set_package_name(const std::string& package_name,
{ {
// Declare "main" as a function which takes no parameters and // Declare "main" as a function which takes no parameters and
// returns no value. // returns no value.
Location uloc = Linemap::unknown_location();
this->declare_function("main", this->declare_function("main",
Type::make_function_type(NULL, NULL, NULL, Type::make_function_type (NULL, NULL, NULL, uloc),
BUILTINS_LOCATION), uloc);
BUILTINS_LOCATION);
} }
} }
@ -292,7 +294,7 @@ void
Gogo::import_package(const std::string& filename, Gogo::import_package(const std::string& filename,
const std::string& local_name, const std::string& local_name,
bool is_local_name_exported, bool is_local_name_exported,
source_location location) Location location)
{ {
if (filename == "unsafe") if (filename == "unsafe")
{ {
@ -502,7 +504,7 @@ Gogo::add_imported_package(const std::string& real_name,
const std::string& alias_arg, const std::string& alias_arg,
bool is_alias_exported, bool is_alias_exported,
const std::string& unique_prefix, const std::string& unique_prefix,
source_location location, Location location,
bool* padd_to_globals) bool* padd_to_globals)
{ {
// FIXME: Now that we compile packages as a whole, should we permit // FIXME: Now that we compile packages as a whole, should we permit
@ -552,7 +554,7 @@ Gogo::add_imported_package(const std::string& real_name,
Named_object* Named_object*
Gogo::add_package(const std::string& real_name, const std::string& alias, Gogo::add_package(const std::string& real_name, const std::string& alias,
const std::string& unique_prefix, source_location location) const std::string& unique_prefix, Location location)
{ {
go_assert(this->in_global_scope()); go_assert(this->in_global_scope());
@ -570,7 +572,7 @@ Gogo::add_package(const std::string& real_name, const std::string& alias,
Package* Package*
Gogo::register_package(const std::string& package_name, Gogo::register_package(const std::string& package_name,
const std::string& unique_prefix, const std::string& unique_prefix,
source_location location) Location location)
{ {
go_assert(!unique_prefix.empty() && !package_name.empty()); go_assert(!unique_prefix.empty() && !package_name.empty());
std::string name = unique_prefix + '.' + package_name; std::string name = unique_prefix + '.' + package_name;
@ -584,7 +586,7 @@ Gogo::register_package(const std::string& package_name,
go_assert(package != NULL); go_assert(package != NULL);
go_assert(package->name() == package_name go_assert(package->name() == package_name
&& package->unique_prefix() == unique_prefix); && package->unique_prefix() == unique_prefix);
if (package->location() == UNKNOWN_LOCATION) if (Linemap::is_unknown_location(package->location()))
package->set_location(location); package->set_location(location);
} }
else else
@ -602,7 +604,7 @@ Gogo::register_package(const std::string& package_name,
Named_object* Named_object*
Gogo::start_function(const std::string& name, Function_type* type, Gogo::start_function(const std::string& name, Function_type* type,
bool add_method_to_type, source_location location) bool add_method_to_type, Location location)
{ {
bool at_top_level = this->functions_.empty(); bool at_top_level = this->functions_.empty();
@ -787,7 +789,7 @@ Gogo::start_function(const std::string& name, Function_type* type,
// Finish compiling a function. // Finish compiling a function.
void void
Gogo::finish_function(source_location location) Gogo::finish_function(Location location)
{ {
this->finish_block(location); this->finish_block(location);
go_assert(this->functions_.back().blocks.empty()); go_assert(this->functions_.back().blocks.empty());
@ -806,7 +808,7 @@ Gogo::current_function() const
// Start a new block. // Start a new block.
void void
Gogo::start_block(source_location location) Gogo::start_block(Location location)
{ {
go_assert(!this->functions_.empty()); go_assert(!this->functions_.empty());
Block* block = new Block(this->current_block(), location); Block* block = new Block(this->current_block(), location);
@ -816,7 +818,7 @@ Gogo::start_block(source_location location)
// Finish a block. // Finish a block.
Block* Block*
Gogo::finish_block(source_location location) Gogo::finish_block(Location location)
{ {
go_assert(!this->functions_.empty()); go_assert(!this->functions_.empty());
go_assert(!this->functions_.back().blocks.empty()); go_assert(!this->functions_.back().blocks.empty());
@ -829,7 +831,7 @@ Gogo::finish_block(source_location location)
// Add an unknown name. // Add an unknown name.
Named_object* Named_object*
Gogo::add_unknown_name(const std::string& name, source_location location) Gogo::add_unknown_name(const std::string& name, Location location)
{ {
return this->package_->bindings()->add_unknown_name(name, location); return this->package_->bindings()->add_unknown_name(name, location);
} }
@ -838,7 +840,7 @@ Gogo::add_unknown_name(const std::string& name, source_location location)
Named_object* Named_object*
Gogo::declare_function(const std::string& name, Function_type* type, Gogo::declare_function(const std::string& name, Function_type* type,
source_location location) Location location)
{ {
if (!type->is_method()) if (!type->is_method())
return this->current_bindings()->add_function_declaration(name, NULL, type, return this->current_bindings()->add_function_declaration(name, NULL, type,
@ -874,7 +876,7 @@ Gogo::declare_function(const std::string& name, Function_type* type,
Label* Label*
Gogo::add_label_definition(const std::string& label_name, Gogo::add_label_definition(const std::string& label_name,
source_location location) Location location)
{ {
go_assert(!this->functions_.empty()); go_assert(!this->functions_.empty());
Function* func = this->functions_.back().function->func_value(); Function* func = this->functions_.back().function->func_value();
@ -887,7 +889,7 @@ Gogo::add_label_definition(const std::string& label_name,
Label* Label*
Gogo::add_label_reference(const std::string& label_name, Gogo::add_label_reference(const std::string& label_name,
source_location location, bool issue_goto_errors) Location location, bool issue_goto_errors)
{ {
go_assert(!this->functions_.empty()); go_assert(!this->functions_.empty());
Function* func = this->functions_.back().function->func_value(); Function* func = this->functions_.back().function->func_value();
@ -898,7 +900,7 @@ Gogo::add_label_reference(const std::string& label_name,
// Return the current binding state. // Return the current binding state.
Bindings_snapshot* Bindings_snapshot*
Gogo::bindings_snapshot(source_location location) Gogo::bindings_snapshot(Location location)
{ {
return new Bindings_snapshot(this->current_block(), location); return new Bindings_snapshot(this->current_block(), location);
} }
@ -916,7 +918,7 @@ Gogo::add_statement(Statement* statement)
// Add a block. // Add a block.
void void
Gogo::add_block(Block* block, source_location location) Gogo::add_block(Block* block, Location location)
{ {
go_assert(!this->functions_.empty() go_assert(!this->functions_.empty()
&& !this->functions_.back().blocks.empty()); && !this->functions_.back().blocks.empty());
@ -936,7 +938,7 @@ Gogo::add_constant(const Typed_identifier& tid, Expression* expr,
// Add a type. // Add a type.
void void
Gogo::add_type(const std::string& name, Type* type, source_location location) Gogo::add_type(const std::string& name, Type* type, Location location)
{ {
Named_object* no = this->current_bindings()->add_type(name, NULL, type, Named_object* no = this->current_bindings()->add_type(name, NULL, type,
location); location);
@ -956,7 +958,7 @@ Gogo::add_named_type(Named_type* type)
// Declare a type. // Declare a type.
Named_object* Named_object*
Gogo::declare_type(const std::string& name, source_location location) Gogo::declare_type(const std::string& name, Location location)
{ {
Bindings* bindings = this->current_bindings(); Bindings* bindings = this->current_bindings();
Named_object* no = bindings->add_type_declaration(name, NULL, location); Named_object* no = bindings->add_type_declaration(name, NULL, location);
@ -971,7 +973,7 @@ Gogo::declare_type(const std::string& name, source_location location)
// Declare a type at the package level. // Declare a type at the package level.
Named_object* Named_object*
Gogo::declare_package_type(const std::string& name, source_location location) Gogo::declare_package_type(const std::string& name, Location location)
{ {
return this->package_->bindings()->add_type_declaration(name, NULL, location); return this->package_->bindings()->add_type_declaration(name, NULL, location);
} }
@ -1077,9 +1079,9 @@ Gogo::define_global_names()
{ {
error_at(no->location(), "expected type"); error_at(no->location(), "expected type");
Type* errtype = Type::make_error_type(); Type* errtype = Type::make_error_type();
Named_object* err = Named_object::make_type("error", NULL, Named_object* err =
errtype, Named_object::make_type("erroneous_type", NULL, errtype,
BUILTINS_LOCATION); Linemap::predeclared_location());
no->set_type_value(err->type_value()); no->set_type_value(err->type_value());
} }
} }
@ -1839,7 +1841,7 @@ Shortcuts::convert_shortcut(Block* enclosing, Expression** pshortcut)
Binary_expression* shortcut = (*pshortcut)->binary_expression(); Binary_expression* shortcut = (*pshortcut)->binary_expression();
Expression* left = shortcut->left(); Expression* left = shortcut->left();
Expression* right = shortcut->right(); Expression* right = shortcut->right();
source_location loc = shortcut->location(); Location loc = shortcut->location();
Block* retblock = new Block(enclosing, loc); Block* retblock = new Block(enclosing, loc);
retblock->set_end_location(loc); retblock->set_end_location(loc);
@ -2032,7 +2034,7 @@ Order_eval::statement(Block* block, size_t* pindex, Statement* s)
if (is_thunk && p + 1 == find_eval_ordering.end()) if (is_thunk && p + 1 == find_eval_ordering.end())
break; break;
source_location loc = (*pexpr)->location(); Location loc = (*pexpr)->location();
Statement* s; Statement* s;
if ((*pexpr)->call_expression() == NULL if ((*pexpr)->call_expression() == NULL
|| (*pexpr)->call_expression()->result_count() < 2) || (*pexpr)->call_expression()->result_count() < 2)
@ -2091,7 +2093,7 @@ Order_eval::variable(Named_object* no)
++p) ++p)
{ {
Expression** pexpr = *p; Expression** pexpr = *p;
source_location loc = (*pexpr)->location(); Location loc = (*pexpr)->location();
Statement* s; Statement* s;
if ((*pexpr)->call_expression() == NULL if ((*pexpr)->call_expression() == NULL
|| (*pexpr)->call_expression()->result_count() < 2) || (*pexpr)->call_expression()->result_count() < 2)
@ -2173,7 +2175,7 @@ class Build_recover_thunks : public Traverse
private: private:
Expression* Expression*
can_recover_arg(source_location); can_recover_arg(Location);
// General IR. // General IR.
Gogo* gogo_; Gogo* gogo_;
@ -2191,7 +2193,7 @@ Build_recover_thunks::function(Named_object* orig_no)
return TRAVERSE_CONTINUE; return TRAVERSE_CONTINUE;
Gogo* gogo = this->gogo_; Gogo* gogo = this->gogo_;
source_location location = orig_func->location(); Location location = orig_func->location();
static int count; static int count;
char buf[50]; char buf[50];
@ -2389,12 +2391,12 @@ Build_recover_thunks::function(Named_object* orig_no)
// __go_can_recover(__builtin_return_address()). // __go_can_recover(__builtin_return_address()).
Expression* Expression*
Build_recover_thunks::can_recover_arg(source_location location) Build_recover_thunks::can_recover_arg(Location location)
{ {
static Named_object* builtin_return_address; static Named_object* builtin_return_address;
if (builtin_return_address == NULL) if (builtin_return_address == NULL)
{ {
const source_location bloc = BUILTINS_LOCATION; const Location bloc = Linemap::predeclared_location();
Typed_identifier_list* param_types = new Typed_identifier_list(); Typed_identifier_list* param_types = new Typed_identifier_list();
Type* uint_type = Type::lookup_integer_type("uint"); Type* uint_type = Type::lookup_integer_type("uint");
@ -2416,7 +2418,7 @@ Build_recover_thunks::can_recover_arg(source_location location)
static Named_object* can_recover; static Named_object* can_recover;
if (can_recover == NULL) if (can_recover == NULL)
{ {
const source_location bloc = BUILTINS_LOCATION; const Location bloc = Linemap::predeclared_location();
Typed_identifier_list* param_types = new Typed_identifier_list(); Typed_identifier_list* param_types = new Typed_identifier_list();
Type* voidptr_type = Type::make_pointer_type(Type::make_void_type()); Type* voidptr_type = Type::make_pointer_type(Type::make_void_type());
param_types->push_back(Typed_identifier("a", voidptr_type, bloc)); param_types->push_back(Typed_identifier("a", voidptr_type, bloc));
@ -2748,7 +2750,7 @@ Gogo::convert_named_types_in_bindings(Bindings* bindings)
// Class Function. // Class Function.
Function::Function(Function_type* type, Function* enclosing, Block* block, Function::Function(Function_type* type, Function* enclosing, Block* block,
source_location location) Location location)
: type_(type), enclosing_(enclosing), results_(NULL), : type_(type), enclosing_(enclosing), results_(NULL),
closure_var_(NULL), block_(block), location_(location), fndecl_(NULL), closure_var_(NULL), block_(block), location_(location), fndecl_(NULL),
defer_stack_(NULL), results_are_named_(false), calls_recover_(false), defer_stack_(NULL), results_are_named_(false), calls_recover_(false),
@ -2829,7 +2831,7 @@ Function::closure_var()
{ {
// We don't know the type of the variable yet. We add fields as // We don't know the type of the variable yet. We add fields as
// we find them. // we find them.
source_location loc = this->type_->location(); Location loc = this->type_->location();
Struct_field_list* sfl = new Struct_field_list; Struct_field_list* sfl = new Struct_field_list;
Type* struct_type = Type::make_struct_type(sfl, loc); Type* struct_type = Type::make_struct_type(sfl, loc);
Variable* var = new Variable(Type::make_pointer_type(struct_type), Variable* var = new Variable(Type::make_pointer_type(struct_type),
@ -2880,7 +2882,7 @@ Function::is_method() const
Label* Label*
Function::add_label_definition(Gogo* gogo, const std::string& label_name, Function::add_label_definition(Gogo* gogo, const std::string& label_name,
source_location location) Location location)
{ {
Label* lnull = NULL; Label* lnull = NULL;
std::pair<Labels::iterator, bool> ins = std::pair<Labels::iterator, bool> ins =
@ -2924,7 +2926,7 @@ Function::add_label_definition(Gogo* gogo, const std::string& label_name,
Label* Label*
Function::add_label_reference(Gogo* gogo, const std::string& label_name, Function::add_label_reference(Gogo* gogo, const std::string& label_name,
source_location location, bool issue_goto_errors) Location location, bool issue_goto_errors)
{ {
Label* lnull = NULL; Label* lnull = NULL;
std::pair<Labels::iterator, bool> ins = std::pair<Labels::iterator, bool> ins =
@ -3039,7 +3041,7 @@ Function::determine_types()
// function which uses defer. // function which uses defer.
Expression* Expression*
Function::defer_stack(source_location location) Function::defer_stack(Location location)
{ {
if (this->defer_stack_ == NULL) if (this->defer_stack_ == NULL)
{ {
@ -3218,7 +3220,7 @@ Function::import_func(Import* imp, std::string* pname,
// Class Block. // Class Block.
Block::Block(Block* enclosing, source_location location) Block::Block(Block* enclosing, Location location)
: enclosing_(enclosing), statements_(), : enclosing_(enclosing), statements_(),
bindings_(new Bindings(enclosing == NULL bindings_(new Bindings(enclosing == NULL
? NULL ? NULL
@ -3463,7 +3465,7 @@ Block::get_backend(Translate_context* context)
// Class Bindings_snapshot. // Class Bindings_snapshot.
Bindings_snapshot::Bindings_snapshot(const Block* b, source_location location) Bindings_snapshot::Bindings_snapshot(const Block* b, Location location)
: block_(b), counts_(), location_(location) : block_(b), counts_(), location_(location)
{ {
while (b != NULL) while (b != NULL)
@ -3476,7 +3478,7 @@ Bindings_snapshot::Bindings_snapshot(const Block* b, source_location location)
// Report errors appropriate for a goto from B to this. // Report errors appropriate for a goto from B to this.
void void
Bindings_snapshot::check_goto_from(const Block* b, source_location loc) Bindings_snapshot::check_goto_from(const Block* b, Location loc)
{ {
size_t dummy; size_t dummy;
if (!this->check_goto_block(loc, b, this->block_, &dummy)) if (!this->check_goto_block(loc, b, this->block_, &dummy))
@ -3504,7 +3506,7 @@ Bindings_snapshot::check_goto_to(const Block* b)
// BFROM. // BFROM.
bool bool
Bindings_snapshot::check_goto_block(source_location loc, const Block* bfrom, Bindings_snapshot::check_goto_block(Location loc, const Block* bfrom,
const Block* bto, size_t* pindex) const Block* bto, size_t* pindex)
{ {
// It is an error if BTO is not either BFROM or above BFROM. // It is an error if BTO is not either BFROM or above BFROM.
@ -3527,7 +3529,7 @@ Bindings_snapshot::check_goto_block(source_location loc, const Block* bfrom,
// CTO is the number of names defined at the point of the label. // CTO is the number of names defined at the point of the label.
void void
Bindings_snapshot::check_goto_defs(source_location loc, const Block* block, Bindings_snapshot::check_goto_defs(Location loc, const Block* block,
size_t cfrom, size_t cto) size_t cfrom, size_t cto)
{ {
if (cfrom < cto) if (cfrom < cto)
@ -3551,7 +3553,7 @@ Bindings_snapshot::check_goto_defs(source_location loc, const Block* block,
Variable::Variable(Type* type, Expression* init, bool is_global, Variable::Variable(Type* type, Expression* init, bool is_global,
bool is_parameter, bool is_receiver, bool is_parameter, bool is_receiver,
source_location location) Location location)
: type_(type), init_(init), preinit_(NULL), location_(location), : type_(type), init_(init), preinit_(NULL), location_(location),
backend_(NULL), is_global_(is_global), is_parameter_(is_parameter), backend_(NULL), is_global_(is_global), is_parameter_(is_parameter),
is_receiver_(is_receiver), is_varargs_parameter_(false), is_receiver_(is_receiver), is_varargs_parameter_(false),
@ -4098,7 +4100,7 @@ Type_declaration::add_method(const std::string& name, Function* function)
Named_object* Named_object*
Type_declaration::add_method_declaration(const std::string& name, Type_declaration::add_method_declaration(const std::string& name,
Function_type* type, Function_type* type,
source_location location) Location location)
{ {
Named_object* ret = Named_object::make_function_declaration(name, NULL, type, Named_object* ret = Named_object::make_function_declaration(name, NULL, type,
location); location);
@ -4165,7 +4167,7 @@ Named_object::Named_object(const std::string& name,
Named_object* Named_object*
Named_object::make_unknown_name(const std::string& name, Named_object::make_unknown_name(const std::string& name,
source_location location) Location location)
{ {
Named_object* named_object = new Named_object(name, NULL, Named_object* named_object = new Named_object(name, NULL,
NAMED_OBJECT_UNKNOWN); NAMED_OBJECT_UNKNOWN);
@ -4194,7 +4196,7 @@ Named_object::make_constant(const Typed_identifier& tid,
Named_object* Named_object*
Named_object::make_type(const std::string& name, const Package* package, Named_object::make_type(const std::string& name, const Package* package,
Type* type, source_location location) Type* type, Location location)
{ {
Named_object* named_object = new Named_object(name, package, Named_object* named_object = new Named_object(name, package,
NAMED_OBJECT_TYPE); NAMED_OBJECT_TYPE);
@ -4208,7 +4210,7 @@ Named_object::make_type(const std::string& name, const Package* package,
Named_object* Named_object*
Named_object::make_type_declaration(const std::string& name, Named_object::make_type_declaration(const std::string& name,
const Package* package, const Package* package,
source_location location) Location location)
{ {
Named_object* named_object = new Named_object(name, package, Named_object* named_object = new Named_object(name, package,
NAMED_OBJECT_TYPE_DECLARATION); NAMED_OBJECT_TYPE_DECLARATION);
@ -4267,7 +4269,7 @@ Named_object*
Named_object::make_function_declaration(const std::string& name, Named_object::make_function_declaration(const std::string& name,
const Package* package, const Package* package,
Function_type* fntype, Function_type* fntype,
source_location location) Location location)
{ {
Named_object* named_object = new Named_object(name, package, Named_object* named_object = new Named_object(name, package,
NAMED_OBJECT_FUNC_DECLARATION); NAMED_OBJECT_FUNC_DECLARATION);
@ -4341,7 +4343,7 @@ Named_object::declare_as_type()
// Return the location of a named object. // Return the location of a named object.
source_location Location
Named_object::location() const Named_object::location() const
{ {
switch (this->classification_) switch (this->classification_)
@ -4717,7 +4719,7 @@ Named_object*
Bindings::add_function_declaration(const std::string& name, Bindings::add_function_declaration(const std::string& name,
const Package* package, const Package* package,
Function_type* type, Function_type* type,
source_location location) Location location)
{ {
Named_object* no = Named_object::make_function_declaration(name, package, Named_object* no = Named_object::make_function_declaration(name, package,
type, location); type, location);
@ -4869,7 +4871,7 @@ Label::get_backend_label(Translate_context* context)
// Return an expression for the address of this label. // Return an expression for the address of this label.
Bexpression* Bexpression*
Label::get_addr(Translate_context* context, source_location location) Label::get_addr(Translate_context* context, Location location)
{ {
Blabel* label = this->get_backend_label(context); Blabel* label = this->get_backend_label(context);
return context->backend()->label_address(label, location); return context->backend()->label_address(label, location);
@ -4905,7 +4907,7 @@ Unnamed_label::get_definition(Translate_context* context)
// Return a goto statement to this unnamed label. // Return a goto statement to this unnamed label.
Bstatement* Bstatement*
Unnamed_label::get_goto(Translate_context* context, source_location location) Unnamed_label::get_goto(Translate_context* context, Location location)
{ {
Blabel* blabel = this->get_blabel(context); Blabel* blabel = this->get_blabel(context);
return context->backend()->goto_statement(blabel, location); return context->backend()->goto_statement(blabel, location);
@ -4914,7 +4916,7 @@ Unnamed_label::get_goto(Translate_context* context, source_location location)
// Class Package. // Class Package.
Package::Package(const std::string& name, const std::string& unique_prefix, Package::Package(const std::string& name, const std::string& unique_prefix,
source_location location) Location location)
: name_(name), unique_prefix_(unique_prefix), bindings_(new Bindings(NULL)), : name_(name), unique_prefix_(unique_prefix), bindings_(new Bindings(NULL)),
priority_(0), location_(location), used_(false), is_imported_(false), priority_(0), location_(location), used_(false), is_imported_(false),
uses_sink_alias_(false) uses_sink_alias_(false)

View File

@ -7,6 +7,8 @@
#ifndef GO_GOGO_H #ifndef GO_GOGO_H
#define GO_GOGO_H #define GO_GOGO_H
#include "go-linemap.h"
class Traverse; class Traverse;
class Statement_inserter; class Statement_inserter;
class Type; class Type;
@ -111,20 +113,25 @@ class Gogo
public: public:
// Create the IR, passing in the sizes of the types "int" and // Create the IR, passing in the sizes of the types "int" and
// "uintptr" in bits. // "uintptr" in bits.
Gogo(Backend* backend, int int_type_size, int pointer_size); Gogo(Backend* backend, Linemap *linemap, int int_type_size, int pointer_size);
// Get the backend generator. // Get the backend generator.
Backend* Backend*
backend() backend()
{ return this->backend_; } { return this->backend_; }
// Get the Location generator.
Linemap*
linemap()
{ return this->linemap_; }
// Get the package name. // Get the package name.
const std::string& const std::string&
package_name() const; package_name() const;
// Set the package name. // Set the package name.
void void
set_package_name(const std::string&, source_location); set_package_name(const std::string&, Location);
// Return whether this is the "main" package. // Return whether this is the "main" package.
bool bool
@ -195,7 +202,7 @@ class Gogo
// the declarations are added to the global scope. // the declarations are added to the global scope.
void void
import_package(const std::string& filename, const std::string& local_name, import_package(const std::string& filename, const std::string& local_name,
bool is_local_name_exported, source_location); bool is_local_name_exported, Location);
// Whether we are the global binding level. // Whether we are the global binding level.
bool bool
@ -223,7 +230,7 @@ class Gogo
add_imported_package(const std::string& real_name, const std::string& alias, add_imported_package(const std::string& real_name, const std::string& alias,
bool is_alias_exported, bool is_alias_exported,
const std::string& unique_prefix, const std::string& unique_prefix,
source_location location, Location location,
bool* padd_to_globals); bool* padd_to_globals);
// Register a package. This package may or may not be imported. // Register a package. This package may or may not be imported.
@ -231,17 +238,17 @@ class Gogo
// it necessary. // it necessary.
Package* Package*
register_package(const std::string& name, const std::string& unique_prefix, register_package(const std::string& name, const std::string& unique_prefix,
source_location); Location);
// Start compiling a function. ADD_METHOD_TO_TYPE is true if a // Start compiling a function. ADD_METHOD_TO_TYPE is true if a
// method function should be added to the type of its receiver. // method function should be added to the type of its receiver.
Named_object* Named_object*
start_function(const std::string& name, Function_type* type, start_function(const std::string& name, Function_type* type,
bool add_method_to_type, source_location); bool add_method_to_type, Location);
// Finish compiling a function. // Finish compiling a function.
void void
finish_function(source_location); finish_function(Location);
// Return the current function. // Return the current function.
Named_object* Named_object*
@ -254,36 +261,36 @@ class Gogo
// Start a new block. This is not initially associated with a // Start a new block. This is not initially associated with a
// function. // function.
void void
start_block(source_location); start_block(Location);
// Finish the current block and return it. // Finish the current block and return it.
Block* Block*
finish_block(source_location); finish_block(Location);
// Declare an unknown name. This is used while parsing. The name // Declare an unknown name. This is used while parsing. The name
// must be resolved by the end of the parse. Unknown names are // must be resolved by the end of the parse. Unknown names are
// always added at the package level. // always added at the package level.
Named_object* Named_object*
add_unknown_name(const std::string& name, source_location); add_unknown_name(const std::string& name, Location);
// Declare a function. // Declare a function.
Named_object* Named_object*
declare_function(const std::string&, Function_type*, source_location); declare_function(const std::string&, Function_type*, Location);
// Add a label. // Add a label.
Label* Label*
add_label_definition(const std::string&, source_location); add_label_definition(const std::string&, Location);
// Add a label reference. ISSUE_GOTO_ERRORS is true if we should // Add a label reference. ISSUE_GOTO_ERRORS is true if we should
// report errors for a goto from the current location to the label // report errors for a goto from the current location to the label
// location. // location.
Label* Label*
add_label_reference(const std::string&, source_location, add_label_reference(const std::string&, Location,
bool issue_goto_errors); bool issue_goto_errors);
// Return a snapshot of the current binding state. // Return a snapshot of the current binding state.
Bindings_snapshot* Bindings_snapshot*
bindings_snapshot(source_location); bindings_snapshot(Location);
// Add a statement to the current block. // Add a statement to the current block.
void void
@ -291,7 +298,7 @@ class Gogo
// Add a block to the current block. // Add a block to the current block.
void void
add_block(Block*, source_location); add_block(Block*, Location);
// Add a constant. // Add a constant.
Named_object* Named_object*
@ -299,7 +306,7 @@ class Gogo
// Add a type. // Add a type.
void void
add_type(const std::string&, Type*, source_location); add_type(const std::string&, Type*, Location);
// Add a named type. This is used for builtin types, and to add an // Add a named type. This is used for builtin types, and to add an
// imported type to the global scope. // imported type to the global scope.
@ -308,12 +315,12 @@ class Gogo
// Declare a type. // Declare a type.
Named_object* Named_object*
declare_type(const std::string&, source_location); declare_type(const std::string&, Location);
// Declare a type at the package level. This is used when the // Declare a type at the package level. This is used when the
// parser sees an unknown name where a type name is required. // parser sees an unknown name where a type name is required.
Named_object* Named_object*
declare_package_type(const std::string&, source_location); declare_package_type(const std::string&, Location);
// Define a type which was already declared. // Define a type which was already declared.
void void
@ -466,12 +473,12 @@ class Gogo
// RETTYPE is the return type. It is followed by NARGS pairs of // RETTYPE is the return type. It is followed by NARGS pairs of
// type and argument (both trees). // type and argument (both trees).
static tree static tree
call_builtin(tree* pdecl, source_location, const char* name, int nargs, call_builtin(tree* pdecl, Location, const char* name, int nargs,
tree rettype, ...); tree rettype, ...);
// Build a call to the runtime error function. // Build a call to the runtime error function.
static tree static tree
runtime_error(int code, source_location); runtime_error(int code, Location);
// Build a builtin struct with a list of fields. // Build a builtin struct with a list of fields.
static tree static tree
@ -503,7 +510,7 @@ class Gogo
// Return a tree which allocate SIZE bytes to hold values of type // Return a tree which allocate SIZE bytes to hold values of type
// TYPE. // TYPE.
tree tree
allocate_memory(Type *type, tree size, source_location); allocate_memory(Type *type, tree size, Location);
// Return a type to use for pointer to const char. // Return a type to use for pointer to const char.
static tree static tree
@ -521,7 +528,7 @@ class Gogo
// Receive a value from a channel. // Receive a value from a channel.
static tree static tree
receive_from_channel(tree type_tree, tree channel, bool for_select, receive_from_channel(tree type_tree, tree channel, bool for_select,
source_location); Location);
// Return a tree for receiving an integer on a channel. // Return a tree for receiving an integer on a channel.
static tree static tree
@ -530,7 +537,7 @@ class Gogo
// Make a trampoline which calls FNADDR passing CLOSURE. // Make a trampoline which calls FNADDR passing CLOSURE.
tree tree
make_trampoline(tree fnaddr, tree closure, source_location); make_trampoline(tree fnaddr, tree closure, Location);
private: private:
// During parsing, we keep a stack of functions. Each function on // During parsing, we keep a stack of functions. Each function on
@ -549,12 +556,12 @@ class Gogo
// Set up the built-in unsafe package. // Set up the built-in unsafe package.
void void
import_unsafe(const std::string&, bool is_exported, source_location); import_unsafe(const std::string&, bool is_exported, Location);
// Add a new imported package. // Add a new imported package.
Named_object* Named_object*
add_package(const std::string& real_name, const std::string& alias, add_package(const std::string& real_name, const std::string& alias,
const std::string& unique_prefix, source_location location); const std::string& unique_prefix, Location location);
// Return the current binding contour. // Return the current binding contour.
Bindings* Bindings*
@ -603,6 +610,8 @@ class Gogo
// The backend generator. // The backend generator.
Backend* backend_; Backend* backend_;
// The object used to keep track of file names and line numbers.
Linemap* linemap_;
// The package we are compiling. // The package we are compiling.
Package* package_; Package* package_;
// The list of currently open functions during parsing. // The list of currently open functions during parsing.
@ -640,7 +649,7 @@ class Gogo
class Block class Block
{ {
public: public:
Block(Block* enclosing, source_location); Block(Block* enclosing, Location);
// Return the enclosing block. // Return the enclosing block.
const Block* const Block*
@ -663,13 +672,13 @@ class Block
// Return the start location. This is normally the location of the // Return the start location. This is normally the location of the
// left curly brace which starts the block. // left curly brace which starts the block.
source_location Location
start_location() const start_location() const
{ return this->start_location_; } { return this->start_location_; }
// Return the end location. This is normally the location of the // Return the end location. This is normally the location of the
// right curly brace which ends the block. // right curly brace which ends the block.
source_location Location
end_location() const end_location() const
{ return this->end_location_; } { return this->end_location_; }
@ -695,7 +704,7 @@ class Block
// Set the end location of the block. // Set the end location of the block.
void void
set_end_location(source_location location) set_end_location(Location location)
{ this->end_location_ = location; } { this->end_location_ = location; }
// Traverse the tree. // Traverse the tree.
@ -735,9 +744,9 @@ class Block
// Binding contour. // Binding contour.
Bindings* bindings_; Bindings* bindings_;
// Location of start of block. // Location of start of block.
source_location start_location_; Location start_location_;
// Location of end of block. // Location of end of block.
source_location end_location_; Location end_location_;
}; };
// A function. // A function.
@ -745,7 +754,7 @@ class Block
class Function class Function
{ {
public: public:
Function(Function_type* type, Function*, Block*, source_location); Function(Function_type* type, Function*, Block*, Location);
// Return the function's type. // Return the function's type.
Function_type* Function_type*
@ -790,7 +799,7 @@ class Function
// Add a new field to the closure variable. // Add a new field to the closure variable.
void void
add_closure_field(Named_object* var, source_location loc) add_closure_field(Named_object* var, Location loc)
{ this->closure_fields_.push_back(std::make_pair(var, loc)); } { this->closure_fields_.push_back(std::make_pair(var, loc)); }
// Whether this function needs a closure. // Whether this function needs a closure.
@ -831,7 +840,7 @@ class Function
{ return this->block_; } { return this->block_; }
// Get the location of the start of the function. // Get the location of the start of the function.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -841,14 +850,14 @@ class Function
// Add a label definition to the function. // Add a label definition to the function.
Label* Label*
add_label_definition(Gogo*, const std::string& label_name, source_location); add_label_definition(Gogo*, const std::string& label_name, Location);
// Add a label reference to a function. ISSUE_GOTO_ERRORS is true // Add a label reference to a function. ISSUE_GOTO_ERRORS is true
// if we should report errors for a goto from the current location // if we should report errors for a goto from the current location
// to the label location. // to the label location.
Label* Label*
add_label_reference(Gogo*, const std::string& label_name, add_label_reference(Gogo*, const std::string& label_name,
source_location, bool issue_goto_errors); Location, bool issue_goto_errors);
// Warn about labels that are defined but not used. // Warn about labels that are defined but not used.
void void
@ -918,11 +927,11 @@ class Function
// Get the value to return when not explicitly specified. May also // Get the value to return when not explicitly specified. May also
// add statements to execute first to STMT_LIST. // add statements to execute first to STMT_LIST.
tree tree
return_value(Gogo*, Named_object*, source_location, tree* stmt_list) const; return_value(Gogo*, Named_object*, Location, tree* stmt_list) const;
// Get a tree for the variable holding the defer stack. // Get a tree for the variable holding the defer stack.
Expression* Expression*
defer_stack(source_location); defer_stack(Location);
// Export the function. // Export the function.
void void
@ -953,7 +962,7 @@ class Function
build_defer_wrapper(Gogo*, Named_object*, tree*, tree*); build_defer_wrapper(Gogo*, Named_object*, tree*, tree*);
typedef std::vector<std::pair<Named_object*, typedef std::vector<std::pair<Named_object*,
source_location> > Closure_fields; Location> > Closure_fields;
// The function's type. // The function's type.
Function_type* type_; Function_type* type_;
@ -972,7 +981,7 @@ class Function
// The outer block of statements in the function. // The outer block of statements in the function.
Block* block_; Block* block_;
// The source location of the start of the function. // The source location of the start of the function.
source_location location_; Location location_;
// Labels defined or referenced in the function. // Labels defined or referenced in the function.
Labels labels_; Labels labels_;
// The function decl. // The function decl.
@ -996,12 +1005,12 @@ class Function
class Bindings_snapshot class Bindings_snapshot
{ {
public: public:
Bindings_snapshot(const Block*, source_location); Bindings_snapshot(const Block*, Location);
// Report any errors appropriate for a goto from the current binding // Report any errors appropriate for a goto from the current binding
// state of B to this one. // state of B to this one.
void void
check_goto_from(const Block* b, source_location); check_goto_from(const Block* b, Location);
// Report any errors appropriate for a goto from this binding state // Report any errors appropriate for a goto from this binding state
// to the current state of B. // to the current state of B.
@ -1010,10 +1019,10 @@ class Bindings_snapshot
private: private:
bool bool
check_goto_block(source_location, const Block*, const Block*, size_t*); check_goto_block(Location, const Block*, const Block*, size_t*);
void void
check_goto_defs(source_location, const Block*, size_t, size_t); check_goto_defs(Location, const Block*, size_t, size_t);
// The current block. // The current block.
const Block* block_; const Block* block_;
@ -1022,7 +1031,7 @@ class Bindings_snapshot
// this->block_->enclosing(), etc. // this->block_->enclosing(), etc.
std::vector<size_t> counts_; std::vector<size_t> counts_;
// The location where this snapshot was taken. // The location where this snapshot was taken.
source_location location_; Location location_;
}; };
// A function declaration. // A function declaration.
@ -1030,7 +1039,7 @@ class Bindings_snapshot
class Function_declaration class Function_declaration
{ {
public: public:
Function_declaration(Function_type* fntype, source_location location) Function_declaration(Function_type* fntype, Location location)
: fntype_(fntype), location_(location), asm_name_(), fndecl_(NULL) : fntype_(fntype), location_(location), asm_name_(), fndecl_(NULL)
{ } { }
@ -1038,7 +1047,7 @@ class Function_declaration
type() const type() const
{ return this->fntype_; } { return this->fntype_; }
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -1064,7 +1073,7 @@ class Function_declaration
// The type of the function. // The type of the function.
Function_type* fntype_; Function_type* fntype_;
// The location of the declaration. // The location of the declaration.
source_location location_; Location location_;
// The assembler name: this is the name to use in references to the // The assembler name: this is the name to use in references to the
// function. This is normally empty. // function. This is normally empty.
std::string asm_name_; std::string asm_name_;
@ -1078,7 +1087,7 @@ class Variable
{ {
public: public:
Variable(Type*, Expression*, bool is_global, bool is_parameter, Variable(Type*, Expression*, bool is_global, bool is_parameter,
bool is_receiver, source_location); bool is_receiver, Location);
// Get the type of the variable. // Get the type of the variable.
Type* Type*
@ -1172,7 +1181,7 @@ class Variable
{ this->is_non_escaping_address_taken_ = true; } { this->is_non_escaping_address_taken_ = true; }
// Get the source location of the variable's declaration. // Get the source location of the variable's declaration.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -1309,7 +1318,7 @@ class Variable
// Statements to run before the init statement. // Statements to run before the init statement.
Block* preinit_; Block* preinit_;
// Location of variable definition. // Location of variable definition.
source_location location_; Location location_;
// Backend representation. // Backend representation.
Bvariable* backend_; Bvariable* backend_;
// Whether this is a global variable. // Whether this is a global variable.
@ -1352,7 +1361,7 @@ class Result_variable
{ {
public: public:
Result_variable(Type* type, Function* function, int index, Result_variable(Type* type, Function* function, int index,
source_location location) Location location)
: type_(type), function_(function), index_(index), location_(location), : type_(type), function_(function), index_(index), location_(location),
backend_(NULL), is_address_taken_(false), backend_(NULL), is_address_taken_(false),
is_non_escaping_address_taken_(false) is_non_escaping_address_taken_(false)
@ -1374,7 +1383,7 @@ class Result_variable
{ return this->index_; } { return this->index_; }
// The location of the variable definition. // The location of the variable definition.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -1422,7 +1431,7 @@ class Result_variable
// Index in list of results. // Index in list of results.
int index_; int index_;
// Where the result variable is defined. // Where the result variable is defined.
source_location location_; Location location_;
// Backend representation. // Backend representation.
Bvariable* backend_; Bvariable* backend_;
// Whether something takes the address of this variable. // Whether something takes the address of this variable.
@ -1439,7 +1448,7 @@ class Named_constant
{ {
public: public:
Named_constant(Type* type, Expression* expr, int iota_value, Named_constant(Type* type, Expression* expr, int iota_value,
source_location location) Location location)
: type_(type), expr_(expr), iota_value_(iota_value), location_(location), : type_(type), expr_(expr), iota_value_(iota_value), location_(location),
lowering_(false) lowering_(false)
{ } { }
@ -1456,7 +1465,7 @@ class Named_constant
iota_value() const iota_value() const
{ return this->iota_value_; } { return this->iota_value_; }
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -1507,7 +1516,7 @@ class Named_constant
// we lower. // we lower.
int iota_value_; int iota_value_;
// The location of the definition. // The location of the definition.
source_location location_; Location location_;
// Whether we are currently lowering this constant. // Whether we are currently lowering this constant.
bool lowering_; bool lowering_;
}; };
@ -1517,13 +1526,13 @@ class Named_constant
class Type_declaration class Type_declaration
{ {
public: public:
Type_declaration(source_location location) Type_declaration(Location location)
: location_(location), in_function_(NULL), methods_(), : location_(location), in_function_(NULL), methods_(),
issued_warning_(false) issued_warning_(false)
{ } { }
// Return the location. // Return the location.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -1546,7 +1555,7 @@ class Type_declaration
// Add a method declaration to this type. // Add a method declaration to this type.
Named_object* Named_object*
add_method_declaration(const std::string& name, Function_type* type, add_method_declaration(const std::string& name, Function_type* type,
source_location location); Location location);
// Return whether any methods were defined. // Return whether any methods were defined.
bool bool
@ -1565,7 +1574,7 @@ class Type_declaration
typedef std::vector<Named_object*> Methods; typedef std::vector<Named_object*> Methods;
// The location of the type declaration. // The location of the type declaration.
source_location location_; Location location_;
// If this type is declared in a function, a pointer back to the // If this type is declared in a function, a pointer back to the
// function in which it is defined. // function in which it is defined.
Named_object* in_function_; Named_object* in_function_;
@ -1585,12 +1594,12 @@ class Type_declaration
class Unknown_name class Unknown_name
{ {
public: public:
Unknown_name(source_location location) Unknown_name(Location location)
: location_(location), real_named_object_(NULL) : location_(location), real_named_object_(NULL)
{ } { }
// Return the location where this name was first seen. // Return the location where this name was first seen.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -1606,7 +1615,7 @@ class Unknown_name
private: private:
// The location where this name was first seen. // The location where this name was first seen.
source_location location_; Location location_;
// The real named object when it is known. // The real named object when it is known.
Named_object* Named_object*
real_named_object_; real_named_object_;
@ -1697,17 +1706,17 @@ class Named_object
// Creators. // Creators.
static Named_object* static Named_object*
make_unknown_name(const std::string& name, source_location); make_unknown_name(const std::string& name, Location);
static Named_object* static Named_object*
make_constant(const Typed_identifier&, const Package*, Expression*, make_constant(const Typed_identifier&, const Package*, Expression*,
int iota_value); int iota_value);
static Named_object* static Named_object*
make_type(const std::string&, const Package*, Type*, source_location); make_type(const std::string&, const Package*, Type*, Location);
static Named_object* static Named_object*
make_type_declaration(const std::string&, const Package*, source_location); make_type_declaration(const std::string&, const Package*, Location);
static Named_object* static Named_object*
make_variable(const std::string&, const Package*, Variable*); make_variable(const std::string&, const Package*, Variable*);
@ -1723,7 +1732,7 @@ class Named_object
static Named_object* static Named_object*
make_function_declaration(const std::string&, const Package*, Function_type*, make_function_declaration(const std::string&, const Package*, Function_type*,
source_location); Location);
static Named_object* static Named_object*
make_package(const std::string& alias, Package* package); make_package(const std::string& alias, Package* package);
@ -1899,7 +1908,7 @@ class Named_object
} }
// The location where this object was defined or referenced. // The location where this object was defined or referenced.
source_location Location
location() const; location() const;
// Convert a variable to the backend representation. // Convert a variable to the backend representation.
@ -1969,7 +1978,7 @@ class Bindings
// Add an unknown name. // Add an unknown name.
Named_object* Named_object*
add_unknown_name(const std::string& name, source_location location) add_unknown_name(const std::string& name, Location location)
{ {
return this->add_named_object(Named_object::make_unknown_name(name, return this->add_named_object(Named_object::make_unknown_name(name,
location)); location));
@ -1988,7 +1997,7 @@ class Bindings
// Add a type. // Add a type.
Named_object* Named_object*
add_type(const std::string& name, const Package* package, Type* type, add_type(const std::string& name, const Package* package, Type* type,
source_location location) Location location)
{ {
return this->add_named_object(Named_object::make_type(name, package, type, return this->add_named_object(Named_object::make_type(name, package, type,
location)); location));
@ -2002,7 +2011,7 @@ class Bindings
// Add a type declaration. // Add a type declaration.
Named_object* Named_object*
add_type_declaration(const std::string& name, const Package* package, add_type_declaration(const std::string& name, const Package* package,
source_location location) Location location)
{ {
Named_object* no = Named_object::make_type_declaration(name, package, Named_object* no = Named_object::make_type_declaration(name, package,
location); location);
@ -2033,7 +2042,7 @@ class Bindings
// Add a function declaration. // Add a function declaration.
Named_object* Named_object*
add_function_declaration(const std::string& name, const Package* package, add_function_declaration(const std::string& name, const Package* package,
Function_type* type, source_location location); Function_type* type, Location location);
// Add a package. The location is the location of the import // Add a package. The location is the location of the import
// statement. // statement.
@ -2153,8 +2162,8 @@ class Label
{ {
public: public:
Label(const std::string& name) Label(const std::string& name)
: name_(name), location_(0), snapshot_(NULL), refs_(), is_used_(false), : name_(name), location_(Linemap::unknown_location()), snapshot_(NULL),
blabel_(NULL) refs_(), is_used_(false), blabel_(NULL)
{ } { }
// Return the label's name. // Return the label's name.
@ -2165,7 +2174,7 @@ class Label
// Return whether the label has been defined. // Return whether the label has been defined.
bool bool
is_defined() const is_defined() const
{ return this->location_ != 0; } { return !Linemap::is_unknown_location(this->location_); }
// Return whether the label has been used. // Return whether the label has been used.
bool bool
@ -2178,7 +2187,7 @@ class Label
{ this->is_used_ = true; } { this->is_used_ = true; }
// Return the location of the definition. // Return the location of the definition.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -2191,7 +2200,7 @@ class Label
void void
add_snapshot_ref(Bindings_snapshot* snapshot) add_snapshot_ref(Bindings_snapshot* snapshot)
{ {
go_assert(this->location_ == 0); go_assert(Linemap::is_unknown_location(this->location_));
this->refs_.push_back(snapshot); this->refs_.push_back(snapshot);
} }
@ -2207,9 +2216,10 @@ class Label
// Define the label at LOCATION with the given bindings snapshot. // Define the label at LOCATION with the given bindings snapshot.
void void
define(source_location location, Bindings_snapshot* snapshot) define(Location location, Bindings_snapshot* snapshot)
{ {
go_assert(this->location_ == 0 && this->snapshot_ == NULL); go_assert(Linemap::is_unknown_location(this->location_)
&& this->snapshot_ == NULL);
this->location_ = location; this->location_ = location;
this->snapshot_ = snapshot; this->snapshot_ = snapshot;
} }
@ -2222,14 +2232,14 @@ class Label
// to get the return address of a deferred function to see whether // to get the return address of a deferred function to see whether
// the function may call recover. // the function may call recover.
Bexpression* Bexpression*
get_addr(Translate_context*, source_location location); get_addr(Translate_context*, Location location);
private: private:
// The name of the label. // The name of the label.
std::string name_; std::string name_;
// The location of the definition. This is 0 if the label has not // The location of the definition. This is 0 if the label has not
// yet been defined. // yet been defined.
source_location location_; Location location_;
// A snapshot of the set of bindings defined at this label, used to // A snapshot of the set of bindings defined at this label, used to
// issue errors about invalid goto statements. // issue errors about invalid goto statements.
Bindings_snapshot* snapshot_; Bindings_snapshot* snapshot_;
@ -2246,18 +2256,18 @@ class Label
class Unnamed_label class Unnamed_label
{ {
public: public:
Unnamed_label(source_location location) Unnamed_label(Location location)
: location_(location), blabel_(NULL) : location_(location), blabel_(NULL)
{ } { }
// Get the location where the label is defined. // Get the location where the label is defined.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
// Set the location where the label is defined. // Set the location where the label is defined.
void void
set_location(source_location location) set_location(Location location)
{ this->location_ = location; } { this->location_ = location; }
// Return a statement which defines this label. // Return a statement which defines this label.
@ -2266,7 +2276,7 @@ class Unnamed_label
// Return a goto to this label from LOCATION. // Return a goto to this label from LOCATION.
Bstatement* Bstatement*
get_goto(Translate_context*, source_location location); get_goto(Translate_context*, Location location);
private: private:
// Return the backend representation. // Return the backend representation.
@ -2274,7 +2284,7 @@ class Unnamed_label
get_blabel(Translate_context*); get_blabel(Translate_context*);
// The location where the label is defined. // The location where the label is defined.
source_location location_; Location location_;
// The backend representation of this label. // The backend representation of this label.
Blabel* blabel_; Blabel* blabel_;
}; };
@ -2285,7 +2295,7 @@ class Package
{ {
public: public:
Package(const std::string& name, const std::string& unique_prefix, Package(const std::string& name, const std::string& unique_prefix,
source_location location); Location location);
// The real name of this package. This may be different from the // The real name of this package. This may be different from the
// name in the associated Named_object if the import statement used // name in the associated Named_object if the import statement used
@ -2295,7 +2305,7 @@ class Package
{ return this->name_; } { return this->name_; }
// Return the location of the import statement. // Return the location of the import statement.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -2378,7 +2388,7 @@ class Package
// Set the location of the package. This is used if it is seen in a // Set the location of the package. This is used if it is seen in a
// different import before it is really imported. // different import before it is really imported.
void void
set_location(source_location location) set_location(Location location)
{ this->location_ = location; } { this->location_ = location; }
// Add a constant to the package. // Add a constant to the package.
@ -2388,12 +2398,12 @@ class Package
// Add a type to the package. // Add a type to the package.
Named_object* Named_object*
add_type(const std::string& name, Type* type, source_location location) add_type(const std::string& name, Type* type, Location location)
{ return this->bindings_->add_type(name, this, type, location); } { return this->bindings_->add_type(name, this, type, location); }
// Add a type declaration to the package. // Add a type declaration to the package.
Named_object* Named_object*
add_type_declaration(const std::string& name, source_location location) add_type_declaration(const std::string& name, Location location)
{ return this->bindings_->add_type_declaration(name, this, location); } { return this->bindings_->add_type_declaration(name, this, location); }
// Add a variable to the package. // Add a variable to the package.
@ -2404,7 +2414,7 @@ class Package
// Add a function declaration to the package. // Add a function declaration to the package.
Named_object* Named_object*
add_function_declaration(const std::string& name, Function_type* type, add_function_declaration(const std::string& name, Function_type* type,
source_location loc) Location loc)
{ return this->bindings_->add_function_declaration(name, this, type, loc); } { return this->bindings_->add_function_declaration(name, this, type, loc); }
// Determine types of constants. // Determine types of constants.
@ -2423,7 +2433,7 @@ class Package
// is used to run init functions in the right order. // is used to run init functions in the right order.
int priority_; int priority_;
// The location of the import statement. // The location of the import statement.
source_location location_; Location location_;
// True if some name from this package was used. This is mutable // True if some name from this package was used. This is mutable
// because we can use a package even if we have a const pointer to // because we can use a package even if we have a const pointer to
// it. // it.

View File

@ -66,7 +66,7 @@ Import::is_archive_magic(const char* bytes)
class Archive_file class Archive_file
{ {
public: public:
Archive_file(const std::string& filename, int fd, source_location location) Archive_file(const std::string& filename, int fd, Location location)
: filename_(filename), fd_(fd), filesize_(-1), extended_names_(), : filename_(filename), fd_(fd), filesize_(-1), extended_names_(),
is_thin_archive_(false), location_(location), nested_archives_() is_thin_archive_(false), location_(location), nested_archives_()
{ } { }
@ -91,7 +91,7 @@ class Archive_file
{ return this->is_thin_archive_; } { return this->is_thin_archive_; }
// Return the location of the import statement. // Return the location of the import statement.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -133,7 +133,7 @@ class Archive_file
// Whether this is a thin archive. // Whether this is a thin archive.
bool is_thin_archive_; bool is_thin_archive_;
// The location of the import statements. // The location of the import statements.
source_location location_; Location location_;
// Table of nested archives. // Table of nested archives.
Nested_archive_table nested_archives_; Nested_archive_table nested_archives_;
}; };
@ -613,7 +613,7 @@ Stream_concatenate::do_advance(size_t skip)
Import::Stream* Import::Stream*
Import::find_archive_export_data(const std::string& filename, int fd, Import::find_archive_export_data(const std::string& filename, int fd,
source_location location) Location location)
{ {
Archive_file afile(filename, fd, location); Archive_file afile(filename, fd, location);
if (!afile.initialize()) if (!afile.initialize())

View File

@ -59,7 +59,7 @@ const char* const Import::import_marker = "*imported*";
// later in the search path. // later in the search path.
Import::Stream* Import::Stream*
Import::open_package(const std::string& filename, source_location location) Import::open_package(const std::string& filename, Location location)
{ {
if (!IS_ABSOLUTE_PATH(filename)) if (!IS_ABSOLUTE_PATH(filename))
{ {
@ -88,7 +88,7 @@ Import::open_package(const std::string& filename, source_location location)
Import::Stream* Import::Stream*
Import::try_package_in_directory(const std::string& filename, Import::try_package_in_directory(const std::string& filename,
source_location location) Location location)
{ {
std::string found_filename = filename; std::string found_filename = filename;
int fd = open(found_filename.c_str(), O_RDONLY | O_BINARY); int fd = open(found_filename.c_str(), O_RDONLY | O_BINARY);
@ -175,7 +175,7 @@ Import::try_suffixes(std::string* pfilename)
Import::Stream* Import::Stream*
Import::find_export_data(const std::string& filename, int fd, Import::find_export_data(const std::string& filename, int fd,
source_location location) Location location)
{ {
// See if we can read this as an object file. // See if we can read this as an object file.
Import::Stream* stream = Import::find_object_export_data(filename, fd, 0, Import::Stream* stream = Import::find_object_export_data(filename, fd, 0,
@ -213,7 +213,7 @@ Import::Stream*
Import::find_object_export_data(const std::string& filename, Import::find_object_export_data(const std::string& filename,
int fd, int fd,
off_t offset, off_t offset,
source_location location) Location location)
{ {
const char* errmsg; const char* errmsg;
int err; int err;
@ -262,7 +262,7 @@ Import::find_object_export_data(const std::string& filename,
// Construct an Import object. We make the builtin_types_ vector // Construct an Import object. We make the builtin_types_ vector
// large enough to hold all the builtin types. // large enough to hold all the builtin types.
Import::Import(Stream* stream, source_location location) Import::Import(Stream* stream, Location location)
: gogo_(NULL), stream_(stream), location_(location), package_(NULL), : gogo_(NULL), stream_(stream), location_(location), package_(NULL),
add_to_globals_(false), add_to_globals_(false),
builtin_types_((- SMALLEST_BUILTIN_CODE) + 1), builtin_types_((- SMALLEST_BUILTIN_CODE) + 1),
@ -448,7 +448,7 @@ Import::import_func(Package* package)
if (is_varargs) if (is_varargs)
fntype->set_is_varargs(); fntype->set_is_varargs();
source_location loc = this->location_; Location loc = this->location_;
Named_object* no; Named_object* no;
if (fntype->is_method()) if (fntype->is_method())
{ {
@ -603,7 +603,7 @@ Import::read_type()
package = this->package_; package = this->package_;
else else
package = this->gogo_->register_package(package_name, unique_prefix, package = this->gogo_->register_package(package_name, unique_prefix,
UNKNOWN_LOCATION); Linemap::unknown_location());
Named_object* no = package->bindings()->lookup(type_name); Named_object* no = package->bindings()->lookup(type_name);
if (no == NULL) if (no == NULL)
@ -798,7 +798,7 @@ Import::Stream::match_bytes(const char* bytes, size_t length)
// Require that the next LENGTH bytes from the stream match BYTES. // Require that the next LENGTH bytes from the stream match BYTES.
void void
Import::Stream::require_bytes(source_location location, const char* bytes, Import::Stream::require_bytes(Location location, const char* bytes,
size_t length) size_t length)
{ {
const char* read; const char* read;

View File

@ -8,6 +8,7 @@
#define GO_IMPORT_H #define GO_IMPORT_H
#include "export.h" #include "export.h"
#include "go-linemap.h"
class Gogo; class Gogo;
class Package; class Package;
@ -78,13 +79,13 @@ class Import
// Give an error if the next bytes do not match STR. Advance the // Give an error if the next bytes do not match STR. Advance the
// read position by the length of STR. // read position by the length of STR.
void void
require_c_string(source_location location, const char* str) require_c_string(Location location, const char* str)
{ this->require_bytes(location, str, strlen(str)); } { this->require_bytes(location, str, strlen(str)); }
// Given an error if the next LENGTH bytes do not match BYTES. // Given an error if the next LENGTH bytes do not match BYTES.
// Advance the read position by LENGTH. // Advance the read position by LENGTH.
void void
require_bytes(source_location, const char* bytes, size_t length); require_bytes(Location, const char* bytes, size_t length);
// Advance the read position by SKIP bytes. // Advance the read position by SKIP bytes.
void void
@ -124,10 +125,10 @@ class Import
// returns a pointer to a Stream object to read the data that it // returns a pointer to a Stream object to read the data that it
// exports. LOCATION is the location of the import statement. // exports. LOCATION is the location of the import statement.
static Stream* static Stream*
open_package(const std::string& filename, source_location location); open_package(const std::string& filename, Location location);
// Constructor. // Constructor.
Import(Stream*, source_location); Import(Stream*, Location);
// Register the builtin types. // Register the builtin types.
void void
@ -142,7 +143,7 @@ class Import
import(Gogo*, const std::string& local_name, bool is_local_name_exported); import(Gogo*, const std::string& local_name, bool is_local_name_exported);
// The location of the import statement. // The location of the import statement.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -190,17 +191,17 @@ class Import
private: private:
static Stream* static Stream*
try_package_in_directory(const std::string&, source_location); try_package_in_directory(const std::string&, Location);
static int static int
try_suffixes(std::string*); try_suffixes(std::string*);
static Stream* static Stream*
find_export_data(const std::string& filename, int fd, source_location); find_export_data(const std::string& filename, int fd, Location);
static Stream* static Stream*
find_object_export_data(const std::string& filename, int fd, find_object_export_data(const std::string& filename, int fd,
off_t offset, source_location); off_t offset, Location);
static const int archive_magic_len = 8; static const int archive_magic_len = 8;
@ -209,7 +210,7 @@ class Import
static Stream* static Stream*
find_archive_export_data(const std::string& filename, int fd, find_archive_export_data(const std::string& filename, int fd,
source_location); Location);
// Read the import control functions. // Read the import control functions.
void void
@ -244,7 +245,7 @@ class Import
// The stream from which to read import data. // The stream from which to read import data.
Stream* stream_; Stream* stream_;
// The location of the import statement we are processing. // The location of the import statement we are processing.
source_location location_; Location location_;
// The package we are importing. // The package we are importing.
Package* package_; Package* package_;
// Whether to add new objects to the global scope, rather than to a // Whether to add new objects to the global scope, rather than to a

View File

@ -146,7 +146,7 @@ static Keywords keywords;
// Make a general token. // Make a general token.
Token::Token(Classification classification, source_location location) Token::Token(Classification classification, Location location)
: classification_(classification), location_(location) : classification_(classification), location_(location)
{ {
} }
@ -432,19 +432,18 @@ Token::print(FILE* file) const
// Class Lex. // Class Lex.
Lex::Lex(const char* input_file_name, FILE* input_file) Lex::Lex(const char* input_file_name, FILE* input_file, Linemap* linemap)
: input_file_name_(input_file_name), input_file_(input_file), : input_file_name_(input_file_name), input_file_(input_file),
linebuf_(NULL), linebufsize_(120), linesize_(0), lineoff_(0), linemap_(linemap), linebuf_(NULL), linebufsize_(120), linesize_(0),
lineno_(0), add_semi_at_eol_(false) lineoff_(0), lineno_(0), add_semi_at_eol_(false)
{ {
this->linebuf_ = new char[this->linebufsize_]; this->linebuf_ = new char[this->linebufsize_];
linemap_add(line_table, LC_ENTER, 0, input_file_name, 1); this->linemap_->start_file(input_file_name, 0);
} }
Lex::~Lex() Lex::~Lex()
{ {
delete[] this->linebuf_; delete[] this->linebuf_;
linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
} }
// Read a new line from the file. // Read a new line from the file.
@ -508,26 +507,26 @@ Lex::require_line()
this->linesize_= got; this->linesize_= got;
this->lineoff_ = 0; this->lineoff_ = 0;
linemap_line_start(line_table, this->lineno_, this->linesize_); this->linemap_->start_line(this->lineno_, this->linesize_);
return true; return true;
} }
// Get the current location. // Get the current location.
source_location Location
Lex::location() const Lex::location() const
{ {
return linemap_position_for_column (line_table, this->lineoff_ + 1); return this->linemap_->get_location(this->lineoff_ + 1);
} }
// Get a location slightly before the current one. This is used for // Get a location slightly before the current one. This is used for
// slightly more efficient handling of operator tokens. // slightly more efficient handling of operator tokens.
source_location Location
Lex::earlier_location(int chars) const Lex::earlier_location(int chars) const
{ {
return linemap_position_for_column (line_table, this->lineoff_ + 1 - chars); return this->linemap_->get_location(this->lineoff_ + 1 - chars);
} }
// Get the next token. // Get the next token.
@ -586,7 +585,7 @@ Lex::next_token()
else if (p[1] == '*') else if (p[1] == '*')
{ {
this->lineoff_ = p - this->linebuf_; this->lineoff_ = p - this->linebuf_;
source_location location = this->location(); Location location = this->location();
if (!this->skip_c_comment()) if (!this->skip_c_comment())
return Token::make_invalid_token(location); return Token::make_invalid_token(location);
p = this->linebuf_ + this->lineoff_; p = this->linebuf_ + this->lineoff_;
@ -889,7 +888,7 @@ Lex::gather_identifier()
buf.append(ubuf); buf.append(ubuf);
} }
} }
source_location location = this->location(); Location location = this->location();
this->add_semi_at_eol_ = true; this->add_semi_at_eol_ = true;
this->lineoff_ = p - this->linebuf_; this->lineoff_ = p - this->linebuf_;
if (has_non_ascii_char) if (has_non_ascii_char)
@ -956,7 +955,7 @@ Lex::gather_number()
const char* p = pstart; const char* p = pstart;
const char* pend = this->linebuf_ + this->linesize_; const char* pend = this->linebuf_ + this->linesize_;
source_location location = this->location(); Location location = this->location();
bool neg = false; bool neg = false;
if (*p == '+') if (*p == '+')
@ -1253,7 +1252,7 @@ Lex::advance_one_char(const char* p, bool is_single_quote, unsigned int* value,
void void
Lex::append_char(unsigned int v, bool is_character, std::string* str, Lex::append_char(unsigned int v, bool is_character, std::string* str,
source_location location) Location location)
{ {
char buf[4]; char buf[4];
size_t len; size_t len;
@ -1319,7 +1318,7 @@ Lex::gather_character()
mpz_t val; mpz_t val;
mpz_init_set_ui(val, value); mpz_init_set_ui(val, value);
source_location location = this->location(); Location location = this->location();
this->lineoff_ = p + 1 - this->linebuf_; this->lineoff_ = p + 1 - this->linebuf_;
Token ret = Token::make_integer_token(val, location); Token ret = Token::make_integer_token(val, location);
mpz_clear(val); mpz_clear(val);
@ -1338,7 +1337,7 @@ Lex::gather_string()
std::string value; std::string value;
while (*p != '"') while (*p != '"')
{ {
source_location loc = this->location(); Location loc = this->location();
unsigned int c; unsigned int c;
bool is_character; bool is_character;
this->lineoff_ = p - this->linebuf_; this->lineoff_ = p - this->linebuf_;
@ -1352,7 +1351,7 @@ Lex::gather_string()
Lex::append_char(c, is_character, &value, loc); Lex::append_char(c, is_character, &value, loc);
} }
source_location location = this->location(); Location location = this->location();
this->lineoff_ = p + 1 - this->linebuf_; this->lineoff_ = p + 1 - this->linebuf_;
return Token::make_string_token(value, location); return Token::make_string_token(value, location);
} }
@ -1364,7 +1363,7 @@ Lex::gather_raw_string()
{ {
const char* p = this->linebuf_ + this->lineoff_ + 1; const char* p = this->linebuf_ + this->lineoff_ + 1;
const char* pend = this->linebuf_ + this->linesize_; const char* pend = this->linebuf_ + this->linesize_;
source_location location = this->location(); Location location = this->location();
std::string value; std::string value;
while (true) while (true)
@ -1376,7 +1375,7 @@ Lex::gather_raw_string()
this->lineoff_ = p + 1 - this->linebuf_; this->lineoff_ = p + 1 - this->linebuf_;
return Token::make_string_token(value, location); return Token::make_string_token(value, location);
} }
source_location loc = this->location(); Location loc = this->location();
unsigned int c; unsigned int c;
bool issued_error; bool issued_error;
this->lineoff_ = p - this->linebuf_; this->lineoff_ = p - this->linebuf_;
@ -1630,8 +1629,7 @@ Lex::skip_cpp_comment()
memcpy(file, p, filelen); memcpy(file, p, filelen);
file[filelen] = '\0'; file[filelen] = '\0';
linemap_add(line_table, LC_LEAVE, 0, NULL, 0); this->linemap_->start_file(file, lineno);
linemap_add(line_table, LC_ENTER, 0, file, lineno);
this->lineno_ = lineno - 1; this->lineno_ = lineno - 1;
p = plend; p = plend;

View File

@ -11,6 +11,7 @@
#include <mpfr.h> #include <mpfr.h>
#include "operator.h" #include "operator.h"
#include "go-linemap.h"
struct Unicode_range; struct Unicode_range;
@ -88,17 +89,17 @@ class Token
// Make a token for an invalid value. // Make a token for an invalid value.
static Token static Token
make_invalid_token(source_location location) make_invalid_token(Location location)
{ return Token(TOKEN_INVALID, location); } { return Token(TOKEN_INVALID, location); }
// Make a token representing end of file. // Make a token representing end of file.
static Token static Token
make_eof_token(source_location location) make_eof_token(Location location)
{ return Token(TOKEN_EOF, location); } { return Token(TOKEN_EOF, location); }
// Make a keyword token. // Make a keyword token.
static Token static Token
make_keyword_token(Keyword keyword, source_location location) make_keyword_token(Keyword keyword, Location location)
{ {
Token tok(TOKEN_KEYWORD, location); Token tok(TOKEN_KEYWORD, location);
tok.u_.keyword = keyword; tok.u_.keyword = keyword;
@ -108,7 +109,7 @@ class Token
// Make an identifier token. // Make an identifier token.
static Token static Token
make_identifier_token(const std::string& value, bool is_exported, make_identifier_token(const std::string& value, bool is_exported,
source_location location) Location location)
{ {
Token tok(TOKEN_IDENTIFIER, location); Token tok(TOKEN_IDENTIFIER, location);
tok.u_.identifier_value.name = new std::string(value); tok.u_.identifier_value.name = new std::string(value);
@ -118,7 +119,7 @@ class Token
// Make a quoted string token. // Make a quoted string token.
static Token static Token
make_string_token(const std::string& value, source_location location) make_string_token(const std::string& value, Location location)
{ {
Token tok(TOKEN_STRING, location); Token tok(TOKEN_STRING, location);
tok.u_.string_value = new std::string(value); tok.u_.string_value = new std::string(value);
@ -127,7 +128,7 @@ class Token
// Make an operator token. // Make an operator token.
static Token static Token
make_operator_token(Operator op, source_location location) make_operator_token(Operator op, Location location)
{ {
Token tok(TOKEN_OPERATOR, location); Token tok(TOKEN_OPERATOR, location);
tok.u_.op = op; tok.u_.op = op;
@ -136,7 +137,7 @@ class Token
// Make an integer token. // Make an integer token.
static Token static Token
make_integer_token(mpz_t val, source_location location) make_integer_token(mpz_t val, Location location)
{ {
Token tok(TOKEN_INTEGER, location); Token tok(TOKEN_INTEGER, location);
mpz_init(tok.u_.integer_value); mpz_init(tok.u_.integer_value);
@ -146,7 +147,7 @@ class Token
// Make a float token. // Make a float token.
static Token static Token
make_float_token(mpfr_t val, source_location location) make_float_token(mpfr_t val, Location location)
{ {
Token tok(TOKEN_FLOAT, location); Token tok(TOKEN_FLOAT, location);
mpfr_init(tok.u_.float_value); mpfr_init(tok.u_.float_value);
@ -156,7 +157,7 @@ class Token
// Make a token for an imaginary number. // Make a token for an imaginary number.
static Token static Token
make_imaginary_token(mpfr_t val, source_location location) make_imaginary_token(mpfr_t val, Location location)
{ {
Token tok(TOKEN_IMAGINARY, location); Token tok(TOKEN_IMAGINARY, location);
mpfr_init(tok.u_.float_value); mpfr_init(tok.u_.float_value);
@ -165,7 +166,7 @@ class Token
} }
// Get the location of the token. // Get the location of the token.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -275,7 +276,7 @@ class Token
private: private:
// Private constructor used by make_..._token functions above. // Private constructor used by make_..._token functions above.
Token(Classification, source_location); Token(Classification, Location);
// Clear the token. // Clear the token.
void void
@ -307,7 +308,7 @@ class Token
Operator op; Operator op;
} u_; } u_;
// The source location. // The source location.
source_location location_; Location location_;
}; };
// The lexer itself. // The lexer itself.
@ -315,7 +316,7 @@ class Token
class Lex class Lex
{ {
public: public:
Lex(const char* input_file_name, FILE* input_file); Lex(const char* input_file_name, FILE* input_file, Linemap *linemap);
~Lex(); ~Lex();
@ -334,7 +335,7 @@ class Lex
// location is used to warn about an out of range character. // location is used to warn about an out of range character.
static void static void
append_char(unsigned int v, bool is_charater, std::string* str, append_char(unsigned int v, bool is_charater, std::string* str,
source_location); Location);
// A helper function. Fetch a UTF-8 character from STR and store it // A helper function. Fetch a UTF-8 character from STR and store it
// in *VALUE. Return the number of bytes read from STR. Return 0 // in *VALUE. Return the number of bytes read from STR. Return 0
@ -350,11 +351,11 @@ class Lex
require_line(); require_line();
// The current location. // The current location.
source_location Location
location() const; location() const;
// A position CHARS column positions before the current location. // A position CHARS column positions before the current location.
source_location Location
earlier_location(int chars) const; earlier_location(int chars) const;
static bool static bool
@ -432,6 +433,8 @@ class Lex
const char* input_file_name_; const char* input_file_name_;
// The input file. // The input file.
FILE* input_file_; FILE* input_file_;
// The object used to keep track of file names and line numbers.
Linemap* linemap_;
// The line buffer. This holds the current line. // The line buffer. This holds the current line.
char* linebuf_; char* linebuf_;
// The size of the line buffer. // The size of the line buffer.

View File

@ -42,8 +42,8 @@ Parse::Enclosing_var_comparison::operator()(const Enclosing_var& v1,
Parse::Parse(Lex* lex, Gogo* gogo) Parse::Parse(Lex* lex, Gogo* gogo)
: lex_(lex), : lex_(lex),
token_(Token::make_invalid_token(0)), token_(Token::make_invalid_token(Linemap::unknown_location())),
unget_token_(Token::make_invalid_token(0)), unget_token_(Token::make_invalid_token(Linemap::unknown_location())),
unget_token_valid_(false), unget_token_valid_(false),
gogo_(gogo), gogo_(gogo),
break_stack_(NULL), break_stack_(NULL),
@ -92,7 +92,7 @@ Parse::unget_token(const Token& token)
// The location of the current token. // The location of the current token.
source_location Location
Parse::location() Parse::location()
{ {
return this->peek_token()->location(); return this->peek_token()->location();
@ -142,7 +142,7 @@ Parse::expression_list(Expression* first, bool may_be_sink)
return ret; return ret;
// Most expression lists permit a trailing comma. // Most expression lists permit a trailing comma.
source_location location = token->location(); Location location = token->location();
this->advance_token(); this->advance_token();
if (!this->expression_may_start_here()) if (!this->expression_may_start_here())
{ {
@ -242,7 +242,7 @@ Parse::type()
return this->interface_type(); return this->interface_type();
else if (token->is_keyword(KEYWORD_FUNC)) else if (token->is_keyword(KEYWORD_FUNC))
{ {
source_location location = token->location(); Location location = token->location();
this->advance_token(); this->advance_token();
Type* type = this->signature(NULL, location); Type* type = this->signature(NULL, location);
if (type == NULL) if (type == NULL)
@ -299,7 +299,7 @@ Parse::type_may_start_here()
Type* Type*
Parse::type_name(bool issue_error) Parse::type_name(bool issue_error)
{ {
source_location location = this->location(); Location location = this->location();
std::string name; std::string name;
Named_object* package; Named_object* package;
@ -425,7 +425,7 @@ Parse::array_type(bool may_use_ellipsis)
Type* Type*
Parse::map_type() Parse::map_type()
{ {
source_location location = this->location(); Location location = this->location();
go_assert(this->peek_token()->is_keyword(KEYWORD_MAP)); go_assert(this->peek_token()->is_keyword(KEYWORD_MAP));
if (!this->advance_token()->is_op(OPERATOR_LSQUARE)) if (!this->advance_token()->is_op(OPERATOR_LSQUARE))
{ {
@ -457,10 +457,10 @@ Type*
Parse::struct_type() Parse::struct_type()
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_STRUCT)); go_assert(this->peek_token()->is_keyword(KEYWORD_STRUCT));
source_location location = this->location(); Location location = this->location();
if (!this->advance_token()->is_op(OPERATOR_LCURLY)) if (!this->advance_token()->is_op(OPERATOR_LCURLY))
{ {
source_location token_loc = this->location(); Location token_loc = this->location();
if (this->peek_token()->is_op(OPERATOR_SEMICOLON) if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
&& this->advance_token()->is_op(OPERATOR_LCURLY)) && this->advance_token()->is_op(OPERATOR_LCURLY))
error_at(token_loc, "unexpected semicolon or newline before %<{%>"); error_at(token_loc, "unexpected semicolon or newline before %<{%>");
@ -514,7 +514,7 @@ void
Parse::field_decl(Struct_field_list* sfl) Parse::field_decl(Struct_field_list* sfl)
{ {
const Token* token = this->peek_token(); const Token* token = this->peek_token();
source_location location = token->location(); Location location = token->location();
bool is_anonymous; bool is_anonymous;
bool is_anonymous_pointer; bool is_anonymous_pointer;
if (token->is_op(OPERATOR_MULT)) if (token->is_op(OPERATOR_MULT))
@ -526,7 +526,7 @@ Parse::field_decl(Struct_field_list* sfl)
{ {
std::string id = token->identifier(); std::string id = token->identifier();
bool is_id_exported = token->is_identifier_exported(); bool is_id_exported = token->is_identifier_exported();
source_location id_location = token->location(); Location id_location = token->location();
token = this->advance_token(); token = this->advance_token();
is_anonymous = (token->is_op(OPERATOR_SEMICOLON) is_anonymous = (token->is_op(OPERATOR_SEMICOLON)
|| token->is_op(OPERATOR_RCURLY) || token->is_op(OPERATOR_RCURLY)
@ -718,7 +718,7 @@ Parse::check_signature_names(const Typed_identifier_list* params,
// This returns NULL on a parse error. // This returns NULL on a parse error.
Function_type* Function_type*
Parse::signature(Typed_identifier* receiver, source_location location) Parse::signature(Typed_identifier* receiver, Location location)
{ {
bool is_varargs = false; bool is_varargs = false;
Typed_identifier_list* params; Typed_identifier_list* params;
@ -801,7 +801,7 @@ Parse::parameters(Typed_identifier_list** pparams, bool* is_varargs)
Typed_identifier_list* Typed_identifier_list*
Parse::parameter_list(bool* is_varargs) Parse::parameter_list(bool* is_varargs)
{ {
source_location location = this->location(); Location location = this->location();
Typed_identifier_list* ret = new Typed_identifier_list(); Typed_identifier_list* ret = new Typed_identifier_list();
bool saw_error = false; bool saw_error = false;
@ -822,7 +822,7 @@ Parse::parameter_list(bool* is_varargs)
{ {
std::string name = token->identifier(); std::string name = token->identifier();
bool is_exported = token->is_identifier_exported(); bool is_exported = token->is_identifier_exported();
source_location location = token->location(); Location location = token->location();
token = this->advance_token(); token = this->advance_token();
if (!token->is_op(OPERATOR_COMMA)) if (!token->is_op(OPERATOR_COMMA))
{ {
@ -1000,7 +1000,7 @@ Parse::parameter_decl(bool parameters_have_names,
if (!parameters_have_names) if (!parameters_have_names)
{ {
Type* type; Type* type;
source_location location = this->location(); Location location = this->location();
if (!this->peek_token()->is_identifier()) if (!this->peek_token()->is_identifier())
{ {
if (!this->peek_token()->is_op(OPERATOR_ELLIPSIS)) if (!this->peek_token()->is_op(OPERATOR_ELLIPSIS))
@ -1078,7 +1078,7 @@ Parse::result(Typed_identifier_list** presults)
return this->parameters(presults, NULL); return this->parameters(presults, NULL);
else else
{ {
source_location location = this->location(); Location location = this->location();
Type* type = this->type(); Type* type = this->type();
if (type->is_error_type()) if (type->is_error_type())
{ {
@ -1096,19 +1096,19 @@ Parse::result(Typed_identifier_list** presults)
// Returns the location of the closing brace. // Returns the location of the closing brace.
source_location Location
Parse::block() Parse::block()
{ {
if (!this->peek_token()->is_op(OPERATOR_LCURLY)) if (!this->peek_token()->is_op(OPERATOR_LCURLY))
{ {
source_location loc = this->location(); Location loc = this->location();
if (this->peek_token()->is_op(OPERATOR_SEMICOLON) if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
&& this->advance_token()->is_op(OPERATOR_LCURLY)) && this->advance_token()->is_op(OPERATOR_LCURLY))
error_at(loc, "unexpected semicolon or newline before %<{%>"); error_at(loc, "unexpected semicolon or newline before %<{%>");
else else
{ {
error_at(this->location(), "expected %<{%>"); error_at(this->location(), "expected %<{%>");
return UNKNOWN_LOCATION; return Linemap::unknown_location();
} }
} }
@ -1125,7 +1125,7 @@ Parse::block()
// Skip ahead to the end of the block, in hopes of avoiding // Skip ahead to the end of the block, in hopes of avoiding
// lots of meaningless errors. // lots of meaningless errors.
source_location ret = token->location(); Location ret = token->location();
int nest = 0; int nest = 0;
while (!token->is_eof()) while (!token->is_eof())
{ {
@ -1147,7 +1147,7 @@ Parse::block()
} }
} }
source_location ret = token->location(); Location ret = token->location();
this->advance_token(); this->advance_token();
return ret; return ret;
} }
@ -1159,11 +1159,11 @@ Type*
Parse::interface_type() Parse::interface_type()
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_INTERFACE)); go_assert(this->peek_token()->is_keyword(KEYWORD_INTERFACE));
source_location location = this->location(); Location location = this->location();
if (!this->advance_token()->is_op(OPERATOR_LCURLY)) if (!this->advance_token()->is_op(OPERATOR_LCURLY))
{ {
source_location token_loc = this->location(); Location token_loc = this->location();
if (this->peek_token()->is_op(OPERATOR_SEMICOLON) if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
&& this->advance_token()->is_op(OPERATOR_LCURLY)) && this->advance_token()->is_op(OPERATOR_LCURLY))
error_at(token_loc, "unexpected semicolon or newline before %<{%>"); error_at(token_loc, "unexpected semicolon or newline before %<{%>");
@ -1224,7 +1224,7 @@ Parse::method_spec(Typed_identifier_list* methods)
std::string name = token->identifier(); std::string name = token->identifier();
bool is_exported = token->is_identifier_exported(); bool is_exported = token->is_identifier_exported();
source_location location = token->location(); Location location = token->location();
if (this->advance_token()->is_op(OPERATOR_LPAREN)) if (this->advance_token()->is_op(OPERATOR_LPAREN))
{ {
@ -1472,7 +1472,7 @@ Parse::type_spec(void*)
} }
std::string name = token->identifier(); std::string name = token->identifier();
bool is_exported = token->is_identifier_exported(); bool is_exported = token->is_identifier_exported();
source_location location = token->location(); Location location = token->location();
token = this->advance_token(); token = this->advance_token();
// The scope of the type name starts at the point where the // The scope of the type name starts at the point where the
@ -1549,7 +1549,7 @@ Parse::var_spec(void*)
Typed_identifier_list til; Typed_identifier_list til;
this->identifier_list(&til); this->identifier_list(&til);
source_location location = this->location(); Location location = this->location();
Type* type = NULL; Type* type = NULL;
Expression_list* init = NULL; Expression_list* init = NULL;
@ -1588,7 +1588,7 @@ Parse::var_spec(void*)
void void
Parse::init_vars(const Typed_identifier_list* til, Type* type, Parse::init_vars(const Typed_identifier_list* til, Type* type,
Expression_list* init, bool is_coloneq, Expression_list* init, bool is_coloneq,
source_location location) Location location)
{ {
// Check for an initialization which can yield multiple values. // Check for an initialization which can yield multiple values.
if (init != NULL && init->size() == 1 && til->size() > 1) if (init != NULL && init->size() == 1 && til->size() > 1)
@ -1648,7 +1648,7 @@ Parse::init_vars(const Typed_identifier_list* til, Type* type,
bool bool
Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type, Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
Expression* expr, bool is_coloneq, Expression* expr, bool is_coloneq,
source_location location) Location location)
{ {
Call_expression* call = expr->call_expression(); Call_expression* call = expr->call_expression();
if (call == NULL) if (call == NULL)
@ -1681,7 +1681,7 @@ Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
bool bool
Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type, Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type,
Expression* expr, bool is_coloneq, Expression* expr, bool is_coloneq,
source_location location) Location location)
{ {
Index_expression* index = expr->index_expression(); Index_expression* index = expr->index_expression();
if (index == NULL) if (index == NULL)
@ -1746,7 +1746,7 @@ Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type,
bool bool
Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type, Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type,
Expression* expr, bool is_coloneq, Expression* expr, bool is_coloneq,
source_location location) Location location)
{ {
Receive_expression* receive = expr->receive_expression(); Receive_expression* receive = expr->receive_expression();
if (receive == NULL) if (receive == NULL)
@ -1812,7 +1812,7 @@ Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type,
bool bool
Parse::init_vars_from_type_guard(const Typed_identifier_list* vars, Parse::init_vars_from_type_guard(const Typed_identifier_list* vars,
Type* type, Expression* expr, Type* type, Expression* expr,
bool is_coloneq, source_location location) bool is_coloneq, Location location)
{ {
Type_guard_expression* type_guard = expr->type_guard_expression(); Type_guard_expression* type_guard = expr->type_guard_expression();
if (type_guard == NULL) if (type_guard == NULL)
@ -1878,7 +1878,7 @@ Named_object*
Parse::init_var(const Typed_identifier& tid, Type* type, Expression* init, Parse::init_var(const Typed_identifier& tid, Type* type, Expression* init,
bool is_coloneq, bool type_from_init, bool* is_new) bool is_coloneq, bool type_from_init, bool* is_new)
{ {
source_location location = tid.location(); Location location = tid.location();
if (Gogo::is_sink_name(tid.name())) if (Gogo::is_sink_name(tid.name()))
{ {
@ -1927,7 +1927,7 @@ Parse::init_var(const Typed_identifier& tid, Type* type, Expression* init,
Named_object* Named_object*
Parse::create_dummy_global(Type* type, Expression* init, Parse::create_dummy_global(Type* type, Expression* init,
source_location location) Location location)
{ {
if (type == NULL && init == NULL) if (type == NULL && init == NULL)
type = Type::lookup_bool_type(); type = Type::lookup_bool_type();
@ -1956,7 +1956,7 @@ Parse::create_dummy_global(Type* type, Expression* init,
void void
Parse::simple_var_decl_or_assignment(const std::string& name, Parse::simple_var_decl_or_assignment(const std::string& name,
source_location location, Location location,
Range_clause* p_range_clause, Range_clause* p_range_clause,
Type_switch* p_type_switch) Type_switch* p_type_switch)
{ {
@ -1976,7 +1976,7 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
std::string id = token->identifier(); std::string id = token->identifier();
bool is_id_exported = token->is_identifier_exported(); bool is_id_exported = token->is_identifier_exported();
source_location id_location = token->location(); Location id_location = token->location();
token = this->advance_token(); token = this->advance_token();
if (!token->is_op(OPERATOR_COMMA)) if (!token->is_op(OPERATOR_COMMA))
@ -2079,7 +2079,7 @@ void
Parse::function_decl() Parse::function_decl()
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_FUNC)); go_assert(this->peek_token()->is_keyword(KEYWORD_FUNC));
source_location location = this->location(); Location location = this->location();
const Token* token = this->advance_token(); const Token* token = this->advance_token();
Typed_identifier* rec = NULL; Typed_identifier* rec = NULL;
@ -2138,7 +2138,7 @@ Parse::function_decl()
// Check for the easy error of a newline before the opening brace. // Check for the easy error of a newline before the opening brace.
if (this->peek_token()->is_op(OPERATOR_SEMICOLON)) if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
{ {
source_location semi_loc = this->location(); Location semi_loc = this->location();
if (this->advance_token()->is_op(OPERATOR_LCURLY)) if (this->advance_token()->is_op(OPERATOR_LCURLY))
error_at(this->location(), error_at(this->location(),
"unexpected semicolon or newline before %<{%>"); "unexpected semicolon or newline before %<{%>");
@ -2155,7 +2155,7 @@ Parse::function_decl()
else else
{ {
this->gogo_->start_function(name, fntype, true, location); this->gogo_->start_function(name, fntype, true, location);
source_location end_loc = this->block(); Location end_loc = this->block();
this->gogo_->finish_function(end_loc); this->gogo_->finish_function(end_loc);
} }
} }
@ -2170,7 +2170,7 @@ Parse::receiver()
std::string name; std::string name;
const Token* token = this->advance_token(); const Token* token = this->advance_token();
source_location location = token->location(); Location location = token->location();
if (!token->is_op(OPERATOR_MULT)) if (!token->is_op(OPERATOR_MULT))
{ {
if (!token->is_identifier()) if (!token->is_identifier())
@ -2271,7 +2271,7 @@ Parse::operand(bool may_be_sink)
{ {
case Token::TOKEN_IDENTIFIER: case Token::TOKEN_IDENTIFIER:
{ {
source_location location = token->location(); Location location = token->location();
std::string id = token->identifier(); std::string id = token->identifier();
bool is_exported = token->is_identifier_exported(); bool is_exported = token->is_identifier_exported();
std::string packed = this->gogo_->pack_hidden_name(id, is_exported); std::string packed = this->gogo_->pack_hidden_name(id, is_exported);
@ -2412,7 +2412,7 @@ Parse::operand(bool may_be_sink)
case KEYWORD_MAP: case KEYWORD_MAP:
case KEYWORD_STRUCT: case KEYWORD_STRUCT:
{ {
source_location location = token->location(); Location location = token->location();
return Expression::make_type(this->type(), location); return Expression::make_type(this->type(), location);
} }
default: default:
@ -2435,7 +2435,7 @@ Parse::operand(bool may_be_sink)
{ {
// Here we call array_type directly, as this is the only // Here we call array_type directly, as this is the only
// case where an ellipsis is permitted for an array type. // case where an ellipsis is permitted for an array type.
source_location location = token->location(); Location location = token->location();
return Expression::make_type(this->array_type(true), location); return Expression::make_type(this->array_type(true), location);
} }
break; break;
@ -2455,7 +2455,7 @@ Parse::operand(bool may_be_sink)
Expression* Expression*
Parse::enclosing_var_reference(Named_object* in_function, Named_object* var, Parse::enclosing_var_reference(Named_object* in_function, Named_object* var,
source_location location) Location location)
{ {
go_assert(var->is_variable() || var->is_result_variable()); go_assert(var->is_variable() || var->is_result_variable());
@ -2505,7 +2505,7 @@ Parse::enclosing_var_reference(Named_object* in_function, Named_object* var,
// 1. In [][][]int{{{1}}} it will be 2. // 1. In [][][]int{{{1}}} it will be 2.
Expression* Expression*
Parse::composite_lit(Type* type, int depth, source_location location) Parse::composite_lit(Type* type, int depth, Location location)
{ {
go_assert(this->peek_token()->is_op(OPERATOR_LCURLY)); go_assert(this->peek_token()->is_op(OPERATOR_LCURLY));
this->advance_token(); this->advance_token();
@ -2530,7 +2530,7 @@ Parse::composite_lit(Type* type, int depth, source_location location)
{ {
std::string identifier = token->identifier(); std::string identifier = token->identifier();
bool is_exported = token->is_identifier_exported(); bool is_exported = token->is_identifier_exported();
source_location location = token->location(); Location location = token->location();
if (this->advance_token()->is_op(OPERATOR_COLON)) if (this->advance_token()->is_op(OPERATOR_COLON))
{ {
@ -2656,7 +2656,7 @@ Parse::composite_lit(Type* type, int depth, source_location location)
Expression* Expression*
Parse::function_lit() Parse::function_lit()
{ {
source_location location = this->location(); Location location = this->location();
go_assert(this->peek_token()->is_keyword(KEYWORD_FUNC)); go_assert(this->peek_token()->is_keyword(KEYWORD_FUNC));
this->advance_token(); this->advance_token();
@ -2679,7 +2679,7 @@ Parse::function_lit()
Named_object* no = this->gogo_->start_function("", type, true, location); Named_object* no = this->gogo_->start_function("", type, true, location);
source_location end_loc = this->block(); Location end_loc = this->block();
this->gogo_->finish_function(end_loc); this->gogo_->finish_function(end_loc);
@ -2706,7 +2706,7 @@ Parse::function_lit()
Expression* Expression*
Parse::create_closure(Named_object* function, Enclosing_vars* enclosing_vars, Parse::create_closure(Named_object* function, Enclosing_vars* enclosing_vars,
source_location location) Location location)
{ {
if (enclosing_vars->empty()) if (enclosing_vars->empty())
return NULL; return NULL;
@ -2761,7 +2761,7 @@ Expression*
Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit, Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
bool* is_type_switch) bool* is_type_switch)
{ {
source_location start_loc = this->location(); Location start_loc = this->location();
bool is_parenthesized = this->peek_token()->is_op(OPERATOR_LPAREN); bool is_parenthesized = this->peek_token()->is_op(OPERATOR_LPAREN);
Expression* ret = this->operand(may_be_sink); Expression* ret = this->operand(may_be_sink);
@ -2792,7 +2792,7 @@ Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
} }
else if (this->peek_token()->is_op(OPERATOR_LPAREN)) else if (this->peek_token()->is_op(OPERATOR_LPAREN))
{ {
source_location loc = this->location(); Location loc = this->location();
this->advance_token(); this->advance_token();
Expression* expr = this->expression(PRECEDENCE_NORMAL, false, true, Expression* expr = this->expression(PRECEDENCE_NORMAL, false, true,
NULL); NULL);
@ -2859,7 +2859,7 @@ Expression*
Parse::selector(Expression* left, bool* is_type_switch) Parse::selector(Expression* left, bool* is_type_switch)
{ {
go_assert(this->peek_token()->is_op(OPERATOR_DOT)); go_assert(this->peek_token()->is_op(OPERATOR_DOT));
source_location location = this->location(); Location location = this->location();
const Token* token = this->advance_token(); const Token* token = this->advance_token();
if (token->is_identifier()) if (token->is_identifier())
@ -2917,7 +2917,7 @@ Parse::selector(Expression* left, bool* is_type_switch)
Expression* Expression*
Parse::index(Expression* expr) Parse::index(Expression* expr)
{ {
source_location location = this->location(); Location location = this->location();
go_assert(this->peek_token()->is_op(OPERATOR_LSQUARE)); go_assert(this->peek_token()->is_op(OPERATOR_LSQUARE));
this->advance_token(); this->advance_token();
@ -2982,7 +2982,7 @@ Parse::call(Expression* func)
// Return an expression for a single unqualified identifier. // Return an expression for a single unqualified identifier.
Expression* Expression*
Parse::id_to_expression(const std::string& name, source_location location) Parse::id_to_expression(const std::string& name, Location location)
{ {
Named_object* in_function; Named_object* in_function;
Named_object* named_object = this->gogo_->lookup(name, &in_function); Named_object* named_object = this->gogo_->lookup(name, &in_function);
@ -3096,7 +3096,7 @@ Parse::expression(Precedence precedence, bool may_be_sink,
} }
Operator op = token->op(); Operator op = token->op();
source_location binop_location = token->location(); Location binop_location = token->location();
if (precedence >= right_precedence) if (precedence >= right_precedence)
{ {
@ -3188,7 +3188,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
|| token->is_op(OPERATOR_MULT) || token->is_op(OPERATOR_MULT)
|| token->is_op(OPERATOR_AND)) || token->is_op(OPERATOR_AND))
{ {
source_location location = token->location(); Location location = token->location();
Operator op = token->op(); Operator op = token->op();
this->advance_token(); this->advance_token();
@ -3288,7 +3288,7 @@ Parse::statement(Label* label)
{ {
std::string identifier = token->identifier(); std::string identifier = token->identifier();
bool is_exported = token->is_identifier_exported(); bool is_exported = token->is_identifier_exported();
source_location location = token->location(); Location location = token->location();
if (this->advance_token()->is_op(OPERATOR_COLON)) if (this->advance_token()->is_op(OPERATOR_COLON))
{ {
this->advance_token(); this->advance_token();
@ -3307,9 +3307,9 @@ Parse::statement(Label* label)
case Token::TOKEN_OPERATOR: case Token::TOKEN_OPERATOR:
if (token->is_op(OPERATOR_LCURLY)) if (token->is_op(OPERATOR_LCURLY))
{ {
source_location location = token->location(); Location location = token->location();
this->gogo_->start_block(location); this->gogo_->start_block(location);
source_location end_loc = this->block(); Location end_loc = this->block();
this->gogo_->add_block(this->gogo_->finish_block(end_loc), this->gogo_->add_block(this->gogo_->finish_block(end_loc),
location); location);
} }
@ -3391,7 +3391,7 @@ Parse::statement_may_start_here()
// Label = identifier . // Label = identifier .
void void
Parse::labeled_stmt(const std::string& label_name, source_location location) Parse::labeled_stmt(const std::string& label_name, Location location)
{ {
Label* label = this->gogo_->add_label_definition(label_name, location); Label* label = this->gogo_->add_label_definition(label_name, location);
@ -3447,7 +3447,7 @@ Parse::simple_stat(bool may_be_composite_lit, bool* return_exp,
{ {
std::string identifier = token->identifier(); std::string identifier = token->identifier();
bool is_exported = token->is_identifier_exported(); bool is_exported = token->is_identifier_exported();
source_location location = token->location(); Location location = token->location();
token = this->advance_token(); token = this->advance_token();
if (token->is_op(OPERATOR_COLONEQ) if (token->is_op(OPERATOR_COLONEQ)
@ -3576,7 +3576,7 @@ void
Parse::send_stmt(Expression* channel) Parse::send_stmt(Expression* channel)
{ {
go_assert(this->peek_token()->is_op(OPERATOR_CHANOP)); go_assert(this->peek_token()->is_op(OPERATOR_CHANOP));
source_location loc = this->location(); Location loc = this->location();
this->advance_token(); this->advance_token();
Expression* val = this->expression(PRECEDENCE_NORMAL, false, true, NULL); Expression* val = this->expression(PRECEDENCE_NORMAL, false, true, NULL);
Statement* s = Statement::make_send_statement(channel, val, loc); Statement* s = Statement::make_send_statement(channel, val, loc);
@ -3655,7 +3655,7 @@ Parse::tuple_assignment(Expression_list* lhs, Range_clause* p_range_clause)
return; return;
} }
Operator op = token->op(); Operator op = token->op();
source_location location = token->location(); Location location = token->location();
token = this->advance_token(); token = this->advance_token();
@ -3803,9 +3803,9 @@ Parse::go_or_defer_stat()
go_assert(this->peek_token()->is_keyword(KEYWORD_GO) go_assert(this->peek_token()->is_keyword(KEYWORD_GO)
|| this->peek_token()->is_keyword(KEYWORD_DEFER)); || this->peek_token()->is_keyword(KEYWORD_DEFER));
bool is_go = this->peek_token()->is_keyword(KEYWORD_GO); bool is_go = this->peek_token()->is_keyword(KEYWORD_GO);
source_location stat_location = this->location(); Location stat_location = this->location();
this->advance_token(); this->advance_token();
source_location expr_location = this->location(); Location expr_location = this->location();
Expression* expr = this->expression(PRECEDENCE_NORMAL, false, true, NULL); Expression* expr = this->expression(PRECEDENCE_NORMAL, false, true, NULL);
Call_expression* call_expr = expr->call_expression(); Call_expression* call_expr = expr->call_expression();
if (call_expr == NULL) if (call_expr == NULL)
@ -3833,7 +3833,7 @@ void
Parse::return_stat() Parse::return_stat()
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_RETURN)); go_assert(this->peek_token()->is_keyword(KEYWORD_RETURN));
source_location location = this->location(); Location location = this->location();
this->advance_token(); this->advance_token();
Expression_list* vals = NULL; Expression_list* vals = NULL;
if (this->expression_may_start_here()) if (this->expression_may_start_here())
@ -3865,7 +3865,7 @@ void
Parse::if_stat() Parse::if_stat()
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_IF)); go_assert(this->peek_token()->is_keyword(KEYWORD_IF));
source_location location = this->location(); Location location = this->location();
this->advance_token(); this->advance_token();
this->gogo_->start_block(location); this->gogo_->start_block(location);
@ -3911,13 +3911,13 @@ Parse::if_stat()
} }
this->gogo_->start_block(this->location()); this->gogo_->start_block(this->location());
source_location end_loc = this->block(); Location end_loc = this->block();
Block* then_block = this->gogo_->finish_block(end_loc); Block* then_block = this->gogo_->finish_block(end_loc);
// Check for the easy error of a newline before "else". // Check for the easy error of a newline before "else".
if (this->peek_token()->is_op(OPERATOR_SEMICOLON)) if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
{ {
source_location semi_loc = this->location(); Location semi_loc = this->location();
if (this->advance_token()->is_keyword(KEYWORD_ELSE)) if (this->advance_token()->is_keyword(KEYWORD_ELSE))
error_at(this->location(), error_at(this->location(),
"unexpected semicolon or newline before %<else%>"); "unexpected semicolon or newline before %<else%>");
@ -3962,7 +3962,7 @@ void
Parse::switch_stat(Label* label) Parse::switch_stat(Label* label)
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_SWITCH)); go_assert(this->peek_token()->is_keyword(KEYWORD_SWITCH));
source_location location = this->location(); Location location = this->location();
this->advance_token(); this->advance_token();
this->gogo_->start_block(location); this->gogo_->start_block(location);
@ -4004,7 +4004,7 @@ Parse::switch_stat(Label* label)
const Token* token = this->peek_token(); const Token* token = this->peek_token();
std::string identifier = token->identifier(); std::string identifier = token->identifier();
bool is_exported = token->is_identifier_exported(); bool is_exported = token->is_identifier_exported();
source_location id_loc = token->location(); Location id_loc = token->location();
token = this->advance_token(); token = this->advance_token();
bool is_coloneq = token->is_op(OPERATOR_COLONEQ); bool is_coloneq = token->is_op(OPERATOR_COLONEQ);
@ -4043,7 +4043,7 @@ Parse::switch_stat(Label* label)
if (!this->peek_token()->is_op(OPERATOR_LCURLY)) if (!this->peek_token()->is_op(OPERATOR_LCURLY))
{ {
source_location token_loc = this->location(); Location token_loc = this->location();
if (this->peek_token()->is_op(OPERATOR_SEMICOLON) if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
&& this->advance_token()->is_op(OPERATOR_LCURLY)) && this->advance_token()->is_op(OPERATOR_LCURLY))
error_at(token_loc, "unexpected semicolon or newline before %<{%>"); error_at(token_loc, "unexpected semicolon or newline before %<{%>");
@ -4088,7 +4088,7 @@ Parse::switch_stat(Label* label)
Statement* Statement*
Parse::expr_switch_body(Label* label, Expression* switch_val, Parse::expr_switch_body(Label* label, Expression* switch_val,
source_location location) Location location)
{ {
Switch_statement* statement = Statement::make_switch_statement(switch_val, Switch_statement* statement = Statement::make_switch_statement(switch_val,
location); location);
@ -4122,7 +4122,7 @@ Parse::expr_switch_body(Label* label, Expression* switch_val,
void void
Parse::expr_case_clause(Case_clauses* clauses, bool* saw_default) Parse::expr_case_clause(Case_clauses* clauses, bool* saw_default)
{ {
source_location location = this->location(); Location location = this->location();
bool is_default = false; bool is_default = false;
Expression_list* vals = this->expr_switch_case(&is_default); Expression_list* vals = this->expr_switch_case(&is_default);
@ -4198,7 +4198,7 @@ Parse::expr_switch_case(bool* is_default)
Statement* Statement*
Parse::type_switch_body(Label* label, const Type_switch& type_switch, Parse::type_switch_body(Label* label, const Type_switch& type_switch,
source_location location) Location location)
{ {
Named_object* switch_no = NULL; Named_object* switch_no = NULL;
if (!type_switch.name.empty()) if (!type_switch.name.empty())
@ -4243,7 +4243,7 @@ void
Parse::type_case_clause(Named_object* switch_no, Type_case_clauses* clauses, Parse::type_case_clause(Named_object* switch_no, Type_case_clauses* clauses,
bool* saw_default) bool* saw_default)
{ {
source_location location = this->location(); Location location = this->location();
std::vector<Type*> types; std::vector<Type*> types;
bool is_default = false; bool is_default = false;
@ -4355,12 +4355,12 @@ void
Parse::select_stat(Label* label) Parse::select_stat(Label* label)
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_SELECT)); go_assert(this->peek_token()->is_keyword(KEYWORD_SELECT));
source_location location = this->location(); Location location = this->location();
const Token* token = this->advance_token(); const Token* token = this->advance_token();
if (!token->is_op(OPERATOR_LCURLY)) if (!token->is_op(OPERATOR_LCURLY))
{ {
source_location token_loc = token->location(); Location token_loc = token->location();
if (token->is_op(OPERATOR_SEMICOLON) if (token->is_op(OPERATOR_SEMICOLON)
&& this->advance_token()->is_op(OPERATOR_LCURLY)) && this->advance_token()->is_op(OPERATOR_LCURLY))
error_at(token_loc, "unexpected semicolon or newline before %<{%>"); error_at(token_loc, "unexpected semicolon or newline before %<{%>");
@ -4402,7 +4402,7 @@ Parse::select_stat(Label* label)
void void
Parse::comm_clause(Select_clauses* clauses, bool* saw_default) Parse::comm_clause(Select_clauses* clauses, bool* saw_default)
{ {
source_location location = this->location(); Location location = this->location();
bool is_send = false; bool is_send = false;
Expression* channel = NULL; Expression* channel = NULL;
Expression* val = NULL; Expression* val = NULL;
@ -4518,7 +4518,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
Gogo* gogo = this->gogo_; Gogo* gogo = this->gogo_;
std::string recv_var = token->identifier(); std::string recv_var = token->identifier();
bool is_rv_exported = token->is_identifier_exported(); bool is_rv_exported = token->is_identifier_exported();
source_location recv_var_loc = token->location(); Location recv_var_loc = token->location();
token = this->advance_token(); token = this->advance_token();
if (token->is_op(OPERATOR_COLONEQ)) if (token->is_op(OPERATOR_COLONEQ))
{ {
@ -4547,7 +4547,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
{ {
std::string recv_closed = token->identifier(); std::string recv_closed = token->identifier();
bool is_rc_exported = token->is_identifier_exported(); bool is_rc_exported = token->is_identifier_exported();
source_location recv_closed_loc = token->location(); Location recv_closed_loc = token->location();
closed_is_id = true; closed_is_id = true;
token = this->advance_token(); token = this->advance_token();
@ -4673,7 +4673,7 @@ void
Parse::for_stat(Label* label) Parse::for_stat(Label* label)
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_FOR)); go_assert(this->peek_token()->is_keyword(KEYWORD_FOR));
source_location location = this->location(); Location location = this->location();
const Token* token = this->advance_token(); const Token* token = this->advance_token();
// Open a block to hold any variables defined in the init statement // Open a block to hold any variables defined in the init statement
@ -4761,7 +4761,7 @@ Parse::for_stat(Label* label)
// For_statement. // For_statement.
this->gogo_->start_block(this->location()); this->gogo_->start_block(this->location());
source_location end_loc = this->block(); Location end_loc = this->block();
Block* statements = this->gogo_->finish_block(end_loc); Block* statements = this->gogo_->finish_block(end_loc);
if (sfor != NULL) if (sfor != NULL)
@ -4830,7 +4830,7 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
Range_clause* p_range_clause) Range_clause* p_range_clause)
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_RANGE)); go_assert(this->peek_token()->is_keyword(KEYWORD_RANGE));
source_location location = this->location(); Location location = this->location();
p_range_clause->found = true; p_range_clause->found = true;
@ -4956,7 +4956,7 @@ void
Parse::break_stat() Parse::break_stat()
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_BREAK)); go_assert(this->peek_token()->is_keyword(KEYWORD_BREAK));
source_location location = this->location(); Location location = this->location();
const Token* token = this->advance_token(); const Token* token = this->advance_token();
Statement* enclosing; Statement* enclosing;
@ -4978,7 +4978,8 @@ Parse::break_stat()
{ {
// If there is a label with this name, mark it as used to // If there is a label with this name, mark it as used to
// avoid a useless error about an unused label. // avoid a useless error about an unused label.
this->gogo_->add_label_reference(token->identifier(), 0, false); this->gogo_->add_label_reference(token->identifier(),
Linemap::unknown_location(), false);
error_at(token->location(), "invalid break label %qs", error_at(token->location(), "invalid break label %qs",
Gogo::message_name(token->identifier()).c_str()); Gogo::message_name(token->identifier()).c_str());
@ -5012,7 +5013,7 @@ void
Parse::continue_stat() Parse::continue_stat()
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_CONTINUE)); go_assert(this->peek_token()->is_keyword(KEYWORD_CONTINUE));
source_location location = this->location(); Location location = this->location();
const Token* token = this->advance_token(); const Token* token = this->advance_token();
Statement* enclosing; Statement* enclosing;
@ -5033,7 +5034,8 @@ Parse::continue_stat()
{ {
// If there is a label with this name, mark it as used to // If there is a label with this name, mark it as used to
// avoid a useless error about an unused label. // avoid a useless error about an unused label.
this->gogo_->add_label_reference(token->identifier(), 0, false); this->gogo_->add_label_reference(token->identifier(),
Linemap::unknown_location(), false);
error_at(token->location(), "invalid continue label %qs", error_at(token->location(), "invalid continue label %qs",
Gogo::message_name(token->identifier()).c_str()); Gogo::message_name(token->identifier()).c_str());
@ -5061,7 +5063,7 @@ void
Parse::goto_stat() Parse::goto_stat()
{ {
go_assert(this->peek_token()->is_keyword(KEYWORD_GOTO)); go_assert(this->peek_token()->is_keyword(KEYWORD_GOTO));
source_location location = this->location(); Location location = this->location();
const Token* token = this->advance_token(); const Token* token = this->advance_token();
if (!token->is_identifier()) if (!token->is_identifier())
error_at(this->location(), "expected label for goto"); error_at(this->location(), "expected label for goto");
@ -5081,7 +5083,7 @@ void
Parse::package_clause() Parse::package_clause()
{ {
const Token* token = this->peek_token(); const Token* token = this->peek_token();
source_location location = token->location(); Location location = token->location();
std::string name; std::string name;
if (!token->is_keyword(KEYWORD_PACKAGE)) if (!token->is_keyword(KEYWORD_PACKAGE))
{ {
@ -5126,7 +5128,7 @@ void
Parse::import_spec(void*) Parse::import_spec(void*)
{ {
const Token* token = this->peek_token(); const Token* token = this->peek_token();
source_location location = token->location(); Location location = token->location();
std::string local_name; std::string local_name;
bool is_local_name_exported = false; bool is_local_name_exported = false;

View File

@ -75,7 +75,7 @@ class Parse
// The variable name. // The variable name.
std::string name; std::string name;
// The location of the variable. // The location of the variable.
source_location location; Location location;
// The expression. // The expression.
Expression* expr; Expression* expr;
@ -147,7 +147,7 @@ class Parse
unget_token(const Token&); unget_token(const Token&);
// The location of the current token. // The location of the current token.
source_location Location
location(); location();
// For break and continue we keep a stack of statements with // For break and continue we keep a stack of statements with
@ -169,12 +169,12 @@ class Parse
Type* pointer_type(); Type* pointer_type();
Type* channel_type(); Type* channel_type();
void check_signature_names(const Typed_identifier_list*, Names*); void check_signature_names(const Typed_identifier_list*, Names*);
Function_type* signature(Typed_identifier*, source_location); Function_type* signature(Typed_identifier*, Location);
bool parameters(Typed_identifier_list**, bool* is_varargs); bool parameters(Typed_identifier_list**, bool* is_varargs);
Typed_identifier_list* parameter_list(bool* is_varargs); Typed_identifier_list* parameter_list(bool* is_varargs);
void parameter_decl(bool, Typed_identifier_list*, bool*, bool*); void parameter_decl(bool, Typed_identifier_list*, bool*, bool*);
bool result(Typed_identifier_list**); bool result(Typed_identifier_list**);
source_location block(); Location block();
Type* interface_type(); Type* interface_type();
void method_spec(Typed_identifier_list*); void method_spec(Typed_identifier_list*);
void declaration(); void declaration();
@ -188,30 +188,30 @@ class Parse
void var_decl(); void var_decl();
void var_spec(void*); void var_spec(void*);
void init_vars(const Typed_identifier_list*, Type*, Expression_list*, void init_vars(const Typed_identifier_list*, Type*, Expression_list*,
bool is_coloneq, source_location); bool is_coloneq, Location);
bool init_vars_from_call(const Typed_identifier_list*, Type*, Expression*, bool init_vars_from_call(const Typed_identifier_list*, Type*, Expression*,
bool is_coloneq, source_location); bool is_coloneq, Location);
bool init_vars_from_map(const Typed_identifier_list*, Type*, Expression*, bool init_vars_from_map(const Typed_identifier_list*, Type*, Expression*,
bool is_coloneq, source_location); bool is_coloneq, Location);
bool init_vars_from_receive(const Typed_identifier_list*, Type*, bool init_vars_from_receive(const Typed_identifier_list*, Type*,
Expression*, bool is_coloneq, source_location); Expression*, bool is_coloneq, Location);
bool init_vars_from_type_guard(const Typed_identifier_list*, Type*, bool init_vars_from_type_guard(const Typed_identifier_list*, Type*,
Expression*, bool is_coloneq, Expression*, bool is_coloneq,
source_location); Location);
Named_object* init_var(const Typed_identifier&, Type*, Expression*, Named_object* init_var(const Typed_identifier&, Type*, Expression*,
bool is_coloneq, bool type_from_init, bool* is_new); bool is_coloneq, bool type_from_init, bool* is_new);
Named_object* create_dummy_global(Type*, Expression*, source_location); Named_object* create_dummy_global(Type*, Expression*, Location);
void simple_var_decl_or_assignment(const std::string&, source_location, void simple_var_decl_or_assignment(const std::string&, Location,
Range_clause*, Type_switch*); Range_clause*, Type_switch*);
void function_decl(); void function_decl();
Typed_identifier* receiver(); Typed_identifier* receiver();
Expression* operand(bool may_be_sink); Expression* operand(bool may_be_sink);
Expression* enclosing_var_reference(Named_object*, Named_object*, Expression* enclosing_var_reference(Named_object*, Named_object*,
source_location); Location);
Expression* composite_lit(Type*, int depth, source_location); Expression* composite_lit(Type*, int depth, Location);
Expression* function_lit(); Expression* function_lit();
Expression* create_closure(Named_object* function, Enclosing_vars*, Expression* create_closure(Named_object* function, Enclosing_vars*,
source_location); Location);
Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit, Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit,
bool* is_type_switch); bool* is_type_switch);
Expression* selector(Expression*, bool* is_type_switch); Expression* selector(Expression*, bool* is_type_switch);
@ -222,11 +222,11 @@ class Parse
bool expression_may_start_here(); bool expression_may_start_here();
Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit, Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit,
bool* is_type_switch); bool* is_type_switch);
Expression* qualified_expr(Expression*, source_location); Expression* qualified_expr(Expression*, Location);
Expression* id_to_expression(const std::string&, source_location); Expression* id_to_expression(const std::string&, Location);
void statement(Label*); void statement(Label*);
bool statement_may_start_here(); bool statement_may_start_here();
void labeled_stmt(const std::string&, source_location); void labeled_stmt(const std::string&, Location);
Expression* simple_stat(bool, bool*, Range_clause*, Type_switch*); Expression* simple_stat(bool, bool*, Range_clause*, Type_switch*);
bool simple_stat_may_start_here(); bool simple_stat_may_start_here();
void statement_list(); void statement_list();
@ -241,10 +241,10 @@ class Parse
void return_stat(); void return_stat();
void if_stat(); void if_stat();
void switch_stat(Label*); void switch_stat(Label*);
Statement* expr_switch_body(Label*, Expression*, source_location); Statement* expr_switch_body(Label*, Expression*, Location);
void expr_case_clause(Case_clauses*, bool* saw_default); void expr_case_clause(Case_clauses*, bool* saw_default);
Expression_list* expr_switch_case(bool*); Expression_list* expr_switch_case(bool*);
Statement* type_switch_body(Label*, const Type_switch&, source_location); Statement* type_switch_body(Label*, const Type_switch&, Location);
void type_case_clause(Named_object*, Type_case_clauses*, bool* saw_default); void type_case_clause(Named_object*, Type_case_clauses*, bool* saw_default);
void type_switch_case(std::vector<Type*>*, bool*); void type_switch_case(std::vector<Type*>*, bool*);
void select_stat(Label*); void select_stat(Label*);

View File

@ -82,7 +82,7 @@ runtime_function_type(Runtime_function_type bft)
go_assert(bft < NUMBER_OF_RUNTIME_FUNCTION_TYPES); go_assert(bft < NUMBER_OF_RUNTIME_FUNCTION_TYPES);
if (runtime_function_types[bft] == NULL) if (runtime_function_types[bft] == NULL)
{ {
const source_location bloc = BUILTINS_LOCATION; const Location bloc = Linemap::predeclared_location();
Type* t; Type* t;
switch (bft) switch (bft)
{ {
@ -193,7 +193,7 @@ runtime_function_type(Runtime_function_type bft)
static Expression* static Expression*
convert_to_runtime_function_type(Runtime_function_type bft, Expression* e, convert_to_runtime_function_type(Runtime_function_type bft, Expression* e,
source_location loc) Location loc)
{ {
switch (bft) switch (bft)
{ {
@ -295,7 +295,7 @@ Runtime::runtime_declaration(Function code)
{ {
const Runtime_function* pb = &runtime_functions[code]; const Runtime_function* pb = &runtime_functions[code];
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Typed_identifier_list* param_types = NULL; Typed_identifier_list* param_types = NULL;
if (pb->parameter_types[0] != RFT_VOID) if (pb->parameter_types[0] != RFT_VOID)
@ -347,7 +347,7 @@ Runtime::runtime_declaration(Function code)
// Make a call to a runtime function. // Make a call to a runtime function.
Call_expression* Call_expression*
Runtime::make_call(Runtime::Function code, source_location loc, Runtime::make_call(Runtime::Function code, Location loc,
int param_count, ...) int param_count, ...)
{ {
go_assert(code < Runtime::NUMBER_OF_FUNCTIONS); go_assert(code < Runtime::NUMBER_OF_FUNCTIONS);
@ -387,7 +387,8 @@ Runtime::map_iteration_type()
mpz_t ival; mpz_t ival;
mpz_init_set_ui(ival, map_iteration_size); mpz_init_set_ui(ival, map_iteration_size);
Expression* iexpr = Expression::make_integer(&ival, NULL, BUILTINS_LOCATION); Expression* iexpr = Expression::make_integer(&ival, NULL,
Linemap::predeclared_location());
mpz_clear(ival); mpz_clear(ival);
return Type::make_array_type(runtime_function_type(RFT_POINTER), iexpr); return Type::make_array_type(runtime_function_type(RFT_POINTER), iexpr);

View File

@ -32,7 +32,7 @@ class Runtime
// Make a call to a runtime function. // Make a call to a runtime function.
static Call_expression* static Call_expression*
make_call(Function, source_location, int, ...); make_call(Function, Location, int, ...);
// Convert all the types used by runtime functions to the backend // Convert all the types used by runtime functions to the backend
// representation. // representation.

View File

@ -20,7 +20,7 @@
// Class Statement. // Class Statement.
Statement::Statement(Statement_classification classification, Statement::Statement(Statement_classification classification,
source_location location) Location location)
: classification_(classification), location_(location) : classification_(classification), location_(location)
{ {
} }
@ -175,7 +175,7 @@ Statement::report_error(const char* msg)
class Error_statement : public Statement class Error_statement : public Statement
{ {
public: public:
Error_statement(source_location location) Error_statement(Location location)
: Statement(STATEMENT_ERROR, location) : Statement(STATEMENT_ERROR, location)
{ } { }
@ -204,7 +204,7 @@ Error_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
// Make an error statement. // Make an error statement.
Statement* Statement*
Statement::make_error_statement(source_location location) Statement::make_error_statement(Location location)
{ {
return new Error_statement(location); return new Error_statement(location);
} }
@ -268,7 +268,7 @@ Variable_declaration_statement::do_get_backend(Translate_context* context)
// Something takes the address of this variable, so the value is // Something takes the address of this variable, so the value is
// stored in the heap. Initialize it to newly allocated memory // stored in the heap. Initialize it to newly allocated memory
// space, and assign the initial value to the new space. // space, and assign the initial value to the new space.
source_location loc = this->location(); Location loc = this->location();
Named_object* newfn = context->gogo()->lookup_global("new"); Named_object* newfn = context->gogo()->lookup_global("new");
go_assert(newfn != NULL && newfn->is_function_declaration()); go_assert(newfn != NULL && newfn->is_function_declaration());
Expression* func = Expression::make_func_reference(newfn, NULL, loc); Expression* func = Expression::make_func_reference(newfn, NULL, loc);
@ -497,7 +497,7 @@ Temporary_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
Temporary_statement* Temporary_statement*
Statement::make_temporary(Type* type, Expression* init, Statement::make_temporary(Type* type, Expression* init,
source_location location) Location location)
{ {
return new Temporary_statement(type, init, location); return new Temporary_statement(type, init, location);
} }
@ -508,7 +508,7 @@ class Assignment_statement : public Statement
{ {
public: public:
Assignment_statement(Expression* lhs, Expression* rhs, Assignment_statement(Expression* lhs, Expression* rhs,
source_location location) Location location)
: Statement(STATEMENT_ASSIGNMENT, location), : Statement(STATEMENT_ASSIGNMENT, location),
lhs_(lhs), rhs_(rhs), are_hidden_fields_ok_(false) lhs_(lhs), rhs_(rhs), are_hidden_fields_ok_(false)
{ } { }
@ -647,7 +647,7 @@ Assignment_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
Statement* Statement*
Statement::make_assignment(Expression* lhs, Expression* rhs, Statement::make_assignment(Expression* lhs, Expression* rhs,
source_location location) Location location)
{ {
return new Assignment_statement(lhs, rhs, location); return new Assignment_statement(lhs, rhs, location);
} }
@ -684,7 +684,7 @@ Move_subexpressions::expression(Expression** pexpr)
--this->skip_; --this->skip_;
else if ((*pexpr)->temporary_reference_expression() == NULL) else if ((*pexpr)->temporary_reference_expression() == NULL)
{ {
source_location loc = (*pexpr)->location(); Location loc = (*pexpr)->location();
Temporary_statement* temp = Statement::make_temporary(NULL, *pexpr, loc); Temporary_statement* temp = Statement::make_temporary(NULL, *pexpr, loc);
this->block_->add_statement(temp); this->block_->add_statement(temp);
*pexpr = Expression::make_temporary_reference(temp, loc); *pexpr = Expression::make_temporary_reference(temp, loc);
@ -731,7 +731,7 @@ Move_ordered_evals::expression(Expression** pexpr)
if ((*pexpr)->must_eval_in_order()) if ((*pexpr)->must_eval_in_order())
{ {
source_location loc = (*pexpr)->location(); Location loc = (*pexpr)->location();
Temporary_statement* temp = Statement::make_temporary(NULL, *pexpr, loc); Temporary_statement* temp = Statement::make_temporary(NULL, *pexpr, loc);
this->block_->add_statement(temp); this->block_->add_statement(temp);
*pexpr = Expression::make_temporary_reference(temp, loc); *pexpr = Expression::make_temporary_reference(temp, loc);
@ -745,7 +745,7 @@ class Assignment_operation_statement : public Statement
{ {
public: public:
Assignment_operation_statement(Operator op, Expression* lhs, Expression* rhs, Assignment_operation_statement(Operator op, Expression* lhs, Expression* rhs,
source_location location) Location location)
: Statement(STATEMENT_ASSIGNMENT_OPERATION, location), : Statement(STATEMENT_ASSIGNMENT_OPERATION, location),
op_(op), lhs_(lhs), rhs_(rhs) op_(op), lhs_(lhs), rhs_(rhs)
{ } { }
@ -794,7 +794,7 @@ Statement*
Assignment_operation_statement::do_lower(Gogo*, Named_object*, Assignment_operation_statement::do_lower(Gogo*, Named_object*,
Block* enclosing, Statement_inserter*) Block* enclosing, Statement_inserter*)
{ {
source_location loc = this->location(); Location loc = this->location();
// We have to evaluate the left hand side expression only once. We // We have to evaluate the left hand side expression only once. We
// do this by moving out any expression with side effects. // do this by moving out any expression with side effects.
@ -875,7 +875,7 @@ Assignment_operation_statement::do_dump_statement(
Statement* Statement*
Statement::make_assignment_operation(Operator op, Expression* lhs, Statement::make_assignment_operation(Operator op, Expression* lhs,
Expression* rhs, source_location location) Expression* rhs, Location location)
{ {
return new Assignment_operation_statement(op, lhs, rhs, location); return new Assignment_operation_statement(op, lhs, rhs, location);
} }
@ -888,7 +888,7 @@ class Tuple_assignment_statement : public Statement
{ {
public: public:
Tuple_assignment_statement(Expression_list* lhs, Expression_list* rhs, Tuple_assignment_statement(Expression_list* lhs, Expression_list* rhs,
source_location location) Location location)
: Statement(STATEMENT_TUPLE_ASSIGNMENT, location), : Statement(STATEMENT_TUPLE_ASSIGNMENT, location),
lhs_(lhs), rhs_(rhs), are_hidden_fields_ok_(false) lhs_(lhs), rhs_(rhs), are_hidden_fields_ok_(false)
{ } { }
@ -944,7 +944,7 @@ Statement*
Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing, Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
Statement_inserter*) Statement_inserter*)
{ {
source_location loc = this->location(); Location loc = this->location();
Block* b = new Block(enclosing, loc); Block* b = new Block(enclosing, loc);
@ -1035,7 +1035,7 @@ Tuple_assignment_statement::do_dump_statement(
Statement* Statement*
Statement::make_tuple_assignment(Expression_list* lhs, Expression_list* rhs, Statement::make_tuple_assignment(Expression_list* lhs, Expression_list* rhs,
source_location location) Location location)
{ {
return new Tuple_assignment_statement(lhs, rhs, location); return new Tuple_assignment_statement(lhs, rhs, location);
} }
@ -1048,7 +1048,7 @@ class Tuple_map_assignment_statement : public Statement
public: public:
Tuple_map_assignment_statement(Expression* val, Expression* present, Tuple_map_assignment_statement(Expression* val, Expression* present,
Expression* map_index, Expression* map_index,
source_location location) Location location)
: Statement(STATEMENT_TUPLE_MAP_ASSIGNMENT, location), : Statement(STATEMENT_TUPLE_MAP_ASSIGNMENT, location),
val_(val), present_(present), map_index_(map_index) val_(val), present_(present), map_index_(map_index)
{ } { }
@ -1097,7 +1097,7 @@ Statement*
Tuple_map_assignment_statement::do_lower(Gogo*, Named_object*, Tuple_map_assignment_statement::do_lower(Gogo*, Named_object*,
Block* enclosing, Statement_inserter*) Block* enclosing, Statement_inserter*)
{ {
source_location loc = this->location(); Location loc = this->location();
Map_index_expression* map_index = this->map_index_->map_index_expression(); Map_index_expression* map_index = this->map_index_->map_index_expression();
if (map_index == NULL) if (map_index == NULL)
@ -1184,7 +1184,7 @@ Tuple_map_assignment_statement::do_dump_statement(
Statement* Statement*
Statement::make_tuple_map_assignment(Expression* val, Expression* present, Statement::make_tuple_map_assignment(Expression* val, Expression* present,
Expression* map_index, Expression* map_index,
source_location location) Location location)
{ {
return new Tuple_map_assignment_statement(val, present, map_index, location); return new Tuple_map_assignment_statement(val, present, map_index, location);
} }
@ -1197,7 +1197,7 @@ class Map_assignment_statement : public Statement
public: public:
Map_assignment_statement(Expression* map_index, Map_assignment_statement(Expression* map_index,
Expression* val, Expression* should_set, Expression* val, Expression* should_set,
source_location location) Location location)
: Statement(STATEMENT_MAP_ASSIGNMENT, location), : Statement(STATEMENT_MAP_ASSIGNMENT, location),
map_index_(map_index), val_(val), should_set_(should_set) map_index_(map_index), val_(val), should_set_(should_set)
{ } { }
@ -1246,7 +1246,7 @@ Statement*
Map_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing, Map_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
Statement_inserter*) Statement_inserter*)
{ {
source_location loc = this->location(); Location loc = this->location();
Map_index_expression* map_index = this->map_index_->map_index_expression(); Map_index_expression* map_index = this->map_index_->map_index_expression();
if (map_index == NULL) if (map_index == NULL)
@ -1318,7 +1318,7 @@ Map_assignment_statement::do_dump_statement(
Statement* Statement*
Statement::make_map_assignment(Expression* map_index, Statement::make_map_assignment(Expression* map_index,
Expression* val, Expression* should_set, Expression* val, Expression* should_set,
source_location location) Location location)
{ {
return new Map_assignment_statement(map_index, val, should_set, location); return new Map_assignment_statement(map_index, val, should_set, location);
} }
@ -1330,7 +1330,7 @@ class Tuple_receive_assignment_statement : public Statement
public: public:
Tuple_receive_assignment_statement(Expression* val, Expression* closed, Tuple_receive_assignment_statement(Expression* val, Expression* closed,
Expression* channel, bool for_select, Expression* channel, bool for_select,
source_location location) Location location)
: Statement(STATEMENT_TUPLE_RECEIVE_ASSIGNMENT, location), : Statement(STATEMENT_TUPLE_RECEIVE_ASSIGNMENT, location),
val_(val), closed_(closed), channel_(channel), for_select_(for_select) val_(val), closed_(closed), channel_(channel), for_select_(for_select)
{ } { }
@ -1382,7 +1382,7 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*,
Block* enclosing, Block* enclosing,
Statement_inserter*) Statement_inserter*)
{ {
source_location loc = this->location(); Location loc = this->location();
Channel_type* channel_type = this->channel_->type()->channel_type(); Channel_type* channel_type = this->channel_->type()->channel_type();
if (channel_type == NULL) if (channel_type == NULL)
@ -1461,7 +1461,7 @@ Statement*
Statement::make_tuple_receive_assignment(Expression* val, Expression* closed, Statement::make_tuple_receive_assignment(Expression* val, Expression* closed,
Expression* channel, Expression* channel,
bool for_select, bool for_select,
source_location location) Location location)
{ {
return new Tuple_receive_assignment_statement(val, closed, channel, return new Tuple_receive_assignment_statement(val, closed, channel,
for_select, location); for_select, location);
@ -1475,7 +1475,7 @@ class Tuple_type_guard_assignment_statement : public Statement
public: public:
Tuple_type_guard_assignment_statement(Expression* val, Expression* ok, Tuple_type_guard_assignment_statement(Expression* val, Expression* ok,
Expression* expr, Type* type, Expression* expr, Type* type,
source_location location) Location location)
: Statement(STATEMENT_TUPLE_TYPE_GUARD_ASSIGNMENT, location), : Statement(STATEMENT_TUPLE_TYPE_GUARD_ASSIGNMENT, location),
val_(val), ok_(ok), expr_(expr), type_(type) val_(val), ok_(ok), expr_(expr), type_(type)
{ } { }
@ -1534,7 +1534,7 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*,
Block* enclosing, Block* enclosing,
Statement_inserter*) Statement_inserter*)
{ {
source_location loc = this->location(); Location loc = this->location();
Type* expr_type = this->expr_->type(); Type* expr_type = this->expr_->type();
if (expr_type->interface_type() == NULL) if (expr_type->interface_type() == NULL)
@ -1599,7 +1599,7 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*,
Call_expression* Call_expression*
Tuple_type_guard_assignment_statement::lower_to_type(Runtime::Function code) Tuple_type_guard_assignment_statement::lower_to_type(Runtime::Function code)
{ {
source_location loc = this->location(); Location loc = this->location();
return Runtime::make_call(code, loc, 2, return Runtime::make_call(code, loc, 2,
Expression::make_type_descriptor(this->type_, loc), Expression::make_type_descriptor(this->type_, loc),
this->expr_); this->expr_);
@ -1612,7 +1612,7 @@ Tuple_type_guard_assignment_statement::lower_to_object_type(
Block* b, Block* b,
Runtime::Function code) Runtime::Function code)
{ {
source_location loc = this->location(); Location loc = this->location();
// var val_temp TYPE // var val_temp TYPE
Temporary_statement* val_temp = Statement::make_temporary(this->type_, Temporary_statement* val_temp = Statement::make_temporary(this->type_,
@ -1655,7 +1655,7 @@ Tuple_type_guard_assignment_statement::do_dump_statement(
Statement* Statement*
Statement::make_tuple_type_guard_assignment(Expression* val, Expression* ok, Statement::make_tuple_type_guard_assignment(Expression* val, Expression* ok,
Expression* expr, Type* type, Expression* expr, Type* type,
source_location location) Location location)
{ {
return new Tuple_type_guard_assignment_statement(val, ok, expr, type, return new Tuple_type_guard_assignment_statement(val, ok, expr, type,
location); location);
@ -1778,7 +1778,7 @@ Statement::make_statement(Expression* expr, bool is_ignored)
class Block_statement : public Statement class Block_statement : public Statement
{ {
public: public:
Block_statement(Block* block, source_location location) Block_statement(Block* block, Location location)
: Statement(STATEMENT_BLOCK, location), : Statement(STATEMENT_BLOCK, location),
block_(block) block_(block)
{ } { }
@ -1826,7 +1826,7 @@ Block_statement::do_dump_statement(Ast_dump_context*) const
// Make a block statement. // Make a block statement.
Statement* Statement*
Statement::make_block_statement(Block* block, source_location location) Statement::make_block_statement(Block* block, Location location)
{ {
return new Block_statement(block, location); return new Block_statement(block, location);
} }
@ -1872,7 +1872,7 @@ class Inc_dec_statement : public Statement
Statement* Statement*
Inc_dec_statement::do_lower(Gogo*, Named_object*, Block*, Statement_inserter*) Inc_dec_statement::do_lower(Gogo*, Named_object*, Block*, Statement_inserter*)
{ {
source_location loc = this->location(); Location loc = this->location();
mpz_t oval; mpz_t oval;
mpz_init_set_ui(oval, 1UL); mpz_init_set_ui(oval, 1UL);
@ -1916,7 +1916,7 @@ Statement::make_dec_statement(Expression* expr)
Thunk_statement::Thunk_statement(Statement_classification classification, Thunk_statement::Thunk_statement(Statement_classification classification,
Call_expression* call, Call_expression* call,
source_location location) Location location)
: Statement(classification, location), : Statement(classification, location),
call_(call), struct_type_(NULL) call_(call), struct_type_(NULL)
{ {
@ -2145,7 +2145,7 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function,
Interface_field_reference_expression* interface_method = Interface_field_reference_expression* interface_method =
fn->interface_field_reference_expression(); fn->interface_field_reference_expression();
source_location location = this->location(); Location location = this->location();
std::string thunk_name = Gogo::thunk_name(); std::string thunk_name = Gogo::thunk_name();
@ -2230,7 +2230,7 @@ Thunk_statement::thunk_field_param(int n, char* buf, size_t buflen)
Struct_type* Struct_type*
Thunk_statement::build_struct(Function_type* fntype) Thunk_statement::build_struct(Function_type* fntype)
{ {
source_location location = this->location(); Location location = this->location();
Struct_field_list* fields = new Struct_field_list(); Struct_field_list* fields = new Struct_field_list();
@ -2288,7 +2288,7 @@ Thunk_statement::build_struct(Function_type* fntype)
void void
Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name) Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
{ {
source_location location = this->location(); Location location = this->location();
Call_expression* ce = this->call_->call_expression(); Call_expression* ce = this->call_->call_expression();
@ -2541,7 +2541,7 @@ Go_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
// Make a go statement. // Make a go statement.
Statement* Statement*
Statement::make_go_statement(Call_expression* call, source_location location) Statement::make_go_statement(Call_expression* call, Location location)
{ {
return new Go_statement(call, location); return new Go_statement(call, location);
} }
@ -2556,7 +2556,7 @@ Defer_statement::do_get_backend(Translate_context* context)
if (!this->get_fn_and_arg(&fn, &arg)) if (!this->get_fn_and_arg(&fn, &arg))
return context->backend()->error_statement(); return context->backend()->error_statement();
source_location loc = this->location(); Location loc = this->location();
Expression* ds = context->function()->func_value()->defer_stack(loc); Expression* ds = context->function()->func_value()->defer_stack(loc);
Expression* call = Runtime::make_call(Runtime::DEFER, loc, 3, Expression* call = Runtime::make_call(Runtime::DEFER, loc, 3,
@ -2581,7 +2581,7 @@ Defer_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
Statement* Statement*
Statement::make_defer_statement(Call_expression* call, Statement::make_defer_statement(Call_expression* call,
source_location location) Location location)
{ {
return new Defer_statement(call, location); return new Defer_statement(call, location);
} }
@ -2623,7 +2623,7 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
this->vals_ = NULL; this->vals_ = NULL;
this->is_lowered_ = true; this->is_lowered_ = true;
source_location loc = this->location(); Location loc = this->location();
size_t vals_count = vals == NULL ? 0 : vals->size(); size_t vals_count = vals == NULL ? 0 : vals->size();
Function::Results* results = function->func_value()->result_variables(); Function::Results* results = function->func_value()->result_variables();
@ -2757,7 +2757,7 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
Bstatement* Bstatement*
Return_statement::do_get_backend(Translate_context* context) Return_statement::do_get_backend(Translate_context* context)
{ {
source_location loc = this->location(); Location loc = this->location();
Function* function = context->function()->func_value(); Function* function = context->function()->func_value();
tree fndecl = function->get_decl(); tree fndecl = function->get_decl();
@ -2795,7 +2795,7 @@ Return_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
Return_statement* Return_statement*
Statement::make_return_statement(Expression_list* vals, Statement::make_return_statement(Expression_list* vals,
source_location location) Location location)
{ {
return new Return_statement(vals, location); return new Return_statement(vals, location);
} }
@ -2805,7 +2805,7 @@ Statement::make_return_statement(Expression_list* vals,
class Bc_statement : public Statement class Bc_statement : public Statement
{ {
public: public:
Bc_statement(bool is_break, Unnamed_label* label, source_location location) Bc_statement(bool is_break, Unnamed_label* label, Location location)
: Statement(STATEMENT_BREAK_OR_CONTINUE, location), : Statement(STATEMENT_BREAK_OR_CONTINUE, location),
label_(label), is_break_(is_break) label_(label), is_break_(is_break)
{ } { }
@ -2855,7 +2855,7 @@ Bc_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
// Make a break statement. // Make a break statement.
Statement* Statement*
Statement::make_break_statement(Unnamed_label* label, source_location location) Statement::make_break_statement(Unnamed_label* label, Location location)
{ {
return new Bc_statement(true, label, location); return new Bc_statement(true, label, location);
} }
@ -2864,7 +2864,7 @@ Statement::make_break_statement(Unnamed_label* label, source_location location)
Statement* Statement*
Statement::make_continue_statement(Unnamed_label* label, Statement::make_continue_statement(Unnamed_label* label,
source_location location) Location location)
{ {
return new Bc_statement(false, label, location); return new Bc_statement(false, label, location);
} }
@ -2874,7 +2874,7 @@ Statement::make_continue_statement(Unnamed_label* label,
class Goto_statement : public Statement class Goto_statement : public Statement
{ {
public: public:
Goto_statement(Label* label, source_location location) Goto_statement(Label* label, Location location)
: Statement(STATEMENT_GOTO, location), : Statement(STATEMENT_GOTO, location),
label_(label) label_(label)
{ } { }
@ -2936,7 +2936,7 @@ Goto_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
// Make a goto statement. // Make a goto statement.
Statement* Statement*
Statement::make_goto_statement(Label* label, source_location location) Statement::make_goto_statement(Label* label, Location location)
{ {
return new Goto_statement(label, location); return new Goto_statement(label, location);
} }
@ -2946,7 +2946,7 @@ Statement::make_goto_statement(Label* label, source_location location)
class Goto_unnamed_statement : public Statement class Goto_unnamed_statement : public Statement
{ {
public: public:
Goto_unnamed_statement(Unnamed_label* label, source_location location) Goto_unnamed_statement(Unnamed_label* label, Location location)
: Statement(STATEMENT_GOTO_UNNAMED, location), : Statement(STATEMENT_GOTO_UNNAMED, location),
label_(label) label_(label)
{ } { }
@ -2987,7 +2987,7 @@ Goto_unnamed_statement::do_dump_statement(
Statement* Statement*
Statement::make_goto_unnamed_statement(Unnamed_label* label, Statement::make_goto_unnamed_statement(Unnamed_label* label,
source_location location) Location location)
{ {
return new Goto_unnamed_statement(label, location); return new Goto_unnamed_statement(label, location);
} }
@ -3024,7 +3024,7 @@ Label_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
// Make a label statement. // Make a label statement.
Statement* Statement*
Statement::make_label_statement(Label* label, source_location location) Statement::make_label_statement(Label* label, Location location)
{ {
return new Label_statement(label, location); return new Label_statement(label, location);
} }
@ -3081,7 +3081,7 @@ class If_statement : public Statement
{ {
public: public:
If_statement(Expression* cond, Block* then_block, Block* else_block, If_statement(Expression* cond, Block* then_block, Block* else_block,
source_location location) Location location)
: Statement(STATEMENT_IF, location), : Statement(STATEMENT_IF, location),
cond_(cond), then_block_(then_block), else_block_(else_block) cond_(cond), then_block_(then_block), else_block_(else_block)
{ } { }
@ -3201,7 +3201,7 @@ If_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
Statement* Statement*
Statement::make_if_statement(Expression* cond, Block* then_block, Statement::make_if_statement(Expression* cond, Block* then_block,
Block* else_block, source_location location) Block* else_block, Location location)
{ {
return new If_statement(cond, then_block, else_block, location); return new If_statement(cond, then_block, else_block, location);
} }
@ -3303,7 +3303,7 @@ Case_clauses::Case_clause::lower(Block* b, Temporary_statement* val_temp,
Unnamed_label* start_label, Unnamed_label* start_label,
Unnamed_label* finish_label) const Unnamed_label* finish_label) const
{ {
source_location loc = this->location_; Location loc = this->location_;
Unnamed_label* next_case_label; Unnamed_label* next_case_label;
if (this->cases_ == NULL || this->cases_->empty()) if (this->cases_ == NULL || this->cases_->empty())
{ {
@ -3335,7 +3335,7 @@ Case_clauses::Case_clause::lower(Block* b, Temporary_statement* val_temp,
} }
Block* then_block = new Block(b, loc); Block* then_block = new Block(b, loc);
next_case_label = new Unnamed_label(UNKNOWN_LOCATION); next_case_label = new Unnamed_label(Linemap::unknown_location());
Statement* s = Statement::make_goto_unnamed_statement(next_case_label, Statement* s = Statement::make_goto_unnamed_statement(next_case_label,
loc); loc);
then_block->add_statement(s); then_block->add_statement(s);
@ -3693,7 +3693,7 @@ class Constant_switch_statement : public Statement
public: public:
Constant_switch_statement(Expression* val, Case_clauses* clauses, Constant_switch_statement(Expression* val, Case_clauses* clauses,
Unnamed_label* break_label, Unnamed_label* break_label,
source_location location) Location location)
: Statement(STATEMENT_CONSTANT_SWITCH, location), : Statement(STATEMENT_CONSTANT_SWITCH, location),
val_(val), clauses_(clauses), break_label_(break_label) val_(val), clauses_(clauses), break_label_(break_label)
{ } { }
@ -3838,7 +3838,7 @@ Statement*
Switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing, Switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
Statement_inserter*) Statement_inserter*)
{ {
source_location loc = this->location(); Location loc = this->location();
if (this->val_ != NULL if (this->val_ != NULL
&& (this->val_->is_error_expression() && (this->val_->is_error_expression()
@ -3915,7 +3915,7 @@ Switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
// Make a switch statement. // Make a switch statement.
Switch_statement* Switch_statement*
Statement::make_switch_statement(Expression* val, source_location location) Statement::make_switch_statement(Expression* val, Location location)
{ {
return new Switch_statement(val, location); return new Switch_statement(val, location);
} }
@ -3949,7 +3949,7 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
Unnamed_label* break_label, Unnamed_label* break_label,
Unnamed_label** stmts_label) const Unnamed_label** stmts_label) const
{ {
source_location loc = this->location_; Location loc = this->location_;
Unnamed_label* next_case_label = NULL; Unnamed_label* next_case_label = NULL;
if (!this->is_default_) if (!this->is_default_)
@ -3979,7 +3979,7 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
if (!this->is_fallthrough_) if (!this->is_fallthrough_)
{ {
// if !COND { goto NEXT_CASE_LABEL } // if !COND { goto NEXT_CASE_LABEL }
next_case_label = new Unnamed_label(UNKNOWN_LOCATION); next_case_label = new Unnamed_label(Linemap::unknown_location());
dest = next_case_label; dest = next_case_label;
cond = Expression::make_unary(OPERATOR_NOT, cond, loc); cond = Expression::make_unary(OPERATOR_NOT, cond, loc);
} }
@ -3988,7 +3988,7 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
// if COND { goto STMTS_LABEL } // if COND { goto STMTS_LABEL }
go_assert(stmts_label != NULL); go_assert(stmts_label != NULL);
if (*stmts_label == NULL) if (*stmts_label == NULL)
*stmts_label = new Unnamed_label(UNKNOWN_LOCATION); *stmts_label = new Unnamed_label(Linemap::unknown_location());
dest = *stmts_label; dest = *stmts_label;
} }
Block* then_block = new Block(b, loc); Block* then_block = new Block(b, loc);
@ -4022,7 +4022,7 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
go_assert(next_case_label == NULL); go_assert(next_case_label == NULL);
else else
{ {
source_location gloc = (this->statements_ == NULL Location gloc = (this->statements_ == NULL
? loc ? loc
: this->statements_->end_location()); : this->statements_->end_location());
b->add_statement(Statement::make_goto_unnamed_statement(break_label, b->add_statement(Statement::make_goto_unnamed_statement(break_label,
@ -4169,7 +4169,7 @@ Statement*
Type_switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing, Type_switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
Statement_inserter*) Statement_inserter*)
{ {
const source_location loc = this->location(); const Location loc = this->location();
if (this->clauses_ != NULL) if (this->clauses_ != NULL)
this->clauses_->check_duplicates(); this->clauses_->check_duplicates();
@ -4268,7 +4268,7 @@ Type_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
Type_switch_statement* Type_switch_statement*
Statement::make_type_switch_statement(Named_object* var, Expression* expr, Statement::make_type_switch_statement(Named_object* var, Expression* expr,
source_location location) Location location)
{ {
return new Type_switch_statement(var, expr, location); return new Type_switch_statement(var, expr, location);
} }
@ -4334,7 +4334,7 @@ Send_statement::do_check_types(Gogo*)
Bstatement* Bstatement*
Send_statement::do_get_backend(Translate_context* context) Send_statement::do_get_backend(Translate_context* context)
{ {
source_location loc = this->location(); Location loc = this->location();
Channel_type* channel_type = this->channel_->type()->channel_type(); Channel_type* channel_type = this->channel_->type()->channel_type();
Type* element_type = channel_type->element_type(); Type* element_type = channel_type->element_type();
@ -4450,7 +4450,7 @@ Send_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
Send_statement* Send_statement*
Statement::make_send_statement(Expression* channel, Expression* val, Statement::make_send_statement(Expression* channel, Expression* val,
source_location location) Location location)
{ {
return new Send_statement(channel, val, location); return new Send_statement(channel, val, location);
} }
@ -4505,7 +4505,7 @@ Select_clauses::Select_clause::lower(Gogo* gogo, Named_object* function,
return; return;
} }
source_location loc = this->location_; Location loc = this->location_;
// Evaluate the channel before the select statement. // Evaluate the channel before the select statement.
Temporary_statement* channel_temp = Statement::make_temporary(NULL, Temporary_statement* channel_temp = Statement::make_temporary(NULL,
@ -4767,7 +4767,7 @@ Select_clauses::may_fall_through() const
Bstatement* Bstatement*
Select_clauses::get_backend(Translate_context* context, Select_clauses::get_backend(Translate_context* context,
Unnamed_label *break_label, Unnamed_label *break_label,
source_location location) Location location)
{ {
size_t count = this->clauses_.size(); size_t count = this->clauses_.size();
@ -4941,7 +4941,7 @@ Select_clauses::get_backend(Translate_context* context,
void void
Select_clauses::add_clause_backend( Select_clauses::add_clause_backend(
Translate_context* context, Translate_context* context,
source_location location, Location location,
int index, int index,
int case_value, int case_value,
Select_clause* clause, Select_clause* clause,
@ -4957,7 +4957,7 @@ Select_clauses::add_clause_backend(
Bstatement* s = clause->get_statements_backend(context); Bstatement* s = clause->get_statements_backend(context);
source_location gloc = (clause->statements() == NULL Location gloc = (clause->statements() == NULL
? clause->location() ? clause->location()
: clause->statements()->end_location()); : clause->statements()->end_location());
Bstatement* g = bottom_label->get_goto(context, gloc); Bstatement* g = bottom_label->get_goto(context, gloc);
@ -5038,7 +5038,7 @@ Select_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
// Make a select statement. // Make a select statement.
Select_statement* Select_statement*
Statement::make_select_statement(source_location location) Statement::make_select_statement(Location location)
{ {
return new Select_statement(location); return new Select_statement(location);
} }
@ -5076,7 +5076,7 @@ For_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
Statement_inserter*) Statement_inserter*)
{ {
Statement* s; Statement* s;
source_location loc = this->location(); Location loc = this->location();
Block* b = new Block(enclosing, this->location()); Block* b = new Block(enclosing, this->location());
if (this->init_ != NULL) if (this->init_ != NULL)
@ -5100,7 +5100,7 @@ For_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
this->statements_->start_location()); this->statements_->start_location());
b->add_statement(s); b->add_statement(s);
source_location end_loc = this->statements_->end_location(); Location end_loc = this->statements_->end_location();
Unnamed_label* cont = this->continue_label_; Unnamed_label* cont = this->continue_label_;
if (cont != NULL) if (cont != NULL)
@ -5120,7 +5120,7 @@ For_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
{ {
b->add_statement(Statement::make_unnamed_label_statement(entry)); b->add_statement(Statement::make_unnamed_label_statement(entry));
source_location cond_loc = this->cond_->location(); Location cond_loc = this->cond_->location();
Block* then_block = new Block(b, cond_loc); Block* then_block = new Block(b, cond_loc);
s = Statement::make_goto_unnamed_statement(top, cond_loc); s = Statement::make_goto_unnamed_statement(top, cond_loc);
then_block->add_statement(s); then_block->add_statement(s);
@ -5211,7 +5211,7 @@ For_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
For_statement* For_statement*
Statement::make_for_statement(Block* init, Expression* cond, Block* post, Statement::make_for_statement(Block* init, Expression* cond, Block* post,
source_location location) Location location)
{ {
return new For_statement(init, cond, post, location); return new For_statement(init, cond, post, location);
} }
@ -5285,7 +5285,7 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
return Statement::make_error_statement(this->location()); return Statement::make_error_statement(this->location());
} }
source_location loc = this->location(); Location loc = this->location();
Block* temp_block = new Block(enclosing, loc); Block* temp_block = new Block(enclosing, loc);
Named_object* range_object = NULL; Named_object* range_object = NULL;
@ -5388,7 +5388,7 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
Expression* Expression*
For_range_statement::make_range_ref(Named_object* range_object, For_range_statement::make_range_ref(Named_object* range_object,
Temporary_statement* range_temp, Temporary_statement* range_temp,
source_location loc) Location loc)
{ {
if (range_object != NULL) if (range_object != NULL)
return Expression::make_var_reference(range_object, loc); return Expression::make_var_reference(range_object, loc);
@ -5402,7 +5402,7 @@ For_range_statement::make_range_ref(Named_object* range_object,
Expression* Expression*
For_range_statement::call_builtin(Gogo* gogo, const char* funcname, For_range_statement::call_builtin(Gogo* gogo, const char* funcname,
Expression* arg, Expression* arg,
source_location loc) Location loc)
{ {
Named_object* no = gogo->lookup_global(funcname); Named_object* no = gogo->lookup_global(funcname);
go_assert(no != NULL && no->is_function_declaration()); go_assert(no != NULL && no->is_function_declaration());
@ -5427,7 +5427,7 @@ For_range_statement::lower_range_array(Gogo* gogo,
Block** piter_init, Block** piter_init,
Block** ppost) Block** ppost)
{ {
source_location loc = this->location(); Location loc = this->location();
// The loop we generate: // The loop we generate:
// len_temp := len(range) // len_temp := len(range)
@ -5519,7 +5519,7 @@ For_range_statement::lower_range_string(Gogo*,
Block** piter_init, Block** piter_init,
Block** ppost) Block** ppost)
{ {
source_location loc = this->location(); Location loc = this->location();
// The loop we generate: // The loop we generate:
// var next_index_temp int // var next_index_temp int
@ -5647,7 +5647,7 @@ For_range_statement::lower_range_map(Gogo*,
Block** piter_init, Block** piter_init,
Block** ppost) Block** ppost)
{ {
source_location loc = this->location(); Location loc = this->location();
// The runtime uses a struct to handle ranges over a map. The // The runtime uses a struct to handle ranges over a map. The
// struct is four pointers long. The first pointer is NULL when we // struct is four pointers long. The first pointer is NULL when we
@ -5752,7 +5752,7 @@ For_range_statement::lower_range_channel(Gogo*,
{ {
go_assert(value_temp == NULL); go_assert(value_temp == NULL);
source_location loc = this->location(); Location loc = this->location();
// The loop we generate: // The loop we generate:
// for { // for {
@ -5863,7 +5863,7 @@ For_range_statement*
Statement::make_for_range_statement(Expression* index_var, Statement::make_for_range_statement(Expression* index_var,
Expression* value_var, Expression* value_var,
Expression* range, Expression* range,
source_location location) Location location)
{ {
return new For_range_statement(index_var, value_var, range, location); return new For_range_statement(index_var, value_var, range, location);
} }

View File

@ -123,7 +123,7 @@ class Statement
STATEMENT_TYPE_SWITCH STATEMENT_TYPE_SWITCH
}; };
Statement(Statement_classification, source_location); Statement(Statement_classification, Location);
virtual ~Statement(); virtual ~Statement();
@ -139,30 +139,30 @@ class Statement
// Either the type or the initialization expression may be NULL, but // Either the type or the initialization expression may be NULL, but
// not both. // not both.
static Temporary_statement* static Temporary_statement*
make_temporary(Type*, Expression*, source_location); make_temporary(Type*, Expression*, Location);
// Make an assignment statement. // Make an assignment statement.
static Statement* static Statement*
make_assignment(Expression*, Expression*, source_location); make_assignment(Expression*, Expression*, Location);
// Make an assignment operation (+=, etc.). // Make an assignment operation (+=, etc.).
static Statement* static Statement*
make_assignment_operation(Operator, Expression*, Expression*, make_assignment_operation(Operator, Expression*, Expression*,
source_location); Location);
// Make a tuple assignment statement. // Make a tuple assignment statement.
static Statement* static Statement*
make_tuple_assignment(Expression_list*, Expression_list*, source_location); make_tuple_assignment(Expression_list*, Expression_list*, Location);
// Make an assignment from a map index to a pair of variables. // Make an assignment from a map index to a pair of variables.
static Statement* static Statement*
make_tuple_map_assignment(Expression* val, Expression* present, make_tuple_map_assignment(Expression* val, Expression* present,
Expression*, source_location); Expression*, Location);
// Make a statement which assigns a pair of values to a map. // Make a statement which assigns a pair of values to a map.
static Statement* static Statement*
make_map_assignment(Expression*, Expression* val, make_map_assignment(Expression*, Expression* val,
Expression* should_set, source_location); Expression* should_set, Location);
// Make an assignment from a nonblocking receive to a pair of // Make an assignment from a nonblocking receive to a pair of
// variables. FOR_SELECT is true is this is being created for a // variables. FOR_SELECT is true is this is being created for a
@ -170,13 +170,13 @@ class Statement
static Statement* static Statement*
make_tuple_receive_assignment(Expression* val, Expression* closed, make_tuple_receive_assignment(Expression* val, Expression* closed,
Expression* channel, bool for_select, Expression* channel, bool for_select,
source_location); Location);
// Make an assignment from a type guard to a pair of variables. // Make an assignment from a type guard to a pair of variables.
static Statement* static Statement*
make_tuple_type_guard_assignment(Expression* val, Expression* ok, make_tuple_type_guard_assignment(Expression* val, Expression* ok,
Expression* expr, Type* type, Expression* expr, Type* type,
source_location); Location);
// Make an expression statement from an Expression. IS_IGNORED is // Make an expression statement from an Expression. IS_IGNORED is
// true if the value is being explicitly ignored, as in an // true if the value is being explicitly ignored, as in an
@ -187,7 +187,7 @@ class Statement
// Make a block statement from a Block. This is an embedded list of // Make a block statement from a Block. This is an embedded list of
// statements which may also include variable definitions. // statements which may also include variable definitions.
static Statement* static Statement*
make_block_statement(Block*, source_location); make_block_statement(Block*, Location);
// Make an increment statement. // Make an increment statement.
static Statement* static Statement*
@ -199,35 +199,35 @@ class Statement
// Make a go statement. // Make a go statement.
static Statement* static Statement*
make_go_statement(Call_expression* call, source_location); make_go_statement(Call_expression* call, Location);
// Make a defer statement. // Make a defer statement.
static Statement* static Statement*
make_defer_statement(Call_expression* call, source_location); make_defer_statement(Call_expression* call, Location);
// Make a return statement. // Make a return statement.
static Return_statement* static Return_statement*
make_return_statement(Expression_list*, source_location); make_return_statement(Expression_list*, Location);
// Make a break statement. // Make a break statement.
static Statement* static Statement*
make_break_statement(Unnamed_label* label, source_location); make_break_statement(Unnamed_label* label, Location);
// Make a continue statement. // Make a continue statement.
static Statement* static Statement*
make_continue_statement(Unnamed_label* label, source_location); make_continue_statement(Unnamed_label* label, Location);
// Make a goto statement. // Make a goto statement.
static Statement* static Statement*
make_goto_statement(Label* label, source_location); make_goto_statement(Label* label, Location);
// Make a goto statement to an unnamed label. // Make a goto statement to an unnamed label.
static Statement* static Statement*
make_goto_unnamed_statement(Unnamed_label* label, source_location); make_goto_unnamed_statement(Unnamed_label* label, Location);
// Make a label statement--where the label is defined. // Make a label statement--where the label is defined.
static Statement* static Statement*
make_label_statement(Label* label, source_location); make_label_statement(Label* label, Location);
// Make an unnamed label statement--where the label is defined. // Make an unnamed label statement--where the label is defined.
static Statement* static Statement*
@ -236,33 +236,33 @@ class Statement
// Make an if statement. // Make an if statement.
static Statement* static Statement*
make_if_statement(Expression* cond, Block* then_block, Block* else_block, make_if_statement(Expression* cond, Block* then_block, Block* else_block,
source_location); Location);
// Make a switch statement. // Make a switch statement.
static Switch_statement* static Switch_statement*
make_switch_statement(Expression* switch_val, source_location); make_switch_statement(Expression* switch_val, Location);
// Make a type switch statement. // Make a type switch statement.
static Type_switch_statement* static Type_switch_statement*
make_type_switch_statement(Named_object* var, Expression*, source_location); make_type_switch_statement(Named_object* var, Expression*, Location);
// Make a send statement. // Make a send statement.
static Send_statement* static Send_statement*
make_send_statement(Expression* channel, Expression* val, source_location); make_send_statement(Expression* channel, Expression* val, Location);
// Make a select statement. // Make a select statement.
static Select_statement* static Select_statement*
make_select_statement(source_location); make_select_statement(Location);
// Make a for statement. // Make a for statement.
static For_statement* static For_statement*
make_for_statement(Block* init, Expression* cond, Block* post, make_for_statement(Block* init, Expression* cond, Block* post,
source_location location); Location location);
// Make a for statement with a range clause. // Make a for statement with a range clause.
static For_range_statement* static For_range_statement*
make_for_range_statement(Expression* index_var, Expression* value_var, make_for_range_statement(Expression* index_var, Expression* value_var,
Expression* range, source_location); Expression* range, Location);
// Return the statement classification. // Return the statement classification.
Statement_classification Statement_classification
@ -270,7 +270,7 @@ class Statement
{ return this->classification_; } { return this->classification_; }
// Get the statement location. // Get the statement location.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -448,7 +448,7 @@ class Statement
// For children to return an error statement from lower(). // For children to return an error statement from lower().
static Statement* static Statement*
make_error_statement(source_location); make_error_statement(Location);
private: private:
// Convert to the desired statement classification, or return NULL. // Convert to the desired statement classification, or return NULL.
@ -474,7 +474,7 @@ class Statement
// The statement classification. // The statement classification.
Statement_classification classification_; Statement_classification classification_;
// The location in the input file of the start of this statement. // The location in the input file of the start of this statement.
source_location location_; Location location_;
}; };
// A statement which creates and initializes a temporary variable. // A statement which creates and initializes a temporary variable.
@ -482,7 +482,7 @@ class Statement
class Temporary_statement : public Statement class Temporary_statement : public Statement
{ {
public: public:
Temporary_statement(Type* type, Expression* init, source_location location) Temporary_statement(Type* type, Expression* init, Location location)
: Statement(STATEMENT_TEMPORARY, location), : Statement(STATEMENT_TEMPORARY, location),
type_(type), init_(init), bvariable_(NULL), are_hidden_fields_ok_(false), type_(type), init_(init), bvariable_(NULL), are_hidden_fields_ok_(false),
is_address_taken_(false) is_address_taken_(false)
@ -579,7 +579,7 @@ class Variable_declaration_statement : public Statement
class Return_statement : public Statement class Return_statement : public Statement
{ {
public: public:
Return_statement(Expression_list* vals, source_location location) Return_statement(Expression_list* vals, Location location)
: Statement(STATEMENT_RETURN, location), : Statement(STATEMENT_RETURN, location),
vals_(vals), are_hidden_fields_ok_(false), is_lowered_(false) vals_(vals), are_hidden_fields_ok_(false), is_lowered_(false)
{ } { }
@ -632,7 +632,7 @@ class Send_statement : public Statement
{ {
public: public:
Send_statement(Expression* channel, Expression* val, Send_statement(Expression* channel, Expression* val,
source_location location) Location location)
: Statement(STATEMENT_SEND, location), : Statement(STATEMENT_SEND, location),
channel_(channel), val_(val), for_select_(false) channel_(channel), val_(val), for_select_(false)
{ } { }
@ -691,7 +691,7 @@ class Select_clauses
void void
add(bool is_send, Expression* channel, Expression* val, Expression* closed, add(bool is_send, Expression* channel, Expression* val, Expression* closed,
Named_object* var, Named_object* closedvar, bool is_default, Named_object* var, Named_object* closedvar, bool is_default,
Block* statements, source_location location) Block* statements, Location location)
{ {
this->clauses_.push_back(Select_clause(is_send, channel, val, closed, var, this->clauses_.push_back(Select_clause(is_send, channel, val, closed, var,
closedvar, is_default, statements, closedvar, is_default, statements,
@ -717,7 +717,7 @@ class Select_clauses
// Convert to the backend representation. // Convert to the backend representation.
Bstatement* Bstatement*
get_backend(Translate_context*, Unnamed_label* break_label, source_location); get_backend(Translate_context*, Unnamed_label* break_label, Location);
// Dump AST representation. // Dump AST representation.
void void
@ -737,7 +737,7 @@ class Select_clauses
Select_clause(bool is_send, Expression* channel, Expression* val, Select_clause(bool is_send, Expression* channel, Expression* val,
Expression* closed, Named_object* var, Expression* closed, Named_object* var,
Named_object* closedvar, bool is_default, Block* statements, Named_object* closedvar, bool is_default, Block* statements,
source_location location) Location location)
: channel_(channel), val_(val), closed_(closed), var_(var), : channel_(channel), val_(val), closed_(closed), var_(var),
closedvar_(closedvar), statements_(statements), location_(location), closedvar_(closedvar), statements_(statements), location_(location),
is_send_(is_send), is_default_(is_default), is_lowered_(false) is_send_(is_send), is_default_(is_default), is_lowered_(false)
@ -780,7 +780,7 @@ class Select_clauses
{ return this->statements_; } { return this->statements_; }
// Return the location. // Return the location.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -813,7 +813,7 @@ class Select_clauses
// The statements to execute. // The statements to execute.
Block* statements_; Block* statements_;
// The location of this clause. // The location of this clause.
source_location location_; Location location_;
// Whether this is a send or a receive. // Whether this is a send or a receive.
bool is_send_; bool is_send_;
// Whether this is the default. // Whether this is the default.
@ -823,7 +823,7 @@ class Select_clauses
}; };
void void
add_clause_backend(Translate_context*, source_location, int index, add_clause_backend(Translate_context*, Location, int index,
int case_value, Select_clause*, Unnamed_label*, int case_value, Select_clause*, Unnamed_label*,
std::vector<std::vector<Bexpression*> >* cases, std::vector<std::vector<Bexpression*> >* cases,
std::vector<Bstatement*>* clauses); std::vector<Bstatement*>* clauses);
@ -838,7 +838,7 @@ class Select_clauses
class Select_statement : public Statement class Select_statement : public Statement
{ {
public: public:
Select_statement(source_location location) Select_statement(Location location)
: Statement(STATEMENT_SELECT, location), : Statement(STATEMENT_SELECT, location),
clauses_(NULL), break_label_(NULL), is_lowered_(false) clauses_(NULL), break_label_(NULL), is_lowered_(false)
{ } { }
@ -892,7 +892,7 @@ class Thunk_statement : public Statement
{ {
public: public:
Thunk_statement(Statement_classification, Call_expression*, Thunk_statement(Statement_classification, Call_expression*,
source_location); Location);
// Return the call expression. // Return the call expression.
Expression* Expression*
@ -955,7 +955,7 @@ class Thunk_statement : public Statement
class Go_statement : public Thunk_statement class Go_statement : public Thunk_statement
{ {
public: public:
Go_statement(Call_expression* call, source_location location) Go_statement(Call_expression* call, Location location)
: Thunk_statement(STATEMENT_GO, call, location) : Thunk_statement(STATEMENT_GO, call, location)
{ } { }
@ -972,7 +972,7 @@ class Go_statement : public Thunk_statement
class Defer_statement : public Thunk_statement class Defer_statement : public Thunk_statement
{ {
public: public:
Defer_statement(Call_expression* call, source_location location) Defer_statement(Call_expression* call, Location location)
: Thunk_statement(STATEMENT_DEFER, call, location) : Thunk_statement(STATEMENT_DEFER, call, location)
{ } { }
@ -989,7 +989,7 @@ class Defer_statement : public Thunk_statement
class Label_statement : public Statement class Label_statement : public Statement
{ {
public: public:
Label_statement(Label* label, source_location location) Label_statement(Label* label, Location location)
: Statement(STATEMENT_LABEL, location), : Statement(STATEMENT_LABEL, location),
label_(label) label_(label)
{ } { }
@ -1020,7 +1020,7 @@ class For_statement : public Statement
{ {
public: public:
For_statement(Block* init, Expression* cond, Block* post, For_statement(Block* init, Expression* cond, Block* post,
source_location location) Location location)
: Statement(STATEMENT_FOR, location), : Statement(STATEMENT_FOR, location),
init_(init), cond_(cond), post_(post), statements_(NULL), init_(init), cond_(cond), post_(post), statements_(NULL),
break_label_(NULL), continue_label_(NULL) break_label_(NULL), continue_label_(NULL)
@ -1086,7 +1086,7 @@ class For_range_statement : public Statement
{ {
public: public:
For_range_statement(Expression* index_var, Expression* value_var, For_range_statement(Expression* index_var, Expression* value_var,
Expression* range, source_location location) Expression* range, Location location)
: Statement(STATEMENT_FOR_RANGE, location), : Statement(STATEMENT_FOR_RANGE, location),
index_var_(index_var), value_var_(value_var), range_(range), index_var_(index_var), value_var_(value_var), range_(range),
statements_(NULL), break_label_(NULL), continue_label_(NULL) statements_(NULL), break_label_(NULL), continue_label_(NULL)
@ -1128,10 +1128,10 @@ class For_range_statement : public Statement
private: private:
Expression* Expression*
make_range_ref(Named_object*, Temporary_statement*, source_location); make_range_ref(Named_object*, Temporary_statement*, Location);
Expression* Expression*
call_builtin(Gogo*, const char* funcname, Expression* arg, source_location); call_builtin(Gogo*, const char* funcname, Expression* arg, Location);
void void
lower_range_array(Gogo*, Block*, Block*, Named_object*, Temporary_statement*, lower_range_array(Gogo*, Block*, Block*, Named_object*, Temporary_statement*,
@ -1186,7 +1186,7 @@ class Case_clauses
// next clause. // next clause.
void void
add(Expression_list* cases, bool is_default, Block* statements, add(Expression_list* cases, bool is_default, Block* statements,
bool is_fallthrough, source_location location) bool is_fallthrough, Location location)
{ {
this->clauses_.push_back(Case_clause(cases, is_default, statements, this->clauses_.push_back(Case_clause(cases, is_default, statements,
is_fallthrough, location)); is_fallthrough, location));
@ -1252,7 +1252,7 @@ class Case_clauses
{ } { }
Case_clause(Expression_list* cases, bool is_default, Block* statements, Case_clause(Expression_list* cases, bool is_default, Block* statements,
bool is_fallthrough, source_location location) bool is_fallthrough, Location location)
: cases_(cases), statements_(statements), is_default_(is_default), : cases_(cases), statements_(statements), is_default_(is_default),
is_fallthrough_(is_fallthrough), location_(location) is_fallthrough_(is_fallthrough), location_(location)
{ } { }
@ -1268,7 +1268,7 @@ class Case_clauses
{ return this->is_default_; } { return this->is_default_; }
// The location of this clause. // The location of this clause.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -1318,7 +1318,7 @@ class Case_clauses
// Whether this falls through after the statements. // Whether this falls through after the statements.
bool is_fallthrough_; bool is_fallthrough_;
// The location of this case clause. // The location of this case clause.
source_location location_; Location location_;
}; };
friend class Case_clause; friend class Case_clause;
@ -1335,7 +1335,7 @@ class Case_clauses
class Switch_statement : public Statement class Switch_statement : public Statement
{ {
public: public:
Switch_statement(Expression* val, source_location location) Switch_statement(Expression* val, Location location)
: Statement(STATEMENT_SWITCH, location), : Statement(STATEMENT_SWITCH, location),
val_(val), clauses_(NULL), break_label_(NULL) val_(val), clauses_(NULL), break_label_(NULL)
{ } { }
@ -1392,7 +1392,7 @@ class Type_case_clauses
// statements; it may be NULL. // statements; it may be NULL.
void void
add(Type* type, bool is_fallthrough, bool is_default, Block* statements, add(Type* type, bool is_fallthrough, bool is_default, Block* statements,
source_location location) Location location)
{ {
this->clauses_.push_back(Type_case_clause(type, is_fallthrough, is_default, this->clauses_.push_back(Type_case_clause(type, is_fallthrough, is_default,
statements, location)); statements, location));
@ -1431,7 +1431,7 @@ class Type_case_clauses
{ } { }
Type_case_clause(Type* type, bool is_fallthrough, bool is_default, Type_case_clause(Type* type, bool is_fallthrough, bool is_default,
Block* statements, source_location location) Block* statements, Location location)
: type_(type), statements_(statements), is_fallthrough_(is_fallthrough), : type_(type), statements_(statements), is_fallthrough_(is_fallthrough),
is_default_(is_default), location_(location) is_default_(is_default), location_(location)
{ } { }
@ -1447,7 +1447,7 @@ class Type_case_clauses
{ return this->is_default_; } { return this->is_default_; }
// The location of this type clause. // The location of this type clause.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -1474,7 +1474,7 @@ class Type_case_clauses
// Whether this is the default case. // Whether this is the default case.
bool is_default_; bool is_default_;
// The location of this type case clause. // The location of this type case clause.
source_location location_; Location location_;
}; };
friend class Type_case_clause; friend class Type_case_clause;
@ -1492,7 +1492,7 @@ class Type_switch_statement : public Statement
{ {
public: public:
Type_switch_statement(Named_object* var, Expression* expr, Type_switch_statement(Named_object* var, Expression* expr,
source_location location) Location location)
: Statement(STATEMENT_TYPE_SWITCH, location), : Statement(STATEMENT_TYPE_SWITCH, location),
var_(var), expr_(expr), clauses_(NULL), break_label_(NULL) var_(var), expr_(expr), clauses_(NULL), break_label_(NULL)
{ go_assert(var == NULL || expr == NULL); } { go_assert(var == NULL || expr == NULL); }

View File

@ -853,7 +853,7 @@ Type::get_btype_without_hash(Gogo* gogo)
// Return a pointer to the type descriptor for this type. // Return a pointer to the type descriptor for this type.
tree tree
Type::type_descriptor_pointer(Gogo* gogo, source_location location) Type::type_descriptor_pointer(Gogo* gogo, Location location)
{ {
Type* t = this->forwarded(); Type* t = this->forwarded();
if (t->type_descriptor_var_ == NULL) if (t->type_descriptor_var_ == NULL)
@ -864,7 +864,7 @@ Type::type_descriptor_pointer(Gogo* gogo, source_location location)
tree var_tree = var_to_tree(t->type_descriptor_var_); tree var_tree = var_to_tree(t->type_descriptor_var_);
if (var_tree == error_mark_node) if (var_tree == error_mark_node)
return error_mark_node; return error_mark_node;
return build_fold_addr_expr_loc(location, var_tree); return build_fold_addr_expr_loc(location.gcc_location(), var_tree);
} }
// A mapping from unnamed types to type descriptor variables. // A mapping from unnamed types to type descriptor variables.
@ -934,7 +934,7 @@ Type::make_type_descriptor_var(Gogo* gogo)
} }
} }
source_location loc = nt == NULL ? BUILTINS_LOCATION : nt->location(); Location loc = nt == NULL ? Linemap::predeclared_location() : nt->location();
if (is_defined_elsewhere) if (is_defined_elsewhere)
{ {
@ -1054,7 +1054,7 @@ Type::make_builtin_struct_type(int nfields, ...)
va_list ap; va_list ap;
va_start(ap, nfields); va_start(ap, nfields);
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Struct_field_list* sfl = new Struct_field_list(); Struct_field_list* sfl = new Struct_field_list();
for (int i = 0; i < nfields; i++) for (int i = 0; i < nfields; i++)
{ {
@ -1077,7 +1077,7 @@ std::vector<Named_type*> Type::named_builtin_types;
Named_type* Named_type*
Type::make_builtin_named_type(const char* name, Type* type) Type::make_builtin_named_type(const char* name, Type* type)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Named_object* no = Named_object::make_type(name, NULL, type, bloc); Named_object* no = Named_object::make_type(name, NULL, type, bloc);
Named_type* ret = no->type_value(); Named_type* ret = no->type_value();
Type::named_builtin_types.push_back(ret); Type::named_builtin_types.push_back(ret);
@ -1110,7 +1110,7 @@ Type::make_type_descriptor_type()
static Type* ret; static Type* ret;
if (ret == NULL) if (ret == NULL)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Type* uint8_type = Type::lookup_integer_type("uint8"); Type* uint8_type = Type::lookup_integer_type("uint8");
Type* uint32_type = Type::lookup_integer_type("uint32"); Type* uint32_type = Type::lookup_integer_type("uint32");
@ -1286,7 +1286,7 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
Named_type* name, const Methods* methods, Named_type* name, const Methods* methods,
bool only_value_methods) bool only_value_methods)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Type* td_type = Type::make_type_descriptor_type(); Type* td_type = Type::make_type_descriptor_type();
const Struct_field_list* fields = td_type->struct_type()->fields(); const Struct_field_list* fields = td_type->struct_type()->fields();
@ -1394,7 +1394,7 @@ Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type,
Named_type* name, const Methods* methods, Named_type* name, const Methods* methods,
bool only_value_methods) const bool only_value_methods) const
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
const Struct_field_list* fields = uncommon_type->struct_type()->fields(); const Struct_field_list* fields = uncommon_type->struct_type()->fields();
@ -1477,7 +1477,7 @@ Type::methods_constructor(Gogo* gogo, Type* methods_type,
const Methods* methods, const Methods* methods,
bool only_value_methods) const bool only_value_methods) const
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
std::vector<std::pair<std::string, const Method*> > smethods; std::vector<std::pair<std::string, const Method*> > smethods;
if (methods != NULL) if (methods != NULL)
@ -1524,7 +1524,7 @@ Type::method_constructor(Gogo*, Type* method_type,
const Method* m, const Method* m,
bool only_value_methods) const bool only_value_methods) const
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
const Struct_field_list* fields = method_type->struct_type()->fields(); const Struct_field_list* fields = method_type->struct_type()->fields();
@ -1688,7 +1688,7 @@ class Error_type : public Type
Expression* Expression*
do_type_descriptor(Gogo*, Named_type*) do_type_descriptor(Gogo*, Named_type*)
{ return Expression::make_error(BUILTINS_LOCATION); } { return Expression::make_error(Linemap::predeclared_location()); }
void void
do_reflection(Gogo*, std::string*) const do_reflection(Gogo*, std::string*) const
@ -1807,9 +1807,9 @@ Named_type*
Type::make_named_bool_type() Type::make_named_bool_type()
{ {
Type* bool_type = Type::make_boolean_type(); Type* bool_type = Type::make_boolean_type();
Named_object* named_object = Named_object::make_type("bool", NULL, Named_object* named_object =
bool_type, Named_object::make_type("bool", NULL, bool_type,
BUILTINS_LOCATION); Linemap::predeclared_location());
Named_type* named_type = named_object->type_value(); Named_type* named_type = named_object->type_value();
named_bool_type = named_type; named_bool_type = named_type;
return named_type; return named_type;
@ -1829,9 +1829,9 @@ Integer_type::create_integer_type(const char* name, bool is_unsigned,
Integer_type* integer_type = new Integer_type(false, is_unsigned, bits, Integer_type* integer_type = new Integer_type(false, is_unsigned, bits,
runtime_type_kind); runtime_type_kind);
std::string sname(name); std::string sname(name);
Named_object* named_object = Named_object::make_type(sname, NULL, Named_object* named_object =
integer_type, Named_object::make_type(sname, NULL, integer_type,
BUILTINS_LOCATION); Linemap::predeclared_location());
Named_type* named_type = named_object->type_value(); Named_type* named_type = named_object->type_value();
std::pair<Named_integer_types::iterator, bool> ins = std::pair<Named_integer_types::iterator, bool> ins =
Integer_type::named_integer_types.insert(std::make_pair(sname, named_type)); Integer_type::named_integer_types.insert(std::make_pair(sname, named_type));
@ -1965,8 +1965,9 @@ Float_type::create_float_type(const char* name, int bits,
{ {
Float_type* float_type = new Float_type(false, bits, runtime_type_kind); Float_type* float_type = new Float_type(false, bits, runtime_type_kind);
std::string sname(name); std::string sname(name);
Named_object* named_object = Named_object::make_type(sname, NULL, float_type, Named_object* named_object =
BUILTINS_LOCATION); Named_object::make_type(sname, NULL, float_type,
Linemap::predeclared_location());
Named_type* named_type = named_object->type_value(); Named_type* named_type = named_object->type_value();
std::pair<Named_float_types::iterator, bool> ins = std::pair<Named_float_types::iterator, bool> ins =
Float_type::named_float_types.insert(std::make_pair(sname, named_type)); Float_type::named_float_types.insert(std::make_pair(sname, named_type));
@ -2089,9 +2090,9 @@ Complex_type::create_complex_type(const char* name, int bits,
Complex_type* complex_type = new Complex_type(false, bits, Complex_type* complex_type = new Complex_type(false, bits,
runtime_type_kind); runtime_type_kind);
std::string sname(name); std::string sname(name);
Named_object* named_object = Named_object::make_type(sname, NULL, Named_object* named_object =
complex_type, Named_object::make_type(sname, NULL, complex_type,
BUILTINS_LOCATION); Linemap::predeclared_location());
Named_type* named_type = named_object->type_value(); Named_type* named_type = named_object->type_value();
std::pair<Named_complex_types::iterator, bool> ins = std::pair<Named_complex_types::iterator, bool> ins =
Complex_type::named_complex_types.insert(std::make_pair(sname, Complex_type::named_complex_types.insert(std::make_pair(sname,
@ -2219,12 +2220,12 @@ String_type::do_get_backend(Gogo* gogo)
Type* pb = Type::make_pointer_type(b); Type* pb = Type::make_pointer_type(b);
fields[0].name = "__data"; fields[0].name = "__data";
fields[0].btype = pb->get_backend(gogo); fields[0].btype = pb->get_backend(gogo);
fields[0].location = UNKNOWN_LOCATION; fields[0].location = Linemap::predeclared_location();
Type* int_type = Type::lookup_integer_type("int"); Type* int_type = Type::lookup_integer_type("int");
fields[1].name = "__length"; fields[1].name = "__length";
fields[1].btype = int_type->get_backend(gogo); fields[1].btype = int_type->get_backend(gogo);
fields[1].location = UNKNOWN_LOCATION; fields[1].location = fields[0].location;
backend_string_type = gogo->backend()->struct_type(fields); backend_string_type = gogo->backend()->struct_type(fields);
} }
@ -2317,9 +2318,9 @@ Named_type*
Type::make_named_string_type() Type::make_named_string_type()
{ {
Type* string_type = Type::make_string_type(); Type* string_type = Type::make_string_type();
Named_object* named_object = Named_object::make_type("string", NULL, Named_object* named_object =
string_type, Named_object::make_type("string", NULL, string_type,
BUILTINS_LOCATION); Linemap::predeclared_location());
Named_type* named_type = named_object->type_value(); Named_type* named_type = named_object->type_value();
named_string_type = named_type; named_string_type = named_type;
return named_type; return named_type;
@ -2742,7 +2743,7 @@ Function_type::make_function_type_descriptor_type()
Expression* Expression*
Function_type::do_type_descriptor(Gogo* gogo, Named_type* name) Function_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Type* ftdt = Function_type::make_function_type_descriptor_type(); Type* ftdt = Function_type::make_function_type_descriptor_type();
@ -2785,7 +2786,7 @@ Function_type::type_descriptor_params(Type* params_type,
const Typed_identifier* receiver, const Typed_identifier* receiver,
const Typed_identifier_list* params) const Typed_identifier_list* params)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
if (receiver == NULL && params == NULL) if (receiver == NULL && params == NULL)
return Expression::make_slice_composite_literal(params_type, NULL, bloc); return Expression::make_slice_composite_literal(params_type, NULL, bloc);
@ -3073,7 +3074,7 @@ Function_type*
Type::make_function_type(Typed_identifier* receiver, Type::make_function_type(Typed_identifier* receiver,
Typed_identifier_list* parameters, Typed_identifier_list* parameters,
Typed_identifier_list* results, Typed_identifier_list* results,
source_location location) Location location)
{ {
return new Function_type(receiver, parameters, results, location); return new Function_type(receiver, parameters, results, location);
} }
@ -3140,7 +3141,7 @@ Pointer_type::do_type_descriptor(Gogo* gogo, Named_type* name)
} }
else else
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
const Methods* methods; const Methods* methods;
Type* deref = this->points_to(); Type* deref = this->points_to();
@ -3302,7 +3303,7 @@ class Call_multiple_result_type : public Type
do_type_descriptor(Gogo*, Named_type*) do_type_descriptor(Gogo*, Named_type*)
{ {
go_assert(saw_errors()); go_assert(saw_errors());
return Expression::make_error(UNKNOWN_LOCATION); return Expression::make_error(Linemap::unknown_location());
} }
void void
@ -3609,7 +3610,7 @@ Struct_type::find_local_field(const std::string& name,
Field_reference_expression* Field_reference_expression*
Struct_type::field_reference(Expression* struct_expr, const std::string& name, Struct_type::field_reference(Expression* struct_expr, const std::string& name,
source_location location) const Location location) const
{ {
unsigned int depth; unsigned int depth;
return this->field_reference_depth(struct_expr, name, location, NULL, return this->field_reference_depth(struct_expr, name, location, NULL,
@ -3622,7 +3623,7 @@ Struct_type::field_reference(Expression* struct_expr, const std::string& name,
Field_reference_expression* Field_reference_expression*
Struct_type::field_reference_depth(Expression* struct_expr, Struct_type::field_reference_depth(Expression* struct_expr,
const std::string& name, const std::string& name,
source_location location, Location location,
Saw_named_type* saw, Saw_named_type* saw,
unsigned int* depth) const unsigned int* depth) const
{ {
@ -3867,7 +3868,7 @@ Struct_type::make_struct_type_descriptor_type()
Expression* Expression*
Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name) Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Type* stdt = Struct_type::make_struct_type_descriptor_type(); Type* stdt = Struct_type::make_struct_type_descriptor_type();
@ -4081,8 +4082,8 @@ Struct_type::do_export(Export* exp) const
if (p->has_tag()) if (p->has_tag())
{ {
exp->write_c_string(" "); exp->write_c_string(" ");
Expression* expr = Expression::make_string(p->tag(), Expression* expr =
BUILTINS_LOCATION); Expression::make_string(p->tag(), Linemap::predeclared_location());
expr->export_expression(exp); expr->export_expression(exp);
delete expr; delete expr;
} }
@ -4140,7 +4141,7 @@ Struct_type::do_import(Import* imp)
Struct_type* Struct_type*
Type::make_struct_type(Struct_field_list* fields, Type::make_struct_type(Struct_field_list* fields,
source_location location) Location location)
{ {
return new Struct_type(fields, location); return new Struct_type(fields, location);
} }
@ -4356,23 +4357,24 @@ get_backend_slice_fields(Gogo* gogo, Array_type* type,
Type* pet = Type::make_pointer_type(type->element_type()); Type* pet = Type::make_pointer_type(type->element_type());
Btype* pbet = pet->get_backend(gogo); Btype* pbet = pet->get_backend(gogo);
Location ploc = Linemap::predeclared_location();
Backend::Btyped_identifier* p = &(*bfields)[0]; Backend::Btyped_identifier* p = &(*bfields)[0];
p->name = "__values"; p->name = "__values";
p->btype = pbet; p->btype = pbet;
p->location = UNKNOWN_LOCATION; p->location = ploc;
Type* int_type = Type::lookup_integer_type("int"); Type* int_type = Type::lookup_integer_type("int");
p = &(*bfields)[1]; p = &(*bfields)[1];
p->name = "__count"; p->name = "__count";
p->btype = int_type->get_backend(gogo); p->btype = int_type->get_backend(gogo);
p->location = UNKNOWN_LOCATION; p->location = ploc;
p = &(*bfields)[2]; p = &(*bfields)[2];
p->name = "__capacity"; p->name = "__capacity";
p->btype = int_type->get_backend(gogo); p->btype = int_type->get_backend(gogo);
p->location = UNKNOWN_LOCATION; p->location = ploc;
} }
// Get a tree for the type of this array. A fixed array is simply // Get a tree for the type of this array. A fixed array is simply
@ -4579,7 +4581,7 @@ Array_type::do_type_descriptor(Gogo* gogo, Named_type* name)
Expression* Expression*
Array_type::array_type_descriptor(Gogo* gogo, Named_type* name) Array_type::array_type_descriptor(Gogo* gogo, Named_type* name)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Type* atdt = Array_type::make_array_type_descriptor_type(); Type* atdt = Array_type::make_array_type_descriptor_type();
@ -4618,7 +4620,7 @@ Array_type::array_type_descriptor(Gogo* gogo, Named_type* name)
Expression* Expression*
Array_type::slice_type_descriptor(Gogo* gogo, Named_type* name) Array_type::slice_type_descriptor(Gogo* gogo, Named_type* name)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Type* stdt = Array_type::make_slice_type_descriptor_type(); Type* stdt = Array_type::make_slice_type_descriptor_type();
@ -4772,29 +4774,31 @@ Map_type::do_get_backend(Gogo* gogo)
{ {
std::vector<Backend::Btyped_identifier> bfields(4); std::vector<Backend::Btyped_identifier> bfields(4);
Location bloc = Linemap::predeclared_location();
Type* pdt = Type::make_type_descriptor_ptr_type(); Type* pdt = Type::make_type_descriptor_ptr_type();
bfields[0].name = "__descriptor"; bfields[0].name = "__descriptor";
bfields[0].btype = pdt->get_backend(gogo); bfields[0].btype = pdt->get_backend(gogo);
bfields[0].location = BUILTINS_LOCATION; bfields[0].location = bloc;
Type* uintptr_type = Type::lookup_integer_type("uintptr"); Type* uintptr_type = Type::lookup_integer_type("uintptr");
bfields[1].name = "__element_count"; bfields[1].name = "__element_count";
bfields[1].btype = uintptr_type->get_backend(gogo); bfields[1].btype = uintptr_type->get_backend(gogo);
bfields[1].location = BUILTINS_LOCATION; bfields[1].location = bloc;
bfields[2].name = "__bucket_count"; bfields[2].name = "__bucket_count";
bfields[2].btype = bfields[1].btype; bfields[2].btype = bfields[1].btype;
bfields[2].location = BUILTINS_LOCATION; bfields[2].location = bloc;
Btype* bvt = gogo->backend()->void_type(); Btype* bvt = gogo->backend()->void_type();
Btype* bpvt = gogo->backend()->pointer_type(bvt); Btype* bpvt = gogo->backend()->pointer_type(bvt);
Btype* bppvt = gogo->backend()->pointer_type(bpvt); Btype* bppvt = gogo->backend()->pointer_type(bpvt);
bfields[3].name = "__buckets"; bfields[3].name = "__buckets";
bfields[3].btype = bppvt; bfields[3].btype = bppvt;
bfields[3].location = BUILTINS_LOCATION; bfields[3].location = bloc;
Btype *bt = gogo->backend()->struct_type(bfields); Btype *bt = gogo->backend()->struct_type(bfields);
bt = gogo->backend()->named_type("__go_map", bt, BUILTINS_LOCATION); bt = gogo->backend()->named_type("__go_map", bt, bloc);
backend_map_type = gogo->backend()->pointer_type(bt); backend_map_type = gogo->backend()->pointer_type(bt);
} }
return backend_map_type; return backend_map_type;
@ -4828,7 +4832,7 @@ Map_type::make_map_type_descriptor_type()
Expression* Expression*
Map_type::do_type_descriptor(Gogo* gogo, Named_type* name) Map_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Type* mtdt = Map_type::make_map_type_descriptor_type(); Type* mtdt = Map_type::make_map_type_descriptor_type();
@ -4864,13 +4868,13 @@ Map_type::Map_descriptors Map_type::map_descriptors;
// Build a map descriptor for this type. Return a pointer to it. // Build a map descriptor for this type. Return a pointer to it.
tree tree
Map_type::map_descriptor_pointer(Gogo* gogo, source_location location) Map_type::map_descriptor_pointer(Gogo* gogo, Location location)
{ {
Bvariable* bvar = this->map_descriptor(gogo); Bvariable* bvar = this->map_descriptor(gogo);
tree var_tree = var_to_tree(bvar); tree var_tree = var_to_tree(bvar);
if (var_tree == error_mark_node) if (var_tree == error_mark_node)
return error_mark_node; return error_mark_node;
return build_fold_addr_expr_loc(location, var_tree); return build_fold_addr_expr_loc(location.gcc_location(), var_tree);
} }
// Build a map descriptor for this type. // Build a map descriptor for this type.
@ -4907,7 +4911,7 @@ Map_type::map_descriptor(Gogo* gogo)
Expression_list* vals = new Expression_list(); Expression_list* vals = new Expression_list();
vals->reserve(4); vals->reserve(4);
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Struct_field_list::const_iterator p = fields->begin(); Struct_field_list::const_iterator p = fields->begin();
@ -5028,7 +5032,7 @@ Map_type::do_import(Import* imp)
// Make a map type. // Make a map type.
Map_type* Map_type*
Type::make_map_type(Type* key_type, Type* val_type, source_location location) Type::make_map_type(Type* key_type, Type* val_type, Location location)
{ {
return new Map_type(key_type, val_type, location); return new Map_type(key_type, val_type, location);
} }
@ -5075,7 +5079,8 @@ Channel_type::do_get_backend(Gogo* gogo)
{ {
std::vector<Backend::Btyped_identifier> bfields; std::vector<Backend::Btyped_identifier> bfields;
Btype* bt = gogo->backend()->struct_type(bfields); Btype* bt = gogo->backend()->struct_type(bfields);
bt = gogo->backend()->named_type("__go_channel", bt, BUILTINS_LOCATION); bt = gogo->backend()->named_type("__go_channel", bt,
Linemap::predeclared_location());
backend_channel_type = gogo->backend()->pointer_type(bt); backend_channel_type = gogo->backend()->pointer_type(bt);
} }
return backend_channel_type; return backend_channel_type;
@ -5111,7 +5116,7 @@ Channel_type::make_chan_type_descriptor_type()
Expression* Expression*
Channel_type::do_type_descriptor(Gogo* gogo, Named_type* name) Channel_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Type* ctdt = Channel_type::make_chan_type_descriptor_type(); Type* ctdt = Channel_type::make_chan_type_descriptor_type();
@ -5670,15 +5675,17 @@ Interface_type::get_backend_empty_interface_type(Gogo* gogo)
{ {
std::vector<Backend::Btyped_identifier> bfields(2); std::vector<Backend::Btyped_identifier> bfields(2);
Location bloc = Linemap::predeclared_location();
Type* pdt = Type::make_type_descriptor_ptr_type(); Type* pdt = Type::make_type_descriptor_ptr_type();
bfields[0].name = "__type_descriptor"; bfields[0].name = "__type_descriptor";
bfields[0].btype = pdt->get_backend(gogo); bfields[0].btype = pdt->get_backend(gogo);
bfields[0].location = UNKNOWN_LOCATION; bfields[0].location = bloc;
Type* vt = Type::make_pointer_type(Type::make_void_type()); Type* vt = Type::make_pointer_type(Type::make_void_type());
bfields[1].name = "__object"; bfields[1].name = "__object";
bfields[1].btype = vt->get_backend(gogo); bfields[1].btype = vt->get_backend(gogo);
bfields[1].location = UNKNOWN_LOCATION; bfields[1].location = bloc;
empty_interface_type = gogo->backend()->struct_type(bfields); empty_interface_type = gogo->backend()->struct_type(bfields);
} }
@ -5693,7 +5700,7 @@ static void
get_backend_interface_fields(Gogo* gogo, Interface_type* type, get_backend_interface_fields(Gogo* gogo, Interface_type* type,
std::vector<Backend::Btyped_identifier>* bfields) std::vector<Backend::Btyped_identifier>* bfields)
{ {
source_location loc = type->location(); Location loc = type->location();
std::vector<Backend::Btyped_identifier> mfields(type->methods()->size() + 1); std::vector<Backend::Btyped_identifier> mfields(type->methods()->size() + 1);
@ -5727,7 +5734,7 @@ get_backend_interface_fields(Gogo* gogo, Interface_type* type,
Type* vt = Type::make_pointer_type(Type::make_void_type()); Type* vt = Type::make_pointer_type(Type::make_void_type());
(*bfields)[1].name = "__object"; (*bfields)[1].name = "__object";
(*bfields)[1].btype = vt->get_backend(gogo); (*bfields)[1].btype = vt->get_backend(gogo);
(*bfields)[1].location = UNKNOWN_LOCATION; (*bfields)[1].location = Linemap::predeclared_location();
} }
// Return a tree for an interface type. An interface is a pointer to // Return a tree for an interface type. An interface is a pointer to
@ -5789,7 +5796,7 @@ Interface_type::make_interface_type_descriptor_type()
Expression* Expression*
Interface_type::do_type_descriptor(Gogo* gogo, Named_type* name) Interface_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{ {
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Type* itdt = Interface_type::make_interface_type_descriptor_type(); Type* itdt = Interface_type::make_interface_type_descriptor_type();
@ -5800,9 +5807,9 @@ Interface_type::do_type_descriptor(Gogo* gogo, Named_type* name)
Struct_field_list::const_iterator pif = ifields->begin(); Struct_field_list::const_iterator pif = ifields->begin();
go_assert(pif->is_field_name("commonType")); go_assert(pif->is_field_name("commonType"));
ivals->push_back(this->type_descriptor_constructor(gogo, const int rt = RUNTIME_TYPE_KIND_INTERFACE;
RUNTIME_TYPE_KIND_INTERFACE, ivals->push_back(this->type_descriptor_constructor(gogo, rt, name, NULL,
name, NULL, true)); true));
++pif; ++pif;
go_assert(pif->is_field_name("methods")); go_assert(pif->is_field_name("methods"));
@ -6095,7 +6102,7 @@ Interface_type::do_import(Import* imp)
Interface_type* Interface_type*
Type::make_interface_type(Typed_identifier_list* methods, Type::make_interface_type(Typed_identifier_list* methods,
source_location location) Location location)
{ {
return new Interface_type(methods, location); return new Interface_type(methods, location);
} }
@ -6105,7 +6112,7 @@ Type::make_interface_type(Typed_identifier_list* methods,
// Bind a method to an object. // Bind a method to an object.
Expression* Expression*
Method::bind_method(Expression* expr, source_location location) const Method::bind_method(Expression* expr, Location location) const
{ {
if (this->stub_ == NULL) if (this->stub_ == NULL)
{ {
@ -6144,7 +6151,7 @@ Named_method::do_type() const
// Return the location of the method receiver. // Return the location of the method receiver.
source_location Location
Named_method::do_receiver_location() const Named_method::do_receiver_location() const
{ {
return this->do_type()->receiver()->location(); return this->do_type()->receiver()->location();
@ -6153,7 +6160,7 @@ Named_method::do_receiver_location() const
// Bind a method to an object. // Bind a method to an object.
Expression* Expression*
Named_method::do_bind_method(Expression* expr, source_location location) const Named_method::do_bind_method(Expression* expr, Location location) const
{ {
Named_object* no = this->named_object_; Named_object* no = this->named_object_;
Bound_method_expression* bme = Expression::make_bound_method(expr, no, Bound_method_expression* bme = Expression::make_bound_method(expr, no,
@ -6177,7 +6184,7 @@ Named_method::do_bind_method(Expression* expr, source_location location) const
Expression* Expression*
Interface_method::do_bind_method(Expression* expr, Interface_method::do_bind_method(Expression* expr,
source_location location) const Location location) const
{ {
return Expression::make_interface_field_reference(expr, this->name_, return Expression::make_interface_field_reference(expr, this->name_,
location); location);
@ -6299,7 +6306,7 @@ Named_type::add_method(const std::string& name, Function* function)
Named_object* Named_object*
Named_type::add_method_declaration(const std::string& name, Package* package, Named_type::add_method_declaration(const std::string& name, Package* package,
Function_type* type, Function_type* type,
source_location location) Location location)
{ {
if (this->local_methods_ == NULL) if (this->local_methods_ == NULL)
this->local_methods_ = new Bindings(NULL); this->local_methods_ = new Bindings(NULL);
@ -6967,7 +6974,7 @@ Named_type::do_type_descriptor(Gogo* gogo, Named_type* name)
void void
Named_type::do_reflection(Gogo* gogo, std::string* ret) const Named_type::do_reflection(Gogo* gogo, std::string* ret) const
{ {
if (this->location() != BUILTINS_LOCATION) if (!Linemap::is_predeclared_location(this->location()))
{ {
const Package* package = this->named_object_->package(); const Package* package = this->named_object_->package();
if (package != NULL) if (package != NULL)
@ -6991,7 +6998,7 @@ Named_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{ {
Named_object* no = this->named_object_; Named_object* no = this->named_object_;
std::string name; std::string name;
if (this->location() == BUILTINS_LOCATION) if (Linemap::is_predeclared_location(this->location()))
go_assert(this->in_function_ == NULL); go_assert(this->in_function_ == NULL);
else else
{ {
@ -7081,7 +7088,7 @@ Named_type::do_export(Export* exp) const
Named_type* Named_type*
Type::make_named_type(Named_object* named_object, Type* type, Type::make_named_type(Named_object* named_object, Type* type,
source_location location) Location location)
{ {
return new Named_type(named_object, type, location); return new Named_type(named_object, type, location);
} }
@ -7091,7 +7098,7 @@ Type::make_named_type(Named_object* named_object, Type* type,
// all required stubs. // all required stubs.
void void
Type::finalize_methods(Gogo* gogo, const Type* type, source_location location, Type::finalize_methods(Gogo* gogo, const Type* type, Location location,
Methods** all_methods) Methods** all_methods)
{ {
*all_methods = NULL; *all_methods = NULL;
@ -7291,7 +7298,7 @@ Type::add_interface_methods_for_type(const Type* type,
void void
Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods, Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods,
source_location location) Location location)
{ {
if (methods == NULL) if (methods == NULL)
return; return;
@ -7317,7 +7324,7 @@ Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods,
Type* receiver_type = const_cast<Type*>(type); Type* receiver_type = const_cast<Type*>(type);
if (!m->is_value_method()) if (!m->is_value_method())
receiver_type = Type::make_pointer_type(receiver_type); receiver_type = Type::make_pointer_type(receiver_type);
source_location receiver_location = m->receiver_location(); Location receiver_location = m->receiver_location();
Typed_identifier* receiver = new Typed_identifier(buf, receiver_type, Typed_identifier* receiver = new Typed_identifier(buf, receiver_type,
receiver_location); receiver_location);
@ -7397,7 +7404,7 @@ Type::build_one_stub_method(Gogo* gogo, Method* method,
const char* receiver_name, const char* receiver_name,
const Typed_identifier_list* params, const Typed_identifier_list* params,
bool is_varargs, bool is_varargs,
source_location location) Location location)
{ {
Named_object* receiver_object = gogo->lookup(receiver_name, NULL); Named_object* receiver_object = gogo->lookup(receiver_name, NULL);
go_assert(receiver_object != NULL); go_assert(receiver_object != NULL);
@ -7460,7 +7467,7 @@ Type::build_one_stub_method(Gogo* gogo, Method* method,
Expression* Expression*
Type::apply_field_indexes(Expression* expr, Type::apply_field_indexes(Expression* expr,
const Method::Field_indexes* field_indexes, const Method::Field_indexes* field_indexes,
source_location location) Location location)
{ {
if (field_indexes == NULL) if (field_indexes == NULL)
return expr; return expr;
@ -7526,7 +7533,7 @@ Type::method_function(const Methods* methods, const std::string& name,
Expression* Expression*
Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr, Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
const std::string& name, const std::string& name,
source_location location) Location location)
{ {
if (type->deref()->is_error_type()) if (type->deref()->is_error_type())
return Expression::make_error(location); return Expression::make_error(location);
@ -8040,7 +8047,7 @@ Forward_declaration_type::add_method(const std::string& name,
Named_object* Named_object*
Forward_declaration_type::add_method_declaration(const std::string& name, Forward_declaration_type::add_method_declaration(const std::string& name,
Function_type* type, Function_type* type,
source_location location) Location location)
{ {
Named_object* no = this->named_object(); Named_object* no = this->named_object();
if (no->is_unknown()) if (no->is_unknown())
@ -8085,15 +8092,16 @@ Forward_declaration_type::do_get_backend(Gogo* gogo)
Expression* Expression*
Forward_declaration_type::do_type_descriptor(Gogo* gogo, Named_type* name) Forward_declaration_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{ {
Location ploc = Linemap::predeclared_location();
if (!this->is_defined()) if (!this->is_defined())
return Expression::make_nil(BUILTINS_LOCATION); return Expression::make_nil(ploc);
else else
{ {
Type* t = this->real_type(); Type* t = this->real_type();
if (name != NULL) if (name != NULL)
return this->named_type_descriptor(gogo, t, name); return this->named_type_descriptor(gogo, t, name);
else else
return Expression::make_type_descriptor(t, BUILTINS_LOCATION); return Expression::make_type_descriptor(t, ploc);
} }
} }

View File

@ -7,6 +7,8 @@
#ifndef GO_TYPES_H #ifndef GO_TYPES_H
#define GO_TYPES_H #define GO_TYPES_H
#include "go-linemap.h"
class Gogo; class Gogo;
class Package; class Package;
class Traverse; class Traverse;
@ -147,14 +149,14 @@ class Method
{ return this->do_type(); } { return this->do_type(); }
// Return the location of the method receiver. // Return the location of the method receiver.
source_location Location
receiver_location() const receiver_location() const
{ return this->do_receiver_location(); } { return this->do_receiver_location(); }
// Return an expression which binds this method to EXPR. This is // Return an expression which binds this method to EXPR. This is
// something which can be used with a function call. // something which can be used with a function call.
Expression* Expression*
bind_method(Expression* expr, source_location location) const; bind_method(Expression* expr, Location location) const;
// Return the named object for this method. This may only be called // Return the named object for this method. This may only be called
// after methods are finalized. // after methods are finalized.
@ -195,12 +197,12 @@ class Method
do_type() const = 0; do_type() const = 0;
// Return the location of the method receiver. // Return the location of the method receiver.
virtual source_location virtual Location
do_receiver_location() const = 0; do_receiver_location() const = 0;
// Bind a method to an object. // Bind a method to an object.
virtual Expression* virtual Expression*
do_bind_method(Expression* expr, source_location location) const = 0; do_bind_method(Expression* expr, Location location) const = 0;
private: private:
// The sequence of field indexes used for this method. If this is // The sequence of field indexes used for this method. If this is
@ -245,12 +247,12 @@ class Named_method : public Method
do_type() const; do_type() const;
// Return the location of the method receiver. // Return the location of the method receiver.
source_location Location
do_receiver_location() const; do_receiver_location() const;
// Bind a method to an object. // Bind a method to an object.
Expression* Expression*
do_bind_method(Expression* expr, source_location location) const; do_bind_method(Expression* expr, Location location) const;
private: private:
// The method itself. For a method which needs a stub, this starts // The method itself. For a method which needs a stub, this starts
@ -265,7 +267,7 @@ class Named_method : public Method
class Interface_method : public Method class Interface_method : public Method
{ {
public: public:
Interface_method(const std::string& name, source_location location, Interface_method(const std::string& name, Location location,
Function_type* fntype, const Field_indexes* field_indexes, Function_type* fntype, const Field_indexes* field_indexes,
unsigned int depth) unsigned int depth)
: Method(field_indexes, depth, true, true), : Method(field_indexes, depth, true, true),
@ -285,19 +287,19 @@ class Interface_method : public Method
{ return this->fntype_; } { return this->fntype_; }
// Return the location of the method receiver. // Return the location of the method receiver.
source_location Location
do_receiver_location() const do_receiver_location() const
{ return this->location_; } { return this->location_; }
// Bind a method to an object. // Bind a method to an object.
Expression* Expression*
do_bind_method(Expression* expr, source_location location) const; do_bind_method(Expression* expr, Location location) const;
private: private:
// The name of the interface method to call. // The name of the interface method to call.
std::string name_; std::string name_;
// The location of the definition of the interface method. // The location of the definition of the interface method.
source_location location_; Location location_;
// The type of the interface method. // The type of the interface method.
Function_type* fntype_; Function_type* fntype_;
}; };
@ -457,7 +459,7 @@ class Type
make_function_type(Typed_identifier* receiver, make_function_type(Typed_identifier* receiver,
Typed_identifier_list* parameters, Typed_identifier_list* parameters,
Typed_identifier_list* results, Typed_identifier_list* results,
source_location); Location);
static Pointer_type* static Pointer_type*
make_pointer_type(Type*); make_pointer_type(Type*);
@ -469,19 +471,19 @@ class Type
make_call_multiple_result_type(Call_expression*); make_call_multiple_result_type(Call_expression*);
static Struct_type* static Struct_type*
make_struct_type(Struct_field_list* fields, source_location); make_struct_type(Struct_field_list* fields, Location);
static Array_type* static Array_type*
make_array_type(Type* element_type, Expression* length); make_array_type(Type* element_type, Expression* length);
static Map_type* static Map_type*
make_map_type(Type* key_type, Type* value_type, source_location); make_map_type(Type* key_type, Type* value_type, Location);
static Channel_type* static Channel_type*
make_channel_type(bool send, bool receive, Type*); make_channel_type(bool send, bool receive, Type*);
static Interface_type* static Interface_type*
make_interface_type(Typed_identifier_list* methods, source_location); make_interface_type(Typed_identifier_list* methods, Location);
static Type* static Type*
make_type_descriptor_type(); make_type_descriptor_type();
@ -490,7 +492,7 @@ class Type
make_type_descriptor_ptr_type(); make_type_descriptor_ptr_type();
static Named_type* static Named_type*
make_named_type(Named_object*, Type*, source_location); make_named_type(Named_object*, Type*, Location);
static Type* static Type*
make_forward_declaration(Named_object*); make_forward_declaration(Named_object*);
@ -806,7 +808,7 @@ class Type
// it, bound to EXPR. // it, bound to EXPR.
static Expression* static Expression*
bind_field_or_method(Gogo*, const Type* type, Expression* expr, bind_field_or_method(Gogo*, const Type* type, Expression* expr,
const std::string& name, source_location); const std::string& name, Location);
// Return true if NAME is an unexported field or method of TYPE. // Return true if NAME is an unexported field or method of TYPE.
static bool static bool
@ -825,7 +827,7 @@ class Type
// it. The location is the location which causes us to need the // it. The location is the location which causes us to need the
// entry. // entry.
tree tree
type_descriptor_pointer(Gogo* gogo, source_location); type_descriptor_pointer(Gogo* gogo, Location);
// Return the type reflection string for this type. // Return the type reflection string for this type.
std::string std::string
@ -889,7 +891,7 @@ class Type
// Finalize the methods for a type. // Finalize the methods for a type.
static void static void
finalize_methods(Gogo*, const Type*, source_location, Methods**); finalize_methods(Gogo*, const Type*, Location, Methods**);
// Return a method from a set of methods. // Return a method from a set of methods.
static Method* static Method*
@ -1061,16 +1063,16 @@ class Type
// Build stub methods for a type. // Build stub methods for a type.
static void static void
build_stub_methods(Gogo*, const Type* type, const Methods* methods, build_stub_methods(Gogo*, const Type* type, const Methods* methods,
source_location); Location);
static void static void
build_one_stub_method(Gogo*, Method*, const char* receiver_name, build_one_stub_method(Gogo*, Method*, const char* receiver_name,
const Typed_identifier_list*, bool is_varargs, const Typed_identifier_list*, bool is_varargs,
source_location); Location);
static Expression* static Expression*
apply_field_indexes(Expression*, const Method::Field_indexes*, apply_field_indexes(Expression*, const Method::Field_indexes*,
source_location); Location);
// Look for a field or method named NAME in TYPE. // Look for a field or method named NAME in TYPE.
static bool static bool
@ -1129,7 +1131,7 @@ class Typed_identifier
{ {
public: public:
Typed_identifier(const std::string& name, Type* type, Typed_identifier(const std::string& name, Type* type,
source_location location) Location location)
: name_(name), type_(type), location_(location) : name_(name), type_(type), location_(location)
{ } { }
@ -1145,7 +1147,7 @@ class Typed_identifier
// Return the location where the name was seen. This is not always // Return the location where the name was seen. This is not always
// meaningful. // meaningful.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -1163,7 +1165,7 @@ class Typed_identifier
// Type. // Type.
Type* type_; Type* type_;
// The location where the name was seen. // The location where the name was seen.
source_location location_; Location location_;
}; };
// A list of Typed_identifiers. // A list of Typed_identifiers.
@ -1240,7 +1242,8 @@ class Typed_identifier_list
resize(size_t c) resize(size_t c)
{ {
go_assert(c <= this->entries_.size()); go_assert(c <= this->entries_.size());
this->entries_.resize(c, Typed_identifier("", NULL, UNKNOWN_LOCATION)); this->entries_.resize(c, Typed_identifier("", NULL,
Linemap::unknown_location()));
} }
// Iterators. // Iterators.
@ -1524,7 +1527,7 @@ class Function_type : public Type
{ {
public: public:
Function_type(Typed_identifier* receiver, Typed_identifier_list* parameters, Function_type(Typed_identifier* receiver, Typed_identifier_list* parameters,
Typed_identifier_list* results, source_location location) Typed_identifier_list* results, Location location)
: Type(TYPE_FUNCTION), : Type(TYPE_FUNCTION),
receiver_(receiver), parameters_(parameters), results_(results), receiver_(receiver), parameters_(parameters), results_(results),
location_(location), is_varargs_(false), is_builtin_(false) location_(location), is_varargs_(false), is_builtin_(false)
@ -1556,7 +1559,7 @@ class Function_type : public Type
{ return this->is_builtin_; } { return this->is_builtin_; }
// The location where this type was defined. // The location where this type was defined.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -1659,7 +1662,7 @@ class Function_type : public Type
// The location where this type was defined. This exists solely to // The location where this type was defined. This exists solely to
// give a location for the fields of the struct if this function // give a location for the fields of the struct if this function
// returns multiple values. // returns multiple values.
source_location location_; Location location_;
// Whether this function takes a variable number of arguments. // Whether this function takes a variable number of arguments.
bool is_varargs_; bool is_varargs_;
// Whether this is a special builtin function which can not simply // Whether this is a special builtin function which can not simply
@ -1742,7 +1745,7 @@ class Struct_field
{ return this->typed_identifier_.type(); } { return this->typed_identifier_.type(); }
// The field location. // The field location.
source_location Location
location() const location() const
{ return this->typed_identifier_.location(); } { return this->typed_identifier_.location(); }
@ -1845,7 +1848,7 @@ class Struct_field_list
class Struct_type : public Type class Struct_type : public Type
{ {
public: public:
Struct_type(Struct_field_list* fields, source_location location) Struct_type(Struct_field_list* fields, Location location)
: Type(TYPE_STRUCT), : Type(TYPE_STRUCT),
fields_(fields), location_(location), all_methods_(NULL) fields_(fields), location_(location), all_methods_(NULL)
{ } { }
@ -1882,7 +1885,7 @@ class Struct_type : public Type
// NULL if there is no field with that name. // NULL if there is no field with that name.
Field_reference_expression* Field_reference_expression*
field_reference(Expression* struct_expr, const std::string& name, field_reference(Expression* struct_expr, const std::string& name,
source_location) const; Location) const;
// Return the total number of fields, including embedded fields. // Return the total number of fields, including embedded fields.
// This is the number of values which can appear in a conversion to // This is the number of values which can appear in a conversion to
@ -1979,13 +1982,13 @@ class Struct_type : public Type
Field_reference_expression* Field_reference_expression*
field_reference_depth(Expression* struct_expr, const std::string& name, field_reference_depth(Expression* struct_expr, const std::string& name,
source_location, Saw_named_type*, Location, Saw_named_type*,
unsigned int* depth) const; unsigned int* depth) const;
// The fields of the struct. // The fields of the struct.
Struct_field_list* fields_; Struct_field_list* fields_;
// The place where the struct was declared. // The place where the struct was declared.
source_location location_; Location location_;
// If this struct is unnamed, a list of methods. // If this struct is unnamed, a list of methods.
Methods* all_methods_; Methods* all_methods_;
}; };
@ -2106,7 +2109,7 @@ class Array_type : public Type
class Map_type : public Type class Map_type : public Type
{ {
public: public:
Map_type(Type* key_type, Type* val_type, source_location location) Map_type(Type* key_type, Type* val_type, Location location)
: Type(TYPE_MAP), : Type(TYPE_MAP),
key_type_(key_type), val_type_(val_type), location_(location) key_type_(key_type), val_type_(val_type), location_(location)
{ } { }
@ -2139,7 +2142,7 @@ class Map_type : public Type
// The location is the location which causes us to need the // The location is the location which causes us to need the
// descriptor. // descriptor.
tree tree
map_descriptor_pointer(Gogo* gogo, source_location); map_descriptor_pointer(Gogo* gogo, Location);
protected: protected:
int int
@ -2184,7 +2187,7 @@ class Map_type : public Type
// The value type. // The value type.
Type* val_type_; Type* val_type_;
// Where the type was defined. // Where the type was defined.
source_location location_; Location location_;
}; };
// The type of a channel. // The type of a channel.
@ -2267,13 +2270,13 @@ class Channel_type : public Type
class Interface_type : public Type class Interface_type : public Type
{ {
public: public:
Interface_type(Typed_identifier_list* methods, source_location location) Interface_type(Typed_identifier_list* methods, Location location)
: Type(TYPE_INTERFACE), : Type(TYPE_INTERFACE),
methods_(methods), location_(location) methods_(methods), location_(location)
{ go_assert(methods == NULL || !methods->empty()); } { go_assert(methods == NULL || !methods->empty()); }
// The location where the interface type was defined. // The location where the interface type was defined.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -2368,7 +2371,7 @@ class Interface_type : public Type
// NULL for the empty interface. // NULL for the empty interface.
Typed_identifier_list* methods_; Typed_identifier_list* methods_;
// The location where the interface was defined. // The location where the interface was defined.
source_location location_; Location location_;
}; };
// The value we keep for a named type. This lets us get the right // The value we keep for a named type. This lets us get the right
@ -2380,7 +2383,7 @@ class Interface_type : public Type
class Named_type : public Type class Named_type : public Type
{ {
public: public:
Named_type(Named_object* named_object, Type* type, source_location location) Named_type(Named_object* named_object, Type* type, Location location)
: Type(TYPE_NAMED), : Type(TYPE_NAMED),
named_object_(named_object), in_function_(NULL), type_(type), named_object_(named_object), in_function_(NULL), type_(type),
local_methods_(NULL), all_methods_(NULL), local_methods_(NULL), all_methods_(NULL),
@ -2436,7 +2439,7 @@ class Named_type : public Type
{ return this->type_; } { return this->type_; }
// Return the location. // Return the location.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
@ -2458,7 +2461,7 @@ class Named_type : public Type
// Whether this is a builtin type. // Whether this is a builtin type.
bool bool
is_builtin() const is_builtin() const
{ return this->location_ == BUILTINS_LOCATION; } { return Linemap::is_predeclared_location(this->location_); }
// Whether this is a circular type: a pointer or function type that // Whether this is a circular type: a pointer or function type that
// refers to itself, which is not possible in C. // refers to itself, which is not possible in C.
@ -2484,7 +2487,7 @@ class Named_type : public Type
// Add a method declaration to this type. // Add a method declaration to this type.
Named_object* Named_object*
add_method_declaration(const std::string& name, Package* package, add_method_declaration(const std::string& name, Package* package,
Function_type* type, source_location location); Function_type* type, Location location);
// Add an existing method--one defined before the type itself was // Add an existing method--one defined before the type itself was
// defined--to a type. // defined--to a type.
@ -2617,7 +2620,7 @@ class Named_type : public Type
// tables for pointers to this type. // tables for pointers to this type.
Interface_method_tables* pointer_interface_method_tables_; Interface_method_tables* pointer_interface_method_tables_;
// The location where this type was defined. // The location where this type was defined.
source_location location_; Location location_;
// The backend representation of this type during backend // The backend representation of this type during backend
// conversion. This is used to avoid endless recursion when a named // conversion. This is used to avoid endless recursion when a named
// type refers to itself. // type refers to itself.
@ -2691,7 +2694,7 @@ class Forward_declaration_type : public Type
// Add a method declaration to this type. // Add a method declaration to this type.
Named_object* Named_object*
add_method_declaration(const std::string& name, Function_type*, add_method_declaration(const std::string& name, Function_type*,
source_location); Location);
protected: protected:
int int

View File

@ -15,9 +15,9 @@
void void
Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported, Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
source_location location) Location location)
{ {
location_t bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
bool add_to_globals; bool add_to_globals;
Package* package = this->add_imported_package("unsafe", local_name, Package* package = this->add_imported_package("unsafe", local_name,
@ -41,7 +41,8 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
if (no == NULL) if (no == NULL)
{ {
Type* type = Type::make_pointer_type(Type::make_void_type()); Type* type = Type::make_pointer_type(Type::make_void_type());
no = bindings->add_type("Pointer", package, type, UNKNOWN_LOCATION); no = bindings->add_type("Pointer", package, type,
Linemap::unknown_location());
} }
else else
{ {