Skip to content

Commit

Permalink
Allow NOTIFY signals defined in parent classes
Browse files Browse the repository at this point in the history
Implemented in Qt 5.10 by commit 2ca187caa383ddc0cdebeb1dbc312405c8c871ad
  • Loading branch information
ogoffart committed Jul 5, 2017
1 parent 7d73e99 commit de725af
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
14 changes: 10 additions & 4 deletions src/generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1074,12 +1074,12 @@ void Generator::GenerateStaticMetaCall()
} else if (!p.member.empty()) {
std::string M = Prefix + p.member;
std::string A = "*reinterpret_cast< " + p.type + "*>(_a[0])";
if (p.notify.notifyId >= 0) {
if (!p.notify.Str.empty()) {
OS_TemplateHeader << "\n"
" if (" << M << " != " << A << ") {\n"
" " << M << " = " << A << ";\n"
" Q_EMIT _t->" << p.notify.Str << "(";
if (p.notify.MD->getMinRequiredArguments() > 0)
if (p.notify.MD && p.notify.MD->getMinRequiredArguments() > 0)
OS_TemplateHeader << M;
OS_TemplateHeader << ");\n"
" } ";
Expand Down Expand Up @@ -1234,7 +1234,7 @@ void Generator::GenerateProperties()
flags |= ResolveUser;
else if (p.user != "false")
flags |= User;
if (p.notify.notifyId != -1)
if (!p.notify.Str.empty())
flags |= Notify;
if (p.revision > 0)
flags |= Revisioned;
Expand All @@ -1249,7 +1249,13 @@ void Generator::GenerateProperties()
if(CDef->NotifyCount) {
OS << "\n // properties: notify_signal_id\n";
for (const PropertyDef &P : CDef->Properties) {
OS << " " << std::max(0, P.notify.notifyId) << ",\n";
if (P.notify.notifyId >= 0) {
OS << " " << P.notify.notifyId << ",\n";
} else if (!P.notify.Str.empty()) {
OS << " 0x70000000 | " << StrIdx(P.notify.Str) << ",\n";
} else {
OS << " 0,\n";
}
}
}

Expand Down
39 changes: 35 additions & 4 deletions src/mocng.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ ClassDef MocNg::parseClass(clang::CXXRecordDecl* RD, clang::Sema& Sema)
for (PropertyDef &P: Def.Properties) {
if (!P.notify.Str.empty()) {
int Idx = 0;
auto errorLevel = clang::DiagnosticsEngine::Error;
for (clang::CXXMethodDecl *MD : Def.Signals) {
if (MD->getName() == P.notify.Str) {
P.notify.notifyId = Idx;
Expand All @@ -458,13 +459,43 @@ ClassDef MocNg::parseClass(clang::CXXRecordDecl* RD, clang::Sema& Sema)
Idx += 1 + MD->getNumParams() - MD->getMinRequiredArguments();
}
if (P.notify.notifyId < 0 ) {
// Search in base classes
clang::CXXRecordDecl *Base = Def.Record;
do {
if (!Base->getNumBases())
break;
Base = Base->bases_begin()->getType()->getAsCXXRecordDecl();
if (!Base)
break;
for (auto it = Base->decls_begin(); it != Base->decls_end(); ++it) {
if (auto *MD = llvm::dyn_cast<clang::CXXMethodDecl>(*it)) {

if (MD->getIdentifier() && MD->getName() == P.notify.Str) {
// We found a possible match. Check if it is indeed a signal
if (std::any_of(MD->specific_attr_begin<clang::AnnotateAttr>(),
MD->specific_attr_end<clang::AnnotateAttr>(),
[&](const clang::AnnotateAttr *a) {
return a->getAnnotation() == "qt_signal";
})) {
P.notify.MD = MD;
break;
}
// Since the official moc let this compile and the runtime will show
// a warning, we just change the level to Warning.
// (required for tst_qmetaobject which tests that)
errorLevel = clang::DiagnosticsEngine::Warning;
}
}
}
} while(!P.notify.MD);
}
if (!P.notify.MD) {
PP.getDiagnostics().Report(P.notify.Loc,
PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
"NOTIFY signal '%0' of property '%1' does not exist in class %2"))
PP.getDiagnostics().getCustomDiagID(errorLevel,
"NOTIFY signal '%0' of property '%1' does not exist in class %2"))
<< P.notify.Str << P.name << Def.Record;
} else {
Def.NotifyCount++;
}
Def.NotifyCount++;
}

if (P.revision > 0)
Expand Down

0 comments on commit de725af

Please sign in to comment.