Moving hidl-gen parser stack outside of AST
Move compiler stack outside of AST members,
adding a parent member to NamedType to make AST
a real tree.
Add a check that interface must be declared in global scope,
that was not checked in hidl-gen.
Also move scanner outside of AST.
Test: compiles, links, boots, hidl_test
Change-Id: Ida0c192b258e40c8cfe033f00a842444df0130ad
diff --git a/AST.cpp b/AST.cpp
index 2dfd7fa..ef17b71 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -25,27 +25,23 @@
#include "Scope.h"
#include "TypeDef.h"
-#include <hidl-util/Formatter.h>
-#include <hidl-util/FQName.h>
#include <android-base/logging.h>
-#include <iostream>
+#include <hidl-util/FQName.h>
+#include <hidl-util/Formatter.h>
+#include <hidl-util/StringHelper.h>
#include <stdlib.h>
+#include <algorithm>
+#include <iostream>
namespace android {
-AST::AST(const Coordinator *coordinator, const std::string &path)
+AST::AST(const Coordinator* coordinator, const std::string& path)
: mCoordinator(coordinator),
mPath(path),
- mScanner(NULL),
- mRootScope(new Scope("" /* localName */, Location::startOf(path))) {
- enterScope(mRootScope);
-}
+ mRootScope("" /* localName */, Location::startOf(path), nullptr /* parent */) {}
-AST::~AST() {
- delete mRootScope;
- mRootScope = nullptr;
-
- CHECK(mScanner == NULL);
+Scope* AST::getRootScope() {
+ return &mRootScope;
}
// used by the parser.
@@ -57,14 +53,6 @@
return mSyntaxErrors;
}
-void *AST::scanner() {
- return mScanner;
-}
-
-void AST::setScanner(void *scanner) {
- mScanner = scanner;
-}
-
const std::string &AST::getFilename() const {
return mPath;
}
@@ -87,11 +75,11 @@
}
bool AST::isInterface() const {
- return mRootScope->getInterface() != nullptr;
+ return mRootScope.getInterface() != nullptr;
}
bool AST::containsInterfaces() const {
- return mRootScope->containsInterfaces();
+ return mRootScope.containsInterfaces();
}
bool AST::addImport(const char *import) {
@@ -187,51 +175,33 @@
mImportedASTs.insert(ast);
}
-void AST::enterScope(Scope *container) {
- mScopePath.push_back(container);
-}
-
-void AST::leaveScope() {
- mScopePath.pop_back();
-}
-
-Scope *AST::scope() {
- CHECK(!mScopePath.empty());
- return mScopePath.back();
-}
-
-bool AST::addTypeDef(const char *localName, Type *type, const Location &location,
- std::string *errorMsg) {
+bool AST::addTypeDef(const char* localName, Type* type, const Location& location,
+ std::string* errorMsg, Scope* scope) {
// The reason we wrap the given type in a TypeDef is simply to suppress
// emitting any type definitions later on, since this is just an alias
// to a type defined elsewhere.
- return addScopedTypeInternal(
- new TypeDef(localName, location, type), errorMsg);
+ return addScopedTypeInternal(new TypeDef(localName, location, scope, type), errorMsg, scope);
}
-bool AST::addScopedType(NamedType *type, std::string *errorMsg) {
- return addScopedTypeInternal(
- type, errorMsg);
+bool AST::addScopedType(NamedType* type, std::string* errorMsg, Scope* scope) {
+ return addScopedTypeInternal(type, errorMsg, scope);
}
-bool AST::addScopedTypeInternal(
- NamedType *type,
- std::string *errorMsg) {
-
- bool success = scope()->addType(type, errorMsg);
+bool AST::addScopedTypeInternal(NamedType* type, std::string* errorMsg, Scope* scope) {
+ bool success = scope->addType(type, errorMsg);
if (!success) {
return false;
}
- std::string path;
- for (size_t i = 1; i < mScopePath.size(); ++i) {
- path.append(mScopePath[i]->localName());
- path.append(".");
+ std::vector<std::string> pathComponents{{type->localName()}};
+ for (; scope != &mRootScope; scope = scope->parent()) {
+ pathComponents.push_back(scope->localName());
}
- path.append(type->localName());
+
+ std::reverse(pathComponents.begin(), pathComponents.end());
+ std::string path = StringHelper::JoinStrings(pathComponents, ".");
FQName fqName(mPackage.package(), mPackage.version(), path);
-
type->setFullName(fqName);
mDefinedTypesByFullName[fqName] = type;
@@ -239,15 +209,14 @@
return true;
}
-EnumValue *AST::lookupEnumValue(const FQName &fqName, std::string *errorMsg) {
-
+EnumValue* AST::lookupEnumValue(const FQName& fqName, std::string* errorMsg, Scope* scope) {
FQName enumTypeName = fqName.typeName();
std::string enumValueName = fqName.valueName();
CHECK(enumTypeName.isValid());
CHECK(!enumValueName.empty());
- Type *type = lookupType(enumTypeName);
+ Type* type = lookupType(enumTypeName, scope);
if(type == nullptr) {
*errorMsg = "Cannot find type " + enumTypeName.string();
return nullptr;
@@ -266,7 +235,7 @@
return v;
}
-Type *AST::lookupType(const FQName &fqName) {
+Type* AST::lookupType(const FQName& fqName, Scope* scope) {
CHECK(fqName.isValid());
if (fqName.name().empty()) {
@@ -278,7 +247,7 @@
if (fqName.package().empty() && fqName.version().empty()) {
// resolve locally first if possible.
- returnedType = lookupTypeLocally(fqName);
+ returnedType = lookupTypeLocally(fqName, scope);
if (returnedType != nullptr) {
return returnedType;
}
@@ -298,12 +267,12 @@
}
// Rule 0: try resolve locally
-Type *AST::lookupTypeLocally(const FQName &fqName) {
+Type* AST::lookupTypeLocally(const FQName& fqName, Scope* scope) {
CHECK(fqName.package().empty() && fqName.version().empty()
&& !fqName.name().empty() && fqName.valueName().empty());
- for (size_t i = mScopePath.size(); i-- > 0;) {
- Type *type = mScopePath[i]->lookupType(fqName);
+ for (; scope != nullptr; scope = scope->parent()) {
+ Type* type = scope->lookupType(fqName);
if (type != nullptr) {
// Resolve typeDefs to the target type.
@@ -329,7 +298,7 @@
// in import.
Type *local = findDefinedType(autofilled, &matchingName);
CHECK(local == nullptr || autofilled == matchingName);
- Type *fromImport = lookupType(autofilled);
+ Type* fromImport = lookupType(autofilled, nullptr /* scope */);
if (local != nullptr && fromImport != nullptr && local != fromImport) {
// Something bad happen; two types have the same FQName.
@@ -531,7 +500,7 @@
bool AST::isJavaCompatible() const {
if (!AST::isInterface()) {
- for (const auto *type : mRootScope->getSubTypes()) {
+ for (const auto* type : mRootScope.getSubTypes()) {
if (!type->isJavaCompatible()) {
return false;
}
@@ -540,26 +509,26 @@
return true;
}
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
return iface->isJavaCompatible();
}
void AST::appendToExportedTypesVector(
std::vector<const Type *> *exportedTypes) const {
- mRootScope->appendToExportedTypesVector(exportedTypes);
+ mRootScope.appendToExportedTypesVector(exportedTypes);
}
bool AST::isIBase() const {
- Interface *iface = mRootScope->getInterface();
+ Interface* iface = mRootScope.getInterface();
return iface != nullptr && iface->isIBase();
}
const Interface *AST::getInterface() const {
- return mRootScope->getInterface();
+ return mRootScope.getInterface();
}
std::string AST::getBaseName() const {
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
return iface ? iface->getBaseName() : "types";
}
diff --git a/AST.h b/AST.h
index 437e2be..bb6e677 100644
--- a/AST.h
+++ b/AST.h
@@ -25,6 +25,7 @@
#include <string>
#include <vector>
+#include "Scope.h"
#include "Type.h"
namespace android {
@@ -36,12 +37,10 @@
struct Method;
struct NamedType;
struct TypedVar;
-struct Scope;
struct EnumValue;
struct AST {
AST(const Coordinator *coordinator, const std::string &path);
- ~AST();
bool setPackage(const char *package);
bool addImport(const char *import);
@@ -51,29 +50,22 @@
bool isInterface() const;
bool containsInterfaces() const;
- void enterScope(Scope *container);
- void leaveScope();
- Scope *scope();
+ // Returns true iff successful.
+ bool addTypeDef(const char* localName, Type* type, const Location& location,
+ std::string* errorMsg, Scope* scope);
// Returns true iff successful.
- bool addTypeDef(const char *localName, Type *type, const Location &location,
- std::string *errorMsg);
-
- // Returns true iff successful.
- bool addScopedType(NamedType *type, std::string *errorMsg);
-
- void *scanner();
- void setScanner(void *scanner);
+ bool addScopedType(NamedType* type, std::string* errorMsg, Scope* scope);
const std::string &getFilename() const;
// Look up an enum value by "FQName:valueName".
- EnumValue *lookupEnumValue(const FQName &fqName, std::string *errorMsg);
+ EnumValue* lookupEnumValue(const FQName& fqName, std::string* errorMsg, Scope* scope);
// 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 FQName &fqName);
+ Type* lookupType(const FQName& fqName, Scope* scope);
void addImportedAST(AST *ast);
@@ -126,13 +118,13 @@
// types or Interface base name (e.x. Foo)
std::string getBaseName() const;
-private:
+ Scope* getRootScope();
+
+ private:
const Coordinator *mCoordinator;
std::string mPath;
- std::vector<Scope *> mScopePath;
- void *mScanner;
- Scope *mRootScope;
+ Scope mRootScope;
FQName mPackage;
@@ -155,12 +147,10 @@
// used by the parser.
size_t mSyntaxErrors = 0;
- bool addScopedTypeInternal(
- NamedType *type,
- std::string *errorMsg);
+ bool addScopedTypeInternal(NamedType* type, std::string* errorMsg, Scope* scope);
// Helper functions for lookupType.
- Type *lookupTypeLocally(const FQName &fqName);
+ Type* lookupTypeLocally(const FQName& fqName, Scope* scope);
status_t lookupAutofilledType(const FQName &fqName, Type **returnedType);
Type *lookupTypeFromImports(const FQName &fqName);
diff --git a/CompoundType.cpp b/CompoundType.cpp
index 154bc67..597e51f 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -23,11 +23,9 @@
namespace android {
-CompoundType::CompoundType(Style style, const char *localName, const Location &location)
- : Scope(localName, location),
- mStyle(style),
- mFields(NULL) {
-}
+CompoundType::CompoundType(Style style, const char* localName, const Location& location,
+ Scope* parent)
+ : Scope(localName, location, parent), mStyle(style), mFields(NULL) {}
CompoundType::Style CompoundType::style() const {
return mStyle;
diff --git a/CompoundType.h b/CompoundType.h
index aa395ba..3aea816 100644
--- a/CompoundType.h
+++ b/CompoundType.h
@@ -32,7 +32,7 @@
STYLE_UNION,
};
- CompoundType(Style style, const char *localName, const Location &location);
+ CompoundType(Style style, const char* localName, const Location& location, Scope* parent);
Style style() const;
diff --git a/EnumType.cpp b/EnumType.cpp
index 6dfabfd..fb8545f 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -25,13 +25,9 @@
namespace android {
-EnumType::EnumType(
- const char *localName,
- const Location &location,
- Type *storageType)
- : Scope(localName, location),
- mValues(),
- mStorageType(storageType) {
+EnumType::EnumType(const char* localName, const Location& location, Type* storageType,
+ Scope* parent)
+ : Scope(localName, location, parent), mValues(), mStorageType(storageType) {
mBitfieldType = new BitFieldType();
mBitfieldType->setElementType(this);
}
diff --git a/EnumType.h b/EnumType.h
index ab9c4a7..d829292 100644
--- a/EnumType.h
+++ b/EnumType.h
@@ -29,9 +29,7 @@
struct BitFieldType;
struct EnumType : public Scope {
- EnumType(const char *localName,
- const Location &location,
- Type *storageType);
+ EnumType(const char* localName, const Location& location, Type* storageType, Scope* parent);
const Type *storageType() const;
const std::vector<EnumValue *> &values() const;
diff --git a/Interface.cpp b/Interface.cpp
index 5974288..26bdf3c 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -67,11 +67,9 @@
LAST_HIDL_TRANSACTION = 0x0fffffff,
};
-Interface::Interface(const char *localName, const Location &location, Interface *super)
- : Scope(localName, location),
- mSuperType(super),
- mIsJavaCompatibleInProgress(false) {
-}
+Interface::Interface(const char* localName, const Location& location, Scope* parent,
+ Interface* super)
+ : Scope(localName, location, parent), mSuperType(super), mIsJavaCompatibleInProgress(false) {}
std::string Interface::typeName() const {
return "interface " + localName();
diff --git a/Interface.h b/Interface.h
index 793226a..b37dc60 100644
--- a/Interface.h
+++ b/Interface.h
@@ -27,7 +27,7 @@
struct InterfaceAndMethod;
struct Interface : public Scope {
- Interface(const char *localName, const Location &location, Interface *super);
+ Interface(const char* localName, const Location& location, Scope* parent, Interface* super);
bool addMethod(Method *method);
bool addAllReservedMethods();
diff --git a/NamedType.cpp b/NamedType.cpp
index 027245a..f6d876f 100644
--- a/NamedType.cpp
+++ b/NamedType.cpp
@@ -18,9 +18,8 @@
namespace android {
-NamedType::NamedType(const char *localName, const Location &loc)
- : mLocalName(localName), mLocation(loc) {
-}
+NamedType::NamedType(const char* localName, const Location& loc, Scope* parent)
+ : mLocalName(localName), mLocation(loc), mParent(parent) {}
bool NamedType::isNamedType() const {
return true;
@@ -54,6 +53,10 @@
return mLocation;
}
+Scope* NamedType::parent() const {
+ return mParent;
+}
+
void NamedType::emitDump(
Formatter &out,
const std::string &streamName,
diff --git a/NamedType.h b/NamedType.h
index 8a1a79e..1e5a614 100644
--- a/NamedType.h
+++ b/NamedType.h
@@ -27,8 +27,10 @@
namespace android {
+struct Scope;
+
struct NamedType : public Type {
- NamedType(const char *localName, const Location &loc);
+ NamedType(const char* localName, const Location& loc, Scope* mParent);
bool isNamedType() const override;
@@ -53,10 +55,13 @@
const std::string &streamName,
const std::string &name) const override;
-private:
+ Scope* parent() const;
+
+ private:
std::string mLocalName;
FQName mFullName;
Location mLocation;
+ Scope* const mParent;
DISALLOW_COPY_AND_ASSIGN(NamedType);
};
diff --git a/Scope.cpp b/Scope.cpp
index b2414b3..b12cec8 100644
--- a/Scope.cpp
+++ b/Scope.cpp
@@ -24,10 +24,8 @@
namespace android {
-Scope::Scope(const char *localName,
- const Location &location)
- : NamedType(localName, location) {
-}
+Scope::Scope(const char* localName, const Location& location, Scope* parent)
+ : NamedType(localName, location, parent) {}
Scope::~Scope(){}
bool Scope::addType(NamedType *type, std::string *errorMsg) {
diff --git a/Scope.h b/Scope.h
index 122520b..0f58444 100644
--- a/Scope.h
+++ b/Scope.h
@@ -30,8 +30,7 @@
struct LocalIdentifier;
struct Scope : public NamedType {
- Scope(const char *localName,
- const Location &location);
+ Scope(const char* localName, const Location& location, Scope* parent);
virtual ~Scope();
bool addType(NamedType *type, std::string *errorMsg);
diff --git a/TypeDef.cpp b/TypeDef.cpp
index cf7c0ab..5ca050e 100644
--- a/TypeDef.cpp
+++ b/TypeDef.cpp
@@ -21,10 +21,8 @@
namespace android {
-TypeDef::TypeDef(const char* localName, const Location &location, Type *type)
- : NamedType(localName, location),
- mReferencedType(type) {
-}
+TypeDef::TypeDef(const char* localName, const Location& location, Scope* parent, Type* type)
+ : NamedType(localName, location, parent), mReferencedType(type) {}
const ScalarType *TypeDef::resolveToScalarType() const {
CHECK(!"Should not be here");
diff --git a/TypeDef.h b/TypeDef.h
index 5ccbf01..58e3d5c 100644
--- a/TypeDef.h
+++ b/TypeDef.h
@@ -23,7 +23,7 @@
namespace android {
struct TypeDef : public NamedType {
- TypeDef(const char* localName, const Location &location, Type *type);
+ TypeDef(const char* localName, const Location& location, Scope* parent, Type* type);
const ScalarType *resolveToScalarType() const override;
diff --git a/generateCpp.cpp b/generateCpp.cpp
index fa2bf25..5dde1e6 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -555,7 +555,7 @@
out << "};\n\n";
}
- err = mRootScope->emitGlobalTypeDeclarations(out);
+ err = mRootScope.emitGlobalTypeDeclarations(out);
if (err != OK) {
return err;
@@ -614,7 +614,7 @@
enterLeaveNamespace(out, true /* enter */);
- status_t err = mRootScope->emitGlobalHwDeclarations(out);
+ status_t err = mRootScope.emitGlobalHwDeclarations(out);
if (err != OK) {
return err;
}
@@ -627,7 +627,7 @@
}
status_t AST::emitTypeDeclarations(Formatter &out) const {
- return mRootScope->emitTypeDeclarations(out);
+ return mRootScope.emitTypeDeclarations(out);
}
static void wrapPassthroughArg(Formatter &out,
@@ -797,7 +797,7 @@
}
status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
const Interface *prevIterface = nullptr;
for (const auto &tuple : iface->allMethodsFromRoot()) {
@@ -826,7 +826,7 @@
}
void AST::generateTemplatizationLink(Formatter& out) const {
- out << "typedef " << mRootScope->getInterface()->localName() << " Pure;\n\n";
+ out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
}
status_t AST::generateStubHeader(const std::string &outputPath) const {
@@ -835,7 +835,7 @@
return OK;
}
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
const std::string klassName = iface->getStubName();
std::string path = outputPath;
@@ -942,7 +942,7 @@
return OK;
}
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
const std::string proxyName = iface->getProxyName();
std::string path = outputPath;
@@ -1079,7 +1079,7 @@
status_t err = generateTypeSource(out, iface ? iface->localName() : "");
if (err == OK && iface) {
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
// need to be put here, generateStubSource is using this.
out << "const char* "
@@ -1150,7 +1150,7 @@
}
if (err == OK && iface) {
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
if (isIBase()) {
out << "// skipped getService, registerAsService, registerForNotifications\n";
@@ -1182,7 +1182,7 @@
status_t AST::generateTypeSource(
Formatter &out, const std::string &ifaceName) const {
- return mRootScope->emitTypeDefinitions(out, ifaceName);
+ return mRootScope.emitTypeDefinitions(out, ifaceName);
}
void AST::declareCppReaderLocals(
@@ -1824,7 +1824,7 @@
return OK;
}
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
CHECK(iface != nullptr);
const std::string klassName = iface->getPassthroughName();
@@ -1919,7 +1919,7 @@
}
status_t AST::generateInterfaceSource(Formatter &out) const {
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
// generate castFrom functions
std::string childTypeResult = iface->getCppResultType();
@@ -1981,7 +1981,7 @@
}
status_t AST::generatePassthroughSource(Formatter &out) const {
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
const std::string klassName = iface->getPassthroughName();
@@ -2034,7 +2034,7 @@
status_t AST::generateCppAtraceCall(Formatter &out,
InstrumentationEvent event,
const Method *method) const {
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
switch (event) {
case SERVER_API_ENTRY:
@@ -2157,7 +2157,7 @@
}
}
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
out.indent();
diff --git a/generateCppImpl.cpp b/generateCppImpl.cpp
index 7025a87..ae95590 100644
--- a/generateCppImpl.cpp
+++ b/generateCppImpl.cpp
@@ -85,7 +85,7 @@
return OK;
}
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
const std::string baseName = iface->getBaseName();
std::string path = outputPath;
@@ -172,7 +172,7 @@
return OK;
}
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
const std::string baseName = iface->getBaseName();
std::string path = outputPath;
diff --git a/generateJava.cpp b/generateJava.cpp
index 0a589ae..f463b7f 100644
--- a/generateJava.cpp
+++ b/generateJava.cpp
@@ -49,7 +49,7 @@
const std::string &outputPath, const std::string &limitToType) const {
// Splits types.hal up into one java file per declared type.
- for (const auto &type : mRootScope->getSubTypes()) {
+ for (const auto& type : mRootScope.getSubTypes()) {
std::string typeName = type->localName();
if (type->isTypeDef()) {
@@ -112,7 +112,7 @@
return generateJavaTypes(outputPath, limitToType);
}
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
std::string ifaceName = iface->localName();
const std::string baseName = iface->getBaseName();
@@ -697,7 +697,7 @@
}
status_t AST::emitJavaTypeDeclarations(Formatter &out) const {
- return mRootScope->emitJavaTypeDeclarations(out, false /* atTopLevel */);
+ return mRootScope.emitJavaTypeDeclarations(out, false /* atTopLevel */);
}
} // namespace android
diff --git a/generateVts.cpp b/generateVts.cpp
index f695bec..5fd8670 100644
--- a/generateVts.cpp
+++ b/generateVts.cpp
@@ -31,11 +31,11 @@
status_t AST::emitVtsTypeDeclarations(Formatter &out) const {
if (AST::isInterface()) {
- const Interface *iface = mRootScope->getInterface();
- return iface->emitVtsAttributeDeclaration(out);
+ const Interface* iface = mRootScope.getInterface();
+ return iface->emitVtsAttributeDeclaration(out);
}
- for (const auto &type : mRootScope->getSubTypes()) {
+ for (const auto& type : mRootScope.getSubTypes()) {
// Skip for TypeDef as it is just an alias of a defined type.
if (type->isTypeDef()) {
continue;
@@ -94,7 +94,7 @@
out << "\n";
if (isInterface()) {
- const Interface *iface = mRootScope->getInterface();
+ const Interface* iface = mRootScope.getInterface();
out << "interface: {\n";
out.indent();
diff --git a/hidl-gen_l.ll b/hidl-gen_l.ll
index 5945df9..13b69bf 100644
--- a/hidl-gen_l.ll
+++ b/hidl-gen_l.ll
@@ -53,8 +53,6 @@
using namespace android;
using token = yy::parser::token;
-int check_type(yyscan_t yyscanner, struct yyguts_t *yyg);
-
#define SCALAR_TYPE(kind) \
do { \
yylval->type = new ScalarType(ScalarType::kind); \
@@ -179,22 +177,22 @@
status_t parseFile(AST *ast) {
FILE *file = fopen(ast->getFilename().c_str(), "rb");
- if (file == NULL) {
+ if (file == nullptr) {
return -errno;
}
yyscan_t scanner;
- yylex_init_extra(ast, &scanner);
- ast->setScanner(scanner);
+ yylex_init(&scanner);
yyset_in(file, scanner);
- int res = yy::parser(ast).parse();
+
+ Scope* scopeStack = ast->getRootScope();
+ int res = yy::parser(scanner, ast, &scopeStack).parse();
yylex_destroy(scanner);
- ast->setScanner(NULL);
fclose(file);
- file = NULL;
+ file = nullptr;
if (res != 0 || ast->syntaxErrors() != 0) {
return UNKNOWN_ERROR;
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index 35f7405..a244579 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -25,6 +25,7 @@
#include "Interface.h"
#include "Location.h"
#include "Method.h"
+#include "Scope.h"
#include "VectorType.h"
#include "RefType.h"
@@ -37,9 +38,17 @@
using namespace android;
-extern int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
+extern int yylex(yy::parser::semantic_type*, yy::parser::location_type*, void*);
-#define scanner ast->scanner()
+void enterScope(AST* /* ast */, Scope** scope, Scope* container) {
+ CHECK(container->parent() == (*scope));
+ *scope = container;
+}
+
+void leaveScope(AST* ast, Scope** scope) {
+ CHECK((*scope) != ast->getRootScope());
+ *scope = (*scope)->parent();
+}
::android::Location convertYYLoc(const yy::parser::location_type &loc) {
return ::android::Location(
@@ -192,8 +201,10 @@
const_cast<std::string *>(&ast->getFilename());
}
-%parse-param { android::AST *ast }
-%lex-param { void *scanner }
+%parse-param { void* scanner }
+%parse-param { android::AST* const ast }
+%parse-param { android::Scope** const scope }
+%lex-param { void* scanner }
%pure-parser
%glr-parser
%skeleton "glr.cc"
@@ -472,7 +483,7 @@
fqtype
: fqname
{
- $$ = ast->lookupType(*($1));
+ $$ = ast->lookupType(*($1), *scope);
if ($$ == NULL) {
std::cerr << "ERROR: Failed to lookup type '" << $1->string() << "' at "
<< @1
@@ -560,13 +571,13 @@
}
if ($2 != nullptr) {
- if (!ast->scope()->isInterface()) {
+ if (!(*scope)->isInterface()) {
std::cerr << "ERROR: unknown error in interface declaration at "
<< @2 << "\n";
YYERROR;
}
- Interface *iface = static_cast<Interface *>(ast->scope());
+ Interface *iface = static_cast<Interface *>(*scope);
if (!iface->addMethod($2)) {
std::cerr << "ERROR: Unable to add method '" << $2->name()
<< "' at " << @2 << "\n";
@@ -623,7 +634,7 @@
YYERROR;
}
if (parent == nullptr) {
- parent = ast->lookupType(gIBaseFqName);
+ parent = ast->lookupType(gIBaseFqName, *scope);
}
}
@@ -641,34 +652,43 @@
YYERROR;
}
- Interface *iface = new Interface($2, convertYYLoc(@2), static_cast<Interface *>(parent));
+ if (*scope != ast->getRootScope()) {
+ std::cerr << "ERROR: All interface must declared in "
+ << "global scope. at " << @2 << "\n";
+
+ YYERROR;
+ }
+
+ Interface* iface = new Interface(
+ $2, convertYYLoc(@2), *scope,
+ static_cast<Interface *>(parent));
// Register interface immediately so it can be referenced inside
// definition.
std::string errorMsg;
- if (!ast->addScopedType(iface, &errorMsg)) {
+ if (!ast->addScopedType(iface, &errorMsg, *scope)) {
std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
YYERROR;
}
- ast->enterScope(iface);
+ enterScope(ast, scope, iface);
}
'{' interface_declarations '}'
{
- if (!ast->scope()->isInterface()) {
+ if (!(*scope)->isInterface()) {
std::cerr << "ERROR: unknown error in interface declaration at "
<< @5 << "\n";
YYERROR;
}
- Interface *iface = static_cast<Interface *>(ast->scope());
+ Interface *iface = static_cast<Interface *>(*scope);
if (!iface->addAllReservedMethods()) {
std::cerr << "ERROR: unknown error in adding reserved methods at "
<< @5 << "\n";
YYERROR;
}
- ast->leaveScope();
+ leaveScope(ast, scope);
$$ = iface;
}
@@ -678,7 +698,7 @@
: TYPEDEF type valid_type_name
{
std::string errorMsg;
- if (!ast->addTypeDef($3, $2, convertYYLoc(@3), &errorMsg)) {
+ if (!ast->addTypeDef($3, $2, convertYYLoc(@3), &errorMsg, *scope)) {
std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
YYERROR;
}
@@ -699,7 +719,7 @@
}
if($1->isIdentifier()) {
std::string identifier = $1->name();
- LocalIdentifier *iden = ast->scope()->lookupIdentifier(identifier);
+ LocalIdentifier *iden = (*scope)->lookupIdentifier(identifier);
if(!iden) {
std::cerr << "ERROR: identifier " << $1->string()
<< " could not be found at " << @1 << ".\n";
@@ -714,7 +734,7 @@
*(static_cast<EnumValue *>(iden)->constExpr()), $1->string());
} else {
std::string errorMsg;
- EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg);
+ EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg, *scope);
if(v == nullptr) {
std::cerr << "ERROR: " << errorMsg << " at " << @1 << ".\n";
YYERROR;
@@ -810,17 +830,17 @@
named_struct_or_union_declaration
: struct_or_union_keyword valid_type_name
{
- CompoundType *container = new CompoundType($1, $2, convertYYLoc(@2));
- ast->enterScope(container);
+ CompoundType *container = new CompoundType($1, $2, convertYYLoc(@2), *scope);
+ enterScope(ast, scope, container);
}
struct_or_union_body
{
- if (!ast->scope()->isCompoundType()) {
+ if (!(*scope)->isCompoundType()) {
std::cerr << "ERROR: unknown error in struct or union declaration at "
<< @4 << "\n";
YYERROR;
}
- CompoundType *container = static_cast<CompoundType *>(ast->scope());
+ CompoundType *container = static_cast<CompoundType *>(*scope);
std::string errorMsg;
if (!container->setFields($4, &errorMsg)) {
@@ -828,9 +848,9 @@
YYERROR;
}
- ast->leaveScope();
+ leaveScope(ast, scope);
- if (!ast->addScopedType(container, &errorMsg)) {
+ if (!ast->addScopedType(container, &errorMsg, *scope)) {
std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
YYERROR;
}
@@ -860,8 +880,8 @@
| type valid_identifier require_semicolon
{
std::string errorMsg;
- if (ast->scope()->isCompoundType() &&
- static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT &&
+ if ((*scope)->isCompoundType() &&
+ static_cast<CompoundType *>(*scope)->style() == CompoundType::STYLE_STRUCT &&
!isValidStructField($2, &errorMsg)) {
std::cerr << "ERROR: " << errorMsg << " at "
<< @2 << "\n";
@@ -872,8 +892,8 @@
| annotated_compound_declaration ';'
{
std::string errorMsg;
- if (ast->scope()->isCompoundType() &&
- static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT &&
+ if ((*scope)->isCompoundType() &&
+ static_cast<CompoundType *>(*scope)->style() == CompoundType::STYLE_STRUCT &&
$1 != nullptr &&
$1->isNamedType() &&
!isValidStructField(static_cast<NamedType *>($1)->localName().c_str(), &errorMsg)) {
@@ -922,21 +942,21 @@
named_enum_declaration
: ENUM valid_type_name enum_storage_type
{
- ast->enterScope(new EnumType($2, convertYYLoc(@2), $3));
+ enterScope(ast, scope, new EnumType($2, convertYYLoc(@2), $3, *scope));
}
enum_declaration_body
{
- if (!ast->scope()->isEnum()) {
+ if (!(*scope)->isEnum()) {
std::cerr << "ERROR: unknown error in enum declaration at "
<< @5 << "\n";
YYERROR;
}
- EnumType *enumType = static_cast<EnumType *>(ast->scope());
- ast->leaveScope();
+ EnumType *enumType = static_cast<EnumType *>(*scope);
+ leaveScope(ast, scope);
std::string errorMsg;
- if (!ast->addScopedType(enumType, &errorMsg)) {
+ if (!ast->addScopedType(enumType, &errorMsg, *scope)) {
std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
YYERROR;
}
@@ -959,23 +979,23 @@
{ /* do nothing */ }
| enum_value
{
- if (!ast->scope()->isEnum()) {
+ if (!(*scope)->isEnum()) {
std::cerr << "ERROR: unknown error in enum declaration at "
<< @1 << "\n";
YYERROR;
}
- static_cast<EnumType *>(ast->scope())->addValue($1);
+ static_cast<EnumType *>(*scope)->addValue($1);
}
| enum_values ',' enum_value
{
- if (!ast->scope()->isEnum()) {
+ if (!(*scope)->isEnum()) {
std::cerr << "ERROR: unknown error in enum declaration at "
<< @3 << "\n";
YYERROR;
}
- static_cast<EnumType *>(ast->scope())->addValue($3);
+ static_cast<EnumType *>(*scope)->addValue($3);
}
;
@@ -1041,7 +1061,7 @@
| INTERFACE
{
// "interface" is a synonym of android.hidl.base@1.0::IBase
- $$ = ast->lookupType(gIBaseFqName);
+ $$ = ast->lookupType(gIBaseFqName, *scope);
if ($$ == nullptr) {
std::cerr << "ERROR: Cannot find "
<< gIBaseFqName.string()
diff --git a/main.cpp b/main.cpp
index b2c4dd9..08af509 100644
--- a/main.cpp
+++ b/main.cpp
@@ -293,7 +293,7 @@
if (fqName.name() == "types") {
CHECK(typesAST != nullptr);
- Scope *rootScope = typesAST->scope();
+ Scope* rootScope = typesAST->getRootScope();
std::vector<NamedType *> subTypes = rootScope->getSubTypes();
std::sort(
@@ -405,7 +405,7 @@
// We'll have to generate Java code if types.hal contains any non-typedef
// type declarations.
- Scope *rootScope = typesAST->scope();
+ Scope* rootScope = typesAST->getRootScope();
std::vector<NamedType *> subTypes = rootScope->getSubTypes();
for (const auto &subType : subTypes) {