Summary: | Extend C++ import for C++11 | ||
---|---|---|---|
Product: | [Applications] umbrello | Reporter: | Mark Stanton <mark> |
Component: | general | Assignee: | Umbrello Development Group <umbrello-devel> |
Status: | CONFIRMED --- | ||
Severity: | wishlist | CC: | bzk0711, milasudril, okellogg, ralf.habacker |
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Fedora RPMs | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
Mark Stanton
2014-08-29 11:10:03 UTC
I should have added "C++" to import, sorry. (In reply to Mark Stanton from comment #1) > I should have added "C++" to import, sorry. Changing the title accordingly. BTW, Umbrello's C++ import does not yet support C++11. How about rephrasing the PR as a wish, e.g. "Extend C++ import for C++11" or so. Is anyone working on this? I really start liking with umbrello right now, however having the import not working for this C++11 codebase is kind of a bummer. I might try to look into it if noone does already, and I find the time.. Aside question: Will I be able to continuously sync my umbrello representation by reimporting changes sources? *** Bug 357372 has been marked as a duplicate of this bug. *** I thought libclang would be usable. This way, new features would already be implemented there. (In reply to milasudril from comment #5) > I thought libclang would be usable. This way, new features would already be implemented there. It may be usable, but noone has opened a working branch and tried to implement this until now. Umbrello always used a copy of the kdevelop c++ parser in the past and it seem to be the easiest to also reuse the clang based c++ language plugin from kdevelop (see https://techbase.kde.org/Projects/KDevelop4/ClangRoadmap#Why_Clang) Some of the Issues which need to be solved are: 1. umbrello needs to be refactored for running kdevelop clang language plugin 2. clang AST is completly different from kdevelop's c++ parser AST, which requires a rewrite of the AST to uml model binding (currently cpp2uml.cpp) 3. The recently used parser is very tolerant against incomplete c++ code, which is not the case for clang, which needs to be called similar to a compiler building the related source code. Incomplete code may come from missing include pathes or defines only available inside the build system of the imported source code files. This may require to run the parser similar to the coverity scan tools, which runs on top of a configured build system. Links: http://milianw.de/blog/katekdevelop-sprint-2014-let-there-be-clang http://llvm.org/devmtg/2015-04/slides/Funk_Libclang_Integration_KDevelop.pdf (In reply to Ralf Habacker from comment #6) > 3. The recently used parser is very tolerant against incomplete c++ code, > which is not the case for clang, which needs to be called similar to a > compiler building the related source code. Incomplete code may come from > missing include pathes or defines only available inside the build system of > the imported source code files. This may require to run the parser similar > to the coverity scan tools, which runs on top of a configured build system. If someone will give it a try: For cmake based projects on linux the following receipt can be used to get an AST (based on the hints at http://clang.llvm.org/docs/LibTooling.html) 1. unpack umbrello source into <umbrello-source-dir> 2. mkdir <umbrello-build-dir> 3. cd <umbrello-build-dir> 4. CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON <umbrello-source-dir> 5. run clang-check -ast-dump -p $PWD <umbrello-source-dir>/umbrello/umlscene.cpp TranslationUnitDecl 0xf54940 <<invalid sloc>> |-TypedefDecl 0xf54e80 <<invalid sloc>> __int128_t '__int128' |-TypedefDecl 0xf54ee0 <<invalid sloc>> __uint128_t 'unsigned __int128' |-TypedefDecl 0xf552a0 <<invalid sloc>> __builtin_va_list '__va_list_tag [1]' |-TypedefDecl 0xf55390 </usr/bin/../lib64/clang/3.3/include/stddef.h:34:1, col:26> ptrdiff_t 'long' |-TypedefDecl 0xf553f0 <line:42:1, col:23> size_t 'unsigned long' |-TypedefDecl 0xf55450 </usr/include/QtCore/qglobal.h:1044:1, col:21> qint8 'signed char' ..... On 01/03/2016 01:01 AM, Ralf Habacker via KDE Bugzilla wrote:
> ...clang, which needs to be called similar to a compiler
> building the related source code
I actually see this as a major problem. Requiring people to have a full build set up would severely limed the usefulness of the tool. I might not even have complete sourcetree available, but just get a bunch of related cpp files from "somewhere" (a collaborator, some old project which no longer builds, ...) and want to import the classes into umbrello.
If this is a basic limitation to using clang, is this really the way the project should go? Maybe it is possible to separate only the parser parts without the whole semantics and error checking from clang? I have no idea about clang internals I must say.
An alternative could be using some parser generator such as antlr or bison to get a syntax tree? I looked around (for maybe half an hour) some weeks ago but it seemed there is nothing yet which would properly parse c++11/14 syntax..
(In reply to Patric Schmitz from comment #8) > On 01/03/2016 01:01 AM, Ralf Habacker via KDE Bugzilla wrote: > > ...clang, which needs to be called similar to a compiler > > building the related source code > > I actually see this as a major problem. Requiring people to have a full > build set up would severely limed the usefulness of the tool. I might not > even have complete sourcetree available, but just get a bunch of related cpp > files from "somewhere" (a collaborator, some old project which no longer > builds, ...) and want to import the classes into umbrello. This is the advantage of the recent parser :-) From recent observations at least all related classes should not be undefined. Here is a simple example with llvm 3.7: 1. Variant class QFont; class Test { public: Test(QFont *font) : m_font(font) {} QFont *m_font; }; running 'clang-check test1.cpp -ast-dump --' returns TranslationUnitDecl 0xb75da0 <<invalid sloc>> <invalid sloc> |-TypedefDecl 0xb762d8 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128' |-TypedefDecl 0xb76338 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128' |-TypedefDecl 0xb76718 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]' |-CXXRecordDecl 0xb76768 </home/ralf/src/umbrello-master/unittests/test.cpp:2:1, col:7> col:7 referenced class QFont `-CXXRecordDecl 0xb76820 <line:4:1, line:10:1> line:4:7 class Test definition |-CXXRecordDecl 0xb76930 <col:1, col:7> col:7 implicit referenced class Test |-AccessSpecDecl 0xb769c0 <line:5:1, col:7> col:1 public |-CXXConstructorDecl 0xbc2060 <line:6:5, col:39> col:5 Test 'void (class QFont *)' | |-ParmVarDecl 0xb76a28 <col:10, col:17> col:17 used font 'class QFont *' | |-CXXCtorInitializer Field 0xbc2138 'm_font' 'class QFont *' | | `-ImplicitCastExpr 0xbc2200 <col:32> 'class QFont *' <LValueToRValue> | | `-DeclRefExpr 0xbc21a8 <col:32> 'class QFont *' lvalue ParmVar 0xb76a28 'font' 'class QFont *' | `-CompoundStmt 0xbc2248 <col:38, col:39> `-FieldDecl 0xbc2138 <line:8:5, col:12> col:12 m_font 'class QFont *' -> no errors, complete AST 2. variant, using incomplete class QFont class QFont; class Test { public: Test(const &QFont font) : m_font(font) {} QFont m_font; }; running 'clang-check test2.cpp -ast-dump --' returns TranslationUnitDecl 0x15afda0 <<invalid sloc>> <invalid sloc> |-TypedefDecl 0x15b02d8 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128' |-TypedefDecl 0x15b0338 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128' |-TypedefDecl 0x15b0718 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]' |-CXXRecordDecl 0x15b0768 </home/ralf/src/umbrello-master/unittests/test.cpp:2:1, col:7> col:7 referenced class QFont `-CXXRecordDecl 0x15b0820 <line:4:1, line:11:1> line:4:7 invalid class Test definition |-CXXRecordDecl 0x15b0930 <col:1, col:7> col:7 implicit referenced class Test |-AccessSpecDecl 0x15b09c0 <line:5:1, col:7> col:1 public |-CXXConstructorDecl 0x15fc060 <line:6:5, col:45> col:5 invalid Test 'void (const int &)' | |-ParmVarDecl 0x15b0a30 <col:10, col:17> col:17 used invalid QFont 'const int &' | `-CompoundStmt 0x15fc618 <col:44, col:45> `-FieldDecl 0x15fc4c0 <line:9:5, col:11> col:11 invalid m_font 'class QFont' > 4 errors generated, incomplete AST. > If this is a basic limitation to using clang, is this really the way the project should go? > Maybe it is possible to separate only the parser parts without the whole semantics and error checking from clang? I don' know yet; it need to be evaluated > An alternative could be using some parser generator such as antlr or bison > to get a syntax tree? In theory yes, but ... > I looked around (for maybe half an hour) some weeks ago > but it seemed there is nothing yet which would properly parse c++11/14 syntax. switching to such a generated parser requires refactoring (=new write) of the parsed output to UML model mapping. The third alternative is to extend the recent parser, which is not very complicated. It has good debugging support (see category 'cppparser' in debug dock window) . [1] Beside the parser stuff there is the need to design how these features should be mapped to the UML model. As an example there is the question how 'constexpr' (https://en.wikipedia.org/wiki/C%2B%2B11#constexpr_.E2.80.93_Generalized_constant_expressions) should be modeled ? Should it be modeled as stereotype 'constexpr', which requires only little refactoring on cpp import/codegeneration (setup stereotype after creating UMLOperation instance and write out 'constexpr' depending on presence of 'constexpr' stereotype) or as operation attribute similar to 'static', which requires extending the class UMLOperation (setter/getter,xmi save/load, property dialog). [1] According to the given example there it is only required to add a new lexer token TOKEN_const_expr and to extend CppTree2Uml::parseFunctionDefinition() to be able to setup the related UMLOperation instance. My proposal for an implementation of this feature is 1. Design how the related C+11 features at https://en.wikipedia.org/wiki/C%2B%2B11 should be modeled in umbrello 2. Implement the required changes in the UML model and properties dialogs 3. Create test cases from the code fragments at https://en.wikipedia.org/wiki/C%2B%2B11 and extend the related lexer, parser and parser stuff. >> If this is a basic limitation to using clang, is this really the way the project should go? >> Maybe it is possible to separate only the parser parts without the whole semantics and error checking from clang? > I don' know yet; it need to be evaluated It seems that clang itself has no means of parsing incomplete code fragments and will fail to produce a syntax tree at all if not all types and symbols can be resolved. This is at least what I get out of this post from Clang Developers: > http://clang-developers.42468.n3.nabble.com/Lenient-lexing-parsing-of-code-snippets-td4042786.html There is a GSoC 2014 project mentioned where someone has a similar requirement (for syntax highlighting). Maybe we could look into that, it seems a fuzzy parser has been developed for that project. However I assume we would end up with something comparable to what KDevelop has right now, and could probably also extend the current parser to account for 11/14. >> An alternative could be using some parser generator... > ... > The third alternative is to extend the recent parser, which is not very > complicated. It has good debugging support (see category 'cppparser' in debug > dock window) . [1] Probably the most reasonable way to go about it after all? > Beside the parser stuff there is the need to design how these features should > be mapped to the UML model. > As an example there is the question how 'constexpr' > (https://en.wikipedia.org/wiki/C%2B%2B11#constexpr_.E2.80.93_Generalized_constant_expressions) > should be modeled ? Hmm in the case of constexpr I don't see why one would want to model this at all. It is a very specific C++ language feature after all and does not really have an equivalent in the UML standard, no? (I don't know either perfectly so I'm not entirely sure about this). (In reply to Patric Schmitz from comment #10) > >> If this is a basic limitation to using clang, is this really the way the project should go? > >> Maybe it is possible to separate only the parser parts without the whole semantics and error checking from clang? > > I don' know yet; it need to be evaluated > > It seems that clang itself has no means of parsing incomplete code fragments > and will fail to produce a syntax tree at all if not all types and symbols > can be resolved. This is at least what I get out of this post from Clang > Developers: > > http://clang-developers.42468.n3.nabble.com/Lenient-lexing-parsing-of-code-snippets-td4042786.html > There is a GSoC 2014 project mentioned where someone has a similar > requirement (for syntax highlighting). Maybe we could look into that, it > seems a fuzzy parser has been developed for that project. here is the related git repo https://github.com/kapf/clang-highlight and a test case https://github.com/kapf/clang-highlight/blob/master/unittests/FuzzyParseTest.cpp (In reply to Patric Schmitz from comment #10) > >> If this is a basic limitation to using clang, is this really the way the project should go? > > Probably the most reasonable way to go about it after all? For now yes Doxygen has an option for CLANG_ASSISTED_PARSING since version 1.8.4. Git commit 2de8b562409f8d502d0efe27c316e6ca4e2df1c8 by Ralf Habacker. Committed on 28/05/2016 at 12:52. Pushed by habacker into branch 'master'. Add llvm test case. M +19 -0 unittests/CMakeLists.txt A +29 -0 unittests/TEST_llvm.cpp [License: UNKNOWN] * The files marked with a * at the end have a non valid license. Please read: http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page. http://commits.kde.org/umbrello/2de8b562409f8d502d0efe27c316e6ca4e2df1c8 Git commit d14553de1c33f9f087baa0d59d41223738eaa5d7 by Ralf Habacker. Committed on 30/05/2016 at 21:30. Pushed by habacker into branch 'master'. Add missing license header. M +19 -0 unittests/TEST_llvm.cpp http://commits.kde.org/umbrello/d14553de1c33f9f087baa0d59d41223738eaa5d7 Git commit 13a513d629e86e8cc98d750f1d9e5741bbc8791a by Ralf Habacker. Committed on 09/09/2016 at 05:34. Pushed by habacker into branch 'master'. Add c++11 code import test cases. A +14 -0 test/import/cxx/cxx11-alternative-function-syntax.h [License: UNKNOWN] * A +1 -0 test/import/cxx/cxx11-constexpr.cpp [License: Trivial file] A +9 -0 test/import/cxx/cxx11-constexpr.h [License: UNKNOWN] * A +24 -0 test/import/cxx/cxx11-explicit-overrides-and-final.h [License: UNKNOWN] * A +4 -0 test/import/cxx/cxx11-extern-template.h [License: UNKNOWN] * A +21 -0 test/import/cxx/cxx11-initializer-lists.h [License: UNKNOWN] * A +4 -0 test/import/cxx/cxx11-lambda-functions-and-expressions.h [License: UNKNOWN] * A +9 -0 test/import/cxx/cxx11-null-pointer-constant.h [License: UNKNOWN] * A +32 -0 test/import/cxx/cxx11-object-construction-improvement.h [License: UNKNOWN] * A +12 -0 test/import/cxx/cxx11-range-based-for-loop.h [License: UNKNOWN] * A +22 -0 test/import/cxx/cxx11-strongly-typed-enumerations.h [License: UNKNOWN] * A +29 -0 test/import/cxx/cxx11-type-inference.h [License: UNKNOWN] * A +31 -0 test/import/cxx/cxx11-uniform-initialization.h [License: UNKNOWN] * The files marked with a * at the end have a non valid license. Please read: http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page. http://commits.kde.org/umbrello/13a513d629e86e8cc98d750f1d9e5741bbc8791a umbrello's git master branch got several c++11 related test cases. If someone has interest in umbrello having c++11 support feel free to extend the c++ parser and send patches one by one to this bug or kde review board. The parser is located at lib/cppparser/parser.cpp|h. If it is required to add additional abstract syntax tree classes, see lib/cppparser/ast.cpp|h. After parsing it may be required to assign the newly parsed elements to related uml objects in umbrello/codeimport/kdevcppparser/cpptree2uml.cpp|h Any update on this task? Git commit 464c7132349e4cf10a84fc9e6f3792087a934158 by Oliver Kellogg. Committed on 30/04/2021 at 19:11. Pushed by okellogg into branch 'release/21.04'. Support C++11 "enum class" in C++ Import: lib/cppparser/ast.{h,cpp} class EnumSpecifierAST - Add functions setClass, isClass accessing new member m_isClass of type bool. - Add functions setEnumBase, enumBase accessing new member m_enumBase of type TypeSpecifierAST::Node. lib/cppparser/parser.cpp function parseEnumSpecifier - Add bool isClass initialized to false. - After consuming Token_enum add int tk initialized to m_lexer->lookAhead(0). - If tk is Token_class or Token_struct then set isClass true and call nextToken(). - After call to parseName(name) add variable enumBase of type TypeSpecifierAST::Node. - If m_lexer->lookAhead(0) is ':' then call nextToken() followed by parseSimpleTypeSpecifier(enumBase). - Reassign tk from m_lexer->lookAhead(0) and permit only ';' or '{' as its value. - Remove call to nextToken(), it is postponed to after the assignments to `ast'. - At assignments to `ast' call ast->setClass(isClass) and ast->setEnumBase(enumBase). test/import/cxx/cxx11-strongly-typed-enumerations.h - Rename second definition of Enum2,Enum3 to Enum4,Enum5 to avoid overlap. M +12 -0 lib/cppparser/ast.cpp M +12 -0 lib/cppparser/ast.h M +40 -20 lib/cppparser/parser.cpp M +5 -4 test/import/cxx/cxx11-strongly-typed-enumerations.h https://invent.kde.org/sdk/umbrello/commit/464c7132349e4cf10a84fc9e6f3792087a934158 (In reply to milasudril from comment #18) > Any update on this task? A added support for C++11 "enum class" and it is working in a Qt4 based build. However, on trying to import https://invent.kde.org/sdk/umbrello/-/blob/master/test/import/cxx/cxx11-strongly-typed-enumerations.h in a Qt5 based build I get a crash: Application: Umbrello UML Modeller (umbrello5), signal: Aborted Content of s_kcrashErrorMessage: [Current thread is 1 (Thread 0x7fc078f12e80 (LWP 9736))] [KCrash Handler] #6 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49 #7 0x00007fc07c02c864 in __GI_abort () at abort.c:79 #8 0x00007fc07c60b10b in qt_message_fatal (message=<synthetic pointer>..., context=...) at global/qlogging.cpp:1914 #9 QMessageLogger::fatal(char const*, ...) const (this=this@entry=0x7fff14653b78, msg=msg@entry=0x7fc07c90aea0 "ASSERT: \"%s\" in file %s, line %d") at global/qlogging.cpp:893 #10 0x00007fc07c60a558 in qt_assert(char const*, char const*, int) (assertion=<optimized out>, file=<optimized out>, line=<optimized out >) at global/qglobal.cpp:3358 #11 0x00000000007b9354 in Lexer::getOffset(QChar const*) const (this=0x7fff14654468, p=0x1852138) at /tools/umbrello-master/lib/cppparse r/lexer.h:265 #12 0x00000000007bb835 in Lexer::currentPosition() const (this=0x7fff14654468) at /tools/umbrello-master/lib/cppparser/lexer.h:853 #13 0x00000000007b4845 in Lexer::nextToken(Token&, bool) (this=0x7fff14654468, tk=..., stopOnNewline=false) at /tools/umbrello-master/li b/cppparser/lexer.cpp:255 #14 0x00000000007b660e in Lexer::tokenize() (this=0x7fff14654468) at /tools/umbrello-master/lib/cppparser/lexer.cpp:497 #15 0x00000000007b3e93 in Lexer::setSource(QString const&) (this=0x7fff14654468, source=...) at /tools/umbrello-master/lib/cppparser/lex er.cpp:143 #16 0x00000000007ab000 in Driver::ParseHelper::ParseHelper(QString const&, bool, Driver*, bool, QString) (this=0x7fff14654420, fileName= ..., force=false, driver=0x10c0260, reportMessages=true, includedFrom=...) at /tools/umbrello-master/lib/cppparser/driver.cpp:321 #17 0x00000000007a0ebc in Driver::parseFile(QString const&, bool, bool, bool) (this=0x10c0260, fileName=..., onlyPreProcess=false, force =false, macrosGlobal=false) at /tools/umbrello-master/lib/cppparser/driver.cpp:555 #18 0x0000000000777b8e in CppImport::parseFile(QString const&) (this=0x15e51d0, fileName=...) at /tools/umbrello-master/umbrello/codeimp ort/cppimport.cpp:145 #19 0x0000000000776edd in ClassImport::importFile(QString const&) (this=0x15e51d0, fileName=...) at /tools/umbrello-master/umbrello/code import/classimport.cpp:120 #20 0x000000000050c44c in CodeImpThread::run() (this=0x10cb250) at /tools/umbrello-master/umbrello/codeimpwizard/codeimpthread.cpp:62 #21 0x0000000000509d8d in CodeImpStatusPage::importCodeFile(bool) (this=0x7fc07000d050, noError=true) at /tools/umbrello-master/umbrello /codeimpwizard/codeimpstatuspage.cpp:192 #22 0x00000000005098a9 in CodeImpStatusPage::importCode() (this=0x7fc07000d050) at /tools/umbrello-master/umbrello/codeimpwizard/codeimp statuspage.cpp:161 #23 0x0000000000479103 in CodeImpStatusPage::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=0x7fc07000d050, _c=QMetaOb ject::InvokeMetaMethod, _id=0, _a=0x7fff14654a40) at /tools/umbrello-master/build/umbrello/libumbrello_autogen/6MVZBMHENV/moc_codeimpsta tuspage.cpp:114 #24 0x00007fc07c85fc50 in doActivate<false>(QObject*, int, void**) (sender=0x1734400, signal_index=9, argv=argv@entry=0x7fff14654a40) at kernel/qobject.cpp:3898 #25 0x00007fc07c858f60 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x1734400, m=m@entry=0x7 fc07d99f4e0 <QAbstractButton::staticMetaObject>, local_signal_index=local_signal_index@entry=2, argv=argv@entry=0x7fff14654a40) at kerne l/qobject.cpp:3946 #26 0x00007fc07d5736a2 in QAbstractButton::clicked(bool) (this=this@entry=0x1734400, _t1=<optimized out>) at .moc/moc_qabstractbutton.cp p:308 #27 0x00007fc07d57391a in QAbstractButtonPrivate::emitClicked() (this=0x1734440) at widgets/qabstractbutton.cpp:415 #28 0x00007fc07d575970 in QAbstractButtonPrivate::click() (this=0x1734440) at widgets/qabstractbutton.cpp:408 #29 0x00007fc07d575b91 in QAbstractButton::mouseReleaseEvent(QMouseEvent*) (this=0x1734400, e=0x7fff14654fc0) at widgets/qabstractbutton .cpp:1044 #30 0x00007fc07d4c1b4e in QWidget::event(QEvent*) (this=0x1734400, event=0x7fff14654fc0) at kernel/qwidget.cpp:9019 #31 0x00007fc07d47faff in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=this@entry=0xbbfc00, receiver=receiver@entry=0x173 4400, e=e@entry=0x7fff14654fc0) at kernel/qapplication.cpp:3632 #32 0x00007fc07d4870cb in QApplication::notify(QObject*, QEvent*) (this=0x7fff14654cf0, receiver=0x1734400, e=0x7fff14654fc0) at kernel/ qapplication.cpp:3076 #33 0x00007fc07c82913a in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x1734400, event=0x7fff14654fc0) at kernel/qcor eapplication.cpp:1063 #34 0x00007fc07d486103 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) (receiver=receiver@entry=0x1734400, event=event@entry=0x7fff14654fc0, alienWidget=alienWidget@entry=0x1734400, nativeWidget =0x16de2d0, buttonDown=<optimized out>, lastMouseReceiver=..., spontaneous=true, onlyDispatchEnterLeave=false) at kernel/qapplication.cp p:2614 #35 0x00007fc07d4db0dc in QWidgetWindow::handleMouseEvent(QMouseEvent*) (this=0x1655bc0, event=0x7fff14655280) at kernel/qwidgetwindow.c pp:683 #36 0x00007fc07d4de505 in QWidgetWindow::event(QEvent*) (this=0x1655bc0, event=0x7fff14655280) at kernel/qwidgetwindow.cpp:300 #37 0x00007fc07d47faff in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x1655bc0, e=0x7fff14655 280) at kernel/qapplication.cpp:3632 #38 0x00007fc07c82913a in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x1655bc0, event=0x7fff14655280) at kernel/qcor eapplication.cpp:1063 #39 0x00007fc07cd2aff3 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) (e=0x17b0ec0) at kernel/ qguiapplication.cpp:2282 #40 0x00007fc07cd00c5c in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) (flags=flags@entry=...) at kernel/qwindowsysteminterface.cpp:1169 #41 0x00007fc076b22c9a in xcbSourceDispatch(GSource*, GSourceFunc, gpointer) (source=source@entry=0xcb96b0) at qxcbeventdispatcher.cpp:1 05 #42 0x00007fc07a9a7817 in g_main_dispatch (context=0x7fc070005000) at ../glib/gmain.c:3337 #43 g_main_context_dispatch (context=0x7fc070005000) at ../glib/gmain.c:4055 #44 0x00007fc07a9a7b98 in g_main_context_iterate (context=context@entry=0x7fc070005000, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:4131 #45 0x00007fc07a9a7c4f in g_main_context_iteration (context=0x7fc070005000, may_block=may_block@entry=1) at ../glib/gmain.c:4196 #46 0x00007fc07c880d30 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0xcc8a20, flags=...) at kerne l/qeventdispatcher_glib.cpp:423 #47 0x00007fc07c827b7b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7fff146555b0, flags=..., flags@entr y=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:69 #48 0x00007fc07d68ab6a in QDialog::exec() (this=0x16de2d0) at ../../include/QtCore/../../src/corelib/global/qflags.h:121 #49 0x00000000006e9015 in UMLApp::slotImportingWizard() (this=0xd1e1e0) at /tools/umbrello-master/umbrello/uml.cpp:2792 #50 0x000000000048273b in UMLApp::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=0xd1e1e0, _c=QMetaObject::InvokeMetaM ethod, _id=2, _a=0x7fff146557a0) at /tools/umbrello-master/build/umbrello/libumbrello_autogen/EWIEGA46WW/moc_uml.cpp:483 #51 0x00007fc07c85fc50 in doActivate<false>(QObject*, int, void**) (sender=0x104a0b0, signal_index=4, argv=argv@entry=0x7fff146557a0) at kernel/qobject.cpp:3898 #52 0x00007fc07c858f60 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x104a0b0, m=m@entry=0x7 fc07d99a0a0 <QAction::staticMetaObject>, local_signal_index=local_signal_index@entry=1, argv=argv@entry=0x7fff146557a0) at kernel/qobjec t.cpp:3946 #53 0x00007fc07d4791d2 in QAction::triggered(bool) (this=this@entry=0x104a0b0, _t1=<optimized out>) at .moc/moc_qaction.cpp:376 #54 0x00007fc07d47be28 in QAction::activate(QAction::ActionEvent) (this=0x104a0b0, event=<optimized out>) at kernel/qaction.cpp:1161 #55 0x00007fc07d6024e2 in QMenuPrivate::activateCausedStack(QVector<QPointer<QWidget> > const&, QAction*, QAction::ActionEvent, bool) (t his=this@entry=0x1171d30, causedStack=..., action=action@entry=0x104a0b0, action_e=action_e@entry=QAction::Trigger, self=self@entry=true ) at widgets/qmenu.cpp:1384 #56 0x00007fc07d60a341 in QMenuPrivate::activateAction(QAction*, QAction::ActionEvent, bool) (this=0x1171d30, action=0x104a0b0, action_e =QAction::Trigger, self=<optimized out>) at widgets/qmenu.cpp:1461 #57 0x00007fc07d4c1b4e in QWidget::event(QEvent*) (this=0x1165cf0, event=0x7fff14655da0) at kernel/qwidget.cpp:9019 #58 0x00007fc07d47faff in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=this@entry=0xbbfc00, receiver=receiver@entry=0x116 5cf0, e=e@entry=0x7fff14655da0) at kernel/qapplication.cpp:3632 #59 0x00007fc07d4870cb in QApplication::notify(QObject*, QEvent*) (this=0x7fff14655ad0, receiver=0x1165cf0, e=0x7fff14655da0) at kernel/ qapplication.cpp:3076 #60 0x00007fc07c82913a in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x1165cf0, event=0x7fff14655da0) at kernel/qcor eapplication.cpp:1063 #61 0x00007fc07d486103 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) (receiver=0x1165cf0, event=event@entry=0x7fff14655da0, alienWidget=0x0, nativeWidget=0x1165cf0, buttonDown=<optimized out>, lastMouseReceiver=..., spontaneous=true, onlyDispatchEnterLeave=false) at kernel/qapplication.cpp:2614 #62 0x00007fc07d4dbbee in QWidgetWindow::handleMouseEvent(QMouseEvent*) (this=0x166bb50, event=0x7fff14656060) at kernel/qwidgetwindow.c pp:580 #63 0x00007fc07d4de505 in QWidgetWindow::event(QEvent*) (this=0x166bb50, event=0x7fff14656060) at kernel/qwidgetwindow.cpp:300 #64 0x00007fc07d47faff in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x166bb50, e=0x7fff14656 060) at kernel/qapplication.cpp:3632 #65 0x00007fc07c82913a in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x166bb50, event=0x7fff14656060) at kernel/qcor eapplication.cpp:1063 #66 0x00007fc07cd2aff3 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) (e=0x7fbffc00d810) at ke rnel/qguiapplication.cpp:2282 #67 0x00007fc07cd00c5c in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) (flags=flags@entry=...) at kernel/qwindowsysteminterface.cpp:1169 #68 0x00007fc076b22c9a in xcbSourceDispatch(GSource*, GSourceFunc, gpointer) (source=source@entry=0xcb96b0) at qxcbeventdispatcher.cpp:1 05 #69 0x00007fc07a9a7817 in g_main_dispatch (context=0x7fc070005000) at ../glib/gmain.c:3337 #70 g_main_context_dispatch (context=0x7fc070005000) at ../glib/gmain.c:4055 #71 0x00007fc07a9a7b98 in g_main_context_iterate (context=context@entry=0x7fc070005000, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:4131 #72 0x00007fc07a9a7c4f in g_main_context_iteration (context=0x7fc070005000, may_block=may_block@entry=1) at ../glib/gmain.c:4196 #73 0x00007fc07c880d30 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0xcc8a20, flags=...) at kerne l/qeventdispatcher_glib.cpp:423 #74 0x00007fc07c827b7b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7fff14656390, flags=..., flags@entr y=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:69 #75 0x00007fc07c82fdb0 in QCoreApplication::exec() () at ../../include/QtCore/../../src/corelib/global/qflags.h:121 #76 0x0000000000470710 in main(int, char**) (argc=1, argv=0x7fff14656898) at /tools/umbrello-master/umbrello/main.cpp:240 (In reply to Oliver Kellogg from comment #20) > (In reply to milasudril from comment #18) > > Any update on this task? > > A added support for C++11 "enum class" and it is working in a Qt4 based > build. > However, on trying to import > https://invent.kde.org/sdk/umbrello/-/blob/master/test/import/cxx/cxx11- > strongly-typed-enumerations.h > in a Qt5 based build I get a crash: > [...] I hereby revoke the crash report, it turned out to be a hardware glitch on the build machine. I tried again on a Windows machine with Cygwin/Qt5/KF5 and the file was imported fine. Git commit 7d3eb053739413a0eef8c111e0c9a41843227cf2 by Oliver Kellogg. Committed on 09/05/2021 at 15:47. Pushed by okellogg into branch 'release/21.04'. Fix crash reported in https://bugs.kde.org/show_bug.cgi?id=338649#c20 related to multiple calls of m_source.unicode() where the calls return different address values. The solution is to call m_source.unicode() only once: lib/cppparser/lexer.h - In class Lexer add private member m_src of type const QChar*. lib/cppparser/lexer.cpp - In function Lexer::setSource, - assign m_source.unicode() to m_src; - if m_source.isEmpty() returns true then return without calling tokenize(). - In function Lexer::reset initialize m_src to null pointer. - In function Lexer::offset return m_src + offset. - In function Lexer::getOffset use m_src in lieu of src. This avoids the second call to m_source.unicode() which on newer Qt5 versions may return a different buffer. M +8 -7 lib/cppparser/lexer.cpp M +1 -0 lib/cppparser/lexer.h https://invent.kde.org/sdk/umbrello/commit/7d3eb053739413a0eef8c111e0c9a41843227cf2 Git commit 3041141b10361aedb3c8c06c9ba36b5d25ac6f9a by Oliver Kellogg. Committed on 13/05/2021 at 16:49. Pushed by okellogg into branch 'release/21.04'. lib/cppparser/lexer.{h,cpp} followup to commit 7d3eb05, > Fix crash [...] related to multiple calls of m_source.unicode() where > the calls return different address values. > The solution is to call m_source.unicode() only once: [...] As detailed by jeremy_k at https://forum.qt.io/post/659243, the above change does not remove the root cause: - m_ptr is initially set to m_source.unicode() - During the import, m_source is modified (e.g. by calls to function insertCurrent). - These modifications invalidate the unicode buffer which is pointed to by m_ptr / m_endPtr. Generally I do not see a significant advantage in using the unicode buffer in this context. Changes in class Lexer: - Remove public functions - const CHARTYPE* offset(int offset) const; - int getOffset(const QChar* p) const. - Remove private function void setEndPtr(const QChar* c). - Remove private members m_src, m_ptr, m_endPtr of type `const QChar*`. - Add private members m_idx, m_endIdx of type int. These are used as indexes into m_source. M +26 -56 lib/cppparser/lexer.cpp M +2 -14 lib/cppparser/lexer.h https://invent.kde.org/sdk/umbrello/commit/3041141b10361aedb3c8c06c9ba36b5d25ac6f9a Git commit 0372f89d7995a5fbc557e6c6090208bc54950e88 by Oliver Kellogg. Committed on 10/09/2021 at 05:51. Pushed by okellogg into branch 'master'. Fix for "C++ importer does not recognize 'noexcept' keyword" : lib/cppparser/keywords.h - Align INSERT calls as table. Add INSERT("noexcept", Token_noexcept). lib/cppparser/lexer.h - In enum Type add Token_noexcept. lib/cppparser/parser.cpp - In functions skipUntilDeclaration, skipUntilStatement while-loop switch add case Token_noexcept. - In function parseExceptionSpecification handle the case (m_lexer->lookAhead(0) == Token_noexcept). test/import/cxx/const-methods.h - Rename file to const-noexcept-methods.h. test/import/cxx/const-noexcept-methods.h - Rename class to ConstNoexceptMethodClass. - Add NoexceptMethod with trailing noexcept. - Add ConstNoexceptMethod with const noexcept and implementation. Related: bug 442134 M +84 -83 lib/cppparser/keywords.h M +1 -0 lib/cppparser/lexer.h M +15 -2 lib/cppparser/parser.cpp D +0 -3 test/import/cxx/const-methods.h A +5 -0 test/import/cxx/const-noexcept-methods.h * The files marked with a * at the end have a non valid license. Please read: https://community.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page. https://invent.kde.org/sdk/umbrello/commit/0372f89d7995a5fbc557e6c6090208bc54950e88 |