QList<const TopLevelDataInformation*> OsdParser::parseStructures() { QFileInfo fileInfo(mDir, mFile); QDomElement rootElem = mDocument.firstChildElement(QLatin1String("data")); parseEnums(); QList<const TopLevelDataInformation*> structures; QDomNodeList list = rootElem.childNodes(); for (uint i = 0; i < list.length(); ++i) { const QDomNode& n = list.at(i); QDomElement elem = n.toElement(); // try to convert the node to an element. if (elem.isNull()) continue; //e is element //kDebug() << "element tag: " << elem.tagName(); QString tag = elem.tagName(); DataInformation* data = parseNode(elem, 0); if (data) { TopLevelDataInformation* topData = new TopLevelDataInformation(data, fileInfo, mEngine, false); structures.append(topData); } else { kDebug() << "data == NULL -> could not parse node " << elem.tagName(); delete data; } } mFullyParsed = true; //however if this method is called again the result will not be cached return structures; }
AbstractEnumDataInformation* OsdParser::enumFromXML(const QDomElement& xmlElem, bool isFlags) { if (!mEnumsParsed) //not always needed parseEnums(); QString name = xmlElem.attribute(QLatin1String("name"), i18n("<invalid name>")); QString typeStr = xmlElem.attribute(QLatin1String("type"), QString()); if (typeStr.isEmpty()) { kWarning() << "no type attribute defined"; return NULL; } QString enumName = xmlElem.attribute(QLatin1String("enum"), QString()); if (enumName.isEmpty()) { kWarning() << "no enum attribute defined"; return NULL; } EnumDefinition::Ptr def = findEnum(enumName); if (!def) { kWarning() << "no enum with name " << enumName << "found."; return NULL; } PrimitiveDataInformation* prim = PrimitiveFactory::newInstance(name, typeStr); if (!prim) { kWarning() << "primitive type is null!!"; return NULL; } if (isFlags) return new FlagDataInformation(name, prim, def); else return new EnumDataInformation(name, prim, def); }
ClassDef MocNg::parseClass(clang::CXXRecordDecl* RD, clang::Sema& Sema) { clang::Preprocessor &PP = Sema.getPreprocessor(); ClassDef Def; Def.Record = RD; for (auto it = RD->decls_begin(); it != RD->decls_end(); ++it) { if (clang::StaticAssertDecl *S = llvm::dyn_cast<clang::StaticAssertDecl>(*it) ) { if (auto *E = llvm::dyn_cast<clang::UnaryExprOrTypeTraitExpr>(S->getAssertExpr())) if (clang::ParenExpr *PE = llvm::dyn_cast<clang::ParenExpr>(E->getArgumentExpr())) { llvm::StringRef key = S->getMessage()->getString(); if (key == "qt_property") { clang::StringLiteral *Val = llvm::dyn_cast<clang::StringLiteral>(PE->getSubExpr()); if (Val) { PropertyParser Parser(Val->getString(), // Val->getStrTokenLoc(0), Val->getLocationOfByte(0, PP.getSourceManager(), PP.getLangOpts(), PP.getTargetInfo()), Sema, Def.Record); Def.Properties.push_back(Parser.parseProperty()); Def.addExtra(Parser.Extra); } else { PP.getDiagnostics().Report(S->getLocation(), PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, "Invalid Q_PROPERTY annotation")); } } else if (key == "qt_private_property") { clang::StringLiteral *Val1 = nullptr, *Val2 = nullptr; std::tie(Val1, Val2) = ExtractLiterals(PE, PP, "Q_PRIVATE_PROPERTY", "Invalid Q_PRIVATE_PROPERTY annotation"); if (Val1 && Val2) { PropertyParser Parser(Val2->getString(), Val2->getLocationOfByte(0, PP.getSourceManager(), PP.getLangOpts(), PP.getTargetInfo()), Sema, Def.Record); PropertyDef P = Parser.parseProperty(true); P.inPrivateClass = Val1->getString(); Def.Properties.push_back(std::move(P)); Def.addExtra(Parser.Extra); } } else if (key == "qt_private_slot") { clang::StringLiteral *Val1 = nullptr, *Val2 = nullptr; std::tie(Val1, Val2) = ExtractLiterals(PE, PP, "Q_PRIVATE_SLOT", "Invalid Q_PRIVATE_SLOT annotation"); if (Val1 && Val2) { PropertyParser Parser(Val2->getString(), Val2->getLocationOfByte(0, PP.getSourceManager(), PP.getLangOpts(), PP.getTargetInfo()), Sema, Def.Record); PrivateSlotDef P = Parser.parsePrivateSlot(); P.InPrivateClass = Val1->getString(); if (!P.Name.empty()) { Def.PrivateSlotCount += P.NumDefault + 1; Def.PrivateSlots.push_back(std::move(P)); } } } else if (key == "qt_enums") { parseEnums(Def, false, PE->getSubExpr(), Sema); } else if (key == "qt_flags") { parseEnums(Def, true, PE->getSubExpr(), Sema); } else if (key == "qt_qobject") { Def.HasQObject = true; } else if (key == "qt_fake") { Def.HasQGadget = false; } else if (key == "qt_qgadget") { Def.HasQGadget = true; } else if (key == "qt_classinfo") { clang::StringLiteral *Val1 = nullptr, *Val2 = nullptr; std::tie(Val1, Val2) = ExtractLiterals(PE, PP, "Q_CLASSINFO", "Expected string literal in Q_CLASSINFO"); if (Val1 && Val2) { Def.ClassInfo.emplace_back(Val1->getString(), Val2->getString()); } } else if (key == "qt_interfaces") { parseInterfaces(Def, PE->getSubExpr(), Sema); } else if (key == "qt_plugin_metadata") { parsePluginMetaData(Def, PE->getSubExpr(), Sema); HasPlugin = true; } } } else if (clang::CXXMethodDecl *M = llvm::dyn_cast<clang::CXXMethodDecl>(*it)) { for (auto attr_it = M->specific_attr_begin<clang::AnnotateAttr>(); attr_it != M->specific_attr_end<clang::AnnotateAttr>(); ++attr_it) { const clang::AnnotateAttr *A = *attr_it; if (A->getAnnotation() == "qt_signal") { Def.Signals.push_back(M); } else if (A->getAnnotation() == "qt_slot") { Def.Slots.push_back(M); } else if (A->getAnnotation() == "qt_invokable" || A->getAnnotation() == "qt_scriptable" ) { if (auto *C = llvm::dyn_cast<clang::CXXConstructorDecl>(M)) { Def.Constructors.push_back(C); } else { Def.Methods.push_back(M); } } else if (A->getAnnotation().startswith("qt_revision:")) { Def.RevisionMethodCount++; } } } } //Check notify Signals for (PropertyDef &P: Def.Properties) { if (!P.notify.Str.empty()) { int Idx = 0; for (clang::CXXMethodDecl *MD : Def.Signals) { if (MD->getName() == P.notify.Str) { P.notify.notifyId = Idx; P.notify.MD = MD; break; } Idx += 1 + MD->getNumParams() - MD->getMinRequiredArguments(); } if (P.notify.notifyId < 0 ) { PP.getDiagnostics().Report(P.notify.Loc, PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, "NOTIFY signal '%0' of property '%1' does not exist in class %2")) << P.notify.Str << P.name << Def.Record; } else { Def.NotifyCount++; } } if (P.revision > 0) Def.RevisionPropertyCount++; } return Def; }