From b7b936848a8dcbc3f726021fddd97273ff771715 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Tue, 28 Jan 2025 00:56:26 +0100 Subject: [PATCH] =?UTF-8?q?Zwischenstand:=20ab=20hier=20m=C3=BC=C3=9Fte=20?= =?UTF-8?q?der=20Code=20zur=20Laufzeit=20testen,=20welcher=20Fall=20vorlie?= =?UTF-8?q?gt,=20um=20den=20richtigen=20Code=20zur=20Serialisierung/Deseri?= =?UTF-8?q?alisierung=20zu=20w=C3=A4hlen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/thrift/generate/t_delphi_generator.cc | 6 +++--- compiler/cpp/src/thrift/parse/parse.cc | 18 +++++++++++++++++- compiler/cpp/src/thrift/parse/t_scope.h | 5 ++++- compiler/cpp/src/thrift/parse/t_struct.h | 8 ++++++++ compiler/cpp/src/thrift/parse/t_type.h | 6 ++++++ compiler/cpp/src/thrift/parse/t_typedef.cc | 6 +++++- compiler/cpp/src/thrift/parse/t_typedef.h | 5 ++++- 7 files changed, 47 insertions(+), 7 deletions(-) diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc index 352dcdca5ab..163d6bc9cc8 100644 --- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc @@ -2637,7 +2637,8 @@ void t_delphi_generator::generate_deserialize_field(ostream& out, string prefix, ostream& local_vars, std::map* generic) { - t_type* type = tfield->get_type()->get_true_type(generic); + const mapped_type* mapped = tfield->get_type()->try_get_true_type(generic); + t_type* type = mapped->get_type() != nullptr ? mapped->get_type() : tfield->get_type(); if (type->is_void()) { throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " + prefix + tfield->get_name(); @@ -3081,8 +3082,7 @@ string t_delphi_generator::type_name(t_type* ttype, return type_name(resolved->get_type(), b_cls, b_no_postfix, generic); } else if(resolved->is_generic_decl()) { return std::string("<" + normalize_name(resolved->symbolic()) + ">"); - } - else { + } else { throw "Unresolved forward declaration: Used type never defined: " + tdef->get_symbolic(); } } else { diff --git a/compiler/cpp/src/thrift/parse/parse.cc b/compiler/cpp/src/thrift/parse/parse.cc index 97c6570c439..4055cfa818e 100644 --- a/compiler/cpp/src/thrift/parse/parse.cc +++ b/compiler/cpp/src/thrift/parse/parse.cc @@ -28,8 +28,24 @@ t_type* t_type::get_true_type(std::map* generic) { const t_type* t_type::get_true_type(std::map* generic) const { const t_type* type = this; - while (type->is_typedef()) { + const t_type* prev = nullptr; + while (type->is_typedef() && (prev != type)) { + prev = type; type = ((t_typedef*)type)->get_type(generic); } return type; } + +mapped_type* t_type::try_get_true_type(std::map* generic) { + return const_cast(const_cast(this)->try_get_true_type(generic)); +} + +const mapped_type* t_type::try_get_true_type(std::map* generic) const { + const mapped_type* mapped = new mapped_type(get_name(), this); + const t_type* type = mapped->get_type(); + while ((type != nullptr) && type->is_typedef()) { + mapped = ((t_typedef*)type)->get_generic_type(generic); + type = type = mapped->get_type(); + } + return mapped; +} diff --git a/compiler/cpp/src/thrift/parse/t_scope.h b/compiler/cpp/src/thrift/parse/t_scope.h index 09f7d6e374a..f676e483d46 100644 --- a/compiler/cpp/src/thrift/parse/t_scope.h +++ b/compiler/cpp/src/thrift/parse/t_scope.h @@ -45,7 +45,10 @@ class t_scope { public: t_scope() = default; - void add_type(std::string name, t_type* type) { types_[name] = type; } + void add_type(std::string name, t_type* type) { + types_[name] = type; + type->mark_as_declaration(); + } t_type* get_type(std::string name) { return types_[name]; } diff --git a/compiler/cpp/src/thrift/parse/t_struct.h b/compiler/cpp/src/thrift/parse/t_struct.h index 8b4c933a1fd..8931f50cb44 100644 --- a/compiler/cpp/src/thrift/parse/t_struct.h +++ b/compiler/cpp/src/thrift/parse/t_struct.h @@ -86,6 +86,14 @@ class t_struct : public t_type { virtual std::vector* get_template_decl_type() const { return tmpl_decl_type_; } + virtual void mark_as_declaration() { + members_type::const_iterator m_iter; + for (m_iter = members_.begin(); m_iter != members_.end(); ++m_iter) { + (*m_iter)->get_type()->mark_as_declaration(); + } + }; + + bool is_generic_type() const { return (tmpl_decl_type_ != nullptr) && (tmpl_decl_type_->size() > 0); } diff --git a/compiler/cpp/src/thrift/parse/t_type.h b/compiler/cpp/src/thrift/parse/t_type.h index 868a7f67d01..ea263a1693c 100644 --- a/compiler/cpp/src/thrift/parse/t_type.h +++ b/compiler/cpp/src/thrift/parse/t_type.h @@ -90,6 +90,8 @@ class t_type : public t_doc { virtual bool is_service() const { return false; } virtual bool is_specialized_generic() const { return false; } + virtual void mark_as_declaration() {}; + t_program* get_program() { return program_; } const t_program* get_program() const { return program_; } @@ -97,6 +99,10 @@ class t_type : public t_doc { t_type* get_true_type(std::map* generic = nullptr); const t_type* get_true_type(std::map* generic = nullptr) const; + mapped_type* t_type::try_get_true_type(std::map* generic); + const mapped_type* t_type::try_get_true_type(std::map* generic) const; + + // This function will break (maybe badly) unless 0 <= num <= 16. static char nybble_to_xdigit(int num) { if (num < 10) { diff --git a/compiler/cpp/src/thrift/parse/t_typedef.cc b/compiler/cpp/src/thrift/parse/t_typedef.cc index 2b9dd497a97..7242c9e9554 100644 --- a/compiler/cpp/src/thrift/parse/t_typedef.cc +++ b/compiler/cpp/src/thrift/parse/t_typedef.cc @@ -31,6 +31,10 @@ const t_type* t_typedef::get_type(std::map* generic) c return mapped->get_type(); } + if (is_declaration()) { + return this; // generic type declaration is fully specialized at usage, not declaration + } + printf("Type \"%s\" not defined\n", symbolic_.c_str()); exit(1); } @@ -52,6 +56,6 @@ const mapped_type* t_typedef::get_generic_type(std::map