Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for EDC types in connect/disconnect #827

Merged
merged 2 commits into from
Aug 12, 2021

Conversation

simone-gaia
Copy link
Contributor

@simone-gaia simone-gaia commented Aug 12, 2021

Add support for EDC types in connect/disconnect. If the EDC types are available (the user included the EDC headers) SemaGaia will generate overloads for the connect/disconnect to include EDC types:

  • bool incubator::connect(sensor__type&)
  • bool incubator::connect(sensor_t&)

Now it is possible to do farmer.incubators.connect(incubator.insert(name: "Zombies"));

Others:

  • Refactor code that adds connect/disconnect into its own Sema::addConnectDisconnect
  • Refactor code that lookup EDC types into Sema::lookupEDCClass

TODO:
farmer.incubators.connect(incubator.insert(name: "Zombies")); will not work if the EDC headers are not included, because of this "bug": https://gaiaplatform.atlassian.net/browse/GAIAPLAT-1167

/// Note: the lookup logic does not follow the Clang way of doing it (see lookupClass).
/// The class name will be searched everywhere regardless of the namespace. If the class
/// name appears multiple times in different namespaces the first occurrence is returned.
/// This is inline with the fact that the translation process is unaware of databases.
Copy link
Contributor

@daxhaw daxhaw Aug 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to tag this with a TODO comment and jira reference (GAIAPLAT-1028?) that if we want the translation engine to differentiate between multiple databases then we'll need to change this behavior. I've been using //TODO[GAIAPLAT-NNNN]... to mark code we need to revisit later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -676,6 +655,77 @@ TagDecl* Sema::lookupClass(std::string className, SourceLocation loc, Scope* sco
return classDecl;
}

TagDecl* Sema::lookupEDCClass(std::string className)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LLVM 101 for me: Do we not know the class type at this time? So you have to search by name? I naively though you could a) restrict the search based on whether the class inherited from edc_base_t and then b) compare the types directly instead of doing string matching. Since we're not doing a namespace lookup here, string matching should work but just curious why.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I understand the question. I'll try to answer.

(Greg may know better, I'll try to give my rough understanding of what is going on, happy to spend some time after the sync up to discuss further).

At this point of the compilation process, we are reading tokens from the input and try to give meaning to them (Sema). What happens is that we get strings and we need to decide what they are and either assigning them to an existing class (which we need to lookup) or creating a new class at runtime (table__type).

Given this ruleset:

on_update(farmer)
{
    cout << farmer.name << endl;
}

"farmer.name" is passed into the SemaGaia::injectVariableDefinition, where it is decided if it is a table reference (getTableType) or a field reference (getFieldType):

size_t dot_position = table.find('.');

if (dot_position != string::npos)
{
   //  Called passing the "farmer" string to getTableType which will call lookupEDCClass.
    qualType = getTableType(table.substr(0, dot_position), loc); <== CALL THIS
}
else
{
    qualType = getFieldType(table, loc);
}

Within the getTableType() we need to check if the EDC type for the farmer table is available. The EDC types may not be available at all if the EDC headers are not included (IMO this is a little wonky, one day we may force the user to include them or inject them).

The Clang way to lookup names (namespaces, function, variables, classes, etc..) is what we do here, which takes into consideration context, scope etc.. https://github.com/gaia-platform/GaiaPlatform/pull/827/files#diff-c6e8da967d5b43ad73a06e39e1d2acab7dcee01bdb9badbd5911b342c48e28d2R629-R656

// ....

auto& types = Context.getTypes();
for (unsigned typeIdx = 0; typeIdx != types.size(); ++typeIdx)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: why can't you just iterate directly over the llvm::SmallVectorImpl<clang::Type*> returned from Context.getTypes()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoopsy, that is indeed possible. Done.

targetTypes.push_back(implicitTargetTypeDecl);

// Lookup the EDC class type (table_t)
string edcTableTypeName = targetTableName + "_t";
Copy link
Contributor

@daxhaw daxhaw Aug 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A TODO[GAIAPLAT-1168] tag would be good here to remind us to update this code to look in the catalog for the typename instead of just assuming it will always be table + "_t". (I just entered GAIAPLAT-1168 as a placeholder for this - if you know of a better item already in Jira, feel free to use that one instead and then close this one. My brief Jira search didn't yield anything related to this, however).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. 100% agree.

targetTypes.push_back(edcTargetTypeDecl);
}

// Add connect/disconnect both for the implicit class and EDC class (if available).
Copy link
Contributor

@daxhaw daxhaw Aug 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, just to make sure I'm clear on this, the EDC class will not be available if:

  1. the rule author has not declared an EDC variable in their rule?
  2. the rule author has not included the EDC generated header in their ruleset
  3. both of the above
  4. none of the above and I should get the number of that truck driving school

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The types are introduced in include files. You don't have to declare anything to make compiler aware of a type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What Greg said.


// This won't work because of https://gaiaplatform.atlassian.net/browse/GAIAPLAT-1167
// the workaround is to have the raised_t type available.
// farmer.connect(raised.insert(birthdate: "2 Aug 1990"));
Copy link
Contributor

@daxhaw daxhaw Aug 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that you entered GAIAPLAT-1167 against V1. How hard would it be to fix for Preview? I realize that explicit connect/disconnect is lower-priority than getting autoconnect/disconnect to work so I understand your priority call on this but just wondering. This falls under the "do not violate the principle of least surprise" and then the "do not introduce another paper cut". The latter, of course, leads to "death by a thousand papercuts".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't do the research but likely a conversion function (similar to what was done to convert between generated types and EDC types) injection is required

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How hard would it be to fix for Preview?

I don't know, yesterday I spent a fair amount of time looking into it without getting anywhere. Probably we need to do what Greg is saying. I switched it to Preview and left the triage-todo label so that we can re-evaluate this decision in the next triaging meeting.

// convert incubator__type into incubator_t.
farmer.incubators.connect(incubator.insert(name: "Zombies"));

// Not putting any checks here because for some reason it does not work...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding your comment "it does not work" - is this a new issue or related to GAIAPLAT-1167?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated, it is likely due to my ignorance about the testing framework...

Copy link
Contributor

@daxhaw daxhaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine to me. My comments were mostly questions and a couple asking you to "tag" the code with JIRA item IDs so that we have breadcrumbs when we come back in V1 and support thins better.

@simone-gaia simone-gaia merged commit f9c32fe into master Aug 12, 2021
@simone-gaia simone-gaia deleted the rondelli-conn-disconn-edc branch August 12, 2021 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants