@@ -861,13 +861,9 @@ void cpp_typecheckt::typecheck_friend_declaration(
861
861
862
862
if (declaration.is_template ())
863
863
{
864
- return ; // TODO
865
-
866
- #if 0
867
864
error ().source_location =declaration.type ().source_location ();
868
865
error () << " friend template not supported" << eom;
869
866
throw 0 ;
870
- #endif
871
867
}
872
868
873
869
// we distinguish these whether there is a declarator
@@ -890,51 +886,41 @@ void cpp_typecheckt::typecheck_friend_declaration(
890
886
throw 0 ;
891
887
}
892
888
893
- // typecheck ftype
894
-
895
- // TODO
896
- // typecheck_type(ftype);
897
- // symbol.type.add("ID_C_friends").move_to_sub(ftype);
889
+ cpp_save_scopet saved_scope (cpp_scopes);
890
+ cpp_scopes.go_to_global_scope ();
891
+ typecheck_type (ftype);
892
+ symbol.type .add (ID_C_friends).move_to_sub (ftype);
898
893
899
894
return ;
900
895
}
901
896
902
897
// It should be a friend function.
903
898
// Do the declarators.
904
899
900
+ #ifdef DEBUG
901
+ std::cout << " friend declaration: " << declaration.pretty () << ' \n ' ;
902
+ #endif
903
+
905
904
for (auto &sub_it : declaration.declarators ())
906
905
{
907
- bool has_value = sub_it.value ().is_not_nil ();
908
-
909
- if (!has_value)
910
- {
911
- // If no value is found, then we jump to the
912
- // global scope, and we convert the declarator
913
- // as if it were declared there
914
- cpp_save_scopet saved_scope (cpp_scopes);
915
- cpp_scopes.go_to_global_scope ();
916
- cpp_declarator_convertert cpp_declarator_converter (*this );
917
- const symbolt &conv_symb=cpp_declarator_converter.convert (
918
- declaration.type (), declaration.storage_spec (),
919
- declaration.member_spec (), sub_it);
920
- exprt symb_expr=cpp_symbol_expr (conv_symb);
921
- symbol.type .add (ID_C_friends).move_to_sub (symb_expr);
922
- }
923
- else
924
- {
925
- cpp_declarator_convertert cpp_declarator_converter (*this );
926
- cpp_declarator_converter.is_friend =true ;
906
+ #ifdef DEBUG
907
+ std::cout << " decl: " << sub_it.pretty () << " \n with value "
908
+ << sub_it.value ().pretty () << ' \n ' ;
909
+ std::cout << " scope: " << cpp_scopes.current_scope ().prefix << ' \n ' ;
910
+ #endif
927
911
912
+ if (sub_it.value ().is_not_nil ())
928
913
declaration.member_spec ().set_inline (true );
929
914
930
- const symbolt &conv_symb=cpp_declarator_converter.convert (
931
- declaration.type (), declaration.storage_spec (),
932
- declaration.member_spec (), sub_it);
933
-
934
- exprt symb_expr=cpp_symbol_expr (conv_symb);
935
-
936
- symbol.type .add (ID_C_friends).move_to_sub (symb_expr);
937
- }
915
+ cpp_declarator_convertert cpp_declarator_converter (*this );
916
+ cpp_declarator_converter.is_friend = true ;
917
+ const symbolt &conv_symb = cpp_declarator_converter.convert (
918
+ declaration.type (),
919
+ declaration.storage_spec (),
920
+ declaration.member_spec (),
921
+ sub_it);
922
+ exprt symb_expr = cpp_symbol_expr (conv_symb);
923
+ symbol.type .add (ID_C_friends).move_to_sub (symb_expr);
938
924
}
939
925
}
940
926
@@ -1322,7 +1308,13 @@ void cpp_typecheckt::typecheck_member_function(
1322
1308
// move early, it must be visible before doing any value
1323
1309
symbolt *new_symbol;
1324
1310
1325
- if (symbol_table.move (symbol, new_symbol))
1311
+ const bool symbol_exists = symbol_table.move (symbol, new_symbol);
1312
+ if (symbol_exists && new_symbol->is_weak )
1313
+ {
1314
+ // there might have been an earlier friend declaration
1315
+ *new_symbol = std::move (symbol);
1316
+ }
1317
+ else if (symbol_exists)
1326
1318
{
1327
1319
error ().source_location =symbol.location ;
1328
1320
error () << " failed to insert new method symbol: " << symbol.name << ' \n '
0 commit comments