Generate structs/exceptions in declared order

Summary: Otherwise you're liable to get forward declaration problems in the generated C++ code.

Reviewed By: dreiss

Test Plan: Generate some code that mixes exceptions/structs and has methods potentially return a list of exceptions


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665423 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_generator.cc b/compiler/cpp/src/generate/t_generator.cc
index 068822c..98ed6ee 100644
--- a/compiler/cpp/src/generate/t_generator.cc
+++ b/compiler/cpp/src/generate/t_generator.cc
@@ -37,18 +37,15 @@
   vector<t_const*> consts = program_->get_consts();
   generate_consts(consts);
 
-  // Generate structs
-  vector<t_struct*> structs = program_->get_structs();
-  vector<t_struct*>::iterator st_iter;
-  for (st_iter = structs.begin(); st_iter != structs.end(); ++st_iter) {
-    generate_struct(*st_iter);
-  }
-
-  // Generate xceptions
-  vector<t_struct*> xceptions = program_->get_xceptions();
-  vector<t_struct*>::iterator x_iter;
-  for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-    generate_xception(*x_iter);
+  // Generate structs and exceptions in declared order
+  vector<t_struct*> objects = program_->get_objects();
+  vector<t_struct*>::iterator o_iter;
+  for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) {
+    if ((*o_iter)->is_xception()) {
+      generate_xception(*o_iter);
+    } else {
+      generate_struct(*o_iter);
+    }
   }
 
   // Generate services
diff --git a/compiler/cpp/src/parse/t_program.h b/compiler/cpp/src/parse/t_program.h
index 66f0620..62528e6 100644
--- a/compiler/cpp/src/parse/t_program.h
+++ b/compiler/cpp/src/parse/t_program.h
@@ -76,14 +76,17 @@
   const std::vector<t_const*>&   get_consts()    const { return consts_;    }
   const std::vector<t_struct*>&  get_structs()   const { return structs_;   }
   const std::vector<t_struct*>&  get_xceptions() const { return xceptions_; }
+  const std::vector<t_struct*>&  get_objects()   const { return objects_;   }
   const std::vector<t_service*>& get_services()  const { return services_;  }
 
   // Program elements
   void add_typedef  (t_typedef* td) { typedefs_.push_back(td);  }
   void add_enum     (t_enum*    te) { enums_.push_back(te);     }
   void add_const    (t_const*   tc) { consts_.push_back(tc);    }
-  void add_struct   (t_struct*  ts) { structs_.push_back(ts);   }
-  void add_xception (t_struct*  tx) { xceptions_.push_back(tx); }
+  void add_struct   (t_struct*  ts) { objects_.push_back(ts);
+                                      structs_.push_back(ts);   }
+  void add_xception (t_struct*  tx) { objects_.push_back(tx);
+                                      xceptions_.push_back(tx); }
   void add_service  (t_service* ts) { services_.push_back(ts);  }
 
   // Programs to include
@@ -211,7 +214,7 @@
   void set_smalltalk_prefix(std::string smalltalk_prefix) {
     smalltalk_prefix_ = smalltalk_prefix;
   }
-  
+
   const std::string& get_smalltalk_prefix() const {
     return smalltalk_prefix_;
   }
@@ -240,6 +243,7 @@
   std::vector<t_typedef*> typedefs_;
   std::vector<t_enum*>    enums_;
   std::vector<t_const*>   consts_;
+  std::vector<t_struct*>  objects_;
   std::vector<t_struct*>  structs_;
   std::vector<t_struct*>  xceptions_;
   std::vector<t_service*> services_;