Merge "Fix -Landroidbp-impl generates file with wrong name."
diff --git a/Method.cpp b/Method.cpp
index 284339e..bfd28c9 100644
--- a/Method.cpp
+++ b/Method.cpp
@@ -235,5 +235,14 @@
     return mType->isJavaCompatible();
 }
 
+////////////////////////////////////////////////////////////////////////////////
+bool TypedVarVector::add(TypedVar *v) {
+    if (mNames.emplace(v->name()).second) {
+        push_back(v);
+        return true;
+    }
+    return false;
+}
+
 }  // namespace android
 
diff --git a/Method.h b/Method.h
index 4f5163d..6981b72 100644
--- a/Method.h
+++ b/Method.h
@@ -21,6 +21,7 @@
 #include <android-base/macros.h>
 #include <functional>
 #include <hidl-util/Formatter.h>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -31,6 +32,7 @@
 struct ScalarType;
 struct Type;
 struct TypedVar;
+struct TypedVarVector;
 
 using MethodImpl = std::function<void(Formatter &)>;
 
@@ -107,6 +109,14 @@
     DISALLOW_COPY_AND_ASSIGN(TypedVar);
 };
 
+struct TypedVarVector : public std::vector<TypedVar *> {
+    TypedVarVector() = default;
+
+    bool add(TypedVar *v);
+private:
+    std::set<std::string> mNames;
+};
+
 }  // namespace android
 
 #endif  // METHOD_H_
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index 4f932e5..9c0e75b 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -268,7 +268,7 @@
     android::ConstantExpression *constantExpression;
     std::vector<android::EnumValue *> *enumValues;
     android::TypedVar *typedVar;
-    std::vector<android::TypedVar *> *typedVars;
+    android::TypedVarVector *typedVars;
     android::Method *method;
     android::CompoundType::Style compoundStyle;
     std::vector<std::string> *stringVec;
@@ -746,17 +746,25 @@
 typed_vars
     : /* empty */
       {
-          $$ = new std::vector<TypedVar *>;
+          $$ = new TypedVarVector();
       }
     | typed_var
       {
-          $$ = new std::vector<TypedVar *>;
-          $$->push_back($1);
+          $$ = new TypedVarVector();
+          if (!$$->add($1)) {
+              std::cerr << "ERROR: duplicated argument or result name "
+                  << $1->name() << " at " << @1 << "\n";
+              ast->addSyntaxError();
+          }
       }
     | typed_vars ',' typed_var
       {
           $$ = $1;
-          $$->push_back($3);
+          if (!$$->add($3)) {
+              std::cerr << "ERROR: duplicated argument or result name "
+                  << $3->name() << " at " << @3 << "\n";
+              ast->addSyntaxError();
+          }
       }
     ;
 
diff --git a/test/errors/syntax/1.0/IEx1.hal b/test/errors/syntax/1.0/IEx1.hal
index 33fc576..bc48d01 100644
--- a/test/errors/syntax/1.0/IEx1.hal
+++ b/test/errors/syntax/1.0/IEx1.hal
@@ -99,4 +99,8 @@
 
     }
     struct Good {};
+
+    duplicatedArg(int32_t bar, MultiDimensional bar);
+    duplicatedResult() generates (uint32_t baz, bool baz);
+
 } // another semicolon
diff --git a/test/errors/syntax/1.0/README b/test/errors/syntax/1.0/README
index d7b9fd9..7e2f04e 100644
--- a/test/errors/syntax/1.0/README
+++ b/test/errors/syntax/1.0/README
@@ -1,5 +1,5 @@
 Run with
 
 croot
-hidl-gen -Lc++ -r tests:system/tools/hidl/test -o ~/temp \
+hidl-gen -Lc++ -r tests:system/tools/hidl/test -r android.hidl:system/libhidl/transport -o ~/temp \
     tests.errors.syntax@1.0