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

[GAIAPLAT-672] Add type safety to connect/disconnect params #816

Merged
merged 14 commits into from
Aug 11, 2021

Conversation

simone-gaia
Copy link
Contributor

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

The purpose of this change is to make connect/disconnect be added to tables/links only when necessary and to accept only the appropriate parameter types.

  • Given a table, connect/disconnect are added for every unique outgoing link. Unique means that the given table has only one link with the target table thus connect/disconnect are known.
  • A field is added to the table for every outgoing link. Each of these fields will expose a connect/disconnect method with the appropriate type.
  • Dynamic types (table__type) are generated only once and reused when necessary.
  • GaiaFieldLValueAttr is no longer attached to the class declaration but to the variable declaration.
  • Simplified the parameter specification for the SemaGaia::addMethod method.

What is missing:

  • connect/disconnect do not accept EDC types
  • the whole gaiat stuff.

NB: This PR is kinda small, but it costed blood, sweat, and tears...

TC Link: http://segate2:8111/buildConfiguration/GaiaPlatform_ProductionGaiaLLVMTestsGdev/15037

QualType getLinkType(const std::string& linkName, const std::string& from_table, const std::string& to_table, SourceLocation loc);
void addMethod(IdentifierInfo *name, DeclSpec::TST retValType, SmallVector<QualType, 8> parameterTypes,
AttributeFactory &attrFactory, ParsedAttributes &attrs, RecordDecl *RD,
SourceLocation loc, bool isVariadic = false, ParsedType returnType = nullptr);
Copy link
Contributor

Choose a reason for hiding this comment

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

