ast_java: shared_ptr everywhere

So that these things will be deleted so that we can turn on leak
detection and so that checks in the destructor (like asserting that
"CheckValid" is called) are actually meaningful.

(note, this is more straightforward than simply rewriting this to not
use ast_java at all due to things like outline methods)

Bug: 37749857
Test: runtests.sh
Test: less leaks reported
Change-Id: Icc59069b9e3b660d0878bc338c86c30b80bb5e18
diff --git a/ast_java.cpp b/ast_java.cpp
index 5eab218..f997494 100644
--- a/ast_java.cpp
+++ b/ast_java.cpp
@@ -65,7 +65,7 @@
   }
 }
 
-void WriteArgumentList(CodeWriter* to, const vector<Expression*>& arguments) {
+void WriteArgumentList(CodeWriter* to, const vector<std::shared_ptr<Expression>>& arguments) {
   size_t N = arguments.size();
   for (size_t i = 0; i < N; i++) {
     arguments[i]->Write(to);
@@ -75,7 +75,7 @@
   }
 }
 
-Field::Field(int m, Variable* v) : ClassElement(), modifiers(m), variable(v) {}
+Field::Field(int m, std::shared_ptr<Variable> v) : ClassElement(), modifiers(m), variable(v) {}
 
 void Field::Write(CodeWriter* to) const {
   if (this->comment.length() != 0) {
@@ -113,13 +113,14 @@
 
 void Variable::Write(CodeWriter* to) const { to->Write("%s", name.c_str()); }
 
-FieldVariable::FieldVariable(Expression* o, const string& n) : receiver(o), name(n) {}
+FieldVariable::FieldVariable(std::shared_ptr<Expression> o, const string& n)
+    : receiver(o), name(n) {}
 
 FieldVariable::FieldVariable(const string& c, const string& n) : receiver(c), name(n) {}
 
 void FieldVariable::Write(CodeWriter* to) const {
   visit(
-      overloaded{[&](Expression* e) { e->Write(to); },
+      overloaded{[&](std::shared_ptr<Expression> e) { e->Write(to); },
                  [&](const std::string& s) { to->Write("%s", s.c_str()); }, [](std::monostate) {}},
       this->receiver);
   to->Write(".%s", name.c_str());
@@ -142,24 +143,26 @@
   to->Write("}\n");
 }
 
-void StatementBlock::Add(Statement* statement) {
+void StatementBlock::Add(std::shared_ptr<Statement> statement) {
   this->statements.push_back(statement);
 }
 
-void StatementBlock::Add(Expression* expression) {
-  this->statements.push_back(new ExpressionStatement(expression));
+void StatementBlock::Add(std::shared_ptr<Expression> expression) {
+  this->statements.push_back(std::make_shared<ExpressionStatement>(expression));
 }
 
-ExpressionStatement::ExpressionStatement(Expression* e) : expression(e) {}
+ExpressionStatement::ExpressionStatement(std::shared_ptr<Expression> e) : expression(e) {}
 
 void ExpressionStatement::Write(CodeWriter* to) const {
   this->expression->Write(to);
   to->Write(";\n");
 }
 
-Assignment::Assignment(Variable* l, Expression* r) : lvalue(l), rvalue(r) {}
+Assignment::Assignment(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r)
+    : lvalue(l), rvalue(r) {}
 
-Assignment::Assignment(Variable* l, Expression* r, string c) : lvalue(l), rvalue(r), cast(c) {}
+Assignment::Assignment(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r, string c)
+    : lvalue(l), rvalue(r), cast(c) {}
 
 void Assignment::Write(CodeWriter* to) const {
   this->lvalue->Write(to);
@@ -172,42 +175,24 @@
 
 MethodCall::MethodCall(const string& n) : name(n) {}
 
-MethodCall::MethodCall(const string& n, int argc = 0, ...) : name(n) {
-  va_list args;
-  va_start(args, argc);
-  init(argc, args);
-  va_end(args);
-}
+MethodCall::MethodCall(const string& n, const std::vector<std::shared_ptr<Expression>>& args)
+    : name(n), arguments(args) {}
 
-MethodCall::MethodCall(Expression* o, const string& n) : receiver(o), name(n) {}
+MethodCall::MethodCall(std::shared_ptr<Expression> o, const string& n) : receiver(o), name(n) {}
 
 MethodCall::MethodCall(const std::string& t, const string& n) : receiver(t), name(n) {}
 
-MethodCall::MethodCall(Expression* o, const string& n, int argc = 0, ...) : receiver(o), name(n) {
-  va_list args;
-  va_start(args, argc);
-  init(argc, args);
-  va_end(args);
-}
+MethodCall::MethodCall(std::shared_ptr<Expression> o, const string& n,
+                       const std::vector<std::shared_ptr<Expression>>& args)
+    : receiver(o), name(n), arguments(args) {}
 
-MethodCall::MethodCall(const std::string& t, const string& n, int argc = 0, ...)
-    : receiver(t), name(n) {
-  va_list args;
-  va_start(args, argc);
-  init(argc, args);
-  va_end(args);
-}
-
-void MethodCall::init(int n, va_list args) {
-  for (int i = 0; i < n; i++) {
-    Expression* expression = (Expression*)va_arg(args, void*);
-    this->arguments.push_back(expression);
-  }
-}
+MethodCall::MethodCall(const std::string& t, const string& n,
+                       const std::vector<std::shared_ptr<Expression>>& args)
+    : receiver(t), name(n), arguments(args) {}
 
 void MethodCall::Write(CodeWriter* to) const {
   visit(
-      overloaded{[&](Expression* e) {
+      overloaded{[&](std::shared_ptr<Expression> e) {
                    e->Write(to);
                    to->Write(".");
                  },
@@ -218,7 +203,8 @@
   to->Write(")");
 }
 
-Comparison::Comparison(Expression* l, const string& o, Expression* r)
+Comparison::Comparison(std::shared_ptr<Expression> l, const string& o,
+                       std::shared_ptr<Expression> r)
     : lvalue(l), op(o), rvalue(r) {}
 
 void Comparison::Write(CodeWriter* to) const {
@@ -231,19 +217,9 @@
 
 NewExpression::NewExpression(const std::string& n) : instantiableName(n) {}
 
-NewExpression::NewExpression(const std::string& n, int argc = 0, ...) : instantiableName(n) {
-  va_list args;
-  va_start(args, argc);
-  init(argc, args);
-  va_end(args);
-}
-
-void NewExpression::init(int n, va_list args) {
-  for (int i = 0; i < n; i++) {
-    Expression* expression = (Expression*)va_arg(args, void*);
-    this->arguments.push_back(expression);
-  }
-}
+NewExpression::NewExpression(const std::string& n,
+                             const std::vector<std::shared_ptr<Expression>>& args)
+    : instantiableName(n), arguments(args) {}
 
 void NewExpression::Write(CodeWriter* to) const {
   to->Write("new %s(", this->instantiableName.c_str());
@@ -251,7 +227,8 @@
   to->Write(")");
 }
 
-NewArrayExpression::NewArrayExpression(const std::string& t, Expression* s) : type(t), size(s) {}
+NewArrayExpression::NewArrayExpression(const std::string& t, std::shared_ptr<Expression> s)
+    : type(t), size(s) {}
 
 void NewArrayExpression::Write(CodeWriter* to) const {
   to->Write("new %s[", this->type.c_str());
@@ -259,7 +236,7 @@
   to->Write("]");
 }
 
-Cast::Cast(const std::string& t, Expression* e) : type(t), expression(e) {}
+Cast::Cast(const std::string& t, std::shared_ptr<Expression> e) : type(t), expression(e) {}
 
 void Cast::Write(CodeWriter* to) const {
   to->Write("((%s)", this->type.c_str());
@@ -267,9 +244,10 @@
   to->Write(")");
 }
 
-VariableDeclaration::VariableDeclaration(Variable* l, Expression* r) : lvalue(l), rvalue(r) {}
+VariableDeclaration::VariableDeclaration(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r)
+    : lvalue(l), rvalue(r) {}
 
-VariableDeclaration::VariableDeclaration(Variable* l) : lvalue(l) {}
+VariableDeclaration::VariableDeclaration(std::shared_ptr<Variable> l) : lvalue(l) {}
 
 void VariableDeclaration::Write(CodeWriter* to) const {
   this->lvalue->WriteDeclaration(to);
@@ -293,7 +271,7 @@
   }
 }
 
-ReturnStatement::ReturnStatement(Expression* e) : expression(e) {}
+ReturnStatement::ReturnStatement(std::shared_ptr<Expression> e) : expression(e) {}
 
 void ReturnStatement::Write(CodeWriter* to) const {
   to->Write("return ");
@@ -330,7 +308,7 @@
   statements->Write(to);
 }
 
-SwitchStatement::SwitchStatement(Expression* e) : expression(e) {}
+SwitchStatement::SwitchStatement(std::shared_ptr<Expression> e) : expression(e) {}
 
 void SwitchStatement::Write(CodeWriter* to) const {
   to->Write("switch (");
@@ -477,11 +455,11 @@
   }
 }
 
-Expression* NULL_VALUE = new LiteralExpression("null");
-Expression* THIS_VALUE = new LiteralExpression("this");
-Expression* SUPER_VALUE = new LiteralExpression("super");
-Expression* TRUE_VALUE = new LiteralExpression("true");
-Expression* FALSE_VALUE = new LiteralExpression("false");
+std::shared_ptr<Expression> NULL_VALUE = std::make_shared<LiteralExpression>("null");
+std::shared_ptr<Expression> THIS_VALUE = std::make_shared<LiteralExpression>("this");
+std::shared_ptr<Expression> SUPER_VALUE = std::make_shared<LiteralExpression>("super");
+std::shared_ptr<Expression> TRUE_VALUE = std::make_shared<LiteralExpression>("true");
+std::shared_ptr<Expression> FALSE_VALUE = std::make_shared<LiteralExpression>("false");
 }  // namespace java
 }  // namespace aidl
 }  // namespace android
diff --git a/ast_java.h b/ast_java.h
index b3b0b54..d037d97 100644
--- a/ast_java.h
+++ b/ast_java.h
@@ -99,10 +99,10 @@
 };
 
 struct FieldVariable : public Expression {
-  std::variant<Expression*, std::string> receiver;
+  std::variant<std::shared_ptr<Expression>, std::string> receiver;
   std::string name;
 
-  FieldVariable(Expression* object, const std::string& name);
+  FieldVariable(std::shared_ptr<Expression> object, const std::string& name);
   FieldVariable(const std::string& clazz, const std::string& name);
   virtual ~FieldVariable() = default;
 
@@ -113,11 +113,11 @@
   std::string comment;
   std::vector<std::string> annotations;
   int modifiers = 0;
-  Variable* variable = nullptr;
+  std::shared_ptr<Variable> variable = nullptr;
   std::string value;
 
   Field() = default;
-  Field(int modifiers, Variable* variable);
+  Field(int modifiers, std::shared_ptr<Variable> variable);
   virtual ~Field() = default;
 
   void Write(CodeWriter* to) const override;
@@ -138,110 +138,108 @@
 };
 
 struct StatementBlock : public Statement {
-  std::vector<Statement*> statements;
+  std::vector<std::shared_ptr<Statement>> statements;
 
   StatementBlock() = default;
   virtual ~StatementBlock() = default;
   void Write(CodeWriter* to) const override;
 
-  void Add(Statement* statement);
-  void Add(Expression* expression);
+  void Add(std::shared_ptr<Statement> statement);
+  void Add(std::shared_ptr<Expression> expression);
 };
 
 struct ExpressionStatement : public Statement {
-  Expression* expression;
+  std::shared_ptr<Expression> expression;
 
-  explicit ExpressionStatement(Expression* expression);
+  explicit ExpressionStatement(std::shared_ptr<Expression> expression);
   virtual ~ExpressionStatement() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct Assignment : public Expression {
-  Variable* lvalue;
-  Expression* rvalue;
+  std::shared_ptr<Variable> lvalue;
+  std::shared_ptr<Expression> rvalue;
   std::optional<std::string> cast = std::nullopt;
 
-  Assignment(Variable* lvalue, Expression* rvalue);
-  Assignment(Variable* lvalue, Expression* rvalue, std::string cast);
+  Assignment(std::shared_ptr<Variable> lvalue, std::shared_ptr<Expression> rvalue);
+  Assignment(std::shared_ptr<Variable> lvalue, std::shared_ptr<Expression> rvalue,
+             std::string cast);
   virtual ~Assignment() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct MethodCall : public Expression {
-  std::variant<std::monostate, Expression*, std::string> receiver;
+  std::variant<std::monostate, std::shared_ptr<Expression>, std::string> receiver;
   std::string name;
-  std::vector<Expression*> arguments;
+  std::vector<std::shared_ptr<Expression>> arguments;
   std::vector<std::string> exceptions;
 
   explicit MethodCall(const std::string& name);
-  MethodCall(const std::string& name, int argc, ...);
-  MethodCall(Expression* obj, const std::string& name);
+  MethodCall(const std::string& name, const std::vector<std::shared_ptr<Expression>>& args);
+  MethodCall(std::shared_ptr<Expression> obj, const std::string& name);
   MethodCall(const std::string& clazz, const std::string& name);
-  MethodCall(Expression* obj, const std::string& name, int argc, ...);
-  MethodCall(const std::string&, const std::string& name, int argc, ...);
+  MethodCall(std::shared_ptr<Expression> obj, const std::string& name,
+             const std::vector<std::shared_ptr<Expression>>& args);
+  MethodCall(const std::string&, const std::string& name,
+             const std::vector<std::shared_ptr<Expression>>& args);
   virtual ~MethodCall() = default;
   void Write(CodeWriter* to) const override;
-
- private:
-  void init(int n, va_list args);
 };
 
 struct Comparison : public Expression {
-  Expression* lvalue;
+  std::shared_ptr<Expression> lvalue;
   std::string op;
-  Expression* rvalue;
+  std::shared_ptr<Expression> rvalue;
 
-  Comparison(Expression* lvalue, const std::string& op, Expression* rvalue);
+  Comparison(std::shared_ptr<Expression> lvalue, const std::string& op,
+             std::shared_ptr<Expression> rvalue);
   virtual ~Comparison() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct NewExpression : public Expression {
   const std::string instantiableName;
-  std::vector<Expression*> arguments;
+  std::vector<std::shared_ptr<Expression>> arguments;
 
   explicit NewExpression(const std::string& name);
-  NewExpression(const std::string& name, int argc, ...);
+  NewExpression(const std::string& name, const std::vector<std::shared_ptr<Expression>>& args);
   virtual ~NewExpression() = default;
   void Write(CodeWriter* to) const override;
-
- private:
-  void init(int n, va_list args);
 };
 
 struct NewArrayExpression : public Expression {
   const std::string type;
-  Expression* size;
+  std::shared_ptr<Expression> size;
 
-  NewArrayExpression(const std::string& type, Expression* size);
+  NewArrayExpression(const std::string& type, std::shared_ptr<Expression> size);
   virtual ~NewArrayExpression() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct Cast : public Expression {
   const std::string type;
-  Expression* expression = nullptr;
+  std::shared_ptr<Expression> expression = nullptr;
 
   Cast() = default;
-  Cast(const std::string& type, Expression* expression);
+  Cast(const std::string& type, std::shared_ptr<Expression> expression);
   virtual ~Cast() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct VariableDeclaration : public Statement {
-  Variable* lvalue = nullptr;
-  Expression* rvalue = nullptr;
+  std::shared_ptr<Variable> lvalue = nullptr;
+  std::shared_ptr<Expression> rvalue = nullptr;
 
-  explicit VariableDeclaration(Variable* lvalue);
-  VariableDeclaration(Variable* lvalue, Expression* rvalue);
+  explicit VariableDeclaration(std::shared_ptr<Variable> lvalue);
+  VariableDeclaration(std::shared_ptr<Variable> lvalue, std::shared_ptr<Expression> rvalue);
   virtual ~VariableDeclaration() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct IfStatement : public Statement {
-  Expression* expression = nullptr;
-  StatementBlock* statements = new StatementBlock;
-  IfStatement* elseif = nullptr;
+  std::shared_ptr<Expression> expression = nullptr;
+  std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
+  std::shared_ptr<IfStatement> elseif = nullptr;
 
   IfStatement() = default;
   virtual ~IfStatement() = default;
@@ -249,15 +247,15 @@
 };
 
 struct ReturnStatement : public Statement {
-  Expression* expression;
+  std::shared_ptr<Expression> expression;
 
-  explicit ReturnStatement(Expression* expression);
+  explicit ReturnStatement(std::shared_ptr<Expression> expression);
   virtual ~ReturnStatement() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct TryStatement : public Statement {
-  StatementBlock* statements = new StatementBlock;
+  std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
 
   TryStatement() = default;
   virtual ~TryStatement() = default;
@@ -265,7 +263,7 @@
 };
 
 struct FinallyStatement : public Statement {
-  StatementBlock* statements = new StatementBlock;
+  std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
 
   FinallyStatement() = default;
   virtual ~FinallyStatement() = default;
@@ -274,7 +272,7 @@
 
 struct Case : public AstNode {
   std::vector<std::string> cases;
-  StatementBlock* statements = new StatementBlock;
+  std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
 
   Case() = default;
   explicit Case(const std::string& c);
@@ -283,10 +281,10 @@
 };
 
 struct SwitchStatement : public Statement {
-  Expression* expression;
-  std::vector<Case*> cases;
+  std::shared_ptr<Expression> expression;
+  std::vector<std::shared_ptr<Case>> cases;
 
-  explicit SwitchStatement(Expression* expression);
+  explicit SwitchStatement(std::shared_ptr<Expression> expression);
   virtual ~SwitchStatement() = default;
   void Write(CodeWriter* to) const override;
 };
@@ -297,9 +295,9 @@
   int modifiers = 0;
   std::optional<std::string> returnType = std::nullopt;  // nullopt means constructor
   std::string name;
-  std::vector<Variable*> parameters;
+  std::vector<std::shared_ptr<Variable>> parameters;
   std::vector<std::string> exceptions;
-  StatementBlock* statements = nullptr;
+  std::shared_ptr<StatementBlock> statements = nullptr;
 
   Method() = default;
   virtual ~Method() = default;
@@ -326,7 +324,7 @@
   std::string type;
   std::optional<std::string> extends = std::nullopt;
   std::vector<std::string> interfaces;
-  std::vector<ClassElement*> elements;
+  std::vector<std::shared_ptr<ClassElement>> elements;
 
   Class() = default;
   virtual ~Class() = default;
@@ -348,11 +346,11 @@
   std::unique_ptr<Class> clazz_;
 };
 
-extern Expression* NULL_VALUE;
-extern Expression* THIS_VALUE;
-extern Expression* SUPER_VALUE;
-extern Expression* TRUE_VALUE;
-extern Expression* FALSE_VALUE;
+extern std::shared_ptr<Expression> NULL_VALUE;
+extern std::shared_ptr<Expression> THIS_VALUE;
+extern std::shared_ptr<Expression> SUPER_VALUE;
+extern std::shared_ptr<Expression> TRUE_VALUE;
+extern std::shared_ptr<Expression> FALSE_VALUE;
 }  // namespace java
 }  // namespace aidl
 }  // namespace android
diff --git a/generate_java.cpp b/generate_java.cpp
index 445b136..1f79691 100644
--- a/generate_java.cpp
+++ b/generate_java.cpp
@@ -40,10 +40,10 @@
 bool generate_java_interface(const string& filename, const AidlInterface* iface,
                              const AidlTypenames& typenames, const IoDelegate& io_delegate,
                              const Options& options) {
-  Class* cl = generate_binder_interface_class(iface, typenames, options);
+  auto cl = generate_binder_interface_class(iface, typenames, options);
 
-  Document* document =
-      new Document("" /* no comment */, iface->GetPackage(), unique_ptr<Class>(cl));
+  std::unique_ptr<Document> document =
+      std::make_unique<Document>("" /* no comment */, iface->GetPackage(), std::move(cl));
 
   CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
   document->Write(code_writer.get());
@@ -53,10 +53,10 @@
 
 bool generate_java_parcel(const std::string& filename, const AidlStructuredParcelable* parcel,
                           const AidlTypenames& typenames, const IoDelegate& io_delegate) {
-  Class* cl = generate_parcel_class(parcel, typenames);
+  auto cl = generate_parcel_class(parcel, typenames);
 
-  Document* document =
-      new Document("" /* no comment */, parcel->GetPackage(), unique_ptr<Class>(cl));
+  std::unique_ptr<Document> document =
+      std::make_unique<Document>("" /* no comment */, parcel->GetPackage(), std::move(cl));
 
   CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
   document->Write(code_writer.get());
@@ -95,9 +95,9 @@
   return false;
 }
 
-android::aidl::java::Class* generate_parcel_class(const AidlStructuredParcelable* parcel,
-                                                  const AidlTypenames& typenames) {
-  Class* parcel_class = new Class;
+std::unique_ptr<android::aidl::java::Class> generate_parcel_class(
+    const AidlStructuredParcelable* parcel, const AidlTypenames& typenames) {
+  auto parcel_class = std::make_unique<Class>();
   parcel_class->comment = parcel->GetComments();
   parcel_class->modifiers = PUBLIC;
   parcel_class->what = Class::CLASS;
@@ -118,7 +118,7 @@
       out << " = " << variable->ValueString(AidlConstantValueDecorator);
     }
     out << ";\n";
-    parcel_class->elements.push_back(new LiteralClassElement(out.str()));
+    parcel_class->elements.push_back(std::make_shared<LiteralClassElement>(out.str()));
   }
 
   std::ostringstream out;
@@ -136,23 +136,23 @@
   out << "    return new " << parcel->GetName() << "[_aidl_size];\n";
   out << "  }\n";
   out << "};\n";
-  parcel_class->elements.push_back(new LiteralClassElement(out.str()));
+  parcel_class->elements.push_back(std::make_shared<LiteralClassElement>(out.str()));
 
-  Variable* flag_variable = new Variable("int", "_aidl_flag");
-  Variable* parcel_variable = new Variable("android.os.Parcel", "_aidl_parcel");
+  auto flag_variable = std::make_shared<Variable>("int", "_aidl_flag");
+  auto parcel_variable = std::make_shared<Variable>("android.os.Parcel", "_aidl_parcel");
 
-  Method* write_method = new Method;
+  auto write_method = std::make_shared<Method>();
   write_method->modifiers = PUBLIC | OVERRIDE | FINAL;
   write_method->returnType = "void";
   write_method->name = "writeToParcel";
   write_method->parameters.push_back(parcel_variable);
   write_method->parameters.push_back(flag_variable);
-  write_method->statements = new StatementBlock();
+  write_method->statements = std::make_shared<StatementBlock>();
 
   out.str("");
   out << "int _aidl_start_pos = _aidl_parcel.dataPosition();\n"
       << "_aidl_parcel.writeInt(0);\n";
-  write_method->statements->Add(new LiteralStatement(out.str()));
+  write_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
 
   for (const auto& field : parcel->GetFields()) {
     string code;
@@ -167,7 +167,7 @@
     };
     WriteToParcelFor(context);
     writer->Close();
-    write_method->statements->Add(new LiteralStatement(code));
+    write_method->statements->Add(std::make_shared<LiteralStatement>(code));
   }
 
   out.str("");
@@ -176,16 +176,16 @@
       << "_aidl_parcel.writeInt(_aidl_end_pos - _aidl_start_pos);\n"
       << "_aidl_parcel.setDataPosition(_aidl_end_pos);\n";
 
-  write_method->statements->Add(new LiteralStatement(out.str()));
+  write_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
 
   parcel_class->elements.push_back(write_method);
 
-  Method* read_method = new Method;
+  auto read_method = std::make_shared<Method>();
   read_method->modifiers = PUBLIC | FINAL;
   read_method->returnType = "void";
   read_method->name = "readFromParcel";
   read_method->parameters.push_back(parcel_variable);
-  read_method->statements = new StatementBlock();
+  read_method->statements = std::make_shared<StatementBlock>();
 
   out.str("");
   out << "int _aidl_start_pos = _aidl_parcel.dataPosition();\n"
@@ -193,12 +193,12 @@
       << "if (_aidl_parcelable_size < 0) return;\n"
       << "try {\n";
 
-  read_method->statements->Add(new LiteralStatement(out.str()));
+  read_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
 
   out.str("");
   out << "  if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;\n";
 
-  LiteralStatement* sizeCheck = nullptr;
+  std::shared_ptr<LiteralStatement> sizeCheck = nullptr;
   // keep this across different fields in order to create the classloader
   // at most once.
   bool is_classloader_created = false;
@@ -216,8 +216,8 @@
     context.writer.Indent();
     CreateFromParcelFor(context);
     writer->Close();
-    read_method->statements->Add(new LiteralStatement(code));
-    if (!sizeCheck) sizeCheck = new LiteralStatement(out.str());
+    read_method->statements->Add(std::make_shared<LiteralStatement>(code));
+    if (!sizeCheck) sizeCheck = std::make_shared<LiteralStatement>(out.str());
     read_method->statements->Add(sizeCheck);
   }
 
@@ -226,16 +226,16 @@
       << "  _aidl_parcel.setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n"
       << "}\n";
 
-  read_method->statements->Add(new LiteralStatement(out.str()));
+  read_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
 
   parcel_class->elements.push_back(read_method);
 
-  Method* describe_contents_method = new Method;
+  auto describe_contents_method = std::make_shared<Method>();
   describe_contents_method->modifiers = PUBLIC | OVERRIDE;
   describe_contents_method->returnType = "int";
   describe_contents_method->name = "describeContents";
-  describe_contents_method->statements = new StatementBlock();
-  describe_contents_method->statements->Add(new LiteralStatement("return 0;\n"));
+  describe_contents_method->statements = std::make_shared<StatementBlock>();
+  describe_contents_method->statements->Add(std::make_shared<LiteralStatement>("return 0;\n"));
   parcel_class->elements.push_back(describe_contents_method);
 
   return parcel_class;
diff --git a/generate_java.h b/generate_java.h
index abeee1b..e4b131b 100644
--- a/generate_java.h
+++ b/generate_java.h
@@ -31,12 +31,11 @@
                    const AidlTypenames& typenames, const IoDelegate& io_delegate,
                    const Options& options);
 
-android::aidl::java::Class* generate_binder_interface_class(const AidlInterface* iface,
-                                                            const AidlTypenames& typenames,
-                                                            const Options& options);
+std::unique_ptr<android::aidl::java::Class> generate_binder_interface_class(
+    const AidlInterface* iface, const AidlTypenames& typenames, const Options& options);
 
-android::aidl::java::Class* generate_parcel_class(const AidlStructuredParcelable* parcel,
-                                                  const AidlTypenames& typenames);
+std::unique_ptr<android::aidl::java::Class> generate_parcel_class(
+    const AidlStructuredParcelable* parcel, const AidlTypenames& typenames);
 
 std::vector<std::string> generate_java_annotations(const AidlAnnotatable& a);
 
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index 96948ca..f1c0dc6 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -49,17 +49,18 @@
   using Variable = ::android::aidl::java::Variable;
 
   explicit VariableFactory(const std::string& base) : base_(base), index_(0) {}
-  Variable* Get(const AidlTypeSpecifier& type) {
-    Variable* v = new Variable(JavaSignatureOf(type), StringPrintf("%s%d", base_.c_str(), index_));
+  std::shared_ptr<Variable> Get(const AidlTypeSpecifier& type) {
+    auto v = std::make_shared<Variable>(JavaSignatureOf(type),
+                                        StringPrintf("%s%d", base_.c_str(), index_));
     vars_.push_back(v);
     index_++;
     return v;
   }
 
-  Variable* Get(int index) { return vars_[index]; }
+  std::shared_ptr<Variable> Get(int index) { return vars_[index]; }
 
  private:
-  std::vector<Variable*> vars_;
+  std::vector<std::shared_ptr<Variable>> vars_;
   std::string base_;
   int index_;
 
@@ -72,13 +73,13 @@
   StubClass(const AidlInterface* interfaceType, const Options& options);
   ~StubClass() override = default;
 
-  Variable* transact_code;
-  Variable* transact_data;
-  Variable* transact_reply;
-  Variable* transact_flags;
-  SwitchStatement* transact_switch;
-  StatementBlock* transact_statements;
-  SwitchStatement* code_to_method_name_switch;
+  std::shared_ptr<Variable> transact_code;
+  std::shared_ptr<Variable> transact_data;
+  std::shared_ptr<Variable> transact_reply;
+  std::shared_ptr<Variable> transact_flags;
+  std::shared_ptr<SwitchStatement> transact_switch;
+  std::shared_ptr<StatementBlock> transact_statements;
+  std::shared_ptr<SwitchStatement> code_to_method_name_switch;
 
   // Where onTransact cases should be generated as separate methods.
   bool transact_outline;
@@ -90,12 +91,12 @@
   // Finish generation. This will add a default case to the switch.
   void finish();
 
-  Expression* get_transact_descriptor(const AidlMethod* method);
+  std::shared_ptr<Expression> get_transact_descriptor(const AidlMethod* method);
 
  private:
   void make_as_interface(const AidlInterface* interfaceType);
 
-  Variable* transact_descriptor;
+  std::shared_ptr<Variable> transact_descriptor;
   const Options& options_;
 
   DISALLOW_COPY_AND_ASSIGN(StubClass);
@@ -115,22 +116,23 @@
   this->interfaces.push_back(interfaceType->GetCanonicalName());
 
   // descriptor
-  Field* descriptor =
-      new Field(STATIC | FINAL | PRIVATE, new Variable("java.lang.String", "DESCRIPTOR"));
+  auto descriptor = std::make_shared<Field>(
+      STATIC | FINAL | PRIVATE, std::make_shared<Variable>("java.lang.String", "DESCRIPTOR"));
   descriptor->value = "\"" + interfaceType->GetCanonicalName() + "\"";
   this->elements.push_back(descriptor);
 
   // ctor
-  Method* ctor = new Method;
+  auto ctor = std::make_shared<Method>();
   ctor->modifiers = PUBLIC;
   ctor->comment =
       "/** Construct the stub at attach it to the "
       "interface. */";
   ctor->name = "Stub";
-  ctor->statements = new StatementBlock;
-  MethodCall* attach =
-      new MethodCall(THIS_VALUE, "attachInterface", 2, THIS_VALUE,
-                     new LiteralExpression("DESCRIPTOR"));
+  ctor->statements = std::make_shared<StatementBlock>();
+  auto attach = std::make_shared<MethodCall>(
+      THIS_VALUE, "attachInterface",
+      std::vector<std::shared_ptr<Expression>>{THIS_VALUE,
+                                               std::make_shared<LiteralExpression>("DESCRIPTOR")});
   ctor->statements->Add(attach);
   this->elements.push_back(ctor);
 
@@ -138,48 +140,49 @@
   make_as_interface(interfaceType);
 
   // asBinder
-  Method* asBinder = new Method;
+  auto asBinder = std::make_shared<Method>();
   asBinder->modifiers = PUBLIC | OVERRIDE;
   asBinder->returnType = "android.os.IBinder";
   asBinder->name = "asBinder";
-  asBinder->statements = new StatementBlock;
-  asBinder->statements->Add(new ReturnStatement(THIS_VALUE));
+  asBinder->statements = std::make_shared<StatementBlock>();
+  asBinder->statements->Add(std::make_shared<ReturnStatement>(THIS_VALUE));
   this->elements.push_back(asBinder);
 
   if (options_.GenTransactionNames()) {
     // getDefaultTransactionName
-    Method* getDefaultTransactionName = new Method;
+    auto getDefaultTransactionName = std::make_shared<Method>();
     getDefaultTransactionName->comment = "/** @hide */";
     getDefaultTransactionName->modifiers = PUBLIC | STATIC;
     getDefaultTransactionName->returnType = "java.lang.String";
     getDefaultTransactionName->name = "getDefaultTransactionName";
-    Variable* code = new Variable("int", "transactionCode");
+    auto code = std::make_shared<Variable>("int", "transactionCode");
     getDefaultTransactionName->parameters.push_back(code);
-    getDefaultTransactionName->statements = new StatementBlock;
-    this->code_to_method_name_switch = new SwitchStatement(code);
+    getDefaultTransactionName->statements = std::make_shared<StatementBlock>();
+    this->code_to_method_name_switch = std::make_shared<SwitchStatement>(code);
     getDefaultTransactionName->statements->Add(this->code_to_method_name_switch);
     this->elements.push_back(getDefaultTransactionName);
 
     // getTransactionName
-    Method* getTransactionName = new Method;
+    auto getTransactionName = std::make_shared<Method>();
     getTransactionName->comment = "/** @hide */";
     getTransactionName->modifiers = PUBLIC;
     getTransactionName->returnType = "java.lang.String";
     getTransactionName->name = "getTransactionName";
-    Variable* code2 = new Variable("int", "transactionCode");
+    auto code2 = std::make_shared<Variable>("int", "transactionCode");
     getTransactionName->parameters.push_back(code2);
-    getTransactionName->statements = new StatementBlock;
-    getTransactionName->statements->Add(
-        new ReturnStatement(new MethodCall(THIS_VALUE, "getDefaultTransactionName", 1, code2)));
+    getTransactionName->statements = std::make_shared<StatementBlock>();
+    getTransactionName->statements->Add(std::make_shared<ReturnStatement>(
+        std::make_shared<MethodCall>(THIS_VALUE, "getDefaultTransactionName",
+                                     std::vector<std::shared_ptr<Expression>>{code2})));
     this->elements.push_back(getTransactionName);
   }
 
   // onTransact
-  this->transact_code = new Variable("int", "code");
-  this->transact_data = new Variable("android.os.Parcel", "data");
-  this->transact_reply = new Variable("android.os.Parcel", "reply");
-  this->transact_flags = new Variable("int", "flags");
-  Method* onTransact = new Method;
+  this->transact_code = std::make_shared<Variable>("int", "code");
+  this->transact_data = std::make_shared<Variable>("android.os.Parcel", "data");
+  this->transact_reply = std::make_shared<Variable>("android.os.Parcel", "reply");
+  this->transact_flags = std::make_shared<Variable>("int", "flags");
+  auto onTransact = std::make_shared<Method>();
   onTransact->modifiers = PUBLIC | OVERRIDE;
   onTransact->returnType = "boolean";
   onTransact->name = "onTransact";
@@ -187,20 +190,21 @@
   onTransact->parameters.push_back(this->transact_data);
   onTransact->parameters.push_back(this->transact_reply);
   onTransact->parameters.push_back(this->transact_flags);
-  onTransact->statements = new StatementBlock;
+  onTransact->statements = std::make_shared<StatementBlock>();
   transact_statements = onTransact->statements;
   onTransact->exceptions.push_back("android.os.RemoteException");
   this->elements.push_back(onTransact);
-  this->transact_switch = new SwitchStatement(this->transact_code);
+  this->transact_switch = std::make_shared<SwitchStatement>(this->transact_code);
 }
 
 void StubClass::finish() {
-  Case* default_case = new Case;
+  auto default_case = std::make_shared<Case>();
 
-  MethodCall* superCall = new MethodCall(
-        SUPER_VALUE, "onTransact", 4, this->transact_code, this->transact_data,
-        this->transact_reply, this->transact_flags);
-  default_case->statements->Add(new ReturnStatement(superCall));
+  auto superCall = std::make_shared<MethodCall>(
+      SUPER_VALUE, "onTransact",
+      std::vector<std::shared_ptr<Expression>>{this->transact_code, this->transact_data,
+                                               this->transact_reply, this->transact_flags});
+  default_case->statements->Add(std::make_shared<ReturnStatement>(superCall));
   transact_switch->cases.push_back(default_case);
 
   transact_statements->Add(this->transact_switch);
@@ -210,8 +214,8 @@
     // Some transaction codes are common, e.g. INTERFACE_TRANSACTION or DUMP_TRANSACTION.
     // Common transaction codes will not be resolved to a string by getTransactionName. The method
     // will return NULL in this case.
-    Case* code_switch_default_case = new Case;
-    code_switch_default_case->statements->Add(new ReturnStatement(NULL_VALUE));
+    auto code_switch_default_case = std::make_shared<Case>();
+    code_switch_default_case->statements->Add(std::make_shared<ReturnStatement>(NULL_VALUE));
     this->code_to_method_name_switch->cases.push_back(code_switch_default_case);
   }
 }
@@ -219,18 +223,18 @@
 // The the expression for the interface's descriptor to be used when
 // generating code for the given method. Null is acceptable for method
 // and stands for synthetic cases.
-Expression* StubClass::get_transact_descriptor(const AidlMethod* method) {
+std::shared_ptr<Expression> StubClass::get_transact_descriptor(const AidlMethod* method) {
   if (transact_outline) {
     if (method != nullptr) {
       // When outlining, each outlined method needs its own literal.
       if (outline_methods.count(method) != 0) {
-        return new LiteralExpression("DESCRIPTOR");
+        return std::make_shared<LiteralExpression>("DESCRIPTOR");
       }
     } else {
       // Synthetic case. A small number is assumed. Use its own descriptor
       // if there are only synthetic cases.
       if (outline_methods.size() == all_method_count) {
-        return new LiteralExpression("DESCRIPTOR");
+        return std::make_shared<LiteralExpression>("DESCRIPTOR");
       }
     }
   }
@@ -238,18 +242,17 @@
   // When not outlining, store the descriptor literal into a local variable, in
   // an effort to save const-string instructions in each switch case.
   if (transact_descriptor == nullptr) {
-    transact_descriptor = new Variable("java.lang.String", "descriptor");
-    transact_statements->Add(
-        new VariableDeclaration(transact_descriptor,
-                                new LiteralExpression("DESCRIPTOR")));
+    transact_descriptor = std::make_shared<Variable>("java.lang.String", "descriptor");
+    transact_statements->Add(std::make_shared<VariableDeclaration>(
+        transact_descriptor, std::make_shared<LiteralExpression>("DESCRIPTOR")));
   }
   return transact_descriptor;
 }
 
 void StubClass::make_as_interface(const AidlInterface* interfaceType) {
-  Variable* obj = new Variable("android.os.IBinder", "obj");
+  auto obj = std::make_shared<Variable>("android.os.IBinder", "obj");
 
-  Method* m = new Method;
+  auto m = std::make_shared<Method>();
   m->comment = "/**\n * Cast an IBinder object into an ";
   m->comment += interfaceType->GetCanonicalName();
   m->comment += " interface,\n";
@@ -258,19 +261,19 @@
   m->returnType = interfaceType->GetCanonicalName();
   m->name = "asInterface";
   m->parameters.push_back(obj);
-  m->statements = new StatementBlock;
+  m->statements = std::make_shared<StatementBlock>();
 
-  IfStatement* ifstatement = new IfStatement();
-  ifstatement->expression = new Comparison(obj, "==", NULL_VALUE);
-  ifstatement->statements = new StatementBlock;
-  ifstatement->statements->Add(new ReturnStatement(NULL_VALUE));
+  auto ifstatement = std::make_shared<IfStatement>();
+  ifstatement->expression = std::make_shared<Comparison>(obj, "==", NULL_VALUE);
+  ifstatement->statements = std::make_shared<StatementBlock>();
+  ifstatement->statements->Add(std::make_shared<ReturnStatement>(NULL_VALUE));
   m->statements->Add(ifstatement);
 
   // IInterface iin = obj.queryLocalInterface(DESCRIPTOR)
-  MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface");
-  queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
-  Variable* iin = new Variable("android.os.IInterface", "iin");
-  VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface);
+  auto queryLocalInterface = std::make_shared<MethodCall>(obj, "queryLocalInterface");
+  queryLocalInterface->arguments.push_back(std::make_shared<LiteralExpression>("DESCRIPTOR"));
+  auto iin = std::make_shared<Variable>("android.os.IInterface", "iin");
+  auto iinVd = std::make_shared<VariableDeclaration>(iin, queryLocalInterface);
   m->statements->Add(iinVd);
 
   // Ensure the instance type of the local object is as expected.
@@ -279,19 +282,19 @@
 
   // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>)
   // iin;
-  Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE);
-  Comparison* instOfCheck =
-      new Comparison(iin, " instanceof ", new LiteralExpression(interfaceType->GetCanonicalName()));
-  IfStatement* instOfStatement = new IfStatement();
-  instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck);
-  instOfStatement->statements = new StatementBlock;
-  instOfStatement->statements->Add(
-      new ReturnStatement(new Cast(interfaceType->GetCanonicalName(), iin)));
+  auto iinNotNull = std::make_shared<Comparison>(iin, "!=", NULL_VALUE);
+  auto instOfCheck = std::make_shared<Comparison>(
+      iin, " instanceof ", std::make_shared<LiteralExpression>(interfaceType->GetCanonicalName()));
+  auto instOfStatement = std::make_shared<IfStatement>();
+  instOfStatement->expression = std::make_shared<Comparison>(iinNotNull, "&&", instOfCheck);
+  instOfStatement->statements = std::make_shared<StatementBlock>();
+  instOfStatement->statements->Add(std::make_shared<ReturnStatement>(
+      std::make_shared<Cast>(interfaceType->GetCanonicalName(), iin)));
   m->statements->Add(instOfStatement);
 
-  NewExpression* ne = new NewExpression(interfaceType->GetCanonicalName() + ".Stub.Proxy");
+  auto ne = std::make_shared<NewExpression>(interfaceType->GetCanonicalName() + ".Stub.Proxy");
   ne->arguments.push_back(obj);
-  m->statements->Add(new ReturnStatement(ne));
+  m->statements->Add(std::make_shared<ReturnStatement>(ne));
 
   this->elements.push_back(m);
 }
@@ -302,7 +305,7 @@
   ProxyClass(const AidlInterface* interfaceType, const Options& options);
   ~ProxyClass() override;
 
-  Variable* mRemote;
+  std::shared_ptr<Variable> mRemote;
 };
 
 ProxyClass::ProxyClass(const AidlInterface* interfaceType, const Options& options) : Class() {
@@ -312,53 +315,56 @@
   this->interfaces.push_back(interfaceType->GetCanonicalName());
 
   // IBinder mRemote
-  mRemote = new Variable("android.os.IBinder", "mRemote");
-  this->elements.push_back(new Field(PRIVATE, mRemote));
+  mRemote = std::make_shared<Variable>("android.os.IBinder", "mRemote");
+  this->elements.push_back(std::make_shared<Field>(PRIVATE, mRemote));
 
   // Proxy()
-  Variable* remote = new Variable("android.os.IBinder", "remote");
-  Method* ctor = new Method;
+  auto remote = std::make_shared<Variable>("android.os.IBinder", "remote");
+  auto ctor = std::make_shared<Method>();
   ctor->name = "Proxy";
-  ctor->statements = new StatementBlock;
+  ctor->statements = std::make_shared<StatementBlock>();
   ctor->parameters.push_back(remote);
-  ctor->statements->Add(new Assignment(mRemote, remote));
+  ctor->statements->Add(std::make_shared<Assignment>(mRemote, remote));
   this->elements.push_back(ctor);
 
   if (options.Version() > 0) {
     std::ostringstream code;
     code << "private int mCachedVersion = -1;\n";
-    this->elements.emplace_back(new LiteralClassElement(code.str()));
+    this->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
   }
 
   // IBinder asBinder()
-  Method* asBinder = new Method;
+  auto asBinder = std::make_shared<Method>();
   asBinder->modifiers = PUBLIC | OVERRIDE;
   asBinder->returnType = "android.os.IBinder";
   asBinder->name = "asBinder";
-  asBinder->statements = new StatementBlock;
-  asBinder->statements->Add(new ReturnStatement(mRemote));
+  asBinder->statements = std::make_shared<StatementBlock>();
+  asBinder->statements->Add(std::make_shared<ReturnStatement>(mRemote));
   this->elements.push_back(asBinder);
 }
 
 ProxyClass::~ProxyClass() {}
 
 // =================================================
-static void generate_new_array(const AidlTypeSpecifier& type, StatementBlock* addTo, Variable* v,
-                               Variable* parcel) {
-  Variable* len = new Variable("int", v->name + "_length");
-  addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt")));
-  IfStatement* lencheck = new IfStatement();
-  lencheck->expression = new Comparison(len, "<", new LiteralExpression("0"));
-  lencheck->statements->Add(new Assignment(v, NULL_VALUE));
-  lencheck->elseif = new IfStatement();
-  lencheck->elseif->statements->Add(
-      new Assignment(v, new NewArrayExpression(InstantiableJavaSignatureOf(type), len)));
+static void generate_new_array(const AidlTypeSpecifier& type, std::shared_ptr<StatementBlock> addTo,
+                               std::shared_ptr<Variable> v, std::shared_ptr<Variable> parcel) {
+  auto len = std::make_shared<Variable>("int", v->name + "_length");
+  addTo->Add(
+      std::make_shared<VariableDeclaration>(len, std::make_shared<MethodCall>(parcel, "readInt")));
+  auto lencheck = std::make_shared<IfStatement>();
+  lencheck->expression =
+      std::make_shared<Comparison>(len, "<", std::make_shared<LiteralExpression>("0"));
+  lencheck->statements->Add(std::make_shared<Assignment>(v, NULL_VALUE));
+  lencheck->elseif = std::make_shared<IfStatement>();
+  lencheck->elseif->statements->Add(std::make_shared<Assignment>(
+      v, std::make_shared<NewArrayExpression>(InstantiableJavaSignatureOf(type), len)));
   addTo->Add(lencheck);
 }
 
-static void generate_write_to_parcel(const AidlTypeSpecifier& type, StatementBlock* addTo,
-                                     Variable* v, Variable* parcel, bool is_return_value,
-                                     const AidlTypenames& typenames) {
+static void generate_write_to_parcel(const AidlTypeSpecifier& type,
+                                     std::shared_ptr<StatementBlock> addTo,
+                                     std::shared_ptr<Variable> v, std::shared_ptr<Variable> parcel,
+                                     bool is_return_value, const AidlTypenames& typenames) {
   string code;
   CodeWriterPtr writer = CodeWriter::ForString(&code);
   CodeGeneratorContext context{
@@ -371,23 +377,23 @@
   };
   WriteToParcelFor(context);
   writer->Close();
-  addTo->Add(new LiteralStatement(code));
+  addTo->Add(std::make_shared<LiteralStatement>(code));
 }
 
 static void generate_int_constant(Class* interface, const std::string& name,
                                   const std::string& value) {
   auto code = StringPrintf("public static final int %s = %s;\n", name.c_str(), value.c_str());
-  interface->elements.push_back(new LiteralClassElement(code));
+  interface->elements.push_back(std::make_shared<LiteralClassElement>(code));
 }
 
 static void generate_string_constant(Class* interface, const std::string& name,
                                      const std::string& value) {
   auto code = StringPrintf("public static final String %s = %s;\n", name.c_str(), value.c_str());
-  interface->elements.push_back(new LiteralClassElement(code));
+  interface->elements.push_back(std::make_shared<LiteralClassElement>(code));
 }
 
-static std::unique_ptr<Method> generate_interface_method(const AidlMethod& method) {
-  std::unique_ptr<Method> decl(new Method);
+static std::shared_ptr<Method> generate_interface_method(const AidlMethod& method) {
+  auto decl = std::make_shared<Method>();
   decl->comment = method.GetComments();
   decl->modifiers = PUBLIC;
   decl->returnType = JavaSignatureOf(method.GetType());
@@ -395,7 +401,8 @@
   decl->annotations = generate_java_annotations(method.GetType());
 
   for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
-    decl->parameters.push_back(new Variable(JavaSignatureOf(arg->GetType()), arg->GetName()));
+    decl->parameters.push_back(
+        std::make_shared<Variable>(JavaSignatureOf(arg->GetType()), arg->GetName()));
   }
 
   decl->exceptions.push_back("android.os.RemoteException");
@@ -404,16 +411,19 @@
 }
 
 static void generate_stub_code(const AidlInterface& iface, const AidlMethod& method, bool oneway,
-                               Variable* transact_data, Variable* transact_reply,
-                               const AidlTypenames& typenames, StatementBlock* statements,
-                               StubClass* stubClass, const Options& options) {
-  TryStatement* tryStatement = nullptr;
-  FinallyStatement* finallyStatement = nullptr;
-  MethodCall* realCall = new MethodCall(THIS_VALUE, method.GetName());
+                               std::shared_ptr<Variable> transact_data,
+                               std::shared_ptr<Variable> transact_reply,
+                               const AidlTypenames& typenames,
+                               std::shared_ptr<StatementBlock> statements,
+                               std::shared_ptr<StubClass> stubClass, const Options& options) {
+  std::shared_ptr<TryStatement> tryStatement;
+  std::shared_ptr<FinallyStatement> finallyStatement;
+  auto realCall = std::make_shared<MethodCall>(THIS_VALUE, method.GetName());
 
   // interface token validation is the very first thing we do
-  statements->Add(new MethodCall(transact_data, "enforceInterface", 1,
-                                 stubClass->get_transact_descriptor(&method)));
+  statements->Add(std::make_shared<MethodCall>(
+      transact_data, "enforceInterface",
+      std::vector<std::shared_ptr<Expression>>{stubClass->get_transact_descriptor(&method)}));
 
   // args
   VariableFactory stubArgs("_arg");
@@ -422,9 +432,9 @@
     // at most once.
     bool is_classloader_created = false;
     for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
-      Variable* v = stubArgs.Get(arg->GetType());
+      std::shared_ptr<Variable> v = stubArgs.Get(arg->GetType());
 
-      statements->Add(new VariableDeclaration(v));
+      statements->Add(std::make_shared<VariableDeclaration>(v));
 
       if (arg->GetDirection() & AidlArgument::IN_DIR) {
         string code;
@@ -437,11 +447,11 @@
                                      .is_classloader_created = &is_classloader_created};
         CreateFromParcelFor(context);
         writer->Close();
-        statements->Add(new LiteralStatement(code));
+        statements->Add(std::make_shared<LiteralStatement>(code));
       } else {
         if (!arg->GetType().IsArray()) {
-          statements->Add(
-              new Assignment(v, new NewExpression(InstantiableJavaSignatureOf(arg->GetType()))));
+          statements->Add(std::make_shared<Assignment>(
+              v, std::make_shared<NewExpression>(InstantiableJavaSignatureOf(arg->GetType()))));
         } else {
           generate_new_array(arg->GetType(), statements, v, transact_data);
         }
@@ -453,18 +463,20 @@
 
   if (options.GenTraces()) {
     // try and finally, but only when generating trace code
-    tryStatement = new TryStatement();
-    finallyStatement = new FinallyStatement();
+    tryStatement = std::make_shared<TryStatement>();
+    finallyStatement = std::make_shared<FinallyStatement>();
 
-    tryStatement->statements->Add(new MethodCall(
-        new LiteralExpression("android.os.Trace"), "traceBegin", 2,
-        new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL"),
-        new StringLiteralExpression(iface.GetName() + "::"
-            + method.GetName() + "::server")));
+    tryStatement->statements->Add(std::make_shared<MethodCall>(
+        std::make_shared<LiteralExpression>("android.os.Trace"), "traceBegin",
+        std::vector<std::shared_ptr<Expression>>{
+            std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL"),
+            std::make_shared<StringLiteralExpression>(iface.GetName() + "::" + method.GetName() +
+                                                      "::server")}));
 
-    finallyStatement->statements->Add(new MethodCall(
-        new LiteralExpression("android.os.Trace"), "traceEnd", 1,
-        new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL")));
+    finallyStatement->statements->Add(std::make_shared<MethodCall>(
+        std::make_shared<LiteralExpression>("android.os.Trace"), "traceEnd",
+        std::vector<std::shared_ptr<Expression>>{
+            std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL")}));
   }
 
   // the real call
@@ -479,25 +491,23 @@
 
     if (!oneway) {
       // report that there were no exceptions
-      MethodCall* ex =
-          new MethodCall(transact_reply, "writeNoException", 0);
+      auto ex = std::make_shared<MethodCall>(transact_reply, "writeNoException");
       statements->Add(ex);
     }
   } else {
-    Variable* _result = new Variable(JavaSignatureOf(method.GetType()), "_result");
+    auto _result = std::make_shared<Variable>(JavaSignatureOf(method.GetType()), "_result");
     if (options.GenTraces()) {
-      statements->Add(new VariableDeclaration(_result));
+      statements->Add(std::make_shared<VariableDeclaration>(_result));
       statements->Add(tryStatement);
-      tryStatement->statements->Add(new Assignment(_result, realCall));
+      tryStatement->statements->Add(std::make_shared<Assignment>(_result, realCall));
       statements->Add(finallyStatement);
     } else {
-      statements->Add(new VariableDeclaration(_result, realCall));
+      statements->Add(std::make_shared<VariableDeclaration>(_result, realCall));
     }
 
     if (!oneway) {
       // report that there were no exceptions
-      MethodCall* ex =
-          new MethodCall(transact_reply, "writeNoException", 0);
+      auto ex = std::make_shared<MethodCall>(transact_reply, "writeNoException");
       statements->Add(ex);
     }
 
@@ -509,7 +519,7 @@
   // out parameters
   int i = 0;
   for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
-    Variable* v = stubArgs.Get(i++);
+    std::shared_ptr<Variable> v = stubArgs.Get(i++);
 
     if (arg->GetDirection() & AidlArgument::OUT_DIR) {
       generate_write_to_parcel(arg->GetType(), statements, v, transact_reply, true, typenames);
@@ -517,14 +527,14 @@
   }
 
   // return true
-  statements->Add(new ReturnStatement(TRUE_VALUE));
+  statements->Add(std::make_shared<ReturnStatement>(TRUE_VALUE));
 }
 
 static void generate_stub_case(const AidlInterface& iface, const AidlMethod& method,
                                const std::string& transactCodeName, bool oneway,
-                               StubClass* stubClass, const AidlTypenames& typenames,
+                               std::shared_ptr<StubClass> stubClass, const AidlTypenames& typenames,
                                const Options& options) {
-  Case* c = new Case(transactCodeName);
+  auto c = std::make_shared<Case>(transactCodeName);
 
   generate_stub_code(iface, method, oneway, stubClass->transact_data, stubClass->transact_reply,
                      typenames, c->statements, stubClass, options);
@@ -534,20 +544,20 @@
 
 static void generate_stub_case_outline(const AidlInterface& iface, const AidlMethod& method,
                                        const std::string& transactCodeName, bool oneway,
-                                       StubClass* stubClass, const AidlTypenames& typenames,
-                                       const Options& options) {
+                                       std::shared_ptr<StubClass> stubClass,
+                                       const AidlTypenames& typenames, const Options& options) {
   std::string outline_name = "onTransact$" + method.GetName() + "$";
   // Generate an "outlined" method with the actual code.
   {
-    Variable* transact_data = new Variable("android.os.Parcel", "data");
-    Variable* transact_reply = new Variable("android.os.Parcel", "reply");
-    Method* onTransact_case = new Method;
+    auto transact_data = std::make_shared<Variable>("android.os.Parcel", "data");
+    auto transact_reply = std::make_shared<Variable>("android.os.Parcel", "reply");
+    auto onTransact_case = std::make_shared<Method>();
     onTransact_case->modifiers = PRIVATE;
     onTransact_case->returnType = "boolean";
     onTransact_case->name = outline_name;
     onTransact_case->parameters.push_back(transact_data);
     onTransact_case->parameters.push_back(transact_reply);
-    onTransact_case->statements = new StatementBlock;
+    onTransact_case->statements = std::make_shared<StatementBlock>();
     onTransact_case->exceptions.push_back("android.os.RemoteException");
     stubClass->elements.push_back(onTransact_case);
 
@@ -557,98 +567,103 @@
 
   // Generate the case dispatch.
   {
-    Case* c = new Case(transactCodeName);
+    auto c = std::make_shared<Case>(transactCodeName);
 
-    MethodCall* helper_call = new MethodCall(THIS_VALUE,
-                                             outline_name,
-                                             2,
-                                             stubClass->transact_data,
-                                             stubClass->transact_reply);
-    c->statements->Add(new ReturnStatement(helper_call));
+    auto helper_call =
+        std::make_shared<MethodCall>(THIS_VALUE, outline_name,
+                                     std::vector<std::shared_ptr<Expression>>{
+                                         stubClass->transact_data, stubClass->transact_reply});
+    c->statements->Add(std::make_shared<ReturnStatement>(helper_call));
 
     stubClass->transact_switch->cases.push_back(c);
   }
 }
 
-static std::unique_ptr<Method> generate_proxy_method(
+static std::shared_ptr<Method> generate_proxy_method(
     const AidlInterface& iface, const AidlMethod& method, const std::string& transactCodeName,
-    bool oneway, ProxyClass* proxyClass, const AidlTypenames& typenames, const Options& options) {
-  std::unique_ptr<Method> proxy(new Method);
+    bool oneway, std::shared_ptr<ProxyClass> proxyClass, const AidlTypenames& typenames,
+    const Options& options) {
+  auto proxy = std::make_shared<Method>();
   proxy->comment = method.GetComments();
   proxy->modifiers = PUBLIC | OVERRIDE;
   proxy->returnType = JavaSignatureOf(method.GetType());
   proxy->name = method.GetName();
-  proxy->statements = new StatementBlock;
+  proxy->statements = std::make_shared<StatementBlock>();
   for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
-    proxy->parameters.push_back(new Variable(JavaSignatureOf(arg->GetType()), arg->GetName()));
+    proxy->parameters.push_back(
+        std::make_shared<Variable>(JavaSignatureOf(arg->GetType()), arg->GetName()));
   }
   proxy->exceptions.push_back("android.os.RemoteException");
 
   // the parcels
-  Variable* _data = new Variable("android.os.Parcel", "_data");
-  proxy->statements->Add(
-      new VariableDeclaration(_data, new MethodCall("android.os.Parcel", "obtain")));
-  Variable* _reply = nullptr;
+  auto _data = std::make_shared<Variable>("android.os.Parcel", "_data");
+  proxy->statements->Add(std::make_shared<VariableDeclaration>(
+      _data, std::make_shared<MethodCall>("android.os.Parcel", "obtain")));
+  std::shared_ptr<Variable> _reply = nullptr;
   if (!oneway) {
-    _reply = new Variable("android.os.Parcel", "_reply");
-    proxy->statements->Add(
-        new VariableDeclaration(_reply, new MethodCall("android.os.Parcel", "obtain")));
+    _reply = std::make_shared<Variable>("android.os.Parcel", "_reply");
+    proxy->statements->Add(std::make_shared<VariableDeclaration>(
+        _reply, std::make_shared<MethodCall>("android.os.Parcel", "obtain")));
   }
 
   // the return value
-  Variable* _result = nullptr;
+  std::shared_ptr<Variable> _result = nullptr;
   if (method.GetType().GetName() != "void") {
-    _result = new Variable(*proxy->returnType, "_result");
-    proxy->statements->Add(new VariableDeclaration(_result));
+    _result = std::make_shared<Variable>(*proxy->returnType, "_result");
+    proxy->statements->Add(std::make_shared<VariableDeclaration>(_result));
   }
 
   // try and finally
-  TryStatement* tryStatement = new TryStatement();
+  auto tryStatement = std::make_shared<TryStatement>();
   proxy->statements->Add(tryStatement);
-  FinallyStatement* finallyStatement = new FinallyStatement();
+  auto finallyStatement = std::make_shared<FinallyStatement>();
   proxy->statements->Add(finallyStatement);
 
   if (options.GenTraces()) {
-    tryStatement->statements->Add(new MethodCall(
-          new LiteralExpression("android.os.Trace"), "traceBegin", 2,
-          new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL"),
-          new StringLiteralExpression(iface.GetName() + "::" +
-                                      method.GetName() + "::client")));
+    tryStatement->statements->Add(std::make_shared<MethodCall>(
+        std::make_shared<LiteralExpression>("android.os.Trace"), "traceBegin",
+        std::vector<std::shared_ptr<Expression>>{
+            std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL"),
+            std::make_shared<StringLiteralExpression>(iface.GetName() + "::" + method.GetName() +
+                                                      "::client")}));
   }
 
   // the interface identifier token: the DESCRIPTOR constant, marshalled as a
   // string
-  tryStatement->statements->Add(new MethodCall(
-      _data, "writeInterfaceToken", 1, new LiteralExpression("DESCRIPTOR")));
+  tryStatement->statements->Add(std::make_shared<MethodCall>(
+      _data, "writeInterfaceToken",
+      std::vector<std::shared_ptr<Expression>>{std::make_shared<LiteralExpression>("DESCRIPTOR")}));
 
   // the parameters
   for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
-    Variable* v = new Variable(JavaSignatureOf(arg->GetType()), arg->GetName());
+    auto v = std::make_shared<Variable>(JavaSignatureOf(arg->GetType()), arg->GetName());
     AidlArgument::Direction dir = arg->GetDirection();
     if (dir == AidlArgument::OUT_DIR && arg->GetType().IsArray()) {
-      IfStatement* checklen = new IfStatement();
-      checklen->expression = new Comparison(v, "==", NULL_VALUE);
-      checklen->statements->Add(
-          new MethodCall(_data, "writeInt", 1, new LiteralExpression("-1")));
-      checklen->elseif = new IfStatement();
-      checklen->elseif->statements->Add(
-          new MethodCall(_data, "writeInt", 1, new FieldVariable(v, "length")));
+      auto checklen = std::make_shared<IfStatement>();
+      checklen->expression = std::make_shared<Comparison>(v, "==", NULL_VALUE);
+      checklen->statements->Add(std::make_shared<MethodCall>(
+          _data, "writeInt",
+          std::vector<std::shared_ptr<Expression>>{std::make_shared<LiteralExpression>("-1")}));
+      checklen->elseif = std::make_shared<IfStatement>();
+      checklen->elseif->statements->Add(std::make_shared<MethodCall>(
+          _data, "writeInt",
+          std::vector<std::shared_ptr<Expression>>{std::make_shared<FieldVariable>(v, "length")}));
       tryStatement->statements->Add(checklen);
     } else if (dir & AidlArgument::IN_DIR) {
       generate_write_to_parcel(arg->GetType(), tryStatement->statements, v, _data, false,
                                typenames);
-    } else {
-      delete v;
     }
   }
 
   // the transact call
-  unique_ptr<MethodCall> call(new MethodCall(
-      proxyClass->mRemote, "transact", 4, new LiteralExpression("Stub." + transactCodeName), _data,
-      _reply ? _reply : NULL_VALUE,
-      new LiteralExpression(oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0")));
-  unique_ptr<Variable> _status(new Variable("boolean", "_status"));
-  tryStatement->statements->Add(new VariableDeclaration(_status.release(), call.release()));
+  auto call = std::make_shared<MethodCall>(
+      proxyClass->mRemote, "transact",
+      std::vector<std::shared_ptr<Expression>>{
+          std::make_shared<LiteralExpression>("Stub." + transactCodeName), _data,
+          _reply ? _reply : NULL_VALUE,
+          std::make_shared<LiteralExpression>(oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0")});
+  auto _status = std::make_shared<Variable>("boolean", "_status");
+  tryStatement->statements->Add(std::make_shared<VariableDeclaration>(_status, call));
 
   // If the transaction returns false, which means UNKNOWN_TRANSACTION, fall
   // back to the local method in the default impl, if set before.
@@ -657,7 +672,7 @@
     arg_names.emplace_back(arg->GetName());
   }
   bool has_return_type = method.GetType().GetName() != "void";
-  tryStatement->statements->Add(new LiteralStatement(
+  tryStatement->statements->Add(std::make_shared<LiteralStatement>(
       android::base::StringPrintf(has_return_type ? "if (!_status && getDefaultImpl() != null) {\n"
                                                     "  return getDefaultImpl().%s(%s);\n"
                                                     "}\n"
@@ -669,7 +684,7 @@
 
   // throw back exceptions.
   if (_reply) {
-    MethodCall* ex = new MethodCall(_reply, "readException", 0);
+    auto ex = std::make_shared<MethodCall>(_reply, "readException");
     tryStatement->statements->Add(ex);
   }
 
@@ -689,7 +704,7 @@
                                    .is_classloader_created = &is_classloader_created};
       CreateFromParcelFor(context);
       writer->Close();
-      tryStatement->statements->Add(new LiteralStatement(code));
+      tryStatement->statements->Add(std::make_shared<LiteralStatement>(code));
     }
 
     // the out/inout parameters
@@ -705,29 +720,31 @@
                                      .is_classloader_created = &is_classloader_created};
         ReadFromParcelFor(context);
         writer->Close();
-        tryStatement->statements->Add(new LiteralStatement(code));
+        tryStatement->statements->Add(std::make_shared<LiteralStatement>(code));
       }
     }
 
-    finallyStatement->statements->Add(new MethodCall(_reply, "recycle"));
+    finallyStatement->statements->Add(std::make_shared<MethodCall>(_reply, "recycle"));
   }
-  finallyStatement->statements->Add(new MethodCall(_data, "recycle"));
+  finallyStatement->statements->Add(std::make_shared<MethodCall>(_data, "recycle"));
 
   if (options.GenTraces()) {
-    finallyStatement->statements->Add(new MethodCall(
-        new LiteralExpression("android.os.Trace"), "traceEnd", 1,
-        new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL")));
+    finallyStatement->statements->Add(std::make_shared<MethodCall>(
+        std::make_shared<LiteralExpression>("android.os.Trace"), "traceEnd",
+        std::vector<std::shared_ptr<Expression>>{
+            std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL")}));
   }
 
   if (_result != nullptr) {
-    proxy->statements->Add(new ReturnStatement(_result));
+    proxy->statements->Add(std::make_shared<ReturnStatement>(_result));
   }
 
   return proxy;
 }
 
 static void generate_methods(const AidlInterface& iface, const AidlMethod& method, Class* interface,
-                             StubClass* stubClass, ProxyClass* proxyClass, int index,
+                             std::shared_ptr<StubClass> stubClass,
+                             std::shared_ptr<ProxyClass> proxyClass, int index,
                              const AidlTypenames& typenames, const Options& options) {
   const bool oneway = method.IsOneway();
 
@@ -735,28 +752,30 @@
   string transactCodeName = "TRANSACTION_";
   transactCodeName += method.GetName();
 
-  Field* transactCode = new Field(STATIC | FINAL, new Variable("int", transactCodeName));
+  auto transactCode =
+      std::make_shared<Field>(STATIC | FINAL, std::make_shared<Variable>("int", transactCodeName));
   transactCode->value =
       StringPrintf("(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
   stubClass->elements.push_back(transactCode);
 
   // getTransactionName
   if (options.GenTransactionNames()) {
-    Case* c = new Case(transactCodeName);
-    c->statements->Add(new ReturnStatement(new StringLiteralExpression(method.GetName())));
+    auto c = std::make_shared<Case>(transactCodeName);
+    c->statements->Add(std::make_shared<ReturnStatement>(
+        std::make_shared<StringLiteralExpression>(method.GetName())));
     stubClass->code_to_method_name_switch->cases.push_back(c);
   }
 
   // == the declaration in the interface ===================================
-  ClassElement* decl;
+  std::shared_ptr<ClassElement> decl;
   if (method.IsUserDefined()) {
-    decl = generate_interface_method(method).release();
+    decl = generate_interface_method(method);
   } else {
     if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
       std::ostringstream code;
       code << "public int " << kGetInterfaceVersion << "() "
            << "throws android.os.RemoteException;\n";
-      decl = new LiteralClassElement(code.str());
+      decl = std::make_shared<LiteralClassElement>(code.str());
     }
   }
   interface->elements.push_back(decl);
@@ -773,23 +792,22 @@
     }
   } else {
     if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
-      Case* c = new Case(transactCodeName);
+      auto c = std::make_shared<Case>(transactCodeName);
       std::ostringstream code;
       code << "data.enforceInterface(descriptor);\n"
            << "reply.writeNoException();\n"
            << "reply.writeInt(" << kGetInterfaceVersion << "());\n"
            << "return true;\n";
-      c->statements->Add(new LiteralStatement(code.str()));
+      c->statements->Add(std::make_shared<LiteralStatement>(code.str()));
       stubClass->transact_switch->cases.push_back(c);
     }
   }
 
   // == the proxy method ===================================================
-  ClassElement* proxy = nullptr;
+  std::shared_ptr<ClassElement> proxy = nullptr;
   if (method.IsUserDefined()) {
     proxy = generate_proxy_method(iface, method, transactCodeName, oneway, proxyClass, typenames,
-                                  options)
-                .release();
+                                  options);
 
   } else {
     if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
@@ -819,7 +837,7 @@
            << "  }\n"
            << "  return mCachedVersion;\n"
            << "}\n";
-      proxy = new LiteralClassElement(code.str());
+      proxy = std::make_shared<LiteralClassElement>(code.str());
     }
   }
   if (proxy != nullptr) {
@@ -827,22 +845,24 @@
   }
 }
 
-static void generate_interface_descriptors(StubClass* stub, ProxyClass* proxy) {
+static void generate_interface_descriptors(std::shared_ptr<StubClass> stub,
+                                           std::shared_ptr<ProxyClass> proxy) {
   // the interface descriptor transaction handler
-  Case* c = new Case("INTERFACE_TRANSACTION");
-  c->statements->Add(new MethodCall(stub->transact_reply, "writeString", 1,
-                                    stub->get_transact_descriptor(nullptr)));
-  c->statements->Add(new ReturnStatement(TRUE_VALUE));
+  auto c = std::make_shared<Case>("INTERFACE_TRANSACTION");
+  c->statements->Add(std::make_shared<MethodCall>(
+      stub->transact_reply, "writeString",
+      std::vector<std::shared_ptr<Expression>>{stub->get_transact_descriptor(nullptr)}));
+  c->statements->Add(std::make_shared<ReturnStatement>(TRUE_VALUE));
   stub->transact_switch->cases.push_back(c);
 
   // and the proxy-side method returning the descriptor directly
-  Method* getDesc = new Method;
+  auto getDesc = std::make_shared<Method>();
   getDesc->modifiers = PUBLIC;
   getDesc->returnType = "java.lang.String";
   getDesc->name = "getInterfaceDescriptor";
-  getDesc->statements = new StatementBlock;
+  getDesc->statements = std::make_shared<StatementBlock>();
   getDesc->statements->Add(
-      new ReturnStatement(new LiteralExpression("DESCRIPTOR")));
+      std::make_shared<ReturnStatement>(std::make_shared<LiteralExpression>("DESCRIPTOR")));
   proxy->elements.push_back(getDesc);
 }
 
@@ -857,8 +877,7 @@
 //
 // Requirements: non_outline_count <= outline_threshold.
 static void compute_outline_methods(const AidlInterface* iface,
-                                    StubClass* stub,
-                                    size_t outline_threshold,
+                                    const std::shared_ptr<StubClass> stub, size_t outline_threshold,
                                     size_t non_outline_count) {
   CHECK_LE(non_outline_count, outline_threshold);
   // We'll outline (create sub methods) if there are more than min_methods
@@ -884,30 +903,30 @@
   }
 }
 
-static unique_ptr<ClassElement> generate_default_impl_method(const AidlMethod& method) {
-  unique_ptr<Method> default_method(new Method);
+static shared_ptr<ClassElement> generate_default_impl_method(const AidlMethod& method) {
+  auto default_method = std::make_shared<Method>();
   default_method->comment = method.GetComments();
   default_method->modifiers = PUBLIC | OVERRIDE;
   default_method->returnType = JavaSignatureOf(method.GetType());
   default_method->name = method.GetName();
-  default_method->statements = new StatementBlock;
+  default_method->statements = std::make_shared<StatementBlock>();
   for (const auto& arg : method.GetArguments()) {
     default_method->parameters.push_back(
-        new Variable(JavaSignatureOf(arg->GetType()), arg->GetName()));
+        std::make_shared<Variable>(JavaSignatureOf(arg->GetType()), arg->GetName()));
   }
   default_method->exceptions.push_back("android.os.RemoteException");
 
   if (method.GetType().GetName() != "void") {
     const string& defaultValue = DefaultJavaValueOf(method.GetType());
     default_method->statements->Add(
-        new LiteralStatement(StringPrintf("return %s;\n", defaultValue.c_str())));
+        std::make_shared<LiteralStatement>(StringPrintf("return %s;\n", defaultValue.c_str())));
   }
   return default_method;
 }
 
-static unique_ptr<Class> generate_default_impl_class(const AidlInterface& iface,
+static shared_ptr<Class> generate_default_impl_class(const AidlInterface& iface,
                                                      const Options& options) {
-  unique_ptr<Class> default_class(new Class);
+  auto default_class = std::make_shared<Class>();
   default_class->comment = "/** Default implementation for " + iface.GetName() + ". */";
   default_class->modifiers = PUBLIC | STATIC;
   default_class->what = Class::CLASS;
@@ -916,7 +935,7 @@
 
   for (const auto& m : iface.GetMethods()) {
     if (m->IsUserDefined()) {
-      default_class->elements.emplace_back(generate_default_impl_method(*(m.get())).release());
+      default_class->elements.emplace_back(generate_default_impl_method(*m.get()));
     } else {
       if (m->GetName() == kGetInterfaceVersion && options.Version() > 0) {
         // This is called only when the remote side is not implementing this
@@ -930,24 +949,25 @@
              << "public int " << kGetInterfaceVersion << "() {\n"
              << "  return -1;\n"
              << "}\n";
-        default_class->elements.emplace_back(new LiteralClassElement(code.str()));
+        default_class->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
       }
     }
   }
 
   default_class->elements.emplace_back(
-      new LiteralClassElement("@Override\n"
-                              "public android.os.IBinder asBinder() {\n"
-                              "  return null;\n"
-                              "}\n"));
+      std::make_shared<LiteralClassElement>("@Override\n"
+                                            "public android.os.IBinder asBinder() {\n"
+                                            "  return null;\n"
+                                            "}\n"));
 
   return default_class;
 }
 
-Class* generate_binder_interface_class(const AidlInterface* iface, const AidlTypenames& typenames,
-                                       const Options& options) {
+std::unique_ptr<Class> generate_binder_interface_class(const AidlInterface* iface,
+                                                       const AidlTypenames& typenames,
+                                                       const Options& options) {
   // the interface class
-  Class* interface = new Class;
+  auto interface = std::make_unique<Class>();
   interface->comment = iface->GetComments();
   interface->modifiers = PUBLIC;
   interface->what = Class::INTERFACE;
@@ -964,15 +984,15 @@
          << " * that the remote object is implementing.\n"
          << " */\n"
          << "public static final int VERSION = " << options.Version() << ";\n";
-    interface->elements.emplace_back(new LiteralClassElement(code.str()));
+    interface->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
   }
 
   // the default impl class
-  Class* default_impl = generate_default_impl_class(*iface, options).release();
+  auto default_impl = generate_default_impl_class(*iface, options);
   interface->elements.emplace_back(default_impl);
 
   // the stub inner class
-  StubClass* stub = new StubClass(iface, options);
+  auto stub = std::make_shared<StubClass>(iface, options);
   interface->elements.push_back(stub);
 
   compute_outline_methods(iface,
@@ -981,7 +1001,7 @@
                           options.onTransact_non_outline_count_);
 
   // the proxy inner class
-  ProxyClass* proxy = new ProxyClass(iface, options);
+  auto proxy = std::make_shared<ProxyClass>(iface, options);
   stub->elements.push_back(proxy);
 
   // stub and proxy support for getInterfaceDescriptor()
@@ -993,13 +1013,13 @@
 
     switch (value.GetType()) {
       case AidlConstantValue::Type::STRING: {
-        generate_string_constant(interface, constant->GetName(),
+        generate_string_constant(interface.get(), constant->GetName(),
                                  constant->ValueString(ConstantValueDecorator));
         break;
       }
       case AidlConstantValue::Type::INTEGRAL:
       case AidlConstantValue::Type::HEXIDECIMAL: {
-        generate_int_constant(interface, constant->GetName(),
+        generate_int_constant(interface.get(), constant->GetName(),
                               constant->ValueString(ConstantValueDecorator));
         break;
       }
@@ -1012,7 +1032,8 @@
   // all the declared methods of the interface
 
   for (const auto& item : iface->GetMethods()) {
-    generate_methods(*iface, *item, interface, stub, proxy, item->GetId(), typenames, options);
+    generate_methods(*iface, *item, interface.get(), stub, proxy, item->GetId(), typenames,
+                     options);
   }
 
   // additional static methods for the default impl set/get to the
@@ -1022,7 +1043,7 @@
   // TODO(b/111417145) make this conditional depending on the Java language
   // version requested
   const string i_name = iface->GetCanonicalName();
-  stub->elements.emplace_back(new LiteralClassElement(
+  stub->elements.emplace_back(std::make_shared<LiteralClassElement>(
       StringPrintf("public static boolean setDefaultImpl(%s impl) {\n"
                    "  if (Stub.Proxy.sDefaultImpl == null && impl != null) {\n"
                    "    Stub.Proxy.sDefaultImpl = impl;\n"
@@ -1032,14 +1053,14 @@
                    "}\n",
                    i_name.c_str())));
   stub->elements.emplace_back(
-      new LiteralClassElement(StringPrintf("public static %s getDefaultImpl() {\n"
-                                           "  return Stub.Proxy.sDefaultImpl;\n"
-                                           "}\n",
-                                           i_name.c_str())));
+      std::make_shared<LiteralClassElement>(StringPrintf("public static %s getDefaultImpl() {\n"
+                                                         "  return Stub.Proxy.sDefaultImpl;\n"
+                                                         "}\n",
+                                                         i_name.c_str())));
 
   // the static field is defined in the proxy class, not in the interface class
   // because all fields in an interface class are by default final.
-  proxy->elements.emplace_back(new LiteralClassElement(
+  proxy->elements.emplace_back(std::make_shared<LiteralClassElement>(
       StringPrintf("public static %s sDefaultImpl;\n", i_name.c_str())));
 
   stub->finish();