-
Notifications
You must be signed in to change notification settings - Fork 518
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
Parser.cpp: fix WalkType + many native bugs #1819
base: main
Are you sure you want to change the base?
Conversation
…ependentTemplateSpecialization
This PR partially fixes #1791, I am still in the process of debugging and fixing the general use case. |
Consider parsing: template <class...>
struct conjunction {};
template <class B>
struct conjunction<B> : B {}; The assertion fails when calling |
Tests in |
…emplateSpecialization
c96090f
to
4b6b3ca
Compare
@tritao Do you think we should refactor the if (LocValid)
{
// ...
TPT->parameter = WalkTypeTemplateParameter(TTTL.getDecl());
}
else if (TP->getDecl())
TPT->parameter = WalkTypeTemplateParameter(TP->getDecl()); |
9fa2c70
to
3a202a8
Compare
If possible yes, it would simplify the parser code a bit.
IIRC unless we used the |
Interesting because most of BTW I am having trouble parsing a relatively big project (without any processing, just parsing and AST generation), with around 650 header files, the process is crashing out of memory (consuming up to 15GB). Is there a way to let clang ignore function bodies? |
Is this in debug or release mode? Are you using the unity header parsing or just header by header parsing? I think QtSharp enabled unity mode, you can check it here: https://gitlab.com/ddobrev/QtSharp |
I am not using |
Since it parses all the headers as a single translation unit, it can be significantly faster than parsing header by header, at the cost of a bit more memory usage. |
I can't afford any more memory. I tried This commit closes #1791, now will keep this PR active, to add tests and fix the one remaining bug in tests which causes crashing in Debug mode. |
I would try to understand what's going on with that particular project, it must be generating a ton of unnecessary garbage. First figure out how much memory parsing with Clang takes, then figure out how much memory we allocate when processing Clang AST, then drill down from there. |
Well I am trying to parse this game engine rbfx, which gets parsed with clang json dump within few minutes, and relatively slow with |
Cool, I actually developed a prototype C# binding for Urho3D with CppSharp many years ago, so it was definitely parseable back then. Also @rokups (from rbfx) contributed a few fixes at the time to CppSharp: https://github.com/mono/CppSharp/commits?author=rokups I would try unity build just in case it helps. |
I will try for sure. |
@tritao I tried adding a test, but because the C++17 requirement for deduction guides, a new bug is being introduced when adding C++17 compiler flag. The following tests are not ignoring the default argument in the C# generator: void defaultNonEmptyCtor(QGenericArgument arg = QGenericArgument(0));
void defaultNonEmptyCtorWithNullPtr(QGenericArgument arg = QGenericArgument(nullptr)); // DEBUG: void defaultNonEmptyCtor(QGenericArgument arg = QGenericArgument(0))
public void DefaultNonEmptyCtor(global::CSharp.QGenericArgument arg = 0)
{
var ____arg0 = arg.__Instance;
var __arg0 = new __IntPtr(&____arg0);
__Internal.DefaultNonEmptyCtor(__Instance, __arg0);
}
// DEBUG: void defaultNonEmptyCtorWithNullPtr(QGenericArgument arg = QGenericArgument(nullptr))
public void DefaultNonEmptyCtorWithNullPtr(global::CSharp.QGenericArgument arg = nullptr)
{
var ____arg0 = arg.__Instance;
var __arg0 = new __IntPtr(&____arg0);
__Internal.DefaultNonEmptyCtorWithNullPtr(__Instance, __arg0);
} Original valid results were: // DEBUG: void defaultNonEmptyCtor(QGenericArgument arg = QGenericArgument(0))
public void DefaultNonEmptyCtor(global::CSharp.QGenericArgument arg)
{
var ____arg0 = arg.__Instance;
var __arg0 = new __IntPtr(&____arg0);
__Internal.DefaultNonEmptyCtor(__Instance, __arg0);
}
// DEBUG: void defaultNonEmptyCtorWithNullPtr(QGenericArgument arg = QGenericArgument(nullptr))
public void DefaultNonEmptyCtorWithNullPtr(global::CSharp.QGenericArgument arg)
{
var ____arg0 = arg.__Instance;
var __arg0 = new __IntPtr(&____arg0);
__Internal.DefaultNonEmptyCtorWithNullPtr(__Instance, __arg0);
} I am not sure which pass is responsible for such modifications, so I can debug further. |
Is public void DefaultNonEmptyCtor(global::CSharp.QGenericArgument arg)
{
var ____arg0 = arg.__Instance;
var __arg0 = new __IntPtr(&____arg0);
__Internal.DefaultNonEmptyCtor(__Instance, __arg0);
}
public void DefaultNonEmptyCtor()
{
var ____arg0 = arg.__Instance;
__Internal.DefaultNonEmptyCtor(__Instance);
} Edit:By the way, I noticed that:
Edit2:Indeed public void DefaultNonEmptyCtor()
{
DefaultNonEmptyCtor(new global::CSharp.QGenericArgument());
} But in my own experience, I would've preferred to generate a matching Edit2:After a bit of debugging: I found that in: void defaultNonEmptyCtor(QGenericArgument arg = QGenericArgument(0));
|
After further debugging, I found out that
|
Nice debugging, that sounds like an annoying issue. So should I merge this one right away, assuming we fix this new C++17 issue at a later stage? |
The solution that will solve the default arguments forever is to:
Then we can close this PR and the related open issue, and later improve the Edit:Just to add an extra notice, |
Again after a lot of digging, and been learning many new conventions along the way, fixing the whole problem with overload generation alone won't be that trivial as it will introduces new constraints which are hard to mitigate considering the current implementation.
Unfortunately, our best bet will be on 1 currently. |
Hey mate, how is progress, still working on this? |
@tritao, basically this PR is valid, but I am having hard time deciding how to fix |
Consider this snippet from the standard string library on msvc, without skipping private declarations:
In Debug mode,
Parser::WalkType
assertion fails:assert(TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization);
The actual
TypeLoc
is:TL->getTypeLocClass() == TypeLoc::TemplateSpecialization
.There are also other problems when
TypeLocClass == TypeLoc::Qualified
and the innerTypeLoc == TypeLoc::Elaborated
.By the way, why the need of
TypeLoc
in the API at all? Haven't seen its usage.