This line is indented differently from the one above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

}
if (memberExp != nullptr)
{
exp = dyn_cast<DeclRefExpr>(memberExp->getBase());
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't know the class relationships here, but can't exp be null after this statement? If it can't be, it would help to add an assert to that effect.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

According to the MemeberExpr constructor, it can't be (it would throw SegFault if Base was nullptr). There is setBase() method that can potentially allow to set it to nullptr. Not a problem for us since we check 11340 if exp != nullptr.

If exp == nullptr it is ok to skip the next if statement.

Copy link
Contributor

Choose a reason for hiding this comment

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

Base may be non nullptr but it may be not of DeclRefExpr type so dyn_cast may return nullptr

ValueDecl *decl = exp->getDecl();
if (exp == nullptr)
{
MemberExpr* memberExp = dyn_cast<MemberExpr>(E);
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these dyn_cast aliases for dynamic_cast or are they something different?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It has the same semantic but works differently, it does not require v-tables. https://stackoverflow.com/a/12083335/1214125.

It seems the standard across the LLVM/Clang codebase hence I'm sticking to it. I honestly don't know what is the advantage of not using v-tables, I assume is performance...

@@ -497,10 +499,39 @@ void Sema::addMethod(IdentifierInfo* name, DeclSpec::TST retValType, DeclaratorC

DS.Finish(*this, getPrintingPolicy());

SmallVector<DeclaratorChunk::ParamInfo, 8> paramsInfo;
Copy link
Contributor

@LaurentiuCristofor LaurentiuCristofor Aug 9, 2021

Choose a reason for hiding this comment

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

Can this 8 be declared as a constant/constexpr? That would help clarify its semantics too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought of that, but I noticed that it is not done anywhere in the LLVM/Clang codebase. Knowing how SmallVector works, you know it means that you expect at most 8 elements in the vector (which will be stack-allocated). If you add more elements they will be heap-allocated.

Copy link
Contributor

Choose a reason for hiding this comment

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

You will be filling a vector with data so it won't be able to declare it const

iter++)
{
NamedDecl* foundDecl = iter.getDecl();
classDeclaration = cast<TagDecl>(previousDeclLookup.getFoundDecl());
Copy link
Contributor

Choose a reason for hiding this comment

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

Given the widespread use of decl in this code, we should be consistent and avoid declaration altogether.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good.

@@ -1,27 +1,27 @@
CREATE DATABASE if not exists incubator;
create database if not exists incubator;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the original idea was to use uppercase for keywords and lowercase for user-specified values. That got broken when if not exists got added, but I still think it's a nicer SQL-style than having everything lowercase. Of course, we'd have to be consistent about it.

@vDonGlover : we probably want to define a SQL/DDL style and use it consistently across all our examples.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm fine with it, as long as we are consistent.

Copy link
Contributor

@LaurentiuCristofor LaurentiuCristofor left a comment

Choose a reason for hiding this comment

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

I can't follow the LLVM code logic, but I left some comments on some small issues. Perhaps the most important is deciding on a style to follow for DDL and SQL files (can be shared across both unless we decide to make our DDL fundamentally different from SQL).

@@ -2770,7 +2769,7 @@ class declarative_insert_handler_t : public MatchFinder::MatchCallback
}
replacement_string.resize(replacement_string.size() - 1);
replacement_string.append("))");
cerr<<replacement_string<<endl;
cerr << replacement_string << endl;
Copy link
Contributor

Choose a reason for hiding this comment

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

Hijacking this PR for a question: what error are we actually outputting here?

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe it is debug output that somehow slipped into merge. It is removed in the upcoming PR with bug fixes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, it seems a leftover debug line :D I'll remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, so I'll leave it there to not conflict with greg's changes.

@@ -4638,17 +4638,22 @@ class Sema {
bool IsExpressionInjected(const Expr* expression) const;
private:

// TODO we need to decide what style to use: PascalCase, camelCase, snake_case (we're using all of them now).
// TODO we need to decide what style to use: PascalCase, camelCase, snake_case (we're using all of them now).
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment can go away now, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well no, this is related to the convention used to name the actual methods within clang.

eg:

  NamedDecl *injectVariableDefinition(IdentifierInfo *II, SourceLocation loc, const std::string &explicitPath);
  std::string ParseExplicitPath(const std::string& pathString, SourceLocation loc);

....
  void addField(IdentifierInfo *name, QualType type, RecordDecl *R, SourceLocation locD) const ;
  void RemoveExplicitPathData(SourceLocation location);
  StringRef ConvertString(const std::string& str, SourceLocation loc);

Apparently, clang people realized it too that they messed it up wrt naming, and they are trying to fix it in the upcoming releases... We could start by being consistent ourselves..

if (S.getLangOpts().Gaia && S.getCurScope()->isInRulesetScope())
{
DeclRefExpr *exp = dyn_cast<DeclRefExpr>(E);
if (S.getLangOpts().Gaia && S.getCurScope()->isInRulesetScope())
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 are these spaces here? clang-format goof or just typos?

Copy link
Contributor Author

@simone-gaia simone-gaia Aug 9, 2021

Choose a reason for hiding this comment

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

We are not running .clang-format yet here, the indentation is manual (and was a little off, I fixed it here). We still need to re-activate the original LLVM .clang-format and apply it to the LLVM code...

{
// TODO we need a way to pass named params to have better diagnostics.
string paramName = "param_" + to_string(paramIndex);
ParmVarDecl* param = ParmVarDecl::Create(
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm guessing that breaking up params into two structures is an LLVM thing? I.e., for every param you have to have a separate info structure?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's one of those things I spent an entire week trying to understand, and honestly, I still don't. But let say that after reading and debugging clang I figured this is the way to go... :D

}
}


ruleset test_connect_disconnect_invalid_syntax
ruleset test_connect_disconnect_invalid_syntax_2
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm probably bllind but do you have a test case that has a valid method but passes an invalid type? I.e., trying to connect/disconnect the wrong table 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.

Whoopsy, I'm probably bllind -> "I'm definitely right" :D adding the tests.

// For every relationship target table we count how many links
// we have from tableName. This is needed to determine if we can
// have a connect/disconnect method for a given target type.
map<string, int> links_targets;
Copy link
Contributor

Choose a reason for hiding this comment

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

unordered_map should be slightly faster for your case

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.

@simone-gaia simone-gaia merged commit 9d75c4d into master Aug 11, 2021
@simone-gaia simone-gaia deleted the rondelli-conn-disconn-params-type branch August 11, 2021 15:04
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.

5 participants