Keeping track of imported names, resolve enum storage types, some finetuning.
diff --git a/AST.cpp b/AST.cpp
index 7c02f1d..26da2bd 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -141,7 +141,7 @@
return mScopePath.top();
}
-Type *AST::lookupType(const char *name) const {
+Type *AST::lookupType(const char *name) {
FQName fqName(name);
CHECK(fqName.isValid());
@@ -166,7 +166,13 @@
// LOG(INFO) << "lookupType now looking for " << fqName.string();
- return mCoordinator->lookupType(fqName);
+ Type *resultType = mCoordinator->lookupType(fqName);
+
+ if (resultType) {
+ mImportedNames.insert(fqName);
+ }
+
+ return resultType;
}
Type *AST::lookupTypeInternal(const std::string &namePath) const {
diff --git a/AST.h b/AST.h
index a159c59..c0fe6b0 100644
--- a/AST.h
+++ b/AST.h
@@ -3,6 +3,7 @@
#define AST_H_
#include <android-base/macros.h>
+#include <set>
#include <string>
#include <utils/Vector.h>
@@ -38,7 +39,7 @@
// Look up a type by FQName, "pure" names, i.e. those without package
// or version are first looked up in the current scope chain.
// After that lookup proceeds to imports.
- Type *lookupType(const char *name) const;
+ Type *lookupType(const char *name);
// Takes dot-separated path components to a type possibly inside this AST.
// Name resolution goes from root scope downwards, i.e. the path must be
@@ -58,6 +59,16 @@
FQName mPackage;
+ std::set<FQName> mImportedNames;
+
+ static void GetPackageComponents(
+ const FQName &fqName, std::vector<std::string> *components);
+
+ static void GetPackageAndVersionComponents(
+ const FQName &fqName,
+ std::vector<std::string> *components,
+ bool cpp_compatible);
+
void getPackageComponents(std::vector<std::string> *components) const;
void getPackageAndVersionComponents(
diff --git a/Android.mk b/Android.mk
index a66daf5..3c6e843 100644
--- a/Android.mk
+++ b/Android.mk
@@ -41,5 +41,4 @@
include $(BUILD_HOST_EXECUTABLE)
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
+# include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/CompoundType.cpp b/CompoundType.cpp
index a96c7e2..d079f96 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -274,7 +274,7 @@
"parcel",
!isReader /* parcelObjIsPointer */,
isReader,
- ErrorMode_Goto,
+ ErrorMode_Return,
"parentHandle",
"parentOffset + offsetof(" + name() + ", " + field->name() + ")");
}
diff --git a/EnumType.cpp b/EnumType.cpp
index 506c796..40948b5 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -3,6 +3,8 @@
#include "Formatter.h"
#include "ScalarType.h"
+#include <android-base/logging.h>
+
namespace android {
EnumValue::EnumValue(const char *name, const char *value)
@@ -60,6 +62,10 @@
out << "};\n\n";
}
+const ScalarType *EnumType::resolveToScalarType() const {
+ return mStorageType->resolveToScalarType();
+}
+
std::string EnumType::getCppType(StorageMode, std::string *extra) const {
extra->clear();
@@ -73,17 +79,29 @@
bool parcelObjIsPointer,
bool isReader,
ErrorMode mode) const {
- mStorageType->emitReaderWriter(
- out, name, parcelObj, parcelObjIsPointer, isReader, mode);
+ const ScalarType *scalarType = mStorageType->resolveToScalarType();
+ CHECK(scalarType != NULL);
+
+ scalarType->emitReaderWriterWithCast(
+ out,
+ name,
+ parcelObj,
+ parcelObjIsPointer,
+ isReader,
+ mode,
+ true /* needsCast */);
}
status_t EnumType::emitTypeDeclarations(Formatter &out) const {
+ const ScalarType *scalarType = mStorageType->resolveToScalarType();
+ CHECK(scalarType != NULL);
+
std::string extra;
out << "enum class "
<< name()
<< " : "
- << mStorageType->getCppType(&extra)
+ << ((Type *)scalarType)->getCppType(&extra)
<< " {\n";
out.indent();
diff --git a/EnumType.h b/EnumType.h
index a0d866a..a587727 100644
--- a/EnumType.h
+++ b/EnumType.h
@@ -30,6 +30,8 @@
void dump(Formatter &out) const override;
+ const ScalarType *resolveToScalarType() const override;
+
std::string getCppType(StorageMode mode, std::string *extra) const override;
void emitReaderWriter(
diff --git a/HandleType.cpp b/HandleType.cpp
index ea5d665..9e55638 100644
--- a/HandleType.cpp
+++ b/HandleType.cpp
@@ -121,8 +121,11 @@
out.indent();
out.indent();
- out << name
- << (nameIsPointer ? "->" : ".")
+ const std::string nameDeref =
+ nameIsPointer ? ("(*" + name + ")") : name;
+
+ out << nameDeref
+ << "->"
<< "handle(),\n"
<< parentName
<< ",\n"
diff --git a/RefType.cpp b/RefType.cpp
index c71d1d7..fcb8604 100644
--- a/RefType.cpp
+++ b/RefType.cpp
@@ -9,6 +9,10 @@
mReferencedType(type) {
}
+const ScalarType *RefType::resolveToScalarType() const {
+ return mReferencedType->resolveToScalarType();
+}
+
const Type *RefType::referencedType() const {
return mReferencedType;
}
diff --git a/RefType.h b/RefType.h
index 87e2194..c5b7b3c 100644
--- a/RefType.h
+++ b/RefType.h
@@ -11,6 +11,8 @@
void dump(Formatter &out) const override;
+ const ScalarType *resolveToScalarType() const override;
+
const Type *referencedType() const;
std::string getCppType(StorageMode mode, std::string *extra) const override;
diff --git a/ScalarType.cpp b/ScalarType.cpp
index c498f8c..14fa4e2 100644
--- a/ScalarType.cpp
+++ b/ScalarType.cpp
@@ -16,6 +16,10 @@
out << kName[mKind];
}
+const ScalarType *ScalarType::resolveToScalarType() const {
+ return this;
+}
+
std::string ScalarType::getCppType(StorageMode, std::string *extra) const {
static const char *const kName[] = {
"char",
@@ -45,6 +49,24 @@
bool parcelObjIsPointer,
bool isReader,
ErrorMode mode) const {
+ emitReaderWriterWithCast(
+ out,
+ name,
+ parcelObj,
+ parcelObjIsPointer,
+ isReader,
+ mode,
+ false /* needsCast */);
+}
+
+void ScalarType::emitReaderWriterWithCast(
+ Formatter &out,
+ const std::string &name,
+ const std::string &parcelObj,
+ bool parcelObjIsPointer,
+ bool isReader,
+ ErrorMode mode,
+ bool needsCast) const {
static const char *const kSuffix[] = {
"Uint8",
"Uint8",
@@ -70,6 +92,14 @@
<< kSuffix[mKind]
<< "(";
+ if (needsCast) {
+ std::string extra;
+
+ out << "("
+ << Type::getCppType(&extra)
+ << (isReader ? " *)" : ")");
+ }
+
if (isReader) {
out << "&";
}
diff --git a/ScalarType.h b/ScalarType.h
index 2bd7cae..61220d6 100644
--- a/ScalarType.h
+++ b/ScalarType.h
@@ -27,6 +27,8 @@
void dump(Formatter &out) const override;
+ const ScalarType *resolveToScalarType() const override;
+
std::string getCppType(StorageMode mode, std::string *extra) const override;
void emitReaderWriter(
@@ -37,6 +39,15 @@
bool isReader,
ErrorMode mode) const override;
+ void emitReaderWriterWithCast(
+ Formatter &out,
+ const std::string &name,
+ const std::string &parcelObj,
+ bool parcelObjIsPointer,
+ bool isReader,
+ ErrorMode mode,
+ bool needsCast) const;
+
private:
Kind mKind;
diff --git a/Type.cpp b/Type.cpp
index 5f3c462..548e425 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -17,6 +17,10 @@
return false;
}
+const ScalarType *Type::resolveToScalarType() const {
+ return NULL;
+}
+
std::string Type::getCppType(StorageMode, std::string *) const {
CHECK(!"Should not be here");
return std::string();
@@ -64,6 +68,12 @@
out << "if (_aidl_err != ::android::OK) { break; }\n\n";
break;
}
+
+ case ErrorMode_Return:
+ {
+ out << "if (_aidl_err != ::android::OK) { return _aidl_err; }\n\n";
+ break;
+ }
}
}
@@ -74,16 +84,24 @@
out << "goto _aidl_error;\n";
break;
}
+
case ErrorMode_Break:
{
out << "break;\n";
break;
}
+
case ErrorMode_Ignore:
{
out << "/* ignoring _aidl_error! */";
break;
}
+
+ case ErrorMode_Return:
+ {
+ out << "return _aidl_err;\n";
+ break;
+ }
}
}
diff --git a/Type.h b/Type.h
index f7f8509..8e84c55 100644
--- a/Type.h
+++ b/Type.h
@@ -9,6 +9,7 @@
namespace android {
struct Formatter;
+struct ScalarType;
struct Type {
Type();
@@ -17,6 +18,7 @@
virtual void dump(Formatter &out) const = 0;
virtual bool isScope() const;
virtual bool isInterface() const;
+ virtual const ScalarType *resolveToScalarType() const;
enum StorageMode {
StorageMode_Stack,
@@ -36,6 +38,7 @@
ErrorMode_Ignore,
ErrorMode_Goto,
ErrorMode_Break,
+ ErrorMode_Return,
};
virtual void emitReaderWriter(
Formatter &out,
diff --git a/TypeDef.cpp b/TypeDef.cpp
index 163a7e7..94c38cb 100644
--- a/TypeDef.cpp
+++ b/TypeDef.cpp
@@ -9,6 +9,10 @@
mReferencedType(type) {
}
+const ScalarType *TypeDef::resolveToScalarType() const {
+ return mReferencedType->resolveToScalarType();
+}
+
const Type *TypeDef::referencedType() const {
return mReferencedType;
}
diff --git a/TypeDef.h b/TypeDef.h
index 6e2c54c..7ea7163 100644
--- a/TypeDef.h
+++ b/TypeDef.h
@@ -11,6 +11,8 @@
void dump(Formatter &out) const override;
+ const ScalarType *resolveToScalarType() const override;
+
const Type *referencedType() const;
std::string getCppType(StorageMode mode, std::string *extra) const override;
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 4d80b06..0ab32b8 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -84,16 +84,21 @@
return err;
}
-void AST::getPackageComponents(
- std::vector<std::string> *components) const {
- SplitString(mPackage.package(), '.', components);
+// static
+void AST::GetPackageComponents(
+ const FQName &fqName,
+ std::vector<std::string> *components) {
+ SplitString(fqName.package(), '.', components);
}
-void AST::getPackageAndVersionComponents(
- std::vector<std::string> *components, bool cpp_compatible) const {
- getPackageComponents(components);
+// static
+void AST::GetPackageAndVersionComponents(
+ const FQName &fqName,
+ std::vector<std::string> *components,
+ bool cpp_compatible) {
+ GetPackageComponents(fqName, components);
- const std::string packageVersion = mPackage.version();
+ const std::string packageVersion = fqName.version();
CHECK(packageVersion[0] == '@');
if (!cpp_compatible) {
@@ -112,6 +117,16 @@
components->push_back(versionString);
}
+void AST::getPackageComponents(
+ std::vector<std::string> *components) const {
+ GetPackageComponents(mPackage, components);
+}
+
+void AST::getPackageAndVersionComponents(
+ std::vector<std::string> *components, bool cpp_compatible) const {
+ GetPackageAndVersionComponents(mPackage, components, cpp_compatible);
+}
+
std::string AST::makeHeaderGuard(const std::string &baseName) const {
std::vector<std::string> packageComponents;
getPackageAndVersionComponents(
@@ -179,6 +194,25 @@
out << "#ifndef " << guard << "\n";
out << "#define " << guard << "\n\n";
+ for (const auto &item : mImportedNames) {
+ out << "#include <";
+
+ std::vector<std::string> components;
+ GetPackageAndVersionComponents(
+ item, &components, false /* cpp_compatible */);
+
+ for (const auto &component : components) {
+ out << component << "/";
+ }
+
+ out << item.name()
+ << ".h>\n";
+ }
+
+ if (!mImportedNames.empty()) {
+ out << "\n";
+ }
+
out << "#include <hwbinder/HidlSupport.h>\n";
if (isInterface) {
@@ -199,7 +233,10 @@
out.indent();
- out << "DECLARE_HWBINDER_META_INTERFACE(" << ifaceName << ");\n\n";
+ // cut off the leading 'I'.
+ const std::string baseName = ifaceName.substr(1);
+
+ out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
}
status_t err = emitTypeDeclarations(out);
diff --git a/main.cpp b/main.cpp
index b21d3aa..7869e4b 100644
--- a/main.cpp
+++ b/main.cpp
@@ -16,6 +16,8 @@
int main(int argc, char **argv) {
std::string outputDir;
+ const char *me = argv[0];
+
int res;
while ((res = getopt(argc, argv, "ho:")) >= 0) {
switch (res) {
@@ -29,7 +31,7 @@
case 'h':
default:
{
- usage(argv[0]);
+ usage(me);
exit(1);
break;
}
@@ -39,8 +41,10 @@
argc -= optind;
argv += optind;
+ // Valid options are now in argv[0] .. argv[argc - 1].
+
if (outputDir.empty()) {
- usage(argv[0]);
+ usage(me);
exit(1);
} else {
const size_t len = outputDir.size();
@@ -60,7 +64,7 @@
Coordinator coordinator(interfacesPath);
- for (int i = 1; i < argc; ++i) {
+ for (int i = 0; i < argc; ++i) {
FQName fqName(argv[i]);
CHECK(fqName.isValid() && fqName.isFullyQualified());