Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

THRIFT-5637: Add no_constructors option to C++ compiler #3037

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 68 additions & 51 deletions compiler/cpp/src/thrift/generate/t_cpp_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class t_cpp_generator : public t_oop_generator {
gen_moveable_ = false;
gen_no_ostream_operators_ = false;
gen_no_skeleton_ = false;
gen_no_constructors_ = false;
has_members_ = false;

for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
Expand All @@ -88,6 +89,8 @@ class t_cpp_generator : public t_oop_generator {
gen_no_ostream_operators_ = true;
} else if ( iter->first.compare("no_skeleton") == 0) {
gen_no_skeleton_ = true;
} else if ( iter->first.compare("no_constructors") == 0) {
gen_no_constructors_ = true;
} else {
throw "unknown option cpp:" + iter->first;
}
Expand Down Expand Up @@ -124,7 +127,7 @@ class t_cpp_generator : public t_oop_generator {
void generate_service(t_service* tservice) override;

void print_const_value(std::ostream& out, std::string name, t_type* type, t_const_value* value);
std::string render_const_value(std::ostream& out,
std::string render_const_value(std::ostream* out,
std::string name,
t_type* type,
t_const_value* value);
Expand Down Expand Up @@ -369,10 +372,15 @@ class t_cpp_generator : public t_oop_generator {
bool gen_no_default_operators_;

/**
* True if we should generate skeleton.
* True if we should omit generating skeleton.
*/
bool gen_no_skeleton_;

/**
* True if we should omit generating constructors/destructors/assignment/destructors.
*/
bool gen_no_constructors_;

/**
* True if thrift has member(s)
*/
Expand Down Expand Up @@ -786,7 +794,7 @@ void t_cpp_generator::print_const_value(ostream& out,
t_const_value* value) {
type = get_true_type(type);
if (type->is_base_type()) {
string v2 = render_const_value(out, name, type, value);
string v2 = render_const_value(&out, name, type, value);
indent(out) << name << " = " << v2 << ";" << '\n' << '\n';
} else if (type->is_enum()) {
indent(out) << name
Expand All @@ -810,7 +818,7 @@ void t_cpp_generator::print_const_value(ostream& out,
if (field_type == nullptr) {
throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
}
string item_val = render_const_value(out, name, field_type, v_iter->second);
string item_val = render_const_value(&out, name, field_type, v_iter->second);
indent(out) << name << "." << v_iter->first->get_string() << " = " << item_val << ";" << '\n';
if (is_nonrequired_field) {
indent(out) << name << ".__isset." << v_iter->first->get_string() << " = true;" << '\n';
Expand All @@ -823,8 +831,8 @@ void t_cpp_generator::print_const_value(ostream& out,
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string key = render_const_value(out, name, ktype, v_iter->first);
string item_val = render_const_value(out, name, vtype, v_iter->second);
string key = render_const_value(&out, name, ktype, v_iter->first);
string item_val = render_const_value(&out, name, vtype, v_iter->second);
indent(out) << name << ".insert(std::make_pair(" << key << ", " << item_val << "));" << '\n';
}
out << '\n';
Expand All @@ -833,7 +841,7 @@ void t_cpp_generator::print_const_value(ostream& out,
const vector<t_const_value*>& val = value->get_list();
vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string item_val = render_const_value(out, name, etype, *v_iter);
string item_val = render_const_value(&out, name, etype, *v_iter);
indent(out) << name << ".push_back(" << item_val << ");" << '\n';
}
out << '\n';
Expand All @@ -842,7 +850,7 @@ void t_cpp_generator::print_const_value(ostream& out,
const vector<t_const_value*>& val = value->get_list();
vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string item_val = render_const_value(out, name, etype, *v_iter);
string item_val = render_const_value(&out, name, etype, *v_iter);
indent(out) << name << ".insert(" << item_val << ");" << '\n';
}
out << '\n';
Expand All @@ -854,7 +862,7 @@ void t_cpp_generator::print_const_value(ostream& out,
/**
*
*/
string t_cpp_generator::render_const_value(ostream& out,
string t_cpp_generator::render_const_value(ostream* out,
string name,
t_type* type,
t_const_value* value) {
Expand Down Expand Up @@ -891,10 +899,10 @@ string t_cpp_generator::render_const_value(ostream& out,
} else if (type->is_enum()) {
render << "static_cast<" << type_name(type) << '>'
<< '(' << value->get_integer() << ')';
} else {
} else if (out) {
string t = tmp("tmp");
indent(out) << type_name(type) << " " << t << ";" << '\n';
print_const_value(out, t, type, value);
indent(*out) << type_name(type) << " " << t << ";" << '\n';
print_const_value(*out, t, type, value);
render << t;
}

Expand Down Expand Up @@ -924,13 +932,15 @@ void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception)
if (!gen_no_default_operators_) {
generate_equality_operator(f_types_impl_, tstruct);
}
generate_copy_constructor(f_types_impl_, tstruct, is_exception);
if (gen_moveable_) {
generate_move_constructor(f_types_impl_, tstruct, is_exception);
}
generate_assignment_operator(f_types_impl_, tstruct);
if (gen_moveable_) {
generate_move_assignment_operator(f_types_impl_, tstruct);
if (!gen_no_constructors_) {
generate_copy_constructor(f_types_impl_, tstruct, is_exception);
if (gen_moveable_) {
generate_move_constructor(f_types_impl_, tstruct, is_exception);
}
generate_assignment_operator(f_types_impl_, tstruct);
if (gen_moveable_) {
generate_move_assignment_operator(f_types_impl_, tstruct);
}
}

if (!has_custom_ostream(tstruct)) {
Expand Down Expand Up @@ -1026,7 +1036,7 @@ void t_cpp_generator::generate_default_constructor(ostream& out,
string dval;
t_const_value* cv = (*m_iter)->get_value();
if (cv != nullptr) {
dval += render_const_value(out, (*m_iter)->get_name(), t, cv);
dval += render_const_value(&out, (*m_iter)->get_name(), t, cv);
} else if (t->is_enum()) {
dval += "static_cast<" + type_name(t) + ">(0)";
} else {
Expand Down Expand Up @@ -1266,7 +1276,7 @@ void t_cpp_generator::generate_struct_declaration(ostream& out,
<< " public:" << '\n' << '\n';
indent_up();

if (!pointers) {
if (!gen_no_constructors_ && !pointers) {
bool ok_noexcept = is_struct_storage_not_throwing(tstruct);
// Copy constructor
indent(out) << tstruct->get_name() << "(const " << tstruct->get_name() << "&)"
Expand Down Expand Up @@ -1295,15 +1305,17 @@ void t_cpp_generator::generate_struct_declaration(ostream& out,
indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept") << ";" << '\n';
}

if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
out << '\n' << indent() << "virtual ~" << tstruct->get_name() << "() noexcept;" << '\n';
if (!gen_no_constructors_ && tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
out << '\n' << indent();
if (!gen_templates_) out << "virtual ";
out << "~" << tstruct->get_name() << "() noexcept;\n";
}

// Declare all fields
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
generate_java_doc(out, *m_iter);
indent(out) << declare_field(*m_iter,
false,
!pointers && gen_no_constructors_,
(pointers && !(*m_iter)->get_type()->is_xception()),
!read) << '\n';
}
Expand Down Expand Up @@ -1376,7 +1388,8 @@ void t_cpp_generator::generate_struct_declaration(ostream& out,
out << '\n';

if (is_user_struct && !has_custom_ostream(tstruct)) {
out << indent() << "virtual ";
out << indent();
if (!gen_templates_) out << "virtual ";
generate_struct_print_method_decl(out, nullptr);
out << ";" << '\n';
}
Expand Down Expand Up @@ -1419,7 +1432,7 @@ void t_cpp_generator::generate_struct_definition(ostream& out,
const vector<t_field*>& members = tstruct->get_members();

// Destructor
if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
if (!gen_no_constructors_ && tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
force_cpp_out << '\n' << indent() << tstruct->get_name() << "::~" << tstruct->get_name()
<< "() noexcept {" << '\n';
indent_up();
Expand All @@ -1428,7 +1441,7 @@ void t_cpp_generator::generate_struct_definition(ostream& out,
force_cpp_out << indent() << "}" << '\n' << '\n';
}

if (!pointers)
if (!gen_no_constructors_ && !pointers)
{
// 'force_cpp_out' always goes into the .cpp file, and never into a .tcc
// file in case templates are involved. Since the constructor is not templated,
Expand Down Expand Up @@ -4607,31 +4620,35 @@ string t_cpp_generator::declare_field(t_field* tfield,
result += " " + tfield->get_name();
if (init) {
t_type* type = get_true_type(tfield->get_type());

if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
switch (tbase) {
case t_base_type::TYPE_VOID:
case t_base_type::TYPE_STRING:
case t_base_type::TYPE_UUID:
break;
case t_base_type::TYPE_BOOL:
result += " = false";
break;
case t_base_type::TYPE_I8:
case t_base_type::TYPE_I16:
case t_base_type::TYPE_I32:
case t_base_type::TYPE_I64:
result += " = 0";
break;
case t_base_type::TYPE_DOUBLE:
result += " = 0.0";
break;
default:
throw "compiler error: no C++ initializer for base type " + t_base_type::t_base_name(tbase);
if (t_const_value* cv = tfield->get_value()) {
result += " = " + render_const_value(nullptr, tfield->get_name(), type, cv);
} else {
if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();

switch (tbase) {
case t_base_type::TYPE_VOID:
case t_base_type::TYPE_STRING:
case t_base_type::TYPE_UUID:
break;
case t_base_type::TYPE_BOOL:
result += " = false";
break;
case t_base_type::TYPE_I8:
case t_base_type::TYPE_I16:
case t_base_type::TYPE_I32:
case t_base_type::TYPE_I64:
result += " = 0";
break;
case t_base_type::TYPE_DOUBLE:
result += " = 0.0";
break;
default:
throw "compiler error: no C++ initializer for base type " + t_base_type::t_base_name(tbase);
}
} else if (type->is_enum()) {
result += " = static_cast<" + type_name(type) + ">(0)";
}
} else if (type->is_enum()) {
result += " = static_cast<" + type_name(type) + ">(0)";
}
}
if (!reference) {
Expand Down