diff options
Diffstat (limited to 'sources')
193 files changed, 4256 insertions, 18970 deletions
diff --git a/sources/pyside2/CMakeLists.txt b/sources/pyside2/CMakeLists.txt index 6c5691d01..6f581e009 100644 --- a/sources/pyside2/CMakeLists.txt +++ b/sources/pyside2/CMakeLists.txt @@ -133,12 +133,22 @@ if(CMAKE_HOST_APPLE) endif() endif() -if(NOT CMAKE_HOST_APPLE) - # Qt5: QT_INCLUDE_DIR does no longer exist. - # On Windows and Linux, it can be computed from Qt5Core_INCLUDE_DIRS - message("Qt5Core_INCLUDE_DIRS ${Qt5Core_INCLUDE_DIRS}") - list(GET Qt5Core_INCLUDE_DIRS 0 QT_INCLUDE_DIR) - message(STATUS "*** computed QT_INCLUDE_DIR as ${QT_INCLUDE_DIR}") +# Qt5: QT_INCLUDE_DIR does no longer exist. +# On Windows, macOS, and Linux it can be computed from Qt5Core_INCLUDE_DIRS, which contains +# a list of include directories. We take the first one. +message(STATUS "*** Qt5Core_INCLUDE_DIRS = ${Qt5Core_INCLUDE_DIRS}") +list(GET Qt5Core_INCLUDE_DIRS 0 QT_INCLUDE_DIR) + +# On macOS, check if Qt is a framework build. This affects how include paths should be handled. +get_target_property(QtCore_is_framework Qt5::Core FRAMEWORK) + +if (QtCore_is_framework) + get_filename_component(QT_FRAMEWORK_INCLUDE_DIR "${QT_INCLUDE_DIR}/../" ABSOLUTE) + message(STATUS "*** QT_FRAMEWORK_INCLUDE_DIR is ${QT_FRAMEWORK_INCLUDE_DIR}") + + # QT_INCLUDE_DIR points to the QtCore.framework directory, so need to adjust this to point + # to the actual include directory. + get_filename_component(QT_INCLUDE_DIR "${QT_INCLUDE_DIR}/../../include" ABSOLUTE) endif() if(MSVC) @@ -162,12 +172,14 @@ else() if (NOT QT_INCLUDE_DIR) set(QT_INCLUDE_DIR "/Library/Frameworks") endif() - if(ALTERNATIVE_QT_INCLUDE_DIR) + if(NOT QT_INCLUDE_DIR AND ALTERNATIVE_QT_INCLUDE_DIR) set(QT_INCLUDE_DIR ${ALTERNATIVE_QT_INCLUDE_DIR}) endif() string(REPLACE " " ":" QT_INCLUDE_DIR ${QT_INCLUDE_DIR}) endif() endif() +message(STATUS "*** computed QT_INCLUDE_DIR as ${QT_INCLUDE_DIR}") + if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE ${SHIBOKEN_BUILD_TYPE}) @@ -254,6 +266,7 @@ if(NOT MSVC) else() set(DISABLE_QtScriptTools 1) ENDIF() +COLLECT_MODULE_IF_FOUND(TextToSpeech opt) COLLECT_MODULE_IF_FOUND(Svg opt) if(Qt5Designer_FOUND) COLLECT_MODULE_IF_FOUND(UiTools opt) diff --git a/sources/pyside2/PySide2/QtCore/CMakeLists.txt b/sources/pyside2/PySide2/QtCore/CMakeLists.txt index 4e833f584..afef603c7 100644 --- a/sources/pyside2/PySide2/QtCore/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtCore/CMakeLists.txt @@ -138,6 +138,7 @@ ${QtCore_GEN_DIR}/qtimer_wrapper.cpp ${QtCore_GEN_DIR}/qtimerevent_wrapper.cpp ${QtCore_GEN_DIR}/qtranslator_wrapper.cpp ${QtCore_GEN_DIR}/qurl_wrapper.cpp +${QtCore_GEN_DIR}/qurlquery_wrapper.cpp ${QtCore_GEN_DIR}/qvariantanimation_wrapper.cpp ${QtCore_GEN_DIR}/qwaitcondition_wrapper.cpp ${QtCore_GEN_DIR}/qwritelocker_wrapper.cpp diff --git a/sources/pyside2/PySide2/QtCore/glue/qcoreapplication_init.cpp b/sources/pyside2/PySide2/QtCore/glue/qcoreapplication_init.cpp index 20e9c4464..c48b4ffa0 100644 --- a/sources/pyside2/PySide2/QtCore/glue/qcoreapplication_init.cpp +++ b/sources/pyside2/PySide2/QtCore/glue/qcoreapplication_init.cpp @@ -55,7 +55,7 @@ void QCoreApplication_constructor(PyObject* self, PyObject* args, QCoreApplicati return; } - *cptr = new QCoreApplicationWrapper(QCoreApplicationArgCount, QCoreApplicationArgValues); + *cptr = new QCoreApplicationWrapper(QCoreApplicationArgCount, QCoreApplicationArgValues, QT_VERSION); Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self)); PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml index e81eb7e21..be570bd60 100644 --- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml +++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml @@ -137,6 +137,33 @@ <rejection class="*" function-name="qFreeAligned"/> <rejection class="QMetaMethod" enum-name="Attributes" /> + <rejection class="*" argument-type="QByteArrayDataPtr"/> + <rejection class="*" argument-type="^qfloat16&?$"/> + <rejection class="*" argument-type="QHashData"/> + <rejection class="*" argument-type="QHashData::Node*"/> + <rejection class="*" argument-type="QLatin1String"/> + <rejection class="*" argument-type="QLinkedListData*"/> + <rejection class="*" argument-type="QListData::ArrayCompatibleLayout"/> + <rejection class="*" argument-type="QListData::Data*"/> + <rejection class="*" argument-type="QListData::NotArrayCompatibleLayout"/> + <rejection class="*" argument-type="QList::Node*"/> + <rejection class="*" argument-type="QMutexData*"/> + <rejection class="*" argument-type="QObjectUserData*"/> + <rejection class="*" argument-type="QtPrivate::QSlotObjectBase*"/> + <rejection class="*" argument-type="^Q\w+Private( const)?\&$"/> + <!-- Note: "QHelpModel(QHelpEnginePrivate*)" is needed --> + <rejection class="*" argument-type="^Q[^H]\w+Private( const)?\*$"/> + <rejection class="*" argument-type="^.*::QPrivateSignal$"/> + <rejection class="*" argument-type="Qt::Initialization"/> + + <rejection class="*" argument-type="FILE*"/> + <rejection class="*" argument-type="std::chrono::milliseconds"/> + <rejection class="*" argument-type="^std::nullptr_t&?$"/> + <rejection class="*" argument-type="^std::initializer_list<.*$"/> + <rejection class="*" argument-type="^std::list<[^>]> const&$"/> + <rejection class="*" argument-type="std::string const&"/> + <rejection class="*" argument-type="^std::vector<[^>]> const&$"/> + <!-- From Qt4.6 ^^^ --> @@ -182,6 +209,16 @@ <!-- FIXME APIExtractor or shiboken do not support multiple includes by primitive type --> <include file-name="signalmanager.h" location="global"/> </primitive-type> + + <!-- Among other use cases, these types are necessary for OpenGL "GLint"-like typedefs on macOS. + --> + <primitive-type name="int32_t" /> + <primitive-type name="int16_t" /> + <primitive-type name="int8_t" /> + <primitive-type name="uint32_t" /> + <primitive-type name="uint16_t" /> + <primitive-type name="uint8_t" /> + <primitive-type name="bool" target-lang-api-name="PyBool"> <conversion-rule> <native-to-target> @@ -2331,6 +2368,7 @@ <include file-name="QSize" location="global"/> </extra-includes> </object-type> + <value-type name="QUrlQuery" since="5.0" /> <value-type name="QUrl" hash-function="PySide::hash"> <!-- Qt5: lots of changes --> <enum-type name="ComponentFormattingOption" flags="ComponentFormattingOptions,FormattingOptions"/> @@ -3240,7 +3278,7 @@ <modify-function signature="notify(QObject*,QEvent*)" allow-thread="yes"> <modify-argument index="2" invalidate-after-use="yes"/> </modify-function> - <modify-function signature="QCoreApplication(int &, char **)" access="private"/> + <modify-function signature="QCoreApplication(int &, char **, int)" access="private"/> <inject-code class="native" file="glue/qcoreapplication_init.cpp" position="beginning" /> <modify-function signature="postEvent(QObject*,QEvent*, int)"> <modify-argument index="2"> @@ -3584,8 +3622,8 @@ <modify-function signature="operator<<(float)" remove="all"/> <modify-function signature="operator<<(qlonglong)" remove="all"/> <modify-function signature="operator<<(qulonglong)" remove="all"/> - <modify-function signature="operator<<(signed short)" remove="all"/> - <modify-function signature="operator<<(signed int)" remove="all"/> + <modify-function signature="operator<<(short)" remove="all"/> + <modify-function signature="operator<<(int)" remove="all"/> <modify-function signature="operator<<(unsigned int)" remove="all"/> <modify-function signature="operator<<(unsigned short)" remove="all"/> <modify-function signature="operator<<(const char*)" remove="all"/> @@ -3596,9 +3634,9 @@ <modify-function signature="operator>>(double&)" remove="all"/> <modify-function signature="operator>>(qlonglong&)" remove="all"/> <modify-function signature="operator>>(qulonglong&)" remove="all"/> - <modify-function signature="operator>>(signed long&)" remove="all"/> - <modify-function signature="operator>>(signed int&)" remove="all"/> - <modify-function signature="operator>>(signed short&)" remove="all"/> + <modify-function signature="operator>>(long&)" remove="all"/> + <modify-function signature="operator>>(int&)" remove="all"/> + <modify-function signature="operator>>(short&)" remove="all"/> <modify-function signature="operator>>(unsigned long&)" remove="all"/> <modify-function signature="operator>>(unsigned int&)" remove="all"/> <modify-function signature="operator>>(unsigned short&)" remove="all"/> @@ -4204,7 +4242,7 @@ s1.addTransition(button.clicked, s1h)</code> <!-- TODO: this need be removed --> <suppress-warning text="skipping function '*', unmatched return type '*'"/> - <suppress-warning text="skipping function '*', unmatched parameter type '*'"/> + <suppress-warning text="skipping function '*', unmatched type '*"/> <suppress-warning text="enum 'q_static_assert_result39' does not have a type entry or is not an enum"/> <suppress-warning text="horribly broken type ''"/> diff --git a/sources/pyside2/PySide2/QtGui/CMakeLists.txt b/sources/pyside2/PySide2/QtGui/CMakeLists.txt index a6a8c1049..b0973debe 100644 --- a/sources/pyside2/PySide2/QtGui/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtGui/CMakeLists.txt @@ -3,6 +3,7 @@ project(QtGui) qt5_wrap_cpp(QPYTEXTOBJECT_MOC "${pyside2_SOURCE_DIR}/qpytextobject.h") set(QtGui_SRC +${QtGui_GEN_DIR}/qabstractopenglfunctions_wrapper.cpp ${QtGui_GEN_DIR}/qabstracttextdocumentlayout_paintcontext_wrapper.cpp ${QtGui_GEN_DIR}/qabstracttextdocumentlayout_selection_wrapper.cpp ${QtGui_GEN_DIR}/qabstracttextdocumentlayout_wrapper.cpp @@ -66,6 +67,23 @@ ${QtGui_GEN_DIR}/qmatrix4x4_wrapper.cpp ${QtGui_GEN_DIR}/qmouseevent_wrapper.cpp ${QtGui_GEN_DIR}/qmoveevent_wrapper.cpp ${QtGui_GEN_DIR}/qmovie_wrapper.cpp +${QtGui_GEN_DIR}/qoffscreensurface_wrapper.cpp +${QtGui_GEN_DIR}/qopenglcontextgroup_wrapper.cpp +${QtGui_GEN_DIR}/qopengldebuglogger_wrapper.cpp +${QtGui_GEN_DIR}/qopengldebugmessage_wrapper.cpp +${QtGui_GEN_DIR}/qopenglextrafunctions_wrapper.cpp +${QtGui_GEN_DIR}/qopenglframebufferobjectformat_wrapper.cpp +${QtGui_GEN_DIR}/qopenglfunctions_wrapper.cpp +# Compile error on Windows: ${QtGui_GEN_DIR}/qopenglpaintdevice_wrapper.cpp +${QtGui_GEN_DIR}/qopenglpixeltransferoptions_wrapper.cpp +${QtGui_GEN_DIR}/qopenglshaderprogram_wrapper.cpp +${QtGui_GEN_DIR}/qopengltexture_wrapper.cpp +${QtGui_GEN_DIR}/qopengltimemonitor_wrapper.cpp +${QtGui_GEN_DIR}/qopengltimerquery_wrapper.cpp +${QtGui_GEN_DIR}/qopenglversionprofile_wrapper.cpp +${QtGui_GEN_DIR}/qopenglvertexarrayobject_wrapper.cpp +${QtGui_GEN_DIR}/qopenglvertexarrayobject_binder_wrapper.cpp +${QtGui_GEN_DIR}/qopenglwindow_wrapper.cpp ${QtGui_GEN_DIR}/qpagedpaintdevice_margins_wrapper.cpp ${QtGui_GEN_DIR}/qpagedpaintdevice_wrapper.cpp ${QtGui_GEN_DIR}/qpagelayout_wrapper.cpp diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml index 7a0db8a41..0d9b56edd 100644 --- a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml +++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml @@ -54,6 +54,7 @@ } </template> + <rejection class="^Q.*$" argument-type="^QPlatform.*$"/> <function signature="qAlpha(uint)" /> <function signature="qBlue(uint)" /> <function signature="qGray(int,int,int)" /> @@ -96,6 +97,27 @@ <rejection class="*" function-name="d_func"/> <rejection class="*" field-name="d_ptr"/> <rejection class="*" field-name="d"/> + <rejection class="^QOpenGL.*$" argument-type="^GLboolean( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="^GLchar( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="GLchar *const const*"/> + <rejection class="^QOpenGL.*$" argument-type="^GLenum( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="^GLfloat( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="^GLfloat( const)?\[.*$"/> + <rejection class="^QOpenGL.*$" argument-type="^GLdouble( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="GLintptr"/> + <rejection class="^QOpenGL.*$" argument-type="^GLint64( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="^GLsizei( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="GLsizeiptr"/> + <rejection class="^QOpenGL.*$" argument-type="GLsync"/> + <rejection class="^QOpenGL.*$" argument-type="^GLubyte( const)?\*$"/> + <rejection class="^QOpenGL.*$" return-type="^GLubyte( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="^GLu?int( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="^QMatrix.x.( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="qopengl_GLintptr"/> + <rejection class="^QOpenGL.*$" argument-type="qopengl_GLsizeiptr"/> + <rejection class="^QOpenGL.*$" argument-type="QOpenGLTextureHelper*"/> + <rejection class="^QOpenGL.*$" argument-type="^QVector.D( const)?\*$"/> + <rejection class="^QOpenGL.*$" argument-type="^void( const)?\*\*?$"/> <!-- Event classes have a lot of non-documented protected fields, those fields @@ -3207,6 +3229,7 @@ <enum-type name="RenderableType"/> <enum-type name="SwapBehavior"/> </value-type> + <object-type name="QOffscreenSurface" since="5.1"/> <primitive-type name="QPlatformSurface"> <extra-includes> <include file-name="QtGui/qpa/qplatformsurface.h" location="global"/> @@ -3263,19 +3286,99 @@ <object-type name="QOpenGLContext"> <enum-type name="OpenGLModuleType" /> </object-type> - <object-type name="QOpenGLFramebufferObject"> + <object-type name="QOpenGLContextGroup" since="5.0"/> + <object-type name="QOpenGLDebugLogger" since="5.1"> + <enum-type name="LoggingMode"/> + </object-type> + <value-type name="QOpenGLDebugMessage" since="5.1"> + <enum-type name="Source" flags="Sources"/> + <enum-type name="Type" flags="Types"/> + <enum-type name="Severity" flags="Severities"/> + </value-type> + <object-type name="QOpenGLFramebufferObject" since="5.0"> <enum-type name="Attachment" /> <enum-type name="FramebufferRestorePolicy" since="5.7"/> </object-type> - <object-type name="QOpenGLShader" > - <enum-type name="ShaderTypeBit" flags="ShaderType" /> + <value-type name="QOpenGLFramebufferObjectFormat"/> + <!-- Compile error on Windows: QOpenGLPaintDevice::QOpenGLPaintDevice(const QOpenGLPaintDevice &)': attempting to reference a deleted function + <object-type name="QOpenGLPaintDevice" since="5.0"/> + --> + <object-type name="QOpenGLExtraFunctions" since="5.6"> + <!-- Exlusions due to compile errors --> + <modify-function signature="glEndTransformFeedback()" remove="all"/> + <modify-function signature="glPauseTransformFeedback()" remove="all"/> + <modify-function signature="glResumeTransformFeedback()" remove="all"/> + </object-type> + <object-type name="QOpenGLFunctions" since="5.0"> + <enum-type name="OpenGLFeature" flags="OpenGLFeatures"/> </object-type> - <!-- Temporarily disable type, because it causes segfault on Linux due to incorrect parsing - of the void setUniformValue(const char *name, const GLfloat value[2][2]); method. - The float[][] ends up with an "Array" cpp signature, which obviously can't be found in the - typesystem. - <object-type name="QOpenGLShaderProgram" /> + <object-type name="QAbstractOpenGLFunctions" since="5.1"/> + <!-- Classes are result of a macro expansion in src/gui/opengl/qopenglversionfunctions.h + <object-type name="QOpenGLFunctions_1_0" since="5.1"/> + <object-type name="QOpenGLFunctions_1_1" since="5.1"/> + <object-type name="QOpenGLFunctions_1_2" since="5.1"/> + <object-type name="QOpenGLFunctions_1_3" since="5.1"/> + <object-type name="QOpenGLFunctions_1_4" since="5.1"/> + <object-type name="QOpenGLFunctions_1_5" since="5.1"/> + <object-type name="QOpenGLFunctions_2_0" since="5.1"> + <object-type name="QOpenGLFunctions_2_1" since="5.1"/> + <object-type name="QOpenGLFunctions_3_0" since="5.1"/> + <object-type name="QOpenGLFunctions_3_1" since="5.1"/> + <object-type name="QOpenGLFunctions_3_2_Compatibility" since="5.1"/> + <object-type name="QOpenGLFunctions_3_2_Core" since="5.1"/> + <object-type name="QOpenGLFunctions_3_3_Compatibility" since="5.1"/> + <object-type name="QOpenGLFunctions_3_3_Core" since="5.1"/> + <object-type name="QOpenGLFunctions_4_0_Compatibility" since="5.1"/> + <object-type name="QOpenGLFunctions_4_0_Core" since="5.1"/> + <object-type name="QOpenGLFunctions_4_1_Compatibility" since="5.1"/> + <object-type name="QOpenGLFunctions_4_1_Core" since="5.1"/> + <object-type name="QOpenGLFunctions_4_2_Compatibility" since="5.1"/> + <object-type name="QOpenGLFunctions_4_2_Core" since="5.1"/> + <object-type name="QOpenGLFunctions_4_3_Compatibility" since="5.1"/> + <object-type name="QOpenGLFunctions_4_3_Core" since="5.1"/> + <object-type name="QOpenGLFunctions_4_4_Compatibility" since="5.5/> + <object-type name="QOpenGLFunctions_4_4_Core" since="5.5"/> + <object-type name="QOpenGLFunctions_4_5_Compatibility since="5.5""/> + <object-type name="QOpenGLFunctions_4_5_Core" since="5.5"/> + <object-type name="QOpenGLFunctions_ES2" since="5.1"/> --> + <value-type name="QOpenGLPixelTransferOptions"/> + <object-type name="QOpenGLShader" since="5.0"> + <enum-type name="ShaderTypeBit" flags="ShaderType" /> + </object-type> + <object-type name="QOpenGLShaderProgram" since="5.0"/> + <object-type name="QOpenGLTexture" since="5.2"> + <enum-type name="BindingTarget"/> + <enum-type name="CoordinateDirection"/> + <enum-type name="ComparisonFunction"/> + <enum-type name="ComparisonMode"/> + <enum-type name="CubeMapFace"/> + <enum-type name="DepthStencilMode"/> + <enum-type name="Feature" flags="Features"/> + <enum-type name="Filter"/> + <enum-type name="MipMapGeneration"/> + <enum-type name="PixelFormat"/> + <enum-type name="PixelType"/> + <enum-type name="SwizzleComponent"/> + <enum-type name="SwizzleValue"/> + <enum-type name="Target"/> + <enum-type name="TextureFormat"/> + <enum-type name="TextureFormatClass"/> + <enum-type name="TextureUnitReset"/> + <enum-type name="WrapMode"/> + <modify-function signature="borderColor(unsigned int*)const" remove="all"/> + <modify-function signature="borderColor(int*)const" remove="all"/> + <modify-function signature="borderColor(float*)const" remove="all"/> + </object-type> + <object-type name="QOpenGLTimeMonitor" since="5.1"/> + <object-type name="QOpenGLTimerQuery" since="5.1"/> + <object-type name="QOpenGLWindow" since="5.4"> + <enum-type name="UpdateBehavior"/> + </object-type> + <value-type name="QOpenGLVersionProfile" since="5.1"/> + <object-type name="QOpenGLVertexArrayObject"> + <object-type name="Binder"/> + </object-type> <value-type name="QPageLayout"> <enum-type name="Mode"/> <enum-type name="Orientation"/> diff --git a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml index 2643f1ca9..2f8424ac7 100644 --- a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml +++ b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml @@ -181,8 +181,10 @@ <enum-type name="SpecialAddress"/> <!-- ### QHostAddress(QIPv6Address) does this --> <modify-function signature="QHostAddress(quint8*)" remove="all" /> - <!-- ### --> + <modify-function signature="QHostAddress(const quint8*)" remove="all" /> + <!-- ### --> <modify-function signature="setAddress(quint8*)" remove="all" /> + <modify-function signature="setAddress(const quint8*)" remove="all" /> </value-type> <value-type name="QHostInfo"> diff --git a/sources/pyside2/PySide2/QtQuick/CMakeLists.txt b/sources/pyside2/PySide2/QtQuick/CMakeLists.txt index 491fc9d9e..11cbdf750 100644 --- a/sources/pyside2/PySide2/QtQuick/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtQuick/CMakeLists.txt @@ -11,7 +11,6 @@ ${QtQuick_GEN_DIR}/qquicktransform_wrapper.cpp ${QtQuick_GEN_DIR}/qquickitem_wrapper.cpp ${QtQuick_GEN_DIR}/qquickitem_updatepaintnodedata_wrapper.cpp ${QtQuick_GEN_DIR}/qquickitemgrabresult_wrapper.cpp -${QtQuick_GEN_DIR}/qsharedpointer_qquickitemgrabresult_wrapper.cpp ${QtQuick_GEN_DIR}/qquickpainteditem_wrapper.cpp ${QtQuick_GEN_DIR}/qquickrendercontrol_wrapper.cpp ${QtQuick_GEN_DIR}/qquicktextdocument_wrapper.cpp diff --git a/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml b/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml index 4cee02eec..0bee346ba 100644 --- a/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml +++ b/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml @@ -46,7 +46,6 @@ <load-typesystem name="typesystem_qml.xml" generate="no"/> <primitive-type name="GLuint"/> - <smart-pointer-type name="QSharedPointer" type="shared" getter="data" /> <extra-includes> <include file-name="pysidequickregistertype.h" location="local"/> diff --git a/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt b/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt new file mode 100644 index 000000000..c616e1234 --- /dev/null +++ b/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt @@ -0,0 +1,40 @@ +project(QtTextToSpeech) + +set(QtTextToSpeech_SRC +${QtTextToSpeech_GEN_DIR}/qtexttospeech_wrapper.cpp +${QtTextToSpeech_GEN_DIR}/qtexttospeechengine_wrapper.cpp +${QtTextToSpeech_GEN_DIR}/qvoice_wrapper.cpp +# module is always needed +${QtTextToSpeech_GEN_DIR}/qttexttospeech_module_wrapper.cpp +) + +make_path(QtTextToSpeech_typesystem_path + ${QtCore_SOURCE_DIR} + ${QtCore_BINARY_DIR} + ${QtTextToSpeech_SOURCE_DIR}) + +set(QtTextToSpeech_include_dirs ${QtTextToSpeech_SOURCE_DIR} + ${QtTextToSpeech_BINARY_DIR} + ${Qt5Core_INCLUDE_DIRS} + ${Qt5TextToSpeech_INCLUDE_DIRS} + ${SHIBOKEN_INCLUDE_DIR} + ${libpyside_SOURCE_DIR} + ${SHIBOKEN_PYTHON_INCLUDE_DIR} + ${QtCore_GEN_DIR}) + +set(QtTextToSpeech_libraries pyside2 + ${SHIBOKEN_PYTHON_LIBRARIES} + ${SHIBOKEN_LIBRARY} + ${Qt5Multimedia_LIBRARIES} + ${Qt5TextToSpeech_LIBRARIES} + ${Qt5Core_LIBRARIES}) + +set(QtTextToSpeech_deps QtCore QtMultimedia) + +create_pyside_module(QtTextToSpeech + QtTextToSpeech_include_dirs + QtTextToSpeech_libraries + QtTextToSpeech_deps + QtTextToSpeech_typesystem_path + QtTextToSpeech_SRC + "") diff --git a/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml b/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml new file mode 100644 index 000000000..420bcc2d8 --- /dev/null +++ b/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml @@ -0,0 +1,53 @@ +<?xml version="1.0"?> +<!-- +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +--> +<typesystem package="PySide2.QtTextToSpeech"> + <load-typesystem name="typesystem_core.xml" generate="no" /> + + <object-type name="QTextToSpeech" since="5.9"> + <enum-type name="State"/> + </object-type> + <object-type name="QTextToSpeechEngine" since="5.9"/> + <value-type name="QVoice" since="5.9"> + <enum-type name="Gender"/> + <enum-type name="Age"/> + </value-type> +</typesystem> diff --git a/sources/pyside2/PySide2/global.h.in b/sources/pyside2/PySide2/global.h.in index 6bddcfcce..3422f0d6e 100644 --- a/sources/pyside2/PySide2/global.h.in +++ b/sources/pyside2/PySide2/global.h.in @@ -37,345 +37,13 @@ ** ****************************************************************************/ -#undef QT_NO_STL - -#undef QT_NO_STL_WCHAR -#define Q_BYTE_ORDER // used to enable QSysInfo.Endian detection on MacOSX - -#if defined(__OBJC__) && !defined(__cplusplus) -# warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)" -#endif - #include <QtCore/qnamespace.h> -QT_BEGIN_NAMESPACE - - -class QByteArray; -struct QArrayData; -typedef QArrayData QByteArrayData; - -class QString; - -#ifndef Q_MOC_OUTPUT_REVISION -#define Q_MOC_OUTPUT_REVISION 67 -#endif - -// The following macros are our "extensions" to C++ -// They are used, strictly speaking, only by the moc. - - -#ifndef QT_NO_META_MACROS -// macro for onaming members -#ifdef METHOD -#undef METHOD -#endif -#ifdef SLOT -#undef SLOT -#endif -#ifdef SIGNAL -#undef SIGNAL -#endif -#endif // QT_NO_META_MACROS - -Q_CORE_EXPORT const char *qFlagLocation(const char *method); - -#ifndef QT_NO_META_MACROS -#ifndef QT_NO_DEBUG -# define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__) -# ifndef QT_NO_KEYWORDS -# define METHOD(a) qFlagLocation("0"#a QLOCATION) -# endif -# define SLOT(a) qFlagLocation("1"#a QLOCATION) -# define SIGNAL(a) qFlagLocation("2"#a QLOCATION) -#else -# ifndef QT_NO_KEYWORDS -# define METHOD(a) "0"#a -# endif -# define SLOT(a) "1"#a -# define SIGNAL(a) "2"#a -#endif - -#define QMETHOD_CODE 0 // member type codes -#define QSLOT_CODE 1 -#define QSIGNAL_CODE 2 -#endif // QT_NO_META_MACROS - -#define Q_ARG(type, data) QArgument<type >(#type, data) -#define Q_RETURN_ARG(type, data) QReturnArgument<type >(#type, data) - -class QObject; -class QMetaMethod; -class QMetaEnum; -class QMetaProperty; -class QMetaClassInfo; - - -class Q_CORE_EXPORT QGenericArgument -{ -public: - inline QGenericArgument(const char *aName = 0, const void *aData = 0) - : _data(aData), _name(aName) {} - inline void *data() const { return const_cast<void *>(_data); } - inline const char *name() const { return _name; } - -private: - const void *_data; - const char *_name; -}; - -class Q_CORE_EXPORT QGenericReturnArgument: public QGenericArgument -{ -public: - inline QGenericReturnArgument(const char *aName = 0, void *aData = 0) - : QGenericArgument(aName, aData) - {} -}; - -template <class T> -class QArgument: public QGenericArgument -{ -public: - inline QArgument(const char *aName, const T &aData) - : QGenericArgument(aName, static_cast<const void *>(&aData)) - {} -}; -template <class T> -class QArgument<T &>: public QGenericArgument -{ -public: - inline QArgument(const char *aName, T &aData) - : QGenericArgument(aName, static_cast<const void *>(&aData)) - {} -}; - - -template <typename T> -class QReturnArgument: public QGenericReturnArgument -{ -public: - inline QReturnArgument(const char *aName, T &aData) - : QGenericReturnArgument(aName, static_cast<void *>(&aData)) - {} -}; - -struct Q_CORE_EXPORT QMetaObject -{ - class Connection; - const char *className() const; - const QMetaObject *superClass() const; - - QObject *cast(QObject *obj) const; - const QObject *cast(const QObject *obj) const; - -#ifndef QT_NO_TRANSLATION - QString tr(const char *s, const char *c, int n = -1) const; -#endif // QT_NO_TRANSLATION - - int methodOffset() const; - int enumeratorOffset() const; - int propertyOffset() const; - int classInfoOffset() const; - - int constructorCount() const; - int methodCount() const; - int enumeratorCount() const; - int propertyCount() const; - int classInfoCount() const; - - int indexOfConstructor(const char *constructor) const; - int indexOfMethod(const char *method) const; - int indexOfSignal(const char *signal) const; - int indexOfSlot(const char *slot) const; - int indexOfEnumerator(const char *name) const; - int indexOfProperty(const char *name) const; - int indexOfClassInfo(const char *name) const; - - QMetaMethod constructor(int index) const; - QMetaMethod method(int index) const; - QMetaEnum enumerator(int index) const; - QMetaProperty property(int index) const; - QMetaClassInfo classInfo(int index) const; - QMetaProperty userProperty() const; - - static bool checkConnectArgs(const char *signal, const char *method); - static bool checkConnectArgs(const QMetaMethod &signal, - const QMetaMethod &method); - static QByteArray normalizedSignature(const char *method); - static QByteArray normalizedType(const char *type); - - // internal index-based connect - static Connection connect(const QObject *sender, int signal_index, - const QObject *receiver, int method_index, - int type = 0, int *types = 0); - // internal index-based disconnect - static bool disconnect(const QObject *sender, int signal_index, - const QObject *receiver, int method_index); - static bool disconnectOne(const QObject *sender, int signal_index, - const QObject *receiver, int method_index); - // internal slot-name based connect - static void connectSlotsByName(QObject *o); - - // internal index-based signal activation - static void activate(QObject *sender, int signal_index, void **argv); - static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv); - static void activate(QObject *sender, int signal_offset, int local_signal_index, void **argv); - - static bool invokeMethod(QObject *obj, const char *member, - Qt::ConnectionType, - QGenericReturnArgument ret, - QGenericArgument val0 = QGenericArgument(0), - QGenericArgument val1 = QGenericArgument(), - QGenericArgument val2 = QGenericArgument(), - QGenericArgument val3 = QGenericArgument(), - QGenericArgument val4 = QGenericArgument(), - QGenericArgument val5 = QGenericArgument(), - QGenericArgument val6 = QGenericArgument(), - QGenericArgument val7 = QGenericArgument(), - QGenericArgument val8 = QGenericArgument(), - QGenericArgument val9 = QGenericArgument()); - - static inline bool invokeMethod(QObject *obj, const char *member, - QGenericReturnArgument ret, - QGenericArgument val0 = QGenericArgument(0), - QGenericArgument val1 = QGenericArgument(), - QGenericArgument val2 = QGenericArgument(), - QGenericArgument val3 = QGenericArgument(), - QGenericArgument val4 = QGenericArgument(), - QGenericArgument val5 = QGenericArgument(), - QGenericArgument val6 = QGenericArgument(), - QGenericArgument val7 = QGenericArgument(), - QGenericArgument val8 = QGenericArgument(), - QGenericArgument val9 = QGenericArgument()) - { - return invokeMethod(obj, member, Qt::AutoConnection, ret, val0, val1, val2, val3, - val4, val5, val6, val7, val8, val9); - } - - static inline bool invokeMethod(QObject *obj, const char *member, - Qt::ConnectionType type, - QGenericArgument val0 = QGenericArgument(0), - QGenericArgument val1 = QGenericArgument(), - QGenericArgument val2 = QGenericArgument(), - QGenericArgument val3 = QGenericArgument(), - QGenericArgument val4 = QGenericArgument(), - QGenericArgument val5 = QGenericArgument(), - QGenericArgument val6 = QGenericArgument(), - QGenericArgument val7 = QGenericArgument(), - QGenericArgument val8 = QGenericArgument(), - QGenericArgument val9 = QGenericArgument()) - { - return invokeMethod(obj, member, type, QGenericReturnArgument(), val0, val1, val2, - val3, val4, val5, val6, val7, val8, val9); - } - - static inline bool invokeMethod(QObject *obj, const char *member, - QGenericArgument val0 = QGenericArgument(0), - QGenericArgument val1 = QGenericArgument(), - QGenericArgument val2 = QGenericArgument(), - QGenericArgument val3 = QGenericArgument(), - QGenericArgument val4 = QGenericArgument(), - QGenericArgument val5 = QGenericArgument(), - QGenericArgument val6 = QGenericArgument(), - QGenericArgument val7 = QGenericArgument(), - QGenericArgument val8 = QGenericArgument(), - QGenericArgument val9 = QGenericArgument()) - { - return invokeMethod(obj, member, Qt::AutoConnection, QGenericReturnArgument(), val0, - val1, val2, val3, val4, val5, val6, val7, val8, val9); - } - - QObject *newInstance(QGenericArgument val0 = QGenericArgument(0), - QGenericArgument val1 = QGenericArgument(), - QGenericArgument val2 = QGenericArgument(), - QGenericArgument val3 = QGenericArgument(), - QGenericArgument val4 = QGenericArgument(), - QGenericArgument val5 = QGenericArgument(), - QGenericArgument val6 = QGenericArgument(), - QGenericArgument val7 = QGenericArgument(), - QGenericArgument val8 = QGenericArgument(), - QGenericArgument val9 = QGenericArgument()) const; - - enum Call { - InvokeMetaMethod, - ReadProperty, - WriteProperty, - ResetProperty, - QueryPropertyDesignable, - QueryPropertyScriptable, - QueryPropertyStored, - QueryPropertyEditable, - QueryPropertyUser, - CreateInstance, - IndexOfMethod, - RegisterPropertyMetaType, - RegisterMethodArgumentMetaType - }; - - int static_metacall(Call, int, void **) const; - static int metacall(QObject *, Call, int, void **); - - struct { // private data - const QMetaObject *superdata; - const QByteArrayData *stringdata; - const uint *data; - typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **); - StaticMetacallFunction static_metacall; - const QMetaObject * const *relatedMetaObjects; - void *extradata; //reserved for future use - } d; -}; - -class Q_CORE_EXPORT QMetaObject::Connection { - void *d_ptr; //QObjectPrivate::Connection* - explicit Connection(void *data) : d_ptr(data) { } - friend class QObject; - friend class QObjectPrivate; - friend struct QMetaObject; -public: - ~Connection(); - Connection(); - Connection(const Connection &other); - Connection &operator=(const Connection &other); -#ifdef Q_QDOC - operator bool() const; -#else - typedef void *Connection::*RestrictedBool; - operator RestrictedBool() const { return d_ptr ? &Connection::d_ptr : 0; } -#endif - -#ifdef Q_COMPILER_RVALUE_REFS - inline Connection(Connection &&o) : d_ptr(o.d_ptr) { o.d_ptr = 0; } - inline Connection &operator=(Connection &&other) - { qSwap(d_ptr, other.d_ptr); return *this; } -#endif -}; - -inline const QMetaObject *QMetaObject::superClass() const -{ return d.superdata; } - -namespace QtPrivate { - /* Trait that tells is a the Object has a Q_OBJECT macro */ - template <typename Object> struct HasQ_OBJECT_Macro { - template <typename T> - static char test(int (T::*)(QMetaObject::Call, int, void **)); - static int test(int (Object::*)(QMetaObject::Call, int, void **)); - enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) }; - }; -} - -QT_END_NAMESPACE - -// This Q_QDOC definition is only a convenience, since the shiboken parser is -// happier with the simplified constructions. XXX remove this for Qt 5.7. -#define Q_QDOC - #if @ENABLE_X11@ #define Q_OS_X11 #elif @ENABLE_MAC@ #define Q_OS_MAC #elif @ENABLE_WIN@ - #include "pysidewtypes.h" #define Q_OS_WIN #endif @@ -383,24 +51,8 @@ QT_END_NAMESPACE // not in release #define QT_NO_DEBUG -#include <QtCore/QtCore> -#if @ENABLE_MAC@ || @ENABLE_WIN@ || @ENABLE_X11@ - // Workaround to parse the QApplication header - #define Q_INTERNAL_QAPP_SRC - #undef Q_QDOC -#endif -#if @Qt5Gui_FOUND@ -# include <QtGui/QtGui> -#endif -#if @Qt5Widgets_FOUND@ -# include <QtWidgets/QtWidgets> -#endif -#ifndef Q_QDOC -// Make sure that Q_QDOC is defined for as much modules as possible. -// This creates more wrappers without extra work. -// Will disappear when we have a really good parser! -# define Q_QDOC -#endif +// Make "signals:", "slots:" visible as access specifiers +#define QT_ANNOTATE_ACCESS_SPECIFIER(a) __attribute__((annotate(#a))) #include "qpytextobject.h" // PySide class @@ -408,20 +60,26 @@ QT_END_NAMESPACE # if @Qt5X11Extras_FOUND@ # include <QtX11Extras/QX11Info> # endif -#elif @ENABLE_MAC@ -# include <QtGui/qmacstyle_mac.h> #endif // QT_WIDGETS_LIB must be defined to QSqlRelationalDelegate become visible. // It also changes code generation in pysideqtesttouch.h #define QT_WIDGETS_LIB -#undef Q_DECLARE_INTERFACE #if @Qt5Test_FOUND@ # include "pysideqtesttouch.h" #endif #ifndef QT_NO_OPENGL +// Define export macros for Windows' gl.h +# ifdef Q_OS_WIN +# ifndef APIENTRY +# define APIENTRY +# endif +# ifndef WINGDIAPI +# define WINGDIAPI +# endif +# endif // Q_OS_WIN # include <@GL_H@> #endif // QT_NO_OPENGL diff --git a/sources/pyside2/cmake/Macros/PySideModules.cmake b/sources/pyside2/cmake/Macros/PySideModules.cmake index f4bfd8858..e2a1bdcdb 100644 --- a/sources/pyside2/cmake/Macros/PySideModules.cmake +++ b/sources/pyside2/cmake/Macros/PySideModules.cmake @@ -69,9 +69,13 @@ macro(create_pyside_module # Contains include directories to pass to shiboken's preprocessor. set(shiboken_include_dirs ${pyside2_SOURCE_DIR}${PATH_SEP}${QT_INCLUDE_DIR}) + set(shiboken_framework_include_dirs_option "") if(CMAKE_HOST_APPLE) + set(shiboken_framework_include_dirs "${QT_FRAMEWORK_INCLUDE_DIR}") # On macOS, provide the framework paths for OpenGL headers. - set(shiboken_include_dirs ${shiboken_include_dirs} ${CMAKE_SYSTEM_FRAMEWORK_PATH}) + set(shiboken_framework_include_dirs ${shiboken_framework_include_dirs} ${CMAKE_SYSTEM_FRAMEWORK_PATH}) + make_path(shiboken_framework_include_dirs ${shiboken_framework_include_dirs}) + set(shiboken_framework_include_dirs_option "--framework-include-paths=${shiboken_framework_include_dirs}") endif() # Transform the path separators into something shiboken understands. @@ -81,6 +85,7 @@ macro(create_pyside_module COMMAND "${SHIBOKEN_BINARY}" ${GENERATOR_EXTRA_FLAGS} ${pyside2_BINARY_DIR}/pyside2_global.h --include-paths=${shiboken_include_dirs} + ${shiboken_framework_include_dirs_option} --typesystem-paths=${pyside2_SOURCE_DIR}${PATH_SEP}${${module_typesystem_path}} --output-directory=${CMAKE_CURRENT_BINARY_DIR} --license-file=${CMAKE_CURRENT_SOURCE_DIR}/../licensecomment.txt diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/alphachannel.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/alphachannel.cpp index 4606ce7b5..df5430bb0 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/alphachannel.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/alphachannel.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.cpp index 42ff004ac..2e4c967e2 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.cpp index f926bbc03..58fb5653b 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/mainwindow.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/mainwindow.cpp index 739e70799..45b08af63 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/mainwindow.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/mainwindow.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/droparea.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/droparea.cpp index ce25fd693..160064627 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/droparea.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/droparea.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/layouts/layouts.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/layouts/layouts.cpp index 1211ccbc5..d98d91f39 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/layouts/layouts.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/layouts/layouts.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/mainwindowsnippet.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/mainwindowsnippet.cpp index fb2440426..615d26aee 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/mainwindowsnippet.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/mainwindowsnippet.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/matrix/matrix.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/matrix/matrix.cpp index 0f5b5f441..c0512f538 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/matrix/matrix.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/matrix/matrix.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/mdiareasnippets.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/mdiareasnippets.cpp index a20f70fc2..e7dd80fe9 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/mdiareasnippets.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/mdiareasnippets.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/picture/picture.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/picture/picture.cpp index 1dba7c686..a46954197 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/picture/picture.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/picture/picture.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/polygon/polygon.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/polygon/polygon.cpp index 5641dbdbe..393ab5a70 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/polygon/polygon.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/polygon/polygon.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qfontdatabase/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qfontdatabase/main.cpp index a7abf4584..02bd2441a 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/qfontdatabase/main.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qfontdatabase/main.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsortfilterproxymodel-details/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsortfilterproxymodel-details/main.cpp index bea97889f..d951c9465 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsortfilterproxymodel-details/main.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsortfilterproxymodel-details/main.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/main.cpp index d24d11e11..cb1888da8 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/main.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/main.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.cpp index b391bcc90..f43744ed7 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.cpp index 1c85cf7cf..64b4f0a16 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.cpp index a3579b789..97e6ce164 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/shareddirmodel/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/shareddirmodel/main.cpp index 187acde31..531660469 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/shareddirmodel/main.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/shareddirmodel/main.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/splitter/splitter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/splitter/splitter.cpp index 269ca02da..3ca90077e 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/splitter/splitter.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/splitter/splitter.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/splitterhandle/splitter.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/splitterhandle/splitter.h index f067f2249..1022e56b3 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/splitterhandle/splitter.h +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/splitterhandle/splitter.h @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.cpp index aa026d755..d92a03335 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-css/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-css/main.cpp index e7d355115..ddac007c6 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-css/main.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-css/main.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.cpp index c15d43646..dedc06e86 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-texttable/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-texttable/main.cpp index 7874764db..640575050 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-texttable/main.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-texttable/main.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/transform/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/transform/main.cpp index 6d84261e9..784f4df1a 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/transform/main.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/transform/main.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/whatsthis/whatsthis.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/whatsthis/whatsthis.cpp index d25ce3637..be575f53f 100644 --- a/sources/pyside2/doc/codesnippets/doc/src/snippets/whatsthis/whatsthis.cpp +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/whatsthis/whatsthis.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.cpp b/sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.cpp index de99bb3ec..18612e4ba 100644 --- a/sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.cpp +++ b/sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp b/sources/pyside2/doc/codesnippets/examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp index 0ec3b071f..4732b7773 100644 --- a/sources/pyside2/doc/codesnippets/examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp +++ b/sources/pyside2/doc/codesnippets/examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.cpp index 82c5f891b..d22a39151 100644 --- a/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.cpp +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.cpp index fa125e01f..c6fd2894b 100644 --- a/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.cpp +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.cpp index 8dc283ebf..33cb540b4 100644 --- a/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.cpp +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.cpp index 7032ba7da..ed23e83eb 100644 --- a/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.cpp +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.cpp index 8dc283ebf..33cb540b4 100644 --- a/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.cpp +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/examples/sql/relationaltablemodel/relationaltablemodel.cpp b/sources/pyside2/doc/codesnippets/examples/sql/relationaltablemodel/relationaltablemodel.cpp index b34c652d0..8df1d73b2 100644 --- a/sources/pyside2/doc/codesnippets/examples/sql/relationaltablemodel/relationaltablemodel.cpp +++ b/sources/pyside2/doc/codesnippets/examples/sql/relationaltablemodel/relationaltablemodel.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/examples/widgets/icons/iconsizespinbox.cpp b/sources/pyside2/doc/codesnippets/examples/widgets/icons/iconsizespinbox.cpp index 22e5fbc37..f0d1f2ac6 100644 --- a/sources/pyside2/doc/codesnippets/examples/widgets/icons/iconsizespinbox.cpp +++ b/sources/pyside2/doc/codesnippets/examples/widgets/icons/iconsizespinbox.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.cpp b/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.cpp index 54a9523ee..bf07fb73c 100644 --- a/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.cpp +++ b/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.cpp @@ -21,13 +21,13 @@ ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: -## # Redistributions of source code must retain the above copyright +## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. -## # Redistributions in binary form must reproduce the above copyright +## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. -## # Neither the name of The Qt Company Ltd nor the names of its +## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## diff --git a/sources/pyside2/libpyside/CMakeLists.txt b/sources/pyside2/libpyside/CMakeLists.txt index 481062caa..b740e4039 100644 --- a/sources/pyside2/libpyside/CMakeLists.txt +++ b/sources/pyside2/libpyside/CMakeLists.txt @@ -33,7 +33,6 @@ if(Qt5Qml_FOUND) endif() else() set(QML_SUPPORT 0) - set(QML_PRIVATE_API_SUPPORT 0) set(QML_INCLUDES "") set(QML_LIBRARIES "") endif() diff --git a/sources/pyside2/tests/QtCore/CMakeLists.txt b/sources/pyside2/tests/QtCore/CMakeLists.txt index 436af3dac..f7eb86d16 100644 --- a/sources/pyside2/tests/QtCore/CMakeLists.txt +++ b/sources/pyside2/tests/QtCore/CMakeLists.txt @@ -104,6 +104,7 @@ PYSIDE_TEST(qtimer_singleshot_test.py) PYSIDE_TEST(qtimer_timeout_test.py) PYSIDE_TEST(qtnamespace_test.py) PYSIDE_TEST(qurl_test.py) +PYSIDE_TEST(qurlquery_test.py) PYSIDE_TEST(repr_test.py) PYSIDE_TEST(setprop_on_ctor_test.py) PYSIDE_TEST(staticMetaObject_test.py) diff --git a/sources/pyside2/tests/QtCore/qurl_test.py b/sources/pyside2/tests/QtCore/qurl_test.py index 595e5931f..d5eb37d6e 100644 --- a/sources/pyside2/tests/QtCore/qurl_test.py +++ b/sources/pyside2/tests/QtCore/qurl_test.py @@ -33,6 +33,7 @@ import unittest from PySide2.QtCore import QUrl +from PySide2.QtCore import QUrlQuery class QUrlBasicConstructor(unittest.TestCase): '''Tests the basic constructors''' @@ -67,59 +68,96 @@ class QUrlBasicConstructor(unittest.TestCase): self.assertEqual(url.toString(), 'ftp://john:abc123@www.google.com:8080/mail/view') +class QueryItemsTest(unittest.TestCase): + '''Test query item management''' + + def testQueryItems(self): + url = QUrl('http://www.google.com/search?q=python&hl=en') + valid_data = [(('q'), ('python')), (('hl'), ('en'))] + + self.assertEqual(sorted(QUrlQuery(url.query()).queryItems()), sorted(valid_data)) + + def testEncodedQueryItems(self): + url = QUrl('http://www.google.com/search?q=python&hl=en') + valid_data = [(('q'), ('python')), (('hl'), ('en'))] + + self.assertEqual(sorted(QUrlQuery(url.query()).queryItems()), sorted(valid_data)) + + def testSetQueryItems(self): + urla = QUrl('http://www.google.com/search?q=python&hl=en') + urlb = QUrl('http://www.google.com/search') + + urlb.setQuery(urla.query()) + + self.assertEqual(urla, urlb) + + def testAddQueryItem(self): + url = QUrlQuery() + valid_data = [('hl', 'en'), ('user', 'konqui')] + + url.addQueryItem(*valid_data[0]) + self.assertEqual(url.queryItems()[0], valid_data[0]) + + url.addQueryItem(*valid_data[1]) + self.assertEqual(sorted(url.queryItems()), sorted(valid_data)) + + def testAllQueryItemsValues(self): + url = QUrlQuery() + key = 'key' + valid_data = ['data', 'valid', 'test'] + + for i, data in enumerate(valid_data): + url.addQueryItem(key, data) + self.assertEqual(url.allQueryItemValues(key), + list(valid_data[:i+1])) + def testPath(self): url = QUrl("http://qt-project.org/images/ban/pgs_front.jpg") self.assertEqual(url.path(), "/images/ban/pgs_front.jpg") # PYSIDE-345: No bindings for QUrlQuery -# class QueryItemsTest(unittest.TestCase): -# '''Test query item management''' -# -# def testQueryItems(self): -# #QUrl.queryItems -# url = QUrl('http://www.google.com/search?q=python&hl=en') -# valid_data = [(('q'), ('python')), (('hl'), ('en'))] -# -# self.assertEqual(sorted(url.queryItems()), sorted(valid_data)) -# -# def testEncodedQueryItems(self): -# #QUrl.encodedQueryItems -# url = QUrl('http://www.google.com/search?q=python&hl=en') -# valid_data = [(('q'), ('python')), (('hl'), ('en'))] -# -# self.assertEqual(sorted(url.encodedQueryItems()), sorted(valid_data)) -# -# def testSetQueryItems(self): -# #QUrl.setQueryItems -# urla = QUrl('http://www.google.com/search?q=python&hl=en') -# urlb = QUrl('http://www.google.com/search') -# -# urlb.setQueryItems(urla.queryItems()) -# -# self.assertEqual(urla, urlb) -# -# def testAddQueryItem(self): -# #QUrl.addQueryItem -# url = QUrl() -# valid_data = [('hl', 'en'), ('user', 'konqui')] -# -# url.addQueryItem(*valid_data[0]) -# self.assertEqual(url.queryItems()[0], valid_data[0]) -# -# url.addQueryItem(*valid_data[1]) -# self.assertEqual(sorted(url.queryItems()), sorted(valid_data)) -# -# def testAllEncodedQueryItemsValues(self): -# #QUrl.allEncodedQueryItemValues -# url = QUrl() -# key = 'key' -# valid_data = ['data', 'valid', 'test'] -# -# for i, data in enumerate(valid_data): -# url.addQueryItem(key, data) -# self.assertEqual(url.allEncodedQueryItemValues(key), -# list(valid_data[:i+1])) +class QueryItemsTest(unittest.TestCase): + '''Test query item management''' + + def testQueryItems(self): + url = QUrl('http://www.google.com/search?q=python&hl=en') + valid_data = [(('q'), ('python')), (('hl'), ('en'))] + + self.assertEqual(sorted(QUrlQuery(url.query()).queryItems()), sorted(valid_data)) + + def testEncodedQueryItems(self): + url = QUrl('http://www.google.com/search?q=python&hl=en') + valid_data = [(('q'), ('python')), (('hl'), ('en'))] + + self.assertEqual(sorted(QUrlQuery(url.query()).queryItems()), sorted(valid_data)) + + def testSetQueryItems(self): + urla = QUrl('http://www.google.com/search?q=python&hl=en') + urlb = QUrl('http://www.google.com/search') + + urlb.setQuery(urla.query()) + + self.assertEqual(urla, urlb) + + def testAddQueryItem(self): + url = QUrlQuery() + valid_data = [('hl', 'en'), ('user', 'konqui')] + + url.addQueryItem(*valid_data[0]) + self.assertEqual(url.queryItems()[0], valid_data[0]) + + url.addQueryItem(*valid_data[1]) + self.assertEqual(sorted(url.queryItems()), sorted(valid_data)) + + def testAllQueryItemsValues(self): + url = QUrlQuery() + key = 'key' + valid_data = ['data', 'valid', 'test'] + for i, data in enumerate(valid_data): + url.addQueryItem(key, data) + self.assertEqual(url.allQueryItemValues(key), + list(valid_data[:i+1])) if __name__ == '__main__': unittest.main() diff --git a/sources/pyside2/tests/QtCore/qurlquery_test.py b/sources/pyside2/tests/QtCore/qurlquery_test.py new file mode 100644 index 000000000..e42856e6d --- /dev/null +++ b/sources/pyside2/tests/QtCore/qurlquery_test.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of PySide2. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +'''Unit tests for QUrlQuery''' + +import unittest +import ctypes +import sys + +from PySide2.QtCore import QUrlQuery + +class QUrlQueryTest(unittest.TestCase): + def testConstructing(self): + empty = QUrlQuery() + self.assertTrue(empty.isEmpty()) + self.assertEqual(empty.queryPairDelimiter(), QUrlQuery.defaultQueryPairDelimiter()) + self.assertEqual(empty.queryValueDelimiter(), QUrlQuery.defaultQueryValueDelimiter()) + + empty.clear(); + self.assertTrue(empty.isEmpty()) + + def testAddRemove(self): + query = QUrlQuery() + + query.addQueryItem("a", "b"); + self.assertTrue(not query.isEmpty()) + self.assertTrue(query.hasQueryItem("a")) + self.assertEqual(query.queryItemValue("a"), "b") + self.assertEqual(query.allQueryItemValues("a"), ["b"]) + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2/tests/QtGui/CMakeLists.txt b/sources/pyside2/tests/QtGui/CMakeLists.txt index 63cf3c35f..eeb7c7e36 100644 --- a/sources/pyside2/tests/QtGui/CMakeLists.txt +++ b/sources/pyside2/tests/QtGui/CMakeLists.txt @@ -37,6 +37,7 @@ PYSIDE_TEST(qpolygonf_test.py) PYSIDE_TEST(qkeysequence_test.py) PYSIDE_TEST(qradialgradient_test.py) PYSIDE_TEST(qrasterwindow_test.py) +PYSIDE_TEST(qopenglwindow_test.py) PYSIDE_TEST(qregion_test.py) PYSIDE_TEST(qstylehints_test.py) PYSIDE_TEST(qtextdocument_undoredo_test.py) diff --git a/sources/pyside2/tests/QtGui/qopenglwindow_test.py b/sources/pyside2/tests/QtGui/qopenglwindow_test.py new file mode 100644 index 000000000..2d11a0238 --- /dev/null +++ b/sources/pyside2/tests/QtGui/qopenglwindow_test.py @@ -0,0 +1,104 @@ +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of PySide2. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +'''Unit test for QOpenGLContext, QOpenGLTexture, QOpenGLWindow and related classes''' + +import sys +import unittest + +from helper import UsesQApplication + +from PySide2.QtCore import QSize, QTimer, Qt +from PySide2.QtGui import (QColor, QGuiApplication, QImage, QOpenGLContext, + QOpenGLTexture, QSurfaceFormat, QOpenGLWindow) + +try: + from OpenGL import GL +except ImportError: + print("Skipping test due to missing OpenGL module") + sys.exit(0) + +class OpenGLWindow(QOpenGLWindow): + def __init__(self): + super(OpenGLWindow, self).__init__() + + self.m_functions = None + self.m_texture = None + self.visibleChanged.connect(self.slotVisibleChanged) + + def slotVisibleChanged(self, visible): + if not visible and self.m_texture is not None and self.context().makeCurrent(self): + self.m_texture = None + self.context().doneCurrent() + + def initializeGL(self): + self.m_functions = self.context().functions() + self.m_functions.initializeOpenGLFunctions() + image = QImage(QSize(200, 200), QImage.Format_RGBA8888) + image.fill(QColor(Qt.red)) + self.m_texture = QOpenGLTexture(image) + + def paintGL(self): + GL.glMatrixMode(GL.GL_MODELVIEW); + GL.glLoadIdentity(); + + GL.glMatrixMode(GL.GL_PROJECTION); + GL.glLoadIdentity(); + GL.glOrtho(0, 1, 1, 0, -1, 1); + + self.m_functions.glClear(GL.GL_COLOR_BUFFER_BIT) + self.m_functions.glEnable(GL.GL_TEXTURE_2D); + self.m_texture.bind() + + d = 0.5 + GL.glBegin(GL.GL_QUADS) + GL.glTexCoord2f(0, 0) + GL.glVertex2f(0, 0) + GL.glTexCoord2f(d, 0) + GL.glVertex2f(d, 0) + GL.glTexCoord2f(d, d) + GL.glVertex2f(d, d) + GL.glTexCoord2f(0, d) + GL.glVertex2f(0, d) + GL.glEnd() + self.m_texture.release() + + def resizeGL(self, w, h): + self.m_functions.glViewport(0, 0, self.width(), self.height()) + +class QOpenGLWindowTest(UsesQApplication): + # On macOS, glClear(), glViewport() are rejected due to GLbitfield/GLint not being resolved properly + def test(self): + openGlWindow = OpenGLWindow() + openGlWindow.resize(640, 480) + openGlWindow.show() + QTimer.singleShot(100, openGlWindow.close) + self.app.exec_() + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2/tests/QtQml/CMakeLists.txt b/sources/pyside2/tests/QtQml/CMakeLists.txt index 8460a8f0b..78aa33450 100755 --- a/sources/pyside2/tests/QtQml/CMakeLists.txt +++ b/sources/pyside2/tests/QtQml/CMakeLists.txt @@ -17,4 +17,3 @@ PYSIDE_TEST(connect_python_qml.py) PYSIDE_TEST(registertype.py) PYSIDE_TEST(javascript_exceptions.py) PYSIDE_TEST(qqmlincubator_incubateWhile.py) -PYSIDE_TEST(qquickitem_grabToImage.py) diff --git a/sources/pyside2/tests/QtTextToSpeech/CMakeLists.txt b/sources/pyside2/tests/QtTextToSpeech/CMakeLists.txt new file mode 100644 index 000000000..6f5851587 --- /dev/null +++ b/sources/pyside2/tests/QtTextToSpeech/CMakeLists.txt @@ -0,0 +1 @@ +PYSIDE_TEST(qtexttospeech_test.py) diff --git a/sources/pyside2/tests/QtTextToSpeech/qtexttospeech_test.py b/sources/pyside2/tests/QtTextToSpeech/qtexttospeech_test.py new file mode 100644 index 000000000..6f26f3691 --- /dev/null +++ b/sources/pyside2/tests/QtTextToSpeech/qtexttospeech_test.py @@ -0,0 +1,63 @@ +#!/usr/bin/python + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of PySide2. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +'''Test cases for QTextToSpeech methods''' + +from helper import UsesQApplication +import sys +import unittest + +from PySide2.QtCore import QTimer + +try: + from PySide2.QtTextToSpeech import QTextToSpeech, QVoice +except ImportError: + print("Skipping test due to missing QtTextToSpeech module") + sys.exit(0) + +class QTextToSpeechTestCase(UsesQApplication): + '''Tests related to QTextToSpeech''' + def testSay(self): + engines = QTextToSpeech.availableEngines() + if not engines: + print('No QTextToSpeech engines available') + else: + speech = QTextToSpeech(engines[0]) + speech.stateChanged.connect(self._slotStateChanged) + speech.say("Hello, PySide2") + QTimer.singleShot(5000, self.app.quit) + self.app.exec_() + + def _slotStateChanged(self, state): + if (state == QTextToSpeech.State.Ready): + self.app.quit() + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2/tests/pysidetest/CMakeLists.txt b/sources/pyside2/tests/pysidetest/CMakeLists.txt index 3a5437e62..05b0b86b4 100644 --- a/sources/pyside2/tests/pysidetest/CMakeLists.txt +++ b/sources/pyside2/tests/pysidetest/CMakeLists.txt @@ -35,14 +35,32 @@ ${CMAKE_CURRENT_BINARY_DIR}/testbinding/testview_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/testbinding/testbinding_module_wrapper.cpp ) +# Get per module include dirs. +# There are usually 3 paths there: +# ./qt/include/; ./qt/include/QtCore ; ./qt/mkspecs/linux-g++ +# on framework build they are: +# ./qt/lib/QtCore.framework; ./qt/lib/QtCore.framework/Headers ; ./qt/mkspecs/macx-clang +# Thus we use the second direct path, which contains the actual header files. + +list(GET Qt5Core_INCLUDE_DIRS 1 Qt5Core_DIRECT_INCLUDE_DIR) +list(GET Qt5Gui_INCLUDE_DIRS 1 Qt5Gui_DIRECT_INCLUDE_DIR) +list(GET Qt5Widgets_INCLUDE_DIRS 1 Qt5Widgets_DIRECT_INCLUDE_DIR) + +# Adjust include headers paths for frameworks. +set(shiboken_framework_include_dirs_option "") +if(CMAKE_HOST_APPLE AND QtCore_is_framework) + set(shiboken_framework_include_dirs "${QT_FRAMEWORK_INCLUDE_DIR}") + set(shiboken_framework_include_dirs_option "--framework-include-paths=${shiboken_framework_include_dirs}") +endif() + make_path(testbinding_include_dirs ${pyside2_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../../PySide2 ${CMAKE_CURRENT_SOURCE_DIR}/../../libpyside ${QT_INCLUDE_DIR} - ${QT_INCLUDE_DIR}/QtCore - ${QT_INCLUDE_DIR}/QtGui - ${QT_INCLUDE_DIR}/QtWidgets + ${Qt5Core_DIRECT_INCLUDE_DIR} + ${Qt5Gui_DIRECT_INCLUDE_DIR} + ${Qt5Widgets_DIRECT_INCLUDE_DIR} ) make_path(testbinding_typesystem_path ${CMAKE_CURRENT_SOURCE_DIR} @@ -55,6 +73,7 @@ add_custom_command(OUTPUT ${testbinding_SRC} COMMAND ${SHIBOKEN_BINARY} ${GENERATOR_EXTRA_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/pysidetest_global.h --include-paths=${testbinding_include_dirs} + ${shiboken_framework_include_dirs_option} --typesystem-paths=${testbinding_typesystem_path} --output-directory=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_pysidetest.xml diff --git a/sources/shiboken2/ApiExtractor/CMakeLists.txt b/sources/shiboken2/ApiExtractor/CMakeLists.txt index 26ae03173..6cb3e0185 100644 --- a/sources/shiboken2/ApiExtractor/CMakeLists.txt +++ b/sources/shiboken2/ApiExtractor/CMakeLists.txt @@ -31,7 +31,6 @@ set(apiextractor_SRC apiextractor.cpp abstractmetabuilder.cpp abstractmetalang.cpp -asttoxml.cpp fileout.cpp graph.cpp reporthandler.cpp @@ -39,28 +38,19 @@ typeparser.cpp typesystem.cpp include.cpp typedatabase.cpp -parser/ast.cpp -parser/binder.cpp -parser/class_compiler.cpp +# Clang +clangparser/compilersupport.cpp +clangparser/clangparser.cpp +clangparser/clangbuilder.cpp +clangparser/clangdebugutils.cpp +clangparser/clangutils.cpp +# Old parser parser/codemodel.cpp -parser/codemodel_finder.cpp -parser/compiler_utils.cpp -parser/control.cpp -parser/declarator_compiler.cpp -parser/default_visitor.cpp -parser/dumptree.cpp -parser/lexer.cpp -parser/list.cpp -parser/name_compiler.cpp -parser/parser.cpp -parser/smallobject.cpp -parser/tokens.cpp -parser/type_compiler.cpp -parser/visitor.cpp -parser/rpp/builtin-macros.cpp -parser/rpp/preprocessor.cpp ) +set(APIEXTRACTOR_EXTRA_INCLUDES ${CLANG_EXTRA_INCLUDES}) +set(APIEXTRACTOR_EXTRA_LIBRARIES ${CLANG_EXTRA_LIBRARIES}) + if (NOT DISABLE_DOCSTRINGS) set(apiextractor_SRC ${apiextractor_SRC} @@ -68,16 +58,12 @@ if (NOT DISABLE_DOCSTRINGS) doxygenparser.cpp qtdocparser.cpp ) - set(APIEXTRACTOR_EXTRA_INCLUDES ${LIBXSLT_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR}) - set(APIEXTRACTOR_EXTRA_LIBRARIES ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES}) -else() - set(APIEXTRACTOR_EXTRA_INCLUDES "") - set(APIEXTRACTOR_EXTRA_LIBRARIES "") + set(APIEXTRACTOR_EXTRA_INCLUDES ${APIEXTRACTOR_EXTRA_INCLUDES} ${LIBXSLT_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR}) + set(APIEXTRACTOR_EXTRA_LIBRARIES ${APIEXTRACTOR_EXTRA_LIBRARIES} ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES}) endif() set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE) -qt5_add_resources(apiextractor_RCCS_SRC generator.qrc) set(CMAKE_AUTOMOC ON) include_directories(${CMAKE_CURRENT_SOURCE_DIR} @@ -96,6 +82,8 @@ target_link_libraries(apiextractor ${APIEXTRACTOR_EXTRA_LIBRARIES} ) +set_property(TARGET apiextractor PROPERTY CXX_STANDARD 11) + if (BUILD_TESTS) enable_testing() add_subdirectory(tests) diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index e71841ec3..3b2ecf8e1 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -30,18 +30,16 @@ #include "reporthandler.h" #include "typedatabase.h" -#include "parser/ast.h" -#include "parser/binder.h" -#include "parser/control.h" -#include "parser/default_visitor.h" -#include "parser/dumptree.h" -#include "parser/lexer.h" -#include "parser/parser.h" -#include "parser/tokens.h" +#include <clangparser/clangbuilder.h> +#include <clangparser/clangutils.h> + +#include "parser/codemodel.h" #include <QDebug> +#include <QDir> #include <QFile> #include <QFileInfo> +#include <QRegularExpression> #include <QTextCodec> #include <QTextStream> #include <QVariant> @@ -168,19 +166,19 @@ QSet<QString> AbstractMetaBuilder::qtMetaTypeDeclaredTypeNames() const void AbstractMetaBuilderPrivate::checkFunctionModifications() { TypeDatabase *types = TypeDatabase::instance(); - SingleTypeEntryHash entryHash = types->entries(); - QList<TypeEntry*> entries = entryHash.values(); + const SingleTypeEntryHash entryHash = types->entries(); - foreach (TypeEntry* entry, entries) { + for (SingleTypeEntryHash::const_iterator it = entryHash.cbegin(), end = entryHash.cend(); it != end; ++it) { + const TypeEntry *entry = it.value(); if (!entry) continue; if (!entry->isComplex() || entry->codeGeneration() == TypeEntry::GenerateNothing) continue; - ComplexTypeEntry* centry = static_cast<ComplexTypeEntry*>(entry); + const ComplexTypeEntry* centry = static_cast<const ComplexTypeEntry*>(entry); FunctionModificationList modifications = centry->functionModifications(); - foreach (const FunctionModification &modification, modifications) { + for (const FunctionModification &modification : qAsConst(modifications)) { QString signature = modification.signature; QString name = signature.trimmed(); @@ -190,10 +188,10 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications() if (!clazz) continue; - AbstractMetaFunctionList functions = clazz->functions(); + const AbstractMetaFunctionList functions = clazz->functions(); bool found = false; QStringList possibleSignatures; - foreach (AbstractMetaFunction *function, functions) { + for (AbstractMetaFunction *function : functions) { if (function->minimalSignature() == signature && function->implementingClass() == clazz) { found = true; break; @@ -427,7 +425,8 @@ void AbstractMetaBuilderPrivate::fixQObjectForScope(const FileModelItem &dom, const TypeDatabase *types, const NamespaceModelItem &scope) { - foreach (const ClassModelItem &item, scope->classes()) { + const ClassList &scopeClasses = scope->classes(); + for (const ClassModelItem &item : scopeClasses) { QString qualifiedName = item->qualifiedName().join(colonColon()); TypeEntry* entry = types->findType(qualifiedName); if (entry) { @@ -437,7 +436,7 @@ void AbstractMetaBuilderPrivate::fixQObjectForScope(const FileModelItem &dom, } const NamespaceList &namespaces = scope->namespaces(); - foreach (const NamespaceModelItem &n, namespaces) { + for (const NamespaceModelItem &n : namespaces) { if (scope != n) fixQObjectForScope(dom, types, n); } @@ -445,29 +444,26 @@ void AbstractMetaBuilderPrivate::fixQObjectForScope(const FileModelItem &dom, void AbstractMetaBuilderPrivate::sortLists() { - foreach (AbstractMetaClass *cls, m_metaClasses) + for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) cls->sortFunctions(); } -FileModelItem AbstractMetaBuilderPrivate::buildDom(QIODevice *input) +FileModelItem AbstractMetaBuilderPrivate::buildDom(const QByteArrayList &arguments, + unsigned clangFlags) { - Q_ASSERT(input); - - if (!input->isOpen() && !input->open(QIODevice::ReadOnly)) - return FileModelItem(); - - QByteArray contents = input->readAll(); - input->close(); - - Control control; - Parser p(&control); - pool __pool; - - TranslationUnitAST* ast = p.parse(contents, contents.size(), &__pool); - - CodeModel model; - Binder binder(&model, p.location()); - return binder.run(ast); + clang::Builder builder; + FileModelItem result = clang::parse(arguments, clangFlags, builder) + ? builder.dom() : FileModelItem(); + const clang::BaseVisitor::Diagnostics &diagnostics = builder.diagnostics(); + if (const int diagnosticsCount = diagnostics.size()) { + QDebug d = qWarning(); + d.nospace(); + d.noquote(); + d << "Clang: " << diagnosticsCount << " diagnostic messages:\n"; + for (int i = 0; i < diagnosticsCount; ++i) + d << " " << diagnostics.at(i) << '\n'; + } + return result; } void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) @@ -482,7 +478,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) // Start the generation... const ClassList &typeValues = dom->classes(); ReportHandler::setProgressReference(typeValues); - foreach (const ClassModelItem &item, typeValues) { + for (const ClassModelItem &item : typeValues) { ReportHandler::progress(QLatin1String("Generating class model...")); AbstractMetaClass *cls = traverseClass(dom, item); if (!cls) @@ -492,8 +488,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) } // We need to know all global enums - ReportHandler::setProgressReference(dom->enums()); - foreach (const EnumModelItem &item, dom->enums()) { + const EnumList &enums = dom->enums(); + ReportHandler::setProgressReference(enums); + for (const EnumModelItem &item : enums) { ReportHandler::progress(QLatin1String("Generating enum model...")); AbstractMetaEnum *metaEnum = traverseEnum(item, 0, QSet<QString>()); if (metaEnum) { @@ -504,7 +501,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) const QSet<NamespaceModelItem> &namespaceTypeValues = dom->uniqueNamespaces(); ReportHandler::setProgressReference(namespaceTypeValues); - foreach (NamespaceModelItem item, namespaceTypeValues) { + for (NamespaceModelItem item : namespaceTypeValues) { ReportHandler::progress(QLatin1String("Generating namespace model...")); AbstractMetaClass *metaClass = traverseNamespace(dom, item); if (metaClass) @@ -513,9 +510,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) // Go through all typedefs to see if we have defined any // specific typedefs to be used as classes. - TypeDefList typeDefs = dom->typeDefs(); + const TypeDefList typeDefs = dom->typeDefs(); ReportHandler::setProgressReference(typeDefs); - foreach (const TypeDefModelItem &typeDef, typeDefs) { + for (const TypeDefModelItem &typeDef : typeDefs) { ReportHandler::progress(QLatin1String("Resolving typedefs...")); AbstractMetaClass* cls = traverseTypeDef(dom, typeDef); addAbstractMetaClass(cls); @@ -523,14 +520,15 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) figureOutEnumValues(); - foreach (const ClassModelItem &item, typeValues) + for (const ClassModelItem &item : typeValues) traverseClassMembers(item); - foreach (const NamespaceModelItem &item, namespaceTypeValues) + for (const NamespaceModelItem &item : namespaceTypeValues) traverseNamespaceMembers(item); // Global functions - foreach (const FunctionModelItem &func, dom->functions()) { + const FunctionList &functions = dom->functions(); + for (const FunctionModelItem &func : functions) { if (func->accessPolicy() != CodeModel::Public || func->name().startsWith(QLatin1String("operator"))) continue; @@ -558,14 +556,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) } ReportHandler::setProgressReference(m_metaClasses); - foreach (AbstractMetaClass* cls, m_metaClasses) { + for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { ReportHandler::progress(QLatin1String("Fixing class inheritance...")); if (!cls->isInterface() && !cls->isNamespace()) setupInheritance(cls); } ReportHandler::setProgressReference(m_metaClasses); - foreach (AbstractMetaClass* cls, m_metaClasses) { + for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { ReportHandler::progress(QLatin1String("Detecting inconsistencies in class model...")); cls->fixFunctions(); @@ -586,11 +584,10 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) if (cls->isAbstract() && !cls->isInterface()) cls->typeEntry()->setLookupName(cls->typeEntry()->targetLangName() + QLatin1String("$ConcreteWrapper")); } - TypeEntryHash allEntries = types->allEntries(); + const TypeEntryHash allEntries = types->allEntries(); ReportHandler::progress(QLatin1String("Detecting inconsistencies in typesystem...")); - foreach (QList<TypeEntry*> entries, allEntries) { - foreach (TypeEntry* entry, entries) { - + for (TypeEntryHash::const_iterator it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) { + for (TypeEntry *entry : it.value()) { if (entry->isPrimitive()) continue; @@ -606,9 +603,10 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) .arg(entry->qualifiedCppName()); } else if (entry->generateCode() && entry->type() == TypeEntry::FunctionType) { const FunctionTypeEntry* fte = static_cast<const FunctionTypeEntry*>(entry); - foreach (const QString &signature, fte->signatures()) { + const QStringList &signatures = fte->signatures(); + for (const QString &signature : signatures) { bool ok = false; - foreach (AbstractMetaFunction* func, m_globalFunctions) { + for (AbstractMetaFunction* func : qAsConst(m_globalFunctions)) { if (signature == func->minimalSignature()) { ok = true; break; @@ -628,7 +626,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) if (cls) { enumFound = cls->findEnum(entry->targetLangName()); } else { // Global enum - foreach (AbstractMetaEnum* metaEnum, m_enums) { + for (AbstractMetaEnum *metaEnum : qAsConst(m_enums)) { if (metaEnum->typeEntry() == entry) { enumFound = true; break; @@ -647,14 +645,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) } { - FunctionList hashFunctions = dom->findFunctions(QLatin1String("qHash")); - foreach (const FunctionModelItem &item, hashFunctions) + const FunctionList &hashFunctions = dom->findFunctions(QLatin1String("qHash")); + for (const FunctionModelItem &item : hashFunctions) registerHashFunction(item); } { - FunctionList hashFunctions = dom->findFunctions(QLatin1String("operator<<")); - foreach (const FunctionModelItem &item, hashFunctions) + const FunctionList &streamOps = dom->findFunctions(QLatin1String("operator<<")); + for (const FunctionModelItem &item : streamOps) registerToStringCapability(item); } @@ -671,7 +669,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) const FunctionList potentiallyBinaryOperators = dom->findFunctions(QStringLiteral("operator*")) + dom->findFunctions(QStringLiteral("operator&")); - foreach (const FunctionModelItem &item, potentiallyBinaryOperators) { + for (const FunctionModelItem &item : potentiallyBinaryOperators) { if (!item->arguments().isEmpty()) binaryOperators.append(item); } @@ -682,14 +680,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) binaryOperators.append(dom->findFunctions(QStringLiteral("operator~"))); binaryOperators.append(dom->findFunctions(QStringLiteral("operator>"))); - foreach (const FunctionModelItem &item, binaryOperators) + for (const FunctionModelItem &item : qAsConst(binaryOperators)) traverseOperatorFunction(item); } { - FunctionList streamOperators = dom->findFunctions(QLatin1String("operator<<")) - + dom->findFunctions(QLatin1String("operator>>")); - foreach (const FunctionModelItem &item, streamOperators) + const FunctionList streamOperators = dom->findFunctions(QLatin1String("operator<<")) + + dom->findFunctions(QLatin1String("operator>>")); + for (const FunctionModelItem &item : streamOperators) traverseStreamOperator(item); } @@ -699,7 +697,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) // sort all classes topologically m_metaClasses = classesTopologicalSorted(); - foreach (AbstractMetaClass* cls, m_metaClasses) { + for (AbstractMetaClass* cls : qAsConst(m_metaClasses)) { // setupEquals(cls); // setupComparable(cls); setupClonable(cls); @@ -719,7 +717,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) m_currentClass = 0; // Functions added to the module on the type system. - foreach (const AddedFunction &addedFunc, types->globalUserFunctions()) { + const AddedFunctionList &globalUserFunctions = types->globalUserFunctions(); + for (const AddedFunction &addedFunc : globalUserFunctions) { AbstractMetaFunction* metaFunc = traverseFunction(addedFunc); metaFunc->setFunctionType(AbstractMetaFunction::NormalFunction); m_globalFunctions << metaFunc; @@ -728,13 +727,15 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) std::puts(""); } -bool AbstractMetaBuilder::build(QIODevice *input) +bool AbstractMetaBuilder::build(const QByteArrayList &arguments, unsigned clangFlags) { - FileModelItem dom = d->buildDom(input); - const bool result = dom.data() != Q_NULLPTR; - if (result) - d->traverseDom(dom); - return result; + const FileModelItem dom = d->buildDom(arguments, clangFlags); + if (dom.isNull()) + return false; + if (ReportHandler::isDebug(ReportHandler::MediumDebug)) + qCDebug(lcShiboken) << dom.data(); + d->traverseDom(dom); + return true; } void AbstractMetaBuilder::setLogDirectory(const QString& logDir) @@ -801,8 +802,8 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel pushScope(namespaceItem); m_namespacePrefix = currentScope()->qualifiedName().join(colonColon()); - ClassList classes = namespaceItem->classes(); - foreach (const ClassModelItem &cls, classes) { + const ClassList &classes = namespaceItem->classes(); + for (const ClassModelItem &cls : classes) { AbstractMetaClass* mjc = traverseClass(dom, cls); if (mjc) { metaClass->addInnerClass(mjc); @@ -814,7 +815,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel // Go through all typedefs to see if we have defined any // specific typedefs to be used as classes. const TypeDefList typeDefs = namespaceItem->typeDefs(); - foreach (const TypeDefModelItem &typeDef, typeDefs) { + for (const TypeDefModelItem &typeDef : typeDefs) { AbstractMetaClass *cls = traverseTypeDef(dom, typeDef); if (cls) { metaClass->addInnerClass(cls); @@ -825,7 +826,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel // Traverse namespaces recursively const QSet<NamespaceModelItem> &innerNamespaces = namespaceItem->uniqueNamespaces(); - foreach (const NamespaceModelItem &ni, innerNamespaces) { + for (const NamespaceModelItem &ni : innerNamespaces) { AbstractMetaClass* mjc = traverseNamespace(dom, ni); if (mjc) { metaClass->addInnerClass(mjc); @@ -985,8 +986,8 @@ void AbstractMetaBuilderPrivate::figureOutEnumValuesForClass(AbstractMetaClass * if (classes->contains(metaClass)) return; - AbstractMetaEnumList enums = metaClass->enums(); - foreach (AbstractMetaEnum* e, enums) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (AbstractMetaEnum* e : enums) { if (!e) { qCWarning(lcShiboken).noquote().nospace() << "bad enum in class " << metaClass->name(); continue; @@ -1009,10 +1010,10 @@ void AbstractMetaBuilderPrivate::figureOutEnumValues() // Keep a set of classes that we already traversed. We use this to // enforce that we traverse base classes prior to subclasses. QSet<AbstractMetaClass*> classes; - foreach (AbstractMetaClass *c, m_metaClasses) + for (AbstractMetaClass *c : qAsConst(m_metaClasses)) figureOutEnumValuesForClass(c, &classes); - foreach (AbstractMetaEnum* metaEnum, m_globalEnums) { + for (AbstractMetaEnum* metaEnum : qAsConst(m_globalEnums)) { AbstractMetaEnumValueList enumValues = metaEnum->values(); int value = 0; for (int i = 0; i < enumValues.size(); ++i) { @@ -1025,9 +1026,11 @@ void AbstractMetaBuilderPrivate::figureOutEnumValues() void AbstractMetaBuilderPrivate::figureOutDefaultEnumArguments() { - foreach (AbstractMetaClass* metaClass, m_metaClasses) { - foreach (AbstractMetaFunction* metaFunction, metaClass->functions()) { - foreach (AbstractMetaArgument *arg, metaFunction->arguments()) { + for (AbstractMetaClass* metaClass : qAsConst(m_metaClasses)) { + const AbstractMetaFunctionList &functions = metaClass->functions(); + for (AbstractMetaFunction* metaFunction : functions) { + const AbstractMetaArgumentList &arguments = metaFunction->arguments(); + for (AbstractMetaArgument *arg : arguments) { QString expr = arg->defaultValueExpression(); if (expr.isEmpty()) continue; @@ -1063,7 +1066,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte typeEntry = TypeDatabase::instance()->findType(qualifiedName); } else { QStringList tmpQualifiedName = enumItem->qualifiedName(); - foreach (const EnumeratorModelItem& enumValue, enumItem->enumerators()) { + const EnumeratorList &enums = enumItem->enumerators(); + for (const EnumeratorModelItem& enumValue : enums) { tmpQualifiedName.removeLast(); tmpQualifiedName << enumValue->name(); qualifiedName = tmpQualifiedName.join(colonColon()); @@ -1079,10 +1083,11 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte if (m_currentClass) className = m_currentClass->typeEntry()->qualifiedCppName(); - if (TypeDatabase::instance()->isEnumRejected(className, enumName)) { + QString rejectReason; + if (TypeDatabase::instance()->isEnumRejected(className, enumName, &rejectReason)) { if (typeEntry) typeEntry->setCodeGeneration(TypeEntry::GenerateNothing); - m_rejectedEnums.insert(qualifiedName, AbstractMetaBuilder::GenerationDisabled); + m_rejectedEnums.insert(qualifiedName + rejectReason, AbstractMetaBuilder::GenerationDisabled); return 0; } @@ -1119,7 +1124,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte if (ReportHandler::isDebug(ReportHandler::MediumDebug)) qCDebug(lcShiboken) << " - traversing enum " << metaEnum->fullName(); - foreach (const EnumeratorModelItem &value, enumItem->enumerators()) { + const EnumeratorList &enums = enumItem->enumerators(); + for (const EnumeratorModelItem &value : enums) { AbstractMetaEnumValue *metaEnumValue = q->createMetaEnumValue(); metaEnumValue->setName(value->name()); @@ -1148,7 +1154,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte metaEnum->setOriginalAttributes(metaEnum->attributes()); // Register all enum values on Type database - foreach(EnumeratorModelItem e, enumItem->enumerators()) { + const EnumeratorList &enumerators = enumItem->enumerators(); + for (EnumeratorModelItem e : enumItem->enumerators()) { QString name; if (enclosing) { name += enclosing->name(); @@ -1271,7 +1278,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem } TemplateParameterList template_parameters = classItem->templateParameters(); - QList<TypeEntry *> template_args; + QVector<TypeEntry *> template_args; template_args.clear(); for (int i = 0; i < template_parameters.size(); ++i) { const TemplateParameterModelItem ¶m = template_parameters.at(i); @@ -1288,7 +1295,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem // Inner classes { const ClassList &innerClasses = classItem->classes(); - foreach (const ClassModelItem &ci, innerClasses) { + for (const ClassModelItem &ci : innerClasses) { AbstractMetaClass *cl = traverseClass(dom, ci); if (cl) { cl->setEnclosingClass(metaClass); @@ -1302,7 +1309,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem // Go through all typedefs to see if we have defined any // specific typedefs to be used as classes. const TypeDefList typeDefs = classItem->typeDefs(); - foreach (const TypeDefModelItem &typeDef, typeDefs) { + for (const TypeDefModelItem &typeDef : typeDefs) { AbstractMetaClass *cls = traverseTypeDef(dom, typeDef); if (cls) { cls->setEnclosingClass(metaClass); @@ -1329,7 +1336,7 @@ void AbstractMetaBuilderPrivate::traverseScopeMembers(ScopeModelItem item, // Inner classes const ClassList &innerClasses = item->classes(); - foreach (const ClassModelItem& ci, innerClasses) + for (const ClassModelItem& ci : innerClasses) traverseClassMembers(ci); } @@ -1380,7 +1387,7 @@ void AbstractMetaBuilderPrivate::traverseNamespaceMembers(NamespaceModelItem ite // Inner namespaces const QSet<NamespaceModelItem> &innerNamespaces = item->uniqueNamespaces(); - foreach (const NamespaceModelItem &ni, innerNamespaces) + for (const NamespaceModelItem &ni : innerNamespaces) traverseNamespaceMembers(ni); m_currentClass = oldCurrentClass; @@ -1410,8 +1417,9 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(VariableModelItem f if (field->accessPolicy() == CodeModel::Private) return 0; - if (TypeDatabase::instance()->isFieldRejected(className, fieldName)) { - m_rejectedFields.insert(qualifiedFieldSignatureWithType(className, field), + QString rejectReason; + if (TypeDatabase::instance()->isFieldRejected(className, fieldName, &rejectReason)) { + m_rejectedFields.insert(qualifiedFieldSignatureWithType(className, field) + rejectReason, AbstractMetaBuilder::GenerationDisabled); return 0; } @@ -1455,7 +1463,8 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(VariableModelItem f void AbstractMetaBuilderPrivate::traverseFields(ScopeModelItem scope_item, AbstractMetaClass *metaClass) { - foreach (const VariableModelItem &field, scope_item->variables()) { + const VariableList &variables = scope_item->variables(); + for (const VariableModelItem &field : variables) { AbstractMetaField* metaField = traverseField(field, metaClass); if (metaField && !metaField->isModifiedRemoved()) { @@ -1491,7 +1500,9 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF return; TypeDatabase* types = TypeDatabase::instance(); - QString castTo = metaFunction->name().remove(QRegExp(QLatin1String("^operator "))).trimmed(); + static const QRegularExpression operatorRegExp(QStringLiteral("^operator ")); + Q_ASSERT(operatorRegExp.isValid()); + QString castTo = metaFunction->name().remove(operatorRegExp).trimmed(); if (castTo.endsWith(QLatin1Char('&'))) castTo.chop(1); @@ -1542,7 +1553,7 @@ static bool _compareAbstractMetaFunctions(const AbstractMetaFunction* func, cons // "QList(const QList &)" to "QList(const QList<T> &)". static bool _fixFunctionModelItemTypes(FunctionModelItem& function, const AbstractMetaClass* metaClass) { - const QList<TypeEntry *> &templateTypes = metaClass->templateArguments(); + const QVector<TypeEntry *> &templateTypes = metaClass->templateArguments(); if (templateTypes.isEmpty()) return false; @@ -1582,7 +1593,7 @@ AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const Sco AbstractMetaFunctionList result; const FunctionList &scopeFunctionList = scopeItem->functions(); result.reserve(scopeFunctionList.size()); - foreach (const FunctionModelItem &function, scopeItem->functions()) { + for (const FunctionModelItem &function : scopeFunctionList) { if (AbstractMetaFunction *metaFunction = traverseFunction(function)) result.append(metaFunction); } @@ -1621,7 +1632,7 @@ AbstractMetaFunctionList AbstractMetaBuilderPrivate::templateClassFunctionList(c const FunctionList &scopeFunctionList = scopeItem->functions(); result.reserve(scopeFunctionList.size()); unchangedFunctions.reserve(scopeFunctionList.size()); - foreach (FunctionModelItem function, scopeItem->functions()) { + for (FunctionModelItem function : scopeFunctionList) { // This fixes method's arguments and return types that are templates // but the template variable wasn't declared in the C++ header. const bool templateTypeFixed =_fixFunctionModelItemTypes(function, metaClass); @@ -1652,7 +1663,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, ? classFunctionList(scopeItem) : templateClassFunctionList(scopeItem, metaClass); - foreach (AbstractMetaFunction *metaFunction, functions) { + for (AbstractMetaFunction *metaFunction : functions){ metaFunction->setOriginalAttributes(metaFunction->attributes()); if (metaClass->isNamespace()) *metaFunction += AbstractMetaAttributes::Static; @@ -1736,15 +1747,16 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, void AbstractMetaBuilderPrivate::fillAddedFunctions(AbstractMetaClass *metaClass) { // Add the functions added by the typesystem - foreach (const AddedFunction &addedFunc, metaClass->typeEntry()->addedFunctions()) + const AddedFunctionList &addedFunctions = metaClass->typeEntry()->addedFunctions(); + for (const AddedFunction &addedFunc : addedFunctions) traverseFunction(addedFunc, metaClass); } void AbstractMetaBuilderPrivate::applyFunctionModifications(AbstractMetaFunction *func) { - FunctionModificationList mods = func->modifications(func->implementingClass()); + const FunctionModificationList &mods = func->modifications(func->implementingClass()); AbstractMetaFunction& funcRef = *func; - foreach (const FunctionModification &mod, mods) { + for (const FunctionModification &mod : mods) { if (mod.isRenameModifier()) { func->setOriginalName(func->name()); func->setName(mod.renamedTo()); @@ -1866,8 +1878,8 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass) } metaClass->addInterface(iface); - AbstractMetaClassList interfaces = iface->interfaces(); - foreach (AbstractMetaClass* iface, interfaces) + const AbstractMetaClassList &interfaces = iface->interfaces(); + for (AbstractMetaClass* iface : interfaces) metaClass->addInterface(iface); } } @@ -1879,8 +1891,8 @@ void AbstractMetaBuilderPrivate::traverseEnums(ScopeModelItem scopeItem, AbstractMetaClass *metaClass, const QStringList &enumsDeclarations) { - EnumList enums = scopeItem->enums(); - foreach (const EnumModelItem &enumItem, enums) { + const EnumList &enums = scopeItem->enums(); + for (const EnumModelItem &enumItem : enums) { AbstractMetaEnum* metaEnum = traverseEnum(enumItem, metaClass, QSet<QString>::fromList(enumsDeclarations)); if (metaEnum) { metaClass->addEnum(metaEnum); @@ -1911,7 +1923,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu metaFunction->setType(translateType(addedFunc.version(), addedFunc.returnType())); - QList<AddedFunction::TypeInfo> args = addedFunc.arguments(); + QVector<AddedFunction::TypeInfo> args = addedFunc.arguments(); AbstractMetaArgumentList metaArguments; for (int i = 0; i < args.count(); ++i) { @@ -2001,8 +2013,9 @@ void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func) { if (func->arguments().isEmpty()) return; - foreach (const FunctionModification &mod, func->modifications(m_currentClass)) { - foreach (const ArgumentModification &argMod, mod.argument_mods) { + const FunctionModificationList &mods = func->modifications(m_currentClass); + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argMod : mod.argument_mods) { if (!argMod.renamed_to.isEmpty()) { AbstractMetaArgument* arg = func->arguments().at(argMod.index - 1); arg->setOriginalName(arg->name()); @@ -2011,51 +2024,83 @@ void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func) } } - int i = 1; - foreach (AbstractMetaArgument* arg, func->arguments()) { - if (arg->name().isEmpty()) - arg->setName(QLatin1String("arg__") + QString::number(i), false); - ++i; + AbstractMetaArgumentList arguments = func->arguments(); + for (int i = 0, size = arguments.size(); i < size; ++i) { + if (arguments.at(i)->name().isEmpty()) + arguments[i]->setName(QLatin1String("arg__") + QString::number(i + 1), false); } } static QString functionSignature(FunctionModelItem functionItem) { QStringList args; - foreach (const ArgumentModelItem &arg, functionItem->arguments()) + const ArgumentList &arguments = functionItem->arguments(); + for (const ArgumentModelItem &arg : arguments) args << arg->type().toString(); return functionItem->name() + QLatin1Char('(') + args.join(QLatin1Char(',')) + QLatin1Char(')'); } -static inline QString functionSignatureWithReturnType(FunctionModelItem functionItem) +static inline QString qualifiedFunctionSignatureWithType(const FunctionModelItem &functionItem, + const QString &className = QString()) +{ + QString result = functionItem->type().toString() + QLatin1Char(' '); + if (!className.isEmpty()) + result += className + colonColon(); + result += functionSignature(functionItem); + return result; +} + +static inline QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n) { - return functionSignature(functionItem) - + QStringLiteral(" -> ") + functionItem->type().toString(); + QString result; + QTextStream str(&result); + str << "unmatched type '" << arg->type().toString() << "' in parameter #" + << (n + 1); + if (!arg->name().isEmpty()) + str << " \"" << arg->name() << '"'; + return result; } -static inline QString qualifiedFunctionSignatureWithType(const QString &className, - FunctionModelItem functionItem) +static inline QString msgVoidParameterType(const ArgumentModelItem &arg, int n) { - return className + colonColon() + functionSignatureWithReturnType(functionItem); + QString result; + QTextStream str(&result); + str << "'void' encountered at parameter #" << (n + 1); + if (!arg->name().isEmpty()) + str << " \"" << arg->name() << '"'; + return result; } AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModelItem functionItem) { + if (!functionItem->templateParameters().isEmpty()) + return nullptr; QString functionName = functionItem->name(); QString className; - QString rejectedFunctionSignature; - if (m_currentClass) + if (m_currentClass) { + // Clang: Skip qt_metacast(), qt_metacall(), expanded from Q_OBJECT + // and overridden metaObject(), QGADGET helpers + if (functionName == QLatin1String("qt_check_for_QGADGET_macro") + || functionName.startsWith(QLatin1String("qt_meta"))) { + return nullptr; + } className = m_currentClass->typeEntry()->qualifiedCppName(); + if (functionName == QLatin1String("metaObject") && className != QLatin1String("QObject")) + return nullptr; + } - if (TypeDatabase::instance()->isFunctionRejected(className, functionName)) { - rejectedFunctionSignature = qualifiedFunctionSignatureWithType(className, functionItem); - m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::GenerationDisabled); + // Store original signature with unresolved typedefs for message/log purposes + const QString originalQualifiedSignatureWithReturn = + qualifiedFunctionSignatureWithType(functionItem, className); + + QString rejectReason; + if (TypeDatabase::instance()->isFunctionRejected(className, functionName, &rejectReason)) { + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); return 0; } else if (TypeDatabase::instance()->isFunctionRejected(className, - functionSignature(functionItem))) { - rejectedFunctionSignature = qualifiedFunctionSignatureWithType(className, functionItem); - m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::GenerationDisabled); + functionSignature(functionItem), &rejectReason)) { + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); return 0; } @@ -2107,6 +2152,13 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel strippedClassName = strippedClassName.mid(cc_pos + 2); TypeInfo functionType = functionItem->type(); + + if (TypeDatabase::instance()->isReturnTypeRejected(className, functionType.toString(), &rejectReason)) { + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); + delete metaFunction; + return nullptr; + } + if (functionName.startsWith(QLatin1Char('~'))) { metaFunction->setFunctionType(AbstractMetaFunction::DestructorFunction); metaFunction->setInvalid(true); @@ -2122,11 +2174,10 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel if (!ok) { Q_ASSERT(type == 0); qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("skipping function '%1::%2', unmatched return type '%3'") - .arg(className, functionItem->name(), + << QStringLiteral("skipping function '%1', unmatched return type '%2'") + .arg(originalQualifiedSignatureWithReturn, functionItem->type().toString()); - rejectedFunctionSignature = qualifiedFunctionSignatureWithType(className, functionItem); - m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedReturnType); + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn, AbstractMetaBuilder::UnmatchedReturnType); metaFunction->setInvalid(true); return metaFunction; } @@ -2153,26 +2204,34 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel for (int i = 0; i < arguments.size(); ++i) { ArgumentModelItem arg = arguments.at(i); + if (TypeDatabase::instance()->isArgumentTypeRejected(className, arg->type().toString(), &rejectReason)) { + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); + delete metaFunction; + return nullptr; + } + bool ok; AbstractMetaType* metaType = translateType(arg->type(), &ok); if (!ok) { Q_ASSERT(metaType == 0); + const QString reason = msgUnmatchedParameterType(arg, i); qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("skipping function '%1::%2', unmatched parameter type '%3'") - .arg(className, functionItem->name(), arg->type().toString()); - rejectedFunctionSignature = qualifiedFunctionSignatureWithType(className, functionItem); + << QStringLiteral("skipping function '%1', %2") + .arg(originalQualifiedSignatureWithReturn, reason); + const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn + + QLatin1String(": ") + reason; m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType); metaFunction->setInvalid(true); return metaFunction; } if (metaType == Q_NULLPTR) { + const QString reason = msgVoidParameterType(arg, i); qCWarning(lcShiboken).noquote().nospace() - << QString::fromLatin1("skipping function '%1::%2', 'void' encountered at parameter " - "position %3, but it can only be the the first and only " - "parameter") - .arg(className, functionItem->name()).arg(i); - rejectedFunctionSignature = qualifiedFunctionSignatureWithType(className, functionItem); + << QString::fromLatin1("skipping function '%1': %2") + .arg(originalQualifiedSignatureWithReturn, reason); + const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn + + QLatin1String(": ") + reason; m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType); metaFunction->setInvalid(true); return metaFunction; @@ -2200,7 +2259,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel } else { FunctionModificationList mods = TypeDatabase::instance()->functionModifications(metaFunction->minimalSignature()); if (!mods.isEmpty()) { - QList<ArgumentModification> argMods = mods.first().argument_mods; + QVector<ArgumentModification> argMods = mods.first().argument_mods; if (!argMods.isEmpty()) replacedExpression = argMods.first().replacedDefaultExpression; } @@ -2320,7 +2379,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(double vr, msg += QLatin1String("Remember to inform the full qualified name for the type you want to use.\nCandidates are:\n"); candidates.sort(); - foreach (const QString& candidate, candidates) { + for (const QString& candidate : qAsConst(candidates)) { msg += QLatin1String(" ") + candidate + QLatin1Char('\n'); } qFatal(qPrintable(msg), NULL); @@ -2333,7 +2392,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(double vr, metaType->setReferenceType(LValueReference); metaType->setConstant(typeInfo.isConstant); if (isTemplate) { - foreach (const QString& templateArg, templateArgs) { + for (const QString& templateArg : qAsConst(templateArgs)) { AbstractMetaType* metaArgType = translateType(vr, AddedFunction::TypeInfo::fromSignature(templateArg)); metaType->addInstantiation(metaArgType); } @@ -2472,7 +2531,8 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ // 5.1.1 - Try using the class parents' scopes if (!type && !m_currentClass->baseClassNames().isEmpty()) { - foreach (const AbstractMetaClass* cls, getBaseClasses(m_currentClass)) { + const AbstractMetaClassList &baseClasses = getBaseClasses(m_currentClass); + for (const AbstractMetaClass *cls : baseClasses) { type = findTypeEntryUsingContext(cls, qualifiedName); if (type) break; @@ -2495,8 +2555,8 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ // 8. No? Check if the current class is a template and this type is one // of the parameters. if (!type && m_currentClass) { - QList<TypeEntry *> template_args = m_currentClass->templateArguments(); - foreach (TypeEntry *te, template_args) { + const QVector<TypeEntry *> &template_args = m_currentClass->templateArguments(); + for (TypeEntry *te : template_args) { if (te->name() == qualifiedName) type = te; } @@ -2544,7 +2604,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ metaType->setConstant(typeInfo.is_constant); metaType->setOriginalTypeDescription(_typei.toString()); - foreach (const TypeParser::Info &ta, typeInfo.template_instantiations) { + for (const TypeParser::Info &ta : qAsConst(typeInfo.template_instantiations)) { TypeInfo info; info.setConstant(ta.is_constant); info.setReferenceType(ta.referenceType); @@ -2585,8 +2645,9 @@ int AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValu // This is a very lame way to handle expression evaluation, // but it is not critical and will do for the time being. - static QRegExp variableNameRegExp(QLatin1String("^[a-zA-Z_][a-zA-Z0-9_]*$")); - if (!variableNameRegExp.exactMatch(stringValue)) { + static const QRegularExpression variableNameRegExp(QStringLiteral("^[a-zA-Z_][a-zA-Z0-9_]*$")); + Q_ASSERT(variableNameRegExp.isValid()); + if (!variableNameRegExp.match(stringValue).hasMatch()) { ok = true; return 0; } @@ -2597,8 +2658,9 @@ int AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValu return enumValue->value(); } - foreach (AbstractMetaEnum* metaEnum, m_globalEnums) { - foreach (AbstractMetaEnumValue* ev, metaEnum->values()) { + for (AbstractMetaEnum *metaEnum : qAsConst(m_globalEnums)) { + const AbstractMetaEnumValueList &values = metaEnum->values(); + for (const AbstractMetaEnumValue *ev : values) { if (ev->name() == stringValue) { ok = true; return ev->value(); @@ -2647,23 +2709,28 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(ArgumentModelItem item, if (!isNumber && expr.indexOf(colonColon()) < 0) { // Add the enum/flag scope to default value, making it usable // from other contexts beside its owner class hierarchy - QRegExp typeRegEx(QLatin1String("[^<]*[<]([^:]*::).*")); - typeRegEx.indexIn(type->minimalSignature()); - expr = typeRegEx.cap(1) + expr; + static const QRegularExpression typeRegEx(QStringLiteral("[^<]*[<]([^:]*::).*")); + Q_ASSERT(typeRegEx.isValid()); + const QRegularExpressionMatch match = typeRegEx.match(type->minimalSignature()); + if (match.hasMatch()) + expr.prepend(match.captured(1)); } } else if (type->isContainer() && expr.contains(QLatin1Char('<'))) { - QRegExp typeRegEx(QLatin1String("[^<]*<(.*)>")); - typeRegEx.indexIn(type->minimalSignature()); - QRegExp defaultRegEx(QLatin1String("([^<]*<).*(>[^>]*)")); - defaultRegEx.indexIn(expr); - expr = defaultRegEx.cap(1) + typeRegEx.cap(1) + defaultRegEx.cap(2); + static const QRegularExpression typeRegEx(QStringLiteral("[^<]*<(.*)>")); + Q_ASSERT(typeRegEx.isValid()); + const QRegularExpressionMatch typeMatch = typeRegEx.match(type->minimalSignature()); + static const QRegularExpression defaultRegEx(QLatin1String("([^<]*<).*(>[^>]*)")); + Q_ASSERT(defaultRegEx.isValid()); + const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr); + if (typeMatch.hasMatch() && defaultMatch.hasMatch()) + expr = defaultMatch.captured(1) + typeMatch.captured(1) + defaultMatch.captured(2); } else { // Here the default value is supposed to be a constructor, // a class field, or a constructor receiving a class field - QRegExp defaultRegEx(QLatin1String("([^\\(]*\\(|)([^\\)]*)(\\)|)")); - defaultRegEx.indexIn(expr); - - QString defaultValueCtorName = defaultRegEx.cap(1); + static const QRegularExpression defaultRegEx(QStringLiteral("([^\\(]*\\(|)([^\\)]*)(\\)|)")); + Q_ASSERT(defaultRegEx.isValid()); + const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr); + QString defaultValueCtorName = defaultMatch.hasMatch() ? defaultMatch.captured(1) : QString(); if (defaultValueCtorName.endsWith(QLatin1Char('('))) defaultValueCtorName.chop(1); @@ -2671,20 +2738,22 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(ArgumentModelItem item, // resolved argument type as a reference. // The following regular expression extracts any // use of namespaces/scopes from the type string. - QRegExp typeRegEx(QLatin1String("^(?:const[\\s]+|)([\\w:]*::|)([A-Za-z_]\\w*)\\s*[&\\*]?$")); - typeRegEx.indexIn(type->minimalSignature()); + static const QRegularExpression typeRegEx(QLatin1String("^(?:const[\\s]+|)([\\w:]*::|)([A-Za-z_]\\w*)\\s*[&\\*]?$")); + Q_ASSERT(typeRegEx.isValid()); + const QRegularExpressionMatch typeMatch = typeRegEx.match(type->minimalSignature()); - QString typeNamespace = typeRegEx.cap(1); - QString typeCtorName = typeRegEx.cap(2); + QString typeNamespace = typeMatch.hasMatch() ? typeMatch.captured(1) : QString(); + QString typeCtorName = typeMatch.hasMatch() ? typeMatch.captured(2) : QString(); if (!typeNamespace.isEmpty() && defaultValueCtorName == typeCtorName) expr.prepend(typeNamespace); // Fix scope if the parameter is a field of the current class if (implementingClass) { - foreach (const AbstractMetaField* field, implementingClass->fields()) { - if (defaultRegEx.cap(2) == field->name()) { - expr = defaultRegEx.cap(1) + implementingClass->name() - + colonColon() + defaultRegEx.cap(2) + defaultRegEx.cap(3); + const AbstractMetaFieldList &fields = implementingClass->fields(); + for (const AbstractMetaField *field : fields) { + if (defaultMatch.hasMatch() && defaultMatch.captured(2) == field->name()) { + expr = defaultMatch.captured(1) + implementingClass->name() + + colonColon() + defaultMatch.captured(2) + defaultMatch.captured(3); break; } } @@ -2766,7 +2835,7 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::findTemplateClass(const QString & QString qualifiedName = info->qualified_name.join(colonColon()); AbstractMetaClass* templ = 0; - foreach (AbstractMetaClass *c, m_templates) { + for (AbstractMetaClass *c : qAsConst(m_templates)) { if (c->typeEntry()->name() == qualifiedName) { templ = c; break; @@ -2789,7 +2858,8 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::findTemplateClass(const QString & AbstractMetaClassList AbstractMetaBuilderPrivate::getBaseClasses(const AbstractMetaClass *metaClass) const { AbstractMetaClassList baseClasses; - foreach (const QString& parent, metaClass->baseClassNames()) { + const QStringList &baseClassNames = metaClass->baseClassNames(); + for (const QString& parent : baseClassNames) { AbstractMetaClass* cls = 0; if (parent.contains(QLatin1Char('<'))) cls = findTemplateClass(parent, metaClass); @@ -2806,14 +2876,15 @@ bool AbstractMetaBuilderPrivate::ancestorHasPrivateCopyConstructor(const Abstrac { if (metaClass->hasPrivateCopyConstructor()) return true; - foreach (const AbstractMetaClass* cls, getBaseClasses(metaClass)) { + const AbstractMetaClassList &baseClasses = getBaseClasses(metaClass); + for (const AbstractMetaClass *cls : baseClasses) { if (ancestorHasPrivateCopyConstructor(cls)) return true; } return false; } -AbstractMetaType* AbstractMetaBuilderPrivate::inheritTemplateType(const QList<AbstractMetaType *> &templateTypes, +AbstractMetaType* AbstractMetaBuilderPrivate::inheritTemplateType(const QVector<AbstractMetaType *> &templateTypes, const AbstractMetaType *metaType, bool *ok) { @@ -2865,8 +2936,8 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, const AbstractMetaClass *templateClass, const TypeParser::Info &info) { - QList<TypeParser::Info> targs = info.template_instantiations; - QList<AbstractMetaType*> templateTypes; + QVector<TypeParser::Info> targs = info.template_instantiations; + QVector<AbstractMetaType *> templateTypes; if (subclass->isTypeDef()) { subclass->setHasCloneOperator(templateClass->hasCloneOperator()); @@ -2878,7 +2949,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, subclass->setHasVirtualDestructor(templateClass->hasVirtualDestructor()); } - foreach (const TypeParser::Info &i, targs) { + for (const TypeParser::Info &i : qAsConst(targs)) { QString typeName = i.qualified_name.join(colonColon()); QStringList possibleNames; possibleNames << subclass->qualifiedCppName() + colonColon() + typeName; @@ -2890,7 +2961,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, TypeDatabase* typeDb = TypeDatabase::instance(); TypeEntry* t = 0; QString templateParamName; - foreach (const QString &possibleName, possibleNames) { + for (const QString &possibleName : qAsConst(possibleNames)) { t = typeDb->findType(possibleName); if (t) { QString templateParamName = possibleName; @@ -2914,7 +2985,8 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, } AbstractMetaFunctionList funcs = subclass->functions(); - foreach (const AbstractMetaFunction* function, templateClass->functions()) { + const AbstractMetaFunctionList &templateClassFunctions = templateClass->functions(); + for (const AbstractMetaFunction *function : templateClassFunctions) { if (function->isModifiedRemoved(TypeSystem::All)) continue; @@ -2929,7 +3001,8 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, continue; } - foreach (AbstractMetaArgument* argument, function->arguments()) { + const AbstractMetaArgumentList &arguments = function->arguments(); + for (AbstractMetaArgument *argument : arguments) { AbstractMetaType* atype = argument->type(); AbstractMetaArgument *arg = argument->copy(); @@ -3068,7 +3141,7 @@ static AbstractMetaFunction* findCopyCtor(AbstractMetaClass* cls) AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::Invisible); functions << cls->queryFunctions(AbstractMetaClass::Visible); - foreach (AbstractMetaFunction* f, functions) { + for (AbstractMetaFunction *f : qAsConst(functions)) { const AbstractMetaFunction::FunctionType t = f->functionType(); if (t == AbstractMetaFunction::CopyConstructorFunction || t == AbstractMetaFunction::AssignmentOperatorFunction) return f; @@ -3088,11 +3161,11 @@ void AbstractMetaBuilderPrivate::setupClonable(AbstractMetaClass *cls) QQueue<AbstractMetaClass*> baseClasses; if (cls->baseClass()) baseClasses.enqueue(cls->baseClass()); - baseClasses << cls->interfaces(); + baseClasses << cls->interfaces().toList(); while (!baseClasses.isEmpty()) { AbstractMetaClass* currentClass = baseClasses.dequeue(); - baseClasses << currentClass->interfaces(); + baseClasses << currentClass->interfaces().toList(); if (currentClass->baseClass()) baseClasses.enqueue(currentClass->baseClass()); @@ -3108,8 +3181,8 @@ void AbstractMetaBuilderPrivate::setupClonable(AbstractMetaClass *cls) void AbstractMetaBuilderPrivate::setupExternalConversion(AbstractMetaClass *cls) { - AbstractMetaFunctionList convOps = cls->operatorOverloads(AbstractMetaClass::ConversionOp); - foreach (AbstractMetaFunction* func, convOps) { + const AbstractMetaFunctionList &convOps = cls->operatorOverloads(AbstractMetaClass::ConversionOp); + for (AbstractMetaFunction *func : convOps) { if (func->isModifiedRemoved()) continue; AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, func->type()->typeEntry()); @@ -3117,7 +3190,8 @@ void AbstractMetaBuilderPrivate::setupExternalConversion(AbstractMetaClass *cls) continue; metaClass->addExternalConversionOperator(func); } - foreach (AbstractMetaClass* innerClass, cls->innerClasses()) + const AbstractMetaClassList &innerClasses = cls->innerClasses(); + for (AbstractMetaClass *innerClass : innerClasses) setupExternalConversion(innerClass); } @@ -3197,7 +3271,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const const AbstractMetaClassList& classList = cppClass ? cppClass->innerClasses() : m_metaClasses; int i = 0; - foreach (AbstractMetaClass* clazz, classList) { + for (AbstractMetaClass *clazz : classList) { if (map.contains(clazz->qualifiedCppName())) continue; map[clazz->qualifiedCppName()] = i; @@ -3207,7 +3281,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const Graph graph(map.count()); - foreach (const Dependency &dep, additionalDependencies) { + for (const Dependency &dep : additionalDependencies) { const int parentIndex = map.value(dep.parent, -1); const int childIndex = map.value(dep.child, -1); if (parentIndex >= 0 && childIndex >= 0) { @@ -3220,14 +3294,16 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const } // TODO choose a better name to these regexs - QRegExp regex1(QLatin1String("\\(.*\\)")); - QRegExp regex2(QLatin1String("::.*")); - foreach (AbstractMetaClass* clazz, classList) { + static const QRegularExpression regex1(QStringLiteral("\\(.*\\)")); + Q_ASSERT(regex1.isValid()); + static const QRegularExpression regex2(QStringLiteral("::.*")); + Q_ASSERT(regex2.isValid()); + for (AbstractMetaClass *clazz : classList) { if (clazz->enclosingClass() && map.contains(clazz->enclosingClass()->qualifiedCppName())) graph.addEdge(map[clazz->enclosingClass()->qualifiedCppName()], map[clazz->qualifiedCppName()]); - AbstractMetaClassList bases = getBaseClasses(clazz); - foreach(AbstractMetaClass* baseClass, bases) { + const AbstractMetaClassList &bases = getBaseClasses(clazz); + for (AbstractMetaClass *baseClass : bases) { // Fix polymorphic expression if (clazz->baseClass() == baseClass) clazz->setBaseClass(baseClass); @@ -3236,8 +3312,10 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const graph.addEdge(map[baseClass->qualifiedCppName()], map[clazz->qualifiedCppName()]); } - foreach (AbstractMetaFunction* func, clazz->functions()) { - foreach (AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaFunctionList &functions = clazz->functions(); + for (AbstractMetaFunction *func : functions) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (AbstractMetaArgument *arg : arguments) { // check methods with default args QString defaultExpression = arg->originalDefaultValueExpression(); if (!defaultExpression.isEmpty()) { @@ -3251,7 +3329,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const QString exprClassName = clazz->qualifiedCppName() + colonColon() + defaultExpression; if (!map.contains(exprClassName)) { bool found = false; - foreach(AbstractMetaClass* baseClass, bases) { + for (AbstractMetaClass *baseClass : bases) { exprClassName = baseClass->qualifiedCppName() + colonColon() + defaultExpression; if (map.contains(exprClassName)) { found = true; @@ -3287,7 +3365,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const << "Cyclic dependency found! Graph can be found at " << QDir::toNativeSeparators(tempFile.fileName()); } else { - foreach (int i, unmappedResult) { + for (int i : qAsConst(unmappedResult)) { Q_ASSERT(reverseMap.contains(i)); if (!reverseMap[i]->isInterface()) result << reverseMap[i]; @@ -3308,7 +3386,7 @@ AbstractMetaArgumentList AbstractMetaBuilderPrivate::reverseList(const AbstractM AbstractMetaArgumentList ret; int index = list.size(); - foreach (AbstractMetaArgument* arg, list) { + for (AbstractMetaArgument *arg : list) { arg->setArgumentIndex(index); ret.prepend(arg); index--; diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h index b4a36a1b6..f7427d488 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h @@ -71,7 +71,7 @@ public: AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClass *cppClass = Q_NULLPTR, const Dependencies &additionalDependencies = Dependencies()) const; - bool build(QIODevice* input); + bool build(const QByteArrayList &arguments, unsigned clangFlags = 0); void setLogDirectory(const QString& logDir); /** diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index f9eb4bb46..96a6fdbfd 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -46,7 +46,7 @@ public: AbstractMetaBuilderPrivate(); ~AbstractMetaBuilderPrivate(); - static FileModelItem buildDom(QIODevice *input); + static FileModelItem buildDom(const QByteArrayList &arguments, unsigned clangFlags); void traverseDom(const FileModelItem &dom); void dumpLog() const; @@ -140,7 +140,7 @@ public: bool inheritTemplate(AbstractMetaClass *subclass, const AbstractMetaClass *templateClass, const TypeParser::Info &info); - AbstractMetaType *inheritTemplateType(const QList<AbstractMetaType *> &templateTypes, + AbstractMetaType *inheritTemplateType(const QVector<AbstractMetaType *> &templateTypes, const AbstractMetaType *metaType, bool *ok = Q_NULLPTR); diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index b861f1b2f..4fa009fd2 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -26,8 +26,6 @@ ** ****************************************************************************/ -#include <QStack> - #include "abstractmetalang.h" #include "reporthandler.h" #include "typedatabase.h" @@ -38,6 +36,9 @@ # include <QtCore/QMetaObject> #endif +#include <QtCore/QRegularExpression> +#include <QtCore/QStack> + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa) { @@ -279,7 +280,7 @@ void AbstractMetaType::decideUsagePattern() bool AbstractMetaType::hasTemplateChildren() const { QStack<AbstractMetaType *> children; - children << m_children.toVector(); + children << m_children; // Recursively iterate over the children / descendants of the type, to check if any of them // corresponds to a template argument type. @@ -287,7 +288,7 @@ bool AbstractMetaType::hasTemplateChildren() const AbstractMetaType *child = children.pop(); if (child->typeEntry()->isTemplateArgument()) return true; - children << child->m_children.toVector(); + children << child->m_children; } return false; @@ -347,8 +348,8 @@ AbstractMetaFunction::~AbstractMetaFunction() */ bool AbstractMetaFunction::isModifiedRemoved(int types) const { - FunctionModificationList mods = modifications(implementingClass()); - foreach (const FunctionModification &mod, mods) { + const FunctionModificationList &mods = modifications(implementingClass()); + for (const FunctionModification &mod : mods) { if (!mod.isRemoveModifier()) continue; @@ -368,7 +369,7 @@ bool AbstractMetaFunction::needsCallThrough() const if (argumentsHaveNativeId() || !isStatic()) return true; - foreach (const AbstractMetaArgument *arg, arguments()) { + for (const AbstractMetaArgument *arg : m_arguments) { if (arg->type()->isArray() || arg->type()->isTargetLangEnum() || arg->type()->isTargetLangFlags()) return true; } @@ -388,8 +389,8 @@ bool AbstractMetaFunction::needsCallThrough() const bool AbstractMetaFunction::needsSuppressUncheckedWarning() const { for (int i = -1; i <= arguments().size(); ++i) { - QList<ReferenceCount> referenceCounts = this->referenceCounts(implementingClass(), i); - foreach (const ReferenceCount &referenceCount, referenceCounts) { + const QVector<ReferenceCount> &referenceCounts = this->referenceCounts(implementingClass(), i); + for (const ReferenceCount &referenceCount : referenceCounts) { if (referenceCount.action != ReferenceCount::Set) return true; } @@ -400,8 +401,7 @@ bool AbstractMetaFunction::needsSuppressUncheckedWarning() const QString AbstractMetaFunction::marshalledName() const { QString returned = QLatin1String("__qt_") + name(); - AbstractMetaArgumentList arguments = this->arguments(); - foreach (const AbstractMetaArgument *arg, arguments) { + for (const AbstractMetaArgument *arg : m_arguments) { returned += QLatin1Char('_'); if (arg->type()->isNativePointer()) { returned += QLatin1String("nativepointer"); @@ -510,7 +510,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const cpy->setConstant(isConstant()); cpy->setOriginalAttributes(originalAttributes()); - foreach (AbstractMetaArgument *arg, arguments()) + for (AbstractMetaArgument *arg : m_arguments) cpy->addArgument(arg->copy()); Q_ASSERT((!type() && !cpy->type()) @@ -525,7 +525,7 @@ bool AbstractMetaFunction::usesRValueReferences() const return true; if (m_type && m_type->referenceType() == RValueReference) return true; - foreach (const AbstractMetaArgument *a, m_arguments) { + for (const AbstractMetaArgument *a : m_arguments) { if (a->type()->referenceType() == RValueReference) return true; } @@ -600,13 +600,13 @@ int AbstractMetaFunction::actualMinimumArgumentCount() const } // Returns reference counts for argument at idx, or all arguments if idx == -2 -QList<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const +QVector<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const { - QList<ReferenceCount> returned; + QVector<ReferenceCount> returned; - FunctionModificationList mods = this->modifications(cls); - foreach (const FunctionModification &mod, mods) { - foreach (const ArgumentModification &argumentMod, mod.argument_mods) { + const FunctionModificationList &mods = this->modifications(cls); + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argumentMod : mod.argument_mods) { if (argumentMod.index != idx && idx != -2) continue; returned += argumentMod.referenceCounts; @@ -619,9 +619,9 @@ QList<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaCl ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls, int idx) const { - FunctionModificationList mods = this->modifications(cls); - foreach (const FunctionModification &mod, mods) { - foreach (const ArgumentModification &argumentMod, mod.argument_mods) { + const FunctionModificationList &mods = this->modifications(cls); + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argumentMod : mod.argument_mods) { if (argumentMod.index != idx) continue; return argumentMod.owner; @@ -633,9 +633,9 @@ ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls, QString AbstractMetaFunction::replacedDefaultExpression(const AbstractMetaClass *cls, int key) const { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == key && !argumentModification.replacedDefaultExpression.isEmpty()) { return argumentModification.replacedDefaultExpression; @@ -648,9 +648,9 @@ QString AbstractMetaFunction::replacedDefaultExpression(const AbstractMetaClass bool AbstractMetaFunction::removedDefaultExpression(const AbstractMetaClass *cls, int key) const { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == key && argumentModification.removedDefaultExpression) { return true; @@ -664,9 +664,9 @@ bool AbstractMetaFunction::removedDefaultExpression(const AbstractMetaClass *cls bool AbstractMetaFunction::resetObjectAfterUse(int argumentIdx) const { const AbstractMetaClass *cls = declaringClass(); - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == argumentIdx && argumentModification.resetAfterUse) return true; } @@ -684,9 +684,9 @@ QString AbstractMetaFunction::nullPointerDefaultValue(const AbstractMetaClass *m cls = implementingClass(); do { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == argumentIdx && argumentModification.noNullPointers) { return argumentModification.nullPointerDefaultValue; @@ -707,9 +707,9 @@ bool AbstractMetaFunction::nullPointersDisabled(const AbstractMetaClass *mainCla cls = implementingClass(); do { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == argumentIdx && argumentModification.noNullPointers) { return true; @@ -725,13 +725,13 @@ bool AbstractMetaFunction::nullPointersDisabled(const AbstractMetaClass *mainCla QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int key) const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index != key) continue; - foreach (const CodeSnip &snip, argumentModification.conversion_rules) { + for (const CodeSnip &snip : argumentModification.conversion_rules) { if (snip.language == language && !snip.code().isEmpty()) return snip.code(); } @@ -743,9 +743,9 @@ QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int QString AbstractMetaFunction::argumentReplaced(int key) const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == key && !argumentModification.replace_value.isEmpty()) return argumentModification.replace_value; } @@ -757,9 +757,9 @@ QString AbstractMetaFunction::argumentReplaced(int key) const // FIXME If we remove a arg. in the method at the base class, it will not reflect here. bool AbstractMetaFunction::argumentRemoved(int key) const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == key) { if (argumentModification.removed) return true; @@ -772,8 +772,8 @@ bool AbstractMetaFunction::argumentRemoved(int key) const bool AbstractMetaFunction::isVirtualSlot() const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { if (modification.isVirtualSlot()) return true; } @@ -785,9 +785,9 @@ bool AbstractMetaFunction::disabledGarbageCollection(const AbstractMetaClass *cl { typedef QHash<TypeSystem::Language, TypeSystem::Ownership>::const_iterator OwnershipMapIt; - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index != key) continue; @@ -804,8 +804,8 @@ bool AbstractMetaFunction::disabledGarbageCollection(const AbstractMetaClass *cl bool AbstractMetaFunction::isDeprecated() const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { if (modification.isDeprecated()) return true; } @@ -814,8 +814,8 @@ bool AbstractMetaFunction::isDeprecated() const bool AbstractMetaFunction::isThread() const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { if (modification.isThread()) return true; } @@ -824,8 +824,8 @@ bool AbstractMetaFunction::isThread() const bool AbstractMetaFunction::allowThread() const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { if (modification.allowThread()) return true; } @@ -835,9 +835,9 @@ bool AbstractMetaFunction::allowThread() const TypeSystem::Ownership AbstractMetaFunction::ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int key) const { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == key) return argumentModification.ownerships.value(language, TypeSystem::InvalidOwnership); } @@ -853,8 +853,8 @@ bool AbstractMetaFunction::isRemovedFromAllLanguages(const AbstractMetaClass *cl bool AbstractMetaFunction::isRemovedFrom(const AbstractMetaClass *cls, TypeSystem::Language language) const { - FunctionModificationList modifications = this->modifications(cls); - foreach (const FunctionModification &modification, modifications) { + const FunctionModificationList &modifications = this->modifications(cls); + for (const FunctionModification &modification : modifications) { if ((modification.removal & language) == language) return true; } @@ -865,9 +865,9 @@ bool AbstractMetaFunction::isRemovedFrom(const AbstractMetaClass *cls, TypeSyste QString AbstractMetaFunction::typeReplaced(int key) const { - FunctionModificationList modifications = this->modifications(declaringClass()); - foreach (const FunctionModification &modification, modifications) { - foreach (const ArgumentModification &argumentModification, modification.argument_mods) { + const FunctionModificationList &modifications = this->modifications(declaringClass()); + for (const FunctionModification &modification : modifications) { + for (const ArgumentModification &argumentModification : modification.argument_mods) { if (argumentModification.index == key && !argumentModification.modified_type.isEmpty()) { return argumentModification.modified_type; @@ -923,9 +923,9 @@ FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaC if ((implementor == implementor->baseClass()) || (implementor == implementingClass() && (mods.size() > 0))) break; - foreach (const AbstractMetaClass* interface, implementor->interfaces()) { + const AbstractMetaClassList &interfaces = implementor->interfaces(); + for (const AbstractMetaClass *interface : interfaces) mods += this->modifications(interface); - } implementor = implementor->baseClass(); } return mods; @@ -950,7 +950,8 @@ bool AbstractMetaFunction::isCallOperator() const bool AbstractMetaFunction::hasInjectedCode() const { - foreach (const FunctionModification &mod, modifications(ownerClass())) { + const FunctionModificationList &mods = modifications(ownerClass()); + for (const FunctionModification &mod : mods) { if (mod.isCodeInjection()) return true; } @@ -960,12 +961,12 @@ bool AbstractMetaFunction::hasInjectedCode() const CodeSnipList AbstractMetaFunction::injectedCodeSnips(TypeSystem::CodeSnipPosition position, TypeSystem::Language language) const { CodeSnipList result; - foreach (const FunctionModification &mod, modifications(ownerClass())) { + const FunctionModificationList &mods = modifications(ownerClass()); + for (const FunctionModification &mod : mods) { if (mod.isCodeInjection()) { - QList<CodeSnip>::const_iterator it = mod.snips.constBegin(); - for (;it != mod.snips.constEnd(); ++it) { - if ((it->language & language) && (it->position == position || position == TypeSystem::CodeSnipPositionAny)) - result << *it; + for (const CodeSnip &snip : mod.snips) { + if ((snip.language & language) && (snip.position == position || position == TypeSystem::CodeSnipPositionAny)) + result << snip; } } } @@ -974,10 +975,11 @@ CodeSnipList AbstractMetaFunction::injectedCodeSnips(TypeSystem::CodeSnipPositio bool AbstractMetaFunction::hasSignatureModifications() const { - foreach (const FunctionModification &mod, modifications()) { + const FunctionModificationList &mods = modifications(); + for (const FunctionModification &mod : mods) { if (mod.isRenameModifier()) return true; - foreach (const ArgumentModification &argmod, mod.argument_mods) { + for (const ArgumentModification &argmod : mod.argument_mods) { // since zero represents the return type and we're // interested only in checking the function arguments, // it will be ignored. @@ -990,8 +992,9 @@ bool AbstractMetaFunction::hasSignatureModifications() const bool AbstractMetaFunction::isConversionOperator(QString funcName) { - static QRegExp opRegEx(QLatin1String("^operator(?:\\s+(?:const|volatile))?\\s+(\\w+\\s*)&?$")); - return opRegEx.indexIn(funcName) > -1; + static const QRegularExpression opRegEx(QStringLiteral("^operator(?:\\s+(?:const|volatile))?\\s+(\\w+\\s*)&?$")); + Q_ASSERT(opRegEx.isValid()); + return opRegEx.match(funcName).hasMatch(); } bool AbstractMetaFunction::isOperatorOverload(QString funcName) @@ -999,12 +1002,13 @@ bool AbstractMetaFunction::isOperatorOverload(QString funcName) if (isConversionOperator(funcName)) return true; - static QRegExp opRegEx(QLatin1String("^operator([+\\-\\*/%=&\\|\\^\\<>!][=]?" + static const QRegularExpression opRegEx(QLatin1String("^operator([+\\-\\*/%=&\\|\\^\\<>!][=]?" "|\\+\\+|\\-\\-|&&|\\|\\||<<[=]?|>>[=]?|~" "|\\[\\]|\\s+delete\\[?\\]?" "|\\(\\)" "|\\s+new\\[?\\]?)$")); - return opRegEx.indexIn(funcName) > -1; + Q_ASSERT(opRegEx.isValid()); + return opRegEx.match(funcName).hasMatch(); } bool AbstractMetaFunction::isCastOperator() const @@ -1133,8 +1137,8 @@ bool AbstractMetaFunction::isVirtual() const QString AbstractMetaFunction::modifiedName() const { if (m_cachedModifiedName.isEmpty()) { - FunctionModificationList mods = modifications(implementingClass()); - foreach (const FunctionModification &mod, mods) { + const FunctionModificationList &mods = modifications(implementingClass()); + for (const FunctionModification &mod : mods) { if (mod.isRenameModifier()) { m_cachedModifiedName = mod.renamedToName; break; @@ -1261,10 +1265,8 @@ AbstractMetaClass::~AbstractMetaClass() qDeleteAll(m_functions); qDeleteAll(m_fields); qDeleteAll(m_enums); - if (hasTemplateBaseClassInstantiations()) { - foreach (AbstractMetaType* inst, templateBaseClassInstantiations()) - delete inst; - } + if (hasTemplateBaseClassInstantiations()) + qDeleteAll(templateBaseClassInstantiations()); } /******************************************************************************* @@ -1300,7 +1302,7 @@ AbstractMetaClass *AbstractMetaClass::extractInterface() iface->setTypeEntry(typeEntry()->designatedInterface()); - foreach (AbstractMetaFunction *function, functions()) { + for (AbstractMetaFunction *function : qAsConst(m_functions)) { if (!function->isConstructor()) iface->addFunction(function->copy()); } @@ -1308,7 +1310,7 @@ AbstractMetaClass *AbstractMetaClass::extractInterface() // iface->setEnums(enums()); // setEnums(AbstractMetaEnumList()); - foreach (const AbstractMetaField *field, fields()) { + for (const AbstractMetaField *field : qAsConst(m_fields)) { if (field->isPublic()) { AbstractMetaField *new_field = field->copy(); new_field->setEnclosingClass(iface); @@ -1329,8 +1331,7 @@ AbstractMetaClass *AbstractMetaClass::extractInterface() AbstractMetaFunctionList AbstractMetaClass::queryFunctionsByName(const QString &name) const { AbstractMetaFunctionList returned; - AbstractMetaFunctionList functions = this->functions(); - foreach (AbstractMetaFunction *function, functions) { + for (AbstractMetaFunction *function : m_functions) { if (function->name() == name) returned.append(function); } @@ -1376,10 +1377,10 @@ AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const AbstractMetaFunctionList AbstractMetaClass::virtualFunctions() const { - AbstractMetaFunctionList list = functionsInShellClass(); + const AbstractMetaFunctionList &list = functionsInShellClass(); AbstractMetaFunctionList returned; - foreach (AbstractMetaFunction *f, list) { + for (AbstractMetaFunction *f : list) { if (!f->isFinalInCpp() || f->isVirtualSlot()) returned += f; } @@ -1393,14 +1394,12 @@ AbstractMetaFunctionList AbstractMetaClass::implicitConversions() const return AbstractMetaFunctionList(); AbstractMetaFunctionList returned; - AbstractMetaFunctionList list = queryFunctions(Constructors); - - list.append(externalConversionOperators()); + const AbstractMetaFunctionList list = queryFunctions(Constructors) + externalConversionOperators(); // Exclude anything that uses rvalue references, be it a move // constructor "QPolygon(QPolygon &&)" or something else like // "QPolygon(QVector<QPoint> &&)". - foreach (AbstractMetaFunction *f, list) { + for (AbstractMetaFunction *f : list) { if ((f->actualMinimumArgumentCount() == 1 || f->arguments().size() == 1 || f->isConversionOperator()) && !f->isExplicit() && f->functionType() != AbstractMetaFunction::CopyConstructorFunction @@ -1415,9 +1414,9 @@ AbstractMetaFunctionList AbstractMetaClass::implicitConversions() const AbstractMetaFunctionList AbstractMetaClass::operatorOverloads(OperatorQueryOptions query) const { - AbstractMetaFunctionList list = queryFunctions(OperatorOverloads | Visible); + const AbstractMetaFunctionList &list = queryFunctions(OperatorOverloads | Visible); AbstractMetaFunctionList returned; - foreach (AbstractMetaFunction *f, list) { + for (AbstractMetaFunction *f : list) { if (((query & ArithmeticOp) && f->isArithmeticOperator()) || ((query & BitwiseOp) && f->isBitwiseOperator()) || ((query & ComparisonOp) && f->isComparisonOperator()) @@ -1434,7 +1433,7 @@ AbstractMetaFunctionList AbstractMetaClass::operatorOverloads(OperatorQueryOptio bool AbstractMetaClass::hasOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isOperatorOverload() && !f->isPrivate()) return true; } @@ -1443,7 +1442,7 @@ bool AbstractMetaClass::hasOperatorOverload() const bool AbstractMetaClass::hasArithmeticOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isArithmeticOperator() && !f->isPrivate()) return true; } @@ -1452,7 +1451,7 @@ bool AbstractMetaClass::hasArithmeticOperatorOverload() const bool AbstractMetaClass::hasBitwiseOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isBitwiseOperator() && !f->isPrivate()) return true; } @@ -1461,7 +1460,7 @@ bool AbstractMetaClass::hasBitwiseOperatorOverload() const bool AbstractMetaClass::hasComparisonOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isComparisonOperator() && !f->isPrivate()) return true; } @@ -1470,7 +1469,7 @@ bool AbstractMetaClass::hasComparisonOperatorOverload() const bool AbstractMetaClass::hasLogicalOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isLogicalOperator() && !f->isPrivate()) return true; } @@ -1479,7 +1478,7 @@ bool AbstractMetaClass::hasLogicalOperatorOverload() const bool AbstractMetaClass::hasSubscriptOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isSubscriptOperator() && !f->isPrivate()) return true; } @@ -1488,7 +1487,7 @@ bool AbstractMetaClass::hasSubscriptOperatorOverload() const bool AbstractMetaClass::hasAssignmentOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isAssignmentOperator() && !f->isPrivate()) return true; } @@ -1497,7 +1496,7 @@ bool AbstractMetaClass::hasAssignmentOperatorOverload() const bool AbstractMetaClass::hasConversionOperatorOverload() const { - foreach (const AbstractMetaFunction *f, m_functions) { + for (const AbstractMetaFunction *f : m_functions) { if (f->ownerClass() == f->implementingClass() && f->isConversionOperator() && !f->isPrivate()) return true; } @@ -1558,7 +1557,7 @@ void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions) QString currentName; bool hasVirtuals = false; AbstractMetaFunctionList finalFunctions; - foreach (AbstractMetaFunction *f, m_functions) { + for (AbstractMetaFunction *f : qAsConst(m_functions)) { f->setOwnerClass(this); m_hasVirtualSlots = m_hasVirtualSlots || f->isVirtualSlot(); @@ -1574,7 +1573,7 @@ void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions) finalFunctions += f; } else { if (hasVirtuals && finalFunctions.size() > 0) { - foreach (AbstractMetaFunction *final_function, finalFunctions) { + for (AbstractMetaFunction *final_function : qAsConst(finalFunctions)) { *final_function += AbstractMetaAttributes::ForceShellImplementation; qCWarning(lcShiboken).noquote().nospace() @@ -1594,7 +1593,7 @@ void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions) bool AbstractMetaClass::hasFieldAccessors() const { - foreach (const AbstractMetaField *field, fields()) { + for (const AbstractMetaField *field : m_fields) { if (field->getter() || field->setter()) return true; } @@ -1604,7 +1603,8 @@ bool AbstractMetaClass::hasFieldAccessors() const bool AbstractMetaClass::hasDefaultToStringFunction() const { - foreach (AbstractMetaFunction *f, queryFunctionsByName(QLatin1String("toString"))) { + const AbstractMetaFunctionList &funcs = queryFunctionsByName(QLatin1String("toString")); + for (const AbstractMetaFunction *f : funcs) { if (!f->actualMinimumArgumentCount()) return true; } @@ -1632,7 +1632,7 @@ bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const if (!other->isSignal()) return false; - foreach (const AbstractMetaFunction *f, functions()) { + for (const AbstractMetaFunction *f : m_functions) { if (f->isSignal() && f->compareTo(other) & AbstractMetaFunction::EqualName) return other->modifiedName() == f->modifiedName(); } @@ -1685,7 +1685,7 @@ bool AbstractMetaClass::hasFunction(const QString &str) const const AbstractMetaFunction* AbstractMetaClass::findFunction(const QString& functionName) const { - foreach (const AbstractMetaFunction *f, functions()) { + for (const AbstractMetaFunction *f : m_functions) { if (f->name() == functionName) return f; } @@ -1694,7 +1694,7 @@ const AbstractMetaFunction* AbstractMetaClass::findFunction(const QString& funct bool AbstractMetaClass::hasProtectedFunctions() const { - foreach (AbstractMetaFunction *func, m_functions) { + for (AbstractMetaFunction *func : m_functions) { if (func->isProtected()) return true; } @@ -1703,7 +1703,7 @@ bool AbstractMetaClass::hasProtectedFunctions() const bool AbstractMetaClass::hasProtectedFields() const { - foreach (const AbstractMetaField *field, fields()) { + for (const AbstractMetaField *field : m_fields) { if (field->isProtected()) return true; } @@ -1775,7 +1775,7 @@ void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList& static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func) { - foreach (const AbstractMetaFunction *f, l) { + for (const AbstractMetaFunction *f : l) { if ((f->compareTo(func) & AbstractMetaFunction::PrettySimilar) == AbstractMetaFunction::PrettySimilar) return true; } @@ -1809,8 +1809,8 @@ AbstractMetaField *AbstractMetaField::copy() const */ bool AbstractMetaField::isModifiedRemoved(int types) const { - FieldModificationList mods = modifications(); - foreach (const FieldModification &mod, mods) { + const FieldModificationList &mods = modifications(); + for (const FieldModification &mod : mods) { if (!mod.isRemoveModifier()) continue; @@ -1854,8 +1854,8 @@ static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QStr f->setAttributes(attr); f->setOriginalAttributes(attr); - FieldModificationList mods = g->modifications(); - foreach (const FieldModification &mod, mods) { + const FieldModificationList &mods = g->modifications(); + for (const FieldModification &mod : mods) { if (mod.isRenameModifier()) f->setName(mod.renamedTo()); if (mod.isAccessModifier()) { @@ -1874,10 +1874,10 @@ static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QStr FieldModificationList AbstractMetaField::modifications() const { - FieldModificationList mods = enclosingClass()->typeEntry()->fieldModifications(); + const FieldModificationList &mods = enclosingClass()->typeEntry()->fieldModifications(); FieldModificationList returned; - foreach (const FieldModification &mod, mods) { + for (const FieldModification &mod : mods) { if (mod.name == name()) returned += mod; } @@ -1994,7 +1994,8 @@ bool AbstractMetaClass::hasConstructors() const bool AbstractMetaClass::hasCopyConstructor() const { - foreach (const AbstractMetaFunction* ctor, queryFunctions(Constructors)) { + const AbstractMetaFunctionList &ctors = queryFunctions(Constructors); + for (const AbstractMetaFunction* ctor : ctors) { if (ctor->functionType() == AbstractMetaFunction::CopyConstructorFunction) return true; } @@ -2003,7 +2004,8 @@ bool AbstractMetaClass::hasCopyConstructor() const bool AbstractMetaClass::hasPrivateCopyConstructor() const { - foreach (const AbstractMetaFunction* ctor, queryFunctions(Constructors)) { + const AbstractMetaFunctionList &ctors = queryFunctions(Constructors); + for (const AbstractMetaFunction *ctor : ctors) { if (ctor->functionType() == AbstractMetaFunction::CopyConstructorFunction && ctor->isPrivate()) return true; } @@ -2077,7 +2079,7 @@ AbstractMetaFunctionList AbstractMetaClass::queryFunctions(FunctionQueryOptions { AbstractMetaFunctionList functions; - foreach (AbstractMetaFunction *f, m_functions) { + for (AbstractMetaFunction *f : m_functions) { if ((query & VirtualSlots) && !f->isVirtualSlot()) continue; @@ -2199,8 +2201,10 @@ void AbstractMetaClass::addInterface(AbstractMetaClass *interface) if (m_extractedInterface && m_extractedInterface != interface) m_extractedInterface->addInterface(interface); + #if 0 - foreach (AbstractMetaFunction *function, interface->functions()) + const AbstractMetaFunctionList &funcs = interface->functions(); + for (AbstractMetaFunction *function : funcs) if (!hasFunction(function) && !function->isConstructor()) { AbstractMetaFunction *cpy = function->copy(); cpy->setImplementingClass(this); @@ -2210,8 +2214,8 @@ void AbstractMetaClass::addInterface(AbstractMetaClass *interface) *cpy += AbstractMetaAttributes::InterfaceFunction; // Copy the modifications in interface into the implementing classes. - FunctionModificationList mods = function->modifications(interface); - foreach (const FunctionModification &mod, mods) + const FunctionModificationList &mods = function->modifications(interface); + for (const FunctionModification &mod : mods) m_typeEntry->addFunctionModification(mod); // It should be mostly safe to assume that when we implement an interface @@ -2228,7 +2232,7 @@ void AbstractMetaClass::addInterface(AbstractMetaClass *interface) void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces) { m_interfaces = interfaces; - foreach (const AbstractMetaClass* interface, interfaces) { + for (const AbstractMetaClass *interface : interfaces) { if (interface) m_isPolymorphic |= interface->isPolymorphic(); } @@ -2237,7 +2241,7 @@ void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces) AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName) { - foreach (AbstractMetaEnum *e, m_enums) { + for (AbstractMetaEnum *e : qAsConst(m_enums)) { if (e->name() == enumName) return e; } @@ -2257,10 +2261,11 @@ AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName) */ AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValueName, AbstractMetaEnum *meta_enum) { - foreach (AbstractMetaEnum *e, m_enums) { + for (AbstractMetaEnum *e : qAsConst(m_enums)) { if (e != meta_enum) continue; - foreach (AbstractMetaEnumValue *v, e->values()) { + const AbstractMetaEnumValueList &values = e->values(); + for (AbstractMetaEnumValue *v : values) { if (v->name() == enumValueName) return v; } @@ -2284,8 +2289,9 @@ AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValue */ AbstractMetaEnum *AbstractMetaClass::findEnumForValue(const QString &enumValueName) { - foreach (AbstractMetaEnum *e, m_enums) { - foreach (AbstractMetaEnumValue *v, e->values()) { + for (AbstractMetaEnum *e : qAsConst(m_enums)) { + const AbstractMetaEnumValueList &values = e->values(); + for (AbstractMetaEnumValue *v : values) { if (v->name() == enumValueName) return e; } @@ -2316,8 +2322,8 @@ static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractM } if (type->hasInstantiations()) { - AbstractMetaTypeList instantiations = type->instantiations(); - foreach (const AbstractMetaType *instantiation, instantiations) + const AbstractMetaTypeList &instantiations = type->instantiations(); + for (const AbstractMetaType *instantiation : instantiations) addExtraIncludeForType(metaClass, instantiation); } } @@ -2328,9 +2334,9 @@ static void addExtraIncludesForFunction(AbstractMetaClass *metaClass, const Abst Q_ASSERT(meta_function); addExtraIncludeForType(metaClass, meta_function->type()); - AbstractMetaArgumentList arguments = meta_function->arguments(); - foreach (AbstractMetaArgument *argument, arguments) - addExtraIncludeForType(metaClass, argument->type()); + const AbstractMetaArgumentList &arguments = meta_function->arguments(); + for (AbstractMetaArgument *argument : arguments) + addExtraIncludeForType(metaClass, argument->type()); } void AbstractMetaClass::fixFunctions() @@ -2448,8 +2454,8 @@ void AbstractMetaClass::fixFunctions() bool hasNonFinalModifier = false; bool isBaseImplPrivate = false; - FunctionModificationList mods = sf->modifications(sf->implementingClass()); - foreach (const FunctionModification &mod, mods) { + const FunctionModificationList &mods = sf->modifications(sf->implementingClass()); + for (const FunctionModification &mod : mods) { if (mod.isNonFinal()) { hasNonFinalModifier = true; break; @@ -2495,7 +2501,7 @@ void AbstractMetaClass::fixFunctions() funcsToAdd << sf; } - foreach (AbstractMetaFunction *f, funcsToAdd) + for (AbstractMetaFunction *f : qAsConst(funcsToAdd)) funcs << f->copy(); if (superClass) @@ -2506,9 +2512,9 @@ void AbstractMetaClass::fixFunctions() bool hasPrivateConstructors = false; bool hasPublicConstructors = false; - foreach (AbstractMetaFunction *func, funcs) { - FunctionModificationList mods = func->modifications(this); - foreach (const FunctionModification &mod, mods) { + for (AbstractMetaFunction *func : qAsConst(funcs)) { + const FunctionModificationList &mods = func->modifications(this); + for (const FunctionModification &mod : mods) { if (mod.isRenameModifier()) { func->setName(mod.renamedTo()); } @@ -2540,8 +2546,8 @@ void AbstractMetaClass::fixFunctions() (*this) -= AbstractMetaAttributes::Final; } - foreach (AbstractMetaFunction *f1, funcs) { - foreach (AbstractMetaFunction *f2, funcs) { + for (AbstractMetaFunction *f1 : qAsConst(funcs)) { + for (AbstractMetaFunction *f2 : qAsConst(funcs)) { if (f1 != f2) { const AbstractMetaFunction::CompareResult cmp = f1->compareTo(f2); if ((cmp & AbstractMetaFunction::EqualName) @@ -2641,15 +2647,6 @@ AbstractMetaEnum *AbstractMetaClass::findEnum(const AbstractMetaClassList &class return metaClass->findEnum(enumName); } -AbstractMetaEnumValue *AbstractMetaEnumValueList::find(const QString &name) const -{ - for (int i = 0; i < size(); ++i) { - if (name == at(i)->name()) - return at(i); - } - return 0; -} - AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const AbstractMetaClassList &classes, const QString &name) { @@ -2664,8 +2661,9 @@ AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const AbstractMetaClassL return cl->findEnumValue(enumName, 0); } - foreach (AbstractMetaClass* metaClass, classes) { - foreach(AbstractMetaEnum* metaEnum, metaClass->enums()) { + for (AbstractMetaClass *metaClass : classes) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (AbstractMetaEnum *metaEnum : enums) { AbstractMetaEnumValue* enumValue = metaClass->findEnumValue(name, metaEnum); if (enumValue) return enumValue; @@ -2688,17 +2686,17 @@ AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &cla if (name.isEmpty()) return 0; - foreach (AbstractMetaClass *c, classes) { + for (AbstractMetaClass *c : classes) { if (c->qualifiedCppName() == name) return c; } - foreach (AbstractMetaClass *c, classes) { + for (AbstractMetaClass *c : classes) { if (c->fullName() == name) return c; } - foreach (AbstractMetaClass *c, classes) { + for (AbstractMetaClass *c : classes) { if (c->name() == name) return c; } @@ -2709,7 +2707,7 @@ AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &cla AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes, const TypeEntry* typeEntry) { - foreach (AbstractMetaClass* c, classes) { + for (AbstractMetaClass* c : classes) { if (c->typeEntry() == typeEntry) return c; } diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index 26702d3a2..4d6d5fb1f 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -956,7 +956,7 @@ public: // true if one or more of the arguments are of QtJambiObject subclasses bool argumentsHaveNativeId() const { - foreach (const AbstractMetaArgument *arg, m_arguments) { + for (const AbstractMetaArgument *arg : m_arguments) { if (arg->type()->hasNativeId()) return true; } @@ -1122,7 +1122,7 @@ public: QString replacedDefaultExpression(const AbstractMetaClass *cls, int idx) const; bool removedDefaultExpression(const AbstractMetaClass *cls, int idx) const; QString conversionRule(TypeSystem::Language language, int idx) const; - QList<ReferenceCount> referenceCounts(const AbstractMetaClass *cls, int idx = -2) const; + QVector<ReferenceCount> referenceCounts(const AbstractMetaClass *cls, int idx = -2) const; ArgumentOwner argumentOwner(const AbstractMetaClass *cls, int idx) const; bool nullPointersDisabled(const AbstractMetaClass *cls = 0, int argument_idx = 0) const; @@ -1293,13 +1293,6 @@ private: Documentation m_doc; }; - -class AbstractMetaEnumValueList : public QList<AbstractMetaEnumValue *> -{ -public: - AbstractMetaEnumValue *find(const QString &name) const; -}; - class AbstractMetaEnum : public AbstractMetaAttributes { public: @@ -1698,12 +1691,12 @@ public: bool hasProtectedMembers() const; - QList<TypeEntry *> templateArguments() const + QVector<TypeEntry *> templateArguments() const { return m_templateArgs; } - void setTemplateArguments(const QList<TypeEntry *> &args) + void setTemplateArguments(const QVector<TypeEntry *> &args) { m_templateArgs = args; } @@ -1772,7 +1765,7 @@ public: m_propertySpecs << spec; } - QList<QPropertySpec *> propertySpecs() const + QVector<QPropertySpec *> propertySpecs() const { return m_propertySpecs; } @@ -1874,13 +1867,13 @@ private: AbstractMetaEnumList m_enums; AbstractMetaClassList m_interfaces; AbstractMetaClass *m_extractedInterface; - QList<QPropertySpec *> m_propertySpecs; + QVector<QPropertySpec *> m_propertySpecs; AbstractMetaClassList m_innerClasses; AbstractMetaFunctionList m_externalConversionOperators; QStringList m_baseClassNames; - QList<TypeEntry *> m_templateArgs; + QVector<TypeEntry *> m_templateArgs; ComplexTypeEntry *m_typeEntry; // FunctionModelItem m_qDebugStreamFunction; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h b/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h index dd6573b78..da8369895 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h @@ -29,21 +29,22 @@ #ifndef ABSTRACTMETALANG_TYPEDEFS_H #define ABSTRACTMETALANG_TYPEDEFS_H -#include <QtCore/QList> +#include <QtCore/QVector> class AbstractMetaClass; class AbstractMetaField; class AbstractMetaArgument; class AbstractMetaEnum; -class AbstractMetaEnumValueList; +class AbstractMetaEnumValue; class AbstractMetaFunction; class AbstractMetaType; -typedef QList<AbstractMetaArgument *> AbstractMetaArgumentList; -typedef QList<AbstractMetaClass *> AbstractMetaClassList; -typedef QList<AbstractMetaEnum *> AbstractMetaEnumList; -typedef QList<AbstractMetaField *> AbstractMetaFieldList; -typedef QList<AbstractMetaFunction *> AbstractMetaFunctionList; -typedef QList<AbstractMetaType *> AbstractMetaTypeList; +typedef QVector<AbstractMetaArgument *> AbstractMetaArgumentList; +typedef QVector<AbstractMetaClass *> AbstractMetaClassList; +typedef QVector<AbstractMetaEnum *> AbstractMetaEnumList; +typedef QVector<AbstractMetaEnumValue *> AbstractMetaEnumValueList; +typedef QVector<AbstractMetaField *> AbstractMetaFieldList; +typedef QVector<AbstractMetaFunction *> AbstractMetaFunctionList; +typedef QVector<AbstractMetaType *> AbstractMetaTypeList; #endif // ABSTRACTMETALANG_TYPEDEFS_H diff --git a/sources/shiboken2/ApiExtractor/apiextractor.cpp b/sources/shiboken2/ApiExtractor/apiextractor.cpp index 371ccf559..abb7c08b9 100644 --- a/sources/shiboken2/ApiExtractor/apiextractor.cpp +++ b/sources/shiboken2/ApiExtractor/apiextractor.cpp @@ -32,25 +32,31 @@ #include <QDir> #include <QDebug> #include <QTemporaryFile> +#include <algorithm> #include <iostream> +#include <iterator> #include "reporthandler.h" #include "typesystem.h" #include "fileout.h" -#include "parser/rpp/pp.h" #include "abstractmetabuilder.h" #include "typedatabase.h" #include "typesystem.h" -static bool preprocess(const QString& sourceFile, - QFile& targetFile, - const QStringList& includes); +static bool appendFile(const QString& sourceFileName, QFile& targetFile) +{ + QFile sourceFile(sourceFileName); + if (!sourceFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + std::cerr << "Cannot open " << qPrintable(QDir::toNativeSeparators(sourceFileName)) + << ": " << qPrintable(sourceFile.errorString()) << '\n'; + return false; + } + targetFile.write(sourceFile.readAll()); + return true; +} ApiExtractor::ApiExtractor() : m_builder(0) { - static bool qrcInitialized = false; - if (!qrcInitialized) - Q_INIT_RESOURCE(generator); // Environment TYPESYSTEMPATH QString envTypesystemPaths = QFile::decodeName(getenv("TYPESYSTEMPATH")); if (!envTypesystemPaths.isEmpty()) @@ -69,16 +75,16 @@ void ApiExtractor::addTypesystemSearchPath (const QString& path) void ApiExtractor::addTypesystemSearchPath(const QStringList& paths) { - foreach (const QString &path, paths) + for (const QString &path : paths) addTypesystemSearchPath(path); } -void ApiExtractor::addIncludePath(const QString& path) +void ApiExtractor::addIncludePath(const HeaderPath& path) { m_includePaths << path; } -void ApiExtractor::addIncludePath(const QStringList& paths) +void ApiExtractor::addIncludePath(const HeaderPaths& paths) { m_includePaths << paths; } @@ -174,8 +180,9 @@ QSet<QString> ApiExtractor::qtMetaTypeDeclaredTypeNames() const static const AbstractMetaEnum* findEnumOnClasses(AbstractMetaClassList metaClasses, const EnumTypeEntry* typeEntry) { const AbstractMetaEnum* result = 0; - foreach (const AbstractMetaClass* metaClass, metaClasses) { - foreach (const AbstractMetaEnum* metaEnum, metaClass->enums()) { + for (const AbstractMetaClass* metaClass : qAsConst(metaClasses)) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (const AbstractMetaEnum *metaEnum : enums) { if (metaEnum->typeEntry() == typeEntry) { result = metaEnum; break; @@ -192,7 +199,8 @@ const AbstractMetaEnum* ApiExtractor::findAbstractMetaEnum(const EnumTypeEntry* { if (!typeEntry) return 0; - foreach (AbstractMetaEnum* metaEnum, m_builder->globalEnums()) { + const AbstractMetaEnumList &globalEnums = m_builder->globalEnums(); + for (AbstractMetaEnum* metaEnum : globalEnums) { if (metaEnum->typeEntry() == typeEntry) return metaEnum; } @@ -243,85 +251,38 @@ bool ApiExtractor::run() return false; } - QTemporaryFile ppFile; -#ifndef NDEBUG - ppFile.setAutoRemove(false); -#endif + const QString pattern = QDir::tempPath() + QLatin1Char('/') + + QFileInfo(m_cppFileName).baseName() + QStringLiteral("_XXXXXX.hpp"); + QTemporaryFile ppFile(pattern); + bool autoRemove = !qEnvironmentVariableIsSet("KEEP_TEMP_FILES"); // make sure that a tempfile can be written if (!ppFile.open()) { - std::cerr << "could not create tempfile in " << qPrintable(QDir::tempPath()); + std::cerr << "could not create tempfile " << qPrintable(pattern) + << ": " << qPrintable(ppFile.errorString()) << '\n'; return false; } - - // run rpp pre-processor - if (!preprocess(m_cppFileName, ppFile, m_includePaths)) { - std::cerr << "Preprocessor failed on file: " << qPrintable(m_cppFileName); + + if (!appendFile(m_cppFileName, ppFile)) return false; - } - ppFile.seek(0); + const QString preprocessedCppFileName = ppFile.fileName(); + ppFile.close(); m_builder = new AbstractMetaBuilder; m_builder->setLogDirectory(m_logDirectory); m_builder->setGlobalHeader(m_cppFileName); - m_builder->build(&ppFile); - - return true; -} - -static bool preprocess(const QString& sourceFile, - QFile& targetFile, - const QStringList& includes) -{ - rpp::pp_environment env; - rpp::pp preprocess(env); - - rpp::pp_null_output_iterator null_out; - - const char *ppconfig = ":/trolltech/generator/pp-qt-configuration"; - - const QString fileName = QLatin1String(ppconfig); - QFile file(fileName); - if (!file.open(QFile::ReadOnly)) { - std::cerr << "Preprocessor configuration file not found " << ppconfig << std::endl; - return false; + QByteArrayList arguments; + arguments.reserve(m_includePaths.size() + 1); + for (const HeaderPath &headerPath : qAsConst(m_includePaths)) + arguments.append(HeaderPath::includeOption(headerPath)); + arguments.append(QFile::encodeName(preprocessedCppFileName)); + qCDebug(lcShiboken) << __FUNCTION__ << arguments; + const bool result = m_builder->build(arguments); + if (!result) + autoRemove = false; + if (!autoRemove) { + ppFile.setAutoRemove(false); + std::cerr << "Keeping temporary file: " << qPrintable(QDir::toNativeSeparators(preprocessedCppFileName)) << '\n'; } - - QByteArray ba = file.readAll(); - file.close(); - preprocess.operator()(ba.constData(), ba.constData() + ba.size(), null_out); - - preprocess.push_include_path("."); - foreach (const QString &include, includes) - preprocess.push_include_path(QDir::toNativeSeparators(include).toStdString()); - preprocess.push_include_path("/usr/include"); - - QString currentDir = QDir::current().absolutePath(); - QFileInfo sourceInfo(sourceFile); - if (!sourceInfo.exists()) { - std::cerr << "File not found " << qPrintable(sourceFile) << std::endl; - return false; - } - QDir::setCurrent(sourceInfo.absolutePath()); - - std::string result; - result.reserve(20 * 1024); // 20K - - result += "# 1 \"builtins\"\n"; - result += "# 1 \""; - result += sourceFile.toStdString(); - result += "\"\n"; - - preprocess.file(sourceInfo.fileName().toStdString(), - rpp::pp_output_iterator<std::string> (result)); - - QDir::setCurrent(currentDir); - - if (!targetFile.open(QIODevice::ReadWrite | QIODevice::Text)) { - std::cerr << "Failed to write preprocessed file: " << qPrintable(targetFile.fileName()) << std::endl; - return false; - } - - targetFile.write(result.c_str(), result.length()); - return true; + return result; } #ifndef QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/apiextractor.h b/sources/shiboken2/ApiExtractor/apiextractor.h index 1080ff507..ac90f5b2f 100644 --- a/sources/shiboken2/ApiExtractor/apiextractor.h +++ b/sources/shiboken2/ApiExtractor/apiextractor.h @@ -33,6 +33,8 @@ #include "dependency.h" #include "abstractmetalang_typedefs.h" #include "apiextractormacros.h" +#include "header_paths.h" +#include "typedatabase_typedefs.h" #include "typesystem_typedefs.h" #include <QStringList> @@ -67,9 +69,9 @@ public: void setSilent(bool value); void addTypesystemSearchPath(const QString& path); void addTypesystemSearchPath(const QStringList& paths); - void addIncludePath(const QString& path); - void addIncludePath(const QStringList& paths); - QStringList includePaths() const { return m_includePaths; } + void addIncludePath(const HeaderPath& path); + void addIncludePath(const HeaderPaths& paths); + HeaderPaths includePaths() const { return m_includePaths; } void setLogDirectory(const QString& logDir); bool setApiVersion(const QString& package, const QString& version); void setDropTypeEntries(QString dropEntries); @@ -94,7 +96,7 @@ public: private: QString m_typeSystemFileName; QString m_cppFileName; - QStringList m_includePaths; + HeaderPaths m_includePaths; AbstractMetaBuilder* m_builder; QString m_logDirectory; diff --git a/sources/shiboken2/ApiExtractor/asttoxml.cpp b/sources/shiboken2/ApiExtractor/asttoxml.cpp deleted file mode 100644 index 7a2f1261e..000000000 --- a/sources/shiboken2/ApiExtractor/asttoxml.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "asttoxml.h" -#include "parser/control.h" -#include "parser/parser.h" -#include "parser/binder.h" - - -#include <QtCore/QXmlStreamWriter> -#include <QtCore/QTextStream> -#include <QtCore/QTextCodec> -#include <QtCore/QFile> - -typedef QHash<QString, EnumModelItem> EnumMap; -typedef QHash<QString, FunctionModelItem> FunctionModelItemMap; -typedef QHash<QString, ClassModelItem> ClassModelItemMap; -typedef QHash<QString, NamespaceModelItem> NamespaceModelItemMap; - -void astToXML(QString name) -{ - QFile file(name); - - if (!file.open(QFile::ReadOnly)) - return; - - QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("UTF-8")); - QByteArray contents = stream.readAll().toUtf8(); - file.close(); - - Control control; - Parser p(&control); - pool __pool; - - TranslationUnitAST *ast = p.parse(contents, contents.size(), &__pool); - - CodeModel model; - Binder binder(&model, p.location()); - FileModelItem dom = binder.run(ast); - - QFile outputFile; - if (!outputFile.open(stdout, QIODevice::WriteOnly)) - return; - - QXmlStreamWriter s(&outputFile); - s.setAutoFormatting(true); - - s.writeStartElement(QLatin1String("code")); - - const NamespaceList &namespaces = dom->namespaces(); - foreach (const NamespaceModelItem &n, namespaces) - writeOutNamespace(s, n); - - const ClassList &classList = dom->classes(); - foreach (const ClassModelItem &c, classList) - writeOutClass(s, c); - - s.writeEndElement(); -} - -void writeOutNamespace(QXmlStreamWriter &s, const NamespaceModelItem &item) -{ - s.writeStartElement(QLatin1String("namespace")); - s.writeAttribute(QLatin1String("name"), item->name()); - - const NamespaceList &namespaces = item->namespaces(); - foreach (const NamespaceModelItem &n, namespaces) - writeOutNamespace(s, n); - - const ClassList &classList = item->classes(); - foreach (const ClassModelItem &c, classList) - writeOutClass(s, c); - - const EnumList &enums = item->enums(); - foreach (const EnumModelItem &e, enums) - writeOutEnum(s, e); - - s.writeEndElement(); -} - -void writeOutEnum(QXmlStreamWriter &s, const EnumModelItem &item) -{ - QString qualifiedName = item->qualifiedName().join(QLatin1String("::")); - s.writeStartElement(QLatin1String("enum")); - s.writeAttribute(QLatin1String("name"), qualifiedName); - - EnumeratorList enumList = item->enumerators(); - for (int i = 0; i < enumList.size() ; i++) { - s.writeStartElement(QLatin1String("enumerator")); - if (!enumList[i]->value().isEmpty()) - s.writeAttribute(QLatin1String("value"), enumList[i]->value()); - s.writeCharacters(enumList[i]->name()); - - s.writeEndElement(); - } - s.writeEndElement(); -} - -void writeOutFunction(QXmlStreamWriter &s, const FunctionModelItem &item) -{ - QString qualifiedName = item->qualifiedName().join(QLatin1String("::")); - s.writeStartElement(QLatin1String("function")); - s.writeAttribute(QLatin1String("name"), qualifiedName); - - ArgumentList arguments = item->arguments(); - for (int i = 0; i < arguments.size() ; i++) { - s.writeStartElement(QLatin1String("argument")); - s.writeAttribute(QLatin1String("type"), arguments[i]->type().qualifiedName().join(QLatin1String("::"))); - s.writeEndElement(); - } - s.writeEndElement(); -} - -void writeOutClass(QXmlStreamWriter &s, const ClassModelItem &item) -{ - QString qualifiedName = item->qualifiedName().join(QLatin1String("::")); - s.writeStartElement(QLatin1String("class")); - s.writeAttribute(QLatin1String("name"), qualifiedName); - - const EnumList &enums = item->enums(); - foreach (const EnumModelItem &e, enums) - writeOutEnum(s, e); - - const FunctionList &functionList = item->functions(); - foreach (const FunctionModelItem &func, functionList) - writeOutFunction(s, func); - - const ClassList &classList = item->classes(); - foreach (const ClassModelItem &c, classList) - writeOutClass(s, c); - - s.writeEndElement(); -} - diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp new file mode 100644 index 000000000..dc0c59dd5 --- /dev/null +++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp @@ -0,0 +1,770 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "clangbuilder.h" +#include "compilersupport.h" +#include "clangutils.h" + +#include <codemodel.h> + +#include <QtCore/QDebug> +#include <QtCore/QDir> +#include <QtCore/QHash> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStack> +#include <QtCore/QVector> + +#include <string.h> + +#if QT_VERSION < 0x050800 +# define Q_FALLTHROUGH() (void)0 +#endif + +namespace clang { + +static inline QString colonColon() { return QStringLiteral("::"); } +static inline QString templateBrackets() { return QStringLiteral("<>"); } + +static inline bool isClassCursor(const CXCursor &c) +{ + return c.kind == CXCursor_ClassDecl || c.kind == CXCursor_StructDecl + || c.kind == CXCursor_ClassTemplate + || c.kind == CXCursor_ClassTemplatePartialSpecialization; +} + +static inline bool withinClassDeclaration(const CXCursor &cursor) +{ + return isClassCursor(clang_getCursorLexicalParent(cursor)); +} + +static QString fixTypeName(QString t) +{ + // Fix "Foo &" -> "Foo&", similarly "Bar **" -> "Bar**" + int pos = t.size() - 1; + for (; pos >= 0 && (t.at(pos) == QLatin1Char('&') || t.at(pos) == QLatin1Char('*')); --pos) {} + if (pos > 0 && t.at(pos) == QLatin1Char(' ')) + t.remove(pos, 1); + return t; +} + +// Insert template parameter to class name: "Foo<>" -> "Foo<T1>" -> "Foo<T1,T2>" +// This needs to be done immediately when template parameters are encountered since +// the class name "Foo<T1,T2>" is the scope for nested items. +static bool insertTemplateParameterIntoClassName(const QString &parmName, QString *name) +{ + if (Q_UNLIKELY(!name->endsWith(QLatin1Char('>')))) + return false; + const bool needsComma = name->at(name->size() - 2) != QLatin1Char('<'); + const int insertionPos = name->size() - 1; + name->insert(insertionPos, parmName); + if (needsComma) + name->insert(insertionPos, QLatin1Char(',')); + return true; +} + +static inline bool insertTemplateParameterIntoClassName(const QString &parmName, + const ClassModelItem &item) +{ + QString name = item->name(); + const bool result = insertTemplateParameterIntoClassName(parmName, &name); + item->setName(name); + return result; +} + +static inline CodeModel::AccessPolicy accessPolicy(CX_CXXAccessSpecifier access) +{ + CodeModel::AccessPolicy result = CodeModel::Public; + switch (access) { + case CX_CXXProtected: + result = CodeModel::Protected; + break; + case CX_CXXPrivate: + result = CodeModel::Private; + break; + default: + break; + } + return result; +} + +static void setFileName(const CXCursor &cursor, _CodeModelItem *item) +{ + const SourceRange range = getCursorRange(cursor); + if (!range.first.file.isEmpty()) { // Has been observed to be 0 for invalid locations + item->setFileName(QDir::cleanPath(range.first.file)); + item->setStartPosition(int(range.first.line), int(range.first.column)); + item->setEndPosition(int(range.second.line), int(range.second.column)); + } +} + +class BuilderPrivate { +public: + typedef QHash<CXCursor, ClassModelItem> CursorClassHash; + typedef QHash<CXCursor, TypeDefModelItem> CursorTypedefHash; + + explicit BuilderPrivate(BaseVisitor *bv) : m_baseVisitor(bv), m_model(new CodeModel) + { + m_scopeStack.push(NamespaceModelItem(new _FileModelItem(m_model))); + } + + // Determine scope from top item. Note that the scope list does not necessarily + // match the scope stack in case of forward-declared inner classes whose definition + // appears in the translation unit while the scope is the outer class. + void updateScope() + { + if (m_scopeStack.size() <= 1) + m_scope.clear(); + else + m_scope = m_scopeStack.back()->scope() << m_scopeStack.back()->name(); + } + + void pushScope(const ScopeModelItem &i) + { + m_scopeStack.push(i); + updateScope(); + } + + void popScope() + { + m_scopeStack.pop(); + updateScope(); + } + + bool addClass(const CXCursor &cursor, CodeModel::ClassType t); + FunctionModelItem createFunction(const CXCursor &cursor, + CodeModel::FunctionType t = CodeModel::Normal) const; + FunctionModelItem createMemberFunction(const CXCursor &cursor, + CodeModel::FunctionType t = CodeModel::Normal) const; + void qualifyConstructor(const CXCursor &cursor); + TypeInfo createTypeInfo(const CXType &type) const; + TypeInfo createTypeInfo(const CXCursor &cursor) const + { return createTypeInfo(clang_getCursorType(cursor)); } + + TemplateParameterModelItem createTemplateParameter(const CXCursor &cursor) const; + TemplateParameterModelItem createNonTypeTemplateParameter(const CXCursor &cursor) const; + void addField(const CXCursor &cursor); + + QString cursorValueExpression(BaseVisitor *bv, const CXCursor &cursor) const; + void addBaseClass(const CXCursor &cursor); + + template <class Item> + void qualifyTypeDef(const CXCursor &typeRefCursor, const QSharedPointer<Item> &item) const; + + BaseVisitor *m_baseVisitor; + CodeModel *m_model; + + QStack<ScopeModelItem> m_scopeStack; + QStringList m_scope; + // Store all classes by cursor so that base classes can be found and inner + // classes can be correctly parented in case of forward-declared inner classes + // (QMetaObject::Connection) + CursorClassHash m_cursorClassHash; + CursorTypedefHash m_cursorTypedefHash; + + ClassModelItem m_currentClass; + EnumModelItem m_currentEnum; + FunctionModelItem m_currentFunction; + ArgumentModelItem m_currentArgument; + VariableModelItem m_currentField; + + int m_anonymousEnumCount = 0; + CodeModel::FunctionType m_currentFunctionType = CodeModel::Normal; +}; + +bool BuilderPrivate::addClass(const CXCursor &cursor, CodeModel::ClassType t) +{ + QString className = getCursorSpelling(cursor); + m_currentClass.reset(new _ClassModelItem(m_model, className)); + setFileName(cursor, m_currentClass.data()); + m_currentClass->setClassType(t); + // Some inner class? Note that it does not need to be (lexically) contained in a + // class since it is possible to forward declare an inner class: + // class QMetaObject { class Connection; } + // class QMetaObject::Connection {} + const CXCursor semPar = clang_getCursorSemanticParent(cursor); + if (isClassCursor(semPar)) { + const CursorClassHash::const_iterator it = m_cursorClassHash.constFind(semPar); + if (it == m_cursorClassHash.constEnd()) { + const QString message = QStringLiteral("Unable to find parent of inner class ") + className; + const Diagnostic d(message, cursor, CXDiagnostic_Error); + qWarning() << d; + m_baseVisitor->appendDiagnostic(d); + return false; + } + const ClassModelItem &containingClass = it.value(); + containingClass->addClass(m_currentClass); + m_currentClass->setScope(containingClass->scope() << containingClass->name()); + } else { + m_currentClass->setScope(m_scope); + m_scopeStack.back()->addClass(m_currentClass); + } + pushScope(m_currentClass); + m_cursorClassHash.insert(cursor, m_currentClass); + return true; +} + +FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor, + CodeModel::FunctionType t) const +{ + QString name = getCursorSpelling(cursor); + // Apply type fixes to "operator X &" -> "operator X&" + if (name.startsWith(QLatin1String("operator "))) + name = fixTypeName(name); + FunctionModelItem result(new _FunctionModelItem(m_model, name)); + setFileName(cursor, result.data()); + result->setType(createTypeInfo(clang_getCursorResultType(cursor))); + result->setFunctionType(t); + result->setScope(m_scope); + result->setStatic(clang_Cursor_getStorageClass(cursor) == CX_SC_Static); + return result; +} + +FunctionModelItem BuilderPrivate::createMemberFunction(const CXCursor &cursor, + CodeModel::FunctionType t) const +{ + FunctionModelItem result = createFunction(cursor, t); + result->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor))); + result->setConstant(clang_CXXMethod_isConst(cursor) != 0); + result->setStatic(clang_CXXMethod_isStatic(cursor) != 0); + result->setVirtual(clang_CXXMethod_isVirtual(cursor) != 0); + result->setAbstract(clang_CXXMethod_isPureVirtual(cursor) != 0); + result->setFunctionType(m_currentFunctionType); + return result; +} + +// For CXCursor_Constructor, on endToken(). +void BuilderPrivate::qualifyConstructor(const CXCursor &cursor) +{ + // Clang does not tell us whether a constructor is explicit, preventing it + // from being used for implicit conversions. Try to guess whether a + // constructor is explicit in the C++99 sense (1 parameter) by checking for + // isConvertingConstructor() == 0. Fixme: The notion of "isConvertingConstructor" + // should be used in the code model instead of "explicit" + if (clang_CXXConstructor_isDefaultConstructor(cursor) == 0 + && m_currentFunction->arguments().size() == 1 + && clang_CXXConstructor_isCopyConstructor(cursor) == 0 + && clang_CXXConstructor_isMoveConstructor(cursor) == 0) { + m_currentFunction->setExplicit(clang_CXXConstructor_isConvertingConstructor(cursor) == 0); + } +} + +TemplateParameterModelItem BuilderPrivate::createTemplateParameter(const CXCursor &cursor) const +{ + return TemplateParameterModelItem(new _TemplateParameterModelItem(m_model, getCursorSpelling(cursor))); +} + +TemplateParameterModelItem BuilderPrivate::createNonTypeTemplateParameter(const CXCursor &cursor) const +{ + TemplateParameterModelItem result = createTemplateParameter(cursor); + result->setType(createTypeInfo(cursor)); + return result; +} + +// CXCursor_VarDecl, CXCursor_FieldDecl cursors +void BuilderPrivate::addField(const CXCursor &cursor) +{ + VariableModelItem field(new _VariableModelItem(m_model, getCursorSpelling(cursor))); + field->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor))); + field->setScope(m_scope); + field->setType(createTypeInfo(cursor)); + field->setMutable(clang_CXXField_isMutable(cursor) != 0); + m_currentField = field; + m_scopeStack.back()->addVariable(field); +} + +// Array helpers: Parse "a[2][4]" into a list of dimensions + +struct ArrayDimensionResult +{ + QVector<QStringRef> dimensions; + int position; +}; + +static ArrayDimensionResult arrayDimensions(const QString &typeName) +{ + ArrayDimensionResult result; + result.position = typeName.indexOf(QLatin1Char('[')); + for (int openingPos = result.position; openingPos != -1; ) { + const int closingPos = typeName.indexOf(QLatin1Char(']'), openingPos + 1); + if (closingPos == -1) + break; + result.dimensions.append(typeName.midRef(openingPos + 1, closingPos - openingPos - 1)); + openingPos = typeName.indexOf(QLatin1Char('['), closingPos + 1); + } + return result; +} + +// Array helpers: Parse "a[2][4]" into a list of dimensions or "" for none +static QStringList parseArrayArgs(const CXType &type, QString *typeName) +{ + const ArrayDimensionResult dimensions = arrayDimensions(*typeName); + Q_ASSERT(!dimensions.dimensions.isEmpty()); + + QStringList result; + // get first dimension from clang, preferably. + // "a[]" is seen as pointer by Clang, set special indicator "" + const long long size = clang_getArraySize(type); + result.append(size >= 0 ? QString::number(size) : QString()); + // Parse out remaining dimensions + for (int i = 1, count = dimensions.dimensions.size(); i < count; ++i) + result.append(dimensions.dimensions.at(i).toString()); + typeName->truncate(dimensions.position); + return result; +} + +TypeInfo BuilderPrivate::createTypeInfo(const CXType &type) const +{ + if (type.kind == CXType_Pointer) { // Check for function pointers, first. + const CXType pointeeType = clang_getPointeeType(type); + const int argCount = clang_getNumArgTypes(pointeeType); + if (argCount >= 0) { + TypeInfo result = createTypeInfo(clang_getResultType(pointeeType)); + result.setFunctionPointer(true); + for (int a = 0; a < argCount; ++a) + result.addArgument(createTypeInfo(clang_getArgType(pointeeType, unsigned(a)))); + return result; + } + } + + TypeInfo typeInfo; + QString typeName = fixTypeName(getTypeName(type)); + + int indirections = 0; + // "int **" + for ( ; typeName.endsWith(QLatin1Char('*')) ; ++indirections) + typeName.chop(1); + typeInfo.setIndirections(indirections); + // "int &&" + if (typeName.endsWith(QLatin1String("&&"))) { + typeName.chop(2); + typeInfo.setReferenceType(RValueReference); + } else if (typeName.endsWith(QLatin1Char('&'))) { // "int &" + typeName.chop(1); + typeInfo.setReferenceType(LValueReference); + } + + // "int [3], int[]" + if (type.kind == CXType_ConstantArray || type.kind == CXType_IncompleteArray + || type.kind == CXType_VariableArray || type.kind == CXType_DependentSizedArray) { + typeInfo.setArrayElements(parseArrayArgs(type, &typeName)); + } + + bool isConstant = clang_isConstQualifiedType(type) != 0; + // A "char *const" parameter, is considered to be const-qualified by Clang, but + // not in the TypeInfo sense (corresponds to "char *" and not "const char *"). + if (type.kind == CXType_Pointer && isConstant && typeName.endsWith(QLatin1String("const"))) { + typeName.chop(5); + typeName = typeName.trimmed(); + isConstant = false; + } + // Clang has been observed to return false for "const int .." + if (!isConstant && typeName.startsWith(QLatin1String("const "))) { + typeName.remove(0, 6); + isConstant = true; + } + typeInfo.setConstant(isConstant); + + // clang_isVolatileQualifiedType() returns true for "volatile int", but not for "volatile int *" + if (typeName.startsWith(QLatin1String("volatile "))) { + typeName.remove(0, 9); + typeInfo.setVolatile(true); + } + + typeName = typeName.trimmed(); + + typeInfo.setQualifiedName(typeName.split(colonColon())); + // 3320:CINDEX_LINKAGE int clang_getNumArgTypes(CXType T); function ptr types? + return typeInfo; +} + +// extract an expression from the cursor via source +// CXCursor_EnumConstantDecl, ParmDecl (a = Flag1 | Flag2) +QString BuilderPrivate::cursorValueExpression(BaseVisitor *bv, const CXCursor &cursor) const +{ + BaseVisitor::CodeSnippet snippet = bv->getCodeSnippet(cursor); + const char *equalSign = std::find(snippet.first, snippet.second, '='); + if (equalSign == snippet.second) + return QString(); + ++equalSign; + return QString::fromLocal8Bit(equalSign, int(snippet.second - equalSign)).trimmed(); +} + +// Add a base class to the current class from CXCursor_CXXBaseSpecifier +void BuilderPrivate::addBaseClass(const CXCursor &cursor) +{ + const CXType inheritedType = clang_getCursorType(cursor); // Note spelling has "struct baseClass", + QString baseClassName = getTypeName(inheritedType); // use type. + const CXCursor declCursor = clang_getTypeDeclaration(inheritedType); + const CursorClassHash::const_iterator it = m_cursorClassHash.constFind(declCursor); + if (it == m_cursorClassHash.constEnd()) { + // Set unqualified name. This happens in cases like "class X : public std::list<...>" + // "template<class T> class Foo : public T" and standard types like true_type, false_type. + m_currentClass->setBaseClasses(m_currentClass->baseClasses() << baseClassName); + return; + } + // Completely qualify the class name by looking it up and taking its scope + // plus the actual baseClass stripped off any scopes. Consider: + // namespace std { + // template <class T> class vector {}; + // namespace n { + // class Foo : public vector<int> {}; + // } + // } + // should have "std::vector<int>" as base class (whereas the type of the base class is + // "std::vector<T>"). + const QStringList &baseScope = it.value()->scope(); + if (!baseScope.isEmpty()) { + const int lastSep = baseClassName.lastIndexOf(colonColon()); + if (lastSep >= 0) + baseClassName.remove(0, lastSep + colonColon().size()); + baseClassName.prepend(colonColon()); + baseClassName.prepend(baseScope.join(colonColon())); + } + m_currentClass->setBaseClasses(m_currentClass->baseClasses() << baseClassName); +} + +static inline CXCursor definitionFromTypeRef(const CXCursor &typeRefCursor) +{ + Q_ASSERT(typeRefCursor.kind == CXCursor_TypeRef); + return clang_getTypeDeclaration(clang_getCursorType(typeRefCursor)); +} + +// Qualify function arguments or fields that are typedef'ed from another scope: +// enum ConversionFlag {}; +// typedef QFlags<ConversionFlag> ConversionFlags; +// class QTextCodec { +// enum ConversionFlag {}; +// typedef QFlags<ConversionFlag> ConversionFlags; +// struct ConverterState { +// explicit ConverterState(ConversionFlags); +// ^^ qualify to QTextCodec::ConversionFlags +// ConversionFlags m_flags; +// ^^ ditto + +template <class Item> // ArgumentModelItem, VariableModelItem +void BuilderPrivate::qualifyTypeDef(const CXCursor &typeRefCursor, const QSharedPointer<Item> &item) const +{ + typedef typename CursorTypedefHash::const_iterator ConstIt; + + TypeInfo type = item->type(); + if (type.qualifiedName().size() == 1) { // item's type is unqualified. + const ConstIt it = m_cursorTypedefHash.constFind(definitionFromTypeRef(typeRefCursor)); + if (it != m_cursorTypedefHash.constEnd() && !it.value()->scope().isEmpty()) { + type.setQualifiedName(it.value()->scope() + type.qualifiedName()); + item->setType(type); + } + } +} + +Builder::Builder() +{ + d = new BuilderPrivate(this); +} + +Builder::~Builder() +{ + delete d; +} + +bool Builder::visitLocation(const CXSourceLocation &location) const +{ + return !clang_Location_isInSystemHeader(location); +} + +FileModelItem Builder::dom() const +{ + Q_ASSERT(!d->m_scopeStack.isEmpty()); + return qSharedPointerDynamicCast<_FileModelItem>(d->m_scopeStack.constFirst()); +} + +static QString msgOutOfOrder(const CXCursor &cursor, const char *expectedScope) +{ + return getCursorKindName(cursor.kind) + QLatin1Char(' ') + + getCursorSpelling(cursor) + QLatin1String(" encountered outside ") + + QLatin1String(expectedScope) + QLatin1Char('.'); +} + +static CodeModel::ClassType codeModelClassTypeFromCursor(CXCursorKind kind) +{ + CodeModel::ClassType result = CodeModel::Class; + if (kind == CXCursor_UnionDecl) + result = CodeModel::Union; + else if (kind == CXCursor_StructDecl) + result = CodeModel::Struct; + return result; +} + +BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor) +{ + switch (cursor.kind) { + case CXCursor_CXXAccessSpecifier: + d->m_currentFunctionType = CodeModel::Normal; + break; + case CXCursor_AnnotateAttr: { + const QString annotation = getCursorSpelling(cursor); + if (annotation == QLatin1String("qt_slot")) + d->m_currentFunctionType = CodeModel::Slot; + else if (annotation == QLatin1String("qt_signal")) + d->m_currentFunctionType = CodeModel::Signal; + else + d->m_currentFunctionType = CodeModel::Normal; + } + break; + case CXCursor_CXXBaseSpecifier: + if (d->m_currentClass.isNull()) { + const Diagnostic d(msgOutOfOrder(cursor, "class"), cursor, CXDiagnostic_Error); + qWarning() << d; + appendDiagnostic(d); + return Error; + } + d->addBaseClass(cursor); + break; + case CXCursor_ClassDecl: + case CXCursor_UnionDecl: + case CXCursor_StructDecl: + if (clang_isCursorDefinition(cursor) == 0) + return Skip; + if (!d->addClass(cursor, codeModelClassTypeFromCursor(cursor.kind))) + return Error; + break; + case CXCursor_ClassTemplate: + case CXCursor_ClassTemplatePartialSpecialization: + if (clang_isCursorDefinition(cursor) == 0) + return Skip; + d->addClass(cursor, CodeModel::Class); + d->m_currentClass->setName(d->m_currentClass->name() + templateBrackets()); + d->m_scope.back() += templateBrackets(); + break; + case CXCursor_EnumDecl: { + QString name = getCursorSpelling(cursor); + const bool anonymous = name.isEmpty(); + if (anonymous) + name = QStringLiteral("enum_") + QString::number(++d->m_anonymousEnumCount); + d->m_currentEnum.reset(new _EnumModelItem(d->m_model, name)); + setFileName(cursor, d->m_currentEnum.data()); + d->m_currentEnum->setScope(d->m_scope); + d->m_currentEnum->setAnonymous(anonymous); + if (!qSharedPointerDynamicCast<_ClassModelItem>(d->m_scopeStack.back()).isNull()) + d->m_currentEnum->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor))); + d->m_scopeStack.back()->addEnum(d->m_currentEnum); + } + break; + case CXCursor_EnumConstantDecl: { + const QString name = getCursorSpelling(cursor); + if (d->m_currentEnum.isNull()) { + const Diagnostic d(msgOutOfOrder(cursor, "enum"), cursor, CXDiagnostic_Error); + qWarning() << d; + appendDiagnostic(d); + return Error; + } + EnumeratorModelItem enumConstant(new _EnumeratorModelItem(d->m_model, name)); + enumConstant->setValue(d->cursorValueExpression(this, cursor)); + d->m_currentEnum->addEnumerator(enumConstant); + } + break; + case CXCursor_VarDecl: + // static class members are seen as CXCursor_VarDecl + if (!d->m_currentClass.isNull() && isClassCursor(clang_getCursorSemanticParent(cursor))) { + d->addField(cursor); + d->m_currentField->setStatic(true); + } + break; + case CXCursor_FieldDecl: + d->addField(cursor); + break; +#if CINDEX_VERSION_MAJOR > 0 || CINDEX_VERSION_MINOR >= 37 // Clang 4.0 + case CXCursor_FriendDecl: + return Skip; +#endif + case CXCursor_Constructor: + case CXCursor_Destructor: // Note: Also use clang_CXXConstructor_is..Constructor? + case CXCursor_CXXMethod: + case CXCursor_ConversionFunction: + // Skip inline member functions outside class, only go by declarations inside class + if (!withinClassDeclaration(cursor)) + return Skip; + d->m_currentFunction = d->createMemberFunction(cursor, CodeModel::Normal); + d->m_scopeStack.back()->addFunction(d->m_currentFunction); + break; + // Not fully supported, currently, seen as normal function + // Note: May appear inside class (member template) or outside (free template). + case CXCursor_FunctionTemplate: { + const CXCursor semParent = clang_getCursorSemanticParent(cursor); + if (isClassCursor(semParent)) { + if (semParent == clang_getCursorLexicalParent(cursor)) { + d->m_currentFunction = d->createMemberFunction(cursor, CodeModel::Normal); + d->m_scopeStack.back()->addFunction(d->m_currentFunction); + break; + } else { + return Skip; // inline member functions outside class + } + } + } + Q_FALLTHROUGH(); // fall through to free template function. + case CXCursor_FunctionDecl: + d->m_currentFunction = d->createFunction(cursor); + d->m_scopeStack.back()->addFunction(d->m_currentFunction); + break; + case CXCursor_Namespace: { + const QString name = getCursorSpelling(cursor); + const NamespaceModelItem parentNamespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(d->m_scopeStack.back()); + if (parentNamespaceItem.isNull()) { + const QString message = msgOutOfOrder(cursor, "namespace") + + QLatin1String(" (current scope: ") + d->m_scopeStack.back()->name() + QLatin1Char(')'); + const Diagnostic d(message, cursor, CXDiagnostic_Error); + qWarning() << d; + appendDiagnostic(d); + return Error; + } + // If possible, continue existing namespace (as otherwise, all headers + // where a namespace is continued show up in the type database). + NamespaceModelItem namespaceItem = parentNamespaceItem->findNamespace(name); + if (namespaceItem.isNull()) { + namespaceItem.reset(new _NamespaceModelItem(d->m_model, name)); + setFileName(cursor, namespaceItem.data()); + namespaceItem->setScope(d->m_scope); + parentNamespaceItem->addNamespace(namespaceItem); + } + d->pushScope(namespaceItem); + } + break; + case CXCursor_ParmDecl: + // Skip in case of nested CXCursor_ParmDecls in case one parameter is a function pointer + // and function pointer typedefs. + if (d->m_currentArgument.isNull() && !d->m_currentFunction.isNull()) { + const QString name = getCursorSpelling(cursor); + d->m_currentArgument.reset(new _ArgumentModelItem(d->m_model, name)); + d->m_currentArgument->setType(d->createTypeInfo(cursor)); + d->m_currentFunction->addArgument(d->m_currentArgument); + QString defaultValueExpression = d->cursorValueExpression(this, cursor); + if (!defaultValueExpression.isEmpty()) { + d->m_currentArgument->setDefaultValueExpression(defaultValueExpression); + d->m_currentArgument->setDefaultValue(true); + } + } else { + return Skip; + } + break; + case CXCursor_TemplateTypeParameter: + case CXCursor_NonTypeTemplateParameter: { + const TemplateParameterModelItem tItem = cursor.kind == CXCursor_TemplateTemplateParameter + ? d->createTemplateParameter(cursor) : d->createNonTypeTemplateParameter(cursor); + // Apply to function/member template? + if (!d->m_currentFunction.isNull()) { + d->m_currentFunction->setTemplateParameters(d->m_currentFunction->templateParameters() << tItem); + } else if (!d->m_currentClass.isNull()) { // Apply to class + const QString &tplParmName = tItem->name(); + if (Q_UNLIKELY(!insertTemplateParameterIntoClassName(tplParmName, d->m_currentClass) + || !insertTemplateParameterIntoClassName(tplParmName, &d->m_scope.back()))) { + const QString message = QStringLiteral("Error inserting template parameter \"") + tplParmName + + QStringLiteral("\" into ") + d->m_currentClass->name(); + const Diagnostic d(message, cursor, CXDiagnostic_Error); + qWarning() << d; + appendDiagnostic(d); + return Error; + } + d->m_currentClass->setTemplateParameters(d->m_currentClass->templateParameters() << tItem); + } + } + break; + case CXCursor_TypeAliasDecl: + case CXCursor_TypeAliasTemplateDecl: // May contain nested CXCursor_TemplateTypeParameter + return Skip; + case CXCursor_TypedefDecl: { + const QString name = getCursorSpelling(cursor); + TypeDefModelItem item(new _TypeDefModelItem(d->m_model, name)); + setFileName(cursor, item.data()); + item->setType(d->createTypeInfo(clang_getTypedefDeclUnderlyingType(cursor))); + item->setScope(d->m_scope); + d->m_scopeStack.back()->addTypeDef(item); + d->m_cursorTypedefHash.insert(cursor, item); + } + break; + case CXCursor_TypeRef: + if (!d->m_currentFunction.isNull()) { + if (d->m_currentArgument.isNull()) + d->qualifyTypeDef(cursor, d->m_currentFunction); // return type + else + d->qualifyTypeDef(cursor, d->m_currentArgument); + } else if (!d->m_currentField.isNull()) { + d->qualifyTypeDef(cursor, d->m_currentField); + } + break; + default: + break; + } + return BaseVisitor::Recurse; +} + +bool Builder::endToken(const CXCursor &cursor) +{ + switch (cursor.kind) { + case CXCursor_UnionDecl: + case CXCursor_ClassDecl: + case CXCursor_StructDecl: + case CXCursor_ClassTemplate: + case CXCursor_ClassTemplatePartialSpecialization: + d->popScope(); + // Continue in outer class after leaving inner class? + if (ClassModelItem lastClass = qSharedPointerDynamicCast<_ClassModelItem>(d->m_scopeStack.back())) + d->m_currentClass = lastClass; + else + d->m_currentClass.clear(); + d->m_currentFunctionType = CodeModel::Normal; + break; + case CXCursor_EnumDecl: + d->m_currentEnum.clear(); + break; + case CXCursor_VarDecl: + case CXCursor_FieldDecl: + d->m_currentField.clear(); + break; + case CXCursor_Constructor: + d->qualifyConstructor(cursor); + d->m_currentFunction.clear(); + break; + case CXCursor_Destructor: + case CXCursor_CXXMethod: + case CXCursor_FunctionDecl: + case CXCursor_FunctionTemplate: + d->m_currentFunction.clear(); + break; + case CXCursor_Namespace: + d->popScope(); + break; + case CXCursor_ParmDecl: + d->m_currentArgument.clear(); + break; + default: + break; + } + return true; +} + +} // namespace clang diff --git a/sources/shiboken2/ApiExtractor/parser/dumptree.h b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h index 5d91c6ef1..c97b7d2b7 100644 --- a/sources/shiboken2/ApiExtractor/parser/dumptree.h +++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h @@ -1,7 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of PySide2. @@ -27,25 +26,33 @@ ** ****************************************************************************/ +#ifndef CLANGBUILDER_H +#define CLANGBUILDER_H -#ifndef DUMPTREE_H -#define DUMPTREE_H +#include "clangparser.h" -#include "default_visitor.h" +#include <codemodel_fwd.h> -class DumpTree: protected DefaultVisitor -{ +namespace clang { + +class BuilderPrivate; + +class Builder : public BaseVisitor { public: - DumpTree(); + Builder(); + ~Builder(); + + bool visitLocation(const CXSourceLocation &location) const override; + + StartTokenResult startToken(const CXCursor &cursor) override; + bool endToken(const CXCursor &cursor) override; - void dump(AST *node) { - visit(node); - } + FileModelItem dom() const; -protected: - virtual void visit(AST *node); +private: + BuilderPrivate *d; }; -#endif // DUMPTREE_H +} // namespace clang -// kate: space-indent on; indent-width 2; replace-tabs on; +#endif // CLANGBUILDER_H diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.cpp new file mode 100644 index 000000000..8d0fd098a --- /dev/null +++ b/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "clangdebugutils.h" +#include "clangutils.h" + +#include <QtCore/QDebug> +#include <QtCore/QString> + +#include <string.h> + +#ifndef QT_NO_DEBUG_STREAM + +#ifdef Q_OS_WIN +const char pathSep = '\\'; +#else +const char pathSep = '/'; +#endif + +static const char *baseName(const char *fileName) +{ + const char *b = strrchr(fileName, pathSep); + return b ? b + 1 : fileName; +} + +QDebug operator<<(QDebug s, const CXString &cs) +{ + s << clang_getCString(cs); + return s; +} + +QDebug operator<<(QDebug s, CXCursorKind cursorKind) // Enum +{ + const CXString kindName = clang_getCursorKindSpelling(cursorKind); + s << kindName; + clang_disposeString(kindName); + return s; +} + +static const char *accessSpecsStrings[] +{ + // CX_CXXInvalidAccessSpecifier, CX_CXXPublic, CX_CXXProtected, CX_CXXPrivate + "invalid", "public", "protected", "private" +}; + +QDebug operator<<(QDebug s, CX_CXXAccessSpecifier ac) +{ + s << accessSpecsStrings[ac]; + return s; +} + +QDebug operator<<(QDebug s, const CXType &t) +{ + CXString typeSpelling = clang_getTypeSpelling(t); + s << typeSpelling; + clang_disposeString(typeSpelling); + return s; +} + +QDebug operator<<(QDebug s, const CXCursor &cursor) +{ + QDebugStateSaver saver(s); + s.nospace(); + s.noquote(); + const CXCursorKind kind = clang_getCursorKind(cursor); + s << kind; + if (kind >= CXCursor_FirstInvalid && kind <= CXCursor_LastInvalid) + return s; + const CXType type = clang_getCursorType(cursor); + switch (kind) { + case CXCursor_CXXAccessSpecifier: + s << ' ' << clang_getCXXAccessSpecifier(cursor); + break; + case CXCursor_CXXBaseSpecifier: + s << ", inherits=\"" << clang::getCursorSpelling(clang_getTypeDeclaration(type)) << '"'; + break; + case CXCursor_CXXMethod: + case CXCursor_FunctionDecl: + case CXCursor_ConversionFunction: + s << ", result type=\"" << clang_getCursorResultType(cursor) << '"'; + break; + case CXCursor_TypedefDecl: + s << ", underlyingType=\"" << clang_getTypedefDeclUnderlyingType(cursor) << '"'; + break; + default: + break; + } + + if (type.kind != CXType_Invalid) + s << ", type=\"" << type << '"'; + if (clang_Cursor_hasAttrs(cursor)) + s << ", [attrs]"; + + const QString cursorSpelling = clang::getCursorSpelling(cursor); + if (!cursorSpelling.isEmpty()) + s << ", spelling=\"" << cursorSpelling << '"'; + CXString cursorDisplay = clang_getCursorDisplayName(cursor); + if (const char *dpy = clang_getCString(cursorDisplay)) { + const QString display = QString::fromUtf8(dpy); + if (display != cursorSpelling) + s << ", display=\"" << dpy << '"'; + } + clang_disposeString(cursorDisplay); + return s; +} + +QDebug operator<<(QDebug s, const CXSourceLocation &location) +{ + QDebugStateSaver saver(s); + s.nospace(); + CXFile file; // void * + unsigned line; + unsigned column; + unsigned offset; + clang_getExpansionLocation(location, &file, &line, &column, &offset); + const CXString cxFileName = clang_getFileName(file); + // Has been observed to be 0 for invalid locations + if (const char *cFileName = clang_getCString(cxFileName)) + s << baseName(cFileName) << ':'; + s << line << ':' << column; + clang_disposeString(cxFileName); + return s; +} + +#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/parser/compiler_utils.h b/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.h index 849baf5aa..323efdd2a 100644 --- a/sources/shiboken2/ApiExtractor/parser/compiler_utils.h +++ b/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.h @@ -1,7 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of PySide2. @@ -27,24 +26,23 @@ ** ****************************************************************************/ +#ifndef CLANGDEBUGUTILS_H +#define CLANGDEBUGUTILS_H -#ifndef COMPILER_UTILS_H -#define COMPILER_UTILS_H +#include <QtCore/QtGlobal> -#include <utility> +#include <clang-c/Index.h> -#include "codemodel.h" +QT_FORWARD_DECLARE_CLASS(QDebug) +QT_FORWARD_DECLARE_CLASS(QString) -struct TypeSpecifierAST; -struct DeclaratorAST; -class TokenStream; -class Binder; +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug s, const CXString &cs); +QDebug operator<<(QDebug s, CXCursorKind cursorKind); +QDebug operator<<(QDebug s, CX_CXXAccessSpecifier ac); +QDebug operator<<(QDebug s, const CXType &t); +QDebug operator<<(QDebug s, const CXCursor &cursor); +QDebug operator<<(QDebug s, const CXSourceLocation &location); +#endif // !QT_NO_DEBUG_STREAM -namespace CompilerUtils -{ - -TypeInfo typeDescription(TypeSpecifierAST *type_specifier, DeclaratorAST *declarator, Binder *binder); - -} // namespace CompilerUtils - -#endif // COMPILER_UTILS_H +#endif // CLANGDEBUGUTILS_H diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp new file mode 100644 index 000000000..eb3be115c --- /dev/null +++ b/sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "clangparser.h" +#include "clangutils.h" +#include "clangdebugutils.h" +#include "compilersupport.h" + +#include <QtCore/QByteArrayList> +#include <QtCore/QDebug> +#include <QtCore/QDir> +#include <QtCore/QFile> +#include <QtCore/QScopedArrayPointer> +#include <QtCore/QString> + +namespace clang { + +SourceFileCache::Snippet SourceFileCache::getCodeSnippet(const CXCursor &cursor) +{ + Snippet result(nullptr, nullptr); + const SourceRange range = getCursorRange(cursor); + if (range.first.file.isEmpty() || range.second.file != range.first.file) + return result; + FileBufferCache::Iterator it = m_fileBufferCache.find(range.first.file); + if (it == m_fileBufferCache.end()) { + QFile file(range.first.file); + if (!file.open(QIODevice::ReadOnly)) { + qWarning().noquote().nospace() + << "Can't open " << QDir::toNativeSeparators(range.first.file) + << ": " << file.errorString(); + return result; + } + it = m_fileBufferCache.insert(range.first.file, file.readAll()); + } + + const unsigned pos = range.first.offset; + const unsigned end = range.second.offset; + const QByteArray &contents = it.value(); + if (end >= unsigned(contents.size())) { + qWarning().noquote().nospace() << "Range end " << end << " is above size of " + << range.first.file << " (" << contents.size() << ')'; + return result; + } + result.first = contents.constData() + pos; + result.second = contents.constData() + end; + return result; +} + +BaseVisitor::BaseVisitor() = default; +BaseVisitor::~BaseVisitor() = default; + +bool BaseVisitor::visitLocation(const CXSourceLocation &location) const +{ + return clang_Location_isFromMainFile(location) != 0; +} + +BaseVisitor::StartTokenResult BaseVisitor::cbHandleStartToken(const CXCursor &cursor) +{ + switch (cursor.kind) { + default: + break; + } + + return startToken(cursor); +} + +bool BaseVisitor::cbHandleEndToken(const CXCursor &cursor, StartTokenResult startResult) +{ + const bool result = startResult != Recurse || endToken(cursor); + switch (cursor.kind) { + default: + break; + } + + return result; +} + +BaseVisitor::CodeSnippet BaseVisitor::getCodeSnippet(const CXCursor &cursor) +{ + CodeSnippet result = m_fileCache.getCodeSnippet(cursor); + if (result.first == nullptr) + appendDiagnostic(Diagnostic(QStringLiteral("Unable to retrieve code snippet."), cursor, CXDiagnostic_Error)); + return result; +} + +QString BaseVisitor::getCodeSnippetString(const CXCursor &cursor) +{ + CodeSnippet result = m_fileCache.getCodeSnippet(cursor); + return result.first != nullptr + ? QString::fromUtf8(result.first, int(result.second - result.first)) + : QString(); +} + +static CXChildVisitResult + visitorCallback(CXCursor cursor, CXCursor /* parent */, CXClientData clientData) +{ + BaseVisitor *bv = reinterpret_cast<BaseVisitor *>(clientData); + + const CXSourceLocation location = clang_getCursorLocation(cursor); + if (!bv->visitLocation(location)) + return CXChildVisit_Continue; + + const BaseVisitor::StartTokenResult startResult = bv->cbHandleStartToken(cursor); + switch (startResult) { + case clang::BaseVisitor::Error: + return CXChildVisit_Break; + case clang::BaseVisitor::Skip: + break; + case clang::BaseVisitor::Recurse: + clang_visitChildren(cursor, visitorCallback, clientData); + break; + } + + if (!bv->cbHandleEndToken(cursor, startResult)) + return CXChildVisit_Break; + + return CXChildVisit_Continue; +} + +BaseVisitor::Diagnostics BaseVisitor::diagnostics() const +{ + return m_diagnostics; +} + +void BaseVisitor::setDiagnostics(const Diagnostics &d) +{ + m_diagnostics = d; +} + +void BaseVisitor::appendDiagnostic(const Diagnostic &d) +{ + m_diagnostics.append(d); +} + +static inline const char **byteArrayListToFlatArgV(const QByteArrayList &bl) +{ + const char **result = new const char *[bl.size() + 1]; + result[bl.size()] = nullptr; + std::transform(bl.cbegin(), bl.cend(), result, + [] (const QByteArray &a) { return a.constData(); }); + return result; +} + +static QByteArray msgCreateTranslationUnit(const QByteArrayList clangArgs, unsigned flags) +{ + QByteArray result = "clang_parseTranslationUnit2(0x"; + result += QByteArray::number(flags, 16); + const int count = clangArgs.size(); + result += ", cmd[" + QByteArray::number(count) + "]="; + for (int i = 0; i < count; ++i) { + const QByteArray &arg = clangArgs.at(i); + if (i) + result += ' '; + const bool quote = arg.contains(' ') || arg.contains('('); + if (quote) + result += '"'; + result += arg; + if (quote) + result += '"'; + } + result += ')'; + return result; +} + +static CXTranslationUnit createTranslationUnit(CXIndex index, + const QByteArrayList &args, + unsigned flags = 0) +{ + // courtesy qdoc + const unsigned defaultFlags = CXTranslationUnit_SkipFunctionBodies + | CXTranslationUnit_Incomplete; + + static const QByteArrayList defaultArgs = { + "-std=c++14", // ! otherwise, t.h is parsed as "C" + "-fPIC", + "-fno-exceptions", // Workaround for clang bug http://reviews.llvm.org/D17988 +#ifdef Q_OS_MACOS + "-Wno-expansion-to-defined", // Workaround for warnings in Darwin stdlib, see + // https://github.com/darlinghq/darling/issues/204 +#endif + "-Wno-constant-logical-operand" + }; + + const QByteArrayList clangArgs = emulatedCompilerOptions() + defaultArgs + args; + QScopedArrayPointer<const char *> argv(byteArrayListToFlatArgV(clangArgs)); + qDebug().noquote().nospace() << msgCreateTranslationUnit(clangArgs, flags); + + CXTranslationUnit tu; + CXErrorCode err = clang_parseTranslationUnit2(index, nullptr, argv.data(), + clangArgs.size(), nullptr, 0, + defaultFlags | flags, &tu); + if (err || !tu) { + qWarning().noquote().nospace() << "Could not parse " + << clangArgs.constLast().constData() << ", error code: " << err; + return nullptr; + } + return tu; +} + +/* clangFlags are flags to clang_parseTranslationUnit2() such as + * CXTranslationUnit_KeepGoing (from CINDEX_VERSION_MAJOR/CINDEX_VERSION_MINOR 0.35) + */ + +bool parse(const QByteArrayList &clangArgs, unsigned clangFlags, BaseVisitor &bv) +{ + CXIndex index = clang_createIndex(0 /* excludeDeclarationsFromPCH */, + 1 /* displayDiagnostics */); + if (!index) { + qWarning() << "clang_createIndex() failed!"; + return false; + } + + CXTranslationUnit translationUnit = createTranslationUnit(index, clangArgs, clangFlags); + if (!translationUnit) + return false; + + CXCursor rootCursor = clang_getTranslationUnitCursor(translationUnit); + + clang_visitChildren(rootCursor, visitorCallback, reinterpret_cast<CXClientData>(&bv)); + + QVector<Diagnostic> diagnostics = getDiagnostics(translationUnit); + diagnostics.append(bv.diagnostics()); + bv.setDiagnostics(diagnostics); + + const bool ok = maxSeverity(diagnostics) < CXDiagnostic_Error; + if (!ok) { + QDebug debug = qWarning(); + debug.noquote(); + debug.nospace(); + debug << "Errors in " + << QDir::toNativeSeparators(QFile::decodeName(clangArgs.constLast())) << ":\n"; + for (const Diagnostic &diagnostic : diagnostics) + debug << diagnostic << '\n'; + } + + clang_disposeTranslationUnit(translationUnit); + clang_disposeIndex(index); + return ok; +} + +} // namespace clang diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangparser.h b/sources/shiboken2/ApiExtractor/clangparser/clangparser.h new file mode 100644 index 000000000..ef1424f17 --- /dev/null +++ b/sources/shiboken2/ApiExtractor/clangparser/clangparser.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CLANGPARSER_H +#define CLANGPARSER_H + +#include <clang-c/Index.h> + +#include <QtCore/QByteArrayList> +#include <QtCore/QHash> +#include <QtCore/QPair> +#include <QtCore/QString> +#include <QtCore/QVector> + +namespace clang { + +struct Diagnostic; + +class SourceFileCache { +public: + typedef QPair<const char *, const char *> Snippet; + + Snippet getCodeSnippet(const CXCursor &cursor); + +private: + typedef QHash<QString, QByteArray> FileBufferCache; + + FileBufferCache m_fileBufferCache; +}; + +class BaseVisitor { + Q_DISABLE_COPY(BaseVisitor) +public: + typedef QVector<Diagnostic> Diagnostics; + typedef SourceFileCache::Snippet CodeSnippet; + + enum StartTokenResult { Error, Skip, Recurse }; + + BaseVisitor(); + virtual ~BaseVisitor(); + + // Whether location should be visited. + // defaults to clang_Location_isFromMainFile() + virtual bool visitLocation(const CXSourceLocation &location) const; + + virtual StartTokenResult startToken(const CXCursor &cursor) = 0; + virtual bool endToken(const CXCursor &cursor) = 0; + + StartTokenResult cbHandleStartToken(const CXCursor &cursor); + bool cbHandleEndToken(const CXCursor &cursor, StartTokenResult startResult); + + CodeSnippet getCodeSnippet(const CXCursor &cursor); + QString getCodeSnippetString(const CXCursor &cursor); + + Diagnostics diagnostics() const; + void setDiagnostics(const Diagnostics &d); + void appendDiagnostic(const Diagnostic &d); + +private: + SourceFileCache m_fileCache; + Diagnostics m_diagnostics; +}; + +bool parse(const QByteArrayList &clangArgs, unsigned clangFlags, BaseVisitor &ctx); + +} // namespace clang + +#endif // !CLANGPARSER_H diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp new file mode 100644 index 000000000..fdc8d3312 --- /dev/null +++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp @@ -0,0 +1,227 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "clangutils.h" + +#include <QtCore/QDebug> +#include <QtCore/QDir> +#include <QtCore/QHashFunctions> +#include <QtCore/QProcess> + +bool operator==(const CXCursor &c1, const CXCursor &c2) +{ + return c1.kind == c2.kind + && c1.xdata == c2.xdata + && std::equal(c1.data, c1.data + sizeof(c1.data) / sizeof(c1.data[0]), c2.data); +} + +uint qHash(const CXCursor &c, uint seed) +{ + return qHash(c.kind) ^ qHash(c.xdata) ^ qHash(c.data[0]) + ^ qHash(c.data[1]) ^ qHash(c.data[2]) ^ seed; +} + +namespace clang { + +SourceLocation getExpansionLocation(const CXSourceLocation &location) +{ + SourceLocation result; + CXFile file; // void * + clang_getExpansionLocation(location, &file, &result.line, &result.column, &result.offset); + const CXString cxFileName = clang_getFileName(file); + // Has been observed to be 0 for invalid locations + if (const char *cFileName = clang_getCString(cxFileName)) + result.file = QString::fromUtf8(cFileName); + clang_disposeString(cxFileName); + return result; +} + +SourceLocation getCursorLocation(const CXCursor &cursor) +{ + const CXSourceRange extent = clang_getCursorExtent(cursor); + return getExpansionLocation(clang_getRangeStart(extent)); +} + +CXString getFileNameFromLocation(const CXSourceLocation &location) +{ + CXFile file; + unsigned line; + unsigned column; + unsigned offset; + clang_getExpansionLocation(location, &file, &line, &column, &offset); + return clang_getFileName(file); +} + +SourceRange getCursorRange(const CXCursor &cursor) +{ + const CXSourceRange extent = clang_getCursorExtent(cursor); + return qMakePair(getExpansionLocation(clang_getRangeStart(extent)), + getExpansionLocation(clang_getRangeEnd(extent))); +} + +QString getCursorKindName(CXCursorKind cursorKind) +{ + CXString kindName = clang_getCursorKindSpelling(cursorKind); + const QString result = QString::fromUtf8(clang_getCString(kindName)); + clang_disposeString(kindName); + return result; +} + +QString getCursorSpelling(const CXCursor &cursor) +{ + CXString cursorSpelling = clang_getCursorSpelling(cursor); + const QString result = QString::fromUtf8(clang_getCString(cursorSpelling)); + clang_disposeString(cursorSpelling); + return result; +} + +QString getCursorDisplayName(const CXCursor &cursor) +{ + CXString displayName = clang_getCursorDisplayName(cursor); + const QString result = QString::fromUtf8(clang_getCString(displayName)); + clang_disposeString(displayName); + return result; +} + +QString getTypeName(const CXType &type) +{ + CXString typeSpelling = clang_getTypeSpelling(type); + const QString result = QString::fromUtf8(clang_getCString(typeSpelling)); + clang_disposeString(typeSpelling); + return result; +} + +Diagnostic::Diagnostic(const QString &m, const CXCursor &c, CXDiagnosticSeverity s) + : message(m), location(getCursorLocation(c)), source(Other), severity(s) +{ +} + +Diagnostic Diagnostic::fromCXDiagnostic(CXDiagnostic cd) +{ + Diagnostic result; + result.source = Clang; + CXString spelling = clang_getDiagnosticSpelling(cd); + result.message = QString::fromUtf8(clang_getCString(spelling)); + clang_disposeString(spelling); + result.severity = clang_getDiagnosticSeverity(cd); + result.location = getExpansionLocation(clang_getDiagnosticLocation(cd)); + + CXDiagnosticSet childDiagnostics = clang_getChildDiagnostics(cd); + if (const unsigned childCount = clang_getNumDiagnosticsInSet(childDiagnostics)) { + result.childMessages.reserve(int(childCount)); + const unsigned format = clang_defaultDiagnosticDisplayOptions(); + for (unsigned i = 0; i < childCount; ++i) { + CXDiagnostic childDiagnostic = clang_getDiagnosticInSet(childDiagnostics, i); + CXString cdm = clang_formatDiagnostic(childDiagnostic, format); + result.childMessages.append(QString::fromUtf8(clang_getCString(cdm))); + clang_disposeString(cdm); + clang_disposeDiagnostic(childDiagnostic); + } + } + + return result; +} + +QVector<Diagnostic> getDiagnostics(CXTranslationUnit tu) +{ + QVector<Diagnostic> result; + const unsigned count = clang_getNumDiagnostics(tu); + result.reserve(int(count)); + for (unsigned i = 0; i < count; ++i) { + const CXDiagnostic d = clang_getDiagnostic(tu, i); + result.append(Diagnostic::fromCXDiagnostic(d)); + clang_disposeDiagnostic(d); + } + return result; +} + +CXDiagnosticSeverity maxSeverity(const QVector<Diagnostic> &ds) +{ + CXDiagnosticSeverity result = CXDiagnostic_Ignored; + for (const Diagnostic d : ds) { + if (d.severity > result) + result = d.severity; + } + return result; +} + +#ifndef QT_NO_DEBUG_STREAM + +QDebug operator<<(QDebug s, const SourceLocation &l) +{ + QDebugStateSaver saver(s); + s.nospace(); + s.noquote(); + s << QDir::toNativeSeparators(l.file) << ':' << l.line; + if (l.column) + s << ':' << l.column; + return s; +} + +// Roughly follow g++ format: +// file.cpp:214:37: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] +QDebug operator<<(QDebug s, const Diagnostic &d) +{ + QDebugStateSaver saver(s); + s.nospace(); + s.noquote(); + s << d.location << ": "; + switch (d.severity) { + case CXDiagnostic_Ignored: + s << "ignored"; + break; + case CXDiagnostic_Note: + s << "note"; + break; + case CXDiagnostic_Warning: + s << "warning"; + break; + case CXDiagnostic_Error: + s << "error"; + break; + case CXDiagnostic_Fatal: + s << "fatal"; + break; + } + s << ": " << d.message; + + if (d.source != Diagnostic::Clang) + s << " [other]"; + + if (const int childMessagesCount = d.childMessages.size()) { + s << '\n'; + for (int i = 0; i < childMessagesCount; ++i) + s << " " << d.childMessages.at(i) << '\n'; + } + + return s; +} + +#endif // QT_NO_DEBUG_STREAM + +} // namespace clang diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h new file mode 100644 index 000000000..3437f51eb --- /dev/null +++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CLANGUTILS_H +#define CLANGUTILS_H + +#include <clang-c/Index.h> +#include <QtCore/QPair> +#include <QtCore/QString> +#include <QtCore/QVector> + +QT_FORWARD_DECLARE_CLASS(QDebug) + +bool operator==(const CXCursor &c1, const CXCursor &c2); +uint qHash(const CXCursor &c, uint seed = 0); + +namespace clang { + +QString getCursorKindName(CXCursorKind cursorKind); +QString getCursorSpelling(const CXCursor &cursor); +QString getCursorDisplayName(const CXCursor &cursor); +QString getTypeName(const CXType &type); +inline QString getCursorTypeName(const CXCursor &cursor) + { return getTypeName(clang_getCursorType(cursor)); } +inline QString getCursorResultTypeName(const CXCursor &cursor) + { return getTypeName(clang_getCursorResultType(cursor)); } + +inline bool isCursorValid(const CXCursor &c) +{ + return c.kind < CXCursor_FirstInvalid || c.kind > CXCursor_LastInvalid; +} + +struct SourceLocation +{ + int compare(const SourceLocation &rhs) const; + + QString file; + unsigned line = 0; + unsigned column = 0; + unsigned offset = 0; +}; + +SourceLocation getExpansionLocation(const CXSourceLocation &location); + +typedef QPair<SourceLocation, SourceLocation> SourceRange; + +SourceLocation getCursorLocation(const CXCursor &cursor); +CXString getFileNameFromLocation(const CXSourceLocation &location); +SourceRange getCursorRange(const CXCursor &cursor); + +struct Diagnostic { + enum Source { Clang, Other }; + + Diagnostic() : source(Clang) {} + // Clang + static Diagnostic fromCXDiagnostic(CXDiagnostic cd); + // Other + explicit Diagnostic(const QString &m, const CXCursor &c, CXDiagnosticSeverity s = CXDiagnostic_Warning); + + QString message; + QStringList childMessages; + SourceLocation location; + Source source; + CXDiagnosticSeverity severity; +}; + +QVector<Diagnostic> getDiagnostics(CXTranslationUnit tu); +CXDiagnosticSeverity maxSeverity(const QVector<Diagnostic> &ds); + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug, const SourceLocation &); +QDebug operator<<(QDebug, const Diagnostic &); +#endif // QT_NO_DEBUG_STREAM +} // namespace clang + +#endif // CLANGUTILS_H diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp new file mode 100644 index 000000000..df82f9080 --- /dev/null +++ b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "compilersupport.h" +#include "header_paths.h" + +#include <QtCore/QDebug> +#include <QtCore/QProcess> +#include <QtCore/QStringList> + +#include <string.h> +#include <algorithm> +#include <iterator> + +namespace clang { + +static bool runProcess(const QString &program, const QStringList &arguments, + QByteArray *stdOutIn = nullptr, QByteArray *stdErrIn = nullptr) +{ + QProcess process; + process.start(program, arguments, QProcess::ReadWrite); + if (!process.waitForStarted()) { + qWarning().noquote().nospace() << "Unable to start " + << process.program() << ": " << process.errorString(); + return false; + } + process.closeWriteChannel(); + const bool finished = process.waitForFinished(); + const QByteArray stdErr = process.readAllStandardError(); + if (stdErrIn) + *stdErrIn = stdErr; + if (stdOutIn) + *stdOutIn = process.readAllStandardOutput(); + + if (!finished) { + qWarning().noquote().nospace() << process.program() << " timed out: " << stdErr; + process.kill(); + return false; + } + + if (process.exitStatus() != QProcess::NormalExit) { + qWarning().noquote().nospace() << process.program() << " crashed: " << stdErr; + return false; + } + + if (process.exitCode() != 0) { + qWarning().noquote().nospace() << process.program() << " exited " + << process.exitCode() << ": " << stdErr; + return false; + } + + return true; +} + +#if defined(Q_CC_GNU) + +static QByteArray frameworkPath() { return QByteArrayLiteral(" (framework directory)"); } + +// Determine g++'s internal include paths from the output of +// g++ -E -x c++ - -v </dev/null +// Output looks like: +// #include <...> search starts here: +// /usr/local/include +// /System/Library/Frameworks (framework directory) +// End of search list. +static HeaderPaths gppInternalIncludePaths(const QString &compiler) +{ + HeaderPaths result; + QStringList arguments; + arguments << QStringLiteral("-E") << QStringLiteral("-x") << QStringLiteral("c++") + << QStringLiteral("-") << QStringLiteral("-v"); + QByteArray stdOut; + QByteArray stdErr; + if (!runProcess(compiler, arguments, &stdOut, &stdErr)) + return result; + const QByteArrayList stdErrLines = stdErr.split('\n'); + bool isIncludeDir = false; + for (const QByteArray &line : stdErrLines) { + if (isIncludeDir) { + if (line.startsWith(QByteArrayLiteral("End of search list"))) { + isIncludeDir = false; + } else { + HeaderPath headerPath(line.trimmed()); + if (headerPath.path.endsWith(frameworkPath())) { + headerPath.m_isFramework = true; + headerPath.path.truncate(headerPath.path.size() - frameworkPath().size()); + } + result.append(headerPath); + } + } else if (line.startsWith(QByteArrayLiteral("#include <...> search starts here"))) { + isIncludeDir = true; + } + } + return result; +} +#endif // Q_CC_MSVC + +// For MSVC, we set the MS compatibility version and let Clang figure out its own +// options and include paths. +// For the others, we pass "-nostdinc" since libclang tries to add it's own system +// include paths, which together with the clang compiler paths causes some clash +// which causes std types not being found and construct -I/-F options from the +// include paths of the host compiler. + +static QByteArray noStandardIncludeOption() { return QByteArrayLiteral("-nostdinc"); } + +// Returns clang options needed for emulating the host compiler +QByteArrayList emulatedCompilerOptions() +{ + QByteArrayList result; +#if defined(Q_CC_MSVC) + const HeaderPaths headerPaths; + result.append(QByteArrayLiteral("-fms-compatibility-version=19")); +#elif defined(Q_CC_CLANG) + const HeaderPaths headerPaths = gppInternalIncludePaths(QStringLiteral("clang++")); + result.append(noStandardIncludeOption()); +#elif defined(Q_CC_GNU) + const HeaderPaths headerPaths = gppInternalIncludePaths(QStringLiteral("g++")); + result.append(noStandardIncludeOption()); +#else + const HeaderPaths headerPaths; +#endif + std::transform(headerPaths.cbegin(), headerPaths.cend(), + std::back_inserter(result), [](const HeaderPath &p) { + return HeaderPath::includeOption(p, true); + }); + return result; +} + +} // namespace clang diff --git a/sources/shiboken2/ApiExtractor/parser/list.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.h index 2d2a78700..f556da551 100644 --- a/sources/shiboken2/ApiExtractor/parser/list.cpp +++ b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.h @@ -1,7 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of PySide2. @@ -27,7 +26,15 @@ ** ****************************************************************************/ +#ifndef COMPILERSUPPORT_H +#define COMPILERSUPPORT_H -#include "list.h" +#include <QtCore/QByteArrayList> -// kate: space-indent on; indent-width 2; replace-tabs on; +namespace clang { + +QByteArrayList emulatedCompilerOptions(); + +} // namespace clang + +#endif // COMPILERSUPPORT_H diff --git a/sources/shiboken2/ApiExtractor/docparser.cpp b/sources/shiboken2/ApiExtractor/docparser.cpp index 4ec1da299..bae438f18 100644 --- a/sources/shiboken2/ApiExtractor/docparser.cpp +++ b/sources/shiboken2/ApiExtractor/docparser.cpp @@ -104,7 +104,7 @@ QString DocParser::applyDocModifications(const DocModificationList& mods, const return xml; bool hasXPathBasedModification = false; - foreach (DocModification mod, mods) { + for (const DocModification &mod : mods) { if (mod.mode() == TypeSystem::DocModificationXPathReplace) { hasXPathBasedModification = true; break; @@ -126,7 +126,7 @@ QString DocParser::applyDocModifications(const DocModificationList& mods, const "</xsl:copy>\n" "</xsl:template>\n" ); - foreach (DocModification mod, mods) { + for (const DocModification &mod : mods) { if (mod.mode() == TypeSystem::DocModificationXPathReplace) { QString xpath = mod.xpath(); xpath.replace(QLatin1Char('"'), QLatin1String(""")); diff --git a/sources/shiboken2/ApiExtractor/doxygenparser.cpp b/sources/shiboken2/ApiExtractor/doxygenparser.cpp index f7d868f8d..6b90fe6fc 100644 --- a/sources/shiboken2/ApiExtractor/doxygenparser.cpp +++ b/sources/shiboken2/ApiExtractor/doxygenparser.cpp @@ -105,8 +105,8 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass) metaClass->setDocumentation(classDoc); //Functions Documentation - AbstractMetaFunctionList funcs = metaClass->functionsInTargetLang(); - foreach (AbstractMetaFunction *func, funcs) { + const AbstractMetaFunctionList &funcs = metaClass->functionsInTargetLang(); + for (AbstractMetaFunction *func : funcs) { if (!func || func->isPrivate()) continue; @@ -128,8 +128,8 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass) query += QLatin1String("/../argsstring[text()=\"") + args + QLatin1String("\"]"); } else { int i = 1; - foreach (AbstractMetaArgument* arg, func->arguments()) { - QString type; + const AbstractMetaArgumentList &arguments = func->arguments(); + for (AbstractMetaArgument *arg : arguments) { if (!arg->type()->isPrimitive()) { query += QLatin1String("/../param[") + QString::number(i) + QLatin1String("]/type/ref[text()=\"") @@ -155,8 +155,8 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass) } //Fields - AbstractMetaFieldList fields = metaClass->fields(); - foreach (AbstractMetaField *field, fields) { + const AbstractMetaFieldList &fields = metaClass->fields(); + for (AbstractMetaField *field : fields) { if (field->isPrivate()) return; @@ -167,8 +167,8 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass) } //Enums - AbstractMetaEnumList enums = metaClass->enums(); - foreach (AbstractMetaEnum *meta_enum, enums) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (AbstractMetaEnum *meta_enum : enums) { QString query = QLatin1String("/doxygen/compounddef/sectiondef/memberdef[@kind=\"enum\"]/name[text()=\"") + meta_enum->name() + QLatin1String("\"]/.."); QString doc = getDocumentation(xquery, query, DocModificationList()); diff --git a/sources/shiboken2/ApiExtractor/doxygenparser.h b/sources/shiboken2/ApiExtractor/doxygenparser.h index 7314cfe3b..3f9ca5142 100644 --- a/sources/shiboken2/ApiExtractor/doxygenparser.h +++ b/sources/shiboken2/ApiExtractor/doxygenparser.h @@ -35,9 +35,9 @@ class DoxygenParser : public DocParser { public: DoxygenParser() {} - virtual void fillDocumentation(AbstractMetaClass *metaClass); - virtual Documentation retrieveModuleDocumentation(); - virtual Documentation retrieveModuleDocumentation(const QString& name); + void fillDocumentation(AbstractMetaClass *metaClass) override; + Documentation retrieveModuleDocumentation() override; + Documentation retrieveModuleDocumentation(const QString& name) override; }; #endif // DOXYGENPARSER_H diff --git a/sources/shiboken2/ApiExtractor/generator.qrc b/sources/shiboken2/ApiExtractor/generator.qrc deleted file mode 100644 index 2d82b37cb..000000000 --- a/sources/shiboken2/ApiExtractor/generator.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource prefix="/trolltech/generator/"> -<file alias="pp-qt-configuration">parser/rpp/pp-qt-configuration</file> -</qresource> -</RCC> diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/preprocessor.h b/sources/shiboken2/ApiExtractor/header_paths.h index 7d00a5d09..3bc26efe0 100644 --- a/sources/shiboken2/ApiExtractor/parser/rpp/preprocessor.h +++ b/sources/shiboken2/ApiExtractor/header_paths.h @@ -1,7 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of PySide2. @@ -27,44 +26,37 @@ ** ****************************************************************************/ -#ifndef PREPROCESSOR_H -#define PREPROCESSOR_H +#ifndef HEADER_PATHS_H +#define HEADER_PATHS_H -#include <QtCore/qglobal.h> -#include <QtCore/qstring.h> -#include <QtCore/qstringlist.h> +#include <QByteArray> +#include <QList> +#include <QString> -class PreprocessorPrivate; - -class Preprocessor -{ +class HeaderPath { public: - Preprocessor(); - ~Preprocessor(); - - void processFile(const QString &fileName); - void processString(const QByteArray &str); - - void addIncludePaths(const QStringList &includePaths); - - QByteArray result() const; - - QStringList macroNames() const; - - struct MacroItem { - QString name; - QStringList parameters; - QString definition; - bool isFunctionLike; -#ifdef PP_WITH_MACRO_POSITION - QString fileName; -#endif - }; - QList<MacroItem> macros() const; - -private: - Q_DISABLE_COPY(Preprocessor) - PreprocessorPrivate *d; + explicit HeaderPath(const QByteArray &p = QByteArray()) : path(p), m_isFramework(false) {} + explicit HeaderPath(const QString &s = QString(), bool isFramework = false) : + path(s.toLatin1()), m_isFramework(isFramework) {} + + QByteArray path; + bool m_isFramework; // macOS framework path + + static QByteArray includeOption(const HeaderPath &p, bool systemInclude = false) + { + QByteArray option; + + if (p.m_isFramework) + option = QByteArrayLiteral("-F"); + else if (systemInclude) + option = QByteArrayLiteral("-isystem"); + else + option = QByteArrayLiteral("-I"); + + return option + p.path; + } }; -#endif +typedef QList<HeaderPath> HeaderPaths; + +#endif // HEADER_PATHS_H diff --git a/sources/shiboken2/ApiExtractor/include.h b/sources/shiboken2/ApiExtractor/include.h index e4ff5b309..dc4965e1a 100644 --- a/sources/shiboken2/ApiExtractor/include.h +++ b/sources/shiboken2/ApiExtractor/include.h @@ -30,7 +30,7 @@ #define INCLUDE_H #include <QString> -#include <QList> +#include <QVector> QT_BEGIN_NAMESPACE class QTextStream; @@ -87,6 +87,6 @@ QTextStream& operator<<(QTextStream& out, const Include& include); QDebug operator<<(QDebug d, const Include &i); #endif -typedef QList<Include> IncludeList; +typedef QVector<Include> IncludeList; #endif diff --git a/sources/shiboken2/ApiExtractor/parser/ast.cpp b/sources/shiboken2/ApiExtractor/parser/ast.cpp deleted file mode 100644 index a744704fe..000000000 --- a/sources/shiboken2/ApiExtractor/parser/ast.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "ast.h" -#include "lexer.h" - -QString AST::toString(TokenStream *stream) const -{ - const Token &tk = stream->token((int) start_token); - const Token &end_tk = stream->token((int) end_token); - return QString::fromLatin1(tk.text + tk.position, end_tk.position - tk.position); -} diff --git a/sources/shiboken2/ApiExtractor/parser/ast.h b/sources/shiboken2/ApiExtractor/parser/ast.h deleted file mode 100644 index 7640b7c38..000000000 --- a/sources/shiboken2/ApiExtractor/parser/ast.h +++ /dev/null @@ -1,884 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef AST_H -#define AST_H - -#include "smallobject.h" -#include "list.h" - -#include <QString> - -#define DECLARE_AST_NODE(k) \ - enum { __node_kind = Kind_##k }; - -class TokenStream; - -struct AccessSpecifierAST; -struct AsmDefinitionAST; -struct BaseClauseAST; -struct BaseSpecifierAST; -struct BinaryExpressionAST; -struct CastExpressionAST; -struct ClassMemberAccessAST; -struct ClassSpecifierAST; -struct CompoundStatementAST; -struct ConditionAST; -struct ConditionalExpressionAST; -struct CppCastExpressionAST; -struct CtorInitializerAST; -struct DeclarationAST; -struct DeclarationStatementAST; -struct DeclaratorAST; -struct DeleteExpressionAST; -struct DoStatementAST; -struct ElaboratedTypeSpecifierAST; -struct EnumSpecifierAST; -struct EnumeratorAST; -struct ExceptionSpecificationAST; -struct ExpressionAST; -struct ExpressionOrDeclarationStatementAST; -struct ExpressionStatementAST; -struct ForStatementAST; -struct FunctionCallAST; -struct FunctionDefinitionAST; -struct IfStatementAST; -struct IncrDecrExpressionAST; -struct InitDeclaratorAST; -struct InitializerAST; -struct InitializerClauseAST; -struct LabeledStatementAST; -struct LinkageBodyAST; -struct LinkageSpecificationAST; -struct MemInitializerAST; -struct NameAST; -struct NamespaceAST; -struct NamespaceAliasDefinitionAST; -struct NewDeclaratorAST; -struct NewExpressionAST; -struct NewInitializerAST; -struct NewTypeIdAST; -struct OperatorAST; -struct OperatorFunctionIdAST; -struct ParameterDeclarationAST; -struct ParameterDeclarationClauseAST; -struct PostfixExpressionAST; -struct PrimaryExpressionAST; -struct PtrOperatorAST; -struct PtrToMemberAST; -struct ReturnStatementAST; -struct SimpleDeclarationAST; -struct SimpleTypeSpecifierAST; -struct SizeofExpressionAST; -struct StatementAST; -struct StringLiteralAST; -struct SubscriptExpressionAST; -struct SwitchStatementAST; -struct TemplateArgumentAST; -struct TemplateDeclarationAST; -struct TemplateParameterAST; -struct ThrowExpressionAST; -struct TranslationUnitAST; -struct TryBlockStatementAST; -struct TypeIdAST; -struct TypeIdentificationAST; -struct TypeParameterAST; -struct TypeSpecifierAST; -struct TypedefAST; -struct UnaryExpressionAST; -struct UnqualifiedNameAST; -struct UsingAST; -struct UsingDirectiveAST; -struct WhileStatementAST; -struct WinDeclSpecAST; -struct QPropertyAST; -struct QEnumsAST; - -struct AST -{ - enum NODE_KIND { - Kind_UNKNOWN = 0, - - Kind_AccessSpecifier, - Kind_AsmDefinition, - Kind_BaseClause, - Kind_BaseSpecifier, - Kind_BinaryExpression, - Kind_CastExpression, - Kind_ClassMemberAccess, - Kind_ClassSpecifier, - Kind_CompoundStatement, - Kind_Condition, - Kind_ConditionalExpression, - Kind_CppCastExpression, - Kind_CtorInitializer, - Kind_DeclarationStatement, - Kind_Declarator, - Kind_DeleteExpression, - Kind_DoStatement, - Kind_ElaboratedTypeSpecifier, - Kind_EnumSpecifier, - Kind_Enumerator, - Kind_ExceptionSpecification, - Kind_ExpressionOrDeclarationStatement, - Kind_ExpressionStatement, - Kind_ForStatement, - Kind_FunctionCall, - Kind_FunctionDefinition, - Kind_IfStatement, - Kind_IncrDecrExpression, - Kind_InitDeclarator, - Kind_Initializer, - Kind_InitializerClause, - Kind_LabeledStatement, - Kind_LinkageBody, - Kind_LinkageSpecification, - Kind_MemInitializer, - Kind_Name, - Kind_Namespace, - Kind_NamespaceAliasDefinition, - Kind_NewDeclarator, - Kind_NewExpression, - Kind_NewInitializer, - Kind_NewTypeId, - Kind_Operator, - Kind_OperatorFunctionId, - Kind_ParameterDeclaration, - Kind_ParameterDeclarationClause, - Kind_PostfixExpression, - Kind_PrimaryExpression, - Kind_PtrOperator, - Kind_PtrToMember, - Kind_ReturnStatement, - Kind_SimpleDeclaration, - Kind_SimpleTypeSpecifier, - Kind_SizeofExpression, - Kind_StringLiteral, - Kind_SubscriptExpression, - Kind_SwitchStatement, - Kind_TemplateArgument, - Kind_TemplateDeclaration, - Kind_TemplateParameter, - Kind_ThrowExpression, - Kind_TranslationUnit, - Kind_TryBlockStatement, - Kind_TypeId, - Kind_TypeIdentification, - Kind_TypeParameter, - Kind_Typedef, - Kind_UnaryExpression, - Kind_UnqualifiedName, - Kind_Using, - Kind_UsingDirective, - Kind_WhileStatement, - Kind_WinDeclSpec, - Kind_QPropertyAST, - Kind_ForwardDeclarationSpecifier, - Kind_QEnumsAST, - - NODE_KIND_COUNT - }; - - QString toString(TokenStream *stream) const; - - int kind; - - std::size_t start_token; - std::size_t end_token; -}; - -struct TypeSpecifierAST: public AST -{ - const ListNode<std::size_t> *cv; -}; - -struct StatementAST: public AST -{ -}; - -struct ExpressionAST: public AST -{ -}; - -struct DeclarationAST: public AST -{ -}; - -struct AccessSpecifierAST: public DeclarationAST -{ - DECLARE_AST_NODE(AccessSpecifier) - - const ListNode<std::size_t> *specs; -}; - -struct AsmDefinitionAST: public DeclarationAST -{ - DECLARE_AST_NODE(AsmDefinition) - - const ListNode<std::size_t> *cv; -}; - -struct BaseClauseAST: public AST -{ // ### kill me - DECLARE_AST_NODE(BaseClause) - - const ListNode<BaseSpecifierAST*> *base_specifiers; -}; - -struct BaseSpecifierAST: public AST -{ - DECLARE_AST_NODE(BaseSpecifier) - - std::size_t virt; - std::size_t access_specifier; - NameAST *name; -}; - -struct BinaryExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(BinaryExpression) - - std::size_t op; - ExpressionAST *left_expression; - ExpressionAST *right_expression; -}; - -struct CastExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(CastExpression) - - TypeIdAST *type_id; - ExpressionAST *expression; -}; - -struct ClassMemberAccessAST: public ExpressionAST -{ - DECLARE_AST_NODE(ClassMemberAccess) - - std::size_t op; - NameAST *name; -}; - -struct ClassSpecifierAST: public TypeSpecifierAST -{ - DECLARE_AST_NODE(ClassSpecifier) - - WinDeclSpecAST *win_decl_specifiers; - std::size_t class_key; - NameAST *name; - BaseClauseAST *base_clause; - const ListNode<DeclarationAST*> *member_specs; -}; - -struct ForwardDeclarationSpecifierAST: public TypeSpecifierAST -{ - DECLARE_AST_NODE(ForwardDeclarationSpecifier) - - std::size_t class_key; - NameAST *name; - BaseClauseAST *base_clause; -}; - -struct CompoundStatementAST: public StatementAST -{ - DECLARE_AST_NODE(CompoundStatement) - - const ListNode<StatementAST*> *statements; -}; - -struct ConditionAST: public AST -{ - DECLARE_AST_NODE(Condition) - - TypeSpecifierAST *type_specifier; - DeclaratorAST *declarator; - ExpressionAST *expression; -}; - -struct ConditionalExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(ConditionalExpression) - - ExpressionAST *condition; - ExpressionAST *left_expression; - ExpressionAST *right_expression; -}; - -struct CppCastExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(CppCastExpression) - - std::size_t op; - TypeIdAST *type_id; - ExpressionAST *expression; - const ListNode<ExpressionAST*> *sub_expressions; -}; - -struct CtorInitializerAST: public AST -{ - DECLARE_AST_NODE(CtorInitializer) - - std::size_t colon; - const ListNode<MemInitializerAST*> *member_initializers; -}; - -struct DeclarationStatementAST: public StatementAST -{ - DECLARE_AST_NODE(DeclarationStatement) - - DeclarationAST *declaration; -}; - -struct DeclaratorAST: public AST -{ - DECLARE_AST_NODE(Declarator) - - const ListNode<PtrOperatorAST*> *ptr_ops; - DeclaratorAST *sub_declarator; - NameAST *id; - ExpressionAST *bit_expression; - const ListNode<ExpressionAST*> *array_dimensions; - ParameterDeclarationClauseAST *parameter_declaration_clause; - const ListNode<std::size_t> *fun_cv; - ExceptionSpecificationAST *exception_spec; -}; - -struct DeleteExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(DeleteExpression) - - std::size_t scope_token; - std::size_t delete_token; - std::size_t lbracket_token; - std::size_t rbracket_token; - ExpressionAST *expression; -}; - -struct DoStatementAST: public StatementAST -{ - DECLARE_AST_NODE(DoStatement) - - StatementAST *statement; - ExpressionAST *expression; -}; - -struct ElaboratedTypeSpecifierAST: public TypeSpecifierAST -{ - DECLARE_AST_NODE(ElaboratedTypeSpecifier) - - std::size_t type; - NameAST *name; -}; - -struct EnumSpecifierAST: public TypeSpecifierAST -{ - DECLARE_AST_NODE(EnumSpecifier) - - NameAST *name; - const ListNode<EnumeratorAST*> *enumerators; -}; - -struct EnumeratorAST: public AST -{ - DECLARE_AST_NODE(Enumerator) - - std::size_t id; - ExpressionAST *expression; -}; - -struct ExceptionSpecificationAST: public AST -{ - DECLARE_AST_NODE(ExceptionSpecification) - - std::size_t ellipsis; - const ListNode<TypeIdAST*> *type_ids; -}; - -struct ExpressionOrDeclarationStatementAST: public StatementAST -{ - DECLARE_AST_NODE(ExpressionOrDeclarationStatement) - - StatementAST *expression; - StatementAST *declaration; -}; - -struct ExpressionStatementAST: public StatementAST -{ - DECLARE_AST_NODE(ExpressionStatement) - - ExpressionAST *expression; -}; - -struct FunctionCallAST: public ExpressionAST -{ - DECLARE_AST_NODE(FunctionCall) - - ExpressionAST *arguments; -}; - -struct FunctionDefinitionAST: public DeclarationAST -{ - DECLARE_AST_NODE(FunctionDefinition) - - const ListNode<std::size_t> *storage_specifiers; - const ListNode<std::size_t> *function_specifiers; - TypeSpecifierAST *type_specifier; - InitDeclaratorAST *init_declarator; - StatementAST *function_body; - WinDeclSpecAST *win_decl_specifiers; -}; - -struct ForStatementAST: public StatementAST -{ - DECLARE_AST_NODE(ForStatement) - - StatementAST *init_statement; - ConditionAST *condition; - ExpressionAST *expression; - StatementAST *statement; -}; - -struct IfStatementAST: public StatementAST -{ - DECLARE_AST_NODE(IfStatement) - - ConditionAST *condition; - StatementAST *statement; - StatementAST *else_statement; -}; - -struct IncrDecrExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(IncrDecrExpression) - - std::size_t op; -}; - -struct InitDeclaratorAST: public AST -{ - DECLARE_AST_NODE(InitDeclarator) - - DeclaratorAST *declarator; - InitializerAST *initializer; -}; - -struct InitializerAST: public AST -{ - DECLARE_AST_NODE(Initializer) - - InitializerClauseAST *initializer_clause; - ExpressionAST *expression; -}; - -struct InitializerClauseAST: public AST -{ - DECLARE_AST_NODE(InitializerClause) - - ExpressionAST *expression; -}; - -struct LabeledStatementAST: public StatementAST -{ - DECLARE_AST_NODE(LabeledStatement) -}; - -struct LinkageBodyAST: public AST -{ - DECLARE_AST_NODE(LinkageBody) - - const ListNode<DeclarationAST*> *declarations; -}; - -struct LinkageSpecificationAST: public DeclarationAST -{ - DECLARE_AST_NODE(LinkageSpecification) - - std::size_t extern_type; - LinkageBodyAST *linkage_body; - DeclarationAST *declaration; -}; - -struct MemInitializerAST: public AST -{ - DECLARE_AST_NODE(MemInitializer) - - NameAST *initializer_id; - ExpressionAST *expression; -}; - -struct NameAST: public AST -{ - DECLARE_AST_NODE(Name) - - bool global; - const ListNode<UnqualifiedNameAST*> *qualified_names; - UnqualifiedNameAST *unqualified_name; -}; - -struct NamespaceAST: public DeclarationAST -{ - DECLARE_AST_NODE(Namespace) - - std::size_t namespace_name; - LinkageBodyAST *linkage_body; -}; - -struct NamespaceAliasDefinitionAST: public DeclarationAST -{ - DECLARE_AST_NODE(NamespaceAliasDefinition) - - std::size_t namespace_name; - NameAST *alias_name; -}; - -struct NewDeclaratorAST: public AST -{ - DECLARE_AST_NODE(NewDeclarator) - - PtrOperatorAST *ptr_op; - NewDeclaratorAST *sub_declarator; - const ListNode<ExpressionAST*> *expressions; -}; - -struct NewExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(NewExpression) - - std::size_t scope_token; - std::size_t new_token; - ExpressionAST *expression; - TypeIdAST *type_id; - NewTypeIdAST *new_type_id; - NewInitializerAST *new_initializer; -}; - -struct NewInitializerAST: public AST -{ - DECLARE_AST_NODE(NewInitializer) - - ExpressionAST *expression; -}; - -struct NewTypeIdAST: public AST -{ - DECLARE_AST_NODE(NewTypeId) - - TypeSpecifierAST *type_specifier; - NewInitializerAST *new_initializer; - NewDeclaratorAST *new_declarator; -}; - -struct OperatorAST: public AST -{ - DECLARE_AST_NODE(Operator) - - std::size_t op; - std::size_t open; - std::size_t close; -}; - -struct OperatorFunctionIdAST: public AST -{ - DECLARE_AST_NODE(OperatorFunctionId) - - OperatorAST *op; - TypeSpecifierAST *type_specifier; - const ListNode<PtrOperatorAST*> *ptr_ops; -}; - -struct ParameterDeclarationAST: public AST -{ - DECLARE_AST_NODE(ParameterDeclaration) - - TypeSpecifierAST *type_specifier; - DeclaratorAST *declarator; - ExpressionAST *expression; -}; - -struct ParameterDeclarationClauseAST: public AST -{ - DECLARE_AST_NODE(ParameterDeclarationClause) - - const ListNode<ParameterDeclarationAST*> *parameter_declarations; - std::size_t ellipsis; -}; - -struct PostfixExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(PostfixExpression) - - TypeSpecifierAST *type_specifier; - ExpressionAST *expression; - const ListNode<ExpressionAST*> *sub_expressions; -}; - -struct PrimaryExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(PrimaryExpression) - - StringLiteralAST *literal; - std::size_t token; - StatementAST *expression_statement; - ExpressionAST *sub_expression; - NameAST *name; -}; - -struct PtrOperatorAST: public AST -{ - DECLARE_AST_NODE(PtrOperator) - - const ListNode<std::size_t> *cv; - std::size_t op; - PtrToMemberAST *mem_ptr; -}; - -struct PtrToMemberAST: public AST -{ - DECLARE_AST_NODE(PtrToMember) -}; - -struct ReturnStatementAST: public StatementAST -{ - DECLARE_AST_NODE(ReturnStatement) - - ExpressionAST *expression; -}; - -struct SimpleDeclarationAST: public DeclarationAST -{ - DECLARE_AST_NODE(SimpleDeclaration) - - const ListNode<std::size_t> *storage_specifiers; - const ListNode<std::size_t> *function_specifiers; - TypeSpecifierAST *type_specifier; - const ListNode<InitDeclaratorAST*> *init_declarators; - WinDeclSpecAST *win_decl_specifiers; -}; - -struct SimpleTypeSpecifierAST: public TypeSpecifierAST -{ - DECLARE_AST_NODE(SimpleTypeSpecifier) - - const ListNode<std::size_t> *integrals; - std::size_t type_of; - TypeIdAST *type_id; - ExpressionAST *expression; - NameAST *name; -}; - -struct SizeofExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(SizeofExpression) - - std::size_t sizeof_token; - TypeIdAST *type_id; - ExpressionAST *expression; -}; - -struct StringLiteralAST: public AST -{ - DECLARE_AST_NODE(StringLiteral) - - const ListNode<std::size_t> *literals; -}; - -struct SubscriptExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(SubscriptExpression) - - ExpressionAST *subscript; -}; - -struct SwitchStatementAST: public StatementAST -{ - DECLARE_AST_NODE(SwitchStatement) - - ConditionAST *condition; - StatementAST *statement; -}; - -struct TemplateArgumentAST: public AST -{ - DECLARE_AST_NODE(TemplateArgument) - - TypeIdAST *type_id; - ExpressionAST *expression; -}; - -struct TemplateDeclarationAST: public DeclarationAST -{ - DECLARE_AST_NODE(TemplateDeclaration) - - std::size_t exported; - const ListNode<TemplateParameterAST*> *template_parameters; - DeclarationAST* declaration; -}; - -struct TemplateParameterAST: public AST -{ - DECLARE_AST_NODE(TemplateParameter) - - TypeParameterAST *type_parameter; - ParameterDeclarationAST *parameter_declaration; -}; - -struct ThrowExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(ThrowExpression) - - std::size_t throw_token; - ExpressionAST *expression; -}; - -struct TranslationUnitAST: public AST -{ - DECLARE_AST_NODE(TranslationUnit) - - const ListNode<DeclarationAST*> *declarations; -}; - -struct TryBlockStatementAST: public StatementAST -{ - DECLARE_AST_NODE(TryBlockStatement) -}; - -struct TypeIdAST: public AST -{ - DECLARE_AST_NODE(TypeId) - - TypeSpecifierAST *type_specifier; - DeclaratorAST *declarator; -}; - -struct TypeIdentificationAST: public ExpressionAST -{ - DECLARE_AST_NODE(TypeIdentification) - - std::size_t typename_token; - NameAST *name; - ExpressionAST *expression; -}; - -struct TypeParameterAST: public AST -{ - DECLARE_AST_NODE(TypeParameter) - - std::size_t type; - NameAST *name; - TypeIdAST *type_id; - const ListNode<TemplateParameterAST*> *template_parameters; - NameAST *template_name; -}; - -struct TypedefAST: public DeclarationAST -{ - DECLARE_AST_NODE(Typedef) - - TypeSpecifierAST *type_specifier; - const ListNode<InitDeclaratorAST*> *init_declarators; -}; - -struct UnaryExpressionAST: public ExpressionAST -{ - DECLARE_AST_NODE(UnaryExpression) - - std::size_t op; - ExpressionAST *expression; -}; - -struct UnqualifiedNameAST: public AST -{ - DECLARE_AST_NODE(UnqualifiedName) - - std::size_t tilde; - std::size_t id; - OperatorFunctionIdAST *operator_id; - const ListNode<TemplateArgumentAST*> *template_arguments; -}; - -struct UsingAST: public DeclarationAST -{ - DECLARE_AST_NODE(Using) - - std::size_t type_name; - NameAST *name; -}; - -struct UsingDirectiveAST: public DeclarationAST -{ - DECLARE_AST_NODE(UsingDirective) - - NameAST *name; -}; - -struct WhileStatementAST: public StatementAST -{ - DECLARE_AST_NODE(WhileStatement) - - ConditionAST *condition; - StatementAST *statement; -}; - -struct WinDeclSpecAST: public AST -{ - DECLARE_AST_NODE(WinDeclSpec) - - std::size_t specifier; - std::size_t modifier; -}; - -struct QPropertyAST : public DeclarationAST -{ - DECLARE_AST_NODE(QPropertyAST) -}; - -struct QEnumsAST : public DeclarationAST -{ - DECLARE_AST_NODE(QEnumsAST) -}; - -template <class _Tp> -_Tp *CreateNode(pool *memory_pool) -{ - _Tp *node = reinterpret_cast<_Tp*>(memory_pool->allocate(sizeof(_Tp), strideof(_Tp))); - node->kind = _Tp::__node_kind; - return node; -} - -template <class _Tp> -_Tp ast_cast(AST *item) -{ - if (item && static_cast<_Tp>(0)->__node_kind == item->kind) - return static_cast<_Tp>(item); - - return 0; -} - -#endif // AST_H diff --git a/sources/shiboken2/ApiExtractor/parser/binder.cpp b/sources/shiboken2/ApiExtractor/parser/binder.cpp deleted file mode 100644 index 709f86c56..000000000 --- a/sources/shiboken2/ApiExtractor/parser/binder.cpp +++ /dev/null @@ -1,866 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "binder.h" -#include "lexer.h" -#include "control.h" -#include "symbol.h" -#include "codemodel_finder.h" -#include "class_compiler.h" -#include "compiler_utils.h" -#include "tokens.h" -#include "dumptree.h" - -#include <iostream> -#include <QDebug> - -Binder::Binder(CodeModel *__model, LocationManager &__location, Control *__control) - : _M_model(__model), - _M_location(__location), - _M_token_stream(&_M_location.token_stream), - _M_control(__control), - _M_current_function_type(CodeModel::Normal), - type_cc(this), - name_cc(this), - decl_cc(this) -{ - _M_qualified_types.insert(QLatin1String("char"), QString()); - _M_qualified_types.insert(QLatin1String("double"), QString()); - _M_qualified_types.insert(QLatin1String("float"), QString()); - _M_qualified_types.insert(QLatin1String("int"), QString()); - _M_qualified_types.insert(QLatin1String("long"), QString()); - _M_qualified_types.insert(QLatin1String("short"), QString()); - _M_qualified_types.insert(QLatin1String("void"), QString()); -} - -Binder::~Binder() -{ -} - -FileModelItem Binder::run(AST *node) -{ - FileModelItem old = _M_current_file; - _M_current_access = CodeModel::Public; - - _M_current_file.reset(new _FileModelItem(model())); - updateItemPosition(_M_current_file, node); - visit(node); - FileModelItem result = _M_current_file; - - _M_current_file = old; // restore - - return result; -} - -ScopeModelItem Binder::currentScope() -{ - if (_M_current_class) - return _M_current_class; - else if (_M_current_namespace) - return _M_current_namespace; - - return _M_current_file; -} - -TemplateParameterList Binder::changeTemplateParameters(TemplateParameterList templateParameters) -{ - TemplateParameterList old = _M_current_template_parameters; - _M_current_template_parameters = templateParameters; - return old; -} - -CodeModel::FunctionType Binder::changeCurrentFunctionType(CodeModel::FunctionType functionType) -{ - CodeModel::FunctionType old = _M_current_function_type; - _M_current_function_type = functionType; - return old; -} - -CodeModel::AccessPolicy Binder::changeCurrentAccess(CodeModel::AccessPolicy accessPolicy) -{ - CodeModel::AccessPolicy old = _M_current_access; - _M_current_access = accessPolicy; - return old; -} - -NamespaceModelItem Binder::changeCurrentNamespace(NamespaceModelItem item) -{ - NamespaceModelItem old = _M_current_namespace; - _M_current_namespace = item; - return old; -} - -ClassModelItem Binder::changeCurrentClass(ClassModelItem item) -{ - ClassModelItem old = _M_current_class; - _M_current_class = item; - return old; -} - -FunctionModelItem Binder::changeCurrentFunction(FunctionModelItem item) -{ - FunctionModelItem old = _M_current_function; - _M_current_function = item; - return old; -} - -int Binder::decode_token(std::size_t index) const -{ - return _M_token_stream->kind(index); -} - -CodeModel::AccessPolicy Binder::decode_access_policy(std::size_t index) const -{ - switch (decode_token(index)) { - case Token_class: - return CodeModel::Private; - - case Token_struct: - case Token_union: - return CodeModel::Public; - - default: - return CodeModel::Public; - } -} - -CodeModel::ClassType Binder::decode_class_type(std::size_t index) const -{ - switch (decode_token(index)) { - case Token_class: - return CodeModel::Class; - case Token_struct: - return CodeModel::Struct; - case Token_union: - return CodeModel::Union; - default: - std::cerr << "** WARNING unrecognized class type" << std::endl; - } - return CodeModel::Class; -} - -const NameSymbol *Binder::decode_symbol(std::size_t index) const -{ - return _M_token_stream->symbol(index); -} - -void Binder::visitAccessSpecifier(AccessSpecifierAST *node) -{ - const ListNode<std::size_t> *it = node->specs; - if (!it) - return; - - it = it->toFront(); - const ListNode<std::size_t> *end = it; - - do { - switch (decode_token(it->element)) { - default: - break; - - case Token_public: - changeCurrentAccess(CodeModel::Public); - changeCurrentFunctionType(CodeModel::Normal); - break; - case Token_protected: - changeCurrentAccess(CodeModel::Protected); - changeCurrentFunctionType(CodeModel::Normal); - break; - case Token_private: - changeCurrentAccess(CodeModel::Private); - changeCurrentFunctionType(CodeModel::Normal); - break; - case Token_signals: - changeCurrentAccess(CodeModel::Protected); - changeCurrentFunctionType(CodeModel::Signal); - break; - case Token_slots: - changeCurrentFunctionType(CodeModel::Slot); - break; - } - it = it->next; - } while (it != end); -} - -void Binder::visitSimpleDeclaration(SimpleDeclarationAST *node) -{ - visit(node->type_specifier); - - if (const ListNode<InitDeclaratorAST*> *it = node->init_declarators) { - it = it->toFront(); - const ListNode<InitDeclaratorAST*> *end = it; - do { - InitDeclaratorAST *init_declarator = it->element; - declare_symbol(node, init_declarator); - it = it->next; - } while (it != end); - } -} - -void Binder::declare_symbol(SimpleDeclarationAST *node, InitDeclaratorAST *init_declarator) -{ - DeclaratorAST *declarator = init_declarator->declarator; - - while (declarator && declarator->sub_declarator) - declarator = declarator->sub_declarator; - - NameAST *id = declarator->id; - if (!declarator->id) { - std::cerr << "** WARNING expected a declarator id" << std::endl; - return; - } - - CodeModelFinder finder(model(), this); - ScopeModelItem symbolScope = finder.resolveScope(id, currentScope()); - if (!symbolScope) { - name_cc.run(id); - std::cerr << "** WARNING scope not found for symbol:" - << qPrintable(name_cc.name()) << std::endl; - return; - } - - decl_cc.run(declarator); - - if (decl_cc.isFunction()) { - name_cc.run(id->unqualified_name); - - FunctionModelItem fun(new _FunctionModelItem(model(), name_cc.name())); - updateItemPosition(fun, node); - fun->setAccessPolicy(_M_current_access); - fun->setFunctionType(_M_current_function_type); - fun->setAbstract(init_declarator->initializer != 0); - fun->setConstant(declarator->fun_cv != 0); - fun->setTemplateParameters(_M_current_template_parameters); - applyStorageSpecifiers(node->storage_specifiers, fun); - applyFunctionSpecifiers(node->function_specifiers, fun); - - // build the type - TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier, - declarator, - this); - - fun->setType(qualifyType(typeInfo, symbolScope->qualifiedName())); - - - fun->setVariadics(decl_cc.isVariadics()); - - // ... and the signature - foreach (const DeclaratorCompiler::Parameter &p, decl_cc.parameters()) { - ArgumentModelItem arg(new _ArgumentModelItem(model(), p.name)); - arg->setType(qualifyType(p.type, _M_context)); - arg->setDefaultValue(p.defaultValue); - if (p.defaultValue) - arg->setDefaultValueExpression(p.defaultValueExpression); - fun->addArgument(arg); - } - - fun->setScope(symbolScope->qualifiedName()); - symbolScope->addFunction(fun); - } else { - VariableModelItem var(new _VariableModelItem(model())); - updateItemPosition(var, node); - var->setTemplateParameters(_M_current_template_parameters); - var->setAccessPolicy(_M_current_access); - name_cc.run(id->unqualified_name); - var->setName(name_cc.name()); - // Possible bug, because second parameter uses declarator instead of - // init_declarator->declarator like in DeclaratorCompiler::visitParameterDeclaration, - // but it doesn't seem to affect anything because the generator doesn't currently use - // variable declarations, only function declarations (because it cares about the API only, - // variable declarations are not exposed to the target language). - // See PYSIDE-455. - TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier, - declarator, - this); - if (declarator != init_declarator->declarator - && init_declarator->declarator->parameter_declaration_clause) { - typeInfo.setFunctionPointer(true); - decl_cc.run(init_declarator->declarator); - foreach (const DeclaratorCompiler::Parameter &p, decl_cc.parameters()) - typeInfo.addArgument(p.type); - } - - var->setType(qualifyType(typeInfo, _M_context)); - applyStorageSpecifiers(node->storage_specifiers, var); - - var->setScope(symbolScope->qualifiedName()); - symbolScope->addVariable(var); - } -} - -void Binder::visitFunctionDefinition(FunctionDefinitionAST *node) -{ - Q_ASSERT(node->init_declarator); - - ScopeModelItem scope = currentScope(); - - InitDeclaratorAST *init_declarator = node->init_declarator; - DeclaratorAST *declarator = init_declarator->declarator; - - // in the case of "void (func)()" or "void ((func))()" we need to - // skip to the inner most. This is in line with how the declarator - // node is generated in 'parser.cpp' - while (declarator && declarator->sub_declarator) - declarator = declarator->sub_declarator; - if (!declarator->id) { - std::cerr << "** WARNING temp hack for Qt 5.6.0: " - << "skipped a class that inherits from a private class" - << std::endl; - return; - } - Q_ASSERT(declarator->id); - - CodeModelFinder finder(model(), this); - - ScopeModelItem functionScope = finder.resolveScope(declarator->id, scope); - if (!functionScope) { - name_cc.run(declarator->id); - std::cerr << "** WARNING scope not found for function definition:" - << qPrintable(name_cc.name()) << std::endl - << "\tdefinition *ignored*" - << std::endl; - return; - } - - decl_cc.run(declarator); - - Q_ASSERT(!decl_cc.id().isEmpty()); - - FunctionModelItem - old = changeCurrentFunction(FunctionModelItem(new _FunctionModelItem(_M_model))); - _M_current_function->setScope(functionScope->qualifiedName()); - updateItemPosition(_M_current_function, node); - - Q_ASSERT(declarator->id->unqualified_name); - name_cc.run(declarator->id->unqualified_name); - QString unqualified_name = name_cc.name(); - - _M_current_function->setName(unqualified_name); - TypeInfo tmp_type = CompilerUtils::typeDescription(node->type_specifier, - declarator, this); - - _M_current_function->setType(qualifyType(tmp_type, _M_context)); - _M_current_function->setAccessPolicy(_M_current_access); - _M_current_function->setFunctionType(_M_current_function_type); - _M_current_function->setConstant(declarator->fun_cv); - _M_current_function->setTemplateParameters(_M_current_template_parameters); - - applyStorageSpecifiers(node->storage_specifiers, - _M_current_function); - applyFunctionSpecifiers(node->function_specifiers, - _M_current_function); - - _M_current_function->setVariadics(decl_cc.isVariadics()); - - foreach (const DeclaratorCompiler::Parameter &p, decl_cc.parameters()) { - ArgumentModelItem arg(new _ArgumentModelItem(model(), p.name)); - arg->setType(qualifyType(p.type, functionScope->qualifiedName())); - arg->setDefaultValue(p.defaultValue); - if (p.defaultValue) - arg->setDefaultValueExpression(p.defaultValueExpression); - _M_current_function->addArgument(arg); - } - - FunctionModelItem prototype = _M_current_function; - FunctionModelItem declared = functionScope->declaredFunction(prototype); - - // try to find a function declaration for this definition.. - if (!declared) { - functionScope->addFunction(prototype); - } else { - applyFunctionSpecifiers(node->function_specifiers, declared); - - // fix the function type and the access policy - _M_current_function->setAccessPolicy(declared->accessPolicy()); - _M_current_function->setFunctionType(declared->functionType()); - } - - changeCurrentFunction(old); -} - -void Binder::visitTemplateDeclaration(TemplateDeclarationAST *node) -{ - const ListNode<TemplateParameterAST*> *it = node->template_parameters; - if (!it) { - // QtScript: we want to visit the declaration still, so that - // e.g. QMetaTypeId<Foo> is added to the code model - visit(node->declaration); - return; - } - - TemplateParameterList savedTemplateParameters = changeTemplateParameters(TemplateParameterList()); - - it = it->toFront(); - const ListNode<TemplateParameterAST*> *end = it; - - TemplateParameterList templateParameters; - do { - TemplateParameterAST *parameter = it->element; - TypeParameterAST *type_parameter = parameter->type_parameter; - - NameAST *name; - if (!type_parameter) { - // A hacky hack to work around missing support for parameter declarations in - // templates. We just need the to get the name of the variable, since we - // aren't actually compiling these anyway. We are still not supporting much - // more, but we are refusing to fail for a few more declarations - if (!parameter->parameter_declaration || - !parameter->parameter_declaration->declarator || - !parameter->parameter_declaration->declarator->id) { - - /*std::cerr << "** WARNING template declaration not supported ``"; - Token const &tk = _M_token_stream->token ((int) node->start_token); - Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token); - - std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''" - << std::endl << std::endl;*/ - - changeTemplateParameters(savedTemplateParameters); - return; - - } - - name = parameter->parameter_declaration->declarator->id; - } else { - int tk = decode_token(type_parameter->type); - if (tk != Token_typename && tk != Token_class) { - /*std::cerr << "** WARNING template declaration not supported ``"; - Token const &tk = _M_token_stream->token ((int) node->start_token); - Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token); - - std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''" - << std::endl << std::endl;*/ - - changeTemplateParameters(savedTemplateParameters); - return; - } - assert(tk == Token_typename || tk == Token_class); - - name = type_parameter->name; - } - - - name_cc.run(name); - const TemplateParameterModelItem p(new _TemplateParameterModelItem(model(), name_cc.name())); - _M_current_template_parameters.append(p); - it = it->next; - } while (it != end); - - visit(node->declaration); - - changeTemplateParameters(savedTemplateParameters); -} - -void Binder::visitTypedef(TypedefAST *node) -{ - const ListNode<InitDeclaratorAST*> *it = node->init_declarators; - if (!it) - return; - - it = it->toFront(); - const ListNode<InitDeclaratorAST*> *end = it; - - do { - InitDeclaratorAST *init_declarator = it->element; - it = it->next; - - Q_ASSERT(init_declarator->declarator); - - // the name - decl_cc.run(init_declarator->declarator); - QString alias_name = decl_cc.id(); - - if (alias_name.isEmpty()) { - std::cerr << "** WARNING anonymous typedef not supported! ``"; - Token const &tk = _M_token_stream->token((int) node->start_token); - Token const &end_tk = _M_token_stream->token((int) node->end_token); - - std::cerr << std::string(&tk.text[tk.position], end_tk.position - tk.position) << "''" - << std::endl << std::endl; - continue; - } - - // build the type - TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier, - init_declarator->declarator, - this); - DeclaratorAST *decl = init_declarator->declarator; - while (decl && decl->sub_declarator) - decl = decl->sub_declarator; - - if (decl != init_declarator->declarator - && init_declarator->declarator->parameter_declaration_clause) { - typeInfo.setFunctionPointer(true); - decl_cc.run(init_declarator->declarator); - foreach (const DeclaratorCompiler::Parameter &p, decl_cc.parameters()) - typeInfo.addArgument(p.type); - } - - ScopeModelItem scope = currentScope(); - DeclaratorAST *declarator = init_declarator->declarator; - CodeModelFinder finder(model(), this); - ScopeModelItem typedefScope = finder.resolveScope(declarator->id, scope); - - TypeDefModelItem typeDef(new _TypeDefModelItem(model())); - updateItemPosition(typeDef, node); - typeDef->setName(alias_name); - typeDef->setType(qualifyType(typeInfo, currentScope()->qualifiedName())); - typeDef->setScope(typedefScope->qualifiedName()); - _M_qualified_types[typeDef->qualifiedName().join(QLatin1Char('.'))] = QString(); - currentScope()->addTypeDef(typeDef); - } while (it != end); -} - -void Binder::visitNamespace(NamespaceAST *node) -{ - bool anonymous = (node->namespace_name == 0); - - ScopeModelItem scope = currentScope(); - - NamespaceModelItem old; - if (!anonymous) { - QString name = decode_symbol(node->namespace_name)->as_string(); - - QStringList qualified_name = scope->qualifiedName(); - qualified_name += name; - const CodeModelItem nsI = _M_model->findItem(qualified_name, _M_current_file); - NamespaceModelItem ns = qSharedPointerDynamicCast<_NamespaceModelItem>(nsI); - if (!ns) { - ns.reset(new _NamespaceModelItem(_M_model)); - updateItemPosition(ns, node); - ns->setName(name); - ns->setScope(scope->qualifiedName()); - } - old = changeCurrentNamespace(ns); - - _M_context.append(name); - } - - DefaultVisitor::visitNamespace(node); - - if (!anonymous) { - Q_ASSERT(scope->kind() == _CodeModelItem::Kind_Namespace - || scope->kind() == _CodeModelItem::Kind_File); - - _M_context.removeLast(); - - if (const NamespaceModelItem ns = qSharedPointerDynamicCast<_NamespaceModelItem>(scope)) - ns->addNamespace(_M_current_namespace); - - changeCurrentNamespace(old); - } -} - -void Binder::visitForwardDeclarationSpecifier(ForwardDeclarationSpecifierAST *node) -{ - name_cc.run(node->name); - if (name_cc.name().isEmpty()) - return; - - ScopeModelItem scope = currentScope(); - _M_qualified_types[(scope->qualifiedName() + name_cc.qualifiedName()).join(QLatin1Char('.'))] = QString(); -} - -void Binder::visitClassSpecifier(ClassSpecifierAST *node) -{ - ClassCompiler class_cc(this); - class_cc.run(node); - - if (class_cc.name().isEmpty()) { - // anonymous not supported - return; - } - - Q_ASSERT(node->name && node->name->unqualified_name); - - ScopeModelItem scope = currentScope(); - - ClassModelItem old = changeCurrentClass(ClassModelItem(new _ClassModelItem(_M_model))); - updateItemPosition(_M_current_class, node); - _M_current_class->setName(class_cc.name()); - - QStringList baseClasses = class_cc.baseClasses(); - TypeInfo info; - for (int i = 0; i < baseClasses.size(); ++i) { - info.setQualifiedName(baseClasses.at(i).split(QLatin1String("::"))); - baseClasses[i] = qualifyType(info, scope->qualifiedName()).qualifiedName().join(QLatin1String("::")); - } - - _M_current_class->setBaseClasses(baseClasses); - _M_current_class->setClassType(decode_class_type(node->class_key)); - _M_current_class->setTemplateParameters(_M_current_template_parameters); - - if (!_M_current_template_parameters.isEmpty()) { - QString name = _M_current_class->name(); - name += QLatin1Char('<'); - for (int i = 0; i < _M_current_template_parameters.size(); ++i) { - if (i > 0) - name += QLatin1Char(','); - - name += _M_current_template_parameters.at(i)->name(); - } - - name += QLatin1Char('>'); - _M_current_class->setName(name); - } - - CodeModel::AccessPolicy oldAccessPolicy = changeCurrentAccess(decode_access_policy(node->class_key)); - CodeModel::FunctionType oldFunctionType = changeCurrentFunctionType(CodeModel::Normal); - - _M_current_class->setScope(scope->qualifiedName()); - _M_qualified_types[_M_current_class->qualifiedName().join(QLatin1Char('.'))] = QString(); - - scope->addClass(_M_current_class); - - name_cc.run(node->name->unqualified_name); - _M_context.append(name_cc.name()); - visitNodes(this, node->member_specs); - _M_context.removeLast(); - - changeCurrentClass(old); - changeCurrentAccess(oldAccessPolicy); - changeCurrentFunctionType(oldFunctionType); -} - -void Binder::visitLinkageSpecification(LinkageSpecificationAST *node) -{ - DefaultVisitor::visitLinkageSpecification(node); -} - -void Binder::visitUsing(UsingAST *node) -{ - DefaultVisitor::visitUsing(node); -} - -void Binder::visitEnumSpecifier(EnumSpecifierAST *node) -{ - CodeModelFinder finder(model(), this); - ScopeModelItem scope = currentScope(); - ScopeModelItem enumScope = finder.resolveScope(node->name, scope); - - name_cc.run(node->name); - QString name = name_cc.name(); - - bool isAnonymous = name.isEmpty(); - if (isAnonymous) { - // anonymous enum - QString key = _M_context.join(QLatin1String("::")); - int current = ++_M_anonymous_enums[key]; - name += QLatin1String("enum_"); - name += QString::number(current); - } - - _M_current_enum.reset(new _EnumModelItem(model())); - _M_current_enum->setAccessPolicy(_M_current_access); - updateItemPosition(_M_current_enum, node); - _M_current_enum->setName(name); - _M_current_enum->setAnonymous(isAnonymous); - _M_current_enum->setScope(enumScope->qualifiedName()); - - _M_qualified_types[_M_current_enum->qualifiedName().join(QLatin1Char('.'))] = QString(); - - enumScope->addEnum(_M_current_enum); - - DefaultVisitor::visitEnumSpecifier(node); - - _M_current_enum.clear(); -} - -static QString strip_preprocessor_lines(const QString &name) -{ - QStringList lst = name.split(QLatin1Char('\n')); - QString s; - for (int i = 0; i < lst.size(); ++i) { - if (!lst.at(i).startsWith(QLatin1Char('#'))) - s += lst.at(i); - } - return s.trimmed(); -} - -void Binder::visitEnumerator(EnumeratorAST *node) -{ - Q_ASSERT(_M_current_enum); - EnumeratorModelItem e(new _EnumeratorModelItem(model())); - updateItemPosition(e, node); - e->setName(decode_symbol(node->id)->as_string()); - - if (ExpressionAST *expr = node->expression) { - const Token &start_token = _M_token_stream->token((int) expr->start_token); - const Token &end_token = _M_token_stream->token((int) expr->end_token); - const QString token = QString::fromUtf8(&start_token.text[start_token.position], - (int)(end_token.position - start_token.position)); - QString lines = strip_preprocessor_lines(token.trimmed()); - lines.remove(QLatin1Char(' ')); - e->setValue(lines); - } - - _M_current_enum->addEnumerator(e); -} - -void Binder::visitUsingDirective(UsingDirectiveAST *node) -{ - DefaultVisitor::visitUsingDirective(node); -} - -void Binder::visitQEnums(QEnumsAST *node) -{ - const Token &start = _M_token_stream->token((int) node->start_token); - const Token &end = _M_token_stream->token((int) node->end_token); - QStringList enum_list = QString::fromLatin1(start.text + start.position, - end.position - start.position).split(QLatin1Char(' ')); - - ScopeModelItem scope = currentScope(); - for (int i = 0; i < enum_list.size(); ++i) - scope->addEnumsDeclaration(enum_list.at(i)); -} - -void Binder::visitQProperty(QPropertyAST *node) -{ - const Token &start = _M_token_stream->token((int) node->start_token); - const Token &end = _M_token_stream->token((int) node->end_token); - QString property = QString::fromLatin1(start.text + start.position, - end.position - start.position); - _M_current_class->addPropertyDeclaration(property); -} - -void Binder::applyStorageSpecifiers(const ListNode<std::size_t> *it, MemberModelItem item) -{ - if (!it) - return; - - it = it->toFront(); - const ListNode<std::size_t> *end = it; - - do { - switch (decode_token(it->element)) { - default: - break; - - case Token_friend: - item->setFriend(true); - break; - case Token_auto: - item->setAuto(true); - break; - case Token_register: - item->setRegister(true); - break; - case Token_static: - item->setStatic(true); - break; - case Token_extern: - item->setExtern(true); - break; - case Token_mutable: - item->setMutable(true); - break; - } - it = it->next; - } while (it != end); -} - -void Binder::applyFunctionSpecifiers(const ListNode<std::size_t> *it, FunctionModelItem item) -{ - if (!it) - return; - - it = it->toFront(); - const ListNode<std::size_t> *end = it; - - do { - switch (decode_token(it->element)) { - default: - break; - - case Token_inline: - item->setInline(true); - break; - - case Token_virtual: - item->setVirtual(true); - break; - - case Token_explicit: - item->setExplicit(true); - break; - - case Token_Q_INVOKABLE: - item->setInvokable(true); - break; - } - it = it->next; - } while (it != end); -} - -TypeInfo Binder::qualifyType(const TypeInfo &type, const QStringList &context) const -{ - // ### Potentially improve to use string list in the name table to - if (!context.size()) { - // ### We can assume that this means global namespace for now... - return type; - } else if (_M_qualified_types.contains(type.qualifiedName().join(QLatin1Char('.')))) { - return type; - } else { - QStringList expanded = context; - expanded << type.qualifiedName(); - if (_M_qualified_types.contains(expanded.join(QLatin1Char('.')))) { - TypeInfo modified_type = type; - modified_type.setQualifiedName(expanded); - return modified_type; - } else { - CodeModelItem scope = model()->findItem(context, _M_current_file); - - if (ClassModelItem klass = qSharedPointerDynamicCast<_ClassModelItem>(scope)) { - foreach (const QString &base, klass->baseClasses()) { - QStringList ctx = context; - ctx.removeLast(); - ctx.append(base); - - TypeInfo qualified = qualifyType(type, ctx); - if (qualified != type) - return qualified; - } - } - - QStringList copy = context; - copy.removeLast(); - return qualifyType(type, copy); - } - } -} - -void Binder::updateItemPosition(CodeModelItem item, AST *node) -{ - QString filename; - int line, column; - - assert(node); - _M_location.positionAt(_M_token_stream->position(node->start_token), &line, &column, &filename); - item->setFileName(filename); -} diff --git a/sources/shiboken2/ApiExtractor/parser/binder.h b/sources/shiboken2/ApiExtractor/parser/binder.h deleted file mode 100644 index cd8d93a95..000000000 --- a/sources/shiboken2/ApiExtractor/parser/binder.h +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef BINDER_H -#define BINDER_H - -#include "default_visitor.h" -#include "codemodel.h" -#include "type_compiler.h" -#include "name_compiler.h" -#include "declarator_compiler.h" - -class TokenStream; -class LocationManager; -class Control; -struct NameSymbol; - -class Binder: protected DefaultVisitor -{ -public: - Binder(CodeModel *__model, LocationManager &__location, Control *__control = 0); - virtual ~Binder(); - - inline TokenStream *tokenStream() const - { - return _M_token_stream; - } - - inline CodeModel *model() const - { - return _M_model; - } - - ScopeModelItem currentScope(); - - FileModelItem run(AST *node); - -// utils - TypeInfo qualifyType(const TypeInfo &type, const QStringList &context) const; - -protected: - virtual void visitAccessSpecifier(AccessSpecifierAST *); - virtual void visitClassSpecifier(ClassSpecifierAST *); - virtual void visitEnumSpecifier(EnumSpecifierAST *); - virtual void visitEnumerator(EnumeratorAST *); - virtual void visitFunctionDefinition(FunctionDefinitionAST *); - virtual void visitLinkageSpecification(LinkageSpecificationAST *); - virtual void visitNamespace(NamespaceAST *); - virtual void visitSimpleDeclaration(SimpleDeclarationAST *); - virtual void visitTemplateDeclaration(TemplateDeclarationAST *); - virtual void visitTypedef(TypedefAST *); - virtual void visitUsing(UsingAST *); - virtual void visitUsingDirective(UsingDirectiveAST *); - virtual void visitQProperty(QPropertyAST *); - virtual void visitForwardDeclarationSpecifier(ForwardDeclarationSpecifierAST *); - virtual void visitQEnums(QEnumsAST *); - -private: - - int decode_token(std::size_t index) const; - const NameSymbol *decode_symbol(std::size_t index) const; - CodeModel::AccessPolicy decode_access_policy(std::size_t index) const; - CodeModel::ClassType decode_class_type(std::size_t index) const; - - CodeModel::FunctionType changeCurrentFunctionType(CodeModel::FunctionType functionType); - CodeModel::AccessPolicy changeCurrentAccess(CodeModel::AccessPolicy accessPolicy); - NamespaceModelItem changeCurrentNamespace(NamespaceModelItem item); - ClassModelItem changeCurrentClass(ClassModelItem item); - FunctionModelItem changeCurrentFunction(FunctionModelItem item); - TemplateParameterList changeTemplateParameters(TemplateParameterList templateParameters); - - void declare_symbol(SimpleDeclarationAST *node, InitDeclaratorAST *init_declarator); - - void applyStorageSpecifiers(const ListNode<std::size_t> *storage_specifiers, MemberModelItem item); - void applyFunctionSpecifiers(const ListNode<std::size_t> *it, FunctionModelItem item); - - void updateItemPosition(CodeModelItem item, AST *node); - -private: - CodeModel *_M_model; - LocationManager &_M_location; - TokenStream *_M_token_stream; - Control *_M_control; - - CodeModel::FunctionType _M_current_function_type; - CodeModel::AccessPolicy _M_current_access; - FileModelItem _M_current_file; - NamespaceModelItem _M_current_namespace; - ClassModelItem _M_current_class; - FunctionModelItem _M_current_function; - EnumModelItem _M_current_enum; - QStringList _M_context; - TemplateParameterList _M_current_template_parameters; // ### check me - QHash<QString, QString> _M_qualified_types; - QHash<QString, int> _M_anonymous_enums; - void dummy() { - _M_control=0; - } - -protected: - TypeCompiler type_cc; - NameCompiler name_cc; - DeclaratorCompiler decl_cc; -}; - -#endif // BINDER_H diff --git a/sources/shiboken2/ApiExtractor/parser/class_compiler.cpp b/sources/shiboken2/ApiExtractor/parser/class_compiler.cpp deleted file mode 100644 index 3387412ff..000000000 --- a/sources/shiboken2/ApiExtractor/parser/class_compiler.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "class_compiler.h" -#include "lexer.h" -#include "binder.h" - -ClassCompiler::ClassCompiler(Binder *binder) - : _M_binder(binder), - _M_token_stream(binder->tokenStream()), - name_cc(_M_binder), - type_cc(_M_binder) -{ -} - -ClassCompiler::~ClassCompiler() -{ -} - -void ClassCompiler::run(ClassSpecifierAST *node) -{ - name_cc.run(node->name); - _M_name = name_cc.name(); - _M_base_classes.clear(); - - visit(node); -} - -void ClassCompiler::visitClassSpecifier(ClassSpecifierAST *node) -{ - visit(node->base_clause); -} - -void ClassCompiler::visitBaseSpecifier(BaseSpecifierAST *node) -{ - name_cc.run(node->name); - QString name = name_cc.name(); - - if (!name.isEmpty()) - _M_base_classes.append(name); -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/class_compiler.h b/sources/shiboken2/ApiExtractor/parser/class_compiler.h deleted file mode 100644 index 09b727fe6..000000000 --- a/sources/shiboken2/ApiExtractor/parser/class_compiler.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef CLASS_COMPILER_H -#define CLASS_COMPILER_H - -#include <QtCore/qglobal.h> -#include <QtCore/QStringList> - -#include <default_visitor.h> -#include <name_compiler.h> -#include <type_compiler.h> - -class TokenStream; -class Binder; - -class ClassCompiler: protected DefaultVisitor -{ -public: - ClassCompiler(Binder *binder); - virtual ~ClassCompiler(); - - inline QString name() const - { - return _M_name; - } - - inline QStringList baseClasses() const - { - return _M_base_classes; - } - - void run(ClassSpecifierAST *node); - -protected: - virtual void visitClassSpecifier(ClassSpecifierAST *node); - virtual void visitBaseSpecifier(BaseSpecifierAST *node); - -private: - Binder *_M_binder; - TokenStream *_M_token_stream; - QString _M_name; - QStringList _M_base_classes; - NameCompiler name_cc; - TypeCompiler type_cc; -}; - -#endif // CLASS_COMPILER_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp index a5024c4a3..667e27344 100644 --- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp +++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp @@ -47,9 +47,9 @@ private: }; template <class T> -static QSharedPointer<T> findModelItem(const QList<QSharedPointer<T> > &list, const QString &name) +static QSharedPointer<T> findModelItem(const QVector<QSharedPointer<T> > &list, const QString &name) { - typedef typename QList<QSharedPointer<T> >::const_iterator It; + typedef typename QVector<QSharedPointer<T> >::const_iterator It; const It it = std::find_if(list.begin(), list.end(), ModelItemNamePredicate<T>(name)); return it != list.end() ? *it : QSharedPointer<T>(); } @@ -221,7 +221,7 @@ QString TypeInfo::toString() const tmp += QLatin1Char(')'); } - foreach(QString elt, arrayElements()) { + for (const QString &elt : m_arrayElements) { tmp += QLatin1Char('['); tmp += elt; tmp += QLatin1Char(']'); @@ -230,7 +230,7 @@ QString TypeInfo::toString() const return tmp; } -bool TypeInfo::operator==(const TypeInfo &other) +bool TypeInfo::operator==(const TypeInfo &other) const { if (arrayElements().count() != other.arrayElements().count()) return false; @@ -588,7 +588,7 @@ void _ClassModelItem::formatDebug(QDebug &d) const // --------------------------------------------------------------------------- FunctionModelItem _ScopeModelItem::declaredFunction(FunctionModelItem item) { - foreach (const FunctionModelItem &fun, m_functions) { + for (const FunctionModelItem &fun : qAsConst(m_functions)) { if (fun->name() == item->name() && fun->isSimilar(item)) return fun; @@ -730,7 +730,7 @@ EnumModelItem _ScopeModelItem::findEnum(const QString &name) const FunctionList _ScopeModelItem::findFunctions(const QString &name) const { FunctionList result; - foreach (const FunctionModelItem &func, m_functions) { + for (const FunctionModelItem &func : m_functions) { if (func->name() == name) result.append(func); } @@ -742,6 +742,14 @@ _NamespaceModelItem::~_NamespaceModelItem() { } +QSet<NamespaceModelItem> _NamespaceModelItem::uniqueNamespaces() const +{ + QSet<NamespaceModelItem> result; + for (const NamespaceModelItem &n : m_namespaces) + result.insert(n); + return result; +} + void _NamespaceModelItem::addNamespace(NamespaceModelItem item) { m_namespaces.append(item); diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h index 811cfec3e..ea16e6912 100644 --- a/sources/shiboken2/ApiExtractor/parser/codemodel.h +++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h @@ -35,7 +35,6 @@ #include "codemodel_enums.h" #include <QtCore/QHash> -#include <QtCore/QList> #include <QtCore/QSet> #include <QtCore/QString> #include <QtCore/QStringList> @@ -158,21 +157,18 @@ public: m_arrayElements = arrayElements; } - QList<TypeInfo> arguments() const - { - return m_arguments; - } + QVector<TypeInfo> arguments() const { return m_arguments; } - void setArguments(const QList<TypeInfo> &arguments); + void setArguments(const QVector<TypeInfo> &arguments); void addArgument(const TypeInfo &arg) { m_arguments.append(arg); } - bool operator==(const TypeInfo &other); + bool operator==(const TypeInfo &other) const; - bool operator!=(const TypeInfo &other) + bool operator!=(const TypeInfo &other) const { return !(*this == other); } @@ -193,7 +189,7 @@ private: QStringList m_qualifiedName; QStringList m_arrayElements; - QList<TypeInfo> m_arguments; + QVector<TypeInfo> m_arguments; union { uint flags; @@ -320,7 +316,7 @@ public: FunctionModelItem declaredFunction(FunctionModelItem item); #ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const Q_DECL_OVERRIDE; + void formatDebug(QDebug &d) const override; #endif protected: @@ -372,7 +368,7 @@ public: QStringList propertyDeclarations() const { return m_propertyDeclarations; } #ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const Q_DECL_OVERRIDE; + void formatDebug(QDebug &d) const override; #endif private: @@ -395,14 +391,14 @@ public: ~_NamespaceModelItem(); NamespaceList namespaces() const { return m_namespaces; } - QSet<NamespaceModelItem> uniqueNamespaces() const { return m_namespaces.toSet(); } + QSet<NamespaceModelItem> uniqueNamespaces() const; void addNamespace(NamespaceModelItem item); NamespaceModelItem findNamespace(const QString &name) const; #ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const Q_DECL_OVERRIDE; + void formatDebug(QDebug &d) const override; #endif private: @@ -442,7 +438,7 @@ public: void setDefaultValueExpression(const QString &expr) { m_defaultValueExpression = expr; } #ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const Q_DECL_OVERRIDE; + void formatDebug(QDebug &d) const override; #endif private: @@ -496,7 +492,7 @@ public: void setType(const TypeInfo &type); #ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const Q_DECL_OVERRIDE; + void formatDebug(QDebug &d) const override; #endif private: @@ -558,7 +554,7 @@ public: bool isSimilar(FunctionModelItem other) const; #ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const Q_DECL_OVERRIDE; + void formatDebug(QDebug &d) const override; #endif private: @@ -602,7 +598,7 @@ public: void setType(const TypeInfo &type); #ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const Q_DECL_OVERRIDE; + void formatDebug(QDebug &d) const override; #endif private: @@ -629,7 +625,7 @@ public: void setAnonymous(bool anonymous); #ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const Q_DECL_OVERRIDE; + void formatDebug(QDebug &d) const override; #endif private: @@ -653,7 +649,7 @@ public: void setValue(const QString &value); #ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const Q_DECL_OVERRIDE; + void formatDebug(QDebug &d) const override; #endif private: @@ -678,7 +674,7 @@ public: void setDefaultValue(bool defaultValue); #ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const Q_DECL_OVERRIDE; + void formatDebug(QDebug &d) const override; #endif private: diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel_finder.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel_finder.cpp deleted file mode 100644 index 57f8ae0cf..000000000 --- a/sources/shiboken2/ApiExtractor/parser/codemodel_finder.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "codemodel_finder.h" -#include "codemodel.h" -#include "binder.h" - -CodeModelFinder::CodeModelFinder(CodeModel *model, Binder *binder) - : _M_model(model), - _M_binder(binder), - _M_token_stream(binder->tokenStream()), - name_cc(_M_binder), - _M_resolve_policy(ResolveItem) -{ -} - -CodeModelFinder::~CodeModelFinder() -{ -} - -ScopeModelItem CodeModelFinder::resolveScope(NameAST *name, ScopeModelItem scope) -{ - Q_ASSERT(scope); - - ResolvePolicy saved_resolve_policy = _M_resolve_policy; - _M_resolve_policy = ResolveScope; - - ScopeModelItem old = changeCurrentScope(scope); - - visit(name); - ScopeModelItem result = _M_current_scope; - - changeCurrentScope(old); // restore - - _M_resolve_policy = saved_resolve_policy; - - return result; -} - -ScopeModelItem CodeModelFinder::changeCurrentScope(ScopeModelItem scope) -{ - ScopeModelItem old = _M_current_scope; - _M_current_scope = scope; - return old; -} - -void CodeModelFinder::visitName(NameAST *node) -{ - visitNodes(this, node->qualified_names); - - if (_M_resolve_policy == ResolveItem) - visit(node->unqualified_name); -} - -void CodeModelFinder::visitUnqualifiedName(UnqualifiedNameAST *node) -{ - if (!_M_current_scope) { - // nothing to do - return; - } - - name_cc.run(node); - QString id = name_cc.name(); - - if (ClassModelItem klass = _M_current_scope->findClass(id)) { - _M_current_scope = klass; - } else if (NamespaceModelItem parentNamespace = qSharedPointerDynamicCast<_NamespaceModelItem>(_M_current_scope)) { - NamespaceModelItem ns = parentNamespace->findNamespace(id); - _M_current_scope = ns; - } else if (FileModelItem file = qSharedPointerDynamicCast<_FileModelItem>(_M_current_scope)) { - NamespaceModelItem ns = file->findNamespace(id); - _M_current_scope = ns; - } -} - -// kate: space-indent on; indent-width 2; replace-tabs on; - diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel_finder.h b/sources/shiboken2/ApiExtractor/parser/codemodel_finder.h deleted file mode 100644 index 0217cbac6..000000000 --- a/sources/shiboken2/ApiExtractor/parser/codemodel_finder.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef CODEMODEL_FINDER_H -#define CODEMODEL_FINDER_H - -#include <default_visitor.h> -#include <codemodel_fwd.h> -#include <name_compiler.h> - -class TokenStream; -class Binder; - -class CodeModelFinder: protected DefaultVisitor -{ - enum ResolvePolicy { - ResolveScope, - ResolveItem - }; - -public: - CodeModelFinder(CodeModel *model, Binder *binder); - virtual ~CodeModelFinder(); - - ScopeModelItem resolveScope(NameAST *name, ScopeModelItem scope); - - inline CodeModel *model() const - { - return _M_model; - } - -protected: - virtual void visitName(NameAST *node); - virtual void visitUnqualifiedName(UnqualifiedNameAST *node); - - ScopeModelItem changeCurrentScope(ScopeModelItem scope); - -private: - CodeModel *_M_model; - Binder *_M_binder; - TokenStream *_M_token_stream; - NameCompiler name_cc; - - ScopeModelItem _M_current_scope; - ResolvePolicy _M_resolve_policy; -}; - -#endif // CODEMODEL_FINDER_H diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h b/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h index 676bda872..d5a9f2850 100644 --- a/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h +++ b/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h @@ -31,7 +31,7 @@ #ifndef CODEMODEL_FWD_H #define CODEMODEL_FWD_H -#include <QtCore/QList> +#include <QtCore/QVector> #include <QtCore/QSharedPointer> // forward declarations @@ -65,18 +65,18 @@ typedef QSharedPointer<_TypeDefModelItem> TypeDefModelItem; typedef QSharedPointer<_VariableModelItem> VariableModelItem; typedef QSharedPointer<_MemberModelItem> MemberModelItem; -typedef QList<ArgumentModelItem> ArgumentList; -typedef QList<ClassModelItem> ClassList; -typedef QList<CodeModelItem> ItemList; -typedef QList<EnumModelItem> EnumList; -typedef QList<EnumeratorModelItem> EnumeratorList; -typedef QList<FileModelItem> FileList; -typedef QList<FunctionModelItem> FunctionList; -typedef QList<NamespaceModelItem> NamespaceList; -typedef QList<ScopeModelItem> ScopeList; -typedef QList<TemplateParameterModelItem> TemplateParameterList; -typedef QList<TypeDefModelItem> TypeDefList; -typedef QList<VariableModelItem> VariableList; -typedef QList<MemberModelItem> MemberList; +typedef QVector<ArgumentModelItem> ArgumentList; +typedef QVector<ClassModelItem> ClassList; +typedef QVector<CodeModelItem> ItemList; +typedef QVector<EnumModelItem> EnumList; +typedef QVector<EnumeratorModelItem> EnumeratorList; +typedef QVector<FileModelItem> FileList; +typedef QVector<FunctionModelItem> FunctionList; +typedef QVector<NamespaceModelItem> NamespaceList; +typedef QVector<ScopeModelItem> ScopeList; +typedef QVector<TemplateParameterModelItem> TemplateParameterList; +typedef QVector<TypeDefModelItem> TypeDefList; +typedef QVector<VariableModelItem> VariableList; +typedef QVector<MemberModelItem> MemberList; #endif // CODEMODEL_FWD_H diff --git a/sources/shiboken2/ApiExtractor/parser/compiler_utils.cpp b/sources/shiboken2/ApiExtractor/parser/compiler_utils.cpp deleted file mode 100644 index 95a9db6c3..000000000 --- a/sources/shiboken2/ApiExtractor/parser/compiler_utils.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "compiler_utils.h" -#include "type_compiler.h" -#include "name_compiler.h" -#include "declarator_compiler.h" -#include "ast.h" -#include "binder.h" - -TypeInfo CompilerUtils::typeDescription(TypeSpecifierAST *type_specifier, DeclaratorAST *declarator, Binder *binder) -{ - TypeCompiler type_cc(binder); - DeclaratorCompiler decl_cc(binder); - - type_cc.run(type_specifier); - decl_cc.run(declarator); - - TypeInfo typeInfo; - typeInfo.setQualifiedName(type_cc.qualifiedName()); - typeInfo.setConstant(type_cc.isConstant()); - typeInfo.setVolatile(type_cc.isVolatile()); - typeInfo.setReferenceType(decl_cc.isReference() ? LValueReference : NoReference); - typeInfo.setIndirections(decl_cc.indirection()); - typeInfo.setArrayElements(decl_cc.arrayElements()); - - return typeInfo; -} diff --git a/sources/shiboken2/ApiExtractor/parser/control.cpp b/sources/shiboken2/ApiExtractor/parser/control.cpp deleted file mode 100644 index f86fa16bb..000000000 --- a/sources/shiboken2/ApiExtractor/parser/control.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "control.h" -#include "lexer.h" - -Control::Control() - : current_context(0), - _M_skipFunctionBody(false), - _M_lexer(0), - _M_parser(0) -{ - pushContext(); - - declareTypedef(findOrInsertName("__builtin_va_list", - strlen("__builtin_va_list")), 0); -} - -Control::~Control() -{ - popContext(); - - Q_ASSERT(current_context == 0); -} - -Lexer *Control::changeLexer(Lexer *lexer) -{ - Lexer *old = _M_lexer; - _M_lexer = lexer; - return old; -} - -Parser *Control::changeParser(Parser *parser) -{ - Parser *old = _M_parser; - _M_parser = parser; - return old; -} - -Type *Control::lookupType(const NameSymbol *name) const -{ - Q_ASSERT(current_context != 0); - - return current_context->resolve(name); -} - -void Control::declare(const NameSymbol *name, Type *type) -{ - //printf("*** Declare:"); - //printSymbol(name); - //putchar('\n'); - Q_ASSERT(current_context != 0); - - current_context->bind(name, type); -} - -void Control::pushContext() -{ - // printf("+Context\n"); - Context *new_context = new Context; - new_context->parent = current_context; - current_context = new_context; -} - -void Control::popContext() -{ - // printf("-Context\n"); - Q_ASSERT(current_context != 0); - - Context *old_context = current_context; - current_context = current_context->parent; - - delete old_context; -} - -void Control::declareTypedef(const NameSymbol *name, Declarator *d) -{ - // printf("declared typedef:"); - // printSymbol(name); - // printf("\n"); - stl_typedef_table.insert(name, d); -} - -bool Control::isTypedef(const NameSymbol *name) const -{ - // printf("is typedef:"); - // printSymbol(name); - // printf("= %d\n", (stl_typedef_table.find(name) != stl_typedef_table.end())); - - return stl_typedef_table.contains(name); -} - -QList<Control::ErrorMessage> Control::errorMessages() const -{ - return _M_error_messages; -} - -void Control::clearErrorMessages() -{ - _M_error_messages.clear(); -} - -void Control::reportError(const ErrorMessage &errmsg) -{ - _M_error_messages.append(errmsg); -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/control.h b/sources/shiboken2/ApiExtractor/parser/control.h deleted file mode 100644 index 92635299e..000000000 --- a/sources/shiboken2/ApiExtractor/parser/control.h +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef CONTROL_H -#define CONTROL_H - -#include "symbol.h" -#include "smallobject.h" - -#include <QtCore/QHash> - -struct Declarator; -struct Type; -class Lexer; -class Parser; - -struct Context { - Context *parent; - - inline void bind(const NameSymbol *name, Type *type) { - symbol_table.insert(name, type); - } - - inline Type *resolve(const NameSymbol *name) const { - if (Type *type = symbol_table.value(name)) - return type; - else if (parent) - return parent->resolve(name); - - return 0; - } - - typedef QHash<const NameSymbol*, Type*> symbol_table_t; - - symbol_table_t symbol_table; -}; - -class Control -{ -public: - class ErrorMessage - { - public: - ErrorMessage(): - _M_line(0), - _M_column(0) {} - - inline int line() const { - return _M_line; - } - inline void setLine(int line) { - _M_line = line; - } - - inline int column() const { - return _M_column; - } - inline void setColumn(int column) { - _M_column = column; - } - - inline QString fileName() const { - return _M_fileName; - } - inline void setFileName(const QString &fileName) { - _M_fileName = fileName; - } - - inline QString message() const { - return _M_message; - } - inline void setMessage(const QString &message) { - _M_message = message; - } - - private: - int _M_line; - int _M_column; - QString _M_fileName; - QString _M_message; - }; - - Control(); - ~Control(); - - inline bool skipFunctionBody() const { - return _M_skipFunctionBody; - } - inline void setSkipFunctionBody(bool skip) { - _M_skipFunctionBody = skip; - } - - Lexer *changeLexer(Lexer *lexer); - Parser *changeParser(Parser *parser); - - Lexer *currentLexer() const { - return _M_lexer; - } - Parser *currentParser() const { - return _M_parser; - } - - Context *current_context; - - inline Context *currentContext() const { - return current_context; - } - - void pushContext(); - void popContext(); - - Type *lookupType(const NameSymbol *name) const; - void declare(const NameSymbol *name, Type *type); - - inline const NameSymbol *findOrInsertName(const char *data, size_t count) { - return name_table.findOrInsert(data, count); - } - - void declareTypedef(const NameSymbol *name, Declarator *d); - bool isTypedef(const NameSymbol *name) const; - - void reportError(const ErrorMessage &errmsg); - QList<ErrorMessage> errorMessages() const; - void clearErrorMessages(); - -private: - NameTable name_table; - QHash<const NameSymbol*, Declarator*> stl_typedef_table; - bool _M_skipFunctionBody; - Lexer *_M_lexer; - Parser *_M_parser; - - QList<ErrorMessage> _M_error_messages; -}; - -#endif // CONTROL_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/declarator_compiler.cpp b/sources/shiboken2/ApiExtractor/parser/declarator_compiler.cpp deleted file mode 100644 index e27ea5842..000000000 --- a/sources/shiboken2/ApiExtractor/parser/declarator_compiler.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "declarator_compiler.h" -#include "name_compiler.h" -#include "type_compiler.h" -#include "compiler_utils.h" -#include "lexer.h" -#include "binder.h" -#include "tokens.h" - -#include <qdebug.h> - -DeclaratorCompiler::DeclaratorCompiler(Binder *binder) - : _M_binder(binder), _M_token_stream(binder->tokenStream()) -{ -} - -void DeclaratorCompiler::run(DeclaratorAST *node) -{ - _M_id.clear(); - _M_parameters.clear(); - _M_array.clear(); - _M_function = false; - _M_reference = false; - _M_variadics = false; - _M_indirection = 0; - - if (node) { - NameCompiler name_cc(_M_binder); - - DeclaratorAST *decl = node; - while (decl && decl->sub_declarator) - decl = decl->sub_declarator; - - Q_ASSERT(decl != 0); - - name_cc.run(decl->id); - _M_id = name_cc.name(); - _M_function = (node->parameter_declaration_clause != 0); - if (node->parameter_declaration_clause && node->parameter_declaration_clause->ellipsis) - _M_variadics = true; - - visitNodes(this, node->ptr_ops); - visit(node->parameter_declaration_clause); - - if (const ListNode<ExpressionAST*> *it = node->array_dimensions) { - it->toFront(); - const ListNode<ExpressionAST*> *end = it; - - do { - QString elt; - if (ExpressionAST *expr = it->element) { - const Token &start_token = _M_token_stream->token((int) expr->start_token); - const Token &end_token = _M_token_stream->token((int) expr->end_token); - - elt += QString::fromUtf8(&start_token.text[start_token.position], - (int)(end_token.position - start_token.position)).trimmed(); - } - - _M_array.append(elt); - - it = it->next; - } while (it != end); - } - } -} - -void DeclaratorCompiler::visitPtrOperator(PtrOperatorAST *node) -{ - std::size_t op = _M_token_stream->kind(node->op); - - switch (op) { - case '&': - _M_reference = true; - break; - case '*': - ++_M_indirection; - break; - - default: - break; - } - - if (node->mem_ptr) { -#if defined(__GNUC__) -#warning "ptr to mem -- not implemented" -#endif - } -} - -void DeclaratorCompiler::visitParameterDeclaration(ParameterDeclarationAST *node) -{ - Parameter p; - DeclaratorCompiler decl_cc(_M_binder); - - // Find the innermost declarator, to extract the name / id of the declaration. - DeclaratorAST *declarator = node->declarator; - while (declarator && declarator->sub_declarator) - declarator = declarator->sub_declarator; - decl_cc.run(declarator); - p.name = decl_cc.id(); - - // Use the original declarator to extract the type. - p.type = CompilerUtils::typeDescription(node->type_specifier, node->declarator, _M_binder); - - // In case if the declarator is a function pointer, extract the arguments of the declarator - // parameter clause. This only works for top-declarator function pointers, it will fail to - // determine nested function pointers. - if (declarator != node->declarator - && node->declarator->parameter_declaration_clause) { - p.type.setFunctionPointer(true); - decl_cc.run(node->declarator); - foreach (const DeclaratorCompiler::Parameter &innerParam, decl_cc.parameters()) - p.type.addArgument(innerParam.type); - } - - if (node->expression != 0) { - const Token &start = _M_token_stream->token((int) node->expression->start_token); - const Token &end = _M_token_stream->token((int) node->expression->end_token); - int length = (int)(end.position - start.position); - - p.defaultValueExpression = QString(); - QString source = QString::fromUtf8(&start.text[start.position], length).trimmed(); - QStringList list = source.split(QLatin1Char('\n')); - - - for (int i = 0; i < list.size(); ++i) { - if (!list.at(i).startsWith(QLatin1Char('#'))) - p.defaultValueExpression += list.at(i).trimmed(); - } - - p.defaultValue = p.defaultValueExpression.size() > 0; - - } - - _M_parameters.append(p); -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/declarator_compiler.h b/sources/shiboken2/ApiExtractor/parser/declarator_compiler.h deleted file mode 100644 index f67bd4672..000000000 --- a/sources/shiboken2/ApiExtractor/parser/declarator_compiler.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef DECLARATOR_COMPILER_H -#define DECLARATOR_COMPILER_H - -#include "default_visitor.h" -#include "codemodel.h" - -#include <QtCore/QString> -#include <QtCore/QList> - -class TokenStream; -class Binder; - -class DeclaratorCompiler: protected DefaultVisitor -{ -public: - struct Parameter { - TypeInfo type; - QString name; - QString defaultValueExpression; - bool defaultValue; - - Parameter(): defaultValue(false) {} - }; - -public: - DeclaratorCompiler(Binder *binder); - - void run(DeclaratorAST *node); - - inline QString id() const { - return _M_id; - } - inline QStringList arrayElements() const { - return _M_array; - } - inline bool isFunction() const { - return _M_function; - } - inline bool isVariadics() const { - return _M_variadics; - } - inline bool isReference() const { - return _M_reference; - } - inline int indirection() const { - return _M_indirection; - } - inline QList<Parameter> parameters() const { - return _M_parameters; - } - -protected: - virtual void visitPtrOperator(PtrOperatorAST *node); - virtual void visitParameterDeclaration(ParameterDeclarationAST *node); - -private: - Binder *_M_binder; - TokenStream *_M_token_stream; - - bool _M_function; - bool _M_reference; - bool _M_variadics; - int _M_indirection; - QString _M_id; - QStringList _M_array; - QList<Parameter> _M_parameters; -}; - -#endif // DECLARATOR_COMPILER_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/default_visitor.cpp b/sources/shiboken2/ApiExtractor/parser/default_visitor.cpp deleted file mode 100644 index e330abcbb..000000000 --- a/sources/shiboken2/ApiExtractor/parser/default_visitor.cpp +++ /dev/null @@ -1,464 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "default_visitor.h" - -void DefaultVisitor::visitAccessSpecifier(AccessSpecifierAST *) -{ - // nothing to do -} - -void DefaultVisitor::visitAsmDefinition(AsmDefinitionAST *) -{ - // nothing to do -} - -void DefaultVisitor::visitBaseClause(BaseClauseAST *node) -{ - visitNodes(this, node->base_specifiers); -} - -void DefaultVisitor::visitBaseSpecifier(BaseSpecifierAST *node) -{ - visit(node->name); -} - -void DefaultVisitor::visitBinaryExpression(BinaryExpressionAST *node) -{ - visit(node->left_expression); - visit(node->right_expression); -} - -void DefaultVisitor::visitCastExpression(CastExpressionAST *node) -{ - visit(node->type_id); - visit(node->expression); -} - -void DefaultVisitor::visitClassMemberAccess(ClassMemberAccessAST *node) -{ - visit(node->name); -} - -void DefaultVisitor::visitClassSpecifier(ClassSpecifierAST *node) -{ - visit(node->win_decl_specifiers); - visit(node->name); - visit(node->base_clause); - visitNodes(this, node->member_specs); -} - -void DefaultVisitor::visitCompoundStatement(CompoundStatementAST *node) -{ - visitNodes(this, node->statements); -} - -void DefaultVisitor::visitCondition(ConditionAST *node) -{ - visit(node->type_specifier); - visit(node->declarator); - visit(node->expression); -} - -void DefaultVisitor::visitConditionalExpression(ConditionalExpressionAST *node) -{ - visit(node->condition); - visit(node->left_expression); - visit(node->right_expression); -} - -void DefaultVisitor::visitCppCastExpression(CppCastExpressionAST *node) -{ - visit(node->type_id); - visit(node->expression); - visitNodes(this, node->sub_expressions); -} - -void DefaultVisitor::visitCtorInitializer(CtorInitializerAST *node) -{ - visitNodes(this, node->member_initializers); -} - -void DefaultVisitor::visitDeclarationStatement(DeclarationStatementAST *node) -{ - visit(node->declaration); -} - -void DefaultVisitor::visitDeclarator(DeclaratorAST *node) -{ - visit(node->sub_declarator); - visitNodes(this, node->ptr_ops); - visit(node->id); - visit(node->bit_expression); - visitNodes(this, node->array_dimensions); - visit(node->parameter_declaration_clause); - visit(node->exception_spec); -} - -void DefaultVisitor::visitDeleteExpression(DeleteExpressionAST *node) -{ - visit(node->expression); -} - -void DefaultVisitor::visitDoStatement(DoStatementAST *node) -{ - visit(node->statement); - visit(node->expression); -} - -void DefaultVisitor::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *node) -{ - visit(node->name); -} - -void DefaultVisitor::visitEnumSpecifier(EnumSpecifierAST *node) -{ - visit(node->name); - visitNodes(this, node->enumerators); -} - -void DefaultVisitor::visitEnumerator(EnumeratorAST *node) -{ - visit(node->expression); -} - -void DefaultVisitor::visitExceptionSpecification(ExceptionSpecificationAST *node) -{ - visitNodes(this, node->type_ids); -} - -void DefaultVisitor::visitExpressionOrDeclarationStatement(ExpressionOrDeclarationStatementAST *node) -{ - visit(node->expression); - visit(node->declaration); -} - -void DefaultVisitor::visitExpressionStatement(ExpressionStatementAST *node) -{ - visit(node->expression); -} - -void DefaultVisitor::visitForStatement(ForStatementAST *node) -{ - visit(node->init_statement); - visit(node->condition); - visit(node->expression); - visit(node->statement); -} - -void DefaultVisitor::visitFunctionCall(FunctionCallAST *node) -{ - visit(node->arguments); -} - -void DefaultVisitor::visitFunctionDefinition(FunctionDefinitionAST *node) -{ - visit(node->type_specifier); - visit(node->init_declarator); - visit(node->function_body); - visit(node->win_decl_specifiers); -} - -void DefaultVisitor::visitIfStatement(IfStatementAST *node) -{ - visit(node->condition); - visit(node->statement); - visit(node->else_statement); -} - -void DefaultVisitor::visitIncrDecrExpression(IncrDecrExpressionAST *) -{ - // nothing to do -} - -void DefaultVisitor::visitInitDeclarator(InitDeclaratorAST *node) -{ - visit(node->declarator); - visit(node->initializer); -} - -void DefaultVisitor::visitInitializer(InitializerAST *node) -{ - visit(node->initializer_clause); - visit(node->expression); -} - -void DefaultVisitor::visitInitializerClause(InitializerClauseAST *node) -{ - visit(node->expression); -} - -void DefaultVisitor::visitLabeledStatement(LabeledStatementAST *) -{ - // nothing to do -} - -void DefaultVisitor::visitLinkageBody(LinkageBodyAST *node) -{ - visitNodes(this, node->declarations); -} - -void DefaultVisitor::visitLinkageSpecification(LinkageSpecificationAST *node) -{ - visit(node->linkage_body); - visit(node->declaration); -} - -void DefaultVisitor::visitMemInitializer(MemInitializerAST *node) -{ - visit(node->initializer_id); - visit(node->expression); -} - -void DefaultVisitor::visitName(NameAST *node) -{ - visitNodes(this, node->qualified_names); - visit(node->unqualified_name); -} - -void DefaultVisitor::visitNamespace(NamespaceAST *node) -{ - visit(node->linkage_body); -} - -void DefaultVisitor::visitNamespaceAliasDefinition(NamespaceAliasDefinitionAST *node) -{ - visit(node->alias_name); -} - -void DefaultVisitor::visitNewDeclarator(NewDeclaratorAST *node) -{ - visit(node->ptr_op); - visit(node->sub_declarator); - visitNodes(this, node->expressions); -} - -void DefaultVisitor::visitNewExpression(NewExpressionAST *node) -{ - visit(node->expression); - visit(node->type_id); - visit(node->new_type_id); - visit(node->new_initializer); -} - -void DefaultVisitor::visitNewInitializer(NewInitializerAST *node) -{ - visit(node->expression); -} - -void DefaultVisitor::visitNewTypeId(NewTypeIdAST *node) -{ - visit(node->type_specifier); - visit(node->new_initializer); - visit(node->new_declarator); -} - -void DefaultVisitor::visitOperator(OperatorAST *) -{ - // nothing to do -} - -void DefaultVisitor::visitOperatorFunctionId(OperatorFunctionIdAST *node) -{ - visit(node->op); - visit(node->type_specifier); - visitNodes(this, node->ptr_ops); -} - -void DefaultVisitor::visitParameterDeclaration(ParameterDeclarationAST *node) -{ - visit(node->type_specifier); - visit(node->declarator); - visit(node->expression); -} - -void DefaultVisitor::visitParameterDeclarationClause(ParameterDeclarationClauseAST *node) -{ - visitNodes(this, node->parameter_declarations); -} - -void DefaultVisitor::visitPostfixExpression(PostfixExpressionAST *node) -{ - visit(node->type_specifier); - visit(node->expression); - visitNodes(this, node->sub_expressions); -} - -void DefaultVisitor::visitPrimaryExpression(PrimaryExpressionAST *node) -{ - visit(node->literal); - visit(node->expression_statement); - visit(node->sub_expression); - visit(node->name); -} - -void DefaultVisitor::visitPtrOperator(PtrOperatorAST *node) -{ - visit(node->mem_ptr); -} - -void DefaultVisitor::visitPtrToMember(PtrToMemberAST *) -{ - // nothing to do -} - -void DefaultVisitor::visitReturnStatement(ReturnStatementAST *node) -{ - visit(node->expression); -} - -void DefaultVisitor::visitSimpleDeclaration(SimpleDeclarationAST *node) -{ - visit(node->type_specifier); - visitNodes(this, node->init_declarators); - visit(node->win_decl_specifiers); -} - -void DefaultVisitor::visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *node) -{ - visit(node->name); - visit(node->type_id); - visit(node->expression); -} - -void DefaultVisitor::visitSizeofExpression(SizeofExpressionAST *node) -{ - visit(node->type_id); - visit(node->expression); -} - -void DefaultVisitor::visitStringLiteral(StringLiteralAST *) -{ - // nothing to do -} - -void DefaultVisitor::visitSubscriptExpression(SubscriptExpressionAST *node) -{ - visit(node->subscript); -} - -void DefaultVisitor::visitSwitchStatement(SwitchStatementAST *node) -{ - visit(node->condition); - visit(node->statement); -} - -void DefaultVisitor::visitTemplateArgument(TemplateArgumentAST *node) -{ - visit(node->type_id); - visit(node->expression); -} - -void DefaultVisitor::visitTemplateDeclaration(TemplateDeclarationAST *node) -{ - visitNodes(this, node->template_parameters); - visit(node->declaration); -} - -void DefaultVisitor::visitTemplateParameter(TemplateParameterAST *node) -{ - visit(node->type_parameter); - visit(node->parameter_declaration); -} - -void DefaultVisitor::visitThrowExpression(ThrowExpressionAST *node) -{ - visit(node->expression); -} - -void DefaultVisitor::visitTranslationUnit(TranslationUnitAST *node) -{ - visitNodes(this, node->declarations); -} - -void DefaultVisitor::visitTryBlockStatement(TryBlockStatementAST *) -{ - // nothing to do -} - -void DefaultVisitor::visitTypeId(TypeIdAST *node) -{ - visit(node->type_specifier); - visit(node->declarator); -} - -void DefaultVisitor::visitTypeIdentification(TypeIdentificationAST *node) -{ - visit(node->name); - visit(node->expression); -} - -void DefaultVisitor::visitTypeParameter(TypeParameterAST *node) -{ - visit(node->name); - visit(node->type_id); - visitNodes(this, node->template_parameters); - visit(node->template_name); -} - -void DefaultVisitor::visitTypedef(TypedefAST *node) -{ - visit(node->type_specifier); - visitNodes(this, node->init_declarators); -} - -void DefaultVisitor::visitUnaryExpression(UnaryExpressionAST *node) -{ - visit(node->expression); -} - -void DefaultVisitor::visitUnqualifiedName(UnqualifiedNameAST *node) -{ - visit(node->operator_id); - visitNodes(this, node->template_arguments); -} - -void DefaultVisitor::visitUsing(UsingAST *node) -{ - visit(node->name); -} - -void DefaultVisitor::visitUsingDirective(UsingDirectiveAST *node) -{ - visit(node->name); -} - -void DefaultVisitor::visitWhileStatement(WhileStatementAST *node) -{ - visit(node->condition); - visit(node->statement); -} - -void DefaultVisitor::visitWinDeclSpec(WinDeclSpecAST *) -{ - // nothing to do -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/default_visitor.h b/sources/shiboken2/ApiExtractor/parser/default_visitor.h deleted file mode 100644 index 1eef8cc85..000000000 --- a/sources/shiboken2/ApiExtractor/parser/default_visitor.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef DEFAULT_VISITOR_H -#define DEFAULT_VISITOR_H - -#include "visitor.h" - -class DefaultVisitor: public Visitor -{ -public: - DefaultVisitor() {} - -protected: - virtual void visitAccessSpecifier(AccessSpecifierAST *); - virtual void visitAsmDefinition(AsmDefinitionAST *); - virtual void visitBaseClause(BaseClauseAST *); - virtual void visitBaseSpecifier(BaseSpecifierAST *); - virtual void visitBinaryExpression(BinaryExpressionAST *); - virtual void visitCastExpression(CastExpressionAST *); - virtual void visitClassMemberAccess(ClassMemberAccessAST *); - virtual void visitClassSpecifier(ClassSpecifierAST *); - virtual void visitCompoundStatement(CompoundStatementAST *); - virtual void visitCondition(ConditionAST *); - virtual void visitConditionalExpression(ConditionalExpressionAST *); - virtual void visitCppCastExpression(CppCastExpressionAST *); - virtual void visitCtorInitializer(CtorInitializerAST *); - virtual void visitDeclarationStatement(DeclarationStatementAST *); - virtual void visitDeclarator(DeclaratorAST *); - virtual void visitDeleteExpression(DeleteExpressionAST *); - virtual void visitDoStatement(DoStatementAST *); - virtual void visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *); - virtual void visitEnumSpecifier(EnumSpecifierAST *); - virtual void visitEnumerator(EnumeratorAST *); - virtual void visitExceptionSpecification(ExceptionSpecificationAST *); - virtual void visitExpressionOrDeclarationStatement(ExpressionOrDeclarationStatementAST *); - virtual void visitExpressionStatement(ExpressionStatementAST *); - virtual void visitForStatement(ForStatementAST *); - virtual void visitFunctionCall(FunctionCallAST *); - virtual void visitFunctionDefinition(FunctionDefinitionAST *); - virtual void visitIfStatement(IfStatementAST *); - virtual void visitIncrDecrExpression(IncrDecrExpressionAST *); - virtual void visitInitDeclarator(InitDeclaratorAST *); - virtual void visitInitializer(InitializerAST *); - virtual void visitInitializerClause(InitializerClauseAST *); - virtual void visitLabeledStatement(LabeledStatementAST *); - virtual void visitLinkageBody(LinkageBodyAST *); - virtual void visitLinkageSpecification(LinkageSpecificationAST *); - virtual void visitMemInitializer(MemInitializerAST *); - virtual void visitName(NameAST *); - virtual void visitNamespace(NamespaceAST *); - virtual void visitNamespaceAliasDefinition(NamespaceAliasDefinitionAST *); - virtual void visitNewDeclarator(NewDeclaratorAST *); - virtual void visitNewExpression(NewExpressionAST *); - virtual void visitNewInitializer(NewInitializerAST *); - virtual void visitNewTypeId(NewTypeIdAST *); - virtual void visitOperator(OperatorAST *); - virtual void visitOperatorFunctionId(OperatorFunctionIdAST *); - virtual void visitParameterDeclaration(ParameterDeclarationAST *); - virtual void visitParameterDeclarationClause(ParameterDeclarationClauseAST *); - virtual void visitPostfixExpression(PostfixExpressionAST *); - virtual void visitPrimaryExpression(PrimaryExpressionAST *); - virtual void visitPtrOperator(PtrOperatorAST *); - virtual void visitPtrToMember(PtrToMemberAST *); - virtual void visitReturnStatement(ReturnStatementAST *); - virtual void visitSimpleDeclaration(SimpleDeclarationAST *); - virtual void visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *); - virtual void visitSizeofExpression(SizeofExpressionAST *); - virtual void visitStringLiteral(StringLiteralAST *); - virtual void visitSubscriptExpression(SubscriptExpressionAST *); - virtual void visitSwitchStatement(SwitchStatementAST *); - virtual void visitTemplateArgument(TemplateArgumentAST *); - virtual void visitTemplateDeclaration(TemplateDeclarationAST *); - virtual void visitTemplateParameter(TemplateParameterAST *); - virtual void visitThrowExpression(ThrowExpressionAST *); - virtual void visitTranslationUnit(TranslationUnitAST *); - virtual void visitTryBlockStatement(TryBlockStatementAST *); - virtual void visitTypeId(TypeIdAST *); - virtual void visitTypeIdentification(TypeIdentificationAST *); - virtual void visitTypeParameter(TypeParameterAST *); - virtual void visitTypedef(TypedefAST *); - virtual void visitUnaryExpression(UnaryExpressionAST *); - virtual void visitUnqualifiedName(UnqualifiedNameAST *); - virtual void visitUsing(UsingAST *); - virtual void visitUsingDirective(UsingDirectiveAST *); - virtual void visitWhileStatement(WhileStatementAST *); - virtual void visitWinDeclSpec(WinDeclSpecAST *); - -private: - typedef void (Visitor::*visitor_fun_ptr)(AST *); - static visitor_fun_ptr _S_table[]; -}; - -#endif // VISITOR_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/dumptree.cpp b/sources/shiboken2/ApiExtractor/parser/dumptree.cpp deleted file mode 100644 index 0a7444c14..000000000 --- a/sources/shiboken2/ApiExtractor/parser/dumptree.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "dumptree.h" - -#include <QtCore/QString> -#include <QtCore/qdebug.h> - -static char const * const names[] = { - 0, - "AccessSpecifier", - "AsmDefinition", - "BaseClause", - "BaseSpecifier", - "BinaryExpression", - "CastExpression", - "ClassMemberAccess", - "ClassSpecifier", - "CompoundStatement", - "Condition", - "ConditionalExpression", - "CppCastExpression", - "CtorInitializer", - "DeclarationStatement", - "Declarator", - "DeleteExpression", - "DoStatement", - "ElaboratedTypeSpecifier", - "EnumSpecifier", - "Enumerator", - "ExceptionSpecification", - "ExpressionOrDeclarationStatement", - "ExpressionStatement", - "ForStatement", - "FunctionCall", - "FunctionDefinition", - "IfStatement", - "IncrDecrExpression", - "InitDeclarator", - "Initializer", - "InitializerClause", - "LabeledStatement", - "LinkageBody", - "LinkageSpecification", - "MemInitializer", - "Name", - "Namespace", - "NamespaceAliasDefinition", - "NewDeclarator", - "NewExpression", - "NewInitializer", - "NewTypeId", - "Operator", - "OperatorFunctionId", - "ParameterDeclaration", - "ParameterDeclarationClause", - "PostfixExpression", - "PrimaryExpression", - "PtrOperator", - "PtrToMember", - "ReturnStatement", - "SimpleDeclaration", - "SimpleTypeSpecifier", - "SizeofExpression", - "StringLiteral", - "SubscriptExpression", - "SwitchStatement", - "TemplateArgument", - "TemplateDeclaration", - "TemplateParameter", - "ThrowExpression", - "TranslationUnit", - "TryBlockStatement", - "TypeId", - "TypeIdentification", - "TypeParameter", - "Typedef", - "UnaryExpression", - "UnqualifiedName", - "Using", - "UsingDirective", - "WhileStatement", - "WinDeclSpec" -}; - -DumpTree::DumpTree() -{ -} - -void DumpTree::visit(AST *node) -{ - static int indent = 0; - - - if (node) - qDebug() << QByteArray(indent * 2, ' ').constData() << names[node->kind] - << '[' << node->start_token << ", " << node->end_token << ']'; - - ++indent; - DefaultVisitor::visit(node); - --indent; -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/lexer.cpp b/sources/shiboken2/ApiExtractor/parser/lexer.cpp deleted file mode 100644 index 3fcf3b561..000000000 --- a/sources/shiboken2/ApiExtractor/parser/lexer.cpp +++ /dev/null @@ -1,1726 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "lexer.h" -#include "tokens.h" -#include "control.h" - -#include <cctype> -#include <iostream> - -scan_fun_ptr Lexer::s_scan_keyword_table[] = { - &Lexer::scanKeyword0, &Lexer::scanKeyword0, - &Lexer::scanKeyword2, &Lexer::scanKeyword3, - &Lexer::scanKeyword4, &Lexer::scanKeyword5, - &Lexer::scanKeyword6, &Lexer::scanKeyword7, - &Lexer::scanKeyword8, &Lexer::scanKeyword9, - &Lexer::scanKeyword10, &Lexer::scanKeyword11, - &Lexer::scanKeyword12, &Lexer::scanKeyword13, - &Lexer::scanKeyword14, &Lexer::scanKeyword0, - &Lexer::scanKeyword16 -}; - -void LocationManager::extract_line(int offset, int *line, QString *filename) const -{ - *line = 0; - if (token_stream.size() < 1) - return; - - const unsigned char *begin_buffer = reinterpret_cast<const unsigned char *>(token_stream[0].text); - const unsigned char *cursor = begin_buffer + offset; - - ++cursor; // skip '#' - if (std::isspace(*cursor) && std::isdigit(*(cursor + 1))) { - ++cursor; - char buffer[1024], *cp = buffer; - do { - *cp++ = *cursor++; - } while (std::isdigit(*cursor)); - *cp = '\0'; - int l = strtol(buffer, 0, 0); - - Q_ASSERT(std::isspace(*cursor)); - ++cursor; - - Q_ASSERT(*cursor == '"'); - ++cursor; - - cp = buffer; - while (*cursor && *cursor != '"') { - *cp++ = *cursor++; - } - *cp = '\0'; - Q_ASSERT(*cursor == '"'); - ++cursor; - - *filename = QLatin1String(buffer); - *line = l; - // printf("filename: %s line: %d\n", buffer, line); - } -} - -void LocationManager::positionAt(std::size_t offset, int *line, int *column, - QString *filename) const -{ - int ppline = 0; - int ppcolumn = 0; - line_table.positionAt(offset, &ppline, &ppcolumn); - - int base_line = 0; - extract_line((int) line_table[ppline-1], &base_line, filename); - - int line2 = 0; - int column2 = 0; - location_table.positionAt((int) line_table[ppline-1], &line2, &column2); - - location_table.positionAt(offset, line, column); - *line = base_line + *line - line2 - 1; -} - -scan_fun_ptr Lexer::s_scan_table[256]; -bool Lexer::s_initialized = false; - -void Lexer::tokenize(const char *contents, std::size_t size) -{ - if (!s_initialized) - initialize_scan_table(); - - token_stream.resize(1024); - token_stream[0].kind = Token_EOF; - token_stream[0].text = contents; - - index = 1; - - cursor = (const unsigned char *) contents; - begin_buffer = (const unsigned char *) contents; - end_buffer = cursor + size; - - location_table.resize(1024); - location_table[0] = 0; - location_table.current_line = 1; - - line_table.resize(1024); - line_table[0] = 0; - line_table.current_line = 1; - - do { - if (index == token_stream.size()) - token_stream.resize(token_stream.size() * 2); - - Token *current_token = &token_stream[(int) index]; - current_token->text = reinterpret_cast<const char*>(begin_buffer); - current_token->position = cursor - begin_buffer; - (this->*s_scan_table[*cursor])(); - current_token->size = cursor - begin_buffer - current_token->position; - } while (cursor < end_buffer); - - if (index == token_stream.size()) - token_stream.resize(token_stream.size() * 2); - - Q_ASSERT(index < token_stream.size()); - token_stream[(int) index].position = cursor - begin_buffer; - token_stream[(int) index].kind = Token_EOF; -} - -void Lexer::reportError(const QString& msg) -{ - int line = 0; - int column = 0; - QString fileName; - - std::size_t tok = token_stream.cursor(); - _M_location.positionAt(token_stream.position(tok), - &line, &column, &fileName); - - Control::ErrorMessage errmsg; - errmsg.setLine(line + 1); - errmsg.setColumn(column); - errmsg.setFileName(fileName); - errmsg.setMessage(QLatin1String("** LEXER ERROR ") + msg); - control->reportError(errmsg); -} - -void Lexer::initialize_scan_table() -{ - s_initialized = true; - - for (int i = 0; i < 256; ++i) { - if (isspace(i)) - s_scan_table[i] = &Lexer::scan_white_spaces; - else if (isalpha(i) || i == '_') - s_scan_table[i] = &Lexer::scan_identifier_or_keyword; - else if (isdigit(i)) - s_scan_table[i] = &Lexer::scan_int_constant; - else - s_scan_table[i] = &Lexer::scan_invalid_input; - } - - s_scan_table[int('L')] = &Lexer::scan_identifier_or_literal; - s_scan_table[int('\n')] = &Lexer::scan_newline; - s_scan_table[int('#')] = &Lexer::scan_preprocessor; - - s_scan_table[int('\'')] = &Lexer::scan_char_constant; - s_scan_table[int('"')] = &Lexer::scan_string_constant; - - s_scan_table[int('.')] = &Lexer::scan_int_constant; - - s_scan_table[int('!')] = &Lexer::scan_not; - s_scan_table[int('%')] = &Lexer::scan_remainder; - s_scan_table[int('&')] = &Lexer::scan_and; - s_scan_table[int('(')] = &Lexer::scan_left_paren; - s_scan_table[int(')')] = &Lexer::scan_right_paren; - s_scan_table[int('*')] = &Lexer::scan_star; - s_scan_table[int('+')] = &Lexer::scan_plus; - s_scan_table[int(',')] = &Lexer::scan_comma; - s_scan_table[int('-')] = &Lexer::scan_minus; - s_scan_table[int('/')] = &Lexer::scan_divide; - s_scan_table[int(':')] = &Lexer::scan_colon; - s_scan_table[int(';')] = &Lexer::scan_semicolon; - s_scan_table[int('<')] = &Lexer::scan_less; - s_scan_table[int('=')] = &Lexer::scan_equal; - s_scan_table[int('>')] = &Lexer::scan_greater; - s_scan_table[int('?')] = &Lexer::scan_question; - s_scan_table[int('[')] = &Lexer::scan_left_bracket; - s_scan_table[int(']')] = &Lexer::scan_right_bracket; - s_scan_table[int('^')] = &Lexer::scan_xor; - s_scan_table[int('{')] = &Lexer::scan_left_brace; - s_scan_table[int('|')] = &Lexer::scan_or; - s_scan_table[int('}')] = &Lexer::scan_right_brace; - s_scan_table[int('~')] = &Lexer::scan_tilde; - - s_scan_table[0] = &Lexer::scan_EOF; -} - -void Lexer::scan_preprocessor() -{ - if (line_table.current_line == line_table.size()) - line_table.resize(line_table.current_line * 2); - - line_table[(int) line_table.current_line++] = (cursor - begin_buffer); - - while (*cursor && *cursor != '\n') - ++cursor; - - if (*cursor != '\n') - reportError(QLatin1String("expected newline")); -} - -void Lexer::scan_char_constant() -{ - const unsigned char *begin = cursor; - - ++cursor; - while (*cursor && *cursor != '\'') { - if (*cursor == '\n') - reportError(QLatin1String("did not expect newline")); - - if (*cursor == '\\') - ++cursor; - ++cursor; - } - - if (*cursor != '\'') - reportError(QLatin1String("expected \'")); - - ++cursor; - - token_stream[(int) index].extra.symbol = - control->findOrInsertName((const char*) begin, cursor - begin); - - token_stream[(int) index++].kind = Token_char_literal; -} - -void Lexer::scan_string_constant() -{ - const unsigned char *begin = cursor; - - ++cursor; - while (*cursor && *cursor != '"') { - if (*cursor == '\n') - reportError(QLatin1String("did not expect newline")); - - if (*cursor == '\\') - ++cursor; - ++cursor; - } - - if (*cursor != '"') - reportError(QLatin1String("expected \"")); - - ++cursor; - - token_stream[(int) index].extra.symbol = - control->findOrInsertName((const char*) begin, cursor - begin); - - token_stream[(int) index++].kind = Token_string_literal; -} - -void Lexer::scan_newline() -{ - if (location_table.current_line == location_table.size()) - location_table.resize(location_table.current_line * 2); - - location_table[(int) location_table.current_line++] = (cursor - begin_buffer); - ++cursor; -} - -void Lexer::scan_white_spaces() -{ - while (isspace(*cursor)) { - if (*cursor == '\n') - scan_newline(); - else - ++cursor; - } -} - -void Lexer::scan_identifier_or_literal() -{ - switch (*(cursor + 1)) { - case '\'': - ++cursor; - scan_char_constant(); - break; - - case '\"': - ++cursor; - scan_string_constant(); - break; - - default: - scan_identifier_or_keyword(); - break; - } -} - -void Lexer::scan_identifier_or_keyword() -{ - const unsigned char *skip = cursor; - while (isalnum(*skip) || *skip == '_') - ++skip; - - int n = skip - cursor; - Token *current_token = &token_stream[(int) index]; - (this->*s_scan_keyword_table[n < 17 ? n : 0])(); - - if (current_token->kind == Token_identifier) { - current_token->extra.symbol = - control->findOrInsertName((const char*) cursor, n); - } - - cursor = skip; -} - -void Lexer::scan_int_constant() -{ - if (*cursor == '.' && !std::isdigit(*(cursor + 1))) { - scan_dot(); - return; - } - - const unsigned char *begin = cursor; - - while (isalnum(*cursor) || *cursor == '.') - ++cursor; - - token_stream[(int) index].extra.symbol = - control->findOrInsertName((const char*) begin, cursor - begin); - - token_stream[(int) index++].kind = Token_number_literal; -} - -void Lexer::scan_not() -{ - /* - '!' ::= not - '!=' ::= not_equal - */ - - ++cursor; - - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_not_eq; - } else { - token_stream[(int) index++].kind = '!'; - } -} - -void Lexer::scan_remainder() -{ - /* - '%' ::= remainder - '%=' ::= remainder_equal - */ - - ++cursor; - - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } else { - token_stream[(int) index++].kind = '%'; - } -} - -void Lexer::scan_and() -{ - /* - '&&' ::= and_and - '&' ::= and - '&=' ::= and_equal - */ - - ++cursor; - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } else if (*cursor == '&') { - ++cursor; - token_stream[(int) index++].kind = Token_and; - } else { - token_stream[(int) index++].kind = '&'; - } -} - -void Lexer::scan_left_paren() -{ - ++cursor; - token_stream[(int) index++].kind = '('; -} - -void Lexer::scan_right_paren() -{ - ++cursor; - token_stream[(int) index++].kind = ')'; -} - -void Lexer::scan_star() -{ - /* - '*' ::= star - '*=' ::= star_equal - */ - - ++cursor; - - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } else { - token_stream[(int) index++].kind = '*'; - } -} - -void Lexer::scan_plus() -{ - /* - '+' ::= plus - '++' ::= incr - '+=' ::= plus_equal - */ - - ++cursor; - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } else if (*cursor == '+') { - ++cursor; - token_stream[(int) index++].kind = Token_incr; - } else { - token_stream[(int) index++].kind = '+'; - } -} - -void Lexer::scan_comma() -{ - ++cursor; - token_stream[(int) index++].kind = ','; -} - -void Lexer::scan_minus() -{ - /* - '-' ::= minus - '--' ::= decr - '-=' ::= minus_equal - '->' ::= left_arrow - */ - - ++cursor; - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } else if (*cursor == '-') { - ++cursor; - token_stream[(int) index++].kind = Token_decr; - } else if (*cursor == '>') { - ++cursor; - token_stream[(int) index++].kind = Token_arrow; - if (*cursor == '*') { - ++cursor; - token_stream[(int) index++].kind = Token_ptrmem; - } - } else { - token_stream[(int) index++].kind = '-'; - } -} - -void Lexer::scan_dot() -{ - /* - '.' ::= dot - '...' ::= ellipsis - */ - - ++cursor; - if (*cursor == '.' && *(cursor + 1) == '.') { - cursor += 2; - token_stream[(int) index++].kind = Token_ellipsis; - } else if (*cursor == '.' && *(cursor + 1) == '*') { - cursor += 2; - token_stream[(int) index++].kind = Token_ptrmem; - } else - token_stream[(int) index++].kind = '.'; -} - -void Lexer::scan_divide() -{ - /* - '/' ::= divide - '/=' ::= divide_equal - */ - - ++cursor; - - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } else { - token_stream[(int) index++].kind = '/'; - } -} - -void Lexer::scan_colon() -{ - ++cursor; - if (*cursor == ':') { - ++cursor; - token_stream[(int) index++].kind = Token_scope; - } else { - token_stream[(int) index++].kind = ':'; - } -} - -void Lexer::scan_semicolon() -{ - ++cursor; - token_stream[(int) index++].kind = ';'; -} - -void Lexer::scan_less() -{ - /* - '<' ::= less - '<<' ::= left_shift - '<<=' ::= left_shift_equal - '<=' ::= less_equal - */ - - ++cursor; - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_leq; - } else if (*cursor == '<') { - ++cursor; - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } else { - token_stream[(int) index++].kind = Token_shift; - } - } else { - token_stream[(int) index++].kind = '<'; - } -} - -void Lexer::scan_equal() -{ - /* - '=' ::= equal - '==' ::= equal_equal - */ - ++cursor; - - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_eq; - } else { - token_stream[(int) index++].kind = '='; - } -} - -void Lexer::scan_greater() -{ - /* - '>' ::= greater - '>=' ::= greater_equal - '>>' ::= right_shift - '>>=' ::= right_shift_equal - */ - - ++cursor; - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_geq; - } else if (*cursor == '>') { - ++cursor; - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } else { - token_stream[(int) index++].kind = Token_shift; - } - } else { - token_stream[(int) index++].kind = '>'; - } -} - -void Lexer::scan_question() -{ - ++cursor; - token_stream[(int) index++].kind = '?'; -} - -void Lexer::scan_left_bracket() -{ - ++cursor; - token_stream[(int) index++].kind = '['; -} - -void Lexer::scan_right_bracket() -{ - ++cursor; - token_stream[(int) index++].kind = ']'; -} - -void Lexer::scan_xor() -{ - /* - '^' ::= xor - '^=' ::= xor_equal - */ - ++cursor; - - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } else { - token_stream[(int) index++].kind = '^'; - } -} - -void Lexer::scan_left_brace() -{ - ++cursor; - token_stream[(int) index++].kind = '{'; -} - -void Lexer::scan_or() -{ - /* - '|' ::= or - '|=' ::= or_equal - '||' ::= or_or - */ - ++cursor; - if (*cursor == '=') { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } else if (*cursor == '|') { - ++cursor; - token_stream[(int) index++].kind = Token_or; - } else { - token_stream[(int) index++].kind = '|'; - } -} - -void Lexer::scan_right_brace() -{ - ++cursor; - token_stream[(int) index++].kind = '}'; -} - -void Lexer::scan_tilde() -{ - ++cursor; - token_stream[(int) index++].kind = '~'; -} - -void Lexer::scan_EOF() -{ - ++cursor; - token_stream[(int) index++].kind = Token_EOF; -} - -void Lexer::scan_invalid_input() -{ - QString errmsg(QLatin1String("invalid input: %1")); - reportError(errmsg); - ++cursor; -} - -void LocationTable::positionAt(std::size_t offset, int max_line, - int *line, int *column) const -{ - if (!(line && column && max_line != 0)) - return; - - int first = 0; - int len = max_line; - int half; - int middle; - - while (len > 0) { - half = len >> 1; - middle = first; - - middle += half; - - if (lines[middle] < offset) { - first = middle; - ++first; - len = len - half - 1; - } else - len = half; - } - - *line = std::max(first, 1); - *column = (int)(offset - lines[*line - 1] - 1); - - if (*column < 0) { - *column = 0; - } -} - -void Lexer::scanKeyword0() -{ - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword2() -{ - switch (*cursor) { - case 'i': - if (*(cursor + 1) == 'f') { - token_stream[(int) index++].kind = Token_if; - return; - } - break; - - case 'd': - if (*(cursor + 1) == 'o') { - token_stream[(int) index++].kind = Token_do; - return; - } - break; - - case 'o': - if (*(cursor + 1) == 'r') { - token_stream[(int) index++].kind = Token_or; - return; - } - break; - - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword3() -{ - switch (*cursor) { - case 'a': - if (*(cursor + 1) == 'n' && - *(cursor + 2) == 'd') { - token_stream[(int) index++].kind = Token_and; - return; - } - if (*(cursor + 1) == 's' && - *(cursor + 2) == 'm') { - token_stream[(int) index++].kind = Token_asm; - return; - } - break; - - case 'f': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'r') { - token_stream[(int) index++].kind = Token_for; - return; - } - break; - - case 'i': - if (*(cursor + 1) == 'n' && - *(cursor + 2) == 't') { - token_stream[(int) index++].kind = Token_int; - return; - } - break; - - case 'n': - if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'w') { - token_stream[(int) index++].kind = Token_new; - return; - } - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 't') { - token_stream[(int) index++].kind = Token_not; - return; - } - break; - - case 't': - if (*(cursor + 1) == 'r' && - *(cursor + 2) == 'y') { - token_stream[(int) index++].kind = Token_try; - return; - } - break; - - case 'x': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'r') { - token_stream[(int) index++].kind = Token_xor; - return; - } - break; - - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword4() -{ - switch (*cursor) { - case 'a': - if (*(cursor + 1) == 'u' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'o') { - token_stream[(int) index++].kind = Token_auto; - return; - } - break; - - case 'c': - if (*(cursor + 1) == 'a' && - *(cursor + 2) == 's' && - *(cursor + 3) == 'e') { - token_stream[(int) index++].kind = Token_case; - return; - } - if (*(cursor + 1) == 'h' && - *(cursor + 2) == 'a' && - *(cursor + 3) == 'r') { - token_stream[(int) index++].kind = Token_char; - return; - } - break; - - case 'b': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'o' && - *(cursor + 3) == 'l') { - token_stream[(int) index++].kind = Token_bool; - return; - } - break; - - case 'e': - if (*(cursor + 1) == 'l' && - *(cursor + 2) == 's' && - *(cursor + 3) == 'e') { - token_stream[(int) index++].kind = Token_else; - return; - } - if (*(cursor + 1) == 'm' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 't') { - token_stream[(int) index++].kind = Token_emit; - return; - } - if (*(cursor + 1) == 'n' && - *(cursor + 2) == 'u' && - *(cursor + 3) == 'm') { - token_stream[(int) index++].kind = Token_enum; - return; - } - break; - - case 'g': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'o') { - token_stream[(int) index++].kind = Token_goto; - return; - } - break; - - case 'l': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 'g') { - token_stream[(int) index++].kind = Token_long; - return; - } - break; - - case 't': - if (*(cursor + 1) == 'h' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 's') { - token_stream[(int) index++].kind = Token_this; - return; - } - break; - - case 'v': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'd') { - token_stream[(int) index++].kind = Token_void; - return; - } - break; - - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword5() -{ - switch (*cursor) { - case 'c': - if (*(cursor + 1) == 'a' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'c' && - *(cursor + 4) == 'h') { - token_stream[(int) index++].kind = Token_catch; - return; - } - if (*(cursor + 1) == 'l' && - *(cursor + 2) == 'a' && - *(cursor + 3) == 's' && - *(cursor + 4) == 's') { - token_stream[(int) index++].kind = Token_class; - return; - } - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'm' && - *(cursor + 3) == 'p' && - *(cursor + 4) == 'l') { - token_stream[(int) index++].kind = Token_compl; - return; - } - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 's' && - *(cursor + 4) == 't') { - token_stream[(int) index++].kind = Token_const; - return; - } - break; - - case 'b': - if (*(cursor + 1) == 'i' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'o' && - *(cursor + 4) == 'r') { - token_stream[(int) index++].kind = Token_bitor; - return; - } - if (*(cursor + 1) == 'r' && - *(cursor + 2) == 'e' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 'k') { - token_stream[(int) index++].kind = Token_break; - return; - } - break; - - case 'f': - if (*(cursor + 1) == 'l' && - *(cursor + 2) == 'o' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 't') { - token_stream[(int) index++].kind = Token_float; - return; - } - break; - - case 'o': - if (*(cursor + 1) == 'r' && - *(cursor + 2) == '_' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'q') { - token_stream[(int) index++].kind = Token_or_eq; - return; - } - break; - - case 's': - if (*(cursor + 1) == 'h' && - *(cursor + 2) == 'o' && - *(cursor + 3) == 'r' && - *(cursor + 4) == 't') { - token_stream[(int) index++].kind = Token_short; - return; - } - if (*(cursor + 1) == 'l' && - *(cursor + 2) == 'o' && - *(cursor + 3) == 't' && - *(cursor + 4) == 's') { - token_stream[(int) index++].kind = Token_slots; - return; - } - break; - - case 'u': - if (*(cursor + 1) == 'n' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'o' && - *(cursor + 4) == 'n') { - token_stream[(int) index++].kind = Token_union; - return; - } - if (*(cursor + 1) == 's' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'n' && - *(cursor + 4) == 'g') { - token_stream[(int) index++].kind = Token_using; - return; - } - break; - - case 't': - if (*(cursor + 1) == 'h' && - *(cursor + 2) == 'r' && - *(cursor + 3) == 'o' && - *(cursor + 4) == 'w') { - token_stream[(int) index++].kind = Token_throw; - return; - } - break; - - case 'w': - if (*(cursor + 1) == 'h' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'l' && - *(cursor + 4) == 'e') { - token_stream[(int) index++].kind = Token_while; - return; - } - break; - - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword6() -{ - switch (*cursor) { - case 'a': - if (*(cursor + 1) == 'n' && - *(cursor + 2) == 'd' && - *(cursor + 3) == '_' && - *(cursor + 4) == 'e' && - *(cursor + 5) == 'q') { - token_stream[(int) index++].kind = Token_and_eq; - return; - } - break; - - case 'b': - if (*(cursor + 1) == 'i' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 'n' && - *(cursor + 5) == 'd') { - token_stream[(int) index++].kind = Token_bitand; - return; - } - break; - - case 'e': - if (*(cursor + 1) == 'x' && - *(cursor + 2) == 'p' && - *(cursor + 3) == 'o' && - *(cursor + 4) == 'r' && - *(cursor + 5) == 't') { - token_stream[(int) index++].kind = Token_export; - return; - } - if (*(cursor + 1) == 'x' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'r' && - *(cursor + 5) == 'n') { - token_stream[(int) index++].kind = Token_extern; - return; - } - break; - - case 'd': - if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'l' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 't' && - *(cursor + 5) == 'e') { - token_stream[(int) index++].kind = Token_delete; - return; - } - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'u' && - *(cursor + 3) == 'b' && - *(cursor + 4) == 'l' && - *(cursor + 5) == 'e') { - token_stream[(int) index++].kind = Token_double; - return; - } - break; - - case 'f': - if (*(cursor + 1) == 'r' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'n' && - *(cursor + 5) == 'd') { - token_stream[(int) index++].kind = Token_friend; - return; - } - break; - - case 'i': - if (*(cursor + 1) == 'n' && - *(cursor + 2) == 'l' && - *(cursor + 3) == 'i' && - *(cursor + 4) == 'n' && - *(cursor + 5) == 'e') { - token_stream[(int) index++].kind = Token_inline; - return; - } - break; - - case 'K': - if (*(cursor + 1) == '_' && - *(cursor + 2) == 'D' && - *(cursor + 3) == 'C' && - *(cursor + 4) == 'O' && - *(cursor + 5) == 'P') { - token_stream[(int) index++].kind = Token_K_DCOP; - return; - } - break; - - case 'n': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 't' && - *(cursor + 3) == '_' && - *(cursor + 4) == 'e' && - *(cursor + 5) == 'q') { - token_stream[(int) index++].kind = Token_not_eq; - return; - } - break; - - case 'p': - if (*(cursor + 1) == 'u' && - *(cursor + 2) == 'b' && - *(cursor + 3) == 'l' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'c') { - token_stream[(int) index++].kind = Token_public; - return; - } - break; - - case 's': - if (*(cursor + 1) == 'i' && - *(cursor + 2) == 'g' && - *(cursor + 3) == 'n' && - *(cursor + 4) == 'e' && - *(cursor + 5) == 'd') { - token_stream[(int) index++].kind = Token_signed; - return; - } - if (*(cursor + 1) == 'i' && - *(cursor + 2) == 'z' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'o' && - *(cursor + 5) == 'f') { - token_stream[(int) index++].kind = Token_sizeof; - return; - } - if (*(cursor + 1) == 't' && - *(cursor + 2) == 'a' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'c') { - token_stream[(int) index++].kind = Token_static; - return; - } - if (*(cursor + 1) == 't' && - *(cursor + 2) == 'r' && - *(cursor + 3) == 'u' && - *(cursor + 4) == 'c' && - *(cursor + 5) == 't') { - token_stream[(int) index++].kind = Token_struct; - return; - } - if (*(cursor + 1) == 'w' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'c' && - *(cursor + 5) == 'h') { - token_stream[(int) index++].kind = Token_switch; - return; - } - break; - - case 'r': - if (*(cursor + 1) == 'e' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'u' && - *(cursor + 4) == 'r' && - *(cursor + 5) == 'n') { - token_stream[(int) index++].kind = Token_return; - return; - } - break; - - case 't': - if (*(cursor + 1) == 'y' && - *(cursor + 2) == 'p' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'd') { - token_stream[(int) index++].kind = Token_typeid; - return; - } - break; - - case 'x': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'r' && - *(cursor + 3) == '_' && - *(cursor + 4) == 'e' && - *(cursor + 5) == 'q') { - token_stream[(int) index++].kind = Token_xor_eq; - return; - } - break; - - case 'k': - if (*(cursor + 1) == '_' && - *(cursor + 2) == 'd' && - *(cursor + 3) == 'c' && - *(cursor + 4) == 'o' && - *(cursor + 5) == 'p') { - token_stream[(int) index++].kind = Token_k_dcop; - return; - } - break; - - case 'Q': - if (*(cursor + 1) == '_' && - *(cursor + 2) == 'E' && - *(cursor + 3) == 'N' && - *(cursor + 4) == 'U' && - *(cursor + 5) == 'M') { // Qt5.5 - token_stream[(int) index++].kind = Token_Q_ENUM; - return; - } - break; - - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword7() -{ - switch (*cursor) { - case 'd': - if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'f' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 'u' && - *(cursor + 5) == 'l' && - *(cursor + 6) == 't') { - token_stream[(int) index++].kind = Token_default; - return; - } - break; - - case 'm': - if (*(cursor + 1) == 'u' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 'b' && - *(cursor + 5) == 'l' && - *(cursor + 6) == 'e') { - token_stream[(int) index++].kind = Token_mutable; - return; - } - break; - - case 'p': - if (*(cursor + 1) == 'r' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'v' && - *(cursor + 4) == 'a' && - *(cursor + 5) == 't' && - *(cursor + 6) == 'e') { - token_stream[(int) index++].kind = Token_private; - return; - } - break; - case 's': - if (*(cursor + 1) == 'i' && - *(cursor + 2) == 'g' && - *(cursor + 3) == 'n' && - *(cursor + 4) == 'a' && - *(cursor + 5) == 'l' && - *(cursor + 6) == 's') { - token_stream[(int) index++].kind = Token_signals; - return; - } - break; - case 't': - if (*(cursor + 1) == 'y' && - *(cursor + 2) == 'p' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'd' && - *(cursor + 5) == 'e' && - *(cursor + 6) == 'f') { - token_stream[(int) index++].kind = Token_typedef; - return; - } - break; - - case 'v': - if (*(cursor + 1) == 'i' && - *(cursor + 2) == 'r' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'u' && - *(cursor + 5) == 'a' && - *(cursor + 6) == 'l') { - token_stream[(int) index++].kind = Token_virtual; - return; - } - break; - - case 'Q': - if (*(cursor + 1) == '_' && - *(cursor + 2) == 'E' && - *(cursor + 3) == 'N' && - *(cursor + 4) == 'U' && - *(cursor + 5) == 'M' && - *(cursor + 6) == 'S') { - token_stream[(int) index++].kind = Token_Q_ENUMS; - return; - } - break; - - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword8() -{ - switch (*cursor) { - case '_': - if (*(cursor + 1) == '_' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'y' && - *(cursor + 4) == 'p' && - *(cursor + 5) == 'e' && - *(cursor + 6) == 'o' && - *(cursor + 7) == 'f') { - token_stream[(int) index++].kind = Token___typeof; - return; - } - break; - - case 'c': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'n' && - *(cursor + 6) == 'u' && - *(cursor + 7) == 'e') { - token_stream[(int) index++].kind = Token_continue; - return; - } - break; - - case 'e': - if (*(cursor + 1) == 'x' && - *(cursor + 2) == 'p' && - *(cursor + 3) == 'l' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'c' && - *(cursor + 6) == 'i' && - *(cursor + 7) == 't') { - token_stream[(int) index++].kind = Token_explicit; - return; - } - break; - - case 'n': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'e' && - *(cursor + 3) == 'x' && - *(cursor + 4) == 'c' && - *(cursor + 5) == 'e' && - *(cursor + 6) == 'p' && - *(cursor + 7) == 't') { - token_stream[(int) index++].kind = Token_noexcept; - return; - } - break; - - case 'o': - if (*(cursor + 1) == 'p' && - *(cursor + 2) == 'e' && - *(cursor + 3) == 'r' && - *(cursor + 4) == 'a' && - *(cursor + 5) == 't' && - *(cursor + 6) == 'o' && - *(cursor + 7) == 'r') { - token_stream[(int) index++].kind = Token_operator; - return; - } - break; - - case 'Q': - if (*(cursor + 1) == '_' && - *(cursor + 2) == 'O' && - *(cursor + 3) == 'B' && - *(cursor + 4) == 'J' && - *(cursor + 5) == 'E' && - *(cursor + 6) == 'C' && - *(cursor + 7) == 'T') { - token_stream[(int) index++].kind = Token_Q_OBJECT; - return; - } - break; - - case 'r': - if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'g' && - *(cursor + 3) == 'i' && - *(cursor + 4) == 's' && - *(cursor + 5) == 't' && - *(cursor + 6) == 'e' && - *(cursor + 7) == 'r') { - token_stream[(int) index++].kind = Token_register; - return; - } - break; - - case 'u': - if (*(cursor + 1) == 'n' && - *(cursor + 2) == 's' && - *(cursor + 3) == 'i' && - *(cursor + 4) == 'g' && - *(cursor + 5) == 'n' && - *(cursor + 6) == 'e' && - *(cursor + 7) == 'd') { - token_stream[(int) index++].kind = Token_unsigned; - return; - } - break; - - case 't': - if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'm' && - *(cursor + 3) == 'p' && - *(cursor + 4) == 'l' && - *(cursor + 5) == 'a' && - *(cursor + 6) == 't' && - *(cursor + 7) == 'e') { - token_stream[(int) index++].kind = Token_template; - return; - } - if (*(cursor + 1) == 'y' && - *(cursor + 2) == 'p' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'n' && - *(cursor + 5) == 'a' && - *(cursor + 6) == 'm' && - *(cursor + 7) == 'e') { - token_stream[(int) index++].kind = Token_typename; - return; - } - break; - - case 'v': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'l' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 't' && - *(cursor + 5) == 'i' && - *(cursor + 6) == 'l' && - *(cursor + 7) == 'e') { - token_stream[(int) index++].kind = Token_volatile; - return; - } - break; - - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword9() -{ - switch (*cursor) { - case 'p': - if (*(cursor + 1) == 'r' && - *(cursor + 2) == 'o' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'e' && - *(cursor + 5) == 'c' && - *(cursor + 6) == 't' && - *(cursor + 7) == 'e' && - *(cursor + 8) == 'd') { - token_stream[(int) index++].kind = Token_protected; - return; - } - break; - - case 'n': - if (*(cursor + 1) == 'a' && - *(cursor + 2) == 'm' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 's' && - *(cursor + 5) == 'p' && - *(cursor + 6) == 'a' && - *(cursor + 7) == 'c' && - *(cursor + 8) == 'e') { - token_stream[(int) index++].kind = Token_namespace; - return; - } - break; - - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword10() -{ - switch (*cursor) { - case 'c': - if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 's' && - *(cursor + 4) == 't' && - *(cursor + 5) == '_' && - *(cursor + 6) == 'c' && - *(cursor + 7) == 'a' && - *(cursor + 8) == 's' && - *(cursor + 9) == 't') { - token_stream[(int) index++].kind = Token_const_cast; - return; - } - break; - - case 'Q': - if (*(cursor + 1) == '_' && - *(cursor + 2) == 'P' && - *(cursor + 3) == 'R' && - *(cursor + 4) == 'O' && - *(cursor + 5) == 'P' && - *(cursor + 6) == 'E' && - *(cursor + 7) == 'R' && - *(cursor + 8) == 'T' && - *(cursor + 9) == 'Y') { - token_stream[(int) index++].kind = Token_Q_PROPERTY; - return; - } - - break; - } - - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword11() -{ - switch (*cursor) { - case 'Q': - if (*(cursor + 1) == '_' && - *(cursor + 2) == 'I' && - *(cursor + 3) == 'N' && - *(cursor + 4) == 'V' && - *(cursor + 5) == 'O' && - *(cursor + 6) == 'K' && - *(cursor + 7) == 'A' && - *(cursor + 8) == 'B' && - *(cursor + 9) == 'L' && - *(cursor + 10) == 'E') { - token_stream[(int) index++].kind = Token_Q_INVOKABLE; - return; - } - break; - - case 's': - if (*(cursor + 1) == 't' && - *(cursor + 2) == 'a' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'c' && - *(cursor + 6) == '_' && - *(cursor + 7) == 'c' && - *(cursor + 8) == 'a' && - *(cursor + 9) == 's' && - *(cursor + 10) == 't') { - token_stream[(int) index++].kind = Token_static_cast; - return; - } - break; - - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword12() -{ - switch (*cursor) { - case 'd': - if (*(cursor + 1) == 'y' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 'm' && - *(cursor + 5) == 'i' && - *(cursor + 6) == 'c' && - *(cursor + 7) == '_' && - *(cursor + 8) == 'c' && - *(cursor + 9) == 'a' && - *(cursor + 10) == 's' && - *(cursor + 11) == 't') { - token_stream[(int) index++].kind = Token_dynamic_cast; - return; - } - break; - - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword13() -{ - switch (*cursor) { - case '_': - if (*(cursor + 1) == '_' && - *(cursor + 2) == 'a' && - *(cursor + 3) == 't' && - *(cursor + 4) == 't' && - *(cursor + 5) == 'r' && - *(cursor + 6) == 'i' && - *(cursor + 7) == 'b' && - *(cursor + 8) == 'u' && - *(cursor + 9) == 't' && - *(cursor + 10) == 'e' && - *(cursor + 11) == '_' && - *(cursor + 12) == '_') { - token_stream[(int) index++].kind = Token___attribute__; - return; - } - break; - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword14() -{ - switch (*cursor) { - case 'k': - if (*(cursor + 1) == '_' && - *(cursor + 2) == 'd' && - *(cursor + 3) == 'c' && - *(cursor + 4) == 'o' && - *(cursor + 5) == 'p' && - *(cursor + 6) == '_' && - *(cursor + 7) == 's' && - *(cursor + 8) == 'i' && - *(cursor + 9) == 'g' && - *(cursor + 10) == 'n' && - *(cursor + 11) == 'a' && - *(cursor + 12) == 'l' && - *(cursor + 13) == 's') { - token_stream[(int) index++].kind = Token_k_dcop_signals; - return; - } - break; - } - token_stream[(int) index++].kind = Token_identifier; -} - -void Lexer::scanKeyword16() -{ - switch (*cursor) { - case 'r': - if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'n' && - *(cursor + 4) == 't' && - *(cursor + 5) == 'e' && - *(cursor + 6) == 'r' && - *(cursor + 7) == 'p' && - *(cursor + 8) == 'r' && - *(cursor + 9) == 'e' && - *(cursor + 10) == 't' && - *(cursor + 11) == '_' && - *(cursor + 12) == 'c' && - *(cursor + 13) == 'a' && - *(cursor + 14) == 's' && - *(cursor + 15) == 't') { - token_stream[(int) index++].kind = Token_reinterpret_cast; - return; - } - break; - } - - token_stream[(int) index++].kind = Token_identifier; -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/lexer.h b/sources/shiboken2/ApiExtractor/parser/lexer.h deleted file mode 100644 index 7144355e4..000000000 --- a/sources/shiboken2/ApiExtractor/parser/lexer.h +++ /dev/null @@ -1,295 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef LEXER_H -#define LEXER_H - -#include "symbol.h" - -#include <QtCore/QString> -#include <cstdlib> -#include <cassert> - -struct NameSymbol; -class Lexer; -class Control; - -typedef void (Lexer::*scan_fun_ptr)(); - -class Token -{ -public: - int kind; - std::size_t position; - std::size_t size; - char const *text; - - union { - const NameSymbol *symbol; - std::size_t right_brace; - } extra; -}; - -class LocationTable -{ -private: - LocationTable(const LocationTable &source); - void operator = (const LocationTable &source); - -public: - inline LocationTable(std::size_t size = 1024) - : lines(0), - line_count(0), - current_line(0) { - resize(size); - } - - inline ~LocationTable() { - free(lines); - } - - inline std::size_t size() const { - return line_count; - } - - void resize(std::size_t size) { - Q_ASSERT(size > 0); - lines = (std::size_t*) ::realloc(lines, sizeof(std::size_t) * size); - line_count = size; - } - - void positionAt(std::size_t offset, int *line, int *column) const { - positionAt(offset, (int) current_line, line, column); - } - - void positionAt(std::size_t offset, int max_line, int *line, int *column) const; - - inline std::size_t &operator[](int index) { - return lines[index]; - } - -private: - std::size_t *lines; - std::size_t line_count; - std::size_t current_line; - - friend class Lexer; -}; - -class TokenStream -{ -private: - TokenStream(const TokenStream &); - void operator = (const TokenStream &); - -public: - inline TokenStream(std::size_t size = 1024) - : tokens(0), - index(0), - token_count(0) { - resize(size); - } - - inline ~TokenStream() { - ::free(tokens); - } - - inline std::size_t size() const { - return token_count; - } - - inline std::size_t cursor() const { - return index; - } - - inline void rewind(int i) { - index = i; - } - - void resize(std::size_t size) { - Q_ASSERT(size > 0); - tokens = (Token*) ::realloc(tokens, sizeof(Token) * size); - token_count = size; - } - - inline std::size_t nextToken() { - return index++; - } - - inline int lookAhead(std::size_t i = 0) const { - return tokens[index + i].kind; - } - - inline int kind(std::size_t i) const { - return tokens[i].kind; - } - - inline std::size_t position(std::size_t i) const { - return tokens[i].position; - } - - inline const NameSymbol *symbol(std::size_t i) const { - return tokens[i].extra.symbol; - } - - inline std::size_t matchingBrace(std::size_t i) const { - return tokens[i].extra.right_brace; - } - - inline Token &operator[](int index) { - return tokens[index]; - } - - inline const Token &token(int index) const { - return tokens[index]; - } - -private: - Token *tokens; - std::size_t index; - std::size_t token_count; - -private: - friend class Lexer; -}; - -class LocationManager -{ - LocationManager(LocationManager const &__other); - void operator = (LocationManager const &__other); - -public: - LocationManager(TokenStream &__token_stream, - LocationTable &__location_table, - LocationTable &__line_table): - token_stream(__token_stream), - location_table(__location_table), - line_table(__line_table) {} - - void positionAt(std::size_t offset, int *line, int *column, - QString *filename) const; - - void extract_line(int offset, int *line, QString *filename) const; - - TokenStream &token_stream; - LocationTable &location_table; - LocationTable &line_table; -}; - -class Lexer -{ -public: - Lexer(LocationManager &__location, Control *__control): - _M_location(__location), - token_stream(_M_location.token_stream), - location_table(_M_location.location_table), - line_table(_M_location.line_table), - control(__control) {} - - void tokenize(const char *contents, std::size_t size); - - LocationManager &_M_location; - TokenStream &token_stream; - LocationTable &location_table; - LocationTable &line_table; - -private: - void reportError(const QString& msg); - - void initialize_scan_table(); - void scan_newline(); - void scan_white_spaces(); - void scan_identifier_or_keyword(); - void scan_identifier_or_literal(); - void scan_int_constant(); - void scan_char_constant(); - void scan_string_constant(); - void scan_invalid_input(); - void scan_preprocessor(); - - // keywords - void scanKeyword0(); - void scanKeyword2(); - void scanKeyword3(); - void scanKeyword4(); - void scanKeyword5(); - void scanKeyword6(); - void scanKeyword7(); - void scanKeyword8(); - void scanKeyword9(); - void scanKeyword10(); - void scanKeyword11(); - void scanKeyword12(); - void scanKeyword13(); - void scanKeyword14(); - void scanKeyword16(); - - // operators - void scan_not(); - void scan_remainder(); - void scan_and(); - void scan_left_paren(); - void scan_right_paren(); - void scan_star(); - void scan_plus(); - void scan_comma(); - void scan_minus(); - void scan_dot(); - void scan_divide(); - void scan_colon(); - void scan_semicolon(); - void scan_less(); - void scan_equal(); - void scan_greater(); - void scan_question(); - void scan_left_bracket(); - void scan_right_bracket(); - void scan_xor(); - void scan_left_brace(); - void scan_or(); - void scan_right_brace(); - void scan_tilde(); - void scan_EOF(); - -private: - Control *control; - const unsigned char *cursor; - const unsigned char *begin_buffer; - const unsigned char *end_buffer; - std::size_t index; - - static scan_fun_ptr s_scan_table[]; - static scan_fun_ptr s_scan_keyword_table[]; - static bool s_initialized; -}; - -#endif // LEXER_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/list.h b/sources/shiboken2/ApiExtractor/parser/list.h deleted file mode 100644 index 764fafffd..000000000 --- a/sources/shiboken2/ApiExtractor/parser/list.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef FASTLIST_H -#define FASTLIST_H - -#include "smallobject.h" - -template <typename Tp> -struct ListNode { - Tp element; - int index; - mutable const ListNode<Tp> *next; - - static ListNode *create(const Tp &element, pool *p) { - ListNode<Tp> *node = new(p->allocate(sizeof(ListNode), strideof(ListNode))) ListNode(); - node->element = element; - node->index = 0; - node->next = node; - - return node; - } - - static ListNode *create(const ListNode *n1, const Tp &element, pool *p) { - ListNode<Tp> *n2 = ListNode::create(element, p); - - n2->index = n1->index + 1; - n2->next = n1->next; - n1->next = n2; - - return n2; - } - - inline ListNode<Tp>() { } - - inline const ListNode<Tp> *at(int index) const { - const ListNode<Tp> *node = this; - while (index != node->index) - node = node->next; - - return node; - } - - inline bool hasNext() const { - return index < next->index; - } - - inline int count() const { - return 1 + toBack()->index; - } - - inline const ListNode<Tp> *toFront() const { - return toBack()->next; - } - - inline const ListNode<Tp> *toBack() const { - const ListNode<Tp> *node = this; - while (node->hasNext()) - node = node->next; - - return node; - } -}; - -template <class Tp> -inline const ListNode<Tp> *snoc(const ListNode<Tp> *list, - const Tp &element, pool *p) -{ - if (!list) - return ListNode<Tp>::create(element, p); - - return ListNode<Tp>::create(list->toBack(), element, p); -} - -#endif // FASTLIST_H - -// kate: space-indent on; indent-width 2; replace-tabs on; - diff --git a/sources/shiboken2/ApiExtractor/parser/name_compiler.cpp b/sources/shiboken2/ApiExtractor/parser/name_compiler.cpp deleted file mode 100644 index 338d81c25..000000000 --- a/sources/shiboken2/ApiExtractor/parser/name_compiler.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "name_compiler.h" -#include "type_compiler.h" -#include "declarator_compiler.h" -#include "lexer.h" -#include "symbol.h" -#include "binder.h" - -#include <QtCore/qdebug.h> - -NameCompiler::NameCompiler(Binder *binder) - : _M_binder(binder), _M_token_stream(binder->tokenStream()) -{ -} - -QString NameCompiler::decode_operator(std::size_t index) const -{ - const Token &tk = _M_token_stream->token((int) index); - return QString::fromUtf8(&tk.text[tk.position], (int) tk.size); -} - -QString NameCompiler::internal_run(AST *node) -{ - _M_name.clear(); - visit(node); - return name(); -} - -void NameCompiler::visitUnqualifiedName(UnqualifiedNameAST *node) -{ - QString tmp_name; - - if (node->tilde) - tmp_name += QLatin1String("~"); - - if (node->id) - tmp_name += _M_token_stream->symbol(node->id)->as_string(); - - if (OperatorFunctionIdAST *op_id = node->operator_id) { -#if defined(__GNUC__) -#warning "NameCompiler::visitUnqualifiedName() -- implement me" -#endif - - if (op_id->op && op_id->op->op) { - tmp_name += QLatin1String("operator"); - tmp_name += decode_operator(op_id->op->op); - if (op_id->op->close) - tmp_name += decode_operator(op_id->op->close); - } else if (op_id->type_specifier) { -#if defined(__GNUC__) -#warning "don't use an hardcoded string as cast' name" -#endif - Token const &tk = _M_token_stream->token((int) op_id->start_token); - Token const &end_tk = _M_token_stream->token((int) op_id->end_token); - tmp_name += QString::fromLatin1(&tk.text[tk.position], - (int)(end_tk.position - tk.position)).trimmed(); - } - } - - _M_name += tmp_name; - if (node->template_arguments) { - // ### cleanup - _M_name.last() += QLatin1String("<"); - visitNodes(this, node->template_arguments); - _M_name.last().truncate(_M_name.last().count() - 1); // remove the last ',' - _M_name.last() += QLatin1String(">"); - } - -} - -void NameCompiler::visitTemplateArgument(TemplateArgumentAST *node) -{ - if (node->type_id && node->type_id->type_specifier) { - TypeCompiler type_cc(_M_binder); - type_cc.run(node->type_id->type_specifier); - - DeclaratorCompiler decl_cc(_M_binder); - decl_cc.run(node->type_id->declarator); - - if (type_cc.isConstant()) - _M_name.last() += QLatin1String("const "); - - QStringList q = type_cc.qualifiedName(); - - if (q.count() == 1) { -#if defined (RXX_RESOLVE_TYPEDEF) // ### it'll break :( - TypeInfo tp; - tp.setQualifiedName(q); - tp = TypeInfo::resolveType(tp, _M_binder->currentScope()->toItem()); - q = tp.qualifiedName(); -#endif - - if (CodeModelItem item = _M_binder->model()->findItem(q, _M_binder->currentScope())) { - if (item->name() == q.last()) - q = item->qualifiedName(); - } - } - - _M_name.last() += q.join(QLatin1String("::")); - - if (decl_cc.isReference()) - _M_name.last() += QLatin1Char('&'); - if (decl_cc.indirection()) - _M_name.last() += QString(decl_cc.indirection(), QLatin1Char('*')); - - _M_name.last() += QLatin1Char(','); - } -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/name_compiler.h b/sources/shiboken2/ApiExtractor/parser/name_compiler.h deleted file mode 100644 index 431d401f8..000000000 --- a/sources/shiboken2/ApiExtractor/parser/name_compiler.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef NAME_COMPILER_H -#define NAME_COMPILER_H - -#include "default_visitor.h" -#include <QtCore/QStringList> - -class TokenStream; -class Binder; - -class NameCompiler: protected DefaultVisitor -{ -public: - NameCompiler(Binder *binder); - - void run(NameAST *node) { - internal_run(node); - } - void run(UnqualifiedNameAST *node) { - internal_run(node); - } - - QString name() const { - return _M_name.join(QLatin1String("::")); - } - QStringList qualifiedName() const { - return _M_name; - } - -protected: - virtual void visitUnqualifiedName(UnqualifiedNameAST *node); - virtual void visitTemplateArgument(TemplateArgumentAST *node); - - QString internal_run(AST *node); - QString decode_operator(std::size_t index) const; - -private: - Binder *_M_binder; - TokenStream *_M_token_stream; - QStringList _M_name; -}; - -#endif // NAME_COMPILER_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/parser.cpp b/sources/shiboken2/ApiExtractor/parser/parser.cpp deleted file mode 100644 index 60d034e83..000000000 --- a/sources/shiboken2/ApiExtractor/parser/parser.cpp +++ /dev/null @@ -1,4075 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - - -// c++ support -#include "parser.h" -#include "tokens.h" -#include "lexer.h" -#include "control.h" - -#include <cstdlib> - -#define ADVANCE(tk, descr) \ - { \ - if (token_stream.lookAhead() != tk) { \ - tokenRequiredError(tk); \ - return false; \ - } \ - token_stream.nextToken(); \ - } - -#define ADVANCE_NR(tk, descr) \ - do { \ - if (token_stream.lookAhead() != tk) { \ - tokenRequiredError(tk); \ - } \ - else \ - token_stream.nextToken(); \ - } while (0) - -#define CHECK(tk) \ - do { \ - if (token_stream.lookAhead() != tk) { \ - return false; \ - } \ - token_stream.nextToken(); \ - } while (0) - -#define UPDATE_POS(_node, start, end) \ - do { \ - (_node)->start_token = start; \ - (_node)->end_token = end; \ - } while (0) - -Parser::Parser(Control *c) - : _M_location(token_stream, location_table, line_table), - control(c), - lexer(_M_location, control) -{ - _M_block_errors = false; -} - -Parser::~Parser() -{ -} - -void Parser::advance() -{ - token_stream.nextToken(); -} - -TranslationUnitAST *Parser::parse(const char *contents, - std::size_t size, pool *p) -{ - _M_block_errors = false; - _M_pool = p; - lexer.tokenize(contents, size); - token_stream.nextToken(); // skip the first token - - Lexer *oldLexer = control->changeLexer(&lexer); - Parser *oldParser = control->changeParser(this); - - TranslationUnitAST *ast = 0; - parseTranslationUnit(ast); - - control->changeLexer(oldLexer); - control->changeParser(oldParser); - - return ast; -} - -bool Parser::parseWinDeclSpec(WinDeclSpecAST *&node) -{ - if (token_stream.lookAhead() != Token_identifier) - return false; - - std::size_t start = token_stream.cursor(); - - const NameSymbol *name_symbol = token_stream.symbol(token_stream.cursor()); - QString name = name_symbol->as_string(); - if (name != QLatin1String("__declspec")) - return false; - std::size_t specifier = token_stream.cursor(); - - token_stream.nextToken(); - if (token_stream.lookAhead() != '(') - return false; - - token_stream.nextToken(); - if (token_stream.lookAhead() != Token_identifier) - return false; - std::size_t modifier = token_stream.cursor(); - - token_stream.nextToken(); - if (token_stream.lookAhead() != ')') - return false; - - token_stream.nextToken(); - - node = CreateNode<WinDeclSpecAST>(_M_pool); - node->specifier = specifier; - node->modifier = modifier; - - UPDATE_POS(node, start, token_stream.cursor()); - - return true; -} - -void Parser::tokenRequiredError(int token) -{ - QString err; - - err += QLatin1String("expected token "); - err += QLatin1String("``"); - err += QLatin1String(token_name(token)); - err += QLatin1String("'' found ``"); - err += QLatin1String(token_name(token_stream.lookAhead())); - err += QLatin1String("''"); - - reportError(err); -} - -void Parser::syntaxError() -{ - QString err; - - err += QLatin1String("unexpected token "); - err += QLatin1String("``"); - err += QLatin1String(token_name(token_stream.lookAhead())); - err += QLatin1String("''"); - - reportError(err); -} - -void Parser::reportError(const QString& msg) -{ - if (!_M_block_errors) { - int line, column; - QString fileName; - - std::size_t tok = token_stream.cursor(); - location().positionAt(token_stream.position(tok), - &line, &column, &fileName); - - Control::ErrorMessage errmsg; - errmsg.setLine(line + 1); - errmsg.setColumn(column); - errmsg.setFileName(fileName); - errmsg.setMessage(QLatin1String("** PARSER ERROR ") + msg); - control->reportError(errmsg); - } -} - -bool Parser::skipUntil(int token) -{ - while (token_stream.lookAhead()) { - if (token_stream.lookAhead() == token) - return true; - - token_stream.nextToken(); - } - - return false; -} - -bool Parser::skipUntilDeclaration() -{ - while (token_stream.lookAhead()) { - - switch (token_stream.lookAhead()) { - case ';': - case '~': - case Token_scope: - case Token_identifier: - case Token_operator: - case Token_char: - case Token_wchar_t: - case Token_bool: - case Token_short: - case Token_int: - case Token_long: - case Token_signed: - case Token_unsigned: - case Token_float: - case Token_double: - case Token_void: - case Token_extern: - case Token_namespace: - case Token_using: - case Token_typedef: - case Token_asm: - case Token_template: - case Token_export: - - case Token_const: // cv - case Token_volatile: // cv - - case Token_public: - case Token_protected: - case Token_private: - case Token_signals: // Qt - case Token_slots: // Qt - return true; - - default: - token_stream.nextToken(); - } - } - - return false; -} - -bool Parser::skipUntilStatement() -{ - while (token_stream.lookAhead()) { - switch (token_stream.lookAhead()) { - case ';': - case '{': - case '}': - case Token_const: - case Token_volatile: - case Token_identifier: - case Token_case: - case Token_default: - case Token_if: - case Token_switch: - case Token_while: - case Token_do: - case Token_for: - case Token_break: - case Token_continue: - case Token_return: - case Token_goto: - case Token_try: - case Token_catch: - case Token_throw: - case Token_char: - case Token_wchar_t: - case Token_bool: - case Token_short: - case Token_int: - case Token_long: - case Token_signed: - case Token_unsigned: - case Token_float: - case Token_double: - case Token_void: - case Token_class: - case Token_struct: - case Token_union: - case Token_enum: - case Token_scope: - case Token_template: - case Token_using: - return true; - - default: - token_stream.nextToken(); - } - } - - return false; -} - -bool Parser::skip(int l, int r) -{ - int count = 0; - while (token_stream.lookAhead()) { - int tk = token_stream.lookAhead(); - - if (tk == l) - ++count; - else if (tk == r) - --count; - else if (l != '{' && (tk == '{' || tk == '}' || tk == ';')) - return false; - - if (!count) - return true; - - token_stream.nextToken(); - } - - return false; -} - -bool Parser::parseName(NameAST *&node, bool acceptTemplateId) -{ - std::size_t start = token_stream.cursor(); - - WinDeclSpecAST *winDeclSpec = 0; - parseWinDeclSpec(winDeclSpec); - - NameAST *ast = CreateNode<NameAST>(_M_pool); - - if (token_stream.lookAhead() == Token_scope) { - ast->global = true; - token_stream.nextToken(); - } - - std::size_t idx = token_stream.cursor(); - - while (true) { - UnqualifiedNameAST *n = 0; - if (!parseUnqualifiedName(n)) - return false; - - if (token_stream.lookAhead() == Token_scope) { - token_stream.nextToken(); - - ast->qualified_names - = snoc(ast->qualified_names, n, _M_pool); - - if (token_stream.lookAhead() == Token_template) { - /// skip optional template #### @todo CHECK - token_stream.nextToken(); - } - } else { - Q_ASSERT(n); - if (!acceptTemplateId) { - token_stream.rewind((int) n->start_token); - parseUnqualifiedName(n, false); - } - - ast->unqualified_name = n; - break; - } - } - - if (idx == token_stream.cursor()) - return false; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseTranslationUnit(TranslationUnitAST *&node) -{ - std::size_t start = token_stream.cursor(); - TranslationUnitAST *ast = CreateNode<TranslationUnitAST>(_M_pool); - - while (token_stream.lookAhead()) { - std::size_t startDecl = token_stream.cursor(); - - DeclarationAST *declaration = 0; - if (parseDeclaration(declaration)) { - ast->declarations = - snoc(ast->declarations, declaration, _M_pool); - } else { - // error recovery - if (startDecl == token_stream.cursor()) { - // skip at least one token - token_stream.nextToken(); - } - - skipUntilDeclaration(); - } - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseDeclaration(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - switch (token_stream.lookAhead()) { - case ';': - token_stream.nextToken(); - return true; - - case Token_extern: - return parseLinkageSpecification(node); - - case Token_namespace: - return parseNamespace(node); - - case Token_using: - return parseUsing(node); - - case Token_typedef: - return parseTypedef(node); - - case Token_asm: - return parseAsmDefinition(node); - - case Token_Q_ENUMS: - case Token_Q_ENUM: - // Qt5: - // These two Q_ENUM tokens map to the same handler. - // If that turns out to be wrong, then write a new one - // named parseQ_ENUM - return parseQ_ENUMS(node); - - case Token_template: - case Token_export: - return parseTemplateDeclaration(node); - - default: { - const ListNode<std::size_t> *cv = 0; - parseCvQualify(cv); - - const ListNode<std::size_t> *storageSpec = 0; - parseStorageClassSpecifier(storageSpec); - - parseCvQualify(cv); - - TypeSpecifierAST *spec = 0; - if (parseEnumSpecifier(spec) - || parseClassSpecifier(spec) - || parseForwardDeclarationSpecifier(spec)) { - parseCvQualify(cv); - - spec->cv = cv; - - const ListNode<InitDeclaratorAST*> *declarators = 0; - parseInitDeclaratorList(declarators); - ADVANCE(';', ";"); - - SimpleDeclarationAST *ast = - CreateNode<SimpleDeclarationAST>(_M_pool); - - ast->storage_specifiers = storageSpec; - ast->type_specifier = spec; - ast->init_declarators = declarators; - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; - } - } - } // end switch - - token_stream.rewind((int) start); - return parseDeclarationInternal(node); -} - -bool Parser::parseLinkageSpecification(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_extern); - - LinkageSpecificationAST *ast = CreateNode<LinkageSpecificationAST>(_M_pool); - - if (token_stream.lookAhead() == Token_string_literal) { - ast->extern_type = token_stream.cursor(); - token_stream.nextToken(); - } - - if (token_stream.lookAhead() == '{') - parseLinkageBody(ast->linkage_body); - else if (!parseDeclaration(ast->declaration)) - reportError(QLatin1String("Declaration syntax error")); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseLinkageBody(LinkageBodyAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK('{'); - - LinkageBodyAST *ast = CreateNode<LinkageBodyAST>(_M_pool); - - while (token_stream.lookAhead()) { - int tk = token_stream.lookAhead(); - - if (tk == '}') - break; - - std::size_t startDecl = token_stream.cursor(); - - DeclarationAST *declaration = 0; - if (parseDeclaration(declaration)) { - ast->declarations = snoc(ast->declarations, declaration, _M_pool); - } else { - // error recovery - if (startDecl == token_stream.cursor()) { - // skip at least one token - token_stream.nextToken(); - } - - skipUntilDeclaration(); - } - } - - if (token_stream.lookAhead() != '}') - reportError(QLatin1String("} expected")); - else - token_stream.nextToken(); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseNamespace(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_namespace); - - std::size_t namespace_name = 0; - if (token_stream.lookAhead() == Token_identifier) { - namespace_name = token_stream.cursor(); - token_stream.nextToken(); - } - - if (token_stream.lookAhead() == '=') { - // namespace alias - token_stream.nextToken(); - - NameAST *name = 0; - if (parseName(name)) { - ADVANCE(';', ";"); - - NamespaceAliasDefinitionAST *ast - = CreateNode<NamespaceAliasDefinitionAST>(_M_pool); - ast->namespace_name = namespace_name; - ast->alias_name = name; - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - return true; - } else { - reportError(QLatin1String("namespace expected")); - return false; - } - } else if (token_stream.lookAhead() != '{') { - reportError(QLatin1String("{ expected")); - return false; - } - - NamespaceAST *ast = CreateNode<NamespaceAST>(_M_pool); - ast->namespace_name = namespace_name; - parseLinkageBody(ast->linkage_body); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseUsing(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_using); - - if (token_stream.lookAhead() == Token_namespace) - return parseUsingDirective(node); - - UsingAST *ast = CreateNode<UsingAST>(_M_pool); - - if (token_stream.lookAhead() == Token_typename) { - ast->type_name = token_stream.cursor(); - token_stream.nextToken(); - } - - if (!parseName(ast->name)) - return false; - - ADVANCE(';', ";"); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseUsingDirective(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_namespace); - - NameAST *name = 0; - if (!parseName(name)) { - reportError(QLatin1String("Namespace name expected")); - return false; - } - - ADVANCE(';', ";"); - - UsingDirectiveAST *ast = CreateNode<UsingDirectiveAST>(_M_pool); - ast->name = name; - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - - -bool Parser::parseOperatorFunctionId(OperatorFunctionIdAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_operator); - - OperatorFunctionIdAST *ast = CreateNode<OperatorFunctionIdAST>(_M_pool); - - if (!parseOperator(ast->op)) { - ast->op = 0; - - // parse cast operator - const ListNode<std::size_t> *cv = 0; - parseCvQualify(cv); - - if (!parseSimpleTypeSpecifier(ast->type_specifier)) { - syntaxError(); - return false; - } - - parseCvQualify(cv); - ast->type_specifier->cv = cv; - - PtrOperatorAST *ptr_op = 0; - while (parsePtrOperator(ptr_op)) - ast->ptr_ops = snoc(ast->ptr_ops, ptr_op, _M_pool); - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - return true; -} - -bool Parser::parseTemplateArgumentList(const ListNode<TemplateArgumentAST*> *&node, - bool reportError) -{ - TemplateArgumentAST *templArg = 0; - if (!parseTemplateArgument(templArg)) - return false; - - node = snoc(node, templArg, _M_pool); - - while (token_stream.lookAhead() == ',') { - token_stream.nextToken(); - - if (!parseTemplateArgument(templArg)) { - if (reportError) { - syntaxError(); - break; - } - - node = 0; - return false; - } - - node = snoc(node, templArg, _M_pool); - } - - return true; -} - -bool Parser::parseTypedef(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_typedef); - - TypeSpecifierAST *spec = 0; - if (!parseTypeSpecifierOrClassSpec(spec)) { - reportError(QLatin1String("Need a type specifier to declare")); - return false; - } - - const ListNode<InitDeclaratorAST*> *declarators = 0; - if (!parseInitDeclaratorList(declarators)) { - //reportError(("Need an identifier to declare")); - //return false; - } - - ADVANCE(';', ";"); - - TypedefAST *ast = CreateNode<TypedefAST>(_M_pool); - ast->type_specifier = spec; - ast->init_declarators = declarators; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseAsmDefinition(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - ADVANCE(Token_asm, "asm"); - - const ListNode<std::size_t> *cv = 0; - parseCvQualify(cv); - -#if defined(__GNUC__) -#warning "implement me" -#endif - skip('(', ')'); - token_stream.nextToken(); - ADVANCE(';', ";"); - - AsmDefinitionAST *ast = CreateNode<AsmDefinitionAST>(_M_pool); - ast->cv = cv; - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseTemplateDeclaration(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - std::size_t exported = 0; - if (token_stream.lookAhead() == Token_export) { - exported = token_stream.cursor(); - token_stream.nextToken(); - } - - CHECK(Token_template); - - const ListNode<TemplateParameterAST*> *params = 0; - if (token_stream.lookAhead() == '<') { - token_stream.nextToken(); - parseTemplateParameterList(params); - - ADVANCE('>', ">"); - } - - DeclarationAST *declaration = 0; - if (!parseDeclaration(declaration)) - reportError(QLatin1String("expected a declaration")); - - TemplateDeclarationAST *ast = CreateNode<TemplateDeclarationAST>(_M_pool); - ast->exported = exported; - ast->template_parameters = params; - ast->declaration = declaration; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseOperator(OperatorAST *&node) -{ - std::size_t start = token_stream.cursor(); - - OperatorAST *ast = CreateNode<OperatorAST>(_M_pool); - - switch (token_stream.lookAhead()) { - case Token_new: - case Token_delete: { - ast->op = token_stream.cursor(); - token_stream.nextToken(); - - if (token_stream.lookAhead() == '[' - && token_stream.lookAhead(1) == ']') { - ast->open = token_stream.cursor(); - token_stream.nextToken(); - - ast->close = token_stream.cursor(); - token_stream.nextToken(); - } - } - break; - - case '+': - case '-': - case '*': - case '/': - case '%': - case '^': - case '&': - case '|': - case '~': - case '!': - case '=': - case '<': - case '>': - case ',': - case Token_assign: - case Token_shift: - case Token_eq: - case Token_not_eq: - case Token_leq: - case Token_geq: - case Token_and: - case Token_or: - case Token_incr: - case Token_decr: - case Token_ptrmem: - case Token_arrow: - ast->op = token_stream.cursor(); - token_stream.nextToken(); - break; - - default: - if (token_stream.lookAhead() == '(' - && token_stream.lookAhead(1) == ')') { - ast->op = ast->open = token_stream.cursor(); - token_stream.nextToken(); - ast->close = token_stream.cursor(); - token_stream.nextToken(); - } else if (token_stream.lookAhead() == '[' - && token_stream.lookAhead(1) == ']') { - ast->op = ast->open = token_stream.cursor(); - token_stream.nextToken(); - ast->close = token_stream.cursor(); - token_stream.nextToken(); - } else { - return false; - } - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseCvQualify(const ListNode<std::size_t> *&node) -{ - std::size_t start = token_stream.cursor(); - - int tk; - while (0 != (tk = token_stream.lookAhead()) - && (tk == Token_const || tk == Token_volatile)) { - node = snoc(node, token_stream.cursor(), _M_pool); - token_stream.nextToken(); - } - - return start != token_stream.cursor(); -} - -bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST *&node, - bool onlyIntegral) -{ - std::size_t start = token_stream.cursor(); - bool isIntegral = false; - bool done = false; - - const ListNode<std::size_t> *integrals = 0; - - while (!done) { - switch (token_stream.lookAhead()) { - case Token_char: - case Token_wchar_t: - case Token_bool: - case Token_short: - case Token_int: - case Token_long: - case Token_signed: - case Token_unsigned: - case Token_float: - case Token_double: - case Token_void: - integrals = snoc(integrals, token_stream.cursor(), _M_pool); - isIntegral = true; - token_stream.nextToken(); - break; - - default: - done = true; - } - } - - SimpleTypeSpecifierAST *ast = CreateNode<SimpleTypeSpecifierAST>(_M_pool); - if (isIntegral) { - ast->integrals = integrals; - } else if (token_stream.lookAhead() == Token___typeof) { - ast->type_of = token_stream.cursor(); - token_stream.nextToken(); - - if (token_stream.lookAhead() == '(') { - token_stream.nextToken(); - - std::size_t saved = token_stream.cursor(); - parseTypeId(ast->type_id); - if (token_stream.lookAhead() != ')') { - ast->type_id = 0; - token_stream.rewind((int) saved); - parseUnaryExpression(ast->expression); - } - ADVANCE(')', ")"); - } else { - parseUnaryExpression(ast->expression); - } - } else if (onlyIntegral) { - token_stream.rewind((int) start); - return false; - } else { - if (!parseName(ast->name, true)) { - ast->name = 0; - token_stream.rewind((int) start); - return false; - } - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parsePtrOperator(PtrOperatorAST *&node) -{ - int tk = token_stream.lookAhead(); - - if (tk != '&' && tk != '*' - && tk != Token_scope && tk != Token_identifier) { - return false; - } - - std::size_t start = token_stream.cursor(); - - PtrOperatorAST *ast = CreateNode<PtrOperatorAST>(_M_pool); - - switch (token_stream.lookAhead()) { - case '&': - case '*': - ast->op = token_stream.cursor(); - token_stream.nextToken(); - break; - - case Token_scope: - case Token_identifier: { - if (!parsePtrToMember(ast->mem_ptr)) { - token_stream.rewind((int) start); - return false; - } - } - break; - - default: - Q_ASSERT(0); - break; - } - - parseCvQualify(ast->cv); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseTemplateArgument(TemplateArgumentAST *&node) -{ - std::size_t start = token_stream.cursor(); - - TypeIdAST *typeId = 0; - ExpressionAST *expr = 0; - - if (!parseTypeId(typeId) || (token_stream.lookAhead() != ',' - && token_stream.lookAhead() != '>')) { - token_stream.rewind((int) start); - - if (!parseLogicalOrExpression(expr, true)) - return false; - } - - TemplateArgumentAST *ast = CreateNode<TemplateArgumentAST>(_M_pool); - ast->type_id = typeId; - ast->expression = expr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseTypeSpecifier(TypeSpecifierAST *&node) -{ - std::size_t start = token_stream.cursor(); - - const ListNode<std::size_t> *cv = 0; - parseCvQualify(cv); - - TypeSpecifierAST *ast = 0; - if (!parseElaboratedTypeSpecifier(ast) && !parseSimpleTypeSpecifier(ast)) { - token_stream.rewind((int) start); - return false; - } - - parseCvQualify(cv); - ast->cv = cv; - - node = ast; - - return true; -} - -bool Parser::parseDeclarator(DeclaratorAST *&node) -{ - std::size_t start = token_stream.cursor(); - - DeclaratorAST *ast = CreateNode<DeclaratorAST>(_M_pool); - - //fprintf(stderr, "[%s-%s] ast->ptr_ops: %p\n", __FILE__, __FUNCTION__, ast->ptr_ops); - - DeclaratorAST *decl = 0; - NameAST *declId = 0; - - PtrOperatorAST *ptrOp = 0; - while (parsePtrOperator(ptrOp)) - ast->ptr_ops = snoc(ast->ptr_ops, ptrOp, _M_pool); - - if (token_stream.lookAhead() == '(') { - token_stream.nextToken(); - - if (!parseDeclarator(decl)) - return false; - - ast->sub_declarator = decl; - - CHECK(')'); - } else { - if (token_stream.lookAhead() == ':') { - // unnamed bitfield - } else if (parseName(declId, true)) { - ast->id = declId; - } else { - token_stream.rewind((int) start); - return false; - } - - if (token_stream.lookAhead() == ':') { - token_stream.nextToken(); - - if (!parseConstantExpression(ast->bit_expression)) - reportError(QLatin1String("Constant expression expected")); - - goto update_pos; - } - } - - { - bool isVector = true; - - while (token_stream.lookAhead() == '[') { - token_stream.nextToken(); - - ExpressionAST *expr = 0; - parseCommaExpression(expr); - - ADVANCE(']', "]"); - - ast->array_dimensions = snoc(ast->array_dimensions, expr, _M_pool); - isVector = true; - } - - bool skipParen = false; - if (token_stream.lookAhead() == Token_identifier - && token_stream.lookAhead(1) == '(' - && token_stream.lookAhead(2) == '(') { - token_stream.nextToken(); - token_stream.nextToken(); - skipParen = true; - } - - int tok = token_stream.lookAhead(); - if (ast->sub_declarator - && !(isVector || tok == '(' || tok == ',' - || tok == ';' || tok == '=')) { - token_stream.rewind((int) start); - return false; - } - - std::size_t index = token_stream.cursor(); - if (token_stream.lookAhead() == '(') { - token_stream.nextToken(); - - ParameterDeclarationClauseAST *params = 0; - if (!parseParameterDeclarationClause(params)) { - token_stream.rewind((int) index); - goto update_pos; - } - - ast->parameter_declaration_clause = params; - - if (token_stream.lookAhead() != ')') { - token_stream.rewind((int) index); - goto update_pos; - } - - token_stream.nextToken(); // skip ')' - - parseCvQualify(ast->fun_cv); - parseNoExcept(); - parseExceptionSpecification(ast->exception_spec); - - if (token_stream.lookAhead() == Token___attribute__) - parse_Attribute__(); - } - - if (skipParen) { - if (token_stream.lookAhead() != ')') - reportError(QLatin1String("')' expected")); - else - token_stream.nextToken(); - } - } - -update_pos: - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseAbstractDeclarator(DeclaratorAST *&node) -{ - std::size_t start = token_stream.cursor(); - - DeclaratorAST *ast = CreateNode<DeclaratorAST>(_M_pool); - DeclaratorAST *decl = 0; - - PtrOperatorAST *ptrOp = 0; - while (parsePtrOperator(ptrOp)) - ast->ptr_ops = snoc(ast->ptr_ops, ptrOp, _M_pool); - - int index = (int) token_stream.cursor(); - if (token_stream.lookAhead() == '(') { - token_stream.nextToken(); - - if (!parseAbstractDeclarator(decl)) { - token_stream.rewind((int) index); - goto label1; - } - - ast->sub_declarator = decl; - - if (token_stream.lookAhead() != ')') { - token_stream.rewind((int) start); - return false; - } - token_stream.nextToken(); - } else if (token_stream.lookAhead() == ':') { - token_stream.nextToken(); - if (!parseConstantExpression(ast->bit_expression)) { - ast->bit_expression = 0; - reportError(QLatin1String("Constant expression expected")); - } - goto update_pos; - } - -label1: { - bool isVector = true; - - while (token_stream.lookAhead() == '[') { - token_stream.nextToken(); - - ExpressionAST *expr = 0; - parseCommaExpression(expr); - - ADVANCE(']', "]"); - - ast->array_dimensions = snoc(ast->array_dimensions, expr, _M_pool); - isVector = true; - } - - int tok = token_stream.lookAhead(); - if (ast->sub_declarator - && !(isVector || tok == '(' || tok == ',' - || tok == ';' || tok == '=')) { - token_stream.rewind((int) start); - return false; - } - - int index = (int) token_stream.cursor(); - if (token_stream.lookAhead() == '(') { - token_stream.nextToken(); - - ParameterDeclarationClauseAST *params = 0; - if (!parseParameterDeclarationClause(params)) { - token_stream.rewind((int) index); - goto update_pos; - } - - ast->parameter_declaration_clause = params; - - if (token_stream.lookAhead() != ')') { - token_stream.rewind((int) index); - goto update_pos; - } - - token_stream.nextToken(); // skip ')' - - parseCvQualify(ast->fun_cv); - parseExceptionSpecification(ast->exception_spec); - } - } - -update_pos: - if (token_stream.cursor() == start) - return false; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseEnumSpecifier(TypeSpecifierAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_enum); - - NameAST *name = 0; - parseName(name); - - if (token_stream.lookAhead() != '{') { - token_stream.rewind((int) start); - return false; - } - token_stream.nextToken(); - - EnumSpecifierAST *ast = CreateNode<EnumSpecifierAST>(_M_pool); - ast->name = name; - - EnumeratorAST *enumerator = 0; - if (parseEnumerator(enumerator)) { - ast->enumerators = snoc(ast->enumerators, enumerator, _M_pool); - - while (token_stream.lookAhead() == ',') { - token_stream.nextToken(); - - if (!parseEnumerator(enumerator)) { - //reportError(("Enumerator expected")); - break; - } - - ast->enumerators = snoc(ast->enumerators, enumerator, _M_pool); - } - } - - ADVANCE_NR('}', "}"); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseTemplateParameterList(const ListNode<TemplateParameterAST*> *&node) -{ - TemplateParameterAST *param = 0; - if (!parseTemplateParameter(param)) - return false; - - node = snoc(node, param, _M_pool); - - while (token_stream.lookAhead() == ',') { - token_stream.nextToken(); - - if (!parseTemplateParameter(param)) { - syntaxError(); - break; - } else { - node = snoc(node, param, _M_pool); - } - } - - return true; -} - -bool Parser::parseTemplateParameter(TemplateParameterAST *&node) -{ - std::size_t start = token_stream.cursor(); - TemplateParameterAST *ast = CreateNode<TemplateParameterAST>(_M_pool); - - int tk = token_stream.lookAhead(); - - if ((tk == Token_class || tk == Token_typename || tk == Token_template) - && parseTypeParameter(ast->type_parameter)) { - // nothing to do - } else if (!parseParameterDeclaration(ast->parameter_declaration)) - return false; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseTypeParameter(TypeParameterAST *&node) -{ - std::size_t start = token_stream.cursor(); - - TypeParameterAST *ast = CreateNode<TypeParameterAST>(_M_pool); - ast->type = start; - - switch (token_stream.lookAhead()) { - case Token_class: - case Token_typename: { - token_stream.nextToken(); // skip class - - // parse optional name - if (parseName(ast->name, true)) { - if (token_stream.lookAhead() == '=') { - token_stream.nextToken(); - - if (!parseTypeId(ast->type_id)) { - //syntaxError(); - token_stream.rewind((int) start); - return false; - } - } else if (token_stream.lookAhead() != ',' - && token_stream.lookAhead() != '>') { - token_stream.rewind((int) start); - return false; - } - } - } - break; - - case Token_template: { - token_stream.nextToken(); // skip template - ADVANCE('<', "<"); - - if (!parseTemplateParameterList(ast->template_parameters)) - return false; - - ADVANCE('>', ">"); - - if (token_stream.lookAhead() == Token_class) - token_stream.nextToken(); - - // parse optional name - if (parseName(ast->name, true)) { - if (token_stream.lookAhead() == '=') { - token_stream.nextToken(); - - if (!parseTypeId(ast->type_id)) { - syntaxError(); - return false; - } - } - } - - if (token_stream.lookAhead() == '=') { - token_stream.nextToken(); - - parseName(ast->template_name, true); - } - } - break; - - default: - return false; - - } // end switch - - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - return true; -} - -bool Parser::parseStorageClassSpecifier(const ListNode<std::size_t> *&node) -{ - std::size_t start = token_stream.cursor(); - - int tk; - while (0 != (tk = token_stream.lookAhead()) - && (tk == Token_friend || tk == Token_auto - || tk == Token_register || tk == Token_static - || tk == Token_extern || tk == Token_mutable)) { - node = snoc(node, token_stream.cursor(), _M_pool); - token_stream.nextToken(); - } - - return start != token_stream.cursor(); -} - -bool Parser::parseFunctionSpecifier(const ListNode<std::size_t> *&node) -{ - std::size_t start = token_stream.cursor(); - - int tk; - while (0 != (tk = token_stream.lookAhead()) - && (tk == Token_inline || tk == Token_virtual - || tk == Token_explicit || tk == Token_Q_INVOKABLE)) { - node = snoc(node, token_stream.cursor(), _M_pool); - token_stream.nextToken(); - } - - return start != token_stream.cursor(); -} - -bool Parser::parseTypeId(TypeIdAST *&node) -{ - /// @todo implement the AST for typeId - std::size_t start = token_stream.cursor(); - - TypeSpecifierAST *spec = 0; - if (!parseTypeSpecifier(spec)) { - token_stream.rewind((int) start); - return false; - } - - DeclaratorAST *decl = 0; - parseAbstractDeclarator(decl); - - TypeIdAST *ast = CreateNode<TypeIdAST>(_M_pool); - ast->type_specifier = spec; - ast->declarator = decl; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseInitDeclaratorList(const ListNode<InitDeclaratorAST*> *&node) -{ - InitDeclaratorAST *decl = 0; - if (!parseInitDeclarator(decl)) - return false; - - node = snoc(node, decl, _M_pool); - - while (token_stream.lookAhead() == ',') { - token_stream.nextToken(); - - if (!parseInitDeclarator(decl)) { - syntaxError(); - break; - } - node = snoc(node, decl, _M_pool); - } - - return true; -} - -bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST *&node) -{ - std::size_t start = token_stream.cursor(); - - ParameterDeclarationClauseAST *ast - = CreateNode<ParameterDeclarationClauseAST>(_M_pool); - - if (!parseParameterDeclarationList(ast->parameter_declarations)) { - if (token_stream.lookAhead() == ')') - goto good; - - if (token_stream.lookAhead() == Token_ellipsis - && token_stream.lookAhead(1) == ')') { - ast->ellipsis = token_stream.cursor(); - goto good; - } - - return false; - } - -good: - - if (token_stream.lookAhead() == Token_ellipsis) { - ast->ellipsis = token_stream.cursor(); - token_stream.nextToken(); - } - - /// @todo add ellipsis - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseParameterDeclarationList(const ListNode<ParameterDeclarationAST*> *&node) -{ - std::size_t start = token_stream.cursor(); - - ParameterDeclarationAST *param = 0; - if (!parseParameterDeclaration(param)) { - token_stream.rewind((int) start); - return false; - } - - node = snoc(node, param, _M_pool); - - while (token_stream.lookAhead() == ',') { - token_stream.nextToken(); - - if (token_stream.lookAhead() == Token_ellipsis) - break; - - if (!parseParameterDeclaration(param)) { - token_stream.rewind((int) start); - return false; - } - node = snoc(node, param, _M_pool); - } - - return true; -} - -bool Parser::parseParameterDeclaration(ParameterDeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - const ListNode<std::size_t> *storage = 0; - parseStorageClassSpecifier(storage); - - // parse decl spec - TypeSpecifierAST *spec = 0; - if (!parseTypeSpecifier(spec)) { - token_stream.rewind((int) start); - return false; - } - - int index = (int) token_stream.cursor(); - - DeclaratorAST *decl = 0; - if (!parseDeclarator(decl)) { - token_stream.rewind((int) index); - - // try with abstract declarator - parseAbstractDeclarator(decl); - } - - ExpressionAST *expr = 0; - if (token_stream.lookAhead() == '=') { - token_stream.nextToken(); - if (!parseLogicalOrExpression(expr, true)) - reportError(QLatin1String("Expression expected")); - } - - ParameterDeclarationAST *ast = CreateNode<ParameterDeclarationAST>(_M_pool); - ast->type_specifier = spec; - ast->declarator = decl; - ast->expression = expr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parse_Attribute__() -{ - token_stream.nextToken(); - - ADVANCE('(', "("); - - ExpressionAST *expr = 0; - parseExpression(expr); - - if (token_stream.lookAhead() != ')') { - reportError(QLatin1String("')' expected")); - return false; - } else { - token_stream.nextToken(); - } - return true; -} - -QString Parser::tokenText(AST *ast) const -{ - if (!ast) - return QString(); - - int start_token = ast->start_token; - int end_token = ast->end_token; - - Token const &tk = token_stream.token(start_token); - Token const &end_tk = token_stream.token(end_token); - - return QString::fromLatin1(&tk.text[tk.position], - (int)(end_tk.position - tk.position)).trimmed(); -} - -bool Parser::parseForwardDeclarationSpecifier(TypeSpecifierAST *&node) -{ - std::size_t start = token_stream.cursor(); - - int kind = token_stream.lookAhead(); - if (kind != Token_class && kind != Token_struct && kind != Token_union) - return false; - - std::size_t class_key = token_stream.cursor(); - token_stream.nextToken(); - - NameAST *name = 0; - if (!parseName(name, false)) { - token_stream.rewind((int) start); - return false; - } - - BaseClauseAST *bases = 0; - if (token_stream.lookAhead() == ':') { - if (!parseBaseClause(bases)) { - token_stream.rewind((int) start); - return false; - } - } - - if (token_stream.lookAhead() != ';') { - token_stream.rewind((int) start); - return false; - } - - ForwardDeclarationSpecifierAST *ast = CreateNode<ForwardDeclarationSpecifierAST>(_M_pool); - ast->class_key = class_key; - ast->name = name; - ast->base_clause = bases; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseClassSpecifier(TypeSpecifierAST *&node) -{ - std::size_t start = token_stream.cursor(); - - int kind = token_stream.lookAhead(); - if (kind != Token_class && kind != Token_struct && kind != Token_union) - return false; - - std::size_t class_key = token_stream.cursor(); - token_stream.nextToken(); - - WinDeclSpecAST *winDeclSpec = 0; - parseWinDeclSpec(winDeclSpec); - - if (token_stream.lookAhead() == Token___attribute__) - parse_Attribute__(); - - while (token_stream.lookAhead() == Token_identifier - && token_stream.lookAhead(1) == Token_identifier) - token_stream.nextToken(); - - NameAST *name = 0; - parseName(name, true); - - BaseClauseAST *bases = 0; - - if (token_stream.lookAhead() == ':') { - if (!parseBaseClause(bases)) - skipUntil('{'); - } - - if (token_stream.lookAhead() != '{') { - - token_stream.rewind((int) start); - return false; - } - - ADVANCE('{', "{"); - - ClassSpecifierAST *ast = CreateNode<ClassSpecifierAST>(_M_pool); - ast->win_decl_specifiers = winDeclSpec; - ast->class_key = class_key; - ast->name = name; - ast->base_clause = bases; - - while (token_stream.lookAhead()) { - if (token_stream.lookAhead() == '}') - break; - - std::size_t startDecl = token_stream.cursor(); - - DeclarationAST *memSpec = 0; - if (!parseMemberSpecification(memSpec)) { - if (startDecl == token_stream.cursor()) - token_stream.nextToken(); // skip at least one token - skipUntilDeclaration(); - } else - ast->member_specs = snoc(ast->member_specs, memSpec, _M_pool); - } - - ADVANCE_NR('}', "}"); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseAccessSpecifier(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - const ListNode<std::size_t> *specs = 0; - - bool done = false; - while (!done) { - switch (token_stream.lookAhead()) { - case Token_signals: - case Token_slots: - case Token_k_dcop: - case Token_k_dcop_signals: - case Token_public: - case Token_protected: - case Token_private: - specs = snoc(specs, token_stream.cursor(), _M_pool); - token_stream.nextToken(); - break; - - default: - done = true; - break; - } - } - - if (!specs) - return false; - - ADVANCE(':', ":"); - - AccessSpecifierAST *ast = CreateNode<AccessSpecifierAST>(_M_pool); - ast->specs = specs; - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseMemberSpecification(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - if (token_stream.lookAhead() == ';') { - token_stream.nextToken(); - return true; - } else if (token_stream.lookAhead() == Token_Q_OBJECT - || token_stream.lookAhead() == Token_K_DCOP) { - token_stream.nextToken(); - return true; - } else if (parseTypedef(node)) { - return true; - } else if (parseUsing(node)) { - return true; - } else if (parseTemplateDeclaration(node)) { - return true; - } else if (parseAccessSpecifier(node)) { - return true; - } else if (parseQ_PROPERTY(node)) { - return true; - } else if (parseQ_ENUMS(node)) { - return true; - } - - token_stream.rewind((int) start); - - const ListNode<std::size_t> *cv = 0; - parseCvQualify(cv); - - const ListNode<std::size_t> *storageSpec = 0; - parseStorageClassSpecifier(storageSpec); - - parseCvQualify(cv); - - TypeSpecifierAST *spec = 0; - if (parseEnumSpecifier(spec) || parseClassSpecifier(spec)) { - parseCvQualify(cv); - spec->cv = cv; - - const ListNode<InitDeclaratorAST*> *declarators = 0; - parseInitDeclaratorList(declarators); - ADVANCE(';', ";"); - - SimpleDeclarationAST *ast = CreateNode<SimpleDeclarationAST>(_M_pool); - ast->type_specifier = spec; - ast->init_declarators = declarators; - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; - } - - token_stream.rewind((int) start); - return parseDeclarationInternal(node); -} - -bool Parser::parseCtorInitializer(CtorInitializerAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(':'); - - CtorInitializerAST *ast = CreateNode<CtorInitializerAST>(_M_pool); - ast->colon = start; - - if (!parseMemInitializerList(ast->member_initializers)) - reportError(QLatin1String("Member initializers expected")); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseElaboratedTypeSpecifier(TypeSpecifierAST *&node) -{ - std::size_t start = token_stream.cursor(); - - int tk = token_stream.lookAhead(); - if (tk == Token_class - || tk == Token_struct - || tk == Token_union - || tk == Token_enum - || tk == Token_typename) { - std::size_t type = token_stream.cursor(); - token_stream.nextToken(); - - NameAST *name = 0; - if (parseName(name, true)) { - ElaboratedTypeSpecifierAST *ast - = CreateNode<ElaboratedTypeSpecifierAST>(_M_pool); - - ast->type = type; - ast->name = name; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; - } - } - - token_stream.rewind((int) start); - return false; -} - -bool Parser::parseNoExcept() -{ - // right now we only accept 'noexcept' with no conditional - CHECK(Token_noexcept); - - return true; -} - -bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_throw); - ADVANCE('(', "("); - - ExceptionSpecificationAST *ast = CreateNode<ExceptionSpecificationAST>(_M_pool); - - if (token_stream.lookAhead() == Token_ellipsis) { - ast->ellipsis = token_stream.cursor(); - token_stream.nextToken(); - } else { - parseTypeIdList(ast->type_ids); - } - - ADVANCE(')', ")"); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseEnumerator(EnumeratorAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_identifier); - std::size_t id = token_stream.cursor() - 1; - - EnumeratorAST *ast = CreateNode<EnumeratorAST>(_M_pool); - ast->id = id; - - if (token_stream.lookAhead() == '=') { - token_stream.nextToken(); - - if (!parseConstantExpression(ast->expression)) - reportError(QLatin1String("Constant expression expected")); - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseInitDeclarator(InitDeclaratorAST *&node) -{ - std::size_t start = token_stream.cursor(); - - DeclaratorAST *decl = 0; - if (!parseDeclarator(decl)) - return false; - - if (token_stream.lookAhead(0) == Token_asm) { - token_stream.nextToken(); - skip('(', ')'); - token_stream.nextToken(); - } - - InitializerAST *init = 0; - parseInitializer(init); - - InitDeclaratorAST *ast = CreateNode<InitDeclaratorAST>(_M_pool); - ast->declarator = decl; - ast->initializer = init; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseBaseClause(BaseClauseAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(':'); - - BaseSpecifierAST *baseSpec = 0; - if (!parseBaseSpecifier(baseSpec)) - return false; - - BaseClauseAST *ast = CreateNode<BaseClauseAST>(_M_pool); - ast->base_specifiers = snoc(ast->base_specifiers, baseSpec, _M_pool); - - while (token_stream.lookAhead() == ',') { - token_stream.nextToken(); - - if (!parseBaseSpecifier(baseSpec)) { - reportError(QLatin1String("Base class specifier expected")); - break; - } - ast->base_specifiers = snoc(ast->base_specifiers, baseSpec, _M_pool); - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseInitializer(InitializerAST *&node) -{ - std::size_t start = token_stream.cursor(); - - int tk = token_stream.lookAhead(); - if (tk != '=' && tk != '(') - return false; - - InitializerAST *ast = CreateNode<InitializerAST>(_M_pool); - - if (tk == '=') { - token_stream.nextToken(); - - if (!parseInitializerClause(ast->initializer_clause)) - reportError(QLatin1String("Initializer clause expected")); - - } else if (tk == '(') { - token_stream.nextToken(); - parseCommaExpression(ast->expression); - CHECK(')'); - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseMemInitializerList(const ListNode<MemInitializerAST*> *&node) -{ - MemInitializerAST *init = 0; - - if (!parseMemInitializer(init)) - return false; - - node = snoc(node, init, _M_pool); - - while (token_stream.lookAhead() == ',') { - token_stream.nextToken(); - - if (!parseMemInitializer(init)) - break; - - node = snoc(node, init, _M_pool); - } - - return true; -} - -bool Parser::parseMemInitializer(MemInitializerAST *&node) -{ - std::size_t start = token_stream.cursor(); - - NameAST *initId = 0; - if (!parseName(initId, true)) { - reportError(QLatin1String("Identifier expected")); - return false; - } - - ADVANCE('(', "("); - ExpressionAST *expr = 0; - parseCommaExpression(expr); - ADVANCE(')', ")"); - - MemInitializerAST *ast = CreateNode<MemInitializerAST>(_M_pool); - ast->initializer_id = initId; - ast->expression = expr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseTypeIdList(const ListNode<TypeIdAST*> *&node) -{ - TypeIdAST *typeId = 0; - if (!parseTypeId(typeId)) - return false; - - node = snoc(node, typeId, _M_pool); - - while (token_stream.lookAhead() == ',') { - token_stream.nextToken(); - if (parseTypeId(typeId)) { - node = snoc(node, typeId, _M_pool); - } else { - reportError(QLatin1String("Type id expected")); - break; - } - } - - return true; -} - -bool Parser::parseBaseSpecifier(BaseSpecifierAST *&node) -{ - std::size_t start = token_stream.cursor(); - - BaseSpecifierAST *ast = CreateNode<BaseSpecifierAST>(_M_pool); - - if (token_stream.lookAhead() == Token_virtual) { - ast->virt = token_stream.cursor(); - token_stream.nextToken(); - - int tk = token_stream.lookAhead(); - if (tk == Token_public || tk == Token_protected - || tk == Token_private) { - ast->access_specifier = token_stream.cursor(); - token_stream.nextToken(); - } - } else { - int tk = token_stream.lookAhead(); - if (tk == Token_public || tk == Token_protected - || tk == Token_private) { - ast->access_specifier = token_stream.cursor(); - token_stream.nextToken(); - } - - if (token_stream.lookAhead() == Token_virtual) { - ast->virt = token_stream.cursor(); - token_stream.nextToken(); - } - } - - if (!parseName(ast->name, true)) - reportError(QLatin1String("Class name expected")); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseInitializerClause(InitializerClauseAST *&node) -{ - std::size_t start = token_stream.cursor(); - - InitializerClauseAST *ast = CreateNode<InitializerClauseAST>(_M_pool); - - if (token_stream.lookAhead() == '{') { -#if defined(__GNUC__) -#warning "implement me" -#endif - if (skip('{', '}')) - token_stream.nextToken(); - else - reportError(QLatin1String("} missing")); - } else { - if (!parseAssignmentExpression(ast->expression)) - reportError(QLatin1String("Expression expected")); - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parsePtrToMember(PtrToMemberAST *&node) -{ -#if defined(__GNUC__) -#warning "implemente me (AST)" -#endif - - std::size_t start = token_stream.cursor(); - - if (token_stream.lookAhead() == Token_scope) { - token_stream.nextToken(); - } - - UnqualifiedNameAST *name = 0; - while (token_stream.lookAhead() == Token_identifier) { - if (!parseUnqualifiedName(name)) - break; - - if (token_stream.lookAhead() == Token_scope - && token_stream.lookAhead(1) == '*') { - token_stream.nextToken(); - token_stream.nextToken(); - - PtrToMemberAST *ast = CreateNode<PtrToMemberAST>(_M_pool); - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; - } - - if (token_stream.lookAhead() == Token_scope) - token_stream.nextToken(); - } - - token_stream.rewind((int) start); - return false; -} - -bool Parser::parseUnqualifiedName(UnqualifiedNameAST *&node, - bool parseTemplateId) -{ - std::size_t start = token_stream.cursor(); - - std::size_t tilde = 0; - std::size_t id = 0; - OperatorFunctionIdAST *operator_id = 0; - - if (token_stream.lookAhead() == Token_identifier) { - id = token_stream.cursor(); - token_stream.nextToken(); - } else if (token_stream.lookAhead() == '~' - && token_stream.lookAhead(1) == Token_identifier) { - tilde = token_stream.cursor(); - token_stream.nextToken(); // skip ~ - - id = token_stream.cursor(); - token_stream.nextToken(); // skip classname - } else if (token_stream.lookAhead() == Token_operator) { - if (!parseOperatorFunctionId(operator_id)) - return false; - } else { - return false; - } - - UnqualifiedNameAST *ast = CreateNode<UnqualifiedNameAST>(_M_pool); - ast->tilde = tilde; - ast->id = id; - ast->operator_id = operator_id; - - if (parseTemplateId && !tilde) { - std::size_t index = token_stream.cursor(); - - if (token_stream.lookAhead() == '<') { - token_stream.nextToken(); - - // optional template arguments - parseTemplateArgumentList(ast->template_arguments); - - if (token_stream.lookAhead() == '>') { - token_stream.nextToken(); - } else { - ast->template_arguments = 0; - token_stream.rewind((int) index); - } - } - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseStringLiteral(StringLiteralAST *&node) -{ - std::size_t start = token_stream.cursor(); - - if (token_stream.lookAhead() != Token_string_literal) - return false; - - StringLiteralAST *ast = CreateNode<StringLiteralAST>(_M_pool); - - while (token_stream.lookAhead() == Token_string_literal) { - ast->literals = snoc(ast->literals, token_stream.cursor(), _M_pool); - token_stream.nextToken(); - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseExpressionStatement(StatementAST *&node) -{ - std::size_t start = token_stream.cursor(); - - ExpressionAST *expr = 0; - parseCommaExpression(expr); - - ADVANCE(';', ";"); - - ExpressionStatementAST *ast = CreateNode<ExpressionStatementAST>(_M_pool); - ast->expression = expr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseStatement(StatementAST *&node) -{ - std::size_t start = token_stream.cursor(); - - switch (token_stream.lookAhead()) { - case Token_while: - return parseWhileStatement(node); - - case Token_do: - return parseDoStatement(node); - - case Token_for: - return parseForStatement(node); - - case Token_if: - return parseIfStatement(node); - - case Token_switch: - return parseSwitchStatement(node); - - case Token_try: - return parseTryBlockStatement(node); - - case Token_case: - case Token_default: - return parseLabeledStatement(node); - - case Token_break: - case Token_continue: -#if defined(__GNUC__) -#warning "implement me" -#endif - token_stream.nextToken(); - ADVANCE(';', ";"); - return true; - - case Token_goto: -#if defined(__GNUC__) -#warning "implement me" -#endif - token_stream.nextToken(); - ADVANCE(Token_identifier, "identifier"); - ADVANCE(';', ";"); - return true; - - case Token_return: { - token_stream.nextToken(); - ExpressionAST *expr = 0; - parseCommaExpression(expr); - - ADVANCE(';', ";"); - - ReturnStatementAST *ast = CreateNode<ReturnStatementAST>(_M_pool); - ast->expression = expr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - case '{': - return parseCompoundStatement(node); - - case Token_identifier: - if (parseLabeledStatement(node)) - return true; - break; - } - - return parseExpressionOrDeclarationStatement(node); -} - -bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node) -{ - bool blocked = block_errors(true); - - std::size_t start = token_stream.cursor(); - - StatementAST *decl_ast = 0; - bool maybe_amb = parseDeclarationStatement(decl_ast); - maybe_amb &= token_stream.kind(token_stream.cursor() - 1) == ';'; - - std::size_t end = token_stream.cursor(); - - token_stream.rewind((int) start); - StatementAST *expr_ast = 0; - maybe_amb &= parseExpressionStatement(expr_ast); - maybe_amb &= token_stream.kind(token_stream.cursor() - 1) == ';'; - - if (maybe_amb) { - Q_ASSERT(decl_ast && expr_ast); - ExpressionOrDeclarationStatementAST *ast = - CreateNode<ExpressionOrDeclarationStatementAST>(_M_pool); - ast->declaration = decl_ast; - ast->expression = expr_ast; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } else { - token_stream.rewind((int) std::max(end, token_stream.cursor())); - - node = decl_ast; - if (!node) - node = expr_ast; - } - - block_errors(blocked); - - if (!node) - syntaxError(); - - return node != 0; -} - -bool Parser::parseCondition(ConditionAST *&node, bool initRequired) -{ - std::size_t start = token_stream.cursor(); - - ConditionAST *ast = CreateNode<ConditionAST>(_M_pool); - TypeSpecifierAST *spec = 0; - - if (parseTypeSpecifier(spec)) { - ast->type_specifier = spec; - - std::size_t declarator_start = token_stream.cursor(); - - DeclaratorAST *decl = 0; - if (!parseDeclarator(decl)) { - token_stream.rewind((int) declarator_start); - if (!initRequired && !parseAbstractDeclarator(decl)) - decl = 0; - } - - if (decl && (!initRequired || token_stream.lookAhead() == '=')) { - ast->declarator = decl; - - if (token_stream.lookAhead() == '=') { - token_stream.nextToken(); - - parseExpression(ast->expression); - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; - } - } - - token_stream.rewind((int) start); - - if (!parseCommaExpression(ast->expression)) - return false; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - - -bool Parser::parseWhileStatement(StatementAST *&node) -{ - std::size_t start = token_stream.cursor(); - - ADVANCE(Token_while, "while"); - ADVANCE('(' , "("); - - ConditionAST *cond = 0; - if (!parseCondition(cond)) { - reportError(QLatin1String("condition expected")); - return false; - } - ADVANCE(')', ")"); - - StatementAST *body = 0; - if (!parseStatement(body)) { - reportError(QLatin1String("statement expected")); - return false; - } - - WhileStatementAST *ast = CreateNode<WhileStatementAST>(_M_pool); - ast->condition = cond; - ast->statement = body; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseDoStatement(StatementAST *&node) -{ - std::size_t start = token_stream.cursor(); - - ADVANCE(Token_do, "do"); - - StatementAST *body = 0; - if (!parseStatement(body)) { - reportError(QLatin1String("statement expected")); - //return false; - } - - ADVANCE_NR(Token_while, "while"); - ADVANCE_NR('(' , "("); - - ExpressionAST *expr = 0; - if (!parseCommaExpression(expr)) { - reportError(QLatin1String("expression expected")); - //return false; - } - - ADVANCE_NR(')', ")"); - ADVANCE_NR(';', ";"); - - DoStatementAST *ast = CreateNode<DoStatementAST>(_M_pool); - ast->statement = body; - ast->expression = expr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseForStatement(StatementAST *&node) -{ - std::size_t start = token_stream.cursor(); - - ADVANCE(Token_for, "for"); - ADVANCE('(', "("); - - StatementAST *init = 0; - if (!parseForInitStatement(init)) { - reportError(QLatin1String("for initialization expected")); - return false; - } - - ConditionAST *cond = 0; - parseCondition(cond); - ADVANCE(';', ";"); - - ExpressionAST *expr = 0; - parseCommaExpression(expr); - ADVANCE(')', ")"); - - StatementAST *body = 0; - if (!parseStatement(body)) - return false; - - ForStatementAST *ast = CreateNode<ForStatementAST>(_M_pool); - ast->init_statement = init; - ast->condition = cond; - ast->expression = expr; - ast->statement = body; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseForInitStatement(StatementAST *&node) -{ - if (parseDeclarationStatement(node)) - return true; - - return parseExpressionStatement(node); -} - -bool Parser::parseCompoundStatement(StatementAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK('{'); - - CompoundStatementAST *ast = CreateNode<CompoundStatementAST>(_M_pool); - - while (token_stream.lookAhead()) { - if (token_stream.lookAhead() == '}') - break; - - std::size_t startStmt = token_stream.cursor(); - - StatementAST *stmt = 0; - if (!parseStatement(stmt)) { - if (startStmt == token_stream.cursor()) - token_stream.nextToken(); - - skipUntilStatement(); - } else { - ast->statements = snoc(ast->statements, stmt, _M_pool); - } - } - - ADVANCE_NR('}', "}"); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseIfStatement(StatementAST *&node) -{ - std::size_t start = token_stream.cursor(); - - ADVANCE(Token_if, "if"); - - ADVANCE('(' , "("); - - IfStatementAST *ast = CreateNode<IfStatementAST>(_M_pool); - - ConditionAST *cond = 0; - if (!parseCondition(cond)) { - reportError(QLatin1String("condition expected")); - return false; - } - ADVANCE(')', ")"); - - StatementAST *stmt = 0; - if (!parseStatement(stmt)) { - reportError(QLatin1String("statement expected")); - return false; - } - - ast->condition = cond; - ast->statement = stmt; - - if (token_stream.lookAhead() == Token_else) { - token_stream.nextToken(); - - if (!parseStatement(ast->else_statement)) { - reportError(QLatin1String("statement expected")); - return false; - } - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseSwitchStatement(StatementAST *&node) -{ - std::size_t start = token_stream.cursor(); - ADVANCE(Token_switch, "switch"); - - ADVANCE('(' , "("); - - ConditionAST *cond = 0; - if (!parseCondition(cond)) { - reportError(QLatin1String("condition expected")); - return false; - } - ADVANCE(')', ")"); - - StatementAST *stmt = 0; - if (!parseCompoundStatement(stmt)) { - syntaxError(); - return false; - } - - SwitchStatementAST *ast = CreateNode<SwitchStatementAST>(_M_pool); - ast->condition = cond; - ast->statement = stmt; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseLabeledStatement(StatementAST *&node) -{ - switch (token_stream.lookAhead()) { - case Token_identifier: - case Token_default: - if (token_stream.lookAhead(1) == ':') { - token_stream.nextToken(); - token_stream.nextToken(); - - StatementAST *stmt = 0; - if (parseStatement(stmt)) { - node = stmt; - return true; - } - } - break; - - case Token_case: { - token_stream.nextToken(); - ExpressionAST *expr = 0; - if (!parseConstantExpression(expr)) { - reportError(QLatin1String("expression expected")); - } else if (token_stream.lookAhead() == Token_ellipsis) { - token_stream.nextToken(); - - ExpressionAST *expr2 = 0; - if (!parseConstantExpression(expr2)) - reportError(QLatin1String("expression expected")); - } - ADVANCE(':', ":"); - - StatementAST *stmt = 0; - if (parseStatement(stmt)) { - node = stmt; - return true; - } - } - break; - - } - - return false; -} - -bool Parser::parseBlockDeclaration(DeclarationAST *&node) -{ - switch (token_stream.lookAhead()) { - case Token_typedef: - return parseTypedef(node); - case Token_using: - return parseUsing(node); - case Token_asm: - return parseAsmDefinition(node); - case Token_namespace: - return parseNamespaceAliasDefinition(node); - } - - std::size_t start = token_stream.cursor(); - - const ListNode<std::size_t> *cv = 0; - parseCvQualify(cv); - - const ListNode<std::size_t> *storageSpec = 0; - parseStorageClassSpecifier(storageSpec); - - parseCvQualify(cv); - - TypeSpecifierAST *spec = 0; - if (!parseTypeSpecifierOrClassSpec(spec)) { // replace with simpleTypeSpecifier?!?! - token_stream.rewind((int) start); - return false; - } - - parseCvQualify(cv); - spec->cv = cv; - - const ListNode<InitDeclaratorAST*> *declarators = 0; - parseInitDeclaratorList(declarators); - - if (token_stream.lookAhead() != ';') { - token_stream.rewind((int) start); - return false; - } - token_stream.nextToken(); - - SimpleDeclarationAST *ast = CreateNode<SimpleDeclarationAST>(_M_pool); - ast->type_specifier = spec; - ast->init_declarators = declarators; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseNamespaceAliasDefinition(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_namespace); - - NamespaceAliasDefinitionAST *ast - = CreateNode<NamespaceAliasDefinitionAST>(_M_pool); - - ADVANCE(Token_identifier, "identifier"); - ast->namespace_name = token_stream.cursor() - 1; - - ADVANCE('=', "="); - - if (!parseName(ast->alias_name)) - reportError(QLatin1String("Namespace name expected")); - - ADVANCE(';', ";"); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseDeclarationStatement(StatementAST *&node) -{ - std::size_t start = token_stream.cursor(); - - DeclarationAST *decl = 0; - if (!parseBlockDeclaration(decl)) - return false; - - DeclarationStatementAST *ast = CreateNode<DeclarationStatementAST>(_M_pool); - ast->declaration = decl; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseDeclarationInternal(DeclarationAST *&node) -{ - std::size_t start = token_stream.cursor(); - - // that is for the case '__declspec(dllexport) int ...' or - // '__declspec(dllexport) inline int ...', etc. - WinDeclSpecAST *winDeclSpec = 0; - parseWinDeclSpec(winDeclSpec); - - const ListNode<std::size_t> *funSpec = 0; - bool hasFunSpec = parseFunctionSpecifier(funSpec); - - const ListNode<std::size_t> *cv = 0; - parseCvQualify(cv); - - const ListNode<std::size_t> *storageSpec = 0; - bool hasStorageSpec = parseStorageClassSpecifier(storageSpec); - - if (hasStorageSpec && !hasFunSpec) - hasFunSpec = parseFunctionSpecifier(funSpec); - - // that is for the case 'friend __declspec(dllexport) ....' - parseWinDeclSpec(winDeclSpec); - - if (!cv) - parseCvQualify(cv); - - int index = (int) token_stream.cursor(); - NameAST *name = 0; - if (parseName(name, true) && token_stream.lookAhead() == '(') { - // no type specifier, maybe a constructor or a cast operator?? - - token_stream.rewind((int) index); - - InitDeclaratorAST *declarator = 0; - if (parseInitDeclarator(declarator)) { - switch (token_stream.lookAhead()) { - case ';': { - token_stream.nextToken(); - - SimpleDeclarationAST *ast - = CreateNode<SimpleDeclarationAST>(_M_pool); - - ast->storage_specifiers = storageSpec; - ast->function_specifiers = funSpec; - ast->init_declarators = snoc(ast->init_declarators, - declarator, _M_pool); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - case ':': { - CtorInitializerAST *ctorInit = 0; - StatementAST *funBody = 0; - - if (parseCtorInitializer(ctorInit) - && parseFunctionBody(funBody)) { - FunctionDefinitionAST *ast - = CreateNode<FunctionDefinitionAST>(_M_pool); - - ast->storage_specifiers = storageSpec; - ast->function_specifiers = funSpec; - ast->init_declarator = declarator; - ast->function_body = funBody; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; - } - } - break; - - case '{': { - StatementAST *funBody = 0; - if (parseFunctionBody(funBody)) { - FunctionDefinitionAST *ast - = CreateNode<FunctionDefinitionAST>(_M_pool); - - ast->storage_specifiers = storageSpec; - ast->function_specifiers = funSpec; - ast->init_declarator = declarator; - ast->function_body = funBody; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; - } - } - break; - - case '(': - case '[': - // ops!! it seems a declarator - goto start_decl; - break; - } - - } - } - -start_decl: - token_stream.rewind((int) index); - - if (token_stream.lookAhead() == Token_const - && token_stream.lookAhead(1) == Token_identifier - && token_stream.lookAhead(2) == '=') { - // constant definition - token_stream.nextToken(); // skip const - - const ListNode<InitDeclaratorAST*> *declarators = 0; - if (!parseInitDeclaratorList(declarators)) { - syntaxError(); - return false; - } - - ADVANCE(';', ";"); - -#if defined(__GNUC__) -#warning "mark the ast as constant" -#endif - SimpleDeclarationAST *ast = CreateNode<SimpleDeclarationAST>(_M_pool); - ast->init_declarators = declarators; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; - } - - TypeSpecifierAST *spec = 0; - if (parseTypeSpecifier(spec)) { - Q_ASSERT(spec); - - if (!hasFunSpec) - parseFunctionSpecifier(funSpec); // e.g. "void inline" - - spec->cv = cv; - - const ListNode<InitDeclaratorAST*> *declarators = 0; - InitDeclaratorAST *decl = 0; - int startDeclarator = (int) token_stream.cursor(); - bool maybeFunctionDefinition = false; - - if (token_stream.lookAhead() != ';') { - if (parseInitDeclarator(decl) && token_stream.lookAhead() == '{') { - // function definition - maybeFunctionDefinition = true; - } else { - token_stream.rewind((int) startDeclarator); - if (!parseInitDeclaratorList(declarators)) { - syntaxError(); - return false; - } - } - } - - switch (token_stream.lookAhead()) { - case ';': { - token_stream.nextToken(); - SimpleDeclarationAST *ast - = CreateNode<SimpleDeclarationAST>(_M_pool); - - ast->storage_specifiers = storageSpec; - ast->function_specifiers = funSpec; - ast->type_specifier = spec; - ast->win_decl_specifiers = winDeclSpec; - ast->init_declarators = declarators; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - case '{': { - if (!maybeFunctionDefinition) { - syntaxError(); - return false; - } - - StatementAST *funBody = 0; - if (parseFunctionBody(funBody)) { - FunctionDefinitionAST *ast - = CreateNode<FunctionDefinitionAST>(_M_pool); - - ast->win_decl_specifiers = winDeclSpec; - ast->storage_specifiers = storageSpec; - ast->function_specifiers = funSpec; - ast->type_specifier = spec; - ast->init_declarator = decl; - ast->function_body = funBody; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; - } - } - break; - } // end switch - } - - syntaxError(); - return false; -} - -bool Parser::skipFunctionBody(StatementAST *&) -{ -#if defined(__GNUC__) -#warning "Parser::skipFunctionBody() -- implement me" -#endif - Q_ASSERT(0); // ### not implemented - return 0; -} - -bool Parser::parseFunctionBody(StatementAST *&node) -{ - if (control->skipFunctionBody()) - return skipFunctionBody(node); - - return parseCompoundStatement(node); -} - -bool Parser::parseTypeSpecifierOrClassSpec(TypeSpecifierAST *&node) -{ - if (parseClassSpecifier(node)) - return true; - else if (parseEnumSpecifier(node)) - return true; - else if (parseTypeSpecifier(node)) - return true; - - return false; -} - -bool Parser::parseTryBlockStatement(StatementAST *&node) -{ -#if defined(__GNUC__) -#warning "implement me" -#endif - CHECK(Token_try); - - StatementAST *stmt = 0; - if (!parseCompoundStatement(stmt)) { - syntaxError(); - return false; - } - - if (token_stream.lookAhead() != Token_catch) { - reportError(QLatin1String("catch expected")); - return false; - } - - while (token_stream.lookAhead() == Token_catch) { - token_stream.nextToken(); - ADVANCE('(', "("); - ConditionAST *cond = 0; - if (token_stream.lookAhead() == Token_ellipsis) { - token_stream.nextToken(); - } else if (!parseCondition(cond, false)) { - reportError(QLatin1String("condition expected")); - return false; - } - ADVANCE(')', ")"); - - StatementAST *body = 0; - if (!parseCompoundStatement(body)) { - syntaxError(); - return false; - } - } - - node = stmt; - return true; -} - -bool Parser::parsePrimaryExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - PrimaryExpressionAST *ast = CreateNode<PrimaryExpressionAST>(_M_pool); - - switch (token_stream.lookAhead()) { - case Token_string_literal: - parseStringLiteral(ast->literal); - break; - - case Token_number_literal: - case Token_char_literal: - case Token_true: - case Token_false: - case Token_this: - ast->token = token_stream.cursor(); - token_stream.nextToken(); - break; - - case '(': - token_stream.nextToken(); - - if (token_stream.lookAhead() == '{') { - if (!parseCompoundStatement(ast->expression_statement)) - return false; - } else { - if (!parseExpression(ast->sub_expression)) - return false; - } - - CHECK(')'); - break; - - default: - if (!parseName(ast->name)) - return false; - - break; - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - - -/* - postfix-expression-internal: - [ expression ] - ( expression-list [opt] ) - (.|->) template [opt] id-expression - (.|->) pseudo-destructor-name - ++ - -- -*/ -bool Parser::parsePostfixExpressionInternal(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - switch (token_stream.lookAhead()) { - case '[': { - token_stream.nextToken(); - ExpressionAST *expr = 0; - parseExpression(expr); - CHECK(']'); - - SubscriptExpressionAST *ast - = CreateNode<SubscriptExpressionAST>(_M_pool); - - ast->subscript = expr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - case '(': { - token_stream.nextToken(); - ExpressionAST *expr = 0; - parseExpression(expr); - CHECK(')'); - - FunctionCallAST *ast = CreateNode<FunctionCallAST>(_M_pool); - ast->arguments = expr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - case '.': - case Token_arrow: { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - std::size_t templ = 0; - if (token_stream.lookAhead() == Token_template) { - templ = token_stream.cursor(); - token_stream.nextToken(); - } - - int saved = int(token_stream.cursor()); - NameAST *name = 0; - - if (parseName(name, true) && name->unqualified_name - && name->unqualified_name->template_arguments - && token_stream.lookAhead() == '(') { - // a template method call - // ### reverse the logic - } else { - token_stream.rewind(saved); - name = 0; - - if (!parseName(name, templ != 0)) - return false; - } - - ClassMemberAccessAST *ast = CreateNode<ClassMemberAccessAST>(_M_pool); - ast->op = op; - ast->name = name; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - case Token_incr: - case Token_decr: { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - IncrDecrExpressionAST *ast = CreateNode<IncrDecrExpressionAST>(_M_pool); - ast->op = op; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - default: - return false; - } -} - -/* - postfix-expression: - simple-type-specifier ( expression-list [opt] ) - primary-expression postfix-expression-internal* -*/ -bool Parser::parsePostfixExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - switch (token_stream.lookAhead()) { - case Token_dynamic_cast: - case Token_static_cast: - case Token_reinterpret_cast: - case Token_const_cast: { - std::size_t castOp = token_stream.cursor(); - token_stream.nextToken(); - - CHECK('<'); - TypeIdAST *typeId = 0; - parseTypeId(typeId); - CHECK('>'); - - CHECK('('); - ExpressionAST *expr = 0; - parseCommaExpression(expr); - CHECK(')'); - - CppCastExpressionAST *ast = CreateNode<CppCastExpressionAST>(_M_pool); - ast->op = castOp; - ast->type_id = typeId; - ast->expression = expr; - - ExpressionAST *e = 0; - while (parsePostfixExpressionInternal(e)) - ast->sub_expressions = snoc(ast->sub_expressions, e, _M_pool); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - case Token_typename: { - std::size_t token = token_stream.cursor(); - token_stream.nextToken(); - - NameAST* name = 0; - if (!parseName(name, true)) - return false; - - CHECK('('); - ExpressionAST *expr = 0; - parseCommaExpression(expr); - CHECK(')'); - - TypeIdentificationAST *ast = CreateNode<TypeIdentificationAST>(_M_pool); - ast->typename_token = token; - ast->name = name; - ast->expression = expr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - case Token_typeid: { - token_stream.nextToken(); - - CHECK('('); - TypeIdAST *typeId = 0; - parseTypeId(typeId); - CHECK(')'); - - TypeIdentificationAST *ast = CreateNode<TypeIdentificationAST>(_M_pool); - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - default: - break; - } - - std::size_t saved_pos = token_stream.cursor(); - - TypeSpecifierAST *typeSpec = 0; - ExpressionAST *expr = 0; - - // let's try to parse a type - NameAST *name = 0; - if (parseName(name, true)) { - Q_ASSERT(name->unqualified_name); - - bool has_template_args = name->unqualified_name->template_arguments != 0; - - if (has_template_args && token_stream.lookAhead() == '(') { - ExpressionAST *cast_expr = 0; - if (parseCastExpression(cast_expr) - && cast_expr->kind == AST::Kind_CastExpression) { - token_stream.rewind((int) saved_pos); - parsePrimaryExpression(expr); - goto L_no_rewind; - } - } - } - - token_stream.rewind((int) saved_pos); - -L_no_rewind: - if (!expr && parseSimpleTypeSpecifier(typeSpec) - && token_stream.lookAhead() == '(') { - token_stream.nextToken(); // skip '(' - parseCommaExpression(expr); - CHECK(')'); - } else if (expr) { - typeSpec = 0; - } else { - typeSpec = 0; - token_stream.rewind((int) start); - - if (!parsePrimaryExpression(expr)) - return false; - } - - const ListNode<ExpressionAST*> *sub_expressions = 0; - ExpressionAST *sub_expression = 0; - - while (parsePostfixExpressionInternal(sub_expression)) - sub_expressions = snoc(sub_expressions, sub_expression, _M_pool); - - if (sub_expressions || !expr || (typeSpec && expr)) { - PostfixExpressionAST *ast = CreateNode<PostfixExpressionAST>(_M_pool); - ast->type_specifier = typeSpec; - ast->expression = expr; - ast->sub_expressions = sub_expressions; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } else - node = expr; - - return true; -} - -bool Parser::parseUnaryExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - switch (token_stream.lookAhead()) { - case Token_incr: - case Token_decr: - case '*': - case '&': - case '+': - case '-': - case '!': - case '~': { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *expr = 0; - if (!parseCastExpression(expr)) - return false; - - UnaryExpressionAST *ast = CreateNode<UnaryExpressionAST>(_M_pool); - ast->op = op; - ast->expression = expr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - return true; - - case Token_sizeof: { - std::size_t sizeof_token = token_stream.cursor(); - token_stream.nextToken(); - - SizeofExpressionAST *ast = CreateNode<SizeofExpressionAST>(_M_pool); - ast->sizeof_token = sizeof_token; - - std::size_t index = token_stream.cursor(); - if (token_stream.lookAhead() == '(') { - token_stream.nextToken(); - if (parseTypeId(ast->type_id) && token_stream.lookAhead() == ')') { - token_stream.nextToken(); // skip ) - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - return true; - } - - ast->type_id = 0; - token_stream.rewind((int) index); - } - - if (!parseUnaryExpression(ast->expression)) - return false; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - return true; - } - - default: - break; - } - - int token = token_stream.lookAhead(); - - if (token == Token_new - || (token == Token_scope && token_stream.lookAhead(1) == Token_new)) - return parseNewExpression(node); - - if (token == Token_delete - || (token == Token_scope && token_stream.lookAhead(1) == Token_delete)) - return parseDeleteExpression(node); - - return parsePostfixExpression(node); -} - -bool Parser::parseNewExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - NewExpressionAST *ast = CreateNode<NewExpressionAST>(_M_pool); - - if (token_stream.lookAhead() == Token_scope - && token_stream.lookAhead(1) == Token_new) { - ast->scope_token = token_stream.cursor(); - token_stream.nextToken(); - } - - CHECK(Token_new); - ast->new_token = token_stream.cursor() - 1; - - if (token_stream.lookAhead() == '(') { - token_stream.nextToken(); - parseCommaExpression(ast->expression); - CHECK(')'); - } - - if (token_stream.lookAhead() == '(') { - token_stream.nextToken(); - parseTypeId(ast->type_id); - CHECK(')'); - } else { - parseNewTypeId(ast->new_type_id); - } - - parseNewInitializer(ast->new_initializer); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseNewTypeId(NewTypeIdAST *&node) -{ - std::size_t start = token_stream.cursor(); - - TypeSpecifierAST *typeSpec = 0; - if (!parseTypeSpecifier(typeSpec)) - return false; - - NewTypeIdAST *ast = CreateNode<NewTypeIdAST>(_M_pool); - ast->type_specifier = typeSpec; - - parseNewDeclarator(ast->new_declarator); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseNewDeclarator(NewDeclaratorAST *&node) -{ - std::size_t start = token_stream.cursor(); - - NewDeclaratorAST *ast = CreateNode<NewDeclaratorAST>(_M_pool); - - PtrOperatorAST *ptrOp = 0; - if (parsePtrOperator(ptrOp)) { - ast->ptr_op = ptrOp; - parseNewDeclarator(ast->sub_declarator); - } - - while (token_stream.lookAhead() == '[') { - token_stream.nextToken(); - ExpressionAST *expr = 0; - parseExpression(expr); - ast->expressions = snoc(ast->expressions, expr, _M_pool); - ADVANCE(']', "]"); - } - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseNewInitializer(NewInitializerAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK('('); - - NewInitializerAST *ast = CreateNode<NewInitializerAST>(_M_pool); - - parseCommaExpression(ast->expression); - - CHECK(')'); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseDeleteExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - DeleteExpressionAST *ast = CreateNode<DeleteExpressionAST>(_M_pool); - - if (token_stream.lookAhead() == Token_scope - && token_stream.lookAhead(1) == Token_delete) { - ast->scope_token = token_stream.cursor(); - token_stream.nextToken(); - } - - CHECK(Token_delete); - ast->delete_token = token_stream.cursor() - 1; - - if (token_stream.lookAhead() == '[') { - ast->lbracket_token = token_stream.cursor(); - token_stream.nextToken(); - CHECK(']'); - ast->rbracket_token = token_stream.cursor() - 1; - } - - if (!parseCastExpression(ast->expression)) - return false; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseCastExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - if (token_stream.lookAhead() == '(') { - token_stream.nextToken(); - - CastExpressionAST *ast = CreateNode<CastExpressionAST>(_M_pool); - - if (parseTypeId(ast->type_id)) { - if (token_stream.lookAhead() == ')') { - token_stream.nextToken(); - - if (parseCastExpression(ast->expression)) { - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; - } - } - } - } - - token_stream.rewind((int) start); - return parseUnaryExpression(node); -} - -bool Parser::parsePmExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - if (!parseCastExpression(node) || !node) // ### fixme - return false; - - while (token_stream.lookAhead() == Token_ptrmem) { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseCastExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseMultiplicativeExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - if (!parsePmExpression(node)) - return false; - - while (token_stream.lookAhead() == '*' - || token_stream.lookAhead() == '/' - || token_stream.lookAhead() == '%') { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parsePmExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - - -bool Parser::parseAdditiveExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - if (!parseMultiplicativeExpression(node)) - return false; - - while (token_stream.lookAhead() == '+' || token_stream.lookAhead() == '-') { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseMultiplicativeExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseShiftExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - if (!parseAdditiveExpression(node)) - return false; - - while (token_stream.lookAhead() == Token_shift) { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseAdditiveExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseRelationalExpression(ExpressionAST *&node, bool templArgs) -{ - std::size_t start = token_stream.cursor(); - - if (!parseShiftExpression(node)) - return false; - - while (token_stream.lookAhead() == '<' - || (token_stream.lookAhead() == '>' && !templArgs) - || token_stream.lookAhead() == Token_leq - || token_stream.lookAhead() == Token_geq) { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseShiftExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseEqualityExpression(ExpressionAST *&node, bool templArgs) -{ - std::size_t start = token_stream.cursor(); - - if (!parseRelationalExpression(node, templArgs)) - return false; - - while (token_stream.lookAhead() == Token_eq - || token_stream.lookAhead() == Token_not_eq) { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseRelationalExpression(rightExpr, templArgs)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseAndExpression(ExpressionAST *&node, bool templArgs) -{ - std::size_t start = token_stream.cursor(); - - if (!parseEqualityExpression(node, templArgs)) - return false; - - while (token_stream.lookAhead() == '&') { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseEqualityExpression(rightExpr, templArgs)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseExclusiveOrExpression(ExpressionAST *&node, bool templArgs) -{ - std::size_t start = token_stream.cursor(); - - if (!parseAndExpression(node, templArgs)) - return false; - - while (token_stream.lookAhead() == '^') { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseAndExpression(rightExpr, templArgs)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseInclusiveOrExpression(ExpressionAST *&node, bool templArgs) -{ - std::size_t start = token_stream.cursor(); - - if (!parseExclusiveOrExpression(node, templArgs)) - return false; - - while (token_stream.lookAhead() == '|') { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseExclusiveOrExpression(rightExpr, templArgs)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseLogicalAndExpression(ExpressionAST *&node, bool templArgs) -{ - std::size_t start = token_stream.cursor(); - - if (!parseInclusiveOrExpression(node, templArgs)) - return false; - - while (token_stream.lookAhead() == Token_and) { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseInclusiveOrExpression(rightExpr, templArgs)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseLogicalOrExpression(ExpressionAST *&node, bool templArgs) -{ - std::size_t start = token_stream.cursor(); - - if (!parseLogicalAndExpression(node, templArgs)) - return false; - - while (token_stream.lookAhead() == Token_or) { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseLogicalAndExpression(rightExpr, templArgs)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseConditionalExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - if (!parseLogicalOrExpression(node)) - return false; - - if (token_stream.lookAhead() == '?') { - token_stream.nextToken(); - - ExpressionAST *leftExpr = 0; - if (!parseExpression(leftExpr)) - return false; - - CHECK(':'); - - ExpressionAST *rightExpr = 0; - if (!parseAssignmentExpression(rightExpr)) - return false; - - ConditionalExpressionAST *ast - = CreateNode<ConditionalExpressionAST>(_M_pool); - - ast->condition = node; - ast->left_expression = leftExpr; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseAssignmentExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - if (token_stream.lookAhead() == Token_throw && !parseThrowExpression(node)) - return false; - else if (!parseConditionalExpression(node)) - return false; - - while (token_stream.lookAhead() == Token_assign - || token_stream.lookAhead() == '=') { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseConditionalExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseConstantExpression(ExpressionAST *&node) -{ - return parseConditionalExpression(node); -} - -bool Parser::parseExpression(ExpressionAST *&node) -{ - return parseCommaExpression(node); -} - -bool Parser::parseCommaExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - if (!parseAssignmentExpression(node)) - return false; - - while (token_stream.lookAhead() == ',') { - std::size_t op = token_stream.cursor(); - token_stream.nextToken(); - - ExpressionAST *rightExpr = 0; - if (!parseAssignmentExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool); - ast->op = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - } - - return true; -} - -bool Parser::parseThrowExpression(ExpressionAST *&node) -{ - std::size_t start = token_stream.cursor(); - - CHECK(Token_throw); - - ThrowExpressionAST *ast = CreateNode<ThrowExpressionAST>(_M_pool); - ast->throw_token = token_stream.cursor() - 1; - - parseAssignmentExpression(ast->expression); - - UPDATE_POS(ast, start, token_stream.cursor()); - node = ast; - - return true; -} - -bool Parser::parseQ_ENUMS(DeclarationAST *&node) -{ - - if ((token_stream.lookAhead() != Token_Q_ENUMS) && - (token_stream.lookAhead() != Token_Q_ENUM)) - return false; - - if (token_stream.lookAhead(1) != '(') - return false; - - token_stream.nextToken(); - token_stream.nextToken(); - - int firstToken = token_stream.cursor(); - while (token_stream.lookAhead() != ')') - token_stream.nextToken(); - - QEnumsAST *ast = CreateNode<QEnumsAST>(_M_pool); - UPDATE_POS(ast, firstToken, token_stream.cursor()); - node = ast; - - token_stream.nextToken(); - - return true; -} - -bool Parser::parseQ_PROPERTY(DeclarationAST *&node) -{ - if (token_stream.lookAhead() != Token_Q_PROPERTY) - return false; - - if (token_stream.lookAhead(1) != '(') - return false; - - token_stream.nextToken(); - token_stream.nextToken(); - - int firstToken = token_stream.cursor(); - while (token_stream.lookAhead() != ')') - token_stream.nextToken(); - - QPropertyAST *ast = CreateNode<QPropertyAST>(_M_pool); - UPDATE_POS(ast, firstToken, token_stream.cursor()); - node = ast; - -// const Token &t1 = token_stream[firstToken]; -// const Token &t2 = token_stream[token_stream.cursor()]; -// printf("property: %s\n", -// qPrintable(QString::fromLatin1(t1.text + t1.position, t2.position - t1.position))); - - token_stream.nextToken(); - - return true; -} - -bool Parser::block_errors(bool block) -{ - bool current = _M_block_errors; - _M_block_errors = block; - return current; -} - -// kate: space-indent on; indent-width 2; replace-tabs on; - diff --git a/sources/shiboken2/ApiExtractor/parser/parser.h b/sources/shiboken2/ApiExtractor/parser/parser.h deleted file mode 100644 index 7aa5b9ad7..000000000 --- a/sources/shiboken2/ApiExtractor/parser/parser.h +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef PARSER_H -#define PARSER_H - -#include "ast.h" -#include "lexer.h" - -#include <QtCore/QString> - -class FileSymbol; -class Control; - -class Parser -{ -public: - Parser(Control *control); - ~Parser(); - - LocationManager &location() { return _M_location; } - - TranslationUnitAST *parse(const char *contents, std::size_t size, pool *p); - -private: - void reportError(const QString& msg); - void syntaxError(); - void tokenRequiredError(int expected); - -public: - bool skipFunctionBody(StatementAST *&node); - -public: - bool parse_Attribute__(); - bool parseAbstractDeclarator(DeclaratorAST *&node); - bool parseAccessSpecifier(DeclarationAST *&node); - bool parseAdditiveExpression(ExpressionAST *&node); - bool parseAndExpression(ExpressionAST *&node, bool templArgs = false); - bool parseAsmDefinition(DeclarationAST *&node); - bool parseAssignmentExpression(ExpressionAST *&node); - bool parseBaseClause(BaseClauseAST *&node); - bool parseBaseSpecifier(BaseSpecifierAST *&node); - bool parseBlockDeclaration(DeclarationAST *&node); - bool parseCastExpression(ExpressionAST *&node); - bool parseClassSpecifier(TypeSpecifierAST *&node); - bool parseForwardDeclarationSpecifier(TypeSpecifierAST *&node); - bool parseCommaExpression(ExpressionAST *&node); - bool parseCompoundStatement(StatementAST *&node); - bool parseCondition(ConditionAST *&node, bool initRequired = true); - bool parseConditionalExpression(ExpressionAST *&node); - bool parseConstantExpression(ExpressionAST *&node); - bool parseCtorInitializer(CtorInitializerAST *&node); - bool parseCvQualify(const ListNode<std::size_t> *&node); - bool parseDeclaration(DeclarationAST *&node); - bool parseDeclarationInternal(DeclarationAST *&node); - bool parseDeclarationStatement(StatementAST *&node); - bool parseDeclarator(DeclaratorAST *&node); - bool parseDeleteExpression(ExpressionAST *&node); - bool parseDoStatement(StatementAST *&node); - bool parseElaboratedTypeSpecifier(TypeSpecifierAST *&node); - bool parseEnumSpecifier(TypeSpecifierAST *&node); - bool parseEnumerator(EnumeratorAST *&node); - bool parseEqualityExpression(ExpressionAST *&node, - bool templArgs = false); - bool parseExceptionSpecification(ExceptionSpecificationAST *&node); - bool parseExclusiveOrExpression(ExpressionAST *&node, - bool templArgs = false); - bool parseExpression(ExpressionAST *&node); - bool parseExpressionOrDeclarationStatement(StatementAST *&node); - bool parseExpressionStatement(StatementAST *&node); - bool parseForInitStatement(StatementAST *&node); - bool parseForStatement(StatementAST *&node); - bool parseFunctionBody(StatementAST *&node); - bool parseFunctionSpecifier(const ListNode<std::size_t> *&node); - bool parseIfStatement(StatementAST *&node); - bool parseInclusiveOrExpression(ExpressionAST *&node, - bool templArgs = false); - bool parseInitDeclarator(InitDeclaratorAST *&node); - bool parseInitDeclaratorList(const ListNode<InitDeclaratorAST*> *&node); - bool parseInitializer(InitializerAST *&node); - bool parseInitializerClause(InitializerClauseAST *&node); - bool parseLabeledStatement(StatementAST *&node); - bool parseLinkageBody(LinkageBodyAST *&node); - bool parseLinkageSpecification(DeclarationAST *&node); - bool parseLogicalAndExpression(ExpressionAST *&node, - bool templArgs = false); - bool parseLogicalOrExpression(ExpressionAST *&node, - bool templArgs = false); - bool parseMemInitializer(MemInitializerAST *&node); - bool parseMemInitializerList(const ListNode<MemInitializerAST*> *&node); - bool parseMemberSpecification(DeclarationAST *&node); - bool parseMultiplicativeExpression(ExpressionAST *&node); - bool parseName(NameAST *&node, bool acceptTemplateId = false); - bool parseNamespace(DeclarationAST *&node); - bool parseNamespaceAliasDefinition(DeclarationAST *&node); - bool parseNewDeclarator(NewDeclaratorAST *&node); - bool parseNewExpression(ExpressionAST *&node); - bool parseNewInitializer(NewInitializerAST *&node); - bool parseNewTypeId(NewTypeIdAST *&node); - bool parseNoExcept(); - bool parseOperator(OperatorAST *&node); - bool parseOperatorFunctionId(OperatorFunctionIdAST *&node); - bool parseParameterDeclaration(ParameterDeclarationAST *&node); - bool parseParameterDeclarationClause(ParameterDeclarationClauseAST *&node); - bool parseParameterDeclarationList(const ListNode<ParameterDeclarationAST*> *&node); - bool parsePmExpression(ExpressionAST *&node); - bool parsePostfixExpression(ExpressionAST *&node); - bool parsePostfixExpressionInternal(ExpressionAST *&node); - bool parsePrimaryExpression(ExpressionAST *&node); - bool parsePtrOperator(PtrOperatorAST *&node); - bool parsePtrToMember(PtrToMemberAST *&node); - bool parseRelationalExpression(ExpressionAST *&node, - bool templArgs = false); - bool parseShiftExpression(ExpressionAST *&node); - bool parseSimpleTypeSpecifier(TypeSpecifierAST *&node, - bool onlyIntegral = false); - bool parseStatement(StatementAST *&node); - bool parseStorageClassSpecifier(const ListNode<std::size_t> *&node); - bool parseStringLiteral(StringLiteralAST *&node); - bool parseSwitchStatement(StatementAST *&node); - bool parseTemplateArgument(TemplateArgumentAST *&node); - bool parseTemplateArgumentList(const ListNode<TemplateArgumentAST*> *&node, - bool reportError = true); - bool parseTemplateDeclaration(DeclarationAST *&node); - bool parseTemplateParameter(TemplateParameterAST *&node); - bool parseTemplateParameterList(const ListNode<TemplateParameterAST*> *&node); - bool parseThrowExpression(ExpressionAST *&node); - bool parseTranslationUnit(TranslationUnitAST *&node); - bool parseTryBlockStatement(StatementAST *&node); - bool parseTypeId(TypeIdAST *&node); - bool parseTypeIdList(const ListNode<TypeIdAST*> *&node); - bool parseTypeParameter(TypeParameterAST *&node); - bool parseTypeSpecifier(TypeSpecifierAST *&node); - bool parseTypeSpecifierOrClassSpec(TypeSpecifierAST *&node); - bool parseTypedef(DeclarationAST *&node); - bool parseUnaryExpression(ExpressionAST *&node); - bool parseUnqualifiedName(UnqualifiedNameAST *&node, - bool parseTemplateId = true); - bool parseUsing(DeclarationAST *&node); - bool parseUsingDirective(DeclarationAST *&node); - bool parseWhileStatement(StatementAST *&node); - bool parseWinDeclSpec(WinDeclSpecAST *&node); - - bool parseQ_PROPERTY(DeclarationAST *&node); - bool parseQ_ENUMS(DeclarationAST *&node); - - bool skipUntil(int token); - bool skipUntilDeclaration(); - bool skipUntilStatement(); - bool skip(int l, int r); - - void advance(); - - // private: - TokenStream token_stream; - LocationTable location_table; - LocationTable line_table; - - bool block_errors(bool block); - -private: - QString tokenText(AST *) const; - - LocationManager _M_location; - Control *control; - Lexer lexer; - pool *_M_pool; - bool _M_block_errors; - -private: - Parser(const Parser& source); - void operator = (const Parser& source); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/r++.macros b/sources/shiboken2/ApiExtractor/parser/r++.macros deleted file mode 100644 index 455276c84..000000000 --- a/sources/shiboken2/ApiExtractor/parser/r++.macros +++ /dev/null @@ -1,28 +0,0 @@ - -#define __attribute__(a...) -#define __typeof__ __typeof - -#define __extension -#define __extension__ - -#define __restrict -#define __restrict__ - -#define __volatile volatile -#define __volatile__ volatile - -#define __inline inline -#define __inline__ inline - -#define __const const -#define __const__ const - -#define __asm asm -#define __asm__ asm - -#define __GNUC__ 3 -//#define __GNUC_MINOR__ 4 - -#define __ROBC__ 0 -#define __ROBC_MINOR__ 1 - diff --git a/sources/shiboken2/ApiExtractor/parser/rpp-allocator.h b/sources/shiboken2/ApiExtractor/parser/rpp-allocator.h deleted file mode 100644 index 4331ef7d4..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp-allocator.h +++ /dev/null @@ -1,29 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "parser/rxx_allocator.h" diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/builtin-macros.cpp b/sources/shiboken2/ApiExtractor/parser/rpp/builtin-macros.cpp deleted file mode 100644 index ccc150339..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/builtin-macros.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-cctype.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-cctype.h deleted file mode 100644 index d2e16b994..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-cctype.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_CCTYPE_H -#define PP_CCTYPE_H - -#include <cctype> - -namespace rpp -{ - -inline bool pp_isalpha(int __ch) -{ - return std::isalpha((unsigned char) __ch) != 0; -} - -inline bool pp_isalnum(int __ch) -{ - return std::isalnum((unsigned char) __ch) != 0; -} - -inline bool pp_isdigit(int __ch) -{ - return std::isdigit((unsigned char) __ch) != 0; -} - -inline bool pp_isspace(int __ch) -{ - return std::isspace((unsigned char) __ch) != 0; -} - -} // namespace rpp - -#endif // PP_CCTYPE_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-configuration b/sources/shiboken2/ApiExtractor/parser/rpp/pp-configuration deleted file mode 100644 index 15586dd88..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-configuration +++ /dev/null @@ -1,86 +0,0 @@ -#define __DBL_MIN_EXP__ (-1021) -#define __FLT_MIN__ 1.17549435e-38F -#define __CHAR_BIT__ 8 -#define __WCHAR_MAX__ 2147483647 -#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 -#define __FLT_EVAL_METHOD__ 2 -#define __DBL_MIN_10_EXP__ (-307) -#define __FINITE_MATH_ONLY__ 0 -#define __GNUC_PATCHLEVEL__ 2 -#define __SHRT_MAX__ 32767 -#define __LDBL_MAX__ 1.18973149535723176502e+4932L -#define __UINTMAX_TYPE__ long long unsigned int -#define __linux 1 -#define __unix 1 -#define __LDBL_MAX_EXP__ 16384 -#define __linux__ 1 -#define __SCHAR_MAX__ 127 -#define __USER_LABEL_PREFIX__ -#define __STDC_HOSTED__ 1 -#define __LDBL_HAS_INFINITY__ 1 -#define __DBL_DIG__ 15 -#define __FLT_EPSILON__ 1.19209290e-7F -#define __GXX_WEAK__ 1 -#define __LDBL_MIN__ 3.36210314311209350626e-4932L -#define __unix__ 1 -#define __DECIMAL_DIG__ 21 -#define __gnu_linux__ 1 -#define __LDBL_HAS_QUIET_NAN__ 1 -#define __GNUC__ 4 -#define __DBL_MAX__ 1.7976931348623157e+308 -#define __DBL_HAS_INFINITY__ 1 -#define __cplusplus 1 -#define __DEPRECATED 1 -#define __DBL_MAX_EXP__ 1024 -#define __GNUG__ 4 -#define __LONG_LONG_MAX__ 9223372036854775807LL -#define __GXX_ABI_VERSION 1002 -#define __FLT_MIN_EXP__ (-125) -#define __DBL_MIN__ 2.2250738585072014e-308 -#define __FLT_MIN_10_EXP__ (-37) -#define __DBL_HAS_QUIET_NAN__ 1 -#define __REGISTER_PREFIX__ -#define __NO_INLINE__ 1 -#define __i386 1 -#define __FLT_MANT_DIG__ 24 -#define __VERSION__ "4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu9)" -#define i386 1 -#define __i486__ 1 -#define unix 1 -#define __i386__ 1 -#define __SIZE_TYPE__ unsigned int -#define __ELF__ 1 -#define __FLT_RADIX__ 2 -#define __LDBL_EPSILON__ 1.08420217248550443401e-19L -#define __FLT_HAS_QUIET_NAN__ 1 -#define __FLT_MAX_10_EXP__ 38 -#define __LONG_MAX__ 2147483647L -#define __FLT_HAS_INFINITY__ 1 -#define linux 1 -#define __EXCEPTIONS 1 -#define __LDBL_MANT_DIG__ 64 -#define __WCHAR_TYPE__ int -#define __FLT_DIG__ 6 -#define __INT_MAX__ 2147483647 -#define __i486 1 -#define __FLT_MAX_EXP__ 128 -#define __DBL_MANT_DIG__ 53 -#define __WINT_TYPE__ unsigned int -#define __LDBL_MIN_EXP__ (-16381) -#define __LDBL_MAX_10_EXP__ 4932 -#define __DBL_EPSILON__ 2.2204460492503131e-16 -#define __tune_i486__ 1 -#define __INTMAX_MAX__ 9223372036854775807LL -#define __FLT_DENORM_MIN__ 1.40129846e-45F -#define __FLT_MAX__ 3.40282347e+38F -#define __INTMAX_TYPE__ long long int -#define __GNUC_MINOR__ 0 -#define __DBL_MAX_10_EXP__ 308 -#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L -#define __PTRDIFF_TYPE__ int -#define __LDBL_MIN_10_EXP__ (-4931) -#define __LDBL_DIG__ 18 -#define _GNU_SOURCE 1 - - -#define __STDC__ diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-engine-bits.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-engine-bits.h deleted file mode 100644 index 3d8aee029..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-engine-bits.h +++ /dev/null @@ -1,1300 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_ENGINE_BITS_H -#define PP_ENGINE_BITS_H - -#include "pp.h" -#include <sys/stat.h> -#include <cstdio> -#include <iostream> - -namespace rpp -{ - -inline std::string pp::fix_file_path(std::string const &filename) const -{ -#if defined (PP_OS_WIN) - std::string s = filename; - for (std::string::iterator it = s.begin(); it != s.end(); ++it) { - if (*it == '/') - *it = '\\'; - } - return s; -#else - return filename; -#endif -} - -inline bool pp::is_absolute(std::string const &filename) const -{ -#if defined(PP_OS_WIN) - return filename.length() >= 3 - && filename.at(1) == ':' - && (filename.at(2) == '\\' || filename.at(2) == '/'); -#else - return filename.length() >= 1 - && filename.at(0) == '/'; -#endif -} - -template <typename _OutputIterator> -void pp::file(std::string const &filename, _OutputIterator __result) -{ - FILE *fp = std::fopen(filename.c_str(), "rb"); - if (fp != 0) { - std::string was = env.current_file; - env.current_file = filename; - file(fp, __result); - env.current_file = was; - } - //else - //std::cerr << "** WARNING file ``" << filename << " not found!" << std::endl; -} - -template <typename _OutputIterator> -void pp::file(FILE *fp, _OutputIterator __result) -{ - assert(fp != 0); - -#if defined (HAVE_MMAP) - struct stat st; - fstat(FILENO(fp), &st); - std::size_t size = st.st_size; - char *buffer = 0; - buffer = (char *) ::mmap(0, size, PROT_READ, MAP_SHARED, FILENO(fp), 0); - fclose(fp); - if (!buffer || buffer == (char*) - 1) - return; - this->operator()(buffer, buffer + size, __result); - ::munmap(buffer, size); -#else - std::string buffer; - while (!feof(fp)) { - char tmp[1024]; - int read = (int) fread(tmp, sizeof(char), 1023, fp); - tmp[read] = '\0'; - buffer += tmp; - } - fclose(fp); - this->operator()(buffer.c_str(), buffer.c_str() + buffer.size(), __result); -#endif -} - -template <typename _InputIterator> -bool pp::find_header_protection(_InputIterator __first, _InputIterator __last, std::string *__prot) -{ - int was = env.current_line; - - while (__first != __last) { - if (pp_isspace(*__first)) { - if (*__first == '\n') - ++env.current_line; - - ++__first; - } else if (_PP_internal::comment_p(__first, __last)) { - __first = skip_comment_or_divop(__first, __last); - env.current_line += skip_comment_or_divop.lines; - } else if (*__first == '#') { - __first = skip_blanks(++__first, __last); - env.current_line += skip_blanks.lines; - - if (__first != __last && *__first == 'i') { - _InputIterator __begin = __first; - __first = skip_identifier(__begin, __last); - env.current_line += skip_identifier.lines; - - std::string __directive(__begin, __first); - - if (__directive == "ifndef") { - __first = skip_blanks(__first, __last); - env.current_line += skip_blanks.lines; - - __begin = __first; - __first = skip_identifier(__first, __last); - env.current_line += skip_identifier.lines; - - if (__begin != __first && __first != __last) { - __prot->assign(__begin, __first); - return true; - } - } - } - break; - } else - break; - } - - env.current_line = was; - return false; -} - -inline pp::PP_DIRECTIVE_TYPE pp::find_directive(char const *__directive, std::size_t __size) const -{ - switch (__size) { - case 0: - return PP_UNNAMED_DIRECTIVE; - case 2: - if (__directive[0] == 'i' - && __directive[1] == 'f') - return PP_IF; - break; - - case 4: - if (__directive[0] == 'e' && !strcmp(__directive, "elif")) - return PP_ELIF; - else if (__directive[0] == 'e' && !strcmp(__directive, "else")) - return PP_ELSE; - break; - - case 5: - if (__directive[0] == 'i' && !strcmp(__directive, "ifdef")) - return PP_IFDEF; - else if (__directive[0] == 'u' && !strcmp(__directive, "undef")) - return PP_UNDEF; - else if (__directive[0] == 'e') { - if (!strcmp(__directive, "endif")) - return PP_ENDIF; - else if (!strcmp(__directive, "error")) - return PP_ERROR; - } - break; - - case 6: - if (__directive[0] == 'i' && !strcmp(__directive, "ifndef")) - return PP_IFNDEF; - else if (__directive[0] == 'd' && !strcmp(__directive, "define")) - return PP_DEFINE; - else if (__directive[0] == 'p' && !strcmp(__directive, "pragma")) - return PP_PRAGMA; - break; - - case 7: - if (__directive[0] == 'i' && !strcmp(__directive, "include")) - return PP_INCLUDE; - else if (!strcmp(__directive, "warning")) - return PP_WARNING; - break; - - case 12: - if (__directive[0] == 'i' && !strcmp(__directive, "include_next")) - return PP_INCLUDE_NEXT; - break; - - default: - break; - } - std::cerr << "** WARNING unknown directive '#" << __directive << "' at " << env.current_file << ":" << env.current_line << std::endl; - return PP_UNKNOWN_DIRECTIVE; -} - -inline bool pp::file_isdir(std::string const &__filename) const -{ - struct stat __st; - if (stat(__filename.c_str(), &__st) == 0) -#if defined(PP_OS_WIN) - return (__st.st_mode & _S_IFDIR) == _S_IFDIR; -#else - return (__st.st_mode & S_IFDIR) == S_IFDIR; -#endif - else - return false; -} - -inline bool pp::file_exists(std::string const &__filename) const -{ - struct stat __st; - return stat(__filename.c_str(), &__st) == 0; -} - -inline FILE *pp::find_include_file(std::string const &__input_filename, std::string *__filepath, - INCLUDE_POLICY __include_policy, bool __skip_current_path) const -{ - assert(__filepath != 0); - assert(! __input_filename.empty()); - - __filepath->assign(__input_filename); - - if (is_absolute(*__filepath) && !file_isdir(*__filepath)) - return std::fopen(__filepath->c_str(), "r"); - - if (! env.current_file.empty()) - _PP_internal::extract_file_path(env.current_file, __filepath); - - if (__include_policy == INCLUDE_LOCAL && ! __skip_current_path) { - std::string __tmp(*__filepath); - __tmp += __input_filename; - - if (file_exists(__tmp) && !file_isdir(__tmp)) { - __filepath->append(__input_filename); - return std::fopen(__filepath->c_str(), "r"); - } - } - - std::vector<std::string>::const_iterator it = include_paths.begin(); - - if (__skip_current_path) { - it = std::find(include_paths.begin(), include_paths.end(), *__filepath); - - if (it != include_paths.end()) - ++it; - - else - it = include_paths.begin(); - } - - for (; it != include_paths.end(); ++it) { - if (__skip_current_path && it == include_paths.begin()) - continue; - - __filepath->assign(*it); - __filepath->append(__input_filename); - - if (file_exists(*__filepath) && !file_isdir(*__filepath)) - return std::fopen(__filepath->c_str(), "r"); - -#ifdef Q_OS_MAC - // try in Framework path on Mac, if there is a path in front - // ### what about escaped slashes? - size_t slashPos = __input_filename.find('/'); - if (slashPos != std::string::npos) { - __filepath->assign(*it); - __filepath->append(__input_filename.substr(0, slashPos)); - __filepath->append(".framework/Headers/"); - __filepath->append(__input_filename.substr(slashPos + 1, std::string::npos)); - - if (file_exists(*__filepath) && !file_isdir(*__filepath)) { - return fopen(__filepath->c_str(), "r"); - } - } -#endif // Q_OS_MAC - } - - return 0; -} - -template <typename _InputIterator, typename _OutputIterator> -_InputIterator pp::handle_directive(char const *__directive, std::size_t __size, - _InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - __first = skip_blanks(__first, __last); - - PP_DIRECTIVE_TYPE d = find_directive(__directive, __size); - switch (d) { - case PP_UNNAMED_DIRECTIVE: - /* There are many boost headers that include the character '#' - * at the beginning of any line and just do nothing else with - * that unnamed directive. Well, as that's not an error so - * we'll just ignore this unnamed directive for now. - */ - ++__last; - return ++__first; - case PP_DEFINE: - if (! skipping()) - return handle_define(__first, __last); - break; - - case PP_INCLUDE: - case PP_INCLUDE_NEXT: - if (! skipping()) - return handle_include(d == PP_INCLUDE_NEXT, __first, __last, __result); - break; - - case PP_UNDEF: - if (! skipping()) - return handle_undef(__first, __last); - break; - - case PP_ELIF: - return handle_elif(__first, __last); - - case PP_ELSE: - return handle_else(__first, __last); - - case PP_ENDIF: - return handle_endif(__first, __last); - - case PP_IF: - return handle_if(__first, __last); - - case PP_IFDEF: - return handle_ifdef(false, __first, __last); - - case PP_IFNDEF: - return handle_ifdef(true, __first, __last); - - default: - break; - } - - return __first; -} - -template <typename _InputIterator, typename _OutputIterator> -_InputIterator pp::handle_include(bool __skip_current_path, _InputIterator __first, _InputIterator __last, - _OutputIterator __result) -{ - if (pp_isalpha(*__first) || *__first == '_') { - pp_macro_expander expand_include(env); - std::string name; - name.reserve(255); - expand_include(__first, __last, std::back_inserter(name)); - std::string::iterator it = skip_blanks(name.begin(), name.end()); - if (it != name.end() && !(*it == '<' || *it == '"')) { - std::cerr << "** WARNING APIExtractor does not support the use " - "of #include directives without passing either " - "\"<path/to/header.h>\" or \"./path/to/header.h\", " - "for example. Invalid use at " << env.current_file - << ":" << env.current_line << "." << std::endl; - return __last; - } - - handle_include(__skip_current_path, it, name.end(), __result); - return __first; - } - - assert(*__first == '<' || *__first == '"'); - int quote = (*__first == '"') ? '"' : '>'; - ++__first; - - _InputIterator end_name = __first; - for (; end_name != __last; ++end_name) { - assert(*end_name != '\n'); - - if (*end_name == quote) - break; - } - - std::string filename(__first, end_name); - -#ifdef PP_OS_WIN - std::replace(filename.begin(), filename.end(), '/', '\\'); -#endif - - std::string filepath; - FILE *fp = find_include_file(filename, &filepath, quote == '>' ? INCLUDE_GLOBAL : INCLUDE_LOCAL, __skip_current_path); - -#if defined (PP_HOOK_ON_FILE_INCLUDED) - PP_HOOK_ON_FILE_INCLUDED(env.current_file, fp ? filepath : filename, fp); -#endif - - if (fp != 0) { - std::string old_file = env.current_file; - env.current_file = filepath; - int __saved_lines = env.current_line; - - env.current_line = 1; - //output_line (env.current_file, 1, __result); - - file(fp, __result); - - // restore the file name and the line position - env.current_file = old_file; - env.current_line = __saved_lines; - - // sync the buffer - _PP_internal::output_line(env.current_file, env.current_line, __result); - } -#ifndef RPP_JAMBI -// else -// std::cerr << "*** WARNING " << filename << ": No such file or directory" << std::endl; -#endif - - return __first; -} - -template <typename _InputIterator, typename _OutputIterator> -void pp::operator()(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ -#ifndef PP_NO_SMART_HEADER_PROTECTION - std::string __prot; - __prot.reserve(255); - pp_fast_string __tmp(__prot.c_str(), __prot.size()); - - if (find_header_protection(__first, __last, &__prot) - && env.resolve(&__tmp) != 0) { - // std::cerr << "** DEBUG found header protection:" << __prot << std::endl; - return; - } -#endif - - env.current_line = 1; - char __buffer[512]; - - while (true) { - __first = skip_blanks(__first, __last); - env.current_line += skip_blanks.lines; - - if (__first == __last) - break; - else if (*__first == '#') { - assert(*__first == '#'); - __first = skip_blanks(++__first, __last); - env.current_line += skip_blanks.lines; - - _InputIterator end_id = skip_identifier(__first, __last); - env.current_line += skip_identifier.lines; - std::size_t __size = end_id - __first; - - assert(__size < 512); - char *__cp = __buffer; - std::copy(__first, end_id, __cp); - __cp[__size] = '\0'; - - end_id = skip_blanks(end_id, __last); - __first = skip(end_id, __last); - - int was = env.current_line; - (void) handle_directive(__buffer, __size, end_id, __first, __result); - - if (env.current_line != was) { - env.current_line = was; - _PP_internal::output_line(env.current_file, env.current_line, __result); - } - } else if (*__first == '\n') { - // ### compress the line - *__result++ = *__first++; - ++env.current_line; - } else if (skipping()) - __first = skip(__first, __last); - else { - _PP_internal::output_line(env.current_file, env.current_line, __result); - __first = expand(__first, __last, __result); - env.current_line += expand.lines; - - if (expand.generated_lines) - _PP_internal::output_line(env.current_file, env.current_line, __result); - } - } -} - -inline pp::pp(pp_environment &__env): - env(__env), expand(env) -{ - iflevel = 0; - _M_skipping[iflevel] = 0; - _M_true_test[iflevel] = 0; -} - -inline std::back_insert_iterator<std::vector<std::string> > pp::include_paths_inserter() -{ - return std::back_inserter(include_paths); -} - -inline std::vector<std::string>::iterator pp::include_paths_begin() -{ - return include_paths.begin(); -} - -inline std::vector<std::string>::iterator pp::include_paths_end() -{ - return include_paths.end(); -} - -inline std::vector<std::string>::const_iterator pp::include_paths_begin() const -{ - return include_paths.begin(); -} - -inline std::vector<std::string>::const_iterator pp::include_paths_end() const -{ - return include_paths.end(); -} - -inline void pp::push_include_path(std::string const &__path) -{ - if (__path.empty() || __path [__path.size() - 1] != PATH_SEPARATOR) { - std::string __tmp(__path); - __tmp += PATH_SEPARATOR; - include_paths.push_back(__tmp); - } - - else - include_paths.push_back(__path); -} - -template <typename _InputIterator> -_InputIterator pp::handle_define(_InputIterator __first, _InputIterator __last) -{ - pp_macro macro; -#if defined (PP_WITH_MACRO_POSITION) - macro.file = pp_symbol::get(env.current_file); -#endif - std::string definition; - - __first = skip_blanks(__first, __last); - _InputIterator end_macro_name = skip_identifier(__first, __last); - pp_fast_string const *macro_name = pp_symbol::get(__first, end_macro_name); - __first = end_macro_name; - - if (__first != __last && *__first == '(') { - macro.function_like = true; - macro.formals.reserve(5); - - __first = skip_blanks(++__first, __last); // skip '(' - _InputIterator arg_end = skip_identifier(__first, __last); - if (__first != arg_end) - macro.formals.push_back(pp_symbol::get(__first, arg_end)); - - __first = skip_blanks(arg_end, __last); - - if (*__first == '.') { - macro.variadics = true; - while (*__first == '.') - ++__first; - } - - while (__first != __last && *__first == ',') { - __first = skip_blanks(++__first, __last); - - arg_end = skip_identifier(__first, __last); - if (__first != arg_end) - macro.formals.push_back(pp_symbol::get(__first, arg_end)); - - __first = skip_blanks(arg_end, __last); - - if (*__first == '.') { - macro.variadics = true; - while (*__first == '.') - ++__first; - } - } - - assert(*__first == ')'); - ++__first; - } - - __first = skip_blanks(__first, __last); - - /* Note: Sometimes one can include a path between brackets (for - * e.g., when defining a macro or so) so that we cannot simply - * ignore that. The in_path variable will handle this situation. - */ - bool in_path = false; - while (__first != __last && *__first != '\n') { - if ((*__first == '<' || *__first == '"') && - (*(__first + 1) != '*' && *(__first + 1) != '/')) { - in_path = true; - goto skip_path; - } - - if (in_path) { - if (*__first == '>' || *__first == '"') { - in_path = false; - goto skip_path; - } else if (*__first == ',' || *__first == ' ' || *__first == '\\') { - in_path = false; - continue; - } - } - - if (*__first == '/') { - if (*(__first + 1) != '*' && *(__first + 1) != '/') { - in_path = true; - goto skip_path; - } else { - __first = skip_comment_or_divop(__first, __last); - env.current_line += skip_comment_or_divop.lines; - if (__first == __last) - break; - } - } - - if (*__first == '\\') { - _InputIterator __begin = __first; - __begin = skip_blanks(++__begin, __last); - - if (__begin != __last && *__begin == '\n') { - ++macro.lines; - __first = skip_blanks(++__begin, __last); - definition += ' '; - continue; - } - } - -skip_path: - definition += *__first++; - } - - macro.definition = pp_symbol::get(definition); - env.bind(macro_name, macro); - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::skip(_InputIterator __first, _InputIterator __last) -{ - pp_skip_string_literal skip_string_literal; - pp_skip_char_literal skip_char_literal; - - while (__first != __last && *__first != '\n') { - if (*__first == '/') { - __first = skip_comment_or_divop(__first, __last); - env.current_line += skip_comment_or_divop.lines; - } else if (*__first == '"') { - __first = skip_string_literal(__first, __last); - env.current_line += skip_string_literal.lines; - } else if (*__first == '\'') { - __first = skip_char_literal(__first, __last); - env.current_line += skip_char_literal.lines; - } else if (*__first == '\\') { - __first = skip_blanks(++__first, __last); - env.current_line += skip_blanks.lines; - - if (__first != __last && *__first == '\n') { - ++__first; - ++env.current_line; - } - } else - ++__first; - } - - return __first; -} - -inline bool pp::test_if_level() -{ - bool result = !_M_skipping[iflevel++]; - _M_skipping[iflevel] = _M_skipping[iflevel - 1]; - _M_true_test[iflevel] = false; - return result; -} - -inline int pp::skipping() const -{ - return _M_skipping[iflevel]; -} - -template <typename _InputIterator> -_InputIterator pp::eval_primary(_InputIterator __first, _InputIterator __last, Value *result) -{ - bool expect_paren = false; - int token; - __first = next_token(__first, __last, &token); - - switch (token) { - case TOKEN_NUMBER: - result->set_long(token_value); - break; - - case TOKEN_UNUMBER: - result->set_ulong(token_uvalue); - break; - - case TOKEN_DEFINED: - __first = next_token(__first, __last, &token); - - if (token == '(') { - expect_paren = true; - __first = next_token(__first, __last, &token); - } - - if (token != TOKEN_IDENTIFIER) { - std::cerr << "** WARNING expected ``identifier'' found:" << char(token) << std::endl; - result->set_long(0); - break; - } - - result->set_long(env.resolve(token_text->c_str(), token_text->size()) != 0); - - next_token(__first, __last, &token); // skip '(' - - if (expect_paren) { - _InputIterator next = next_token(__first, __last, &token); - if (token != ')') - std::cerr << "** WARNING expected ``)''" << std::endl; - else - __first = next; - } - break; - - case TOKEN_IDENTIFIER: - result->set_long(0); - break; - - case '-': - __first = eval_primary(__first, __last, result); - result->set_long(- result->l); - return __first; - - case '+': - __first = eval_primary(__first, __last, result); - return __first; - - case '!': - __first = eval_primary(__first, __last, result); - result->set_long(result->is_zero()); - return __first; - - case '(': - __first = eval_constant_expression(__first, __last, result); - next_token(__first, __last, &token); - - if (token != ')') { - std::cerr << "** WARNING expected ``)'' = " << token << " (at " - << env.current_file << ":" << env.current_line - << ")." << std::endl; - } else { - __first = next_token(__first, __last, &token); - } - break; - - default: - result->set_long(0); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_multiplicative(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_primary(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '*' || token == '/' || token == '%') { - Value value; - __first = eval_primary(next, __last, &value); - - if (token == '*') - result->op_mult(value); - else if (token == '/') { - if (value.is_zero()) { - std::cerr << "** WARNING division by zero" << std::endl; - result->set_long(0); - } else - result->op_div(value); - } else { - if (value.is_zero()) { - std::cerr << "** WARNING division by zero" << std::endl; - result->set_long(0); - } else - result->op_mod(value); - } - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_additive(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_multiplicative(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '+' || token == '-') { - Value value; - __first = eval_multiplicative(next, __last, &value); - - if (token == '+') - result->op_add(value); - else - result->op_sub(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_shift(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_additive(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == TOKEN_LT_LT || token == TOKEN_GT_GT) { - Value value; - __first = eval_additive(next, __last, &value); - - if (token == TOKEN_LT_LT) - result->op_lhs(value); - else - result->op_rhs(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_relational(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_shift(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '<' - || token == '>' - || token == TOKEN_LT_EQ - || token == TOKEN_GT_EQ) { - Value value; - __first = eval_shift(next, __last, &value); - - switch (token) { - default: - assert(0); - break; - - case '<': - result->op_lt(value); - break; - - case '>': - result->op_gt(value); - break; - - case TOKEN_LT_EQ: - result->op_le(value); - break; - - case TOKEN_GT_EQ: - result->op_ge(value); - break; - } - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_equality(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_relational(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == TOKEN_EQ_EQ || token == TOKEN_NOT_EQ) { - Value value; - __first = eval_relational(next, __last, &value); - - if (token == TOKEN_EQ_EQ) - result->op_eq(value); - else - result->op_ne(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_and(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_equality(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '&') { - Value value; - __first = eval_equality(next, __last, &value); - result->op_bit_and(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_xor(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_and(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '^') { - Value value; - __first = eval_and(next, __last, &value); - result->op_bit_xor(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_or(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_xor(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '|') { - Value value; - __first = eval_xor(next, __last, &value); - result->op_bit_or(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_logical_and(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_or(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == TOKEN_AND_AND) { - Value value; - __first = eval_or(next, __last, &value); - result->op_and(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_logical_or(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_logical_and(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == TOKEN_OR_OR) { - Value value; - __first = eval_logical_and(next, __last, &value); - result->op_or(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_constant_expression(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_logical_or(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - if (token == '?') { - Value left_value; - __first = eval_constant_expression(next, __last, &left_value); - __first = skip_blanks(__first, __last); - - __first = next_token(__first, __last, &token); - if (token == ':') { - Value right_value; - __first = eval_constant_expression(__first, __last, &right_value); - - *result = !result->is_zero() ? left_value : right_value; - } else { - std::cerr << "** WARNING expected ``:'' = " << int (token) << std::endl; - *result = left_value; - } - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_expression(_InputIterator __first, _InputIterator __last, Value *result) -{ - return __first = eval_constant_expression(skip_blanks(__first, __last), __last, result); -} - -template <typename _InputIterator> -_InputIterator pp::handle_if(_InputIterator __first, _InputIterator __last) -{ - if (test_if_level()) { - pp_macro_expander expand_condition(env); - std::string condition; - condition.reserve(255); - expand_condition(skip_blanks(__first, __last), __last, std::back_inserter(condition)); - - Value result; - result.set_long(0); - eval_expression(condition.c_str(), condition.c_str() + condition.size(), &result); - - _M_true_test[iflevel] = !result.is_zero(); - _M_skipping[iflevel] = result.is_zero(); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::handle_else(_InputIterator __first, _InputIterator /*__last*/) -{ - if (iflevel == 0 && !skipping()) { - std::cerr << "** WARNING #else without #if" << std::endl; - } else if (iflevel > 0 && _M_skipping[iflevel - 1]) { - _M_skipping[iflevel] = true; - } else { - _M_skipping[iflevel] = _M_true_test[iflevel]; - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::handle_elif(_InputIterator __first, _InputIterator __last) -{ - assert(iflevel > 0); - - if (iflevel == 0 && !skipping()) { - std::cerr << "** WARNING #else without #if" << std::endl; - } else if (!_M_true_test[iflevel] && !_M_skipping[iflevel - 1]) { - Value result; - __first = eval_expression(__first, __last, &result); - _M_true_test[iflevel] = !result.is_zero(); - _M_skipping[iflevel] = result.is_zero(); - } else { - _M_skipping[iflevel] = true; - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::handle_endif(_InputIterator __first, _InputIterator /*__last*/) -{ - if (iflevel == 0 && !skipping()) { - std::cerr << "** WARNING #endif without #if" << std::endl; - } else { - _M_skipping[iflevel] = 0; - _M_true_test[iflevel] = 0; - - --iflevel; - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::handle_ifdef(bool check_undefined, _InputIterator __first, _InputIterator __last) -{ - if (test_if_level()) { - _InputIterator end_macro_name = skip_identifier(__first, __last); - - std::size_t __size; -#if defined(__SUNPRO_CC) - std::distance(__first, end_macro_name, __size); -#else - __size = std::distance(__first, end_macro_name); -#endif - assert(__size < 256); - - char __buffer [256]; - std::copy(__first, end_macro_name, __buffer); - - bool value = env.resolve(__buffer, __size) != 0; - - __first = end_macro_name; - - if (check_undefined) - value = !value; - - _M_true_test[iflevel] = value; - _M_skipping[iflevel] = !value; - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::handle_undef(_InputIterator __first, _InputIterator __last) -{ - __first = skip_blanks(__first, __last); - _InputIterator end_macro_name = skip_identifier(__first, __last); - assert(end_macro_name != __first); - - std::size_t __size; -#if defined(__SUNPRO_CC) - std::distance(__first, end_macro_name, __size); -#else - __size = std::distance(__first, end_macro_name); -#endif - - assert(__size < 256); - - char __buffer [256]; - std::copy(__first, end_macro_name, __buffer); - - pp_fast_string const __tmp(__buffer, __size); - env.unbind(&__tmp); - - __first = end_macro_name; - - return __first; -} - -template <typename _InputIterator> -char pp::peek_char(_InputIterator __first, _InputIterator __last) -{ - if (__first == __last) - return 0; - - return *++__first; -} - -template <typename _InputIterator> -_InputIterator pp::next_token(_InputIterator __first, _InputIterator __last, int *kind) -{ - __first = skip_blanks(__first, __last); - - if (__first == __last) { - *kind = 0; - return __first; - } - - char ch = *__first; - char ch2 = peek_char(__first, __last); - - switch (ch) { - case '/': - if (ch2 == '/' || ch2 == '*') { - __first = skip_comment_or_divop(__first, __last); - return next_token(__first, __last, kind); - } - ++__first; - *kind = '/'; - break; - - case '<': - ++__first; - if (ch2 == '<') { - ++__first; - *kind = TOKEN_LT_LT; - } else if (ch2 == '=') { - ++__first; - *kind = TOKEN_LT_EQ; - } else - *kind = '<'; - - return __first; - - case '>': - ++__first; - if (ch2 == '>') { - ++__first; - *kind = TOKEN_GT_GT; - } else if (ch2 == '=') { - ++__first; - *kind = TOKEN_GT_EQ; - } else - *kind = '>'; - - return __first; - - case '!': - ++__first; - if (ch2 == '=') { - ++__first; - *kind = TOKEN_NOT_EQ; - } else - *kind = '!'; - - return __first; - - case '=': - ++__first; - if (ch2 == '=') { - ++__first; - *kind = TOKEN_EQ_EQ; - } else - *kind = '='; - - return __first; - - case '|': - ++__first; - if (ch2 == '|') { - ++__first; - *kind = TOKEN_OR_OR; - } else - *kind = '|'; - - return __first; - - case '&': - ++__first; - if (ch2 == '&') { - ++__first; - *kind = TOKEN_AND_AND; - } else - *kind = '&'; - - return __first; - - default: - if (pp_isalpha(ch) || ch == '_') { - _InputIterator end = skip_identifier(__first, __last); - _M_current_text.assign(__first, end); - - token_text = &_M_current_text; - __first = end; - - if (*token_text == "defined") - *kind = TOKEN_DEFINED; - else - *kind = TOKEN_IDENTIFIER; - } else if (pp_isdigit(ch)) { - _InputIterator end = skip_number(__first, __last); - std::string __str(__first, __last); - char ch = __str [__str.size() - 1]; - if (ch == 'u' || ch == 'U') { - token_uvalue = strtoul(__str.c_str(), 0, 0); - *kind = TOKEN_UNUMBER; - } else { - token_value = strtol(__str.c_str(), 0, 0); - *kind = TOKEN_NUMBER; - } - __first = end; - } else - *kind = *__first++; - } - - return __first; -} - -} // namespace rpp - -#endif // PP_ENGINE_BITS_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-engine.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-engine.h deleted file mode 100644 index 689d7720e..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-engine.h +++ /dev/null @@ -1,288 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_ENGINE_H -#define PP_ENGINE_H - -#include <string> -#include <vector> -#include "pp-scanner.h" -#include "pp-macro-expander.h" -#include "pp-environment.h" - -namespace rpp -{ - -struct Value { - Value() : kind(Kind_Long), l(0) {} - - enum Kind { - Kind_Long, - Kind_ULong, - }; - - Kind kind; - - union { - long l; - unsigned long ul; - }; - - inline bool is_ulong() const { - return kind == Kind_ULong; - } - - inline void set_ulong(unsigned long v) { - ul = v; - kind = Kind_ULong; - } - - inline void set_long(long v) { - l = v; - kind = Kind_Long; - } - - inline bool is_zero() const { - return l == 0; - } - -#define PP_DEFINE_BIN_OP(name, op) \ - inline Value &name (const Value &other) \ - { \ - if (is_ulong () || other.is_ulong ()) \ - set_ulong (ul op other.ul); \ - else \ - set_long (l op other.l); \ - return *this; \ - } - - PP_DEFINE_BIN_OP(op_add, +) - PP_DEFINE_BIN_OP(op_sub, -) - PP_DEFINE_BIN_OP(op_mult, *) - PP_DEFINE_BIN_OP(op_div, /) - PP_DEFINE_BIN_OP(op_mod, %) - PP_DEFINE_BIN_OP(op_lhs, <<) - PP_DEFINE_BIN_OP(op_rhs, >>) - PP_DEFINE_BIN_OP(op_lt, <) - PP_DEFINE_BIN_OP(op_gt, >) - PP_DEFINE_BIN_OP(op_le, <=) - PP_DEFINE_BIN_OP(op_ge, >=) - PP_DEFINE_BIN_OP(op_eq, ==) - PP_DEFINE_BIN_OP(op_ne, !=) - PP_DEFINE_BIN_OP(op_bit_and, &) - PP_DEFINE_BIN_OP(op_bit_or, |) - PP_DEFINE_BIN_OP(op_bit_xor, ^) - PP_DEFINE_BIN_OP(op_and, &&) - PP_DEFINE_BIN_OP(op_or, ||) - -#undef PP_DEFINE_BIN_OP -}; - -class pp -{ - pp_environment &env; - pp_macro_expander expand; - pp_skip_identifier skip_identifier; - pp_skip_comment_or_divop skip_comment_or_divop; - pp_skip_blanks skip_blanks; - pp_skip_number skip_number; - std::vector<std::string> include_paths; - std::string _M_current_text; - - enum { MAX_LEVEL = 512 }; - int _M_skipping[MAX_LEVEL]; - int _M_true_test[MAX_LEVEL]; - int iflevel; - - union { - long token_value; - unsigned long token_uvalue; - std::string *token_text; - }; - - enum INCLUDE_POLICY { - INCLUDE_GLOBAL, - INCLUDE_LOCAL - }; - - enum TOKEN_TYPE { - TOKEN_NUMBER = 1000, - TOKEN_UNUMBER, - TOKEN_IDENTIFIER, - TOKEN_DEFINED, - TOKEN_LT_LT, - TOKEN_LT_EQ, - TOKEN_GT_GT, - TOKEN_GT_EQ, - TOKEN_EQ_EQ, - TOKEN_NOT_EQ, - TOKEN_OR_OR, - TOKEN_AND_AND, - }; - - enum PP_DIRECTIVE_TYPE { - PP_UNKNOWN_DIRECTIVE, - PP_UNNAMED_DIRECTIVE, - PP_DEFINE, - PP_INCLUDE, - PP_INCLUDE_NEXT, - PP_ELIF, - PP_ELSE, - PP_ENDIF, - PP_IF, - PP_IFDEF, - PP_IFNDEF, - PP_UNDEF, - PP_PRAGMA, - PP_ERROR, - PP_WARNING - }; - -public: - pp(pp_environment &__env); - - inline std::back_insert_iterator<std::vector<std::string> > include_paths_inserter(); - - inline void push_include_path(std::string const &__path); - - inline std::vector<std::string>::iterator include_paths_begin(); - inline std::vector<std::string>::iterator include_paths_end(); - - inline std::vector<std::string>::const_iterator include_paths_begin() const; - inline std::vector<std::string>::const_iterator include_paths_end() const; - - template <typename _InputIterator> - inline _InputIterator eval_expression(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _OutputIterator> - void file(std::string const &filename, _OutputIterator __result); - - template <typename _OutputIterator> - void file(FILE *fp, _OutputIterator __result); - - template <typename _InputIterator, typename _OutputIterator> - void operator()(_InputIterator __first, _InputIterator __last, _OutputIterator __result); - -private: - inline bool file_isdir(std::string const &__filename) const; - inline bool file_exists(std::string const &__filename) const; - FILE *find_include_file(std::string const &__filename, std::string *__filepath, - INCLUDE_POLICY __include_policy, bool __skip_current_path = false) const; - - inline int skipping() const; - bool test_if_level(); - - inline std::string fix_file_path(std::string const &filename) const; - inline bool is_absolute(std::string const &filename) const; - - PP_DIRECTIVE_TYPE find_directive(char const *__directive, std::size_t __size) const; - - template <typename _InputIterator> - bool find_header_protection(_InputIterator __first, _InputIterator __last, std::string *__prot); - - template <typename _InputIterator> - _InputIterator skip(_InputIterator __first, _InputIterator __last); - - template <typename _InputIterator> - _InputIterator eval_primary(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_multiplicative(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_additive(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_shift(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_relational(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_equality(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_and(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_xor(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_or(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_logical_and(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_logical_or(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator> - _InputIterator eval_constant_expression(_InputIterator __first, _InputIterator __last, Value *result); - - template <typename _InputIterator, typename _OutputIterator> - _InputIterator handle_directive(char const *__directive, std::size_t __size, - _InputIterator __first, _InputIterator __last, _OutputIterator __result); - - template <typename _InputIterator, typename _OutputIterator> - _InputIterator handle_include(bool skip_current_path, _InputIterator __first, _InputIterator __last, - _OutputIterator __result); - - template <typename _InputIterator> - _InputIterator handle_define(_InputIterator __first, _InputIterator __last); - - template <typename _InputIterator> - _InputIterator handle_if(_InputIterator __first, _InputIterator __last); - - template <typename _InputIterator> - _InputIterator handle_else(_InputIterator __first, _InputIterator __last); - - template <typename _InputIterator> - _InputIterator handle_elif(_InputIterator __first, _InputIterator __last); - - template <typename _InputIterator> - _InputIterator handle_endif(_InputIterator __first, _InputIterator __last); - - template <typename _InputIterator> - _InputIterator handle_ifdef(bool check_undefined, _InputIterator __first, _InputIterator __last); - - template <typename _InputIterator> - _InputIterator handle_undef(_InputIterator __first, _InputIterator __last); - - template <typename _InputIterator> - inline char peek_char(_InputIterator __first, _InputIterator __last); - - template <typename _InputIterator> - _InputIterator next_token(_InputIterator __first, _InputIterator __last, int *kind); -}; - -} // namespace rpp - -#endif // PP_ENGINE_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-environment.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-environment.h deleted file mode 100644 index 23f22e483..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-environment.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_ENVIRONMENT_H -#define PP_ENVIRONMENT_H - -#include <vector> -#include <string> -#include <cstring> -#include "pp-macro.h" - -namespace rpp -{ - -class pp_environment -{ -public: - typedef std::vector<pp_macro*>::const_iterator const_iterator; - -public: - pp_environment(): - current_line(0), - _M_hash_size(4093) { - _M_base = (pp_macro **) memset(new pp_macro* [_M_hash_size], 0, _M_hash_size * sizeof(pp_macro*)); - } - - ~pp_environment() { - for (std::size_t i = 0; i < _M_macros.size(); ++i) - delete _M_macros [i]; - - delete [] _M_base; - } - - const_iterator first_macro() const { - return _M_macros.begin(); - } - const_iterator last_macro() const { - return _M_macros.end(); - } - - inline void bind(pp_fast_string const *__name, pp_macro const &__macro) { - std::size_t h = hash_code(*__name) % _M_hash_size; - pp_macro *m = new pp_macro(__macro); - m->name = __name; - m->next = _M_base [h]; - m->hash_code = h; - _M_base [h] = m; - - _M_macros.push_back(m); - - if (_M_macros.size() == _M_hash_size) - rehash(); - } - - inline void unbind(pp_fast_string const *__name) { - if (pp_macro *m = resolve(__name)) - m->hidden = true; - } - - inline void unbind(char const *__s, std::size_t __size) { - pp_fast_string __tmp(__s, __size); - unbind(&__tmp); - } - - inline pp_macro *resolve(pp_fast_string const *__name) const { - std::size_t h = hash_code(*__name) % _M_hash_size; - pp_macro *it = _M_base [h]; - - while (it && it->name && it->hash_code == h && (*it->name != *__name || it->hidden)) - it = it->next; - - return it; - } - - inline pp_macro *resolve(char const *__data, std::size_t __size) const { - pp_fast_string const __tmp(__data, __size); - return resolve(&__tmp); - } - - std::string current_file; - int current_line; - -private: - inline std::size_t hash_code(pp_fast_string const &s) const { - std::size_t hash_value = 0; - - for (std::size_t i = 0; i < s.size(); ++i) - hash_value = (hash_value << 5) - hash_value + s.at(i); - - return hash_value; - } - - void rehash() { - delete[] _M_base; - - _M_hash_size <<= 1; - - _M_base = (pp_macro **) memset(new pp_macro* [_M_hash_size], 0, _M_hash_size * sizeof(pp_macro*)); - for (std::size_t index = 0; index < _M_macros.size(); ++index) { - pp_macro *elt = _M_macros [index]; - std::size_t h = hash_code(*elt->name) % _M_hash_size; - elt->next = _M_base [h]; - elt->hash_code = h; - _M_base [h] = elt; - } - } - -private: - std::vector<pp_macro*> _M_macros; - pp_macro **_M_base; - std::size_t _M_hash_size; -}; - -} // namespace rpp - -#endif // PP_ENVIRONMENT_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-fwd.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-fwd.h deleted file mode 100644 index 2814b6d44..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-fwd.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_FWD_H -#define PP_FWD_H - -namespace rpp -{ - -template <typename _CharT> class pp_string; - -typedef pp_string<char> pp_fast_string; - -} // namespace rpp - -#endif // PP_FWD_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-internal.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-internal.h deleted file mode 100644 index 33efa0c27..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-internal.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_INTERNAL_H -#define PP_INTERNAL_H - -#include <algorithm> -#include <string> -#include "pp.h" - -namespace rpp -{ - -namespace _PP_internal -{ - -inline void extract_file_path(const std::string &__filename, std::string *__filepath) -{ - std::size_t __index = __filename.rfind(PATH_SEPARATOR); - - if (__index == std::string::npos) - *__filepath = "/"; - - else - __filepath->assign(__filename, 0, __index + 1); -} - -template <typename _OutputIterator> -void output_line(const std::string &__filename, int __line, _OutputIterator __result) -{ - std::string __msg; - - __msg += "# "; - - char __line_descr[16]; - pp_snprintf(__line_descr, 16, "%d", __line); - __msg += __line_descr; - - __msg += " \""; - - if (__filename.empty()) - __msg += "<internal>"; - else - __msg += __filename; - - __msg += "\"\n"; - std::copy(__msg.begin(), __msg.end(), __result); -} - -template <typename _InputIterator> -inline bool comment_p(_InputIterator __first, _InputIterator __last) /*const*/ -{ - if (__first == __last) - return false; - - if (*__first != '/') - return false; - - if (++__first == __last) - return false; - - return (*__first == '/' || *__first == '*'); -} - -struct _Compare_string: public std::binary_function<bool, pp_fast_string const *, pp_fast_string const *> { - inline bool operator()(pp_fast_string const *__lhs, pp_fast_string const *__rhs) const { - return *__lhs < *__rhs; - } -}; - -struct _Equal_to_string: public std::binary_function<bool, pp_fast_string const *, pp_fast_string const *> { - inline bool operator()(pp_fast_string const *__lhs, pp_fast_string const *__rhs) const { - return *__lhs == *__rhs; - } -}; - -struct _Hash_string: public std::unary_function<std::size_t, pp_fast_string const *> { - inline std::size_t operator()(pp_fast_string const *__s) const { - char const *__ptr = __s->begin(); - std::size_t __size = __s->size(); - std::size_t __h = 0; - - for (std::size_t i = 0; i < __size; ++i) - __h = (__h << 5) - __h + __ptr [i]; - - return __h; - } -}; - -} // _PP_internal - -} // namespace rpp - -#endif // PP_INTERNAL_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-iterator.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-iterator.h deleted file mode 100644 index 35964fea4..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-iterator.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_ITERATOR_H -#define PP_ITERATOR_H - -#include <iterator> - -namespace rpp -{ - -class pp_null_output_iterator - : public std::iterator<std::output_iterator_tag, void, void, void, void> -{ -public: - pp_null_output_iterator() {} - - template <typename _Tp> - pp_null_output_iterator &operator=(_Tp const &) { - return *this; - } - - inline pp_null_output_iterator &operator *() { - return *this; - } - inline pp_null_output_iterator &operator ++ () { - return *this; - } - inline pp_null_output_iterator operator ++ (int) { - return *this; - } -}; - -template <typename _Container> -class pp_output_iterator - : public std::iterator<std::output_iterator_tag, void, void, void, void> -{ - std::string &_M_result; - -public: - explicit pp_output_iterator(std::string &__result): - _M_result(__result) {} - - inline pp_output_iterator<_Container>& operator=(const pp_output_iterator<_Container>& other) - { - _M_result = other._M_result; - return *this; - } - - inline pp_output_iterator &operator=(typename _Container::const_reference __v) { - if (_M_result.capacity() == _M_result.size()) - _M_result.reserve(_M_result.capacity() << 2); - - _M_result.push_back(__v); - return *this; - } - - inline pp_output_iterator &operator *() { - return *this; - } - inline pp_output_iterator &operator ++ () { - return *this; - } - inline pp_output_iterator operator ++ (int) { - return *this; - } -}; - -} // namespace rpp - -#endif // PP_ITERATOR_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-macro-expander.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-macro-expander.h deleted file mode 100644 index db93c3214..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-macro-expander.h +++ /dev/null @@ -1,356 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_MACRO_EXPANDER_H -#define PP_MACRO_EXPANDER_H - -namespace rpp -{ - -struct pp_frame { - pp_macro *expanding_macro; - std::vector<std::string> *actuals; - - pp_frame(pp_macro *__expanding_macro, std::vector<std::string> *__actuals): - expanding_macro(__expanding_macro), actuals(__actuals) {} -}; - -class pp_macro_expander -{ - pp_environment &env; - pp_frame *frame; - - pp_skip_number skip_number; - pp_skip_identifier skip_identifier; - pp_skip_string_literal skip_string_literal; - pp_skip_char_literal skip_char_literal; - pp_skip_argument skip_argument; - pp_skip_comment_or_divop skip_comment_or_divop; - pp_skip_blanks skip_blanks; - pp_skip_whitespaces skip_whitespaces; - - std::string const *resolve_formal(pp_fast_string const *__name) { - assert(__name != 0); - - if (! frame) - return 0; - - assert(frame->expanding_macro != 0); - - std::vector<pp_fast_string const *> const formals = frame->expanding_macro->formals; - for (std::size_t index = 0; index < formals.size(); ++index) { - pp_fast_string const *formal = formals[index]; - - if (*formal != *__name) - continue; - - else if (frame->actuals && index < frame->actuals->size()) - return &(*frame->actuals)[index]; - - else - assert(0); // internal error? - } - - return 0; - } - -public: // attributes - int lines; - int generated_lines; - -public: - pp_macro_expander(pp_environment &__env, pp_frame *__frame = 0): - env(__env), frame(__frame), lines(0), generated_lines(0) {} - - template <typename _InputIterator, typename _OutputIterator> - _InputIterator operator()(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { - generated_lines = 0; - __first = skip_blanks(__first, __last); - lines = skip_blanks.lines; - - while (__first != __last) { - if (*__first == '\n') { - *__result++ = *__first; - ++lines; - - __first = skip_blanks(++__first, __last); - lines += skip_blanks.lines; - - if (__first != __last && *__first == '#') - break; - } else if (*__first == '#') { - __first = skip_blanks(++__first, __last); - lines += skip_blanks.lines; - - _InputIterator end_id = skip_identifier(__first, __last); - - // ### rewrite: not safe - char name_buffer[512], *cp = name_buffer; - std::copy(__first, end_id, cp); - std::size_t name_size = end_id - __first; - name_buffer[name_size] = '\0'; - - pp_fast_string fast_name(name_buffer, name_size); - - if (std::string const *actual = resolve_formal(&fast_name)) { - *__result++ = '\"'; - - for (std::string::const_iterator it = skip_whitespaces(actual->begin(), actual->end()); - it != actual->end(); ++it) { - if (*it == '"') { - *__result++ = '\\'; - *__result++ = *it; - } - - else if (*it == '\n') { - *__result++ = '"'; - *__result++ = '\n'; - *__result++ = '"'; - } - - else - *__result++ = *it; - } - - *__result++ = '\"'; - __first = end_id; - } else - *__result++ = '#'; // ### warning message? - } else if (*__first == '\"') { - _InputIterator next_pos = skip_string_literal(__first, __last); - lines += skip_string_literal.lines; - std::copy(__first, next_pos, __result); - __first = next_pos; - } else if (*__first == '\'') { - _InputIterator next_pos = skip_char_literal(__first, __last); - lines += skip_char_literal.lines; - std::copy(__first, next_pos, __result); - __first = next_pos; - } else if (_PP_internal::comment_p(__first, __last)) { - __first = skip_comment_or_divop(__first, __last); - int n = skip_comment_or_divop.lines; - lines += n; - - while (n-- > 0) - *__result++ = '\n'; - } else if (pp_isspace(*__first)) { - for (; __first != __last; ++__first) { - if (*__first == '\n' || !pp_isspace(*__first)) - break; - } - - *__result = ' '; - } else if (pp_isdigit(*__first)) { - _InputIterator next_pos = skip_number(__first, __last); - lines += skip_number.lines; - std::copy(__first, next_pos, __result); - __first = next_pos; - } else if (pp_isalpha(*__first) || *__first == '_') { - _InputIterator name_begin = __first; - _InputIterator name_end = skip_identifier(__first, __last); - __first = name_end; // advance - - // search for the paste token - _InputIterator next = skip_blanks(__first, __last); - if (next != __last && *next == '#') { - ++next; - if (next != __last && *next == '#') - __first = skip_blanks(++next, __last); - } - - // ### rewrite: not safe - - std::ptrdiff_t name_size; -#if defined(__SUNPRO_CC) - std::distance(name_begin, name_end, name_size); -#else - name_size = std::distance(name_begin, name_end); -#endif - assert(name_size >= 0 && name_size < 512); - - char name_buffer[512], *cp = name_buffer; - std::size_t __size = name_end - name_begin; - std::copy(name_begin, name_end, cp); - name_buffer[__size] = '\0'; - - pp_fast_string fast_name(name_buffer, name_size); - - if (std::string const *actual = resolve_formal(&fast_name)) { - std::copy(actual->begin(), actual->end(), __result); - continue; - } - - static bool hide_next = false; // ### remove me - - pp_macro *macro = env.resolve(name_buffer, name_size); - if (! macro || macro->hidden || hide_next) { - hide_next = ! strcmp(name_buffer, "defined"); - - if (__size == 8 && name_buffer [0] == '_' && name_buffer [1] == '_') { - if (! strcmp(name_buffer, "__LINE__")) { - char buf [16]; - char *end = buf + pp_snprintf(buf, 16, "%d", env.current_line + lines); - - std::copy(&buf [0], end, __result); - continue; - } - - else if (! strcmp(name_buffer, "__FILE__")) { - __result++ = '"'; - std::copy(env.current_file.begin(), env.current_file.end(), __result); // ### quote - __result++ = '"'; - continue; - } - } - - std::copy(name_begin, name_end, __result); - continue; - } - - if (! macro->function_like) { - pp_macro *m = 0; - - if (macro->definition) { - macro->hidden = true; - - std::string __tmp; - __tmp.reserve(256); - - pp_macro_expander expand_macro(env); - expand_macro(macro->definition->begin(), macro->definition->end(), std::back_inserter(__tmp)); - generated_lines += expand_macro.lines; - - if (! __tmp.empty()) { - std::string::iterator __begin_id = skip_whitespaces(__tmp.begin(), __tmp.end()); - std::string::iterator __end_id = skip_identifier(__begin_id, __tmp.end()); - - if (__end_id == __tmp.end()) { - std::string __id; - __id.assign(__begin_id, __end_id); - - std::size_t x; -#if defined(__SUNPRO_CC) - std::distance(__begin_id, __end_id, x); -#else - x = std::distance(__begin_id, __end_id); -#endif - m = env.resolve(__id.c_str(), x); - } - - if (! m) - std::copy(__tmp.begin(), __tmp.end(), __result); - } - - macro->hidden = false; - } - - if (! m) - continue; - - macro = m; - } - - // function like macro - _InputIterator arg_it = skip_whitespaces(__first, __last); - - if (arg_it == __last || *arg_it != '(') { - std::copy(name_begin, name_end, __result); - lines += skip_whitespaces.lines; - __first = arg_it; - continue; - } - - std::vector<std::string> actuals; - actuals.reserve(5); - ++arg_it; // skip '(' - - pp_macro_expander expand_actual(env, frame); - - _InputIterator arg_end = skip_argument_variadics(actuals, macro, arg_it, __last); - if (arg_it != arg_end) { - std::string actual(arg_it, arg_end); - actuals.resize(actuals.size() + 1); - actuals.back().reserve(255); - expand_actual(actual.begin(), actual.end(), std::back_inserter(actuals.back())); - arg_it = arg_end; - } - - while (arg_it != __last && *arg_end == ',') { - ++arg_it; // skip ',' - - arg_end = skip_argument_variadics(actuals, macro, arg_it, __last); - std::string actual(arg_it, arg_end); - actuals.resize(actuals.size() + 1); - actuals.back().reserve(255); - expand_actual(actual.begin(), actual.end(), std::back_inserter(actuals.back())); - arg_it = arg_end; - } - - assert(arg_it != __last && *arg_it == ')'); - - ++arg_it; // skip ')' - __first = arg_it; - -#if 0 // ### enable me - assert((macro->variadics && macro->formals.size() >= actuals.size()) - || macro->formals.size() == actuals.size()); -#endif - - pp_frame frame(macro, &actuals); - pp_macro_expander expand_macro(env, &frame); - macro->hidden = true; - expand_macro(macro->definition->begin(), macro->definition->end(), __result); - macro->hidden = false; - generated_lines += expand_macro.lines; - } else - *__result++ = *__first++; - } - - return __first; - } - - template <typename _InputIterator> - _InputIterator skip_argument_variadics(std::vector<std::string> const &__actuals, pp_macro *__macro, - _InputIterator __first, _InputIterator __last) { - _InputIterator arg_end = skip_argument(__first, __last); - - while (__macro->variadics && __first != arg_end && arg_end != __last && *arg_end == ',' - && (__actuals.size() + 1) == __macro->formals.size()) { - arg_end = skip_argument(++arg_end, __last); - } - - return arg_end; - } -}; - -} // namespace rpp - -#endif // PP_MACRO_EXPANDER_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-macro.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-macro.h deleted file mode 100644 index 9e95840a1..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-macro.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_MACRO_H -#define PP_MACRO_H - -#include <vector> -#include "pp-fwd.h" - -namespace rpp -{ - -struct pp_macro { -#if defined (PP_WITH_MACRO_POSITION) - pp_fast_string const *file; -#endif - pp_fast_string const *name; - pp_fast_string const *definition; - std::vector<pp_fast_string const *> formals; - - union { - int unsigned state; - - struct { - int unsigned hidden: 1; - int unsigned function_like: 1; - int unsigned variadics: 1; - }; - }; - - int lines; - pp_macro *next; - std::size_t hash_code; - - inline pp_macro(): -#if defined (PP_WITH_MACRO_POSITION) - file(0), -#endif - name(0), - definition(0), - state(0), - lines(0), - next(0), - hash_code(0) {} -}; - -} // namespace rpp - -#endif // PP_MACRO_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-qt-configuration b/sources/shiboken2/ApiExtractor/parser/rpp/pp-qt-configuration deleted file mode 100644 index ba356c323..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-qt-configuration +++ /dev/null @@ -1,24 +0,0 @@ -#define __cplusplus 1 - -#define __STDC__ 1 - -// Qt -#define QOBJECTDEFS_H - -// not yet supported -#define Q_SLOTS slots -#define Q_SIGNALS signals -#define Q_FLAGS(a) -#define Q_PRIVATE_SLOT(a, b) -#define Q_DECLARE_INTERFACE(a,b) -#define Q_INTERFACES(a) -#define Q_GADGET -#define Q_OVERRIDE(a) -#define Q_OS_OS2 -#define Q_NO_USING_KEYWORD -#define QT_NO_QOBJECT_CHECK -#define QT_NO_MEMBER_TEMPLATES -// There are symbols in Qt that exist in Debug but -// not in release -#define QT_NO_DEBUG - diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-scanner.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-scanner.h deleted file mode 100644 index 0c5007e0f..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-scanner.h +++ /dev/null @@ -1,318 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_SCANNER_H -#define PP_SCANNER_H - -#include "pp-cctype.h" -#include <cassert> - -namespace rpp -{ - -struct pp_skip_blanks { - int lines; - - template <typename _InputIterator> - _InputIterator operator()(_InputIterator __first, _InputIterator __last) { - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { - if (*__first == '\\') { - _InputIterator __begin = __first; - ++__begin; - - if (__begin != __last && *__begin == '\n') - ++__first; - else - break; - } else if (*__first == '\n' || !pp_isspace(*__first)) - break; - } - - return __first; - } -}; - -struct pp_skip_whitespaces { - int lines; - - template <typename _InputIterator> - _InputIterator operator()(_InputIterator __first, _InputIterator __last) { - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { - if (! pp_isspace(*__first)) - break; - } - - return __first; - } -}; - -struct pp_skip_comment_or_divop { - int lines; - - template <typename _InputIterator> - _InputIterator operator()(_InputIterator __first, _InputIterator __last) { - enum { - MAYBE_BEGIN, - BEGIN, - MAYBE_END, - END, - IN_COMMENT, - IN_CXX_COMMENT - } state(MAYBE_BEGIN); - - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { - switch (state) { - default: - assert(0); - break; - - case MAYBE_BEGIN: - if (*__first != '/') - return __first; - - state = BEGIN; - break; - - case BEGIN: - if (*__first == '*') - state = IN_COMMENT; - else if (*__first == '/') - state = IN_CXX_COMMENT; - else - return __first; - break; - - case IN_COMMENT: - if (*__first == '*') - state = MAYBE_END; - break; - - case IN_CXX_COMMENT: - if (*__first == '\n') - return __first; - break; - - case MAYBE_END: - if (*__first == '/') - state = END; - else if (*__first != '*') - state = IN_COMMENT; - break; - - case END: - return __first; - } - } - - return __first; - } -}; - -struct pp_skip_identifier { - int lines; - - template <typename _InputIterator> - _InputIterator operator()(_InputIterator __first, _InputIterator __last) { - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { - if (! pp_isalnum(*__first) && *__first != '_') - break; - } - - return __first; - } -}; - -struct pp_skip_number { - int lines; - - template <typename _InputIterator> - _InputIterator operator()(_InputIterator __first, _InputIterator __last) { - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { - if (! pp_isalnum(*__first) && *__first != '.') - break; - } - - return __first; - } -}; - -struct pp_skip_string_literal { - int lines; - - template <typename _InputIterator> - _InputIterator operator()(_InputIterator __first, _InputIterator __last) { - enum { - BEGIN, - IN_STRING, - QUOTE, - END - } state(BEGIN); - - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { - switch (state) { - default: - assert(0); - break; - - case BEGIN: - if (*__first != '\"') - return __first; - state = IN_STRING; - break; - - case IN_STRING: - assert(*__first != '\n'); - - if (*__first == '\"') - state = END; - else if (*__first == '\\') - state = QUOTE; - break; - - case QUOTE: - state = IN_STRING; - break; - - case END: - return __first; - } - } - - return __first; - } -}; - -struct pp_skip_char_literal { - int lines; - - template <typename _InputIterator> - _InputIterator operator()(_InputIterator __first, _InputIterator __last) { - enum { - BEGIN, - IN_STRING, - QUOTE, - END - } state(BEGIN); - - lines = 0; - - for (; state != END && __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { - switch (state) { - default: - assert(0); - break; - - case BEGIN: - if (*__first != '\'') - return __first; - state = IN_STRING; - break; - - case IN_STRING: - assert(*__first != '\n'); - - if (*__first == '\'') - state = END; - else if (*__first == '\\') - state = QUOTE; - break; - - case QUOTE: - state = IN_STRING; - break; - } - } - - return __first; - } -}; - -struct pp_skip_argument { - pp_skip_identifier skip_number; - pp_skip_identifier skip_identifier; - pp_skip_string_literal skip_string_literal; - pp_skip_char_literal skip_char_literal; - pp_skip_comment_or_divop skip_comment_or_divop; - int lines; - - template <typename _InputIterator> - _InputIterator operator()(_InputIterator __first, _InputIterator __last) { - int depth = 0; - lines = 0; - - while (__first != __last) { - if (!depth && (*__first == ')' || *__first == ',')) - break; - else if (*__first == '(') - ++depth, ++__first; - else if (*__first == ')') - --depth, ++__first; - else if (*__first == '\"') { - __first = skip_string_literal(__first, __last); - lines += skip_string_literal.lines; - } else if (*__first == '\'') { - __first = skip_char_literal(__first, __last); - lines += skip_char_literal.lines; - } else if (*__first == '/') { - __first = skip_comment_or_divop(__first, __last); - lines += skip_comment_or_divop.lines; - } else if (pp_isalpha(*__first) || *__first == '_') { - __first = skip_identifier(__first, __last); - lines += skip_identifier.lines; - } else if (pp_isdigit(*__first)) { - __first = skip_number(__first, __last); - lines += skip_number.lines; - } else if (*__first == '\n') { - ++__first; - ++lines; - } else - ++__first; - } - - return __first; - } -}; - -} // namespace rpp - -#endif // PP_SCANNER_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-string.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-string.h deleted file mode 100644 index 25db0389a..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-string.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_STRING_H -#define PP_STRING_H - -namespace rpp -{ - -template <typename _CharT> -class pp_string -{ - typedef std::char_traits<_CharT> traits_type; - typedef std::size_t size_type; - - _CharT const *_M_begin; - std::size_t _M_size; - -public: - inline pp_string(): - _M_begin(0), _M_size(0) {} - - explicit pp_string(std::string const &__s): - _M_begin(__s.c_str()), _M_size(__s.size()) {} - - inline pp_string(_CharT const *__begin, std::size_t __size): - _M_begin(__begin), _M_size(__size) {} - - inline _CharT const *begin() const { - return _M_begin; - } - inline _CharT const *end() const { - return _M_begin + _M_size; - } - - inline _CharT at(std::size_t index) const { - return _M_begin [index]; - } - - inline std::size_t size() const { - return _M_size; - } - - inline int compare(pp_string const &__other) const { - size_type const __size = this->size(); - size_type const __osize = __other.size(); - size_type const __len = std::min(__size, __osize); - - int __r = traits_type::compare(_M_begin, __other._M_begin, __len); - if (!__r) - __r = (int)(__size - __osize); - - return __r; - } - - inline bool operator == (pp_string const &__other) const { - return compare(__other) == 0; - } - - inline bool operator != (pp_string const &__other) const { - return compare(__other) != 0; - } - - inline bool operator < (pp_string const &__other) const { - return compare(__other) < 0; - } - - inline bool operator == (char const *s) const { - std::size_t n = strlen(s); - - if (n != _M_size) - return false; - - return ! strncmp(_M_begin, s, n); - } - - inline bool operator != (char const *s) const { - return ! operator == (s); - } -}; - -} // namespace rpp - -#endif // PP_STRING_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-symbol.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-symbol.h deleted file mode 100644 index 9b06d2643..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-symbol.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_SYMBOL_H -#define PP_SYMBOL_H - -#include <cassert> -#include <iterator> -#include "pp-fwd.h" -#include "parser/rxx_allocator.h" - -namespace rpp -{ - -class pp_symbol -{ - static rxx_allocator<char> &allocator_instance() { - static rxx_allocator<char>__allocator; - return __allocator; - } - static rxx_allocator<pp_fast_string> &ppfs_allocator_instance () - { - static rxx_allocator<pp_fast_string>__ppfs_allocator; - return __ppfs_allocator; - } - -public: - static int &N() { - static int __N; - return __N; - } - - static pp_fast_string const *get(char const *__data, std::size_t __size) { - ++N(); - char *data = allocator_instance().allocate(__size + 1); - memcpy(data, __data, __size); - data[__size] = '\0'; - - pp_fast_string *where = ppfs_allocator_instance ().allocate (sizeof (pp_fast_string)); - return new(where) pp_fast_string(data, __size); - } - - template <typename _InputIterator> - static pp_fast_string const *get(_InputIterator __first, _InputIterator __last) { - ++N(); - std::ptrdiff_t __size; -#if defined(__SUNPRO_CC) - std::distance(__first, __last, __size); -#else - __size = std::distance(__first, __last); -#endif - assert(__size >= 0 && __size < 512); - - char *data = allocator_instance().allocate(__size + 1); - std::copy(__first, __last, data); - data[__size] = '\0'; - - pp_fast_string *where = ppfs_allocator_instance ().allocate (sizeof (pp_fast_string)); - return new(where) pp_fast_string(data, __size); - } - - static pp_fast_string const *get(std::string const &__s) { - return get(__s.c_str(), __s.size()); - } -}; - -} // namespace rpp - -#endif // PP_SYMBOL_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp.h deleted file mode 100644 index dfeeac432..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_H -#define PP_H - -#if defined(_WIN64) || defined(WIN64) || defined(__WIN64__) \ - || defined(_WIN32) || defined(WIN32) || defined(__WIN32__) -# define PP_OS_WIN -#endif - -#include <set> -#include <map> -#include <vector> -#include <string> -#include <iterator> -#include <iostream> -#include <cassert> -#include <cctype> -#include <cstdio> - -#include <fcntl.h> - -#ifdef HAVE_MMAP -# include <sys/mman.h> -#endif - -#include <sys/stat.h> -#include <sys/types.h> - -#if (_MSC_VER >= 1400) -# define FILENO _fileno -#else -# define FILENO fileno -#endif - -#if defined (PP_OS_WIN) -# define PATH_SEPARATOR '\\' -#else -# define PATH_SEPARATOR '/' -#endif - -#if defined (RPP_JAMBI) -# include "parser/rxx_allocator.h" -#else -# include "parser/rpp-allocator.h" -#endif - -#if defined (_MSC_VER) -# define pp_snprintf _snprintf -#else -# define pp_snprintf snprintf -#endif - -#include "pp-fwd.h" -#include "pp-cctype.h" -#include "pp-string.h" -#include "pp-symbol.h" -#include "pp-internal.h" -#include "pp-iterator.h" -#include "pp-macro.h" -#include "pp-environment.h" -#include "pp-scanner.h" -#include "pp-macro-expander.h" -#include "pp-engine.h" -#include "pp-engine-bits.h" - -#endif // PP_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/preprocessor.cpp b/sources/shiboken2/ApiExtractor/parser/rpp/preprocessor.cpp deleted file mode 100644 index 315343321..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/preprocessor.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "preprocessor.h" - -#include <string> -#include <cstdio> - -// register callback for include hooks -static void includeFileHook(const std::string &, const std::string &, FILE *); - -#define PP_HOOK_ON_FILE_INCLUDED(A, B, C) includeFileHook(A, B, C) -#include "pp.h" - -using namespace rpp; - -#include <QtCore/QtCore> - -class PreprocessorPrivate -{ -public: - QByteArray result; - pp_environment env; - QStringList includePaths; - - void initPP(pp &proc) { - foreach(QString path, includePaths) - proc.push_include_path(path.toStdString()); - } -}; - -QHash<QString, QStringList> includedFiles; - -void includeFileHook(const std::string &fileName, const std::string &filePath, FILE *) -{ - includedFiles[QString::fromStdString(fileName)].append(QString::fromStdString(filePath)); -} - -Preprocessor::Preprocessor() -{ - d = new PreprocessorPrivate; - includedFiles.clear(); -} - -Preprocessor::~Preprocessor() -{ - delete d; -} - -void Preprocessor::processFile(const QString &fileName) -{ - pp proc(d->env); - d->initPP(proc); - - d->result.reserve(d->result.size() + 20 * 1024); - - d->result += "# 1 \"" + fileName.toLatin1() + "\"\n"; // ### REMOVE ME - proc.file(fileName.toLocal8Bit().constData(), std::back_inserter(d->result)); -} - -void Preprocessor::processString(const QByteArray &str) -{ - pp proc(d->env); - d->initPP(proc); - - proc(str.begin(), str.end(), std::back_inserter(d->result)); -} - -QByteArray Preprocessor::result() const -{ - return d->result; -} - -void Preprocessor::addIncludePaths(const QStringList &includePaths) -{ - d->includePaths += includePaths; -} - -QStringList Preprocessor::macroNames() const -{ - QStringList macros; - - pp_environment::const_iterator it = d->env.first_macro(); - while (it != d->env.last_macro()) { - const pp_macro *m = *it; - macros += QString::fromLatin1(m->name->begin(), m->name->size()); - ++it; - } - - return macros; -} - -QList<Preprocessor::MacroItem> Preprocessor::macros() const -{ - QList<MacroItem> items; - - pp_environment::const_iterator it = d->env.first_macro(); - while (it != d->env.last_macro()) { - const pp_macro *m = *it; - MacroItem item; - item.name = QString::fromLatin1(m->name->begin(), m->name->size()); - item.definition = QString::fromLatin1(m->definition->begin(), - m->definition->size()); - for (size_t i = 0; i < m->formals.size(); ++i) { - item.parameters += QString::fromLatin1(m->formals[i]->begin(), - m->formals[i]->size()); - } - item.isFunctionLike = m->function_like; - -#ifdef PP_WITH_MACRO_POSITION - item.fileName = QString::fromLatin1(m->file->begin(), m->file->size()); -#endif - items += item; - - ++it; - } - - return items; -} - -/* -int main() -{ - Preprocessor pp; - - QStringList paths; - paths << "/usr/include"; - pp.addIncludePaths(paths); - - pp.processFile("pp-configuration"); - pp.processFile("/usr/include/stdio.h"); - - qDebug() << pp.result(); - - return 0; -} -*/ - diff --git a/sources/shiboken2/ApiExtractor/parser/rxx_allocator.h b/sources/shiboken2/ApiExtractor/parser/rxx_allocator.h deleted file mode 100644 index 8325edbdf..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rxx_allocator.h +++ /dev/null @@ -1,146 +0,0 @@ -/* This file is part of KDevelop - Copyright 2002-2005 Roberto Raggi <roberto@kdevelop.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef RXX_ALLOCATOR_H -#define RXX_ALLOCATOR_H - -#include <cstddef> -#include <cstdlib> -#include <string.h> -#include <memory> - -// Stride calculation -template <typename T> -struct Tchar { - T t; - char c; -}; - -#define strideof(T) \ - ((sizeof(Tchar<T>) > sizeof(T)) ? \ - sizeof(Tchar<T>)-sizeof(T) : sizeof(T)) - - -/**The allocator which uses fixed size blocks for allocation of its elements. -Block size is currently 64k, allocated space is not reclaimed, -if the size of the element being allocated extends the amount of free -memory in the block then a new block is allocated. - -The allocator supports standard c++ library interface but does not -make use of allocation hints. -*/ -template <class _Tp> class rxx_allocator { -public: - typedef _Tp value_type; - typedef _Tp* pointer; - typedef const _Tp* const_pointer; - typedef _Tp& reference; - typedef const _Tp& const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - static const size_type max_block_count = size_type(-1); - static const size_type _S_block_size = 1 << 16; // 64K - - rxx_allocator() { - init(); - } - - rxx_allocator(const rxx_allocator &/*__o*/) { - init(); - } - - ~rxx_allocator() { - for (size_type index = 0; index < _M_block_index + 1; ++index) - delete[] _M_storage[index]; - - ::free(_M_storage); - } - - pointer address(reference __val) { return &__val; } - const_pointer address(const_reference __val) const { return &__val; } - - /**Allocates @p __n elements continuosly in the pool. Warning! no - check is done to check if the size of those @p __n elements - fit into the block. You should assure you do not allocate more - than the size of a block.*/ - pointer allocate(size_type __n, const void* = 0) { - const size_type bytes = __n * sizeof(_Tp); - - if (_M_current_block == 0 - || _S_block_size < _M_current_index + bytes) - { - ++_M_block_index; - - _M_storage = reinterpret_cast<char**> - (::realloc(_M_storage, sizeof(char*) * (1 + _M_block_index))); - - _M_current_block = _M_storage[_M_block_index] = reinterpret_cast<char*> - (new char[_S_block_size]); - - ::memset(_M_current_block, 0, _S_block_size); - _M_current_index = 0; - } - - pointer p = reinterpret_cast<pointer> - (_M_current_block + _M_current_index); - - _M_current_index += bytes; - - return p; - } - - pointer allocate(size_type __n, size_type stride, const void* = 0) { - if (reinterpret_cast<size_type>(_M_current_block + _M_current_index) % stride > 0) - _M_current_index += stride - reinterpret_cast<size_type>(_M_current_block + _M_current_index) % stride; - return allocate(__n); - } - - /**Deallocate does nothing in this implementation.*/ - void deallocate(pointer /*__p*/, size_type /*__n*/) {} - - size_type max_size() const { return size_type(-1) / sizeof(_Tp); } - - void construct(pointer __p, const_reference __val) { new (__p) _Tp(__val); } - void destroy(pointer __p) { __p->~_Tp(); } - - template <class _Tp1> struct rebind { - typedef rxx_allocator<_Tp1> other; - }; - -private: - - void init() - { - _M_block_index = max_block_count; - _M_current_index = 0; - _M_storage = 0; - _M_current_block = 0; - } - - template <class _Tp1> rxx_allocator(const rxx_allocator<_Tp1> &__o) {} - -private: - size_type _M_block_index; - size_type _M_current_index; - char *_M_current_block; - char **_M_storage; -}; - -#endif // RXX_ALLOCATOR_H - diff --git a/sources/shiboken2/ApiExtractor/parser/smallobject.cpp b/sources/shiboken2/ApiExtractor/parser/smallobject.cpp deleted file mode 100644 index 9cee247e0..000000000 --- a/sources/shiboken2/ApiExtractor/parser/smallobject.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "smallobject.h" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/smallobject.h b/sources/shiboken2/ApiExtractor/parser/smallobject.h deleted file mode 100644 index 99e4ea44a..000000000 --- a/sources/shiboken2/ApiExtractor/parser/smallobject.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef SMALLOBJECT_H -#define SMALLOBJECT_H - -#include "rxx_allocator.h" -#include <cstring> - -class pool -{ - rxx_allocator<char> __alloc; - -public: - inline void *allocate(std::size_t __size); - inline void *allocate(std::size_t __size, std::size_t __stride); -}; - -inline void *pool::allocate(std::size_t __size) -{ - return __alloc.allocate(__size); -} - -inline void *pool::allocate(std::size_t __size, std::size_t __stride) -{ - return __alloc.allocate(__size, __stride); -} - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/symbol.h b/sources/shiboken2/ApiExtractor/parser/symbol.h deleted file mode 100644 index 588653846..000000000 --- a/sources/shiboken2/ApiExtractor/parser/symbol.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef SYMBOL_H -#define SYMBOL_H - -#include <QtCore/QString> -#include <cstring> - -#include <QtCore/QHash> -#include <QtCore/QPair> - -struct NameSymbol -{ - const char *data; - std::size_t count; - - inline QString as_string() const - { - return QString::fromUtf8(data, (int) count); - } - - inline bool operator == (const NameSymbol &other) const - { - return count == other.count - && !std::strncmp(data, other.data, count); - } - -protected: - inline NameSymbol() {} - inline NameSymbol(const char *d, std::size_t c) - : data(d), count(c) {} - -private: - void operator = (const NameSymbol &); - - friend class NameTable; -}; - -inline uint qHash(const NameSymbol &r) -{ - uint hash_value = 0; - - for (std::size_t i = 0; i < r.count; ++i) - hash_value = (hash_value << 5) - hash_value + r.data[i]; - - return hash_value; -} - -inline uint qHash(const QPair<const char*, std::size_t> &r) -{ - uint hash_value = 0; - - for (std::size_t i = 0; i < r.second; ++i) - hash_value = (hash_value << 5) - hash_value + r.first[i]; - - return hash_value; -} - -class NameTable -{ -public: - typedef QPair<const char *, std::size_t> KeyType; - typedef QHash<KeyType, NameSymbol*> ContainerType; - -public: - NameTable() {} - - ~NameTable() - { - qDeleteAll(_M_storage); - } - - inline const NameSymbol *findOrInsert(const char *str, std::size_t len) - { - KeyType key(str, len); - - NameSymbol *name = _M_storage.value(key); - if (!name) { - name = new NameSymbol(str, len); - _M_storage.insert(key, name); - } - - return name; - } - - inline std::size_t count() const { return _M_storage.size(); } - -private: - ContainerType _M_storage; - -private: - NameTable(const NameTable &other); - void operator=(const NameTable &other); -}; - -#endif // SYMBOL_H - -// kate: space-indent on; indent-width 2; replace-tabs on; - diff --git a/sources/shiboken2/ApiExtractor/parser/tokens.cpp b/sources/shiboken2/ApiExtractor/parser/tokens.cpp deleted file mode 100644 index eace3c9fa..000000000 --- a/sources/shiboken2/ApiExtractor/parser/tokens.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include <QtCore/qglobal.h> - -#include "tokens.h" - -static char const * const _S_token_names[] = { - "K_DCOP", - "Q_OBJECT", - "Q_PROPERTY", - "__attribute__", - "__typeof", - "and", - "and_eq", - "arrow", - "asm", - "assign", - "auto", - "bitand", - "bitor", - "bool", - "break", - "case", - "catch", - "char", - "char_literal", - "class", - "comment", - "compl", - "concat", - "const", - "const_cast", - "continue", - "decr", - "default", - "delete", - "do", - "double", - "dynamic_cast", - "ellipsis", - "else", - "emit", - "enum", - "eq", - "explicit", - "export", - "extern", - "false", - "float", - "for", - "friend", - "geq", - "goto", - "identifier", - "if", - "incr", - "inline", - "int", - "k_dcop", - "k_dcop_signals", - "leq", - "long", - "mutable", - "namespace", - "new", - "noexcept", - "not", - "not_eq", - "number_literal", - "operator", - "or", - "or_eq", - "preproc", - "private", - "protected", - "ptrmem", - "public", - "register", - "reinterpret_cast", - "return", - "scope", - "shift", - "short", - "signals", - "signed", - "sizeof", - "slots", - "static", - "static_cast", - "string_literal", - "struct", - "switch", - "template", - "this", - "throw", - "true", - "try", - "typedef", - "typeid", - "typename", - "union", - "unsigned", - "using", - "virtual", - "void", - "volatile", - "wchar_t", - "while", - "whitespaces", - "xor", - "xor_eq", - "Q_ENUMS", - "Q_ENUM" -}; - -static char _S_printable[][2] = { - { char(32), '\0' }, - { char(33), '\0' }, - { char(34), '\0' }, - { char(35), '\0' }, - { char(36), '\0' }, - { char(37), '\0' }, - { char(38), '\0' }, - { char(39), '\0' }, - { char(40), '\0' }, - { char(41), '\0' }, - { char(42), '\0' }, - { char(43), '\0' }, - { char(44), '\0' }, - { char(45), '\0' }, - { char(46), '\0' }, - { char(47), '\0' }, - { char(48), '\0' }, - { char(49), '\0' }, - { char(50), '\0' }, - { char(51), '\0' }, - { char(52), '\0' }, - { char(53), '\0' }, - { char(54), '\0' }, - { char(55), '\0' }, - { char(56), '\0' }, - { char(57), '\0' }, - { char(58), '\0' }, - { char(59), '\0' }, - { char(60), '\0' }, - { char(61), '\0' }, - { char(62), '\0' }, - { char(63), '\0' }, - { char(64), '\0' }, - { char(65), '\0' }, - { char(66), '\0' }, - { char(67), '\0' }, - { char(68), '\0' }, - { char(69), '\0' }, - { char(70), '\0' }, - { char(71), '\0' }, - { char(72), '\0' }, - { char(73), '\0' }, - { char(74), '\0' }, - { char(75), '\0' }, - { char(76), '\0' }, - { char(77), '\0' }, - { char(78), '\0' }, - { char(79), '\0' }, - { char(80), '\0' }, - { char(81), '\0' }, - { char(82), '\0' }, - { char(83), '\0' }, - { char(84), '\0' }, - { char(85), '\0' }, - { char(86), '\0' }, - { char(87), '\0' }, - { char(88), '\0' }, - { char(89), '\0' }, - { char(90), '\0' }, - { char(91), '\0' }, - { char(92), '\0' }, - { char(93), '\0' }, - { char(94), '\0' }, - { char(95), '\0' }, - { char(96), '\0' }, - { char(97), '\0' }, - { char(98), '\0' }, - { char(99), '\0' }, - { char(100), '\0' }, - { char(101), '\0' }, - { char(102), '\0' }, - { char(103), '\0' }, - { char(104), '\0' }, - { char(105), '\0' }, - { char(106), '\0' }, - { char(107), '\0' }, - { char(108), '\0' }, - { char(109), '\0' }, - { char(110), '\0' }, - { char(111), '\0' }, - { char(112), '\0' }, - { char(113), '\0' }, - { char(114), '\0' }, - { char(115), '\0' }, - { char(116), '\0' }, - { char(117), '\0' }, - { char(118), '\0' }, - { char(119), '\0' }, - { char(120), '\0' }, - { char(121), '\0' }, - { char(122), '\0' }, - { char(123), '\0' }, - { char(124), '\0' }, - { char(125), '\0' }, - { char(126), '\0' }, - { char(127), '\0' }, -}; - -char const *token_name(int token) -{ - if (token == 0) - return "eof"; - else if (token >= 32 && token <= 127) - return _S_printable[token - 32]; - else if (token >= 1000) - return _S_token_names[token - 1000]; - - Q_ASSERT(0); - return 0; -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/tokens.h b/sources/shiboken2/ApiExtractor/parser/tokens.h deleted file mode 100644 index 46ec96e74..000000000 --- a/sources/shiboken2/ApiExtractor/parser/tokens.h +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef TOKENS_H -#define TOKENS_H - -enum TOKEN_KIND { - Token_EOF = 0, - - Token_K_DCOP = 1000, - Token_Q_OBJECT, - Token_Q_PROPERTY, - Token___attribute__, - Token___typeof, - Token_and, - Token_and_eq, - Token_arrow, - Token_asm, - Token_assign, - Token_auto, - Token_bitand, - Token_bitor, - Token_bool, - Token_break, - Token_case, - Token_catch, - Token_char, - Token_char_literal, - Token_class, - Token_comment, - Token_compl, - Token_concat, - Token_const, - Token_const_cast, - Token_continue, - Token_decr, - Token_default, - Token_delete, - Token_do, - Token_double, - Token_dynamic_cast, - Token_ellipsis, - Token_else, - Token_emit, - Token_enum, - Token_eq, - Token_explicit, - Token_export, - Token_extern, - Token_false, - Token_float, - Token_for, - Token_friend, - Token_geq, - Token_goto, - Token_identifier, - Token_if, - Token_incr, - Token_inline, - Token_int, - Token_k_dcop, - Token_k_dcop_signals, - Token_leq, - Token_long, - Token_mutable, - Token_namespace, - Token_new, - Token_noexcept, - Token_not, - Token_not_eq, - Token_number_literal, - Token_operator, - Token_or, - Token_or_eq, - Token_preproc, - Token_private, - Token_protected, - Token_ptrmem, - Token_public, - Token_register, - Token_reinterpret_cast, - Token_return, - Token_scope, - Token_shift, - Token_short, - Token_signals, - Token_signed, - Token_sizeof, - Token_slots, - Token_static, - Token_static_cast, - Token_string_literal, - Token_struct, - Token_switch, - Token_template, - Token_this, - Token_throw, - Token_true, - Token_try, - Token_typedef, - Token_typeid, - Token_typename, - Token_union, - Token_unsigned, - Token_using, - Token_virtual, - Token_void, - Token_volatile, - Token_wchar_t, - Token_while, - Token_whitespaces, - Token_xor, - Token_xor_eq, - Token_Q_ENUMS, - Token_Q_ENUM, - Token_Q_INVOKABLE, - - TOKEN_KIND_COUNT -}; - -char const *token_name(int token); - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/type_compiler.cpp b/sources/shiboken2/ApiExtractor/parser/type_compiler.cpp deleted file mode 100644 index c08f210fa..000000000 --- a/sources/shiboken2/ApiExtractor/parser/type_compiler.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - - -#include "type_compiler.h" -#include "name_compiler.h" -#include "lexer.h" -#include "symbol.h" -#include "tokens.h" -#include "binder.h" - -#include <QtCore/QString> - -TypeCompiler::TypeCompiler(Binder *binder) - : _M_binder(binder), _M_token_stream(binder->tokenStream()) -{ -} - -void TypeCompiler::run(TypeSpecifierAST *node) -{ - _M_type.clear(); - _M_cv.clear(); - - visit(node); - - if (node && node->cv) { - const ListNode<std::size_t> *it = node->cv->toFront(); - const ListNode<std::size_t> *end = it; - do { - int kind = _M_token_stream->kind(it->element); - if (!_M_cv.contains(kind)) - _M_cv.append(kind); - - it = it->next; - } while (it != end); - } -} - -void TypeCompiler::visitClassSpecifier(ClassSpecifierAST *node) -{ - visit(node->name); -} - -void TypeCompiler::visitEnumSpecifier(EnumSpecifierAST *node) -{ - visit(node->name); -} - -void TypeCompiler::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *node) -{ - visit(node->name); -} - -void TypeCompiler::visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *node) -{ - if (const ListNode<std::size_t> *it = node->integrals) { - it = it->toFront(); - const ListNode<std::size_t> *end = it; - QString current_item; - do { - std::size_t token = it->element; - current_item += QLatin1String(token_name(_M_token_stream->kind(token))); - current_item += QLatin1Char(' '); - it = it->next; - } while (it != end); - _M_type += current_item.trimmed(); - } else if (node->type_of) { - // ### implement me - _M_type += QLatin1String("typeof<...>"); - } - - visit(node->name); -} - -void TypeCompiler::visitName(NameAST *node) -{ - NameCompiler name_cc(_M_binder); - name_cc.run(node); - _M_type = name_cc.qualifiedName(); -} - -QStringList TypeCompiler::cvString() const -{ - QStringList lst; - - foreach (int q, cv()) { - if (q == Token_const) - lst.append(QLatin1String("const")); - else if (q == Token_volatile) - lst.append(QLatin1String("volatile")); - } - - return lst; -} - -bool TypeCompiler::isConstant() const -{ - return _M_cv.contains(Token_const); -} - -bool TypeCompiler::isVolatile() const -{ - return _M_cv.contains(Token_volatile); -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/type_compiler.h b/sources/shiboken2/ApiExtractor/parser/type_compiler.h deleted file mode 100644 index 6755b30c3..000000000 --- a/sources/shiboken2/ApiExtractor/parser/type_compiler.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef TYPE_COMPILER_H -#define TYPE_COMPILER_H - -#include "default_visitor.h" - -#include <QtCore/QString> -#include <QtCore/QStringList> -#include <QtCore/QList> - -class TokenStream; -class Binder; - -class TypeCompiler: protected DefaultVisitor -{ -public: - TypeCompiler(Binder *binder); - - inline QStringList qualifiedName() const { return _M_type; } - inline QList<int> cv() const { return _M_cv; } - - bool isConstant() const; - bool isVolatile() const; - - QStringList cvString() const; - - void run(TypeSpecifierAST *node); - -protected: - virtual void visitClassSpecifier(ClassSpecifierAST *node); - virtual void visitEnumSpecifier(EnumSpecifierAST *node); - virtual void visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *node); - virtual void visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *node); - - virtual void visitName(NameAST *node); - -private: - Binder *_M_binder; - TokenStream *_M_token_stream; - QStringList _M_type; - QList<int> _M_cv; -}; - -#endif // TYPE_COMPILER_H - -// kate: space-indent on; indent-width 2; replace-tabs on; - diff --git a/sources/shiboken2/ApiExtractor/parser/visitor.cpp b/sources/shiboken2/ApiExtractor/parser/visitor.cpp deleted file mode 100644 index e13e4acb3..000000000 --- a/sources/shiboken2/ApiExtractor/parser/visitor.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "visitor.h" - -Visitor::visitor_fun_ptr Visitor::_S_table[AST::NODE_KIND_COUNT] = { - 0, - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitAccessSpecifier), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitAsmDefinition), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitBaseClause), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitBaseSpecifier), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitBinaryExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitCastExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitClassMemberAccess), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitClassSpecifier), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitCompoundStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitCondition), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitConditionalExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitCppCastExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitCtorInitializer), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitDeclarationStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitDeclarator), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitDeleteExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitDoStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitElaboratedTypeSpecifier), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitEnumSpecifier), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitEnumerator), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitExceptionSpecification), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitExpressionOrDeclarationStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitExpressionStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitForStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitFunctionCall), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitFunctionDefinition), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitIfStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitIncrDecrExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitInitDeclarator), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitInitializer), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitInitializerClause), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitLabeledStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitLinkageBody), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitLinkageSpecification), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitMemInitializer), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitName), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitNamespace), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitNamespaceAliasDefinition), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitNewDeclarator), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitNewExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitNewInitializer), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitNewTypeId), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitOperator), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitOperatorFunctionId), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitParameterDeclaration), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitParameterDeclarationClause), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitPostfixExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitPrimaryExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitPtrOperator), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitPtrToMember), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitReturnStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitSimpleDeclaration), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitSimpleTypeSpecifier), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitSizeofExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitStringLiteral), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitSubscriptExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitSwitchStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitTemplateArgument), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitTemplateDeclaration), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitTemplateParameter), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitThrowExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitTranslationUnit), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitTryBlockStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitTypeId), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitTypeIdentification), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitTypeParameter), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitTypedef), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitUnaryExpression), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitUnqualifiedName), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitUsing), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitUsingDirective), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitWhileStatement), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitWinDeclSpec), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitQProperty), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitForwardDeclarationSpecifier), - reinterpret_cast<Visitor::visitor_fun_ptr>(&Visitor::visitQEnums) -}; - -Visitor::Visitor() -{ -} - -Visitor::~Visitor() -{ -} - -void Visitor::visit(AST *node) -{ - if (node) - (this->*_S_table[node->kind])(node); -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/visitor.h b/sources/shiboken2/ApiExtractor/parser/visitor.h deleted file mode 100644 index b1fbf8763..000000000 --- a/sources/shiboken2/ApiExtractor/parser/visitor.h +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef VISITOR_H -#define VISITOR_H - -#include "ast.h" - -class Visitor -{ -public: - Visitor(); - virtual ~Visitor(); - - virtual void visit(AST *node); - -protected: - virtual void visitAccessSpecifier(AccessSpecifierAST *) {} - virtual void visitAsmDefinition(AsmDefinitionAST *) {} - virtual void visitBaseClause(BaseClauseAST *) {} - virtual void visitBaseSpecifier(BaseSpecifierAST *) {} - virtual void visitBinaryExpression(BinaryExpressionAST *) {} - virtual void visitCastExpression(CastExpressionAST *) {} - virtual void visitClassMemberAccess(ClassMemberAccessAST *) {} - virtual void visitClassSpecifier(ClassSpecifierAST *) {} - virtual void visitCompoundStatement(CompoundStatementAST *) {} - virtual void visitCondition(ConditionAST *) {} - virtual void visitConditionalExpression(ConditionalExpressionAST *) {} - virtual void visitCppCastExpression(CppCastExpressionAST *) {} - virtual void visitCtorInitializer(CtorInitializerAST *) {} - virtual void visitDeclarationStatement(DeclarationStatementAST *) {} - virtual void visitDeclarator(DeclaratorAST *) {} - virtual void visitDeleteExpression(DeleteExpressionAST *) {} - virtual void visitDoStatement(DoStatementAST *) {} - virtual void visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *) {} - virtual void visitEnumSpecifier(EnumSpecifierAST *) {} - virtual void visitEnumerator(EnumeratorAST *) {} - virtual void visitExceptionSpecification(ExceptionSpecificationAST *) {} - virtual void visitExpressionOrDeclarationStatement(ExpressionOrDeclarationStatementAST *) {} - virtual void visitExpressionStatement(ExpressionStatementAST *) {} - virtual void visitForStatement(ForStatementAST *) {} - virtual void visitFunctionCall(FunctionCallAST *) {} - virtual void visitFunctionDefinition(FunctionDefinitionAST *) {} - virtual void visitIfStatement(IfStatementAST *) {} - virtual void visitIncrDecrExpression(IncrDecrExpressionAST *) {} - virtual void visitInitDeclarator(InitDeclaratorAST *) {} - virtual void visitInitializer(InitializerAST *) {} - virtual void visitInitializerClause(InitializerClauseAST *) {} - virtual void visitLabeledStatement(LabeledStatementAST *) {} - virtual void visitLinkageBody(LinkageBodyAST *) {} - virtual void visitLinkageSpecification(LinkageSpecificationAST *) {} - virtual void visitMemInitializer(MemInitializerAST *) {} - virtual void visitName(NameAST *) {} - virtual void visitNamespace(NamespaceAST *) {} - virtual void visitNamespaceAliasDefinition(NamespaceAliasDefinitionAST *) {} - virtual void visitNewDeclarator(NewDeclaratorAST *) {} - virtual void visitNewExpression(NewExpressionAST *) {} - virtual void visitNewInitializer(NewInitializerAST *) {} - virtual void visitNewTypeId(NewTypeIdAST *) {} - virtual void visitOperator(OperatorAST *) {} - virtual void visitOperatorFunctionId(OperatorFunctionIdAST *) {} - virtual void visitParameterDeclaration(ParameterDeclarationAST *) {} - virtual void visitParameterDeclarationClause(ParameterDeclarationClauseAST *) {} - virtual void visitPostfixExpression(PostfixExpressionAST *) {} - virtual void visitPrimaryExpression(PrimaryExpressionAST *) {} - virtual void visitPtrOperator(PtrOperatorAST *) {} - virtual void visitPtrToMember(PtrToMemberAST *) {} - virtual void visitReturnStatement(ReturnStatementAST *) {} - virtual void visitSimpleDeclaration(SimpleDeclarationAST *) {} - virtual void visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *) {} - virtual void visitSizeofExpression(SizeofExpressionAST *) {} - virtual void visitStringLiteral(StringLiteralAST *) {} - virtual void visitSubscriptExpression(SubscriptExpressionAST *) {} - virtual void visitSwitchStatement(SwitchStatementAST *) {} - virtual void visitTemplateArgument(TemplateArgumentAST *) {} - virtual void visitTemplateDeclaration(TemplateDeclarationAST *) {} - virtual void visitTemplateParameter(TemplateParameterAST *) {} - virtual void visitThrowExpression(ThrowExpressionAST *) {} - virtual void visitTranslationUnit(TranslationUnitAST *) {} - virtual void visitTryBlockStatement(TryBlockStatementAST *) {} - virtual void visitTypeId(TypeIdAST *) {} - virtual void visitTypeIdentification(TypeIdentificationAST *) {} - virtual void visitTypeParameter(TypeParameterAST *) {} - virtual void visitTypedef(TypedefAST *) {} - virtual void visitUnaryExpression(UnaryExpressionAST *) {} - virtual void visitUnqualifiedName(UnqualifiedNameAST *) {} - virtual void visitUsing(UsingAST *) {} - virtual void visitUsingDirective(UsingDirectiveAST *) {} - virtual void visitWhileStatement(WhileStatementAST *) {} - virtual void visitWinDeclSpec(WinDeclSpecAST *) {} - virtual void visitQProperty(QPropertyAST *) {} - virtual void visitForwardDeclarationSpecifier(ForwardDeclarationSpecifierAST *) {} - virtual void visitQEnums(QEnumsAST *) {} - -private: - typedef void (Visitor::*visitor_fun_ptr)(AST *); - static visitor_fun_ptr _S_table[]; -}; - -template <class _Tp> -void visitNodes(Visitor *v, const ListNode<_Tp> *nodes) -{ - if (!nodes) - return; - - const ListNode<_Tp> - *it = nodes->toFront(), - *end = it; - - do { - v->visit(it->element); - it = it->next; - } while (it != end); -} - -#endif // VISITOR_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp index f1421ff91..00e2384f0 100644 --- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp +++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp @@ -79,7 +79,8 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) + className + QLatin1String("\"]/description"); DocModificationList signedModifs, classModifs; - foreach (DocModification docModif, metaClass->typeEntry()->docModifications()) { + const DocModificationList &mods = metaClass->typeEntry()->docModifications(); + for (const DocModification &docModif : mods) { if (docModif.signature().isEmpty()) classModifs.append(docModif); else @@ -91,8 +92,8 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) //Functions Documentation - AbstractMetaFunctionList funcs = metaClass->functionsInTargetLang(); - foreach (AbstractMetaFunction *func, funcs) { + const AbstractMetaFunctionList &funcs = metaClass->functionsInTargetLang(); + for (AbstractMetaFunction *func : funcs) { if (!func || func->isPrivate()) continue; @@ -109,8 +110,9 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) + QString::number(func->arguments().count()) + QLatin1String(" and @const=\"") + isConst + QLatin1String("\"]"); - int i = 1; - foreach (AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (int i = 0, size = arguments.size(); i < size; ++i) { + const AbstractMetaArgument *arg = arguments.at(i); QString type = arg->type()->name(); if (arg->type()->isConstant()) @@ -125,14 +127,13 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) for (int j = 0, max = arg->type()->indirections(); j < max; ++j) type += QLatin1Char('*'); } - query += QLatin1String("/parameter[") + QString::number(i) + query += QLatin1String("/parameter[") + QString::number(i + 1) + QLatin1String("][@left=\"") + type + QLatin1String("\"]/.."); - ++i; } } query += QLatin1String("/description"); DocModificationList funcModifs; - foreach (DocModification funcModif, signedModifs) { + for (const DocModification &funcModif : qAsConst(signedModifs)) { if (funcModif.signature() == func->minimalSignature()) funcModifs.append(funcModif); } @@ -141,8 +142,8 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) } #if 0 // Fields - AbstractMetaFieldList fields = metaClass->fields(); - foreach (AbstractMetaField *field, fields) { + const AbstractMetaFieldList &fields = metaClass->fields(); + for (AbstractMetaField *field : fields) { if (field->isPrivate()) return; @@ -152,8 +153,8 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) } #endif // Enums - AbstractMetaEnumList enums = metaClass->enums(); - foreach (AbstractMetaEnum *meta_enum, enums) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (AbstractMetaEnum *meta_enum : enums) { QString query = QLatin1String("/WebXML/document/") + type + QLatin1String("[@name=\"") + className + QLatin1String("\"]/enum[@name=\"") diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.h b/sources/shiboken2/ApiExtractor/qtdocparser.h index 04c491853..f6bd479cd 100644 --- a/sources/shiboken2/ApiExtractor/qtdocparser.h +++ b/sources/shiboken2/ApiExtractor/qtdocparser.h @@ -35,9 +35,9 @@ class QtDocParser : public DocParser { public: QtDocParser() {} - virtual void fillDocumentation(AbstractMetaClass* metaClass); - virtual Documentation retrieveModuleDocumentation(); - virtual Documentation retrieveModuleDocumentation(const QString& name); + void fillDocumentation(AbstractMetaClass* metaClass) override; + Documentation retrieveModuleDocumentation() override; + Documentation retrieveModuleDocumentation(const QString& name) override; }; #endif // QTDOCPARSER_H diff --git a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt index 5429c1cb8..860a37d9d 100644 --- a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt +++ b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt @@ -16,6 +16,7 @@ macro(declare_test testname) ${apiextractor_SOURCE_DIR} ${Qt5Test_INCLUDE_DIRS} ) + link_directories(${APIEXTRACTOR_EXTRA_LINK_DIRECTORIES}) target_link_libraries(${testname} ${Qt5XmlPatterns_LIBRARIES} ${Qt5Test_LIBRARIES} diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp index 028522159..423b8d9ff 100644 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp @@ -57,7 +57,7 @@ void TestAbstractMetaClass::testClassNameUnderNamespace() AbstractMetaClassList classes = builder->classes(); QCOMPARE(classes.count(), 2); // 1 namespace + 1 class if (classes.first()->name() != QLatin1String("ClassName")) - classes.swap(0, 1); + qSwap(classes[0], classes[1]); QCOMPARE(classes[0]->name(), QLatin1String("ClassName")); QCOMPARE(classes[0]->qualifiedCppName(), QLatin1String("Namespace::ClassName")); @@ -71,7 +71,7 @@ void TestAbstractMetaClass::testClassNameUnderNamespace() AbstractMetaFunctionList ctors = classes[0]->queryFunctions(AbstractMetaClass::Constructors); QCOMPARE(ctors.size(), 2); if (ctors.first()->minimalSignature() != QLatin1String("ClassName()")) - ctors.swap(0, 1); + qSwap(ctors[0], ctors[1]); QCOMPARE(ctors[0]->arguments().size(), 0); QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("ClassName()")); @@ -361,7 +361,7 @@ void TestAbstractMetaClass::testClassDefaultConstructors() AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); QCOMPARE(ctors.size(), 2); if (ctors.first()->minimalSignature() != QLatin1String("A()")) - ctors.swap(0, 1); + qSwap(ctors[0], ctors[1]); QCOMPARE(ctors[0]->arguments().size(), 0); QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("A()")); @@ -395,7 +395,7 @@ void TestAbstractMetaClass::testClassDefaultConstructors() ctors = classF->queryFunctions(AbstractMetaClass::Constructors); QCOMPARE(ctors.size(), 2); if (ctors.first()->minimalSignature() != QLatin1String("F(int,int)")) - ctors.swap(0, 1); + qSwap(ctors[0], ctors[1]); QCOMPARE(ctors[0]->arguments().size(), 2); QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("F(int,int)")); @@ -428,7 +428,7 @@ void TestAbstractMetaClass::testClassInheritedDefaultConstructors() AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); QCOMPARE(ctors.size(), 2); if (ctors.first()->minimalSignature() != QLatin1String("A()")) - ctors.swap(0, 1); + qSwap(ctors[0], ctors[1]); QCOMPARE(ctors[0]->arguments().size(), 0); QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("A()")); diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp index 6e1da17ae..bcc5238bc 100644 --- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp @@ -49,7 +49,7 @@ void TestAddFunction::testParsingFuncNameAndConstness() const char sig2[] = " _fu__nc_ ( type1, const type2, const Abc<int& , C<char*> * > * *, const type3* const ) const "; AddedFunction f2(QLatin1String(sig2), QLatin1String("const Abc<int& , C<char*> * > * *"), 0); QCOMPARE(f2.name(), QLatin1String("_fu__nc_")); - QList< AddedFunction::TypeInfo > args = f2.arguments(); + QVector< AddedFunction::TypeInfo > args = f2.arguments(); QCOMPARE(args.count(), 4); retval = f2.returnType(); QCOMPARE(retval.name, QLatin1String("Abc<int& , C<char*> * >")); @@ -423,8 +423,8 @@ void TestAddFunction::testAddFunctionOnTypedef() AbstractMetaClass* foo = AbstractMetaClass::findClass(classes, QLatin1String("FooInt")); QVERIFY(foo); QVERIFY(foo->hasNonPrivateConstructor()); - AbstractMetaFunctionList lst = foo->queryFunctions(AbstractMetaClass::Constructors); - foreach(AbstractMetaFunction* f, lst) + const AbstractMetaFunctionList &lst = foo->queryFunctions(AbstractMetaClass::Constructors); + for (const AbstractMetaFunction *f : lst) QVERIFY(f->signature().startsWith(f->name())); QCOMPARE(lst.size(), 2); const AbstractMetaFunction* method = foo->findFunction(QLatin1String("method")); diff --git a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp index 5385c9140..4d46d44bc 100644 --- a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp @@ -112,7 +112,8 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnu AbstractMetaEnum* someEnum = builder->globalEnums().first(); QVERIFY(someEnum); AbstractMetaEnumValue* nvalues = 0; - foreach (AbstractMetaEnumValue* enumValue, someEnum->values()) { + const AbstractMetaEnumValueList &values = someEnum->values(); + for (AbstractMetaEnumValue *enumValue : values) { if (enumValue->name() == QLatin1String("NValues")) { nvalues = enumValue; break; diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp index cae4a3a62..86f571328 100644 --- a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp @@ -65,7 +65,7 @@ void TestConversionOperator::testConversionOperator() QCOMPARE(classA->externalConversionOperators().count(), 2); AbstractMetaFunction* convOp = 0; - foreach(AbstractMetaFunction* func, classB->functions()) { + for (AbstractMetaFunction *func : classB->functions()) { if (func->isConversionOperator()) { convOp = func; break; diff --git a/sources/shiboken2/ApiExtractor/tests/testenum.cpp b/sources/shiboken2/ApiExtractor/tests/testenum.cpp index 6700239d6..98e56b86e 100644 --- a/sources/shiboken2/ApiExtractor/tests/testenum.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testenum.cpp @@ -318,7 +318,7 @@ void TestEnum::testEnumValueFromExpression() AbstractMetaEnumValue* valueA4 = enumA->values().at(4); QCOMPARE(valueA4->name(), QLatin1String("ValueA4")); - QCOMPARE(valueA4->stringValue(), QLatin1String("8|ValueA3")); + QCOMPARE(valueA4->stringValue(), QLatin1String("8 |ValueA3")); QCOMPARE(valueA4->value(), 8|0xf0); AbstractMetaEnumValue* valueA5 = enumA->values().at(5); @@ -328,12 +328,12 @@ void TestEnum::testEnumValueFromExpression() AbstractMetaEnumValue* valueA6 = enumA->values().at(6); QCOMPARE(valueA6->name(), QLatin1String("ValueA6")); - QCOMPARE(valueA6->stringValue(), QLatin1String("ValueA3>>1")); + QCOMPARE(valueA6->stringValue(), QLatin1String("ValueA3 >> 1")); QCOMPARE(valueA6->value(), 0xf0 >> 1); AbstractMetaEnumValue* valueA7 = enumA->values().at(7); QCOMPARE(valueA7->name(), QLatin1String("ValueA7")); - QCOMPARE(valueA7->stringValue(), QLatin1String("ValueA3<<1")); + QCOMPARE(valueA7->stringValue(), QLatin1String("ValueA3 << 1")); QCOMPARE(valueA7->value(), 0xf0 << 1); } diff --git a/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp b/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp index 94158377e..97f0d568e 100644 --- a/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp @@ -50,7 +50,7 @@ void TestExtraInclude::testClassExtraInclude() const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); QVERIFY(classA); - QList<Include> includes = classA->typeEntry()->extraIncludes(); + QVector<Include> includes = classA->typeEntry()->extraIncludes(); QCOMPARE(includes.count(), 1); QCOMPARE(includes.first().name(), QLatin1String("header.h")); } @@ -76,7 +76,7 @@ void TestExtraInclude::testGlobalExtraIncludes() TypeEntry* module = td->findType(QLatin1String("Foo")); QVERIFY(module); - QList<Include> includes = module->extraIncludes(); + QVector<Include> includes = module->extraIncludes(); QCOMPARE(includes.count(), 2); QCOMPARE(includes.first().name(), QLatin1String("header1.h")); QCOMPARE(includes.last().name(), QLatin1String("header2.h")); diff --git a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp index 4438550b2..7e8db42f3 100644 --- a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp @@ -152,7 +152,7 @@ void TestImplicitConversions::testWithExternalConversionOperator() QCOMPARE(externalConvOps.count(), 1); const AbstractMetaFunction* convOp = 0; - foreach(const AbstractMetaFunction* func, classB->functions()) { + for (const AbstractMetaFunction *func : classB->functions()) { if (func->isConversionOperator()) convOp = func; } diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp index 0e6bdc248..3d4ef9c89 100644 --- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp @@ -232,7 +232,7 @@ void TestModifyFunction::testGlobalFunctionModification() FunctionModificationList mods = TypeDatabase::instance()->functionModifications(QLatin1String("function(A*)")); QCOMPARE(mods.count(), 1); - QList<ArgumentModification> argMods = mods.first().argument_mods; + QVector<ArgumentModification> argMods = mods.first().argument_mods; QCOMPARE(argMods.count(), 1); ArgumentModification argMod = argMods.first(); QCOMPARE(argMod.replacedDefaultExpression, QLatin1String("A()")); diff --git a/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp b/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp index 67c9089ce..b78e6ec01 100644 --- a/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp @@ -61,7 +61,8 @@ void TestMultipleInheritance::testVirtualClass() const AbstractMetaClass *classD = AbstractMetaClass::findClass(classes, QLatin1String("D")); bool functionFound = false; - foreach (AbstractMetaFunction* f, classD->functions()) { + const AbstractMetaFunctionList &functions = classD->functions(); + for (AbstractMetaFunction *f : functions) { if (f->name() == QLatin1String("theBug")) { functionFound = true; break; diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp b/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp index 6b27227d6..508cff586 100644 --- a/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp @@ -105,7 +105,8 @@ void TestRemoveOperatorMethod::testRemoveOperatorMethod() removedSignatures.append(QLatin1String("operator>>(Char&)")); removedSignatures.append(QLatin1String("operator>>(String&)")); int notRemoved = classA->functions().size(); - foreach (const AbstractMetaFunction* f, classA->functions()) { + const AbstractMetaFunctionList &functions = classA->functions(); + for (const AbstractMetaFunction *f : functions) { QCOMPARE(f->isModifiedRemoved(), bool(removedSignatures.contains(f->minimalSignature()))); notRemoved -= int(f->isModifiedRemoved()); } diff --git a/sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp b/sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp index 76ba7d3b4..18d6902c2 100644 --- a/sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp @@ -53,7 +53,7 @@ void TestReverseOperators::testReverseSum() const AbstractMetaFunction* reverseOp = 0; const AbstractMetaFunction* normalOp = 0; - foreach(const AbstractMetaFunction* func, classA->functions()) { + for (const AbstractMetaFunction *func : classA->functions()) { if (func->name() == QLatin1String("operator+")) { if (func->isReverseOperator()) reverseOp = func; @@ -89,6 +89,7 @@ void TestReverseOperators::testReverseSumWithAmbiguity() </typesystem>"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); + QEXPECT_FAIL("", "Clang: Does not compile", Abort); QVERIFY(!builder.isNull()); AbstractMetaClassList classes = builder->classes(); const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); @@ -101,7 +102,7 @@ void TestReverseOperators::testReverseSumWithAmbiguity() const AbstractMetaFunction* reverseOp = 0; const AbstractMetaFunction* normalOp = 0; - foreach(const AbstractMetaFunction* func, classB->functions()) { + for (const AbstractMetaFunction *func : classB->functions()) { if (func->name() == QLatin1String("operator+")) { if (func->isReverseOperator()) reverseOp = func; diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp index cb90383db..4a66264d8 100644 --- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp @@ -228,6 +228,7 @@ void TestTemplates::testTemplateParameterFixup() const AbstractMetaFunction *erase = list->findFunction(QStringLiteral("erase")); QVERIFY(erase); QCOMPARE(erase->arguments().size(), 1); + QEXPECT_FAIL("", "Clang: Some other code changes the parameter type", Abort); QCOMPARE(erase->arguments().at(0)->type()->cppSignature(), QLatin1String("List::Iterator")); } diff --git a/sources/shiboken2/ApiExtractor/tests/testutil.h b/sources/shiboken2/ApiExtractor/tests/testutil.h index d4eb2fdf6..200fdb104 100644 --- a/sources/shiboken2/ApiExtractor/tests/testutil.h +++ b/sources/shiboken2/ApiExtractor/tests/testutil.h @@ -29,6 +29,9 @@ #ifndef TESTUTIL_H #define TESTUTIL_H #include <QtCore/QBuffer> +#include <QtCore/QDebug> +#include <QtCore/QDir> +#include <QtCore/QTemporaryFile> #include "abstractmetabuilder.h" #include "reporthandler.h" #include "typedatabase.h" @@ -53,9 +56,18 @@ namespace TestUtil td->parseFile(&buffer); buffer.close(); // parse C++ code - buffer.setData(cppCode); + QTemporaryFile tempSource(QDir::tempPath() + QLatin1String("/st_XXXXXX_main.cpp")); + if (!tempSource.open()) { + qWarning().noquote().nospace() << "Creation of temporary file failed: " + << tempSource.errorString(); + return nullptr; + } + QByteArrayList arguments; + arguments.append(QFile::encodeName(tempSource.fileName())); + tempSource.write(cppCode, qint64(strlen(cppCode))); + tempSource.close(); AbstractMetaBuilder *builder = new AbstractMetaBuilder; - if (!builder->build(&buffer)) { + if (!builder->build(arguments, 0)) { delete builder; return Q_NULLPTR; } diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp index 55170d7c1..a1b28070b 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp @@ -31,6 +31,7 @@ #include "typesystem_p.h" #include <QtCore/QFile> +#include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QPair> #include <QtCore/QVector> @@ -175,8 +176,8 @@ FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const TypeEntry* TypeDatabase::findType(const QString& name) const { - QList<TypeEntry *> entries = findTypes(name); - foreach (TypeEntry *entry, entries) { + const TypeEntryList &entries = findTypes(name); + for (TypeEntry *entry : entries) { if (entry && (!entry->isPrimitive() || static_cast<PrimitiveTypeEntry *>(entry)->preferredTargetLangType())) { return entry; @@ -185,7 +186,7 @@ TypeEntry* TypeDatabase::findType(const QString& name) const return 0; } -QList<TypeEntry *> TypeDatabase::findTypes(const QString &name) const +TypeEntryList TypeDatabase::findTypes(const QString &name) const { return m_entries.value(name); } @@ -201,12 +202,12 @@ SingleTypeEntryHash TypeDatabase::entries() const return returned; } -QList<const PrimitiveTypeEntry*> TypeDatabase::primitiveTypes() const +PrimitiveTypeEntryList TypeDatabase::primitiveTypes() const { TypeEntryHash entries = allEntries(); - QList<const PrimitiveTypeEntry*> returned; + PrimitiveTypeEntryList returned; for (TypeEntryHash::const_iterator it = entries.cbegin(), end = entries.cend(); it != end; ++it) { - foreach (TypeEntry *typeEntry, it.value()) { + for (TypeEntry *typeEntry : it.value()) { if (typeEntry->isPrimitive()) returned.append(static_cast<PrimitiveTypeEntry *>(typeEntry)); } @@ -214,75 +215,121 @@ QList<const PrimitiveTypeEntry*> TypeDatabase::primitiveTypes() const return returned; } -QList<const ContainerTypeEntry*> TypeDatabase::containerTypes() const +ContainerTypeEntryList TypeDatabase::containerTypes() const { TypeEntryHash entries = allEntries(); - QList<const ContainerTypeEntry*> returned; + ContainerTypeEntryList returned; for (TypeEntryHash::const_iterator it = entries.cbegin(), end = entries.cend(); it != end; ++it) { - foreach (TypeEntry *typeEntry, it.value()) { + for (TypeEntry *typeEntry : it.value()) { if (typeEntry->isContainer()) returned.append(static_cast<ContainerTypeEntry *>(typeEntry)); } } return returned; } -void TypeDatabase::addRejection(const QString& className, const QString& functionName, - const QString& fieldName, const QString& enumName) + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const TypeRejection &r) { - TypeRejection r; - r.class_name = className; - r.function_name = functionName; - r.field_name = fieldName; - r.enum_name = enumName; + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + d << "TypeRejection(type=" << r.matchType << ", class=" + << r.className.pattern() << ", pattern=" << r.pattern.pattern() << ')'; + return d; +} +#endif // !QT_NO_DEBUG_STREAM +void TypeDatabase::addRejection(const TypeRejection &r) +{ m_rejections << r; } -bool TypeDatabase::isClassRejected(const QString& className) const +static inline QString msgRejectReason(const TypeRejection &r, const QString &needle = QString()) +{ + QString result; + QTextStream str(&result); + switch (r.matchType) { + case TypeRejection::ExcludeClass: + str << " matches class exclusion \"" << r.className.pattern() << '"'; + break; + case TypeRejection::Function: + case TypeRejection::Field: + case TypeRejection::Enum: + str << " matches class \"" << r.className.pattern() << "\" and \"" << r.pattern.pattern() << '"'; + break; + case TypeRejection::ArgumentType: + case TypeRejection::ReturnType: + str << " matches class \"" << r.className.pattern() << "\" and \"" << needle + << "\" matches \"" << r.pattern.pattern() << '"'; + break; + } + return result; +} + +// Match class name only +bool TypeDatabase::isClassRejected(const QString& className, QString *reason) const { - foreach (const TypeRejection& r, m_rejections) { - if (r.class_name == className && r.function_name == QLatin1String("*") - && r.field_name == QLatin1String("*") && r.enum_name == QLatin1String("*")) { + for (const TypeRejection& r : m_rejections) { + if (r.matchType == TypeRejection::ExcludeClass && r.className.match(className).hasMatch()) { + if (reason) + *reason = msgRejectReason(r); return true; } } return false; } -bool TypeDatabase::isEnumRejected(const QString& className, const QString& enumName) const +// Match class name and function/enum/field +static bool findRejection(const QVector<TypeRejection> &rejections, + TypeRejection::MatchType matchType, + const QString& className, const QString& name, + QString *reason = nullptr) { - foreach (const TypeRejection& r, m_rejections) { - if (r.enum_name == enumName - && (r.class_name == className || r.class_name == QLatin1String("*"))) { + Q_ASSERT(matchType != TypeRejection::ExcludeClass); + for (const TypeRejection& r : rejections) { + if (r.matchType == matchType && r.pattern.match(name).hasMatch() + && r.className.match(className).hasMatch()) { + if (reason) + *reason = msgRejectReason(r, name); return true; } } - return false; } +bool TypeDatabase::isEnumRejected(const QString& className, const QString& enumName, QString *reason) const +{ + return findRejection(m_rejections, TypeRejection::Enum, className, enumName, reason); +} + void TypeDatabase::addType(TypeEntry *e) { m_entries[e->qualifiedCppName()].append(e); } -bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName) const +bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName, + QString *reason) const { - foreach (const TypeRejection& r, m_rejections) - if (r.function_name == functionName && - (r.class_name == className || r.class_name == QLatin1String("*"))) - return true; - return false; + return findRejection(m_rejections, TypeRejection::Function, className, functionName, reason); } +bool TypeDatabase::isFieldRejected(const QString& className, const QString& fieldName, + QString *reason) const +{ + return findRejection(m_rejections, TypeRejection::Field, className, fieldName, reason); +} -bool TypeDatabase::isFieldRejected(const QString& className, const QString& fieldName) const +bool TypeDatabase::isArgumentTypeRejected(const QString& className, const QString& typeName, + QString *reason) const { - foreach (const TypeRejection& r, m_rejections) - if (r.field_name == fieldName && - (r.class_name == className || r.class_name == QLatin1String("*"))) - return true; - return false; + return findRejection(m_rejections, TypeRejection::ArgumentType, className, typeName, reason); +} + +bool TypeDatabase::isReturnTypeRejected(const QString& className, const QString& typeName, + QString *reason) const +{ + return findRejection(m_rejections, TypeRejection::ReturnType, className, typeName, reason); } FlagsTypeEntry* TypeDatabase::findFlagsType(const QString &name) const @@ -321,7 +368,7 @@ void TypeDatabase::addGlobalUserFunctions(const AddedFunctionList &functions) AddedFunctionList TypeDatabase::findGlobalUserFunctions(const QString& name) const { AddedFunctionList addedFunctions; - foreach (const AddedFunction &func, m_globalUserFunctions) { + for (const AddedFunction &func : m_globalUserFunctions) { if (func.name() == name) addedFunctions.append(func); } @@ -360,8 +407,7 @@ bool TypeDatabase::isSuppressedWarning(const QString& s) const if (!m_suppressWarnings) return false; - foreach (const QString &_warning, m_suppressedWarnings) { - QString warning = _warning; + for (QString warning : m_suppressedWarnings) { warning.replace(QLatin1String("\\*"), QLatin1String("&place_holder_for_asterisk;")); QStringList segs = warning.split(QLatin1Char('*'), QString::SkipEmptyParts); @@ -389,7 +435,7 @@ QString TypeDatabase::modifiedTypesystemFilepath(const QString& tsFile) const if (tsFi.isFile()) // Make path absolute return tsFi.absoluteFilePath(); const QString fileName = tsFi.fileName(); - foreach (const QString &path, m_typesystemPaths) { + for (const QString &path : m_typesystemPaths) { const QFileInfo fi(path + QLatin1Char('/') + fileName); if (fi.isFile()) return fi.absoluteFilePath(); @@ -440,9 +486,9 @@ bool TypeDatabase::parseFile(QIODevice* device, bool generate) PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const { - QList<TypeEntry*> entries = findTypes(name); + const TypeEntryList &entries = findTypes(name); - foreach (TypeEntry* entry, entries) { + for (TypeEntry *entry : entries) { if (entry && entry->isPrimitive() && static_cast<PrimitiveTypeEntry*>(entry)->preferredTargetLangType()) return static_cast<PrimitiveTypeEntry*>(entry); } @@ -452,8 +498,8 @@ PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const { - QList<TypeEntry*> entries = findTypes(name); - foreach (TypeEntry* entry, entries) { + const TypeEntryList &entries = findTypes(name); + for (TypeEntry *entry : entries) { if (entry && entry->isComplex()) return static_cast<ComplexTypeEntry*>(entry); } @@ -462,8 +508,8 @@ ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const { - QList<TypeEntry*> entries = findTypes(name); - foreach (TypeEntry* entry, entries) { + const TypeEntryList &entries = findTypes(name); + for (TypeEntry *entry : entries) { if (entry && entry->isObject()) return static_cast<ObjectTypeEntry*>(entry); } @@ -472,8 +518,8 @@ ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const NamespaceTypeEntry* TypeDatabase::findNamespaceType(const QString& name) const { - QList<TypeEntry*> entries = findTypes(name); - foreach (TypeEntry* entry, entries) { + const TypeEntryList &entries = findTypes(name); + for (TypeEntry *entry : entries) { if (entry && entry->isNamespace()) return static_cast<NamespaceTypeEntry*>(entry); } @@ -518,13 +564,13 @@ static bool compareTypeEntriesByName(const TypeEntry* t1, const TypeEntry* t2) static void _computeTypeIndexes() { TypeDatabase* tdb = TypeDatabase::instance(); - typedef QMap<int, QList<TypeEntry*> > GroupedTypeEntries; + typedef QMap<int, TypeEntryList> GroupedTypeEntries; GroupedTypeEntries groupedEntries; // Group type entries by revision numbers - TypeEntryHash allEntries = tdb->allEntries(); - foreach (QList<TypeEntry*> entryList, allEntries) { - foreach (TypeEntry* entry, entryList) { + const TypeEntryHash &allEntries = tdb->allEntries(); + for (TypeEntryHash::const_iterator tit = allEntries.cbegin(), end = allEntries.cend(); tit != end; ++tit) { + for (TypeEntry *entry : tit.value()) { if (entry->isPrimitive() || entry->isContainer() || entry->isFunction() @@ -543,12 +589,12 @@ static void _computeTypeIndexes() GroupedTypeEntries::iterator it = groupedEntries.begin(); for (; it != groupedEntries.end(); ++it) { // Remove duplicates - QList<TypeEntry*>::iterator newEnd = std::unique(it.value().begin(), it.value().end()); + TypeEntryList::iterator newEnd = std::unique(it.value().begin(), it.value().end()); it.value().erase(newEnd, it.value().end()); // Sort the type entries by name qSort(it.value().begin(), newEnd, compareTypeEntriesByName); - foreach (TypeEntry* entry, it.value()) { + for (TypeEntry *entry : qAsConst(it.value())) { (*typeEntryFields())[entry].second = maxTypeIndex++; } } diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h index 4255cf458..86f933448 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.h +++ b/sources/shiboken2/ApiExtractor/typedatabase.h @@ -31,6 +31,7 @@ #include "apiextractormacros.h" #include "include.h" +#include "typedatabase_typedefs.h" #include "typesystem_enums.h" #include "typesystem_typedefs.h" @@ -95,16 +96,22 @@ public: SingleTypeEntryHash entries() const; - QList<const PrimitiveTypeEntry*> primitiveTypes() const; + PrimitiveTypeEntryList primitiveTypes() const; - QList<const ContainerTypeEntry*> containerTypes() const; + ContainerTypeEntryList containerTypes() const; - void addRejection(const QString& className, const QString& functionName, - const QString& fieldName, const QString& enumName); - bool isClassRejected(const QString& className) const; - bool isFunctionRejected(const QString& className, const QString& functionName) const; - bool isFieldRejected(const QString& className, const QString& fieldName) const; - bool isEnumRejected(const QString& className, const QString& enumName) const; + void addRejection(const TypeRejection &); + bool isClassRejected(const QString& className, QString *reason = nullptr) const; + bool isFunctionRejected(const QString& className, const QString& functionName, + QString *reason = nullptr) const; + bool isFieldRejected(const QString& className, const QString& fieldName, + QString *reason = nullptr) const; + bool isEnumRejected(const QString& className, const QString& enumName, + QString *reason = nullptr) const; + bool isArgumentTypeRejected(const QString& className, const QString& typeName, + QString *reason = nullptr) const; + bool isReturnTypeRejected(const QString& className, const QString& typeName, + QString *reason = nullptr) const; void addType(TypeEntry* e); @@ -150,7 +157,7 @@ public: void formatDebug(QDebug &d) const; #endif private: - QList<TypeEntry *> findTypes(const QString &name) const; + TypeEntryList findTypes(const QString &name) const; QString modifiedTypesystemFilepath(const QString &tsFile) const; bool m_suppressWarnings; @@ -167,7 +174,7 @@ private: QStringList m_typesystemPaths; QHash<QString, bool> m_parsedTypesystemFiles; - QList<TypeRejection> m_rejections; + QVector<TypeRejection> m_rejections; QStringList m_dropTypeEntries; }; diff --git a/sources/shiboken2/ApiExtractor/asttoxml.h b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h index ed2a04833..95859a399 100644 --- a/sources/shiboken2/ApiExtractor/asttoxml.h +++ b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of PySide2. @@ -26,21 +26,24 @@ ** ****************************************************************************/ +#ifndef TYPEDATABASE_TYPEDEFS_H +#define TYPEDATABASE_TYPEDEFS_H -#ifndef ASTTOXML -#define ASTTOXML - -#include "parser/codemodel_fwd.h" - +#include <QtCore/QHash> #include <QtCore/QString> +#include <QtCore/QVector> -QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter) +class ContainerTypeEntry; +class PrimitiveTypeEntry; +class TemplateEntry; +class TypeEntry; -void astToXML(const QString name); -void writeOutNamespace(QXmlStreamWriter &s, const NamespaceModelItem &item); -void writeOutEnum(QXmlStreamWriter &s, const EnumModelItem &item); -void writeOutFunction(QXmlStreamWriter &s, const FunctionModelItem &item); -void writeOutClass(QXmlStreamWriter &s, const ClassModelItem &item); +typedef QVector<TypeEntry *> TypeEntryList; +typedef QHash<QString, TypeEntryList> TypeEntryHash; +typedef QHash<QString, TypeEntry *> SingleTypeEntryHash; +typedef QHash<QString, TemplateEntry *> TemplateEntryHash; +typedef QVector<const ContainerTypeEntry *> ContainerTypeEntryList; +typedef QVector<const PrimitiveTypeEntry *> PrimitiveTypeEntryList; -#endif // ASTTOXML +#endif // TYPEDATABASE_TYPEDEFS_H diff --git a/sources/shiboken2/ApiExtractor/typeparser.cpp b/sources/shiboken2/ApiExtractor/typeparser.cpp index 67120a1ac..8165bfe44 100644 --- a/sources/shiboken2/ApiExtractor/typeparser.cpp +++ b/sources/shiboken2/ApiExtractor/typeparser.cpp @@ -286,7 +286,7 @@ QString TypeParser::Info::instantiationName() const QString s(qualified_name.join(QLatin1String("::"))); if (!template_instantiations.isEmpty()) { QStringList insts; - foreach (const Info &info, template_instantiations) + for (const Info &info : template_instantiations) insts << info.toString(); s += QLatin1String("< ") + insts.join(QLatin1String(", ")) + QLatin1String(" >"); } diff --git a/sources/shiboken2/ApiExtractor/typeparser.h b/sources/shiboken2/ApiExtractor/typeparser.h index 9ccd0992c..f42c42a5e 100644 --- a/sources/shiboken2/ApiExtractor/typeparser.h +++ b/sources/shiboken2/ApiExtractor/typeparser.h @@ -34,6 +34,7 @@ #include <QtCore/QList> #include <QtCore/QString> #include <QtCore/QStringList> +#include <QtCore/QVector> class TypeParser { @@ -43,7 +44,7 @@ public: Info() : referenceType(NoReference), is_constant(false), is_busted(false), indirections(0) { } QStringList qualified_name; QStringList arrays; - QList<Info> template_instantiations; + QVector<Info> template_instantiations; ReferenceType referenceType; uint is_constant : 1; uint is_busted : 1; diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp index 869904d43..3ec82c56d 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -32,6 +32,7 @@ #include "reporthandler.h" #include <QtCore/QDir> #include <QtCore/QFile> +#include <QtCore/QRegularExpression> #include <QtCore/QXmlStreamAttributes> #include <QtCore/QXmlStreamReader> @@ -47,8 +48,81 @@ static inline QString quoteBeforeLineAttribute() { return QStringLiteral("quote- static inline QString nameAttribute() { return QStringLiteral("name"); } static inline QString sinceAttribute() { return QStringLiteral("since"); } static inline QString flagsAttribute() { return QStringLiteral("flags"); } +static inline QString classAttribute() { return QStringLiteral("class"); } +static inline QString functionNameAttribute() { return QStringLiteral("function-name"); } +static inline QString fieldNameAttribute() { return QStringLiteral("field-name"); } +static inline QString enumNameAttribute() { return QStringLiteral("enum-name"); } +static inline QString argumentTypeAttribute() { return QStringLiteral("argument-type"); } +static inline QString returnTypeAttribute() { return QStringLiteral("return-type"); } + +static QVector<CustomConversion *> customConversionsForReview; + +// Set a regular expression for rejection from text. By legacy, those are fixed +// strings, except for '*' meaning 'match all'. Enclosing in "^..$" +// indicates regular expression. +static bool setRejectionRegularExpression(const QString &patternIn, + QRegularExpression *re, + QString *errorMessage) +{ + QString pattern; + if (patternIn.startsWith(QLatin1Char('^')) && patternIn.endsWith(QLatin1Char('$'))) + pattern = patternIn; + else if (patternIn == QLatin1String("*")) + pattern = QStringLiteral("^.*$"); + else + pattern = QLatin1Char('^') + QRegularExpression::escape(patternIn) + QLatin1Char('$'); + re->setPattern(pattern); + if (!re->isValid()) { + *errorMessage = QLatin1String("Invalid pattern \"") + patternIn + + QLatin1String("\": ") + re->errorString(); + return false; + } + return true; +} + +static bool addRejection(TypeDatabase *database, const QHash<QString, QString> &attributes, + QString *errorMessage) +{ + typedef QPair<QString, TypeRejection::MatchType> AttributeMatchTypePair; + + TypeRejection rejection; + + const QString className = attributes.value(classAttribute()); + if (!setRejectionRegularExpression(className, &rejection.className, errorMessage)) + return false; + + static const AttributeMatchTypePair attributeMatchTypeMapping[] = + {{functionNameAttribute(), TypeRejection::Function}, + {fieldNameAttribute(), TypeRejection::Field}, + {enumNameAttribute(), TypeRejection::Enum}, + {argumentTypeAttribute(), TypeRejection::ArgumentType}, + {returnTypeAttribute(), TypeRejection::ReturnType} + }; + + // Search for non-empty attribute (function, field, enum) + const auto aend = attributes.cend(); + for (const AttributeMatchTypePair &mapping : attributeMatchTypeMapping) { + const auto it = attributes.constFind(mapping.first); + if (it != aend && !it.value().isEmpty()) { + if (!setRejectionRegularExpression(it.value(), &rejection.pattern, errorMessage)) + return false; + rejection.matchType = mapping.second; + database->addRejection(rejection); + return true; + } + } + + // Special case: When all fields except class are empty, completely exclude class + if (className == QLatin1String("*")) { + *errorMessage = QLatin1String("bad reject entry, neither 'class', 'function-name'" + " nor 'field' specified"); + return false; + } + rejection.matchType = TypeRejection::ExcludeClass; + database->addRejection(rejection); + return true; +} -static QList<CustomConversion*> customConversionsForReview = QList<CustomConversion*>(); Handler::Handler(TypeDatabase* database, bool generate) : m_database(database), m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass) @@ -209,8 +283,9 @@ bool Handler::endElement(const QStringRef &localName) if (m_generate == TypeEntry::GenerateAll) { TypeDatabase::instance()->addGlobalUserFunctions(m_contextStack.top()->addedFunctions); TypeDatabase::instance()->addGlobalUserFunctionModifications(m_contextStack.top()->functionMods); - foreach (CustomConversion* customConversion, customConversionsForReview) { - foreach (CustomConversion::TargetToNativeConversion* toNative, customConversion->targetToNativeConversions()) + for (CustomConversion *customConversion : qAsConst(customConversionsForReview)) { + const CustomConversion::TargetToNativeConversions &toNatives = customConversion->targetToNativeConversions(); + for (CustomConversion::TargetToNativeConversion *toNative : toNatives) toNative->setSourceType(m_database->findType(toNative->sourceTypeName())); } } @@ -493,7 +568,8 @@ static QString getNamePrefix(StackElement* element) static QString checkSignatureError(const QString& signature, const QString& tag) { QString funcName = signature.left(signature.indexOf(QLatin1Char('('))).trimmed(); - static QRegExp whiteSpace(QLatin1String("\\s")); + static const QRegularExpression whiteSpace(QStringLiteral("\\s")); + Q_ASSERT(whiteSpace.isValid()); if (!funcName.startsWith(QLatin1String("operator ")) && funcName.contains(whiteSpace)) { return QString::fromLatin1("Error in <%1> tag signature attribute '%2'.\n" "White spaces aren't allowed in function names, " @@ -725,8 +801,9 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts } QString rename = attributes[QLatin1String("rename")]; if (!rename.isEmpty()) { - static QRegExp functionNameRegExp(QLatin1String("^[a-zA-Z_][a-zA-Z0-9_]*$")); - if (!functionNameRegExp.exactMatch(rename)) { + static const QRegularExpression functionNameRegExp(QLatin1String("^[a-zA-Z_][a-zA-Z0-9_]*$")); + Q_ASSERT(functionNameRegExp.isValid()); + if (!functionNameRegExp.match(rename).hasMatch()) { m_error = QLatin1String("can not rename '") + signature + QLatin1String("', '") + rename + QLatin1String("' is not a valid function name"); return false; @@ -850,7 +927,8 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts // put in the flags parallel... const QString flagNames = attributes.value(flagsAttribute()); if (!flagNames.isEmpty()) { - foreach (const QString &flagName, flagNames.split(QLatin1Char(','))) + const QStringList &flagNameList = flagNames.split(QLatin1Char(',')); + for (const QString &flagName : flagNameList) addFlags(name, flagName.trimmed(), attributes, since); } } @@ -1177,10 +1255,12 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts attributes.insert(QLatin1String("to"), QString()); break; case StackElement::Rejection: - attributes.insert(QLatin1String("class"), QLatin1String("*")); - attributes.insert(QLatin1String("function-name"), QLatin1String("*")); - attributes.insert(QLatin1String("field-name"), QLatin1String("*")); - attributes.insert(QLatin1String("enum-name"), QLatin1String("*")); + attributes.insert(classAttribute(), QString()); + attributes.insert(functionNameAttribute(), QString()); + attributes.insert(fieldNameAttribute(), QString()); + attributes.insert(enumNameAttribute(), QString()); + attributes.insert(argumentTypeAttribute(), QString()); + attributes.insert(returnTypeAttribute(), QString()); break; case StackElement::Removal: attributes.insert(QLatin1String("class"), QLatin1String("all")); @@ -1746,8 +1826,8 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts if (rc.action == ReferenceCount::Invalid) { m_error = QLatin1String("unrecognized value for action attribute. supported actions:"); - foreach (const QString &action, actions.keys()) - m_error += QLatin1Char(' ') + action; + for (QHash<QString, ReferenceCount::Action>::const_iterator it = actions.cbegin(), end = actions.cend(); it != end; ++it) + m_error += QLatin1Char(' ') + it.key(); } m_contextStack.top()->functionMods.last().argument_mods.last().referenceCounts.append(rc); @@ -1930,18 +2010,9 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts } } break; - case StackElement::Rejection: { - QString cls = attributes[QLatin1String("class")]; - QString function = attributes[QLatin1String("function-name")]; - QString field = attributes[QLatin1String("field-name")]; - QString enum_ = attributes[QLatin1String("enum-name")]; - if (cls == QLatin1String("*") && function == QLatin1String("*") && field == QLatin1String("*") && enum_ == QLatin1String("*")) { - m_error = QLatin1String("bad reject entry, neither 'class', 'function-name' nor " - "'field' specified"); + case StackElement::Rejection: + if (!addRejection(m_database, attributes, &m_error)) return false; - } - m_database->addRejection(cls, function, field, enum_); - } break; case StackElement::Template: element->value.templateEntry = new TemplateEntry(attributes[nameAttribute()], since); @@ -2172,7 +2243,7 @@ QString TemplateInstance::expandCode() const QString CodeSnipAbstract::code() const { QString res; - foreach (const CodeSnipFragment &codeFrag, codeList) + for (const CodeSnipFragment &codeFrag : codeList) res.append(codeFrag.code()); return res; @@ -2205,7 +2276,7 @@ QString FunctionModification::toString() const if (modifiers & Writable) str += QLatin1String("writable"); if (modifiers & CodeInjection) { - foreach (const CodeSnip &s, snips) { + for (const CodeSnip &s : snips) { str += QLatin1String("\n//code injection:\n"); str += s.code(); } @@ -2254,7 +2325,8 @@ bool FunctionModification::operator==(const FunctionModification& other) const static AddedFunction::TypeInfo parseType(const QString& signature, int startPos = 0, int* endPos = 0) { AddedFunction::TypeInfo result; - QRegExp regex(QLatin1String("\\w")); + static const QRegularExpression regex(QLatin1String("\\w")); + Q_ASSERT(regex.isValid()); int length = signature.length(); int start = signature.indexOf(regex, startPos); if (start == -1) { @@ -2563,9 +2635,7 @@ CustomConversion::CustomConversion(TypeEntry* ownerType) CustomConversion::~CustomConversion() { - foreach (TargetToNativeConversion* targetToNativeConversion, m_d->targetToNativeConversions) - delete targetToNativeConversion; - m_d->targetToNativeConversions.clear(); + qDeleteAll(m_d->targetToNativeConversions); delete m_d; } diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index a8ee0ced4..b75da48ba 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -35,9 +35,11 @@ #include <QtCore/QHash> #include <QtCore/qobjectdefs.h> +#include <QtCore/QRegularExpression> #include <QtCore/QString> #include <QtCore/QStringList> #include <QtCore/QMap> +#include <QtCore/QVector> //Used to identify the conversion rule to avoid break API #define TARGET_CONVERSION_RULE_FLAG "0" @@ -47,6 +49,7 @@ class Indentor; class AbstractMetaType; QT_BEGIN_NAMESPACE +class QDebug; class QTextStream; QT_END_NAMESPACE @@ -103,6 +106,7 @@ private: TemplateInstance *m_instance; public: + CodeSnipFragment() : m_instance(0) {} CodeSnipFragment(const QString &code) : m_code(code), m_instance(0) {} @@ -126,7 +130,7 @@ public: codeList.append(CodeSnipFragment(ti)); } - QList<CodeSnipFragment> codeList; + QVector<CodeSnipFragment> codeList; }; class CustomFunction : public CodeSnipAbstract @@ -194,6 +198,7 @@ private: class CodeSnip : public CodeSnipAbstract { public: + CodeSnip() : language(TypeSystem::TargetLangCode), version(0) {} CodeSnip(double vr) : language(TypeSystem::TargetLangCode), version(vr) { } CodeSnip(double vr, TypeSystem::Language lang) : language(lang), version(vr) { } @@ -205,6 +210,8 @@ public: struct ArgumentModification { + ArgumentModification() : removedDefaultExpression(false), removed(false), + noNullPointers(false), index(-1), version(0) {} ArgumentModification(int idx, double vr) : removedDefaultExpression(false), removed(false), noNullPointers(false), index(idx), version(vr) {} @@ -219,7 +226,7 @@ struct ArgumentModification int index; // Reference count flags for this argument - QList<ReferenceCount> referenceCounts; + QVector<ReferenceCount> referenceCounts; // The text given for the new type of the argument QString modified_type; @@ -344,6 +351,7 @@ struct Modification struct FunctionModification: public Modification { + FunctionModification() : m_thread(false), m_allowThread(false), m_version(0) {} FunctionModification(double vr) : m_thread(false), m_allowThread(false), m_version(vr) {} bool isCodeInjection() const @@ -381,11 +389,9 @@ struct FunctionModification: public Modification QString association; CodeSnipList snips; - QList<ArgumentModification> argument_mods; + QVector<ArgumentModification> argument_mods; private: - FunctionModification() {} - bool m_thread; bool m_allowThread; double m_version; @@ -440,6 +446,7 @@ struct AddedFunction /// Creates a new AddedFunction with a signature and a return type. AddedFunction(QString signature, QString returnType, double vr); + AddedFunction() : m_access(Protected), m_isConst(false), m_isStatic(false), m_version(0) {} /// Returns the function name. QString name() const @@ -466,7 +473,7 @@ struct AddedFunction } /// Returns a list of argument type infos. - QList<TypeInfo> arguments() const + QVector<TypeInfo> arguments() const { return m_arguments; } @@ -496,7 +503,7 @@ struct AddedFunction private: QString m_name; Access m_access; - QList<TypeInfo> m_arguments; + QVector<TypeInfo> m_arguments; TypeInfo m_returnType; bool m_isConst; bool m_isStatic; @@ -525,6 +532,7 @@ class ObjectTypeEntry; class DocModification { public: + DocModification() : format(TypeSystem::NativeCode), m_mode(TypeSystem::DocModificationXPathReplace), m_version(0) {} DocModification(const QString& xpath, const QString& signature, double vr) : format(TypeSystem::NativeCode), m_mode(TypeSystem::DocModificationXPathReplace), m_xpath(xpath), m_signature(signature), m_version(vr) {} @@ -882,7 +890,13 @@ public: } void setInclude(const Include &inc) { - m_include = inc; + // This is a workaround for preventing double inclusion of the QSharedPointer implementation + // header, which does not use header guards. In the previous parser this was not a problem + // because the Q_QDOC define was set, and the implementation header was never included. + if (inc.name() == QLatin1String("qsharedpointer_impl.h")) + m_include = Include(inc.type(), QLatin1String("qsharedpointer.h")); + else + m_include = inc; } // Replace conversionRule arg to CodeSnip in future version @@ -1004,11 +1018,11 @@ public: return m_nestedType; } - QString targetLangName() const + QString targetLangName() const override { return m_nestedType->targetLangName() + QLatin1String("[]"); } - QString targetLangApiName() const + QString targetLangApiName() const override { if (m_nestedType->isPrimitive()) return m_nestedType->targetLangApiName() + QLatin1String("Array"); @@ -1032,7 +1046,7 @@ public: { } - QString targetLangName() const + QString targetLangName() const override { return m_targetLangName; } @@ -1041,7 +1055,7 @@ public: m_targetLangName = targetLangName; } - QString targetLangApiName() const + QString targetLangApiName() const override { return m_targetLangApiName; } @@ -1088,26 +1102,26 @@ public: */ PrimitiveTypeEntry* basicReferencedTypeEntry() const; - virtual bool preferredConversion() const + bool preferredConversion() const override { return m_preferredConversion; } - virtual void setPreferredConversion(bool b) + void setPreferredConversion(bool b) override { m_preferredConversion = b; } - virtual bool preferredTargetLangType() const + bool preferredTargetLangType() const { return m_preferredTargetLangType; } - virtual void setPreferredTargetLangType(bool b) + void setPreferredTargetLangType(bool b) { m_preferredTargetLangType = b; } void setTargetLangPackage(const QString& package); - QString targetLangPackage() const; + QString targetLangPackage() const override; private: QString m_targetLangName; QString m_targetLangApiName; @@ -1119,6 +1133,7 @@ private: struct EnumValueRedirection { + EnumValueRedirection() {} EnumValueRedirection(const QString &rej, const QString &us) : rejected(rej), used(us) @@ -1157,7 +1172,7 @@ public: return m_targetLangName; } QString targetLangQualifier() const; - QString qualifiedTargetLangName() const + QString qualifiedTargetLangName() const override { QString qualifiedName; QString pkg = targetLangPackage(); @@ -1172,7 +1187,7 @@ public: return qualifiedName; } - QString targetLangApiName() const; + QString targetLangApiName() const override; QString qualifier() const { @@ -1183,7 +1198,7 @@ public: m_qualifier = q; } - virtual bool preferredConversion() const + bool preferredConversion() const override { return false; } @@ -1272,7 +1287,7 @@ private: QString m_upperBound; QStringList m_rejectedEnums; - QList<EnumValueRedirection> m_enumRedirections; + QVector<EnumValueRedirection> m_enumRedirections; FlagsTypeEntry *m_flags; @@ -1303,13 +1318,13 @@ public: { } - QString qualifiedTargetLangName() const; - QString targetLangName() const + QString qualifiedTargetLangName() const override; + QString targetLangName() const override { return m_targetLangName; } - QString targetLangApiName() const; - virtual bool preferredConversion() const + QString targetLangApiName() const override; + bool preferredConversion() const override { return false; } @@ -1346,7 +1361,7 @@ public: m_enum = e; } - QString targetLangPackage() const + QString targetLangPackage() const override { return m_enum->targetLangPackage(); } @@ -1414,12 +1429,12 @@ public: m_lookupName = name; } - virtual QString lookupName() const + QString lookupName() const override { return m_lookupName.isEmpty() ? targetLangName() : m_lookupName; } - QString targetLangApiName() const; + QString targetLangApiName() const override; void setTypeFlags(TypeFlags flags) { @@ -1495,7 +1510,7 @@ public: m_defaultSuperclass = sc; } - virtual QString qualifiedCppName() const + QString qualifiedCppName() const override { return m_qualifiedCppName; } @@ -1547,7 +1562,7 @@ public: m_targetType = code; } - QString targetLangName() const + QString targetLangName() const override { return m_targetLangName.isEmpty() ? TypeEntry::targetLangName() @@ -1728,12 +1743,12 @@ class ValueTypeEntry : public ComplexTypeEntry public: ValueTypeEntry(const QString &name, double vr) : ComplexTypeEntry(name, BasicValueType, vr) { } - bool isValue() const + bool isValue() const override { return true; } - virtual bool isNativeIdBased() const + bool isNativeIdBased() const override { return true; } @@ -1752,11 +1767,11 @@ public: setCodeGeneration(GenerateNothing); } - QString targetLangApiName() const; - QString targetLangName() const; - QString targetLangPackage() const; + QString targetLangApiName() const override; + QString targetLangName() const override; + QString targetLangPackage() const override; - virtual bool isNativeIdBased() const + bool isNativeIdBased() const override { return false; } @@ -1770,14 +1785,14 @@ public: setCodeGeneration(GenerateNothing); } - QString targetLangApiName() const; - QString targetLangName() const; - QString targetLangPackage() const + QString targetLangApiName() const override; + QString targetLangName() const override; + QString targetLangPackage() const override { return QString(); } - virtual bool isNativeIdBased() const + bool isNativeIdBased() const override { return false; } @@ -1788,11 +1803,11 @@ class VariantTypeEntry: public ValueTypeEntry public: VariantTypeEntry(const QString &name, double vr) : ValueTypeEntry(name, VariantType, vr) { } - QString targetLangApiName() const; - QString targetLangName() const; - QString targetLangPackage() const; + QString targetLangApiName() const override; + QString targetLangName() const override; + QString targetLangPackage() const override; - virtual bool isNativeIdBased() const + bool isNativeIdBased() const override { return false; } @@ -1819,11 +1834,11 @@ public: m_origin = origin; } - virtual bool isNativeIdBased() const + bool isNativeIdBased() const override { return true; } - virtual QString qualifiedCppName() const + QString qualifiedCppName() const override { const int len = ComplexTypeEntry::qualifiedCppName().length() - interfaceName(QString()).length(); return ComplexTypeEntry::qualifiedCppName().left(len); @@ -1875,7 +1890,7 @@ public: m_interface = entry; } - virtual bool isNativeIdBased() const + bool isNativeIdBased() const override { return true; } @@ -1886,12 +1901,25 @@ private: struct TypeRejection { - QString class_name; - QString function_name; - QString field_name; - QString enum_name; + enum MatchType + { + ExcludeClass, // Match className only + Function, // Match className and function name + Field, // Match className and field name + Enum, // Match className and enum name + ArgumentType, // Match className and argument type + ReturnType // Match className and return type + }; + + QRegularExpression className; + QRegularExpression pattern; + MatchType matchType; }; +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const TypeRejection &r); +#endif + QString fixCppTypeName(const QString &name); class CustomConversion @@ -1932,7 +1960,7 @@ public: bool replaceOriginalTargetToNativeConversions() const; void setReplaceOriginalTargetToNativeConversions(bool replaceOriginalTargetToNativeConversions); - typedef QList<TargetToNativeConversion*> TargetToNativeConversions; + typedef QVector<TargetToNativeConversion*> TargetToNativeConversions; bool hasTargetToNativeConversions() const; TargetToNativeConversions& targetToNativeConversions(); const TargetToNativeConversions& targetToNativeConversions() const; diff --git a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h index 04b669655..4f29deced 100644 --- a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h +++ b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h @@ -31,28 +31,19 @@ #include <QtCore/QHash> #include <QtCore/QList> +#include <QtCore/QVector> class CodeSnip; -class ContainerTypeEntry; class DocModification; -class PrimitiveTypeEntry; -class TemplateEntry; -class TypeEntry; struct AddedFunction; struct FieldModification; struct FunctionModification; -typedef QHash<QString, QList<TypeEntry *> > TypeEntryHash; -typedef QHash<QString, TypeEntry *> SingleTypeEntryHash; -typedef QHash<QString, TemplateEntry *> TemplateEntryHash; - -typedef QList<AddedFunction> AddedFunctionList; -typedef QList<CodeSnip> CodeSnipList; -typedef QList<const ContainerTypeEntry *> ContainerTypeEntryList; -typedef QList<DocModification> DocModificationList; -typedef QList<FieldModification> FieldModificationList; -typedef QList<FunctionModification> FunctionModificationList; -typedef QList<const PrimitiveTypeEntry *> PrimitiveTypeEntryList; +typedef QVector<AddedFunction> AddedFunctionList; +typedef QVector<CodeSnip> CodeSnipList; +typedef QVector<DocModification> DocModificationList; +typedef QVector<FieldModification> FieldModificationList; +typedef QVector<FunctionModification> FunctionModificationList; #endif // TYPESYSTEM_TYPEDEFS_H diff --git a/sources/shiboken2/CMakeLists.txt b/sources/shiboken2/CMakeLists.txt index 96d4ec5cc..ddba62df8 100644 --- a/sources/shiboken2/CMakeLists.txt +++ b/sources/shiboken2/CMakeLists.txt @@ -27,6 +27,47 @@ else() find_package(PythonLibs 2.6) endif() +set(CLANG_DIR "") +set(CLANG_DIR_SOURCE "") + +if (DEFINED ENV{LLVM_INSTALL_DIR}) + set(CLANG_DIR $ENV{LLVM_INSTALL_DIR}) + set(CLANG_DIR_SOURCE "LLVM_INSTALL_DIR") +elseif (DEFINED ENV{CLANG_INSTALL_DIR}) + set(CLANG_DIR $ENV{CLANG_INSTALL_DIR}) + set(CLANG_DIR_SOURCE "CLANG_INSTALL_DIR") +else () + EXEC_PROGRAM("llvm-config" ARGS "--prefix" OUTPUT_VARIABLE CLANG_DIR) + set(CLANG_DIR_SOURCE "llvm-config") + if (NOT "${CLANG_DIR}" STREQUAL "") + EXEC_PROGRAM("llvm-config" ARGS "--version" OUTPUT_VARIABLE CLANG_VERSION) + if (CLANG_VERSION VERSION_LESS 3.9) + message(FATAL_ERROR "LLVM version 3.9 is required (llvm-config detected ${CLANG_VERSION} at ${CLANG_DIR}).") + endif() + endif() +endif() + +if ("${CLANG_DIR}" STREQUAL "") + message(FATAL_ERROR "Unable to detect CLANG location by checking LLVM_INSTALL_DIR, CLANG_INSTALL_DIR or running llvm-config.") +elseif (NOT IS_DIRECTORY ${CLANG_DIR}) + message(FATAL_ERROR "${CLANG_DIR} detected by ${CLANG_DIR_SOURCE} does not exist.") +endif() + +set(CLANG_LIB_NAME "clang") +if(MSVC) + set(CLANG_LIB_NAME "libclang") +endif() + +find_library(CLANG_LIBRARY ${CLANG_LIB_NAME} HINTS ${CLANG_DIR}/lib) +if (NOT EXISTS ${CLANG_LIBRARY}) + message(FATAL_ERROR "Unable to find Clang library ${CLANG_LIB_NAME} in ${CLANG_DIR}.") +endif() + +message(STATUS "CLANG: ${CLANG_DIR}, ${CLANG_LIBRARY} detected by ${CLANG_DIR_SOURCE}") + +set(CLANG_EXTRA_INCLUDES ${CLANG_DIR}/include) +set(CLANG_EXTRA_LIBRARIES ${CLANG_LIBRARY}) + ## For debugging the PYTHON* variables message("PYTHONLIBS_FOUND: " ${PYTHONLIBS_FOUND}) message("PYTHON_LIBRARIES: " ${PYTHON_LIBRARIES}) diff --git a/sources/shiboken2/ext/sparsehash/AUTHORS b/sources/shiboken2/ext/sparsehash/AUTHORS deleted file mode 100644 index ee92be88d..000000000 --- a/sources/shiboken2/ext/sparsehash/AUTHORS +++ /dev/null @@ -1,2 +0,0 @@ -opensource@google.com - diff --git a/sources/shiboken2/ext/sparsehash/COPYING b/sources/shiboken2/ext/sparsehash/COPYING deleted file mode 100644 index e4956cfd9..000000000 --- a/sources/shiboken2/ext/sparsehash/COPYING +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2005, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sources/shiboken2/ext/sparsehash/google/dense_hash_map b/sources/shiboken2/ext/sparsehash/google/dense_hash_map deleted file mode 100644 index 09b0c4428..000000000 --- a/sources/shiboken2/ext/sparsehash/google/dense_hash_map +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright (c) 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ---- -// Author: Craig Silverstein -// -// This is just a very thin wrapper over densehashtable.h, just -// like sgi stl's stl_hash_map is a very thin wrapper over -// stl_hashtable. The major thing we define is operator[], because -// we have a concept of a data_type which stl_hashtable doesn't -// (it only has a key and a value). -// -// NOTE: this is exactly like sparse_hash_map.h, with the word -// "sparse" replaced by "dense", except for the addition of -// set_empty_key(). -// -// YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION. -// -// Otherwise your program will die in mysterious ways. -// -// In other respects, we adhere mostly to the STL semantics for -// hash-map. One important exception is that insert() invalidates -// iterators entirely. On the plus side, though, erase() doesn't -// invalidate iterators at all, or even change the ordering of elements. -// -// Here are a few "power user" tips: -// -// 1) set_deleted_key(): -// If you want to use erase() you *must* call set_deleted_key(), -// in addition to set_empty_key(), after construction. -// The deleted and empty keys must differ. -// -// 2) resize(0): -// When an item is deleted, its memory isn't freed right -// away. This allows you to iterate over a hashtable, -// and call erase(), without invalidating the iterator. -// To force the memory to be freed, call resize(0). -// For tr1 compatibility, this can also be called as rehash(0). -// -// 3) min_load_factor(0.0) -// Setting the minimum load factor to 0.0 guarantees that -// the hash table will never shrink. -// -// Guide to what kind of hash_map to use: -// (1) dense_hash_map: fastest, uses the most memory -// (2) sparse_hash_map: slowest, uses the least memory -// (3) hash_map (STL): in the middle -// Typically I use sparse_hash_map when I care about space and/or when -// I need to save the hashtable on disk. I use hash_map otherwise. I -// don't personally use dense_hash_set ever; some people use it for -// small sets with lots of lookups. -// -// - dense_hash_map has, typically, a factor of 2 memory overhead (if your -// data takes up X bytes, the hash_map uses X more bytes in overhead). -// - sparse_hash_map has about 2 bits overhead per entry. -// - sparse_hash_map can be 3-7 times slower than the others for lookup and, -// especially, inserts. See time_hash_map.cc for details. -// -// See /usr/(local/)?doc/sparsehash-*/dense_hash_map.html -// for information about how to use this class. - -#ifndef _DENSE_HASH_MAP_H_ -#define _DENSE_HASH_MAP_H_ - -#include "google/sparsehash/sparseconfig.h" -#include <stdio.h> // for FILE * in read()/write() -#include <algorithm> // for the default template args -#include <functional> // for equal_to -#include <memory> // for alloc<> -#include <utility> // for pair<> -#include HASH_FUN_H // defined in config.h -#include "google/sparsehash/densehashtable.h" - - -_START_GOOGLE_NAMESPACE_ - -using STL_NAMESPACE::pair; - -template <class Key, class T, - class HashFcn = SPARSEHASH_HASH<Key>, // defined in sparseconfig.h - class EqualKey = STL_NAMESPACE::equal_to<Key>, - class Alloc = STL_NAMESPACE::allocator<T> > -class dense_hash_map { - private: - // Apparently select1st is not stl-standard, so we define our own - struct SelectKey { - const Key& operator()(const pair<const Key, T>& p) const { - return p.first; - } - }; - struct SetKey { - void operator()(pair<const Key, T>* value, const Key& new_key) const { - *const_cast<Key*>(&value->first) = new_key; - // It would be nice to clear the rest of value here as well, in - // case it's taking up a lot of memory. We do this by clearing - // the value. This assumes T has a zero-arg constructor! - value->second = T(); - } - }; - - // The actual data - typedef dense_hashtable<pair<const Key, T>, Key, HashFcn, - SelectKey, SetKey, EqualKey, Alloc> ht; - ht rep; - - public: - typedef typename ht::key_type key_type; - typedef T data_type; - typedef T mapped_type; - typedef typename ht::value_type value_type; - typedef typename ht::hasher hasher; - typedef typename ht::key_equal key_equal; - typedef Alloc allocator_type; - - typedef typename ht::size_type size_type; - typedef typename ht::difference_type difference_type; - typedef typename ht::pointer pointer; - typedef typename ht::const_pointer const_pointer; - typedef typename ht::reference reference; - typedef typename ht::const_reference const_reference; - - typedef typename ht::iterator iterator; - typedef typename ht::const_iterator const_iterator; - typedef typename ht::local_iterator local_iterator; - typedef typename ht::const_local_iterator const_local_iterator; - - // Iterator functions - iterator begin() { return rep.begin(); } - iterator end() { return rep.end(); } - const_iterator begin() const { return rep.begin(); } - const_iterator end() const { return rep.end(); } - - - // These come from tr1's unordered_map. For us, a bucket has 0 or 1 elements. - local_iterator begin(size_type i) { return rep.begin(i); } - local_iterator end(size_type i) { return rep.end(i); } - const_local_iterator begin(size_type i) const { return rep.begin(i); } - const_local_iterator end(size_type i) const { return rep.end(i); } - - // Accessor functions - // TODO(csilvers): implement Alloc get_allocator() const; - hasher hash_funct() const { return rep.hash_funct(); } - hasher hash_function() const { return hash_funct(); } - key_equal key_eq() const { return rep.key_eq(); } - - - // Constructors - explicit dense_hash_map(size_type expected_max_items_in_table = 0, - const hasher& hf = hasher(), - const key_equal& eql = key_equal()) - : rep(expected_max_items_in_table, hf, eql) { } - - template <class InputIterator> - dense_hash_map(InputIterator f, InputIterator l, - size_type expected_max_items_in_table = 0, - const hasher& hf = hasher(), - const key_equal& eql = key_equal()) - : rep(expected_max_items_in_table, hf, eql) { - rep.insert(f, l); - } - // We use the default copy constructor - // We use the default operator=() - // We use the default destructor - - void clear() { rep.clear(); } - // This clears the hash map without resizing it down to the minimum - // bucket count, but rather keeps the number of buckets constant - void clear_no_resize() { rep.clear_no_resize(); } - void swap(dense_hash_map& hs) { rep.swap(hs.rep); } - - - // Functions concerning size - size_type size() const { return rep.size(); } - size_type max_size() const { return rep.max_size(); } - bool empty() const { return rep.empty(); } - size_type bucket_count() const { return rep.bucket_count(); } - size_type max_bucket_count() const { return rep.max_bucket_count(); } - - // These are tr1 methods. bucket() is the bucket the key is or would be in. - size_type bucket_size(size_type i) const { return rep.bucket_size(i); } - size_type bucket(const key_type& key) const { return rep.bucket(key); } - float load_factor() const { - return size() * 1.0f / bucket_count(); - } - float max_load_factor() const { - float shrink, grow; - rep.get_resizing_parameters(&shrink, &grow); - return grow; - } - void max_load_factor(float new_grow) { - float shrink, grow; - rep.get_resizing_parameters(&shrink, &grow); - rep.set_resizing_parameters(shrink, new_grow); - } - // These aren't tr1 methods but perhaps ought to be. - float min_load_factor() const { - float shrink, grow; - rep.get_resizing_parameters(&shrink, &grow); - return shrink; - } - void min_load_factor(float new_shrink) { - float shrink, grow; - rep.get_resizing_parameters(&shrink, &grow); - rep.set_resizing_parameters(new_shrink, grow); - } - // Deprecated; use min_load_factor() or max_load_factor() instead. - void set_resizing_parameters(float shrink, float grow) { - return rep.set_resizing_parameters(shrink, grow); - } - - void resize(size_type hint) { rep.resize(hint); } - void rehash(size_type hint) { resize(hint); } // the tr1 name - - // Lookup routines - iterator find(const key_type& key) { return rep.find(key); } - const_iterator find(const key_type& key) const { return rep.find(key); } - - data_type& operator[](const key_type& key) { // This is our value-add! - iterator it = find(key); - if (it != end()) { - return it->second; - } else { - return insert(value_type(key, data_type())).first->second; - } - } - - size_type count(const key_type& key) const { return rep.count(key); } - - pair<iterator, iterator> equal_range(const key_type& key) { - return rep.equal_range(key); - } - pair<const_iterator, const_iterator> equal_range(const key_type& key) const { - return rep.equal_range(key); - } - - // Insertion routines - pair<iterator, bool> insert(const value_type& obj) { return rep.insert(obj); } - template <class InputIterator> - void insert(InputIterator f, InputIterator l) { rep.insert(f, l); } - void insert(const_iterator f, const_iterator l) { rep.insert(f, l); } - // required for std::insert_iterator; the passed-in iterator is ignored - iterator insert(iterator, const value_type& obj) { return insert(obj).first; } - - - // Deletion and empty routines - // THESE ARE NON-STANDARD! I make you specify an "impossible" key - // value to identify deleted and empty buckets. You can change the - // deleted key as time goes on, or get rid of it entirely to be insert-only. - void set_empty_key(const key_type& key) { // YOU MUST CALL THIS! - rep.set_empty_key(value_type(key, data_type())); // rep wants a value - } - void set_deleted_key(const key_type& key) { - rep.set_deleted_key(key); - } - void clear_deleted_key() { rep.clear_deleted_key(); } - - // These are standard - size_type erase(const key_type& key) { return rep.erase(key); } - void erase(iterator it) { rep.erase(it); } - void erase(iterator f, iterator l) { rep.erase(f, l); } - - - // Comparison - bool operator==(const dense_hash_map& hs) const { return rep == hs.rep; } - bool operator!=(const dense_hash_map& hs) const { return rep != hs.rep; } - - - // I/O -- this is an add-on for writing metainformation to disk - bool write_metadata(FILE *fp) { return rep.write_metadata(fp); } - bool read_metadata(FILE *fp) { return rep.read_metadata(fp); } - bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); } - bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); } -}; - -// We need a global swap as well -template <class Key, class T, class HashFcn, class EqualKey, class Alloc> -inline void swap(dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1, - dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) { - hm1.swap(hm2); -} - -_END_GOOGLE_NAMESPACE_ - -#endif /* _DENSE_HASH_MAP_H_ */ diff --git a/sources/shiboken2/ext/sparsehash/google/dense_hash_set b/sources/shiboken2/ext/sparsehash/google/dense_hash_set deleted file mode 100644 index faa21dc59..000000000 --- a/sources/shiboken2/ext/sparsehash/google/dense_hash_set +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Craig Silverstein -// -// This is just a very thin wrapper over densehashtable.h, just -// like sgi stl's stl_hash_set is a very thin wrapper over -// stl_hashtable. The major thing we define is operator[], because -// we have a concept of a data_type which stl_hashtable doesn't -// (it only has a key and a value). -// -// This is more different from dense_hash_map than you might think, -// because all iterators for sets are const (you obviously can't -// change the key, and for sets there is no value). -// -// NOTE: this is exactly like sparse_hash_set.h, with the word -// "sparse" replaced by "dense", except for the addition of -// set_empty_key(). -// -// YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION. -// -// Otherwise your program will die in mysterious ways. -// -// In other respects, we adhere mostly to the STL semantics for -// hash-set. One important exception is that insert() invalidates -// iterators entirely. On the plus side, though, erase() doesn't -// invalidate iterators at all, or even change the ordering of elements. -// -// Here are a few "power user" tips: -// -// 1) set_deleted_key(): -// If you want to use erase() you must call set_deleted_key(), -// in addition to set_empty_key(), after construction. -// The deleted and empty keys must differ. -// -// 2) resize(0): -// When an item is deleted, its memory isn't freed right -// away. This allows you to iterate over a hashtable, -// and call erase(), without invalidating the iterator. -// To force the memory to be freed, call resize(0). -// For tr1 compatibility, this can also be called as rehash(0). -// -// 3) min_load_factor(0.0) -// Setting the minimum load factor to 0.0 guarantees that -// the hash table will never shrink. -// -// Guide to what kind of hash_set to use: -// (1) dense_hash_set: fastest, uses the most memory -// (2) sparse_hash_set: slowest, uses the least memory -// (3) hash_set (STL): in the middle -// Typically I use sparse_hash_set when I care about space and/or when -// I need to save the hashtable on disk. I use hash_set otherwise. I -// don't personally use dense_hash_set ever; some people use it for -// small sets with lots of lookups. -// -// - dense_hash_set has, typically, a factor of 2 memory overhead (if your -// data takes up X bytes, the hash_set uses X more bytes in overhead). -// - sparse_hash_set has about 2 bits overhead per entry. -// - sparse_hash_map can be 3-7 times slower than the others for lookup and, -// especially, inserts. See time_hash_map.cc for details. -// -// See /usr/(local/)?doc/sparsehash-*/dense_hash_set.html -// for information about how to use this class. - -#ifndef _DENSE_HASH_SET_H_ -#define _DENSE_HASH_SET_H_ - -#include <google/sparsehash/sparseconfig.h> -#include <stdio.h> // for FILE * in read()/write() -#include <algorithm> // for the default template args -#include <functional> // for equal_to -#include <memory> // for alloc<> -#include <utility> // for pair<> -#include HASH_FUN_H // defined in config.h -#include <google/sparsehash/densehashtable.h> - - -_START_GOOGLE_NAMESPACE_ - -using STL_NAMESPACE::pair; - -template <class Value, - class HashFcn = SPARSEHASH_HASH<Value>, // defined in sparseconfig.h - class EqualKey = STL_NAMESPACE::equal_to<Value>, - class Alloc = STL_NAMESPACE::allocator<Value> > -class dense_hash_set { - private: - // Apparently identity is not stl-standard, so we define our own - struct Identity { - Value& operator()(Value& v) const { return v; } - const Value& operator()(const Value& v) const { return v; } - }; - struct SetKey { - void operator()(Value* value, const Value& new_key) const { - *value = new_key; - } - }; - - // The actual data - typedef dense_hashtable<Value, Value, HashFcn, - Identity, SetKey, EqualKey, Alloc> ht; - ht rep; - - public: - typedef typename ht::key_type key_type; - typedef typename ht::value_type value_type; - typedef typename ht::hasher hasher; - typedef typename ht::key_equal key_equal; - typedef Alloc allocator_type; - - typedef typename ht::size_type size_type; - typedef typename ht::difference_type difference_type; - typedef typename ht::const_pointer pointer; - typedef typename ht::const_pointer const_pointer; - typedef typename ht::const_reference reference; - typedef typename ht::const_reference const_reference; - - typedef typename ht::const_iterator iterator; - typedef typename ht::const_iterator const_iterator; - typedef typename ht::const_local_iterator local_iterator; - typedef typename ht::const_local_iterator const_local_iterator; - - - // Iterator functions -- recall all iterators are const - iterator begin() const { return rep.begin(); } - iterator end() const { return rep.end(); } - - // These come from tr1's unordered_set. For us, a bucket has 0 or 1 elements. - local_iterator begin(size_type i) const { return rep.begin(i); } - local_iterator end(size_type i) const { return rep.end(i); } - - - // Accessor functions - hasher hash_funct() const { return rep.hash_funct(); } - key_equal key_eq() const { return rep.key_eq(); } - - - // Constructors - explicit dense_hash_set(size_type expected_max_items_in_table = 0, - const hasher& hf = hasher(), - const key_equal& eql = key_equal()) - : rep(expected_max_items_in_table, hf, eql) { } - - template <class InputIterator> - dense_hash_set(InputIterator f, InputIterator l, - size_type expected_max_items_in_table = 0, - const hasher& hf = hasher(), - const key_equal& eql = key_equal()) - : rep(expected_max_items_in_table, hf, eql) { - rep.insert(f, l); - } - // We use the default copy constructor - // We use the default operator=() - // We use the default destructor - - void clear() { rep.clear(); } - // This clears the hash set without resizing it down to the minimum - // bucket count, but rather keeps the number of buckets constant - void clear_no_resize() { rep.clear_no_resize(); } - void swap(dense_hash_set& hs) { rep.swap(hs.rep); } - - - // Functions concerning size - size_type size() const { return rep.size(); } - size_type max_size() const { return rep.max_size(); } - bool empty() const { return rep.empty(); } - size_type bucket_count() const { return rep.bucket_count(); } - size_type max_bucket_count() const { return rep.max_bucket_count(); } - - // These are tr1 methods. bucket() is the bucket the key is or would be in. - size_type bucket_size(size_type i) const { return rep.bucket_size(i); } - size_type bucket(const key_type& key) const { return rep.bucket(key); } - float load_factor() const { - return size() * 1.0f / bucket_count(); - } - float max_load_factor() const { - float shrink, grow; - rep.get_resizing_parameters(&shrink, &grow); - return grow; - } - void max_load_factor(float new_grow) { - float shrink, grow; - rep.get_resizing_parameters(&shrink, &grow); - rep.set_resizing_parameters(shrink, new_grow); - } - // These aren't tr1 methods but perhaps ought to be. - float min_load_factor() const { - float shrink, grow; - rep.get_resizing_parameters(&shrink, &grow); - return shrink; - } - void min_load_factor(float new_shrink) { - float shrink, grow; - rep.get_resizing_parameters(&shrink, &grow); - rep.set_resizing_parameters(new_shrink, grow); - } - // Deprecated; use min_load_factor() or max_load_factor() instead. - void set_resizing_parameters(float shrink, float grow) { - return rep.set_resizing_parameters(shrink, grow); - } - - void resize(size_type hint) { rep.resize(hint); } - void rehash(size_type hint) { resize(hint); } // the tr1 name - - // Lookup routines - iterator find(const key_type& key) const { return rep.find(key); } - - size_type count(const key_type& key) const { return rep.count(key); } - - pair<iterator, iterator> equal_range(const key_type& key) const { - return rep.equal_range(key); - } - - // Insertion routines - pair<iterator, bool> insert(const value_type& obj) { - pair<typename ht::iterator, bool> p = rep.insert(obj); - return pair<iterator, bool>(p.first, p.second); // const to non-const - } - template <class InputIterator> - void insert(InputIterator f, InputIterator l) { rep.insert(f, l); } - void insert(const_iterator f, const_iterator l) { rep.insert(f, l); } - // required for std::insert_iterator; the passed-in iterator is ignored - iterator insert(iterator, const value_type& obj) { return insert(obj).first; } - - - // Deletion and empty routines - // THESE ARE NON-STANDARD! I make you specify an "impossible" key - // value to identify deleted and empty buckets. You can change the - // deleted key as time goes on, or get rid of it entirely to be insert-only. - void set_empty_key(const key_type& key) { rep.set_empty_key(key); } - void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); } - void clear_deleted_key() { rep.clear_deleted_key(); } - - // These are standard - size_type erase(const key_type& key) { return rep.erase(key); } - void erase(iterator it) { rep.erase(it); } - void erase(iterator f, iterator l) { rep.erase(f, l); } - - - // Comparison - bool operator==(const dense_hash_set& hs) const { return rep == hs.rep; } - bool operator!=(const dense_hash_set& hs) const { return rep != hs.rep; } - - - // I/O -- this is an add-on for writing metainformation to disk - bool write_metadata(FILE *fp) { return rep.write_metadata(fp); } - bool read_metadata(FILE *fp) { return rep.read_metadata(fp); } - bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); } - bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); } -}; - -template <class Val, class HashFcn, class EqualKey, class Alloc> -inline void swap(dense_hash_set<Val, HashFcn, EqualKey, Alloc>& hs1, - dense_hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) { - hs1.swap(hs2); -} - -_END_GOOGLE_NAMESPACE_ - -#endif /* _DENSE_HASH_SET_H_ */ diff --git a/sources/shiboken2/ext/sparsehash/google/sparsehash/densehashtable.h b/sources/shiboken2/ext/sparsehash/google/sparsehash/densehashtable.h deleted file mode 100644 index 33b191ec8..000000000 --- a/sources/shiboken2/ext/sparsehash/google/sparsehash/densehashtable.h +++ /dev/null @@ -1,1062 +0,0 @@ -// Copyright (c) 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Craig Silverstein -// -// A dense hashtable is a particular implementation of -// a hashtable: one that is meant to minimize memory allocation. -// It does this by using an array to store all the data. We -// steal a value from the key space to indicate "empty" array -// elements (ie indices where no item lives) and another to indicate -// "deleted" elements. -// -// (Note it is possible to change the value of the delete key -// on the fly; you can even remove it, though after that point -// the hashtable is insert_only until you set it again. The empty -// value however can't be changed.) -// -// To minimize allocation and pointer overhead, we use internal -// probing, in which the hashtable is a single table, and collisions -// are resolved by trying to insert again in another bucket. The -// most cache-efficient internal probing schemes are linear probing -// (which suffers, alas, from clumping) and quadratic probing, which -// is what we implement by default. -// -// Type requirements: value_type is required to be Copy Constructible -// and Default Constructible. It is not required to be (and commonly -// isn't) Assignable. -// -// You probably shouldn't use this code directly. Use -// <google/dense_hash_map> or <google/dense_hash_set> instead. - -// You can change the following below: -// HT_OCCUPANCY_FLT -- how full before we double size -// HT_EMPTY_FLT -- how empty before we halve size -// HT_MIN_BUCKETS -- default smallest bucket size -// -// You can also change enlarge_resize_percent (which defaults to -// HT_OCCUPANCY_FLT), and shrink_resize_percent (which defaults to -// HT_EMPTY_FLT) with set_resizing_parameters(). -// -// How to decide what values to use? -// shrink_resize_percent's default of .4 * OCCUPANCY_FLT, is probably good. -// HT_MIN_BUCKETS is probably unnecessary since you can specify -// (indirectly) the starting number of buckets at construct-time. -// For enlarge_resize_percent, you can use this chart to try to trade-off -// expected lookup time to the space taken up. By default, this -// code uses quadratic probing, though you can change it to linear -// via _JUMP below if you really want to. -// -// From http://www.augustana.ca/~mohrj/courses/1999.fall/csc210/lecture_notes/hashing.html -// NUMBER OF PROBES / LOOKUP Successful Unsuccessful -// Quadratic collision resolution 1 - ln(1-L) - L/2 1/(1-L) - L - ln(1-L) -// Linear collision resolution [1+1/(1-L)]/2 [1+1/(1-L)2]/2 -// -// -- enlarge_resize_percent -- 0.10 0.50 0.60 0.75 0.80 0.90 0.99 -// QUADRATIC COLLISION RES. -// probes/successful lookup 1.05 1.44 1.62 2.01 2.21 2.85 5.11 -// probes/unsuccessful lookup 1.11 2.19 2.82 4.64 5.81 11.4 103.6 -// LINEAR COLLISION RES. -// probes/successful lookup 1.06 1.5 1.75 2.5 3.0 5.5 50.5 -// probes/unsuccessful lookup 1.12 2.5 3.6 8.5 13.0 50.0 5000.0 - -#ifndef _DENSEHASHTABLE_H_ -#define _DENSEHASHTABLE_H_ - -// The probing method -// Linear probing -// #define JUMP_(key, num_probes) ( 1 ) -// Quadratic-ish probing -#define JUMP_(key, num_probes) ( num_probes ) - - -#include "google/sparsehash/sparseconfig.h" -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> // for abort() -#include <algorithm> // For swap(), eg -#include <iostream> // For cerr -#include <memory> // For uninitialized_fill, uninitialized_copy -#include <utility> // for pair<> -#include <iterator> // for facts about iterator tags -#include "google/type_traits.h" // for true_type, integral_constant, etc. - -_START_GOOGLE_NAMESPACE_ - -using STL_NAMESPACE::pair; - -// Hashtable class, used to implement the hashed associative containers -// hash_set and hash_map. - -// Value: what is stored in the table (each bucket is a Value). -// Key: something in a 1-to-1 correspondence to a Value, that can be used -// to search for a Value in the table (find() takes a Key). -// HashFcn: Takes a Key and returns an integer, the more unique the better. -// ExtractKey: given a Value, returns the unique Key associated with it. -// SetKey: given a Value* and a Key, modifies the value such that -// ExtractKey(value) == key. We guarantee this is only called -// with key == deleted_key or key == empty_key. -// EqualKey: Given two Keys, says whether they are the same (that is, -// if they are both associated with the same Value). -// Alloc: STL allocator to use to allocate memory. Currently ignored. - -template <class Value, class Key, class HashFcn, - class ExtractKey, class SetKey, class EqualKey, class Alloc> -class dense_hashtable; - -template <class V, class K, class HF, class ExK, class SetK, class EqK, class A> -struct dense_hashtable_iterator; - -template <class V, class K, class HF, class ExK, class SetK, class EqK, class A> -struct dense_hashtable_const_iterator; - -// We're just an array, but we need to skip over empty and deleted elements -template <class V, class K, class HF, class ExK, class SetK, class EqK, class A> -struct dense_hashtable_iterator { - public: - typedef dense_hashtable_iterator<V,K,HF,ExK,SetK,EqK,A> iterator; - typedef dense_hashtable_const_iterator<V,K,HF,ExK,SetK,EqK,A> const_iterator; - - typedef STL_NAMESPACE::forward_iterator_tag iterator_category; - typedef V value_type; - typedef STL_NAMESPACE::ptrdiff_t difference_type; - typedef size_t size_type; - typedef V& reference; // Value - typedef V* pointer; - - // "Real" constructor and default constructor - dense_hashtable_iterator(const dense_hashtable<V,K,HF,ExK,SetK,EqK,A> *h, - pointer it, pointer it_end, bool advance) - : ht(h), pos(it), end(it_end) { - if (advance) advance_past_empty_and_deleted(); - } - dense_hashtable_iterator() { } - // The default destructor is fine; we don't define one - // The default operator= is fine; we don't define one - - // Happy dereferencer - reference operator*() const { return *pos; } - pointer operator->() const { return &(operator*()); } - - // Arithmetic. The only hard part is making sure that - // we're not on an empty or marked-deleted array element - void advance_past_empty_and_deleted() { - while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this)) ) - ++pos; - } - iterator& operator++() { - assert(pos != end); ++pos; advance_past_empty_and_deleted(); return *this; - } - iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; } - - // Comparison. - bool operator==(const iterator& it) const { return pos == it.pos; } - bool operator!=(const iterator& it) const { return pos != it.pos; } - - - // The actual data - const dense_hashtable<V,K,HF,ExK,SetK,EqK,A> *ht; - pointer pos, end; -}; - - -// Now do it all again, but with const-ness! -template <class V, class K, class HF, class ExK, class SetK, class EqK, class A> -struct dense_hashtable_const_iterator { - public: - typedef dense_hashtable_iterator<V,K,HF,ExK,SetK,EqK,A> iterator; - typedef dense_hashtable_const_iterator<V,K,HF,ExK,SetK,EqK,A> const_iterator; - - typedef STL_NAMESPACE::forward_iterator_tag iterator_category; - typedef V value_type; - typedef STL_NAMESPACE::ptrdiff_t difference_type; - typedef size_t size_type; - typedef const V& reference; // Value - typedef const V* pointer; - - // "Real" constructor and default constructor - dense_hashtable_const_iterator( - const dense_hashtable<V,K,HF,ExK,SetK,EqK,A> *h, - pointer it, pointer it_end, bool advance) - : ht(h), pos(it), end(it_end) { - if (advance) advance_past_empty_and_deleted(); - } - dense_hashtable_const_iterator() { } - // This lets us convert regular iterators to const iterators - dense_hashtable_const_iterator(const iterator &it) - : ht(it.ht), pos(it.pos), end(it.end) { } - // The default destructor is fine; we don't define one - // The default operator= is fine; we don't define one - - // Happy dereferencer - reference operator*() const { return *pos; } - pointer operator->() const { return &(operator*()); } - - // Arithmetic. The only hard part is making sure that - // we're not on an empty or marked-deleted array element - void advance_past_empty_and_deleted() { - while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this)) ) - ++pos; - } - const_iterator& operator++() { - assert(pos != end); ++pos; advance_past_empty_and_deleted(); return *this; - } - const_iterator operator++(int) { const_iterator tmp(*this); ++*this; return tmp; } - - // Comparison. - bool operator==(const const_iterator& it) const { return pos == it.pos; } - bool operator!=(const const_iterator& it) const { return pos != it.pos; } - - - // The actual data - const dense_hashtable<V,K,HF,ExK,SetK,EqK,A> *ht; - pointer pos, end; -}; - -template <class Value, class Key, class HashFcn, - class ExtractKey, class SetKey, class EqualKey, class Alloc> -class dense_hashtable { - public: - typedef Key key_type; - typedef Value value_type; - typedef HashFcn hasher; - typedef EqualKey key_equal; - - typedef size_t size_type; - typedef STL_NAMESPACE::ptrdiff_t difference_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef dense_hashtable_iterator<Value, Key, HashFcn, - ExtractKey, SetKey, EqualKey, Alloc> - iterator; - - typedef dense_hashtable_const_iterator<Value, Key, HashFcn, - ExtractKey, SetKey, EqualKey, Alloc> - const_iterator; - - // These come from tr1. For us they're the same as regular iterators. - typedef iterator local_iterator; - typedef const_iterator const_local_iterator; - - // How full we let the table get before we resize, by default. - // Knuth says .8 is good -- higher causes us to probe too much, - // though it saves memory. - static const float HT_OCCUPANCY_FLT; // = 0.5; - - // How empty we let the table get before we resize lower, by default. - // (0.0 means never resize lower.) - // It should be less than OCCUPANCY_FLT / 2 or we thrash resizing - static const float HT_EMPTY_FLT; // = 0.4 * HT_OCCUPANCY_FLT - - // Minimum size we're willing to let hashtables be. - // Must be a power of two, and at least 4. - // Note, however, that for a given hashtable, the initial size is a - // function of the first constructor arg, and may be >HT_MIN_BUCKETS. - static const size_t HT_MIN_BUCKETS = 4; - - // By default, if you don't specify a hashtable size at - // construction-time, we use this size. Must be a power of two, and - // at least HT_MIN_BUCKETS. - static const size_t HT_DEFAULT_STARTING_BUCKETS = 32; - - - // ITERATOR FUNCTIONS - iterator begin() { return iterator(this, table, - table + num_buckets, true); } - iterator end() { return iterator(this, table + num_buckets, - table + num_buckets, true); } - const_iterator begin() const { return const_iterator(this, table, - table+num_buckets,true);} - const_iterator end() const { return const_iterator(this, table + num_buckets, - table+num_buckets,true);} - - // These come from tr1 unordered_map. They iterate over 'bucket' n. - // For sparsehashtable, we could consider each 'group' to be a bucket, - // I guess, but I don't really see the point. We'll just consider - // bucket n to be the n-th element of the sparsetable, if it's occupied, - // or some empty element, otherwise. - local_iterator begin(size_type i) { - return local_iterator(this, table + i, table + i+1, false); - } - local_iterator end(size_type i) { - local_iterator it = begin(i); - if (!test_empty(i) && !test_deleted(i)) - ++it; - return it; - } - const_local_iterator begin(size_type i) const { - return const_local_iterator(this, table + i, table + i+1, false); - } - const_local_iterator end(size_type i) const { - const_local_iterator it = begin(i); - if (!test_empty(i) && !test_deleted(i)) - ++it; - return it; - } - - // ACCESSOR FUNCTIONS for the things we templatize on, basically - hasher hash_funct() const { return hash; } - key_equal key_eq() const { return equals; } - - private: - // Annoyingly, we can't copy values around, because they might have - // const components (they're probably pair<const X, Y>). We use - // explicit destructor invocation and placement new to get around - // this. Arg. - void set_value(value_type* dst, const value_type& src) { - dst->~value_type(); - new(dst) value_type(src); - } - - void destroy_buckets(size_type first, size_type last) { - for ( ; first != last; ++first) - table[first].~value_type(); - } - - // DELETE HELPER FUNCTIONS - // This lets the user describe a key that will indicate deleted - // table entries. This key should be an "impossible" entry -- - // if you try to insert it for real, you won't be able to retrieve it! - // (NB: while you pass in an entire value, only the key part is looked - // at. This is just because I don't know how to assign just a key.) - private: - void squash_deleted() { // gets rid of any deleted entries we have - if ( num_deleted ) { // get rid of deleted before writing - dense_hashtable tmp(*this); // copying will get rid of deleted - swap(tmp); // now we are tmp - } - assert(num_deleted == 0); - } - - public: - void set_deleted_key(const key_type &key) { - // the empty indicator (if specified) and the deleted indicator - // must be different - assert(!use_empty || !equals(key, get_key(emptyval))); - // It's only safe to change what "deleted" means if we purge deleted guys - squash_deleted(); - use_deleted = true; - delkey = key; - } - void clear_deleted_key() { - squash_deleted(); - use_deleted = false; - } - - // These are public so the iterators can use them - // True if the item at position bucknum is "deleted" marker - bool test_deleted(size_type bucknum) const { - // The num_deleted test is crucial for read(): after read(), the ht values - // are garbage, and we don't want to think some of them are deleted. - return (use_deleted && num_deleted > 0 && - equals(delkey, get_key(table[bucknum]))); - } - bool test_deleted(const iterator &it) const { - return (use_deleted && num_deleted > 0 && - equals(delkey, get_key(*it))); - } - bool test_deleted(const const_iterator &it) const { - return (use_deleted && num_deleted > 0 && - equals(delkey, get_key(*it))); - } - // Set it so test_deleted is true. true if object didn't used to be deleted - // See below (at erase()) to explain why we allow const_iterators - bool set_deleted(const_iterator &it) { - assert(use_deleted); // bad if set_deleted_key() wasn't called - bool retval = !test_deleted(it); - // &* converts from iterator to value-type - set_key(const_cast<value_type*>(&(*it)), delkey); - return retval; - } - // Set it so test_deleted is false. true if object used to be deleted - bool clear_deleted(const_iterator &it) { - assert(use_deleted); // bad if set_deleted_key() wasn't called - // happens automatically when we assign something else in its place - return test_deleted(it); - } - - // EMPTY HELPER FUNCTIONS - // This lets the user describe a key that will indicate empty (unused) - // table entries. This key should be an "impossible" entry -- - // if you try to insert it for real, you won't be able to retrieve it! - // (NB: while you pass in an entire value, only the key part is looked - // at. This is just because I don't know how to assign just a key.) - public: - // These are public so the iterators can use them - // True if the item at position bucknum is "empty" marker - bool test_empty(size_type bucknum) const { - assert(use_empty); // we always need to know what's empty! - return equals(get_key(emptyval), get_key(table[bucknum])); - } - bool test_empty(const iterator &it) const { - assert(use_empty); // we always need to know what's empty! - return equals(get_key(emptyval), get_key(*it)); - } - bool test_empty(const const_iterator &it) const { - assert(use_empty); // we always need to know what's empty! - return equals(get_key(emptyval), get_key(*it)); - } - - private: - // You can either set a range empty or an individual element - void set_empty(size_type bucknum) { - assert(use_empty); - set_value(&table[bucknum], emptyval); - } - void fill_range_with_empty(value_type* table_start, value_type* table_end) { - // Like set_empty(range), but doesn't destroy previous contents - STL_NAMESPACE::uninitialized_fill(table_start, table_end, emptyval); - } - void set_empty(size_type buckstart, size_type buckend) { - assert(use_empty); - destroy_buckets(buckstart, buckend); - fill_range_with_empty(table + buckstart, table + buckend); - } - - public: - // TODO(csilvers): change all callers of this to pass in a key instead, - // and take a const key_type instead of const value_type. - void set_empty_key(const value_type &val) { - // Once you set the empty key, you can't change it - assert(!use_empty); - // The deleted indicator (if specified) and the empty indicator - // must be different. - assert(!use_deleted || !equals(get_key(val), delkey)); - use_empty = true; - set_value(&emptyval, val); - - assert(!table); // must set before first use - // num_buckets was set in constructor even though table was NULL - table = (value_type *) malloc(num_buckets * sizeof(*table)); - assert(table); - fill_range_with_empty(table, table + num_buckets); - } - - // FUNCTIONS CONCERNING SIZE - public: - size_type size() const { return num_elements - num_deleted; } - // Buckets are always a power of 2 - size_type max_size() const { return (size_type(-1) >> 1U) + 1; } - bool empty() const { return size() == 0; } - size_type bucket_count() const { return num_buckets; } - size_type max_bucket_count() const { return max_size(); } - size_type nonempty_bucket_count() const { return num_elements; } - // These are tr1 methods. Their idea of 'bucket' doesn't map well to - // what we do. We just say every bucket has 0 or 1 items in it. - size_type bucket_size(size_type i) const { - return begin(i) == end(i) ? 0 : 1; - } - - - - private: - // Because of the above, size_type(-1) is never legal; use it for errors - static const size_type ILLEGAL_BUCKET = size_type(-1); - - private: - // This is the smallest size a hashtable can be without being too crowded - // If you like, you can give a min #buckets as well as a min #elts - size_type min_size(size_type num_elts, size_type min_buckets_wanted) { - size_type sz = HT_MIN_BUCKETS; // min buckets allowed - while ( sz < min_buckets_wanted || num_elts >= sz * enlarge_resize_percent ) - sz *= 2; - return sz; - } - - // Used after a string of deletes - void maybe_shrink() { - assert(num_elements >= num_deleted); - assert((bucket_count() & (bucket_count()-1)) == 0); // is a power of two - assert(bucket_count() >= HT_MIN_BUCKETS); - - // If you construct a hashtable with < HT_DEFAULT_STARTING_BUCKETS, - // we'll never shrink until you get relatively big, and we'll never - // shrink below HT_DEFAULT_STARTING_BUCKETS. Otherwise, something - // like "dense_hash_set<int> x; x.insert(4); x.erase(4);" will - // shrink us down to HT_MIN_BUCKETS buckets, which is too small. - if (shrink_threshold > 0 && - (num_elements-num_deleted) < shrink_threshold && - bucket_count() > HT_DEFAULT_STARTING_BUCKETS ) { - size_type sz = bucket_count() / 2; // find how much we should shrink - while ( sz > HT_DEFAULT_STARTING_BUCKETS && - (num_elements - num_deleted) < sz * shrink_resize_percent ) - sz /= 2; // stay a power of 2 - dense_hashtable tmp(*this, sz); // Do the actual resizing - swap(tmp); // now we are tmp - } - consider_shrink = false; // because we just considered it - } - - // We'll let you resize a hashtable -- though this makes us copy all! - // When you resize, you say, "make it big enough for this many more elements" - void resize_delta(size_type delta) { - if ( consider_shrink ) // see if lots of deletes happened - maybe_shrink(); - if ( bucket_count() > HT_MIN_BUCKETS && - (num_elements + delta) <= enlarge_threshold ) - return; // we're ok as we are - - // Sometimes, we need to resize just to get rid of all the - // "deleted" buckets that are clogging up the hashtable. So when - // deciding whether to resize, count the deleted buckets (which - // are currently taking up room). But later, when we decide what - // size to resize to, *don't* count deleted buckets, since they - // get discarded during the resize. - const size_type needed_size = min_size(num_elements + delta, 0); - if ( needed_size > bucket_count() ) { // we don't have enough buckets - const size_type resize_to = min_size(num_elements - num_deleted + delta, - 0); - dense_hashtable tmp(*this, resize_to); - swap(tmp); // now we are tmp - } - } - - // Increase number of buckets, assuming value_type has trivial copy - // constructor and destructor. (Really, we want it to have "trivial - // move", because that's what realloc does. But there's no way to - // capture that using type_traits, so we pretend that move(x, y) is - // equivalent to "x.~T(); new(x) T(y);" which is pretty much - // correct, if a bit conservative.) - void expand_array(size_t resize_to, true_type) { - table = (value_type *) realloc(table, resize_to * sizeof(value_type)); - assert(table); - fill_range_with_empty(table + num_buckets, table + resize_to); - } - - // Increase number of buckets, without special assumptions about value_type. - // TODO(austern): make this exception safe. Handle exceptions from - // value_type's copy constructor. - void expand_array(size_t resize_to, false_type) { - value_type* new_table = - (value_type *) malloc(resize_to * sizeof(value_type)); - assert(new_table); - STL_NAMESPACE::uninitialized_copy(table, table + num_buckets, new_table); - fill_range_with_empty(new_table + num_buckets, new_table + resize_to); - destroy_buckets(0, num_buckets); - free(table); - table = new_table; - } - - // Used to actually do the rehashing when we grow/shrink a hashtable - void copy_from(const dense_hashtable &ht, size_type min_buckets_wanted) { - clear(); // clear table, set num_deleted to 0 - - // If we need to change the size of our table, do it now - const size_type resize_to = min_size(ht.size(), min_buckets_wanted); - if ( resize_to > bucket_count() ) { // we don't have enough buckets - typedef integral_constant<bool, - (has_trivial_copy<value_type>::value && - has_trivial_destructor<value_type>::value)> - realloc_ok; // we pretend mv(x,y) == "x.~T(); new(x) T(y)" - expand_array(resize_to, realloc_ok()); - num_buckets = resize_to; - reset_thresholds(); - } - - // We use a normal iterator to get non-deleted bcks from ht - // We could use insert() here, but since we know there are - // no duplicates and no deleted items, we can be more efficient - assert((bucket_count() & (bucket_count()-1)) == 0); // a power of two - for ( const_iterator it = ht.begin(); it != ht.end(); ++it ) { - size_type num_probes = 0; // how many times we've probed - size_type bucknum; - const size_type bucket_count_minus_one = bucket_count() - 1; - for (bucknum = hash(get_key(*it)) & bucket_count_minus_one; - !test_empty(bucknum); // not empty - bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one) { - ++num_probes; - assert(num_probes < bucket_count()); // or else the hashtable is full - } - set_value(&table[bucknum], *it); // copies the value to here - num_elements++; - } - } - - // Required by the spec for hashed associative container - public: - // Though the docs say this should be num_buckets, I think it's much - // more useful as req_elements. As a special feature, calling with - // req_elements==0 will cause us to shrink if we can, saving space. - void resize(size_type req_elements) { // resize to this or larger - if ( consider_shrink || req_elements == 0 ) - maybe_shrink(); - if ( req_elements > num_elements ) - return resize_delta(req_elements - num_elements); - } - - // Get and change the value of shrink_resize_percent and - // enlarge_resize_percent. The description at the beginning of this - // file explains how to choose the values. Setting the shrink - // parameter to 0.0 ensures that the table never shrinks. - void get_resizing_parameters(float* shrink, float* grow) const { - *shrink = shrink_resize_percent; - *grow = enlarge_resize_percent; - } - void set_resizing_parameters(float shrink, float grow) { - assert(shrink >= 0.0); - assert(grow <= 1.0); - if (shrink > grow/2.0f) - shrink = grow / 2.0f; // otherwise we thrash hashtable size - shrink_resize_percent = shrink; - enlarge_resize_percent = grow; - reset_thresholds(); - } - - // CONSTRUCTORS -- as required by the specs, we take a size, - // but also let you specify a hashfunction, key comparator, - // and key extractor. We also define a copy constructor and =. - // DESTRUCTOR -- needs to free the table - explicit dense_hashtable(size_type expected_max_items_in_table = 0, - const HashFcn& hf = HashFcn(), - const EqualKey& eql = EqualKey(), - const ExtractKey& ext = ExtractKey(), - const SetKey& set = SetKey()) - : hash(hf), equals(eql), get_key(ext), set_key(set), num_deleted(0), - use_deleted(false), use_empty(false), - delkey(), emptyval(), enlarge_resize_percent(HT_OCCUPANCY_FLT), - shrink_resize_percent(HT_EMPTY_FLT), table(NULL), - num_buckets(expected_max_items_in_table == 0 - ? HT_DEFAULT_STARTING_BUCKETS - : min_size(expected_max_items_in_table, 0)), - num_elements(0) { - // table is NULL until emptyval is set. However, we set num_buckets - // here so we know how much space to allocate once emptyval is set - reset_thresholds(); - } - - // As a convenience for resize(), we allow an optional second argument - // which lets you make this new hashtable a different size than ht - dense_hashtable(const dense_hashtable& ht, - size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS) - : hash(ht.hash), equals(ht.equals), - get_key(ht.get_key), set_key(ht.set_key), num_deleted(0), - use_deleted(ht.use_deleted), use_empty(ht.use_empty), - delkey(ht.delkey), emptyval(ht.emptyval), - enlarge_resize_percent(ht.enlarge_resize_percent), - shrink_resize_percent(ht.shrink_resize_percent), table(NULL), - num_buckets(0), num_elements(0) { - reset_thresholds(); - copy_from(ht, min_buckets_wanted); // copy_from() ignores deleted entries - } - - dense_hashtable& operator= (const dense_hashtable& ht) { - if (&ht == this) return *this; // don't copy onto ourselves - clear(); - hash = ht.hash; - equals = ht.equals; - get_key = ht.get_key; - set_key = ht.set_key; - use_deleted = ht.use_deleted; - use_empty = ht.use_empty; - delkey = ht.delkey; - set_value(&emptyval, ht.emptyval); - enlarge_resize_percent = ht.enlarge_resize_percent; - shrink_resize_percent = ht.shrink_resize_percent; - copy_from(ht, HT_MIN_BUCKETS); // sets num_deleted to 0 too - return *this; - } - - ~dense_hashtable() { - if (table) { - destroy_buckets(0, num_buckets); - free(table); - } - } - - // Many STL algorithms use swap instead of copy constructors - void swap(dense_hashtable& ht) { - STL_NAMESPACE::swap(hash, ht.hash); - STL_NAMESPACE::swap(equals, ht.equals); - STL_NAMESPACE::swap(get_key, ht.get_key); - STL_NAMESPACE::swap(set_key, ht.set_key); - STL_NAMESPACE::swap(num_deleted, ht.num_deleted); - STL_NAMESPACE::swap(use_deleted, ht.use_deleted); - STL_NAMESPACE::swap(use_empty, ht.use_empty); - STL_NAMESPACE::swap(enlarge_resize_percent, ht.enlarge_resize_percent); - STL_NAMESPACE::swap(shrink_resize_percent, ht.shrink_resize_percent); - STL_NAMESPACE::swap(delkey, ht.delkey); - { value_type tmp; // for annoying reasons, swap() doesn't work - set_value(&tmp, emptyval); - set_value(&emptyval, ht.emptyval); - set_value(&ht.emptyval, tmp); - } - STL_NAMESPACE::swap(table, ht.table); - STL_NAMESPACE::swap(num_buckets, ht.num_buckets); - STL_NAMESPACE::swap(num_elements, ht.num_elements); - reset_thresholds(); - ht.reset_thresholds(); - } - - // It's always nice to be able to clear a table without deallocating it - void clear() { - if (table) - destroy_buckets(0, num_buckets); - num_buckets = min_size(0,0); // our new size - reset_thresholds(); - table = (value_type *) realloc(table, num_buckets * sizeof(*table)); - assert(table); - fill_range_with_empty(table, table + num_buckets); - num_elements = 0; - num_deleted = 0; - } - - // Clear the table without resizing it. - // Mimicks the stl_hashtable's behaviour when clear()-ing in that it - // does not modify the bucket count - void clear_no_resize() { - if (table) { - set_empty(0, num_buckets); - } - // don't consider to shrink before another erase() - reset_thresholds(); - num_elements = 0; - num_deleted = 0; - } - - // LOOKUP ROUTINES - private: - // Returns a pair of positions: 1st where the object is, 2nd where - // it would go if you wanted to insert it. 1st is ILLEGAL_BUCKET - // if object is not found; 2nd is ILLEGAL_BUCKET if it is. - // Note: because of deletions where-to-insert is not trivial: it's the - // first deleted bucket we see, as long as we don't find the key later - pair<size_type, size_type> find_position(const key_type &key) const { - size_type num_probes = 0; // how many times we've probed - const size_type bucket_count_minus_one = bucket_count() - 1; - size_type bucknum = hash(key) & bucket_count_minus_one; - size_type insert_pos = ILLEGAL_BUCKET; // where we would insert - while ( 1 ) { // probe until something happens - if ( test_empty(bucknum) ) { // bucket is empty - if ( insert_pos == ILLEGAL_BUCKET ) // found no prior place to insert - return pair<size_type,size_type>(ILLEGAL_BUCKET, bucknum); - else - return pair<size_type,size_type>(ILLEGAL_BUCKET, insert_pos); - - } else if ( test_deleted(bucknum) ) {// keep searching, but mark to insert - if ( insert_pos == ILLEGAL_BUCKET ) - insert_pos = bucknum; - - } else if ( equals(key, get_key(table[bucknum])) ) { - return pair<size_type,size_type>(bucknum, ILLEGAL_BUCKET); - } - ++num_probes; // we're doing another probe - bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one; - assert(num_probes < bucket_count()); // don't probe too many times! - } - } - - public: - iterator find(const key_type& key) { - if ( size() == 0 ) return end(); - pair<size_type, size_type> pos = find_position(key); - if ( pos.first == ILLEGAL_BUCKET ) // alas, not there - return end(); - else - return iterator(this, table + pos.first, table + num_buckets, false); - } - - const_iterator find(const key_type& key) const { - if ( size() == 0 ) return end(); - pair<size_type, size_type> pos = find_position(key); - if ( pos.first == ILLEGAL_BUCKET ) // alas, not there - return end(); - else - return const_iterator(this, table + pos.first, table+num_buckets, false); - } - - // This is a tr1 method: the bucket a given key is in, or what bucket - // it would be put in, if it were to be inserted. Shrug. - size_type bucket(const key_type& key) const { - pair<size_type, size_type> pos = find_position(key); - return pos.first == ILLEGAL_BUCKET ? pos.second : pos.first; - } - - // Counts how many elements have key key. For maps, it's either 0 or 1. - size_type count(const key_type &key) const { - pair<size_type, size_type> pos = find_position(key); - return pos.first == ILLEGAL_BUCKET ? 0 : 1; - } - - // Likewise, equal_range doesn't really make sense for us. Oh well. - pair<iterator,iterator> equal_range(const key_type& key) { - iterator pos = find(key); // either an iterator or end - if (pos == end()) { - return pair<iterator,iterator>(pos, pos); - } else { - const iterator startpos = pos++; - return pair<iterator,iterator>(startpos, pos); - } - } - pair<const_iterator,const_iterator> equal_range(const key_type& key) const { - const_iterator pos = find(key); // either an iterator or end - if (pos == end()) { - return pair<const_iterator,const_iterator>(pos, pos); - } else { - const const_iterator startpos = pos++; - return pair<const_iterator,const_iterator>(startpos, pos); - } - } - - - // INSERTION ROUTINES - private: - // If you know *this is big enough to hold obj, use this routine - pair<iterator, bool> insert_noresize(const value_type& obj) { - // First, double-check we're not inserting delkey or emptyval - assert(!use_empty || !equals(get_key(obj), get_key(emptyval))); - assert(!use_deleted || !equals(get_key(obj), delkey)); - const pair<size_type,size_type> pos = find_position(get_key(obj)); - if ( pos.first != ILLEGAL_BUCKET) { // object was already there - return pair<iterator,bool>(iterator(this, table + pos.first, - table + num_buckets, false), - false); // false: we didn't insert - } else { // pos.second says where to put it - if ( test_deleted(pos.second) ) { // just replace if it's been del. - const_iterator delpos(this, table + pos.second, // shrug: - table + num_buckets, false);// shouldn't need const - clear_deleted(delpos); - assert( num_deleted > 0); - --num_deleted; // used to be, now it isn't - } else { - ++num_elements; // replacing an empty bucket - } - set_value(&table[pos.second], obj); - return pair<iterator,bool>(iterator(this, table + pos.second, - table + num_buckets, false), - true); // true: we did insert - } - } - - public: - // This is the normal insert routine, used by the outside world - pair<iterator, bool> insert(const value_type& obj) { - resize_delta(1); // adding an object, grow if need be - return insert_noresize(obj); - } - - // When inserting a lot at a time, we specialize on the type of iterator - template <class InputIterator> - void insert(InputIterator f, InputIterator l) { - // specializes on iterator type - insert(f, l, typename STL_NAMESPACE::iterator_traits<InputIterator>::iterator_category()); - } - - // Iterator supports operator-, resize before inserting - template <class ForwardIterator> - void insert(ForwardIterator f, ForwardIterator l, - STL_NAMESPACE::forward_iterator_tag) { - size_type n = STL_NAMESPACE::distance(f, l); // TODO(csilvers): standard? - resize_delta(n); - for ( ; n > 0; --n, ++f) - insert_noresize(*f); - } - - // Arbitrary iterator, can't tell how much to resize - template <class InputIterator> - void insert(InputIterator f, InputIterator l, - STL_NAMESPACE::input_iterator_tag) { - for ( ; f != l; ++f) - insert(*f); - } - - - // DELETION ROUTINES - size_type erase(const key_type& key) { - // First, double-check we're not trying to erase delkey or emptyval - assert(!use_empty || !equals(key, get_key(emptyval))); - assert(!use_deleted || !equals(key, delkey)); - const_iterator pos = find(key); // shrug: shouldn't need to be const - if ( pos != end() ) { - assert(!test_deleted(pos)); // or find() shouldn't have returned it - set_deleted(pos); - ++num_deleted; - consider_shrink = true; // will think about shrink after next insert - return 1; // because we deleted one thing - } else { - return 0; // because we deleted nothing - } - } - - // This is really evil: really it should be iterator, not const_iterator. - // But...the only reason keys are const is to allow lookup. - // Since that's a moot issue for deleted keys, we allow const_iterators - void erase(const_iterator pos) { - if ( pos == end() ) return; // sanity check - if ( set_deleted(pos) ) { // true if object has been newly deleted - ++num_deleted; - consider_shrink = true; // will think about shrink after next insert - } - } - - void erase(const_iterator f, const_iterator l) { - for ( ; f != l; ++f) { - if ( set_deleted(f) ) // should always be true - ++num_deleted; - } - consider_shrink = true; // will think about shrink after next insert - } - - - // COMPARISON - bool operator==(const dense_hashtable& ht) const { - if (size() != ht.size()) { - return false; - } else if (this == &ht) { - return true; - } else { - // Iterate through the elements in "this" and see if the - // corresponding element is in ht - for ( const_iterator it = begin(); it != end(); ++it ) { - const_iterator it2 = ht.find(get_key(*it)); - if ((it2 == ht.end()) || (*it != *it2)) { - return false; - } - } - return true; - } - } - bool operator!=(const dense_hashtable& ht) const { - return !(*this == ht); - } - - - // I/O - // We support reading and writing hashtables to disk. Alas, since - // I don't know how to write a hasher or key_equal, you have to make - // sure everything but the table is the same. We compact before writing - // - // NOTE: These functions are currently TODO. They've not been implemented. - bool write_metadata(FILE *fp) { - squash_deleted(); // so we don't have to worry about delkey - return false; // TODO - } - - bool read_metadata(FILE *fp) { - num_deleted = 0; // since we got rid before writing - assert(use_empty); // have to set this before calling us - if (table) free(table); // we'll make our own - // TODO: read magic number - // TODO: read num_buckets - reset_thresholds(); - table = (value_type *) malloc(num_buckets * sizeof(*table)); - assert(table); - fill_range_with_empty(table, table + num_buckets); - // TODO: read num_elements - for ( size_type i = 0; i < num_elements; ++i ) { - // TODO: read bucket_num - // TODO: set with non-empty, non-deleted value - } - return false; // TODO - } - - // If your keys and values are simple enough, we can write them to - // disk for you. "simple enough" means value_type is a POD type - // that contains no pointers. However, we don't try to normalize - // endianness - bool write_nopointer_data(FILE *fp) const { - for ( const_iterator it = begin(); it != end(); ++it ) { - // TODO: skip empty/deleted values - if ( !fwrite(&*it, sizeof(*it), 1, fp) ) return false; - } - return false; - } - - // When reading, we have to override the potential const-ness of *it - bool read_nopointer_data(FILE *fp) { - for ( iterator it = begin(); it != end(); ++it ) { - // TODO: skip empty/deleted values - if ( !fread(reinterpret_cast<void*>(&(*it)), sizeof(*it), 1, fp) ) - return false; - } - return false; - } - - private: - // The actual data - hasher hash; // required by hashed_associative_container - key_equal equals; - ExtractKey get_key; - SetKey set_key; - size_type num_deleted; // how many occupied buckets are marked deleted - bool use_deleted; // false until delkey has been set - bool use_empty; // you must do this before you start - // TODO(csilvers): make a pointer, and get rid of use_deleted (benchmark!) - key_type delkey; // which key marks deleted entries - value_type emptyval; // which key marks unused entries - float enlarge_resize_percent; // how full before resize - float shrink_resize_percent; // how empty before resize - size_type shrink_threshold; // num_buckets * shrink_resize_percent - size_type enlarge_threshold; // num_buckets * enlarge_resize_percent - value_type *table; - size_type num_buckets; - size_type num_elements; - bool consider_shrink; // true if we should try to shrink before next insert - - void reset_thresholds() { - enlarge_threshold = static_cast<size_type>(num_buckets - * enlarge_resize_percent); - shrink_threshold = static_cast<size_type>(num_buckets - * shrink_resize_percent); - consider_shrink = false; // whatever caused us to reset already considered - } -}; - -// We need a global swap as well -template <class V, class K, class HF, class ExK, class SetK, class EqK, class A> -inline void swap(dense_hashtable<V,K,HF,ExK,SetK,EqK,A> &x, - dense_hashtable<V,K,HF,ExK,SetK,EqK,A> &y) { - x.swap(y); -} - -#undef JUMP_ - -template <class V, class K, class HF, class ExK, class SetK, class EqK, class A> -const typename dense_hashtable<V,K,HF,ExK,SetK,EqK,A>::size_type -dense_hashtable<V,K,HF,ExK,SetK,EqK,A>::ILLEGAL_BUCKET; - -// How full we let the table get before we resize. Knuth says .8 is -// good -- higher causes us to probe too much, though saves memory. -// However, we go with .5, getting better performance at the cost of -// more space (a trade-off densehashtable explicitly chooses to make). -// Feel free to play around with different values, though. -template <class V, class K, class HF, class ExK, class SetK, class EqK, class A> -const float dense_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_OCCUPANCY_FLT = 0.5f; - -// How empty we let the table get before we resize lower. -// It should be less than OCCUPANCY_FLT / 2 or we thrash resizing -template <class V, class K, class HF, class ExK, class SetK, class EqK, class A> -const float dense_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_EMPTY_FLT - = 0.4f * dense_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_OCCUPANCY_FLT; - -_END_GOOGLE_NAMESPACE_ - -#endif /* _DENSEHASHTABLE_H_ */ diff --git a/sources/shiboken2/ext/sparsehash/google/sparsehash/sparseconfig.h b/sources/shiboken2/ext/sparsehash/google/sparsehash/sparseconfig.h deleted file mode 100644 index 28c85d1f4..000000000 --- a/sources/shiboken2/ext/sparsehash/google/sparsehash/sparseconfig.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * NOTE: This file is for internal use only. - * Do not use these #defines in your own program! - */ - -/* Namespace for Google classes */ -#define GOOGLE_NAMESPACE ::google - -#ifdef _MSC_VER - /* the location of the header defining hash functions */ - #define HASH_FUN_H <unordered_map> - /* the namespace of the hash<> function */ - #define HASH_NAMESPACE stdext - /* The system-provided hash function including the namespace. */ - #define SPARSEHASH_HASH HASH_NAMESPACE::hash_compare -/* libc++ does not implement the tr1 namespce, instead the - * equivalient functionality is placed in namespace std, - * so use when it targeting such systems (OS X 10.7 onwards) */ -#elif defined(_LIBCPP_VERSION) - /* the location of the header defining hash functions */ - #define HASH_FUN_H <functional> - /* the namespace of the hash<> function */ - #define HASH_NAMESPACE std - /* The system-provided hash function including the namespace. */ - #define SPARSEHASH_HASH HASH_NAMESPACE::hash -#else - /* the location of the header defining hash functions */ - #define HASH_FUN_H <tr1/functional> - /* the namespace of the hash<> function */ - #define HASH_NAMESPACE std::tr1 - /* The system-provided hash function including the namespace. */ - #define SPARSEHASH_HASH HASH_NAMESPACE::hash -#endif - -/* Define to 1 if the system has the type `long long'. */ -#define HAVE_LONG_LONG 1 - -/* the namespace where STL code like vector<> is defined */ -#define STL_NAMESPACE std - -/* Stops putting the code inside the Google namespace */ -#define _END_GOOGLE_NAMESPACE_ } - -/* Puts following code inside the Google namespace */ -#define _START_GOOGLE_NAMESPACE_ namespace google { diff --git a/sources/shiboken2/ext/sparsehash/google/type_traits.h b/sources/shiboken2/ext/sparsehash/google/type_traits.h deleted file mode 100644 index d9d4faf83..000000000 --- a/sources/shiboken2/ext/sparsehash/google/type_traits.h +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ---- -// Author: Matt Austern -// -// Define a small subset of tr1 type traits. The traits we define are: -// is_integral -// is_floating_point -// is_pointer -// is_reference -// is_pod -// has_trivial_constructor -// has_trivial_copy -// has_trivial_assign -// has_trivial_destructor -// remove_const -// remove_volatile -// remove_cv -// remove_reference -// remove_pointer -// is_convertible -// We can add more type traits as required. - -#ifndef BASE_TYPE_TRAITS_H_ -#define BASE_TYPE_TRAITS_H_ - -#include "google/sparsehash/sparseconfig.h" -#include <utility> // For pair - -_START_GOOGLE_NAMESPACE_ - -// integral_constant, defined in tr1, is a wrapper for an integer -// value. We don't really need this generality; we could get away -// with hardcoding the integer type to bool. We use the fully -// general integer_constant for compatibility with tr1. - -template<class T, T v> -struct integral_constant { - static const T value = v; - typedef T value_type; - typedef integral_constant<T, v> type; -}; - -template <class T, T v> const T integral_constant<T, v>::value; - -// Abbreviations: true_type and false_type are structs that represent -// boolean true and false values. -typedef integral_constant<bool, true> true_type; -typedef integral_constant<bool, false> false_type; - -// Types small_ and big_ are guaranteed such that sizeof(small_) < -// sizeof(big_) -typedef char small_; - -struct big_ { - char dummy[2]; -}; - -// is_integral is false except for the built-in integer types. -template <class T> struct is_integral : false_type { }; -template<> struct is_integral<bool> : true_type { }; -template<> struct is_integral<char> : true_type { }; -template<> struct is_integral<unsigned char> : true_type { }; -template<> struct is_integral<signed char> : true_type { }; -#if defined(_MSC_VER) -// wchar_t is not by default a distinct type from unsigned short in -// Microsoft C. -// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx -template<> struct is_integral<__wchar_t> : true_type { }; -#else -template<> struct is_integral<wchar_t> : true_type { }; -#endif -template<> struct is_integral<short> : true_type { }; -template<> struct is_integral<unsigned short> : true_type { }; -template<> struct is_integral<int> : true_type { }; -template<> struct is_integral<unsigned int> : true_type { }; -template<> struct is_integral<long> : true_type { }; -template<> struct is_integral<unsigned long> : true_type { }; -#ifdef HAVE_LONG_LONG -template<> struct is_integral<long long> : true_type { }; -template<> struct is_integral<unsigned long long> : true_type { }; -#endif - - -// is_floating_point is false except for the built-in floating-point types. -template <class T> struct is_floating_point : false_type { }; -template<> struct is_floating_point<float> : true_type { }; -template<> struct is_floating_point<double> : true_type { }; -template<> struct is_floating_point<long double> : true_type { }; - - -// is_pointer is false except for pointer types. -template <class T> struct is_pointer : false_type { }; -template <class T> struct is_pointer<T*> : true_type { }; - - -// is_reference is false except for reference types. -template<typename T> struct is_reference : false_type {}; -template<typename T> struct is_reference<T&> : true_type {}; - - -// We can't get is_pod right without compiler help, so fail conservatively. -// We will assume it's false except for arithmetic types and pointers, -// and const versions thereof. Note that std::pair is not a POD. -template <class T> struct is_pod - : integral_constant<bool, (is_integral<T>::value || - is_floating_point<T>::value || - is_pointer<T>::value)> { }; -template <class T> struct is_pod<const T> : is_pod<T> { }; - - -// We can't get has_trivial_constructor right without compiler help, so -// fail conservatively. We will assume it's false except for: (1) types -// for which is_pod is true. (2) std::pair of types with trivial -// constructors. (3) array of a type with a trivial constructor. -// (4) const versions thereof. -template <class T> struct has_trivial_constructor : is_pod<T> { }; -template <class T, class U> struct has_trivial_constructor<std::pair<T, U> > - : integral_constant<bool, - (has_trivial_constructor<T>::value && - has_trivial_constructor<U>::value)> { }; -template <class A, int N> struct has_trivial_constructor<A[N]> - : has_trivial_constructor<A> { }; -template <class T> struct has_trivial_constructor<const T> - : has_trivial_constructor<T> { }; - -// We can't get has_trivial_copy right without compiler help, so fail -// conservatively. We will assume it's false except for: (1) types -// for which is_pod is true. (2) std::pair of types with trivial copy -// constructors. (3) array of a type with a trivial copy constructor. -// (4) const versions thereof. -template <class T> struct has_trivial_copy : is_pod<T> { }; -template <class T, class U> struct has_trivial_copy<std::pair<T, U> > - : integral_constant<bool, - (has_trivial_copy<T>::value && - has_trivial_copy<U>::value)> { }; -template <class A, int N> struct has_trivial_copy<A[N]> - : has_trivial_copy<A> { }; -template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { }; - -// We can't get has_trivial_assign right without compiler help, so fail -// conservatively. We will assume it's false except for: (1) types -// for which is_pod is true. (2) std::pair of types with trivial copy -// constructors. (3) array of a type with a trivial assign constructor. -template <class T> struct has_trivial_assign : is_pod<T> { }; -template <class T, class U> struct has_trivial_assign<std::pair<T, U> > - : integral_constant<bool, - (has_trivial_assign<T>::value && - has_trivial_assign<U>::value)> { }; -template <class A, int N> struct has_trivial_assign<A[N]> - : has_trivial_assign<A> { }; - -// We can't get has_trivial_destructor right without compiler help, so -// fail conservatively. We will assume it's false except for: (1) types -// for which is_pod is true. (2) std::pair of types with trivial -// destructors. (3) array of a type with a trivial destructor. -// (4) const versions thereof. -template <class T> struct has_trivial_destructor : is_pod<T> { }; -template <class T, class U> struct has_trivial_destructor<std::pair<T, U> > - : integral_constant<bool, - (has_trivial_destructor<T>::value && - has_trivial_destructor<U>::value)> { }; -template <class A, int N> struct has_trivial_destructor<A[N]> - : has_trivial_destructor<A> { }; -template <class T> struct has_trivial_destructor<const T> - : has_trivial_destructor<T> { }; - -// Specified by TR1 [4.7.1] -template<typename T> struct remove_const { typedef T type; }; -template<typename T> struct remove_const<T const> { typedef T type; }; -template<typename T> struct remove_volatile { typedef T type; }; -template<typename T> struct remove_volatile<T volatile> { typedef T type; }; -template<typename T> struct remove_cv { - typedef typename remove_const<typename remove_volatile<T>::type>::type type; -}; - - -// Specified by TR1 [4.7.2] -template<typename T> struct remove_reference { typedef T type; }; -template<typename T> struct remove_reference<T&> { typedef T type; }; - -// Specified by TR1 [4.7.4] Pointer modifications. -template<typename T> struct remove_pointer { typedef T type; }; -template<typename T> struct remove_pointer<T*> { typedef T type; }; -template<typename T> struct remove_pointer<T* const> { typedef T type; }; -template<typename T> struct remove_pointer<T* volatile> { typedef T type; }; -template<typename T> struct remove_pointer<T* const volatile> { - typedef T type; }; - -// Specified by TR1 [4.6] Relationships between types -#ifndef _MSC_VER -namespace internal { - -// This class is an implementation detail for is_convertible, and you -// don't need to know how it works to use is_convertible. For those -// who care: we declare two different functions, one whose argument is -// of type To and one with a variadic argument list. We give them -// return types of different size, so we can use sizeof to trick the -// compiler into telling us which function it would have chosen if we -// had called it with an argument of type From. See Alexandrescu's -// _Modern C++ Design_ for more details on this sort of trick. - -template <typename From, typename To> -struct ConvertHelper { - static small_ Test(To); - static big_ Test(...); - static From Create(); -}; -} // namespace internal - -// Inherits from true_type if From is convertible to To, false_type otherwise. -template <typename From, typename To> -struct is_convertible - : integral_constant<bool, - sizeof(internal::ConvertHelper<From, To>::Test( - internal::ConvertHelper<From, To>::Create())) - == sizeof(small_)> { -}; -#endif - -_END_GOOGLE_NAMESPACE_ - -#endif // BASE_TYPE_TRAITS_H_ diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp index d7f98a90f..76d104c12 100644 --- a/sources/shiboken2/generator/generator.cpp +++ b/sources/shiboken2/generator/generator.cpp @@ -36,6 +36,7 @@ #include <QtCore/QDir> #include <QtCore/QFile> #include <QtCore/QFileInfo> +#include <QtCore/QRegularExpression> #include <QDebug> #include <typedatabase.h> @@ -48,18 +49,14 @@ struct Generator::GeneratorPrivate { int numGenerated; QStringList instantiatedContainersNames; QStringList instantiatedSmartPointerNames; - QList<const AbstractMetaType *> instantiatedContainers; - QList<const AbstractMetaType *> instantiatedSmartPointers; + QVector<const AbstractMetaType *> instantiatedContainers; + QVector<const AbstractMetaType *> instantiatedSmartPointers; }; Generator::Generator() : m_d(new GeneratorPrivate) { m_d->numGenerated = 0; - m_d->instantiatedContainers = QList<const AbstractMetaType *>(); - m_d->instantiatedSmartPointers = QList<const AbstractMetaType *>(); - m_d->instantiatedContainersNames = QStringList(); - m_d->instantiatedSmartPointerNames = QStringList(); } Generator::~Generator() @@ -73,7 +70,7 @@ bool Generator::setup(const ApiExtractor& extractor, const QMap< QString, QStrin TypeEntryHash allEntries = TypeDatabase::instance()->allEntries(); TypeEntry* entryFound = 0; for (TypeEntryHash::const_iterator it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) { - foreach (TypeEntry *entry, it.value()) { + for (TypeEntry *entry : it.value()) { if (entry->type() == TypeEntry::TypeSystemType && entry->generateCode()) { entryFound = entry; break; @@ -120,7 +117,8 @@ void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType { if (!type) return; - foreach (const AbstractMetaType* t, type->instantiations()) + const AbstractMetaTypeList &instantiations = type->instantiations(); + for (const AbstractMetaType* t : instantiations) addInstantiatedContainersAndSmartPointers(t, context); if (!type->typeEntry()->isContainer() && !type->typeEntry()->isSmartPointer()) return; @@ -156,7 +154,8 @@ void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType void Generator::collectInstantiatedContainersAndSmartPointers(const AbstractMetaFunction *func) { addInstantiatedContainersAndSmartPointers(func->type(), func->signature()); - foreach (const AbstractMetaArgument* arg, func->arguments()) + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) addInstantiatedContainersAndSmartPointers(arg->type(), func->signature()); } @@ -164,28 +163,33 @@ void Generator::collectInstantiatedContainersAndSmartPointers(const AbstractMeta { if (!metaClass->typeEntry()->generateCode()) return; - foreach (const AbstractMetaFunction* func, metaClass->functions()) + const AbstractMetaFunctionList &funcs = metaClass->functions(); + for (const AbstractMetaFunction *func : funcs) collectInstantiatedContainersAndSmartPointers(func); - foreach (const AbstractMetaField* field, metaClass->fields()) + const AbstractMetaFieldList &fields = metaClass->fields(); + for (const AbstractMetaField *field : fields) addInstantiatedContainersAndSmartPointers(field->type(), field->name()); - foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) + const AbstractMetaClassList &innerClasses = metaClass->innerClasses(); + for (AbstractMetaClass *innerClass : innerClasses) collectInstantiatedContainersAndSmartPointers(innerClass); } void Generator::collectInstantiatedContainersAndSmartPointers() { - foreach (const AbstractMetaFunction* func, globalFunctions()) + const AbstractMetaFunctionList &funcs = globalFunctions(); + for (const AbstractMetaFunction *func : funcs) collectInstantiatedContainersAndSmartPointers(func); - foreach (const AbstractMetaClass* metaClass, classes()) + const AbstractMetaClassList &classList = classes(); + for (const AbstractMetaClass *metaClass : classList) collectInstantiatedContainersAndSmartPointers(metaClass); } -QList<const AbstractMetaType*> Generator::instantiatedContainers() const +QVector<const AbstractMetaType *> Generator::instantiatedContainers() const { return m_d->instantiatedContainers; } -QList<const AbstractMetaType*> Generator::instantiatedSmartPointers() const +QVector<const AbstractMetaType*> Generator::instantiatedSmartPointers() const { return m_d->instantiatedSmartPointers; } @@ -215,12 +219,12 @@ AbstractMetaEnumList Generator::globalEnums() const return m_d->apiextractor->globalEnums(); } -QList<const PrimitiveTypeEntry*> Generator::primitiveTypes() const +PrimitiveTypeEntryList Generator::primitiveTypes() const { return m_d->apiextractor->primitiveTypes(); } -QList<const ContainerTypeEntry*> Generator::containerTypes() const +ContainerTypeEntryList Generator::containerTypes() const { return m_d->apiextractor->containerTypes(); } @@ -351,13 +355,14 @@ QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType *smartP bool Generator::generate() { - foreach (AbstractMetaClass *cls, m_d->apiextractor->classes()) { + const AbstractMetaClassList &classList = m_d->apiextractor->classes(); + for (AbstractMetaClass *cls : classList) { GeneratorContext context(cls); if (!generateFileForContext(context)) return false; } - foreach (const AbstractMetaType *type, instantiatedSmartPointers()) { + for (const AbstractMetaType *type : qAsConst(m_d->instantiatedSmartPointers)) { AbstractMetaClass *smartPointerClass = AbstractMetaClass::findClass(m_d->apiextractor->smartPointers(), type->name()); GeneratorContext context(smartPointerClass, type, true); @@ -394,7 +399,8 @@ void Generator::replaceTemplateVariables(QString &code, const AbstractMetaFuncti if (cpp_class) code.replace(QLatin1String("%TYPE"), cpp_class->name()); - foreach (AbstractMetaArgument *arg, func->arguments()) + const AbstractMetaArgumentList &argument = func->arguments(); + for (AbstractMetaArgument *arg : argument) code.replace(QLatin1Char('%') + QString::number(arg->argumentIndex() + 1), arg->name()); //template values @@ -419,10 +425,11 @@ void Generator::replaceTemplateVariables(QString &code, const AbstractMetaFuncti QTextStream& formatCode(QTextStream &s, const QString& code, Indentor &indentor) { // detect number of spaces before the first character - QStringList lst(code.split(QLatin1Char('\n'))); - QRegExp nonSpaceRegex(QLatin1String("[^\\s]")); + const QStringList lst(code.split(QLatin1Char('\n'))); + static const QRegularExpression nonSpaceRegex(QStringLiteral("[^\\s]")); + Q_ASSERT(nonSpaceRegex.isValid()); int spacesToRemove = 0; - foreach(QString line, lst) { + for (const QString &line : lst) { if (!line.trimmed().isEmpty()) { spacesToRemove = line.indexOf(nonSpaceRegex); if (spacesToRemove == -1) @@ -431,10 +438,11 @@ QTextStream& formatCode(QTextStream &s, const QString& code, Indentor &indentor) } } - static QRegExp emptyLine(QLatin1String("\\s*[\\r]?[\\n]?\\s*")); + static const QRegularExpression emptyLine(QStringLiteral("^\\s*[\\r]?[\\n]?\\s*$")); + Q_ASSERT(emptyLine.isValid()); - foreach(QString line, lst) { - if (!line.isEmpty() && !emptyLine.exactMatch(line)) { + for (QString line : lst) { + if (!line.isEmpty() && !emptyLine.match(line).hasMatch()) { while (line.end()->isSpace()) line.chop(1); int limit = 0; @@ -639,9 +647,9 @@ QString Generator::minimalConstructor(const AbstractMetaClass* metaClass) const if (cType->hasDefaultConstructor()) return cType->defaultConstructor(); - AbstractMetaFunctionList constructors = metaClass->queryFunctions(AbstractMetaClass::Constructors); + const AbstractMetaFunctionList &constructors = metaClass->queryFunctions(AbstractMetaClass::Constructors); int maxArgs = 0; - foreach (const AbstractMetaFunction* ctor, constructors) { + for (const AbstractMetaFunction *ctor : constructors) { if (ctor->isUserAdded() || ctor->isPrivate() || ctor->functionType() != AbstractMetaFunction::ConstructorFunction) continue; @@ -656,28 +664,29 @@ QString Generator::minimalConstructor(const AbstractMetaClass* metaClass) const QString qualifiedCppName = metaClass->typeEntry()->qualifiedCppName(); QStringList templateTypes; - foreach (TypeEntry* templateType, metaClass->templateArguments()) + const QVector<TypeEntry *> &templateArguments = metaClass->templateArguments(); + for (TypeEntry *templateType : templateArguments) templateTypes << templateType->qualifiedCppName(); // Empty constructor. if (maxArgs == 0) return QLatin1String("::") + qualifiedCppName + QLatin1String("()"); - QList<const AbstractMetaFunction*> candidates; + QVector<const AbstractMetaFunction *> candidates; // Constructors with C++ primitive types, enums or pointers only. // Start with the ones with fewer arguments. for (int i = 1; i <= maxArgs; ++i) { - foreach (const AbstractMetaFunction* ctor, constructors) { + for (const AbstractMetaFunction *ctor : constructors) { if (ctor->isUserAdded() || ctor->isPrivate() || ctor->functionType() != AbstractMetaFunction::ConstructorFunction) continue; - AbstractMetaArgumentList arguments = ctor->arguments(); + const AbstractMetaArgumentList &arguments = ctor->arguments(); if (arguments.size() != i) continue; QStringList args; - foreach (const AbstractMetaArgument* arg, arguments) { + for (const AbstractMetaArgument *arg : arguments) { const TypeEntry* type = arg->type()->typeEntry(); if (type == metaClass->typeEntry()) { args.clear(); @@ -715,9 +724,10 @@ QString Generator::minimalConstructor(const AbstractMetaClass* metaClass) const // Constructors with C++ primitive types, enums, pointers, value types, // and user defined primitive types. // Builds the minimal constructor recursively. - foreach (const AbstractMetaFunction* ctor, candidates) { + for (const AbstractMetaFunction *ctor : qAsConst(candidates)) { QStringList args; - foreach (const AbstractMetaArgument* arg, ctor->arguments()) { + const AbstractMetaArgumentList &arguments = ctor->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (arg->type()->typeEntry() == metaClass->typeEntry()) { args.clear(); break; diff --git a/sources/shiboken2/generator/generator.h b/sources/shiboken2/generator/generator.h index f734ff9d7..5ff5d6ae5 100644 --- a/sources/shiboken2/generator/generator.h +++ b/sources/shiboken2/generator/generator.h @@ -30,6 +30,7 @@ #define GENERATOR_H #include <abstractmetalang_typedefs.h> +#include <typedatabase_typedefs.h> #include <dependency.h> #include <QtCore/QObject> #include <QtCore/QSharedPointer> @@ -198,10 +199,10 @@ public: AbstractMetaEnumList globalEnums() const; /// Returns all primitive types found by APIExtractor - QList<const PrimitiveTypeEntry*> primitiveTypes() const; + PrimitiveTypeEntryList primitiveTypes() const; /// Returns all container types found by APIExtractor - QList<const ContainerTypeEntry*> containerTypes() const; + ContainerTypeEntryList containerTypes() const; /// Returns an AbstractMetaEnum for a given EnumTypeEntry, or NULL if not found. const AbstractMetaEnum* findAbstractMetaEnum(const EnumTypeEntry* typeEntry) const; @@ -388,8 +389,8 @@ protected: */ virtual QString subDirectoryForPackage(QString packageName = QString()) const; - QList<const AbstractMetaType*> instantiatedContainers() const; - QList<const AbstractMetaType*> instantiatedSmartPointers() const; + QVector<const AbstractMetaType*> instantiatedContainers() const; + QVector<const AbstractMetaType*> instantiatedSmartPointers() const; static QString getSimplifiedContainerTypeName(const AbstractMetaType *type); void addInstantiatedContainersAndSmartPointers(const AbstractMetaType *type, diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp index 874540e54..25b50b04e 100644 --- a/sources/shiboken2/generator/main.cpp +++ b/sources/shiboken2/generator/main.cpp @@ -156,6 +156,7 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args) return false; QStringList includePaths; + QStringList frameworkIncludePaths; QStringList typesystemPaths; QStringList apiVersions; @@ -176,6 +177,8 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args) if (key == "include-path") includePaths << QDir::toNativeSeparators(value); + else if (key == "framework-include-path") + frameworkIncludePaths << QDir::toNativeSeparators(value); else if (key == "typesystem-path") typesystemPaths << QDir::toNativeSeparators(value); else if (key == "api-version") @@ -191,6 +194,10 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args) if (!includePaths.isEmpty()) args.insert(QLatin1String("include-paths"), includePaths.join(QLatin1String(PATH_SPLITTER))); + if (!frameworkIncludePaths.isEmpty()) + args.insert(QLatin1String("framework-include-paths"), + frameworkIncludePaths.join(QLatin1String(PATH_SPLITTER))); + if (!typesystemPaths.isEmpty()) args.insert(QLatin1String("typesystem-paths"), typesystemPaths.join(QLatin1String(PATH_SPLITTER))); if (!apiVersions.isEmpty()) @@ -206,7 +213,7 @@ static QMap<QString, QString> getInitializedArguments() arguments.removeFirst(); QString projectFileName; - foreach (const QString& arg, arguments) { + for (const QString &arg : qAsConst(arguments)) { if (arg.startsWith(QLatin1String("--project-file"))) { int split = arg.indexOf(QLatin1Char('=')); if (split > 0) @@ -246,7 +253,7 @@ static QMap<QString, QString> getCommandLineArgs() arguments.removeFirst(); int argNum = 0; - foreach (const QString &carg, arguments) { + for (const QString &carg : qAsConst(arguments)) { const QString &arg = carg.trimmed(); if (arg.startsWith(QLatin1String("--"))) { int split = arg.indexOf(QLatin1Char('=')); @@ -301,6 +308,8 @@ void printUsage() QLatin1String("The directory where the generated files will be written")); generalOptions.insert(QLatin1String("include-paths=<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]"), QLatin1String("Include paths used by the C++ parser")); + generalOptions.insert(QLatin1String("framework-include-paths=<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]"), + QLatin1String("Framework include paths used by the C++ parser")); generalOptions.insert(QLatin1String("typesystem-paths=<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]"), QLatin1String("Paths used when searching for typesystems")); generalOptions.insert(QLatin1String("documentation-only"), @@ -318,7 +327,7 @@ void printUsage() printOptions(s, generalOptions); const Generators generators = shibokenGenerators() + docGenerators(); - foreach (const GeneratorPtr &generator, generators) { + for (const GeneratorPtr &generator : generators) { QMap<QString, QString> options = generator->options(); if (!options.isEmpty()) { s << endl << generator->name() << " options:\n"; @@ -437,8 +446,8 @@ int main(int argc, char *argv[]) extractor.setSuppressWarnings(false); if (argsHandler.argExists(QLatin1String("api-version"))) { - QStringList versions = argsHandler.removeArg(QLatin1String("api-version")).split(QLatin1Char('|')); - foreach (const QString &fullVersion, versions) { + const QStringList &versions = argsHandler.removeArg(QLatin1String("api-version")).split(QLatin1Char('|')); + for (const QString &fullVersion : versions) { QStringList parts = fullVersion.split(QLatin1Char(',')); QString package; QString version; @@ -460,8 +469,22 @@ int main(int argc, char *argv[]) extractor.addTypesystemSearchPath(path.split(QLatin1String(PATH_SPLITTER))); path = argsHandler.removeArg(QLatin1String("include-paths")); - if (!path.isEmpty()) - extractor.addIncludePath(path.split(QLatin1String(PATH_SPLITTER))); + if (!path.isEmpty()) { + const QStringList includePathListList = path.split(QLatin1String(PATH_SPLITTER)); + for (const QString &s : qAsConst(includePathListList)) { + const bool isFramework = false; + extractor.addIncludePath(HeaderPath(s, isFramework)); + } + } + + path = argsHandler.removeArg(QLatin1String("framework-include-paths")); + if (!path.isEmpty()) { + const QStringList frameworkPathList = path.split(QLatin1String(PATH_SPLITTER)); + const bool isFramework = true; + for (const QString &s : qAsConst(frameworkPathList)) { + extractor.addIncludePath(HeaderPath(s, isFramework)); + } + } QString cppFileName = argsHandler.removeArg(QLatin1String("arg-1")); QString typeSystemFileName = argsHandler.removeArg(QLatin1String("arg-2")); @@ -478,7 +501,7 @@ int main(int argc, char *argv[]) for ( ; it != projectFileArgs.constEnd(); ++it) argsHandler.removeArg(it.key()); } - foreach (const GeneratorPtr &generator, generators) { + for (const GeneratorPtr &generator : qAsConst(generators)) { QMap<QString, QString> options = generator->options(); if (!options.isEmpty()) { QMap<QString, QString>::const_iterator it = options.constBegin(); @@ -505,7 +528,7 @@ int main(int argc, char *argv[]) qCDebug(lcShiboken) << extractor; - foreach (const GeneratorPtr &g, generators) { + for (const GeneratorPtr &g : qAsConst(generators)) { g->setOutputDirectory(outputDirectory); g->setLicenseComment(licenseComment); if (g->setup(extractor, args)) { diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp index a7a176907..02fd40354 100644 --- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp +++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp @@ -55,7 +55,8 @@ static bool shouldSkip(const AbstractMetaFunction* func) // Search a const clone if (!skipable && !func->isConstant()) { const AbstractMetaArgumentList funcArgs = func->arguments(); - foreach (AbstractMetaFunction* f, func->ownerClass()->functions()) { + const AbstractMetaFunctionList &ownerFunctions = func->ownerClass()->functions(); + for (AbstractMetaFunction *f : ownerFunctions) { if (f != func && f->isConstant() && f->name() == func->name() @@ -202,7 +203,8 @@ QString QtXmlToSphinx::expandFunction(const QString& function) QStringList functionSpec = function.split(QLatin1Char('.')); QString className = functionSpec.first(); const AbstractMetaClass* metaClass = 0; - foreach (const AbstractMetaClass* cls, m_generator->classes()) { + const AbstractMetaClassList &classes = m_generator->classes(); + for (const AbstractMetaClass *cls : classes) { if (cls->name() == className) { metaClass = cls; break; @@ -224,7 +226,8 @@ QString QtXmlToSphinx::resolveContextForMethod(const QString& methodName) QString currentClass = m_context.split(QLatin1Char('.')).last(); const AbstractMetaClass* metaClass = 0; - foreach (const AbstractMetaClass* cls, m_generator->classes()) { + const AbstractMetaClassList &classes = m_generator->classes(); + for (const AbstractMetaClass *cls : classes) { if (cls->name() == currentClass) { metaClass = cls; break; @@ -233,13 +236,14 @@ QString QtXmlToSphinx::resolveContextForMethod(const QString& methodName) if (metaClass) { QList<const AbstractMetaFunction*> funcList; - foreach (const AbstractMetaFunction* func, metaClass->queryFunctionsByName(methodName)) { + const AbstractMetaFunctionList &methods = metaClass->queryFunctionsByName(methodName); + for (const AbstractMetaFunction *func : methods) { if (methodName == func->name()) funcList.append(func); } const AbstractMetaClass* implementingClass = 0; - foreach (const AbstractMetaFunction* func, funcList) { + for (const AbstractMetaFunction *func : qAsConst(funcList)) { implementingClass = func->implementingClass(); if (implementingClass->name() == currentClass) break; @@ -300,7 +304,7 @@ QString QtXmlToSphinx::readFromLocations(const QStringList& locations, const QSt { QString result; bool ok; - foreach (QString location, locations) { + for (QString location : locations) { location.append(QLatin1Char('/')); location.append(path); result = readFromLocation(location, identifier, &ok); @@ -466,7 +470,8 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader) if (code.isEmpty()) { m_output << INDENT << "<Code snippet \"" << location << ':' << identifier << "\" not found>" << endl; } else { - foreach (const QString &line, code.split(QLatin1Char('\n'))) { + const QStringList lines = code.split(QLatin1Char('\n')); + for (const QString &line : lines) { if (!QString(line).trimmed().isEmpty()) m_output << INDENT << line; @@ -577,7 +582,7 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader) if (!m_currentTable.isEmpty()) { if (listType == QLatin1String("bullet")) { m_output << endl; - foreach (TableCell cell, m_currentTable.first()) { + for (const TableCell &cell : m_currentTable.constFirst()) { QStringList itemLines = cell.data.split(QLatin1Char('\n')); m_output << INDENT << "* " << itemLines.first() << endl; for (int i = 1, max = itemLines.count(); i < max; ++i) @@ -714,8 +719,8 @@ void QtXmlToSphinx::handleRawTag(QXmlStreamReader& reader) QString format = reader.attributes().value(QLatin1String("format")).toString(); m_output << INDENT << ".. raw:: " << format.toLower() << endl << endl; } else if (token == QXmlStreamReader::Characters) { - QStringList lst(reader.text().toString().split(QLatin1Char('\n'))); - foreach(QString row, lst) + const QStringList lst(reader.text().toString().split(QLatin1Char('\n'))); + for (const QString &row : lst) m_output << INDENT << INDENT << row << endl; } else if (token == QXmlStreamReader::EndElement) { m_output << endl << endl; @@ -730,8 +735,8 @@ void QtXmlToSphinx::handleCodeTag(QXmlStreamReader& reader) m_output << INDENT << "::" << endl << endl; INDENT.indent++; } else if (token == QXmlStreamReader::Characters) { - QStringList lst(reader.text().toString().split(QLatin1Char('\n'))); - foreach(QString row, lst) + const QStringList lst(reader.text().toString().split(QLatin1Char('\n'))); + for (const QString row : lst) m_output << INDENT << INDENT << row << endl; } else if (token == QXmlStreamReader::EndElement) { m_output << endl << endl; @@ -802,7 +807,8 @@ void QtXmlToSphinx::handleQuoteFileTag(QXmlStreamReader& reader) if (code.isEmpty()) { m_output << INDENT << "<Code snippet \"" << location << "\" not found>" << endl; } else { - foreach (QString line, code.split(QLatin1Char('\n'))) { + const QStringList lines = code.split(QLatin1Char('\n')); + for (const QString &line : lines) { if (!QString(line).trimmed().isEmpty()) m_output << INDENT << line; @@ -882,8 +888,8 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table) for (int i = 0, maxI = table.count(); i < maxI; ++i) { const QtXmlToSphinx::TableRow& row = table[i]; for (int j = 0, maxJ = std::min(row.count(), colWidths.size()); j < maxJ; ++j) { - QStringList rowLines = row[j].data.split(QLatin1Char('\n')); // cache this would be a good idea - foreach (QString str, rowLines) + const QStringList rowLines = row[j].data.split(QLatin1Char('\n')); // cache this would be a good idea + for (const QString &str : rowLines) colWidths[j] = std::max(colWidths[j], str.count()); rowHeights[i] = std::max(rowHeights[i], row[j].data.count(QLatin1Char('\n')) + 1); } @@ -1018,16 +1024,16 @@ void QtDocGenerator::writeFormatedText(QTextStream& s, const Documentation& doc, QtXmlToSphinx x(this, doc.value(), metaClassName); s << x; } else { - QStringList lines = doc.value().split(QLatin1Char('\n')); + const QStringList lines = doc.value().split(QLatin1Char('\n')); QRegExp regex(QLatin1String("\\S")); // non-space character int typesystemIndentation = std::numeric_limits<int>().max(); // check how many spaces must be removed from the begining of each line - foreach (QString line, lines) { + for (const QString &line : lines) { int idx = line.indexOf(regex); if (idx >= 0) typesystemIndentation = qMin(typesystemIndentation, idx); } - foreach (QString line, lines) + for (QString line : lines) s << INDENT << line.remove(0, typesystemIndentation) << endl; } @@ -1037,7 +1043,7 @@ void QtDocGenerator::writeFormatedText(QTextStream& s, const Documentation& doc, static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaClass, const AbstractMetaClassList& allClasses) { AbstractMetaClassList res; - foreach (AbstractMetaClass* c, allClasses) { + for (AbstractMetaClass *c : allClasses) { if (c != metaClass && c->inheritsFrom(metaClass)) res << c; } @@ -1047,7 +1053,7 @@ static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaCl s << "**Inherited by:** "; QStringList classes; - foreach (AbstractMetaClass* c, res) + for (AbstractMetaClass *c : qAsConst(res)) classes << QLatin1String(":ref:`") + getClassTargetFullName(c, false) + QLatin1Char('`'); s << classes.join(QLatin1String(", ")) << endl << endl; } @@ -1098,7 +1104,7 @@ void QtDocGenerator::generateClass(QTextStream &s, GeneratorContext &classContex writeFields(s, metaClass); - foreach (AbstractMetaFunction* func, functionList) { + for (AbstractMetaFunction *func : qAsConst(functionList)) { if (shouldSkip(func)) continue; @@ -1121,7 +1127,8 @@ void QtDocGenerator::writeFunctionList(QTextStream& s, const AbstractMetaClass* QStringList slotList; QStringList staticFunctionList; - foreach (AbstractMetaFunction* func, cppClass->functions()) { + const AbstractMetaFunctionList &classFunctions = cppClass->functions(); + for (AbstractMetaFunction *func : classFunctions) { if (shouldSkip(func)) continue; @@ -1180,7 +1187,7 @@ void QtDocGenerator::writeFunctionBlock(QTextStream& s, const QString& title, QS s << ".. container:: function_list" << endl << endl; Indentation indentation(INDENT); - foreach (QString func, functions) + for (const QString &func : qAsConst(functions)) s << '*' << INDENT << func << endl; s << endl << endl; @@ -1191,7 +1198,8 @@ void QtDocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClas { static const QString section_title = QLatin1String(".. attribute:: "); - foreach (AbstractMetaEnum* en, cppClass->enums()) { + const AbstractMetaEnumList &enums = cppClass->enums(); + for (AbstractMetaEnum *en : enums) { s << section_title << getClassTargetFullName(cppClass) << '.' << en->name() << endl << endl; writeFormatedText(s, en->documentation(), cppClass); @@ -1205,7 +1213,8 @@ void QtDocGenerator::writeFields(QTextStream& s, const AbstractMetaClass* cppCla { static const QString section_title = QLatin1String(".. attribute:: "); - foreach (AbstractMetaField* field, cppClass->fields()) { + const AbstractMetaFieldList &fields = cppClass->fields(); + for (AbstractMetaField *field : fields) { s << section_title << getClassTargetFullName(cppClass) << "." << field->name() << endl << endl; //TODO: request for member ‘documentation’ is ambiguous writeFormatedText(s, field->AbstractMetaAttributes::documentation(), cppClass); @@ -1217,12 +1226,12 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass* static const QString sectionTitle = QLatin1String(".. class:: "); static const QString sectionTitleSpace = QString(sectionTitle.size(), QLatin1Char(' ')); - AbstractMetaFunctionList lst = cppClass->queryFunctions(AbstractMetaClass::Constructors | AbstractMetaClass::Visible); + const AbstractMetaFunctionList lst = cppClass->queryFunctions(AbstractMetaClass::Constructors | AbstractMetaClass::Visible); bool first = true; QHash<QString, AbstractMetaArgument*> arg_map; - foreach(AbstractMetaFunction* func, lst) { + for (AbstractMetaFunction *func : lst) { if (func->isModifiedRemoved()) continue; @@ -1233,8 +1242,8 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass* s << sectionTitleSpace; } writeFunction(s, false, cppClass, func); - foreach(AbstractMetaArgument* arg, func->arguments()) - { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (AbstractMetaArgument *arg : arguments) { if (!arg_map.contains(arg->name())) { arg_map.insert(arg->name(), arg); } @@ -1243,16 +1252,15 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass* s << endl; - foreach (AbstractMetaArgument* arg, arg_map.values()) { + for (QHash<QString, AbstractMetaArgument*>::const_iterator it = arg_map.cbegin(), end = arg_map.cend(); it != end; ++it) { Indentation indentation(INDENT); - writeParamerteType(s, cppClass, arg); + writeParamerteType(s, cppClass, it.value()); } s << endl; - foreach (AbstractMetaFunction* func, lst) { + for (AbstractMetaFunction *func : lst) writeFormatedText(s, func->documentation(), cppClass); - } } QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* cppClass, const AbstractMetaFunction* func) @@ -1260,7 +1268,8 @@ QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* cppClass, cons QString ret; int optArgs = 0; - foreach (AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (AbstractMetaArgument *arg : arguments) { if (func->argumentRemoved(arg->argumentIndex() + 1)) continue; @@ -1311,7 +1320,7 @@ void QtDocGenerator::writeDocSnips(QTextStream &s, invalidStrings << QLatin1String("*") << QLatin1String("//") << QLatin1String("/*") << QLatin1String("*/"); - foreach (CodeSnip snip, codeSnips) { + for (const CodeSnip &snip : codeSnips) { if ((snip.position != position) || !(snip.language & language)) continue; @@ -1325,14 +1334,13 @@ void QtDocGenerator::writeDocSnips(QTextStream &s, break; QString codeBlock = code.mid(startBlock, endBlock - startBlock); - QStringList rows = codeBlock.split(QLatin1Char('\n')); + const QStringList rows = codeBlock.split(QLatin1Char('\n')); int currenRow = 0; int offset = 0; - foreach(QString row, rows) { - foreach(QString invalidString, invalidStrings) { - row = row.remove(invalidString); - } + for (QString row : rows) { + for (const QString &invalidString : qAsConst(invalidStrings)) + row.remove(invalidString); if (row.trimmed().size() == 0) { if (currenRow == 0) @@ -1370,7 +1378,8 @@ bool QtDocGenerator::writeInjectDocumentation(QTextStream& s, Indentation indentation(INDENT); bool didSomething = false; - foreach (DocModification mod, cppClass->typeEntry()->docModifications()) { + const DocModificationList &mods = cppClass->typeEntry()->docModifications(); + for (const DocModification &mod : mods) { if (mod.mode() == mode) { bool modOk = func ? mod.signature() == func->minimalSignature() : mod.signature().isEmpty(); @@ -1473,7 +1482,8 @@ void QtDocGenerator::writeFunctionParametersType(QTextStream& s, const AbstractM Indentation indentation(INDENT); s << endl; - foreach (AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &funcArgs = func->arguments(); + for (AbstractMetaArgument *arg : funcArgs) { if (func->argumentRemoved(arg->argumentIndex() + 1)) continue; @@ -1485,8 +1495,9 @@ void QtDocGenerator::writeFunctionParametersType(QTextStream& s, const AbstractM QString retType; // check if the return type was modified - foreach (FunctionModification mod, func->modifications()) { - foreach (ArgumentModification argMod, mod.argument_mods) { + const FunctionModificationList &mods = func->modifications(); + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argMod : mod.argument_mods) { if (argMod.index == 0) { retType = argMod.modified_type; break; @@ -1526,7 +1537,7 @@ static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 4 TocMap tocMap; QChar Q = QLatin1Char('Q'); QChar idx; - foreach (QString item, items) { + for (QString item : items) { if (item.isEmpty()) continue; if (item.startsWith(Q) && item.length() > 1) @@ -1551,7 +1562,7 @@ static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 4 ss << "**" << it.key() << "**" << endl << endl; i += 2; // a letter title is equivalent to two entries in space - foreach (QString item, it.value()) { + for (const QString &item : qAsConst(it.value())) { ss << "* :doc:`" << item << "`" << endl; ++i; @@ -1628,7 +1639,7 @@ bool QtDocGenerator::finishGeneration() s << INDENT << ".. toctree::" << endl; Indentation deeperIndentation(INDENT); s << INDENT << ":maxdepth: 1" << endl << endl; - foreach (QString className, it.value()) + for (const QString &className : qAsConst(it.value())) s << INDENT << className << endl; s << endl << endl; } diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 68b62477e..6aa2c83df 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -36,6 +36,7 @@ #include <QtCore/QDir> #include <QtCore/QMetaObject> +#include <QtCore/QRegularExpression> #include <QtCore/QTextStream> #include <QtCore/QDebug> #include <QMetaType> @@ -153,13 +154,15 @@ QString CppGenerator::fileNameForContext(GeneratorContext &context) const } } -QList<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(const AbstractMetaClass* metaClass, +QVector<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(const AbstractMetaClass* metaClass, uint queryIn) { // ( func_name, num_args ) => func_list - QMap<QPair<QString, int >, AbstractMetaFunctionList> results; + typedef QMap<QPair<QString, int >, AbstractMetaFunctionList> ResultMap; + ResultMap results; const AbstractMetaClass::OperatorQueryOptions query(queryIn); - foreach (AbstractMetaFunction* func, metaClass->operatorOverloads(query)) { + const AbstractMetaFunctionList &funcs = metaClass->operatorOverloads(query); + for (AbstractMetaFunction *func : funcs) { if (func->isModifiedRemoved() || func->usesRValueReferences() || func->name() == QLatin1String("operator[]") @@ -176,7 +179,11 @@ QList<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(con QPair<QString, int > op(func->name(), args); results[op].append(func); } - return results.values(); + QVector<AbstractMetaFunctionList> result; + result.reserve(results.size()); + for (ResultMap::const_iterator it = results.cbegin(), end = results.cend(); it != end; ++it) + result.append(it.value()); + return result; } bool CppGenerator::hasBoolCast(const AbstractMetaClass* metaClass) const @@ -203,6 +210,13 @@ static const char includeQDebug[] = "#endif\n" "#include <QDebug>\n"; +static QString chopType(QString s) +{ + if (s.endsWith(QLatin1String("_Type"))) + s.chop(5); + return s; +} + /*! Function used to write the class generated binding code on the buffer \param s the output buffer @@ -263,7 +277,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) } s << endl << "// inner classes" << endl; - foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) { + const AbstractMetaClassList &innerClasses = metaClass->innerClasses(); + for (AbstractMetaClass *innerClass : innerClasses) { GeneratorContext innerClassContext(innerClass); if (shouldGenerate(innerClass)) { QString headerfile = fileNameForContext(innerClassContext); @@ -273,16 +288,16 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) } AbstractMetaEnumList classEnums = metaClass->enums(); - foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) + for (AbstractMetaClass *innerClass : innerClasses) lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass); //Extra includes s << endl << "// Extra includes" << endl; - QList<Include> includes = metaClass->typeEntry()->extraIncludes(); - foreach (AbstractMetaEnum* cppEnum, classEnums) + QVector<Include> includes = metaClass->typeEntry()->extraIncludes(); + for (AbstractMetaEnum *cppEnum : qAsConst(classEnums)) includes.append(cppEnum->typeEntry()->extraIncludes()); qSort(includes.begin(), includes.end()); - foreach (const Include &inc, includes) + for (const Include &inc : qAsConst(includes)) s << inc.toString() << endl; s << endl; @@ -335,7 +350,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) s << "}\n\n"; } - foreach (const AbstractMetaFunction* func, filterFunctions(metaClass)) { + const AbstractMetaFunctionList &funcs = filterFunctions(metaClass); + for (const AbstractMetaFunction *func : funcs) { if ((func->isPrivate() && !visibilityModifiedToPrivate(func)) || (func->isModifiedRemoved() && !func->isAbstract())) continue; @@ -366,7 +382,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { AbstractMetaFunctionList overloads; QSet<QString> seenSignatures; - foreach (AbstractMetaFunction* func, it.value()) { + for (AbstractMetaFunction *func : it.value()) { if (!func->isAssignmentOperator() && !func->usesRValueReferences() && !func->isCastOperator() @@ -439,8 +455,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) } } - QString className = cpythonTypeName(metaClass); - className.remove(QRegExp(QLatin1String("_Type$"))); + const QString className = chopType(cpythonTypeName(metaClass)); if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) writeCopyFunction(s, classContext); @@ -487,15 +502,15 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) } if (supportsNumberProtocol(metaClass) && !metaClass->typeEntry()->isSmartPointer()) { - QList<AbstractMetaFunctionList> opOverloads = filterGroupedOperatorFunctions( + const QVector<AbstractMetaFunctionList> opOverloads = filterGroupedOperatorFunctions( metaClass, AbstractMetaClass::ArithmeticOp | AbstractMetaClass::LogicalOp | AbstractMetaClass::BitwiseOp); - foreach (const AbstractMetaFunctionList &allOverloads, opOverloads) { + for (const AbstractMetaFunctionList &allOverloads : opOverloads) { AbstractMetaFunctionList overloads; - foreach (AbstractMetaFunction* func, allOverloads) { + for (AbstractMetaFunction *func : allOverloads) { if (!func->isModifiedRemoved() && !func->isPrivate() && (func->ownerClass() == func->implementingClass() || func->isAbstract())) @@ -523,7 +538,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) } if (shouldGenerateGetSetList(metaClass) && !classContext.forSmartPointer()) { - foreach (const AbstractMetaField* metaField, metaClass->fields()) { + const AbstractMetaFieldList &fields = metaClass->fields(); + for (const AbstractMetaField *metaField : fields) { if (metaField->isStatic()) continue; writeGetterFunction(s, metaField, classContext); @@ -534,7 +550,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) s << "// Getters and Setters for " << metaClass->name() << endl; s << "static PyGetSetDef " << cpythonGettersSettersDefinitionName(metaClass) << "[] = {" << endl; - foreach (const AbstractMetaField* metaField, metaClass->fields()) { + for (const AbstractMetaField *metaField : fields) { if (metaField->isStatic()) continue; @@ -564,7 +580,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) writeTypeDiscoveryFunction(s, metaClass); - foreach (AbstractMetaEnum* cppEnum, classEnums) { + for (AbstractMetaEnum *cppEnum : qAsConst(classEnums)) { if (cppEnum->isAnonymous() || cppEnum->isPrivate()) continue; @@ -616,7 +632,8 @@ static bool allArgumentsRemoved(const AbstractMetaFunction* func) { if (func->arguments().isEmpty()) return false; - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (!func->argumentRemoved(arg->argumentIndex() + 1)) return false; } @@ -668,19 +685,24 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun QString defaultReturnExpr; if (retType) { - foreach (const FunctionModification &mod, func->modifications()) { - foreach (const ArgumentModification &argMod, mod.argument_mods) { + const FunctionModificationList &mods = func->modifications(); + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argMod : mod.argument_mods) { if (argMod.index == 0 && !argMod.replacedDefaultExpression.isEmpty()) { - QRegExp regex(QLatin1String("%(\\d+)")); + static const QRegularExpression regex(QStringLiteral("%(\\d+)")); + Q_ASSERT(regex.isValid()); defaultReturnExpr = argMod.replacedDefaultExpression; - int offset = 0; - while ((offset = regex.indexIn(defaultReturnExpr, offset)) != -1) { - int argId = regex.cap(1).toInt() - 1; + for (int offset = 0; ; ) { + const QRegularExpressionMatch match = regex.match(defaultReturnExpr, offset); + if (!match.hasMatch()) + break; + const int argId = match.capturedRef(1).toInt() - 1; if (argId < 0 || argId > func->arguments().count()) { qCWarning(lcShiboken) << "The expression used in return value contains an invalid index."; break; } - defaultReturnExpr.replace(regex.cap(0), func->arguments()[argId]->name()); + defaultReturnExpr.replace(match.captured(0), func->arguments()[argId]->name()); + offset = match.capturedStart(1); } } } @@ -766,7 +788,8 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun s << "PyTuple_New(0));" << endl; } else { QStringList argConversions; - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (func->argumentRemoved(arg->argumentIndex() + 1)) continue; @@ -812,8 +835,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun bool invalidateReturn = false; QSet<int> invalidateArgs; - foreach (const FunctionModification &funcMod, func->modifications()) { - foreach (const ArgumentModification &argMod, funcMod.argument_mods) { + const FunctionModificationList &mods = func->modifications(); + for (const FunctionModification &funcMod : mods) { + for (const ArgumentModification &argMod : funcMod.argument_mods) { if (argMod.resetAfterUse && !invalidateArgs.contains(argMod.index)) { invalidateArgs.insert(argMod.index); s << INDENT << "bool invalidateArg" << argMod.index; @@ -910,7 +934,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun Indentation indentation(INDENT); s << INDENT << "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR ".object());" << endl; } - foreach (int argIndex, invalidateArgs) { + for (int argIndex : qAsConst(invalidateArgs)) { s << INDENT << "if (invalidateArg" << argIndex << ')' << endl; Indentation indentation(INDENT); s << INDENT << "Shiboken::Object::invalidate(PyTuple_GET_ITEM(" PYTHON_ARGS ", "; @@ -918,8 +942,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun } - foreach (const FunctionModification &funcMod, func->modifications()) { - foreach (const ArgumentModification &argMod, funcMod.argument_mods) { + const FunctionModificationList &funcMods = func->modifications(); + for (const FunctionModification &funcMod : funcMods) { + for (const ArgumentModification &argMod : funcMod.argument_mods) { if (argMod.ownerships.contains(TypeSystem::NativeCode) && argMod.index == 0 && argMod.ownerships[TypeSystem::NativeCode] == TypeSystem::CppOwnership) { s << INDENT << "if (Shiboken::Object::checkType(" PYTHON_RETURN_VAR "))" << endl; @@ -1092,11 +1117,12 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla s << "// Type conversion functions." << endl << endl; AbstractMetaEnumList classEnums = metaClass->enums(); - foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) + const AbstractMetaClassList &innerClasses = metaClass->innerClasses(); + for (AbstractMetaClass *innerClass : innerClasses) lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass); if (!classEnums.isEmpty()) s << "// Python to C++ enum conversion." << endl; - foreach (const AbstractMetaEnum* metaEnum, classEnums) + for (const AbstractMetaEnum *metaEnum : qAsConst(classEnums)) writeEnumConverterFunctions(s, metaEnum); if (metaClass->isNamespace()) @@ -1206,7 +1232,8 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla // Implicit conversions. AbstractMetaFunctionList implicitConvs; if (!customConversion || !customConversion->replaceOriginalTargetToNativeConversions()) { - foreach (AbstractMetaFunction* func, implicitConversions(metaClass->typeEntry())) { + const AbstractMetaFunctionList &allImplicitConvs = implicitConversions(metaClass->typeEntry()); + for (AbstractMetaFunction *func : allImplicitConvs) { if (!func->isUserAdded()) implicitConvs << func; } @@ -1216,7 +1243,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla s << "// Implicit conversions." << endl; AbstractMetaType* targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass); - foreach (const AbstractMetaFunction* conv, implicitConvs) { + for (const AbstractMetaFunction* conv : qAsConst(implicitConvs)) { if (conv->isModifiedRemoved()) continue; @@ -1290,7 +1317,7 @@ void CppGenerator::writeCustomConverterFunctions(QTextStream& s, const CustomCon if (toCppConversions.isEmpty()) return; s << "// Python to C++ conversions for type '" << customConversion->ownerType()->qualifiedCppName() << "'." << endl; - foreach (CustomConversion::TargetToNativeConversion* toNative, toCppConversions) + for (CustomConversion::TargetToNativeConversion *toNative : toCppConversions) writePythonToCppConversionFunctions(s, toNative, customConversion->ownerType()); s << endl; } @@ -1370,7 +1397,8 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas // Add implicit conversions. AbstractMetaFunctionList implicitConvs; if (!customConversion || !customConversion->replaceOriginalTargetToNativeConversions()) { - foreach (AbstractMetaFunction* func, implicitConversions(metaClass->typeEntry())) { + const AbstractMetaFunctionList &allImplicitConvs = implicitConversions(metaClass->typeEntry()); + for (AbstractMetaFunction *func : allImplicitConvs) { if (!func->isUserAdded()) implicitConvs << func; } @@ -1380,7 +1408,7 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas s << INDENT << "// Add implicit conversions to type converter." << endl; AbstractMetaType* targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass); - foreach (const AbstractMetaFunction* conv, implicitConvs) { + for (const AbstractMetaFunction *conv : qAsConst(implicitConvs)) { if (conv->isModifiedRemoved()) continue; const AbstractMetaType* sourceType; @@ -1408,7 +1436,7 @@ void CppGenerator::writeCustomConverterRegister(QTextStream& s, const CustomConv if (toCppConversions.isEmpty()) return; s << INDENT << "// Add user defined implicit conversions to type converter." << endl; - foreach (CustomConversion::TargetToNativeConversion* toNative, toCppConversions) { + for (CustomConversion::TargetToNativeConversion *toNative : toCppConversions) { QString toCpp = pythonToCppFunctionName(toNative, customConversion->ownerType()); QString isConv = convertibleToCppFunctionName(toNative, customConversion->ownerType()); writeAddPythonToCppConversion(s, converterVar, toCpp, isConv); @@ -1518,8 +1546,10 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun QSet<QString> argNamesSet; if (usePySideExtensions() && metaClass->isQObject()) { // Write argNames variable with all known argument names. - foreach (const AbstractMetaFunction* func, overloadData.overloads()) { - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const OverloadData::MetaFunctionList &overloads = overloadData.overloads(); + for (const AbstractMetaFunction *func : overloads) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (arg->defaultValueExpression().isEmpty() || func->argumentRemoved(arg->argumentIndex() + 1)) continue; argNamesSet << arg->name(); @@ -1623,8 +1653,9 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun // Constructor code injections, position=end bool hasCodeInjectionsAtEnd = false; - foreach(AbstractMetaFunction* func, overloads) { - foreach (const CodeSnip &cs, func->injectedCodeSnips()) { + for (AbstractMetaFunction *func : overloads) { + const CodeSnipList &injectedCodeSnips = func->injectedCodeSnips(); + for (const CodeSnip &cs : injectedCodeSnips) { if (cs.position == TypeSystem::CodeSnipPositionEnd) { hasCodeInjectionsAtEnd = true; break; @@ -1634,9 +1665,10 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun if (hasCodeInjectionsAtEnd) { // FIXME: C++ arguments are not available in code injection on constructor when position = end. s << INDENT << "switch(overloadId) {" << endl; - foreach(AbstractMetaFunction* func, overloads) { + for (AbstractMetaFunction *func : overloads) { Indentation indent(INDENT); - foreach (const CodeSnip &cs, func->injectedCodeSnips()) { + const CodeSnipList &injectedCodeSnips = func->injectedCodeSnips(); + for (const CodeSnip &cs : injectedCodeSnips) { if (cs.position == TypeSystem::CodeSnipPositionEnd) { s << INDENT << "case " << metaClass->functions().indexOf(func) << ':' << endl; s << INDENT << '{' << endl; @@ -1814,10 +1846,10 @@ void CppGenerator::writeArgumentsInitializer(QTextStream& s, OverloadData& overl s << INDENT << '}'; } } - QList<int> invalidArgsLength = overloadData.invalidArgumentLengths(); + const QVector<int> invalidArgsLength = overloadData.invalidArgumentLengths(); if (!invalidArgsLength.isEmpty()) { QStringList invArgsLen; - foreach (int i, invalidArgsLength) + for (int i : qAsConst(invalidArgsLength)) invArgsLen << QStringLiteral("numArgs == %1").arg(i); if (usesNamedArguments && (!ownerClassIsQObject || minArgs > 0)) s << " else "; @@ -1945,9 +1977,11 @@ void CppGenerator::writeErrorSection(QTextStream& s, OverloadData& overloadData) s << INDENT << "Shiboken::setErrorAboutWrongArguments(" << argsVar << ", \"" << funcName << "\", 0);" << endl; } else { QStringList overloadSignatures; - foreach (const AbstractMetaFunction* f, overloadData.overloads()) { + const OverloadData::MetaFunctionList &overloads = overloadData.overloads(); + for (const AbstractMetaFunction *f : overloads) { QStringList args; - foreach(AbstractMetaArgument* arg, f->arguments()) { + const AbstractMetaArgumentList &arguments = f->arguments(); + for (AbstractMetaArgument *arg : arguments) { QString strArg; AbstractMetaType* argType = arg->type(); if (isCString(argType)) { @@ -1963,7 +1997,9 @@ void CppGenerator::writeErrorSection(QTextStream& s, OverloadData& overloadData) strArg = QLatin1String("1-unicode"); } else { strArg = ptp->name(); - strArg.remove(QRegExp(QLatin1String("^signed\\s+"))); + static const QRegularExpression regex(QStringLiteral("^signed\\s+")); + Q_ASSERT(regex.isValid()); + strArg.remove(regex); if (strArg == QLatin1String("double")) strArg = QLatin1String("float"); } @@ -2045,9 +2081,13 @@ void CppGenerator::writeInvalidPyObjectCheck(QTextStream& s, const QString& pyOb static QString pythonToCppConverterForArgumentName(const QString& argumentName) { - static QRegExp pyArgsRegex(QLatin1String(PYTHON_ARGS"(\\[\\d+[-]?\\d*\\])")); - pyArgsRegex.indexIn(argumentName); - return QLatin1String(PYTHON_TO_CPP_VAR) + pyArgsRegex.cap(1); + static const QRegularExpression pyArgsRegex(QLatin1String(PYTHON_ARGS"(\\[\\d+[-]?\\d*\\])")); + Q_ASSERT(pyArgsRegex.isValid()); + const QRegularExpressionMatch match = pyArgsRegex.match(argumentName); + QString result = QLatin1String(PYTHON_TO_CPP_VAR); + if (match.hasMatch()) + result += match.captured(1); + return result; } void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argType, QString argumentName, bool isNumber, QString customType, bool rejectNull) @@ -2116,9 +2156,10 @@ static void checkTypeViability(const AbstractMetaFunction* func) void CppGenerator::writeTypeCheck(QTextStream& s, const OverloadData* overloadData, QString argumentName) { QSet<const TypeEntry*> numericTypes; - - foreach (OverloadData* od, overloadData->previousOverloadData()->nextOverloadData()) { - foreach (const AbstractMetaFunction* func, od->overloads()) { + const OverloadDataList &overloads = overloadData->previousOverloadData()->nextOverloadData(); + for (OverloadData *od : overloads) { + const OverloadData::MetaFunctionList &odOverloads = od->overloads(); + for (const AbstractMetaFunction *func : odOverloads) { checkTypeViability(func); const AbstractMetaType* argType = od->argument(func)->type(); if (!argType->isPrimitive()) @@ -2291,7 +2332,8 @@ static void addConversionRuleCodeSnippet(CodeSnipList& snippetList, QString& rul void CppGenerator::writeConversionRule(QTextStream& s, const AbstractMetaFunction* func, TypeSystem::Language language) { CodeSnipList snippets; - foreach (AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (AbstractMetaArgument *arg : arguments) { QString rule = func->conversionRule(language, arg->argumentIndex() + 1); addConversionRuleCodeSnippet(snippets, rule, language, TypeSystem::TargetLangCode, arg->name(), arg->name()); @@ -2319,7 +2361,7 @@ void CppGenerator::writeOverloadedFunctionDecisor(QTextStream& s, const Overload { s << INDENT << "// Overloaded function decisor" << endl; const AbstractMetaFunction* rfunc = overloadData.referenceFunction(); - QList<const AbstractMetaFunction*> functionOverloads = overloadData.overloadsWithoutRepetition(); + const OverloadData::MetaFunctionList &functionOverloads = overloadData.overloadsWithoutRepetition(); for (int i = 0; i < functionOverloads.count(); i++) s << INDENT << "// " << i << ": " << functionOverloads.at(i)->minimalSignature() << endl; writeOverloadedFunctionDecisorEngine(s, &overloadData); @@ -2353,7 +2395,8 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov // variable to be used further on this method on the conditional that identifies default // method calls. if (!hasDefaultCall) { - foreach (const AbstractMetaFunction* func, parentOverloadData->overloads()) { + const OverloadData::MetaFunctionList &overloads = parentOverloadData->overloads(); + for (const AbstractMetaFunction *func : overloads) { if (parentOverloadData->isFinalOccurrence(func)) { referenceFunction = func; hasDefaultCall = true; @@ -2394,6 +2437,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov // If the next argument has a default value the decisor can perform a method call; // it just need to check if the number of arguments received from Python are equal // to the number of parameters preceding the argument with the default value. + const OverloadDataList &overloads = parentOverloadData->nextOverloadData(); if (hasDefaultCall) { isFirst = false; int numArgs = parentOverloadData->argPos() + 1; @@ -2401,7 +2445,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov { Indentation indent(INDENT); const AbstractMetaFunction* func = referenceFunction; - foreach (OverloadData* overloadData, parentOverloadData->nextOverloadData()) { + for (OverloadData *overloadData : overloads) { const AbstractMetaFunction* defValFunc = overloadData->getFunctionWithDefaultValue(); if (defValFunc) { func = defValFunc; @@ -2414,7 +2458,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov s << INDENT << '}'; } - foreach (OverloadData* overloadData, parentOverloadData->nextOverloadData()) { + for (OverloadData *overloadData : overloads) { bool signatureFound = overloadData->overloads().size() == 1 && !overloadData->getFunctionWithDefaultValue() && !overloadData->findNextArgWithDefault(); @@ -2503,7 +2547,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov void CppGenerator::writeFunctionCalls(QTextStream &s, const OverloadData &overloadData, GeneratorContext &context) { - QList<const AbstractMetaFunction*> overloads = overloadData.overloadsWithoutRepetition(); + const OverloadData::MetaFunctionList &overloads = overloadData.overloadsWithoutRepetition(); s << INDENT << "// Call function/method" << endl; s << INDENT << (overloads.count() > 1 ? "switch (overloadId) " : "") << '{' << endl; { @@ -2825,16 +2869,17 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream& s, const Abs const AbstractMetaType* type = containerType->instantiations().at(i); QString typeName = getFullTypeName(type); if (type->isValue() && isValueTypeWithCopyConstructorOnly(type)) { - static QRegExp regex(QLatin1String(CONVERTTOCPP_REGEX)); - int pos = 0; - while ((pos = regex.indexIn(code, pos)) != -1) { - pos += regex.matchedLength(); - QStringList list = regex.capturedTexts(); - QString varName = list.at(1); - QString leftCode = code.left(pos); + static const QRegularExpression regex(QLatin1String(CONVERTTOCPP_REGEX)); + Q_ASSERT(regex.isValid()); + for (int pos = 0; ; ) { + const QRegularExpressionMatch match = regex.match(code, pos); + if (!match.hasMatch()) + break; + pos = match.capturedEnd(); + const QString varName = match.captured(1); QString rightCode = code.mid(pos); rightCode.replace(varName, QLatin1Char('*') + varName); - code = leftCode + rightCode; + code.replace(pos, code.size() - pos, rightCode); } typeName.append(QLatin1Char('*')); } @@ -2869,7 +2914,7 @@ void CppGenerator::writeAddPythonToCppConversion(QTextStream& s, const QString& void CppGenerator::writeNamedArgumentResolution(QTextStream& s, const AbstractMetaFunction* func, bool usePyArgs) { - AbstractMetaArgumentList args = OverloadData::getArgumentsWithDefaultValues(func); + const AbstractMetaArgumentList &args = OverloadData::getArgumentsWithDefaultValues(func); if (args.isEmpty()) return; @@ -2880,7 +2925,7 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream& s, const AbstractMe { Indentation indent(INDENT); s << INDENT << "PyObject* "; - foreach (const AbstractMetaArgument* arg, args) { + for (const AbstractMetaArgument *arg : args) { int pyArgIndex = arg->argumentIndex() - OverloadData::numberOfRemovedArguments(func, arg->argumentIndex()); QString pyArgName = usePyArgs ? QString::fromLatin1(PYTHON_ARGS "[%1]").arg(pyArgIndex) @@ -2955,7 +3000,8 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f { s << INDENT << "// " << func->minimalSignature() << (func->isReverseOperator() ? " [reverse operator]": "") << endl; if (func->isConstructor()) { - foreach (const CodeSnip &cs, func->injectedCodeSnips()) { + const CodeSnipList &snips = func->injectedCodeSnips(); + for (const CodeSnip &cs : snips) { if (cs.position == TypeSystem::CodeSnipPositionEnd) { s << INDENT << "overloadId = " << func->ownerClass()->functions().indexOf(const_cast<AbstractMetaFunction* const>(func)) << ';' << endl; break; @@ -3257,11 +3303,12 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f bool hasReturnPolicy = false; // Ownership transference between C++ and Python. - QList<ArgumentModification> ownership_mods; + QVector<ArgumentModification> ownership_mods; // Python object reference management. - QList<ArgumentModification> refcount_mods; - foreach (const FunctionModification &func_mod, func->modifications()) { - foreach (const ArgumentModification &arg_mod, func_mod.argument_mods) { + QVector<ArgumentModification> refcount_mods; + const FunctionModificationList &funcMods = func->modifications(); + for (const FunctionModification &func_mod : funcMods) { + for (const ArgumentModification &arg_mod : func_mod.argument_mods) { if (!arg_mod.ownerships.isEmpty() && arg_mod.ownerships.contains(TypeSystem::TargetLangCode)) ownership_mods.append(arg_mod); else if (!arg_mod.referenceCounts.isEmpty()) @@ -3275,7 +3322,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f if (!ownership_mods.isEmpty()) { s << endl << INDENT << "// Ownership transferences." << endl; - foreach (const ArgumentModification &arg_mod, ownership_mods) { + for (const ArgumentModification &arg_mod : qAsConst(ownership_mods)) { const AbstractMetaClass* wrappedClass = 0; QString pyArgName = argumentNameFromIndex(func, arg_mod.index, &wrappedClass); if (!wrappedClass) { @@ -3306,7 +3353,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f } } else if (!refcount_mods.isEmpty()) { - foreach (const ArgumentModification &arg_mod, refcount_mods) { + for (const ArgumentModification &arg_mod : qAsConst(refcount_mods)) { ReferenceCount refCount = arg_mod.referenceCounts.first(); if (refCount.action != ReferenceCount::Set && refCount.action != ReferenceCount::Remove @@ -3351,15 +3398,15 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass* metaClass) { QStringList result; - AbstractMetaClassList baseClases = getBaseClasses(metaClass); + const AbstractMetaClassList &baseClases = getBaseClasses(metaClass); if (!baseClases.isEmpty()) { - foreach (const AbstractMetaClass* baseClass, baseClases) { + for (const AbstractMetaClass *baseClass : baseClases) { result.append(QString::fromLatin1("((size_t) static_cast<const %1*>(class_ptr)) - base") .arg(baseClass->qualifiedCppName())); result.append(QString::fromLatin1("((size_t) static_cast<const %1*>((%2*)((void*)class_ptr))) - base") .arg(baseClass->qualifiedCppName(), metaClass->qualifiedCppName())); } - foreach (const AbstractMetaClass* baseClass, baseClases) + for (const AbstractMetaClass *baseClass : baseClases) result.append(getAncestorMultipleInheritance(baseClass)); } return result; @@ -3368,7 +3415,7 @@ QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream& s, const AbstractMetaClass* metaClass) { QString className = metaClass->qualifiedCppName(); - QStringList ancestors = getAncestorMultipleInheritance(metaClass); + const QStringList ancestors = getAncestorMultipleInheritance(metaClass); s << "static int mi_offsets[] = { "; for (int i = 0; i < ancestors.size(); i++) s << "-1, "; @@ -3384,7 +3431,7 @@ void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream& s, c s << INDENT << "const " << className << "* class_ptr = reinterpret_cast<const " << className << "*>(cptr);" << endl; s << INDENT << "size_t base = (size_t) class_ptr;" << endl; - foreach (const QString &ancestor, ancestors) + for (const QString &ancestor : ancestors) s << INDENT << "offsets.insert(" << ancestor << ");" << endl; s << endl; @@ -3412,7 +3459,8 @@ void CppGenerator::writeSpecialCastFunction(QTextStream& s, const AbstractMetaCl s << "{\n"; s << INDENT << className << "* me = reinterpret_cast< ::" << className << "*>(obj);\n"; bool firstClass = true; - foreach (const AbstractMetaClass* baseClass, getAllAncestors(metaClass)) { + const AbstractMetaClassList &allAncestors = getAllAncestors(metaClass); + for (const AbstractMetaClass *baseClass : allAncestors) { s << INDENT << (!firstClass ? "else " : "") << "if (desiredType == reinterpret_cast<SbkObjectType*>(" << cpythonTypeNameExt(baseClass->typeEntry()) << "))\n"; Indentation indent(INDENT); s << INDENT << "return static_cast< ::" << baseClass->qualifiedCppName() << "*>(me);\n"; @@ -3531,10 +3579,11 @@ void CppGenerator::writeContainerConverterInitialization(QTextStream& s, const A writeAddPythonToCppConversion(s, converterObject(type), toCpp, isConv); } -void CppGenerator::writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, const QList<const AbstractMetaClass*>& conversions) +void CppGenerator::writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, + const QVector<const AbstractMetaClass*>& conversions) { s << INDENT << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << endl; - foreach (const AbstractMetaClass* sourceClass, conversions) { + for (const AbstractMetaClass *sourceClass : conversions) { const QString converterVar = QLatin1String("reinterpret_cast<SbkObjectType *>(") + cppApiVariableName(externalType->targetLangPackage()) + QLatin1Char('[') + getTypeIndexVariableName(externalType) + QLatin1String("])"); @@ -3589,7 +3638,8 @@ bool CppGenerator::supportsSequenceProtocol(const AbstractMetaClass* metaClass) bool CppGenerator::shouldGenerateGetSetList(const AbstractMetaClass* metaClass) { - foreach (AbstractMetaField* f, metaClass->fields()) { + const AbstractMetaFieldList &fields = metaClass->fields(); + for (const AbstractMetaField *f : fields) { if (!f->isStatic()) return true; } @@ -3607,11 +3657,11 @@ void CppGenerator::writeClassDefinition(QTextStream &s, QString tp_hash(QLatin1Char('0')); QString tp_call = tp_hash; QString cppClassName = metaClass->qualifiedCppName(); - QString className = cpythonTypeName(metaClass); - className.remove(QRegExp(QLatin1String("_Type$"))); + const QString className = chopType(cpythonTypeName(metaClass)); QString baseClassName(QLatin1Char('0')); AbstractMetaFunctionList ctors; - foreach (AbstractMetaFunction* f, metaClass->queryFunctions(AbstractMetaClass::Constructors)) { + const AbstractMetaFunctionList &allCtors = metaClass->queryFunctions(AbstractMetaClass::Constructors); + for (AbstractMetaFunction *f : allCtors) { if (!f->isPrivate() && !f->isModifiedRemoved() && !classContext.forSmartPointer()) ctors.append(f); } @@ -3669,7 +3719,8 @@ void CppGenerator::writeClassDefinition(QTextStream &s, // search for special functions ShibokenGenerator::clearTpFuncs(); - foreach (AbstractMetaFunction* func, metaClass->functions()) { + const AbstractMetaFunctionList &funcs = metaClass->functions(); + for (AbstractMetaFunction *func : funcs) { if (m_tpFuncs.contains(func->name())) m_tpFuncs[func->name()] = cpythonFunctionName(func); } @@ -3926,13 +3977,13 @@ void CppGenerator::writeTypeAsNumberDefinition(QTextStream& s, const AbstractMet nb.insert(QLatin1String("__ixor__"), QString()); nb.insert(QLatin1String("__ior__"), QString()); - QList<AbstractMetaFunctionList> opOverloads = + const QVector<AbstractMetaFunctionList> opOverloads = filterGroupedOperatorFunctions(metaClass, AbstractMetaClass::ArithmeticOp | AbstractMetaClass::LogicalOp | AbstractMetaClass::BitwiseOp); - foreach (const AbstractMetaFunctionList &opOverload, opOverloads) { + for (const AbstractMetaFunctionList &opOverload : opOverloads) { const AbstractMetaFunction* rfunc = opOverload[0]; QString opName = ShibokenGenerator::pythonOperatorFunctionName(rfunc); nb[opName] = cpythonFunctionName(rfunc); @@ -3991,8 +4042,7 @@ void CppGenerator::writeTpClearFunction(QTextStream& s, const AbstractMetaClass* void CppGenerator::writeCopyFunction(QTextStream &s, GeneratorContext &context) { const AbstractMetaClass *metaClass = context.metaClass(); - QString className = cpythonTypeName(metaClass); - className.remove(QRegExp(QLatin1String("_Type$"))); + const QString className = chopType(cpythonTypeName(metaClass)); s << "static PyObject* " << className << "___copy__(PyObject* " PYTHON_SELF_VAR ")" << endl; s << "{" << endl; writeCppSelfDefinition(s, context, false, true); @@ -4171,7 +4221,8 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co s << INDENT << "switch (op) {" << endl; { Indentation indent(INDENT); - foreach (const AbstractMetaFunctionList &overloads, filterGroupedOperatorFunctions(metaClass, AbstractMetaClass::ComparisonOp)) { + const QVector<AbstractMetaFunctionList> &groupedFuncs = filterGroupedOperatorFunctions(metaClass, AbstractMetaClass::ComparisonOp); + for (const AbstractMetaFunctionList &overloads : groupedFuncs) { const AbstractMetaFunction* rfunc = overloads[0]; QString operatorId = ShibokenGenerator::pythonRichCompareOperatorId(rfunc); @@ -4183,7 +4234,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co op = op.right(op.size() - QLatin1String("operator").size()); int alternativeNumericTypes = 0; - foreach (const AbstractMetaFunction* func, overloads) { + for (const AbstractMetaFunction *func : overloads) { if (!func->isStatic() && ShibokenGenerator::isNumber(func->arguments()[0]->type()->typeEntry())) alternativeNumericTypes++; @@ -4191,7 +4242,8 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co bool first = true; OverloadData overloadData(overloads, this); - foreach (OverloadData* od, overloadData.nextOverloadData()) { + const OverloadDataList &nextOverloads = overloadData.nextOverloadData(); + for (OverloadData *od : nextOverloads) { const AbstractMetaFunction* func = od->referenceFunction(); if (func->isStatic()) continue; @@ -4318,7 +4370,7 @@ void CppGenerator::writeEnumsInitialization(QTextStream& s, AbstractMetaEnumList if (enums.isEmpty()) return; s << INDENT << "// Initialization of enums." << endl << endl; - foreach (const AbstractMetaEnum* cppEnum, enums) { + for (const AbstractMetaEnum *cppEnum : qAsConst(enums)) { if (cppEnum->isPrivate()) continue; writeEnumInitialization(s, cppEnum); @@ -4369,7 +4421,8 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu } } - foreach (const AbstractMetaEnumValue* enumValue, cppEnum->values()) { + const AbstractMetaEnumValueList &enumValues = cppEnum->values(); + for (const AbstractMetaEnumValue *enumValue : enumValues) { if (cppEnum->typeEntry()->isEnumValueRejected(enumValue->name())) continue; @@ -4428,10 +4481,12 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu void CppGenerator::writeSignalInitialization(QTextStream& s, const AbstractMetaClass* metaClass) { // Try to check something and print some warnings - foreach (const AbstractMetaFunction* cppSignal, metaClass->cppSignalFunctions()) { + const AbstractMetaFunctionList &signalFuncs = metaClass->cppSignalFunctions(); + for (const AbstractMetaFunction *cppSignal : signalFuncs) { if (cppSignal->declaringClass() != metaClass) continue; - foreach (AbstractMetaArgument* arg, cppSignal->arguments()) { + const AbstractMetaArgumentList &arguments = cppSignal->arguments(); + for (AbstractMetaArgument *arg : arguments) { AbstractMetaType* metaType = arg->type(); const QByteArray origType = QMetaObject::normalizedType(qPrintable(metaType->originalTypeDescription())); @@ -4664,7 +4719,7 @@ void CppGenerator::writeClassRegister(QTextStream &s, if (metaClass->baseClassNames().size() > 1) { s << INDENT << "PyObject* " << pyTypeBasesVariable << " = PyTuple_Pack(" << baseClasses.size() << ',' << endl; QStringList bases; - foreach (const AbstractMetaClass* base, baseClasses) + for (const AbstractMetaClass *base : baseClasses) bases << QLatin1String("(PyObject*)") + cpythonTypeNameExt(base->typeEntry()); Indentation indent(INDENT); QString separator; @@ -4758,7 +4813,8 @@ void CppGenerator::writeClassRegister(QTextStream &s, } AbstractMetaEnumList classEnums = metaClass->enums(); - foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) + const AbstractMetaClassList &innerClasses = metaClass->innerClasses(); + for (AbstractMetaClass *innerClass : innerClasses) lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass); ErrorCode errorCode(QString::null); @@ -4768,7 +4824,8 @@ void CppGenerator::writeClassRegister(QTextStream &s, writeSignalInitialization(s, metaClass); // Write static fields - foreach (const AbstractMetaField* field, metaClass->fields()) { + const AbstractMetaFieldList &fields = metaClass->fields(); + for (const AbstractMetaField *field : fields) { if (!field->isStatic()) continue; s << INDENT << QLatin1String("PyDict_SetItemString(") + cpythonTypeName(metaClass) + QLatin1String(".super.ht_type.tp_dict, \""); @@ -4828,7 +4885,8 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont bool canBeValue = false; if (!isObjectType(metaClass)) { // check if there's a empty ctor - foreach (AbstractMetaFunction* func, metaClass->functions()) { + const AbstractMetaFunctionList &funcs = metaClass->functions(); + for (AbstractMetaFunction *func : funcs) { if (func->isConstructor() && !func->arguments().count()) { canBeValue = true; break; @@ -4837,7 +4895,7 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont } if (canBeValue) { - foreach (const QString &name, nameVariants) { + for (const QString &name : qAsConst(nameVariants)) { if (name == QLatin1String("iterator")) { qCWarning(lcShiboken).noquote().nospace() << QString::fromLatin1("%1:%2 FIXME:\n" @@ -4851,9 +4909,10 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont } } - foreach (AbstractMetaEnum* metaEnum, metaClass->enums()) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (AbstractMetaEnum *metaEnum : enums) { if (!metaEnum->isPrivate() && !metaEnum->isAnonymous()) { - foreach (const QString &name, nameVariants) + for (const QString &name : qAsConst(nameVariants)) s << INDENT << "qRegisterMetaType< ::" << metaEnum->typeEntry()->qualifiedCppName() << " >(\"" << name << "::" << metaEnum->name() << "\");" << endl; if (metaEnum->typeEntry()->flags()) { @@ -4881,8 +4940,8 @@ void CppGenerator::writeTypeDiscoveryFunction(QTextStream& s, const AbstractMeta s << INDENT << "return cptr;" << endl; } } else if (metaClass->isPolymorphic()) { - AbstractMetaClassList ancestors = getAllAncestors(metaClass); - foreach (AbstractMetaClass* ancestor, ancestors) { + const AbstractMetaClassList &ancestors = getAllAncestors(metaClass); + for (AbstractMetaClass *ancestor : ancestors) { if (ancestor->baseClass()) continue; if (ancestor->isPolymorphic()) { @@ -4993,7 +5052,8 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, GeneratorContext &conte } s << INDENT << '}' << endl; - foreach (const AbstractMetaFunction* func, getMethodsWithBothStaticAndNonStaticMethods(metaClass)) { + const AbstractMetaFunctionList &funcs = getMethodsWithBothStaticAndNonStaticMethods(metaClass); + for (const AbstractMetaFunction *func : funcs) { QString defName = cpythonMethodDefinitionName(func); s << INDENT << "static PyMethodDef non_static_" << defName << " = {" << endl; { @@ -5086,7 +5146,7 @@ bool CppGenerator::finishGeneration() const FunctionGroupMap &functionGroups = getFunctionGroups(); for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { AbstractMetaFunctionList overloads; - foreach (AbstractMetaFunction* func, it.value()) { + for (AbstractMetaFunction *func : it.value()) { if (!func->isModifiedRemoved()) { overloads.append(func); if (func->typeEntry()) @@ -5116,7 +5176,7 @@ bool CppGenerator::finishGeneration() } const AbstractMetaClassList lst = classesTopologicalSorted(additionalDependencies); - foreach (const AbstractMetaClass* cls, lst) { + for (const AbstractMetaClass *cls : lst){ if (!shouldGenerate(cls)) continue; @@ -5132,7 +5192,8 @@ bool CppGenerator::finishGeneration() } // Initialize smart pointer types. - foreach (const AbstractMetaType *metaType, instantiatedSmartPointers()) { + const QVector<const AbstractMetaType *> &smartPtrs = instantiatedSmartPointers(); + for (const AbstractMetaType *metaType : smartPtrs) { GeneratorContext context(0, metaType, true); QString initFunctionName = getInitFunctionName(context); s_classInitDecl << "void init_" << initFunctionName << "(PyObject* module);" << endl; @@ -5166,13 +5227,14 @@ bool CppGenerator::finishGeneration() } s << "#include \"" << getModuleHeaderFileName() << '"' << endl << endl; - foreach (const Include& include, includes) + for (const Include &include : qAsConst(includes)) s << include; s << endl; // Global enums AbstractMetaEnumList globalEnums = this->globalEnums(); - foreach (const AbstractMetaClass* metaClass, classes()) { + const AbstractMetaClassList &classList = classes(); + for (const AbstractMetaClass *metaClass : classList) { const AbstractMetaClass* encClass = metaClass->enclosingClass(); if (encClass && encClass->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass) continue; @@ -5184,13 +5246,13 @@ bool CppGenerator::finishGeneration() //Extra includes s << endl << "// Extra includes" << endl; - QList<Include> extraIncludes; + QVector<Include> extraIncludes; if (moduleEntry) extraIncludes = moduleEntry->extraIncludes(); - foreach (AbstractMetaEnum* cppEnum, globalEnums) + for (AbstractMetaEnum *cppEnum : qAsConst(globalEnums)) extraIncludes.append(cppEnum->typeEntry()->extraIncludes()); qSort(extraIncludes.begin(), extraIncludes.end()); - foreach (const Include& inc, extraIncludes) + for (const Include &inc : qAsConst(extraIncludes)) s << inc; s << endl; @@ -5245,7 +5307,7 @@ bool CppGenerator::finishGeneration() s << "// Enum definitions "; s << "------------------------------------------------------------" << endl; - foreach (const AbstractMetaEnum* cppEnum, globalEnums) { + for (const AbstractMetaEnum *cppEnum : qAsConst(globalEnums)) { if (cppEnum->isAnonymous() || cppEnum->isPrivate()) continue; writeEnumConverterFunctions(s, cppEnum); @@ -5261,10 +5323,10 @@ bool CppGenerator::finishGeneration() } } - QStringList requiredModules = typeDb->requiredTargetImports(); + const QStringList &requiredModules = typeDb->requiredTargetImports(); if (!requiredModules.isEmpty()) s << "// Required modules' type and converter arrays." << endl; - foreach (const QString& requiredModule, requiredModules) { + for (const QString &requiredModule : requiredModules) { s << "PyTypeObject** " << cppApiVariableName(requiredModule) << ';' << endl; s << "SbkConverter** " << convertersVariableName(requiredModule) << ';' << endl; } @@ -5278,7 +5340,7 @@ bool CppGenerator::finishGeneration() for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) { const TypeEntry *externalType = it.key(); s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << endl; - foreach (const AbstractMetaClass* sourceClass, extendedConverters[externalType]) { + for (const AbstractMetaClass *sourceClass : it.value()) { AbstractMetaType* sourceType = buildAbstractMetaTypeFromAbstractMetaClass(sourceClass); AbstractMetaType* targetType = buildAbstractMetaTypeFromTypeEntry(externalType); writePythonToCppConversionFunctions(s, sourceType, targetType); @@ -5286,10 +5348,10 @@ bool CppGenerator::finishGeneration() } } - QList<const CustomConversion*> typeConversions = getPrimitiveCustomConversions(); + const QVector<const CustomConversion *> &typeConversions = getPrimitiveCustomConversions(); if (!typeConversions.isEmpty()) { s << endl << "// Primitive Type converters." << endl << endl; - foreach (const CustomConversion* conversion, typeConversions) { + for (const CustomConversion *conversion : typeConversions) { s << "// C++ to Python conversion for type '" << conversion->ownerType()->qualifiedCppName() << "'." << endl; writeCppToPythonFunction(s, conversion); writeCustomConverterFunctions(s, conversion); @@ -5297,10 +5359,10 @@ bool CppGenerator::finishGeneration() s << endl; } - QList<const AbstractMetaType*> containers = instantiatedContainers(); + const QVector<const AbstractMetaType *> &containers = instantiatedContainers(); if (!containers.isEmpty()) { s << "// Container Type converters." << endl << endl; - foreach (const AbstractMetaType* container, containers) { + for (const AbstractMetaType *container : containers) { s << "// C++ to Python conversion for type '" << container->cppSignature() << "'." << endl; writeContainerConverterFunctions(s, container); } @@ -5337,7 +5399,7 @@ bool CppGenerator::finishGeneration() s << endl; } - foreach (const QString& requiredModule, typeDb->requiredTargetImports()) { + for (const QString& requiredModule : requiredModules) { s << INDENT << "{" << endl; { Indentation indentation(INDENT); @@ -5379,7 +5441,7 @@ bool CppGenerator::finishGeneration() if (!typeConversions.isEmpty()) { s << endl; - foreach (const CustomConversion* conversion, typeConversions) { + for (const CustomConversion *conversion : typeConversions) { writePrimitiveConverterInitialization(s, conversion); s << endl; } @@ -5387,7 +5449,7 @@ bool CppGenerator::finishGeneration() if (!containers.isEmpty()) { s << endl; - foreach (const AbstractMetaType* container, containers) { + for (const AbstractMetaType *container : containers) { writeContainerConverterInitialization(s, container); s << endl; } @@ -5404,7 +5466,8 @@ bool CppGenerator::finishGeneration() writeEnumsInitialization(s, globalEnums); s << INDENT << "// Register primitive types converters." << endl; - foreach(const PrimitiveTypeEntry* pte, primitiveTypes()) { + const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes(); + for (const PrimitiveTypeEntry *pte : primitiveTypeList) { if (!pte->generateCode() || !pte->isCppPrimitive()) continue; const TypeEntry *referencedType = pte->basicReferencedTypeEntry(); @@ -5420,12 +5483,15 @@ bool CppGenerator::finishGeneration() } // Register type resolver for all containers found in signals. QSet<QByteArray> typeResolvers; - foreach (AbstractMetaClass* metaClass, classes()) { + + for (AbstractMetaClass *metaClass : classList) { if (!metaClass->isQObject() || !metaClass->typeEntry()->generateCode()) continue; - foreach (AbstractMetaFunction* func, metaClass->functions()) { + const AbstractMetaFunctionList &functions = metaClass->functions(); + for (AbstractMetaFunction *func : functions) { if (func->isSignal()) { - foreach (AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (AbstractMetaArgument *arg : arguments) { if (arg->type()->isContainer()) { QString value = translateType(arg->type(), metaClass, ExcludeConst | ExcludeReference); if (value.startsWith(QLatin1String("::"))) @@ -5463,7 +5529,7 @@ bool CppGenerator::finishGeneration() } if (usePySideExtensions()) { - foreach (AbstractMetaEnum* metaEnum, globalEnums) + for (AbstractMetaEnum *metaEnum : qAsConst(globalEnums)) if (!metaEnum->isAnonymous()) { s << INDENT << "qRegisterMetaType< ::" << metaEnum->typeEntry()->qualifiedCppName() << " >(\"" << metaEnum->name() << "\");" << endl; } diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h index 5dc3f5a15..c3ca48307 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.h +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h @@ -39,12 +39,12 @@ class CppGenerator : public ShibokenGenerator public: CppGenerator(); protected: - QString fileNamePrefix() const; - QString fileNameForContext(GeneratorContext &context) const; - QList<AbstractMetaFunctionList> filterGroupedOperatorFunctions(const AbstractMetaClass* metaClass, - uint query); - void generateClass(QTextStream& s, GeneratorContext &classContext); - bool finishGeneration(); + QString fileNamePrefix() const override; + QString fileNameForContext(GeneratorContext &context) const override; + QVector<AbstractMetaFunctionList> filterGroupedOperatorFunctions(const AbstractMetaClass* metaClass, + uint query); + void generateClass(QTextStream& s, GeneratorContext &classContext) override; + bool finishGeneration() override; private: void writeConstructorNative(QTextStream& s, const AbstractMetaFunction* func); @@ -290,7 +290,7 @@ private: void writeEnumConverterInitialization(QTextStream& s, const TypeEntry* enumType); void writeEnumConverterInitialization(QTextStream& s, const AbstractMetaEnum* metaEnum); void writeContainerConverterInitialization(QTextStream& s, const AbstractMetaType* type); - void writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, const QList<const AbstractMetaClass*>& conversions); + void writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, const QVector<const AbstractMetaClass*>& conversions); void writeParentChildManagement(QTextStream& s, const AbstractMetaFunction* func, bool userHeuristicForReturn); bool writeParentChildManagement(QTextStream& s, const AbstractMetaFunction* func, int argIndex, bool userHeuristicPolicy); diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp index 5ef5d5612..6b8185dc9 100644 --- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp @@ -35,7 +35,6 @@ #include <QtCore/QDir> #include <QtCore/QTextStream> #include <QtCore/QVariant> -#include <QtCore/QRegExp> #include <QtCore/QDebug> QString HeaderGenerator::fileNamePrefix() const @@ -133,14 +132,16 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte s << endl << '{' << endl << "public:" << endl; bool hasVirtualFunction = false; - foreach (AbstractMetaFunction *func, filterFunctions(metaClass)) { + const AbstractMetaFunctionList &funcs = filterFunctions(metaClass); + for (AbstractMetaFunction *func : funcs) { if (func->isVirtual()) hasVirtualFunction = true; writeFunction(s, func); } if (avoidProtectedHack() && metaClass->hasProtectedFields()) { - foreach (AbstractMetaField* field, metaClass->fields()) { + const AbstractMetaFieldList &fields = metaClass->fields(); + for (AbstractMetaField *field : fields) { if (!field->isProtected()) continue; writeProtectedFieldAccessors(s, field); @@ -203,7 +204,8 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction* s << func->ownerClass()->qualifiedCppName() << "::"; s << func->originalName() << '('; QStringList args; - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { QString argName = arg->name(); const TypeEntry* enumTypeEntry = 0; if (arg->type()->isFlags()) @@ -239,7 +241,8 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction* s << functionSignature(func, QString(), QString(), virtualOption) << ';' << endl; // Check if this method hide other methods in base classes - foreach (const AbstractMetaFunction* f, func->ownerClass()->functions()) { + const AbstractMetaFunctionList &ownerFuncs = func->ownerClass()->functions(); + for (const AbstractMetaFunction *f : ownerFuncs) { if (f != func && !f->isConstructor() && !f->isPrivate() @@ -292,7 +295,8 @@ void HeaderGenerator::writeTypeIndexDefine(QTextStream& s, const AbstractMetaCla if (!metaClass->typeEntry()->generateCode()) return; writeTypeIndexDefineLine(s, metaClass->typeEntry()); - foreach (const AbstractMetaEnum* metaEnum, metaClass->enums()) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (const AbstractMetaEnum *metaEnum : enums) { if (metaEnum->isPrivate()) continue; writeTypeIndexDefineLine(s, metaEnum->typeEntry()); @@ -316,18 +320,20 @@ bool HeaderGenerator::finishGeneration() macrosStream << "// Type indices" << endl; AbstractMetaEnumList globalEnums = this->globalEnums(); - foreach (const AbstractMetaClass* metaClass, classes()) { + const AbstractMetaClassList &classList = classes(); + for (const AbstractMetaClass *metaClass : classList) { writeTypeIndexDefine(macrosStream, metaClass); lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass); } - foreach (const AbstractMetaEnum* metaEnum, globalEnums) + for (const AbstractMetaEnum *metaEnum : qAsConst(globalEnums)) writeTypeIndexDefineLine(macrosStream, metaEnum->typeEntry()); // Write the smart pointer define indexes. int smartPointerCountIndex = getMaxTypeIndex(); int smartPointerCount = 0; - foreach (const AbstractMetaType *metaType, instantiatedSmartPointers()) { + const QVector<const AbstractMetaType *> &instantiatedSmartPtrs = instantiatedSmartPointers(); + for (const AbstractMetaType *metaType : instantiatedSmartPtrs) { QString variableName = getTypeIndexVariableName(metaType); macrosStream << "#define "; macrosStream.setFieldWidth(60); @@ -353,9 +359,9 @@ bool HeaderGenerator::finishGeneration() // TODO-CONVERTER ------------------------------------------------------------------------------ // Using a counter would not do, a fix must be made to APIExtractor's getTypeIndex(). macrosStream << "// Converter indices" << endl; - QList<const PrimitiveTypeEntry*> primitives = primitiveTypes(); + const PrimitiveTypeEntryList &primitives = primitiveTypes(); int pCount = 0; - foreach (const PrimitiveTypeEntry* ptype, primitives) { + for (const PrimitiveTypeEntry *ptype : primitives) { /* Note: do not generate indices for typedef'd primitive types * as they'll use the primitive type converters instead, so we * don't need to create any other. @@ -366,7 +372,8 @@ bool HeaderGenerator::finishGeneration() _writeTypeIndexDefineLine(macrosStream, getTypeIndexVariableName(ptype), pCount++); } - foreach (const AbstractMetaType* container, instantiatedContainers()) { + const QVector<const AbstractMetaType *> &containers = instantiatedContainers(); + for (const AbstractMetaType *container : containers) { //_writeTypeIndexDefineLine(macrosStream, getTypeIndexVariableName(container), pCount); // DEBUG QString variableName = getTypeIndexVariableName(container); @@ -387,7 +394,7 @@ bool HeaderGenerator::finishGeneration() // TODO-CONVERTER ------------------------------------------------------------------------------ macrosStream << "// Macros for type check" << endl; - foreach (const AbstractMetaEnum* cppEnum, globalEnums) { + for (const AbstractMetaEnum *cppEnum : globalEnums) { if (cppEnum->isAnonymous() || cppEnum->isPrivate()) continue; includes << cppEnum->typeEntry()->include(); @@ -395,7 +402,7 @@ bool HeaderGenerator::finishGeneration() writeSbkTypeFunction(typeFunctions, cppEnum); } - foreach (AbstractMetaClass* metaClass, classes()) { + for (AbstractMetaClass *metaClass : classList) { if (!shouldGenerate(metaClass)) continue; @@ -403,7 +410,8 @@ bool HeaderGenerator::finishGeneration() const TypeEntry* classType = metaClass->typeEntry(); includes << classType->include(); - foreach (const AbstractMetaEnum* cppEnum, metaClass->enums()) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (const AbstractMetaEnum *cppEnum : enums) { if (cppEnum->isAnonymous() || cppEnum->isPrivate()) continue; EnumTypeEntry* enumType = cppEnum->typeEntry(); @@ -416,7 +424,7 @@ bool HeaderGenerator::finishGeneration() writeSbkTypeFunction(typeFunctions, metaClass); } - foreach (const AbstractMetaType *metaType, instantiatedSmartPointers()) { + for (const AbstractMetaType *metaType : instantiatedSmartPtrs) { const TypeEntry *classType = metaType->typeEntry(); includes << classType->include(); writeSbkTypeFunction(typeFunctions, metaType); @@ -452,25 +460,27 @@ bool HeaderGenerator::finishGeneration() QStringList requiredTargetImports = TypeDatabase::instance()->requiredTargetImports(); if (!requiredTargetImports.isEmpty()) { s << "// Module Includes" << endl; - foreach (const QString& requiredModule, requiredTargetImports) + for (const QString &requiredModule : qAsConst(requiredTargetImports)) s << "#include <" << getModuleHeaderFileName(requiredModule) << ">" << endl; s << endl; } s << "// Binded library includes" << endl; - foreach (const Include& include, includes) + for (const Include &include : qAsConst(includes)) s << include; if (!primitiveTypes().isEmpty()) { s << "// Conversion Includes - Primitive Types" << endl; - foreach (const PrimitiveTypeEntry* ptype, primitiveTypes()) + const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes(); + for (const PrimitiveTypeEntry *ptype : primitiveTypeList) s << ptype->include(); s << endl; } if (!containerTypes().isEmpty()) { s << "// Conversion Includes - Container Types" << endl; - foreach (const ContainerTypeEntry* ctype, containerTypes()) + const ContainerTypeEntryList &containerTypeList = containerTypes(); + for (const ContainerTypeEntry *ctype : containerTypeList) s << ctype->include(); s << endl; } @@ -535,13 +545,14 @@ void HeaderGenerator::writeSbkTypeFunction(QTextStream &s, const AbstractMetaTyp void HeaderGenerator::writeInheritedOverloads(QTextStream& s) { - foreach (const AbstractMetaFunction* func, m_inheritedOverloads) { + for (const AbstractMetaFunction *func : qAsConst(m_inheritedOverloads)) { s << INDENT << "inline "; s << functionSignature(func, QString(), QString(), Generator::EnumAsInts|Generator::OriginalTypeDescription) << " { "; s << (func->type() ? "return " : ""); s << func->ownerClass()->qualifiedCppName() << "::" << func->originalName() << '('; QStringList args; - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { QString argName = arg->name(); const TypeEntry* enumTypeEntry = 0; if (arg->type()->isFlags()) diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.h b/sources/shiboken2/generator/shiboken2/headergenerator.h index 72dcbf69f..5c1ffec35 100644 --- a/sources/shiboken2/generator/shiboken2/headergenerator.h +++ b/sources/shiboken2/generator/shiboken2/headergenerator.h @@ -41,12 +41,12 @@ class AbstractMetaFunction; class HeaderGenerator : public ShibokenGenerator { public: - QMap<QString, QString> options() const { return QMap<QString, QString>(); } + QMap<QString, QString> options() const override { return QMap<QString, QString>(); } protected: - QString fileNamePrefix() const; - QString fileNameForContext(GeneratorContext &context) const; - void generateClass(QTextStream& s, GeneratorContext &classContext); - bool finishGeneration(); + QString fileNamePrefix() const override; + QString fileNameForContext(GeneratorContext &context) const override; + void generateClass(QTextStream& s, GeneratorContext &classContext) override; + bool finishGeneration() override; private: void writeCopyCtor(QTextStream &s, const AbstractMetaClass* metaClass) const; diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp index 8731fe911..876185cbe 100644 --- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp +++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp @@ -53,7 +53,8 @@ static QString getTypeName(const AbstractMetaType* type) QString typeName = typeEntry->name(); if (typeEntry->isContainer()) { QStringList types; - foreach (const AbstractMetaType* cType, type->instantiations()) { + const AbstractMetaTypeList &instantiations = type->instantiations(); + for (const AbstractMetaType *cType : instantiations) { const TypeEntry *typeEntry = getReferencedTypeEntry(cType->typeEntry()); types << typeEntry->name(); } @@ -144,7 +145,8 @@ static QString getImplicitConversionTypeName(const AbstractMetaType* containerTy impConv = getTypeName(function->arguments().first()->type()); QStringList types; - foreach (const AbstractMetaType* otherType, containerType->instantiations()) + const AbstractMetaTypeList &instantiations = containerType->instantiations(); + for (const AbstractMetaType *otherType : instantiations) types << (otherType == instantiation ? impConv : getTypeName(otherType)); const ContainerTypeEntry* containerTypeEntry = dynamic_cast<const ContainerTypeEntry*>(containerType->typeEntry()); @@ -153,7 +155,7 @@ static QString getImplicitConversionTypeName(const AbstractMetaType* containerTy } static QString msgCyclicDependency(const QString &funcName, const QString &graphName, - const QList<const AbstractMetaFunction *> &involvedConversions) + const OverloadData::MetaFunctionList &involvedConversions) { QString result; QTextStream str(&result); @@ -209,7 +211,7 @@ void OverloadData::sortNextOverloads() << QLatin1String("long"); // sort the children overloads - foreach(OverloadData *ov, m_nextOverloadData) + for (OverloadData *ov : m_nextOverloadData) ov->sortNextOverloads(); if (m_nextOverloadData.size() <= 1) @@ -218,7 +220,7 @@ void OverloadData::sortNextOverloads() // Populates the OverloadSortData object containing map and reverseMap, to map type names to ids, // these ids will be used by the topological sort algorithm, because is easier and faster to work // with graph sorting using integers. - foreach(OverloadData* ov, m_nextOverloadData) { + for (OverloadData *ov : m_nextOverloadData) { sortData.mapType(ov); const QString typeName(getTypeName(ov)); @@ -240,7 +242,8 @@ void OverloadData::sortNextOverloads() qstringIndex = sortData.lastProcessedItemId(); } - foreach (const AbstractMetaType* instantiation, ov->argType()->instantiations()) { + const AbstractMetaTypeList &instantiations = ov->argType()->instantiations(); + for (const AbstractMetaType *instantiation : instantiations) { // Add dependencies for type instantiation of container. QString typeName = getTypeName(instantiation); sortData.mapType(typeName); @@ -251,10 +254,11 @@ void OverloadData::sortNextOverloads() // as Point must come before the PointF instantiation, or else list<Point> will never // be called. In the case of primitive types, list<double> must come before list<int>. if (instantiation->isPrimitive() && (signedIntegerPrimitives.contains(instantiation->name()))) { - foreach (const QString& primitive, nonIntegerPrimitives) + for (const QString &primitive : qAsConst(nonIntegerPrimitives)) sortData.mapType(getImplicitConversionTypeName(ov->argType(), instantiation, 0, primitive)); } else { - foreach (const AbstractMetaFunction* function, m_generator->implicitConversions(instantiation)) + const AbstractMetaFunctionList &funcs = m_generator->implicitConversions(instantiation); + for (const AbstractMetaFunction *function : funcs) sortData.mapType(getImplicitConversionTypeName(ov->argType(), instantiation, function)); } } @@ -287,15 +291,16 @@ void OverloadData::sortNextOverloads() QStringList classesWithIntegerImplicitConversion; - QList<const AbstractMetaFunction *> involvedConversions; + MetaFunctionList involvedConversions; - foreach(OverloadData* ov, m_nextOverloadData) { + for (OverloadData *ov : m_nextOverloadData) { const AbstractMetaType* targetType = ov->argType(); const QString targetTypeEntryName(getTypeName(ov)); int targetTypeId = sortData.map[targetTypeEntryName]; // Process implicit conversions - foreach(AbstractMetaFunction* function, m_generator->implicitConversions(targetType)) { + const AbstractMetaFunctionList &functions = m_generator->implicitConversions(targetType); + for (AbstractMetaFunction *function : functions) { QString convertibleType; if (function->isConversionOperator()) convertibleType = function->ownerClass()->typeEntry()->name(); @@ -320,7 +325,8 @@ void OverloadData::sortNextOverloads() // Process inheritance relationships if (targetType->isValue() || targetType->isObject()) { const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_generator->classes(), targetType->typeEntry()); - foreach (const AbstractMetaClass* ancestor, m_generator->getAllAncestors(metaClass)) { + const AbstractMetaClassList &ancestors = m_generator->getAllAncestors(metaClass); + for (const AbstractMetaClass *ancestor : ancestors) { QString ancestorTypeName = ancestor->typeEntry()->name(); if (!sortData.map.contains(ancestorTypeName)) continue; @@ -331,7 +337,8 @@ void OverloadData::sortNextOverloads() } // Process template instantiations - foreach (const AbstractMetaType* instantiation, targetType->instantiations()) { + const AbstractMetaTypeList &instantiations = targetType->instantiations(); + for (const AbstractMetaType *instantiation : instantiations) { if (sortData.map.contains(getTypeName(instantiation))) { int convertible = sortData.map[getTypeName(instantiation)]; @@ -339,14 +346,15 @@ void OverloadData::sortNextOverloads() graph.addEdge(convertible, targetTypeId); if (instantiation->isPrimitive() && (signedIntegerPrimitives.contains(instantiation->name()))) { - foreach (const QString& primitive, nonIntegerPrimitives) { + for (const QString &primitive : qAsConst(nonIntegerPrimitives)) { QString convertibleTypeName = getImplicitConversionTypeName(ov->argType(), instantiation, 0, primitive); if (!graph.containsEdge(targetTypeId, sortData.map[convertibleTypeName])) // Avoid cyclic dependency. graph.addEdge(sortData.map[convertibleTypeName], targetTypeId); } } else { - foreach (const AbstractMetaFunction* function, m_generator->implicitConversions(instantiation)) { + const AbstractMetaFunctionList &funcs = m_generator->implicitConversions(instantiation); + for (const AbstractMetaFunction *function : funcs) { QString convertibleTypeName = getImplicitConversionTypeName(ov->argType(), instantiation, function); if (!graph.containsEdge(targetTypeId, sortData.map[convertibleTypeName])) { // Avoid cyclic dependency. graph.addEdge(sortData.map[convertibleTypeName], targetTypeId); @@ -396,22 +404,22 @@ void OverloadData::sortNextOverloads() if (sortData.map.contains(QLatin1String("QString")) && sortData.map.contains(QLatin1String("QByteArray"))) graph.addEdge(sortData.map[QLatin1String("QString")], sortData.map[QLatin1String("QByteArray")]); - foreach(OverloadData* ov, m_nextOverloadData) { + for (OverloadData *ov : m_nextOverloadData) { const AbstractMetaType* targetType = ov->argType(); if (!targetType->isEnum()) continue; QString targetTypeEntryName = getTypeName(targetType); // Enum values must precede types implicitly convertible from "int" or "unsigned int". - foreach (const QString& implicitFromInt, classesWithIntegerImplicitConversion) + for (const QString &implicitFromInt : qAsConst(classesWithIntegerImplicitConversion)) graph.addEdge(sortData.map[targetTypeEntryName], sortData.map[implicitFromInt]); } // Special case for double(int i) (not tracked by m_generator->implicitConversions - foreach (const QString& signedIntegerName, signedIntegerPrimitives) { + for (const QString &signedIntegerName : qAsConst(signedIntegerPrimitives)) { if (sortData.map.contains(signedIntegerName)) { - foreach (const QString& nonIntegerName, nonIntegerPrimitives) { + for (const QString &nonIntegerName : qAsConst(nonIntegerPrimitives)) { if (sortData.map.contains(nonIntegerName)) graph.addEdge(sortData.map[nonIntegerName], sortData.map[signedIntegerName]); } @@ -419,7 +427,7 @@ void OverloadData::sortNextOverloads() } // sort the overloads topologically based on the dependency graph. - QLinkedList<int> unmappedResult = graph.topologicalSort(); + const QLinkedList<int> unmappedResult = graph.topologicalSort(); if (unmappedResult.isEmpty()) { QString funcName = referenceFunction()->name(); if (referenceFunction()->ownerClass()) @@ -436,7 +444,7 @@ void OverloadData::sortNextOverloads() } m_nextOverloadData.clear(); - foreach(int i, unmappedResult) { + for (int i : unmappedResult) { if (!sortData.reverseMap[i]) continue; m_nextOverloadData << sortData.reverseMap[i]; @@ -464,7 +472,7 @@ OverloadData::OverloadData(const AbstractMetaFunctionList& overloads, const Shib : m_minArgs(256), m_maxArgs(0), m_argPos(-1), m_argType(0), m_headOverloadData(this), m_previousOverloadData(0), m_generator(generator) { - foreach (const AbstractMetaFunction* func, overloads) { + for (const AbstractMetaFunction *func : overloads) { m_overloads.append(func); int argSize = func->arguments().size() - numberOfRemovedArguments(func); if (m_minArgs > argSize) @@ -472,7 +480,8 @@ OverloadData::OverloadData(const AbstractMetaFunctionList& overloads, const Shib else if (m_maxArgs < argSize) m_maxArgs = argSize; OverloadData* currentOverloadData = this; - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (func->argumentRemoved(arg->argumentIndex() + 1)) continue; currentOverloadData = currentOverloadData->addOverloadData(func, arg); @@ -528,7 +537,7 @@ OverloadData* OverloadData::addOverloadData(const AbstractMetaFunction* func, const AbstractMetaType* argType = arg->type(); OverloadData* overloadData = 0; if (!func->isOperatorOverload()) { - foreach (OverloadData* tmp, m_nextOverloadData) { + for (OverloadData *tmp : qAsConst(m_nextOverloadData)) { // TODO: 'const char *', 'char *' and 'char' will have the same TypeEntry? // If an argument have a type replacement, then we should create a new overloaddata @@ -560,7 +569,7 @@ OverloadData* OverloadData::addOverloadData(const AbstractMetaFunction* func, QStringList OverloadData::returnTypes() const { QSet<QString> retTypes; - foreach (const AbstractMetaFunction* func, m_overloads) { + for (const AbstractMetaFunction *func : m_overloads) { if (!func->typeReplaced(0).isEmpty()) retTypes << func->typeReplaced(0); else if (func->type() && !func->argumentRemoved(0)) @@ -579,7 +588,7 @@ bool OverloadData::hasNonVoidReturnType() const bool OverloadData::hasVarargs() const { - foreach (const AbstractMetaFunction* func, m_overloads) { + for (const AbstractMetaFunction *func : m_overloads) { AbstractMetaArgumentList args = func->arguments(); if (args.size() > 1 && args.last()->type()->isVarargs()) return true; @@ -589,7 +598,7 @@ bool OverloadData::hasVarargs() const bool OverloadData::hasAllowThread() const { - foreach (const AbstractMetaFunction* func, m_overloads) { + for (const AbstractMetaFunction *func : m_overloads) { if (func->allowThread()) return true; } @@ -598,7 +607,7 @@ bool OverloadData::hasAllowThread() const bool OverloadData::hasStaticFunction(const AbstractMetaFunctionList& overloads) { - foreach (const AbstractMetaFunction* func, overloads) { + for (const AbstractMetaFunction *func : qAsConst(overloads)) { if (func->isStatic()) return true; } @@ -607,7 +616,7 @@ bool OverloadData::hasStaticFunction(const AbstractMetaFunctionList& overloads) bool OverloadData::hasStaticFunction() const { - foreach (const AbstractMetaFunction* func, m_overloads) { + for (const AbstractMetaFunction *func : m_overloads) { if (func->isStatic()) return true; } @@ -616,7 +625,7 @@ bool OverloadData::hasStaticFunction() const bool OverloadData::hasInstanceFunction(const AbstractMetaFunctionList& overloads) { - foreach (const AbstractMetaFunction* func, overloads) { + for (const AbstractMetaFunction *func : qAsConst(overloads)) { if (!func->isStatic()) return true; } @@ -625,7 +634,7 @@ bool OverloadData::hasInstanceFunction(const AbstractMetaFunctionList& overloads bool OverloadData::hasInstanceFunction() const { - foreach (const AbstractMetaFunction* func, m_overloads) { + for (const AbstractMetaFunction *func : m_overloads) { if (!func->isStatic()) return true; } @@ -670,7 +679,8 @@ OverloadDataList OverloadData::overloadDataOnPosition(OverloadData* overloadData if (overloadData->argPos() == argPos) { overloadDataList.append(overloadData); } else if (overloadData->argPos() < argPos) { - foreach (OverloadData* pd, overloadData->nextOverloadData()) + const OverloadDataList &data = overloadData->nextOverloadData(); + for (OverloadData *pd : data) overloadDataList += overloadDataOnPosition(pd, argPos); } return overloadDataList; @@ -685,7 +695,7 @@ OverloadDataList OverloadData::overloadDataOnPosition(int argPos) const bool OverloadData::nextArgumentHasDefaultValue() const { - foreach (OverloadData* overloadData, m_nextOverloadData) { + for (OverloadData *overloadData : m_nextOverloadData) { if (overloadData->getFunctionWithDefaultValue()) return true; } @@ -698,7 +708,8 @@ static OverloadData* _findNextArgWithDefault(OverloadData* overloadData) return overloadData; OverloadData* result = 0; - foreach (OverloadData* odata, overloadData->nextOverloadData()) { + const OverloadDataList &data = overloadData->nextOverloadData(); + for (OverloadData *odata : data) { OverloadData* tmp = _findNextArgWithDefault(odata); if (!result || (tmp && result->argPos() > tmp->argPos())) result = tmp; @@ -713,20 +724,20 @@ OverloadData* OverloadData::findNextArgWithDefault() bool OverloadData::isFinalOccurrence(const AbstractMetaFunction* func) const { - foreach (const OverloadData* pd, m_nextOverloadData) { + for (const OverloadData *pd : m_nextOverloadData) { if (pd->overloads().contains(func)) return false; } return true; } -QList<const AbstractMetaFunction*> OverloadData::overloadsWithoutRepetition() const +OverloadData::MetaFunctionList OverloadData::overloadsWithoutRepetition() const { - QList<const AbstractMetaFunction*> overloads = m_overloads; - foreach (const AbstractMetaFunction* func, m_overloads) { + MetaFunctionList overloads = m_overloads; + for (const AbstractMetaFunction *func : m_overloads) { if (func->minimalSignature().endsWith(QLatin1String("const"))) continue; - foreach (const AbstractMetaFunction* f, overloads) { + for (const AbstractMetaFunction *f : qAsConst(overloads)) { if ((func->minimalSignature() + QLatin1String("const")) == f->minimalSignature()) { overloads.removeOne(f); break; @@ -738,7 +749,7 @@ QList<const AbstractMetaFunction*> OverloadData::overloadsWithoutRepetition() co const AbstractMetaFunction* OverloadData::getFunctionWithDefaultValue() const { - foreach (const AbstractMetaFunction* func, m_overloads) { + for (const AbstractMetaFunction *func : m_overloads) { int removedArgs = 0; for (int i = 0; i <= m_argPos + removedArgs; i++) { if (func->argumentRemoved(i + 1)) @@ -750,11 +761,11 @@ const AbstractMetaFunction* OverloadData::getFunctionWithDefaultValue() const return 0; } -QList<int> OverloadData::invalidArgumentLengths() const +QVector<int> OverloadData::invalidArgumentLengths() const { QSet<int> validArgLengths; - foreach (const AbstractMetaFunction* func, m_headOverloadData->m_overloads) { + for (const AbstractMetaFunction *func : qAsConst(m_headOverloadData->m_overloads)) { const AbstractMetaArgumentList args = func->arguments(); int offset = 0; for (int i = 0; i < args.size(); ++i) { @@ -768,7 +779,7 @@ QList<int> OverloadData::invalidArgumentLengths() const validArgLengths << args.size() - offset; } - QList<int> invalidArgLengths; + QVector<int> invalidArgLengths; for (int i = minArgs() + 1; i < maxArgs(); i++) { if (!validArgLengths.contains(i)) invalidArgLengths.append(i); @@ -821,7 +832,7 @@ QPair<int, int> OverloadData::getMinMaxArguments(const AbstractMetaFunctionList& bool OverloadData::isSingleArgument(const AbstractMetaFunctionList& overloads) { bool singleArgument = true; - foreach (const AbstractMetaFunction* func, overloads) { + for (const AbstractMetaFunction *func : overloads) { if (func->arguments().size() - numberOfRemovedArguments(func) != 1) { singleArgument = false; break; @@ -859,7 +870,7 @@ QString OverloadData::dumpGraph() const // Shows all function signatures s << "legend [fontsize=9 fontname=freemono shape=rect label=\""; - foreach (const AbstractMetaFunction* func, overloads()) { + for (const AbstractMetaFunction *func : m_overloads) { s << "f" << functionNumber(func) << " : "; if (func->type()) s << toHtml(func->type()->cppSignature()); @@ -893,7 +904,7 @@ QString OverloadData::dumpGraph() const s << "</td></tr>"; // Shows type changes for all function signatures - foreach (const AbstractMetaFunction* func, overloads()) { + for (const AbstractMetaFunction *func : m_overloads) { if (func->typeReplaced(0).isEmpty()) continue; s << "<tr><td bgcolor=\"gray\" align=\"right\">f" << functionNumber(func); @@ -916,13 +927,13 @@ QString OverloadData::dumpGraph() const // Overloads for the signature to present point s << "<tr><td bgcolor=\"gray\" align=\"right\">overloads</td><td bgcolor=\"gray\" align=\"left\">"; - foreach (const AbstractMetaFunction* func, overloads()) + for (const AbstractMetaFunction *func : m_overloads) s << 'f' << functionNumber(func) << ' '; s << "</td></tr>"; s << "</table>> ];" << endl; - foreach (const OverloadData* pd, nextOverloadData()) + for (const OverloadData *pd : m_nextOverloadData) s << indent << '"' << rfunc->name() << "\" -> " << pd->dumpGraph(); s << "}" << endl; @@ -948,12 +959,12 @@ QString OverloadData::dumpGraph() const // Overloads for the signature to present point s << "<tr><td bgcolor=\"gray\" align=\"right\">overloads</td><td bgcolor=\"gray\" align=\"left\">"; - foreach (const AbstractMetaFunction* func, overloads()) + for (const AbstractMetaFunction *func : m_overloads) s << 'f' << functionNumber(func) << ' '; s << "</td></tr>"; // Show default values (original and modified) for various functions - foreach (const AbstractMetaFunction* func, overloads()) { + for (const AbstractMetaFunction *func : m_overloads) { const AbstractMetaArgument* arg = argument(func); if (!arg) continue; @@ -973,7 +984,7 @@ QString OverloadData::dumpGraph() const s << "</table>>];" << endl; - foreach (const OverloadData* pd, nextOverloadData()) + for (const OverloadData *pd : m_nextOverloadData) s << indent << argId << " -> " << pd->dumpGraph(); } return result; @@ -1004,7 +1015,7 @@ bool OverloadData::hasArgumentWithDefaultValue(const AbstractMetaFunctionList& o { if (OverloadData::getMinMaxArguments(overloads).second == 0) return false; - foreach (const AbstractMetaFunction* func, overloads) { + for (const AbstractMetaFunction *func : overloads) { if (hasArgumentWithDefaultValue(func)) return true; } @@ -1015,7 +1026,7 @@ bool OverloadData::hasArgumentWithDefaultValue() const { if (maxArgs() == 0) return false; - foreach (const AbstractMetaFunction* func, overloads()) { + for (const AbstractMetaFunction *func : m_overloads) { if (hasArgumentWithDefaultValue(func)) return true; } @@ -1024,7 +1035,8 @@ bool OverloadData::hasArgumentWithDefaultValue() const bool OverloadData::hasArgumentWithDefaultValue(const AbstractMetaFunction* func) { - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (func->argumentRemoved(arg->argumentIndex() + 1)) continue; if (!ShibokenGenerator::getDefaultValue(func, arg).isEmpty()) @@ -1036,7 +1048,8 @@ bool OverloadData::hasArgumentWithDefaultValue(const AbstractMetaFunction* func) AbstractMetaArgumentList OverloadData::getArgumentsWithDefaultValues(const AbstractMetaFunction* func) { AbstractMetaArgumentList args; - foreach (AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (AbstractMetaArgument *arg : arguments) { if (ShibokenGenerator::getDefaultValue(func, arg).isEmpty() || func->argumentRemoved(arg->argumentIndex() + 1)) continue; diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.h b/sources/shiboken2/generator/shiboken2/overloaddata.h index 959b96d0b..2d815f6bb 100644 --- a/sources/shiboken2/generator/shiboken2/overloaddata.h +++ b/sources/shiboken2/generator/shiboken2/overloaddata.h @@ -30,19 +30,21 @@ #define OVERLOADDATA_H #include <abstractmetalang_typedefs.h> -#include <QtCore/QList> #include <QtCore/QBitArray> +#include <QtCore/QVector> QT_FORWARD_DECLARE_CLASS(QDebug) class ShibokenGenerator; class OverloadData; -typedef QList<OverloadData*> OverloadDataList; +typedef QVector<OverloadData *> OverloadDataList; class OverloadData { public: + typedef QVector<const AbstractMetaFunction *> MetaFunctionList; + OverloadData(const AbstractMetaFunctionList& overloads, const ShibokenGenerator* generator); ~OverloadData(); @@ -100,12 +102,12 @@ public: bool isFinalOccurrence(const AbstractMetaFunction* func) const; /// Returns the list of overloads removing repeated constant functions (ex.: "foo()" and "foo()const", the second is removed). - QList<const AbstractMetaFunction*> overloadsWithoutRepetition() const; - const QList<const AbstractMetaFunction*>& overloads() const { return m_overloads; } + MetaFunctionList overloadsWithoutRepetition() const; + const MetaFunctionList& overloads() const { return m_overloads; } OverloadDataList nextOverloadData() const { return m_nextOverloadData; } OverloadData* previousOverloadData() const { return m_previousOverloadData; } - QList<int> invalidArgumentLengths() const; + QVector<int> invalidArgumentLengths() const; static int numberOfRemovedArguments(const AbstractMetaFunction* func, int finalArgPos = -1); static QPair<int, int> getMinMaxArguments(const AbstractMetaFunctionList& overloads); @@ -146,7 +148,7 @@ private: int m_argPos; const AbstractMetaType* m_argType; QString m_argTypeReplaced; - QList<const AbstractMetaFunction*> m_overloads; + MetaFunctionList m_overloads; OverloadData* m_headOverloadData; OverloadDataList m_nextOverloadData; diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp index 7b664e105..4768ddc88 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp @@ -35,6 +35,7 @@ #include <QtCore/QDir> #include <QtCore/QDebug> +#include <QtCore/QRegularExpression> #include <limits> #include <memory> @@ -54,6 +55,11 @@ QHash<QString, QString> ShibokenGenerator::m_formatUnits = QHash<QString, QStrin QHash<QString, QString> ShibokenGenerator::m_tpFuncs = QHash<QString, QString>(); QStringList ShibokenGenerator::m_knownPythonTypes = QStringList(); +static QRegularExpression placeHolderRegex(int index) +{ + return QRegularExpression(QLatin1Char('%') + QString::number(index) + QStringLiteral("\\b")); +} + static QString resolveScopePrefix(const AbstractMetaClass* scope, const QString& value) { if (!scope) @@ -87,10 +93,10 @@ ShibokenGenerator::ShibokenGenerator() : Generator() m_typeSystemConvName[TypeSystemIsConvertibleFunction] = QLatin1String("isConvertible"); m_typeSystemConvName[TypeSystemToCppFunction] = QLatin1String("toCpp"); m_typeSystemConvName[TypeSystemToPythonFunction] = QLatin1String("toPython"); - m_typeSystemConvRegEx[TypeSystemCheckFunction] = QRegExp(QLatin1String(CHECKTYPE_REGEX)); - m_typeSystemConvRegEx[TypeSystemIsConvertibleFunction] = QRegExp(QLatin1String(ISCONVERTIBLE_REGEX)); - m_typeSystemConvRegEx[TypeSystemToPythonFunction] = QRegExp(QLatin1String(CONVERTTOPYTHON_REGEX)); - m_typeSystemConvRegEx[TypeSystemToCppFunction] = QRegExp(QLatin1String(CONVERTTOCPP_REGEX)); + m_typeSystemConvRegEx[TypeSystemCheckFunction] = QRegularExpression(QLatin1String(CHECKTYPE_REGEX)); + m_typeSystemConvRegEx[TypeSystemIsConvertibleFunction] = QRegularExpression(QLatin1String(ISCONVERTIBLE_REGEX)); + m_typeSystemConvRegEx[TypeSystemToPythonFunction] = QRegularExpression(QLatin1String(CONVERTTOPYTHON_REGEX)); + m_typeSystemConvRegEx[TypeSystemToCppFunction] = QRegularExpression(QLatin1String(CONVERTTOCPP_REGEX)); } ShibokenGenerator::~ShibokenGenerator() @@ -243,7 +249,8 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass* metaCl if (!result && metaClass->hasProtectedFunctions()) { int protectedFunctions = 0; int protectedOperators = 0; - foreach (const AbstractMetaFunction* func, metaClass->functions()) { + const AbstractMetaFunctionList &funcs = metaClass->functions(); + for (const AbstractMetaFunction *func : funcs) { if (!func->isProtected() || func->isSignal() || func->isModifiedRemoved()) continue; else if (func->isOperatorOverload()) @@ -265,7 +272,8 @@ void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumLi return; if (metaClass->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass) { - foreach (const AbstractMetaEnum* metaEnum, metaClass->enums()) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (const AbstractMetaEnum *metaEnum : enums) { if (metaEnum->isPrivate() || metaEnum->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass) continue; if (!enumList.contains(const_cast<AbstractMetaEnum*>(metaEnum))) @@ -412,9 +420,10 @@ static QString searchForEnumScope(const AbstractMetaClass* metaClass, const QStr if (!metaClass) return QString(); - - foreach (const AbstractMetaEnum* metaEnum, metaClass->enums()) { - foreach (const AbstractMetaEnumValue* enumValue, metaEnum->values()) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (const AbstractMetaEnum* metaEnum : enums) { + const AbstractMetaEnumValueList &values = metaEnum->values(); + for (const AbstractMetaEnumValue *enumValue : values) { if (enumValueName == enumValue->name()) return metaClass->qualifiedCppName(); } @@ -441,7 +450,14 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction* if (isPointer(arg->type())) return value; - static QRegExp enumValueRegEx(QLatin1String("^([A-Za-z_]\\w*)?$")); + static const QRegularExpression enumValueRegEx(QStringLiteral("^([A-Za-z_]\\w*)?$")); + Q_ASSERT(enumValueRegEx.isValid()); + // Do not qualify macros by class name, eg QSGGeometry(..., int t = GL_UNSIGNED_SHORT); + static const QRegularExpression macroRegEx(QStringLiteral("^[A-Z_][A-Z0-9_]*$")); + Q_ASSERT(macroRegEx.isValid()); + if (arg->type()->isPrimitive() && macroRegEx.match(value).hasMatch()) + return value; + QString prefix; QString suffix; @@ -450,8 +466,9 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction* if (metaEnum) prefix = resolveScopePrefix(metaEnum->enclosingClass(), value); } else if (arg->type()->isFlags()) { - static QRegExp numberRegEx(QLatin1String("^\\d+$")); // Numbers to flags - if (numberRegEx.exactMatch(value)) { + static const QRegularExpression numberRegEx(QStringLiteral("^\\d+$")); // Numbers to flags + Q_ASSERT(numberRegEx.isValid()); + if (numberRegEx.match(value).hasMatch()) { QString typeName = translateTypeForWrapperMethod(arg->type(), func->implementingClass()); if (arg->type()->isConstant()) typeName.remove(0, sizeof("const ") / sizeof(char) - 1); @@ -469,16 +486,18 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction* suffix = QLatin1Char(')'); } - static QRegExp enumCombinationRegEx(QLatin1String("^([A-Za-z_][\\w:]*)\\(([^,\\(\\)]*)\\)$")); // FlagName(EnumItem|EnumItem|...) - if (prefix.isEmpty() && enumCombinationRegEx.indexIn(value) != -1) { - QString flagName = enumCombinationRegEx.cap(1); - QStringList enumItems = enumCombinationRegEx.cap(2).split(QLatin1Char('|')); + static const QRegularExpression enumCombinationRegEx(QStringLiteral("^([A-Za-z_][\\w:]*)\\(([^,\\(\\)]*)\\)$")); // FlagName(EnumItem|EnumItem|...) + Q_ASSERT(enumCombinationRegEx.isValid()); + const QRegularExpressionMatch match = enumCombinationRegEx.match(value); + if (prefix.isEmpty() && match.hasMatch()) { + QString flagName = match.captured(1); + QStringList enumItems = match.captured(2).split(QLatin1Char('|')); QString scope = searchForEnumScope(func->implementingClass(), enumItems.first()); if (!scope.isEmpty()) scope.append(QLatin1String("::")); QStringList fixedEnumItems; - foreach (const QString& enumItem, enumItems) + for (const QString &enumItem : qAsConst(enumItems)) fixedEnumItems << QString(scope + enumItem); if (!fixedEnumItems.isEmpty()) { @@ -489,16 +508,19 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction* } } else if (arg->type()->typeEntry()->isValue()) { const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes(), arg->type()->typeEntry()); - if (enumValueRegEx.exactMatch(value)&& value != QLatin1String("NULL")) + if (enumValueRegEx.match(value).hasMatch() && value != QLatin1String("NULL")) prefix = resolveScopePrefix(metaClass, value); } else if (arg->type()->isPrimitive() && arg->type()->name() == QLatin1String("int")) { - if (enumValueRegEx.exactMatch(value) && func->implementingClass()) + if (enumValueRegEx.match(value).hasMatch() && func->implementingClass()) prefix = resolveScopePrefix(func->implementingClass(), value); } else if(arg->type()->isPrimitive()) { - static QRegExp unknowArgumentRegEx(QLatin1String("^(?:[A-Za-z_][\\w:]*\\()?([A-Za-z_]\\w*)(?:\\))?$")); // [PrimitiveType(] DESIREDNAME [)] - if (unknowArgumentRegEx.indexIn(value) != -1 && func->implementingClass()) { - foreach (const AbstractMetaField* field, func->implementingClass()->fields()) { - if (unknowArgumentRegEx.cap(1).trimmed() == field->name()) { + static const QRegularExpression unknowArgumentRegEx(QStringLiteral("^(?:[A-Za-z_][\\w:]*\\()?([A-Za-z_]\\w*)(?:\\))?$")); // [PrimitiveType(] DESIREDNAME [)] + Q_ASSERT(unknowArgumentRegEx.isValid()); + const QRegularExpressionMatch match = unknowArgumentRegEx.match(value); + if (match.hasMatch() && func->implementingClass()) { + const AbstractMetaFieldList &fields = func->implementingClass()->fields(); + for (const AbstractMetaField *field : fields) { + if (match.captured(1).trimmed() == field->name()) { QString fieldName = field->name(); if (field->isStatic()) { prefix = resolveScopePrefix(func->implementingClass(), value); @@ -507,7 +529,7 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction* } else { fieldName.prepend(QLatin1String(CPP_SELF_VAR "->")); } - value.replace(unknowArgumentRegEx.cap(1), fieldName); + value.replace(match.captured(1), fieldName); break; } } @@ -619,8 +641,9 @@ bool ShibokenGenerator::shouldRejectNullPointerArgument(const AbstractMetaFuncti return false; if (func->argumentRemoved(argIndex + 1)) return false; - foreach (const FunctionModification &funcMod, func->modifications()) { - foreach (const ArgumentModification &argMod, funcMod.argument_mods) { + const FunctionModificationList &mods = func->modifications(); + for (const FunctionModification &funcMod : mods) { + for (const ArgumentModification &argMod : funcMod.argument_mods) { if (argMod.index == argIndex + 1 && argMod.noNullPointers) return true; } @@ -632,7 +655,8 @@ QString ShibokenGenerator::getFormatUnitString(const AbstractMetaFunction* func, { QString result; const char objType = (incRef ? 'O' : 'N'); - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (func->argumentRemoved(arg->argumentIndex() + 1)) continue; @@ -1051,7 +1075,8 @@ bool ShibokenGenerator::shouldDereferenceAbstractMetaTypePointer(const AbstractM bool ShibokenGenerator::visibilityModifiedToPrivate(const AbstractMetaFunction* func) { - foreach (const FunctionModification &mod, func->modifications()) { + const FunctionModificationList &mods = func->modifications(); + for (const FunctionModification &mod : mods) { if (mod.modifiers & Modification::Private) return true; } @@ -1307,8 +1332,6 @@ QString ShibokenGenerator::argumentString(const AbstractMetaFunction *func, arg += argument->name(); } - QList<ReferenceCount> referenceCounts; - referenceCounts = func->referenceCounts(func->implementingClass(), argument->argumentIndex() + 1); if ((options & Generator::SkipDefaultValues) != Generator::SkipDefaultValues && !argument->originalDefaultValueExpression().isEmpty()) { @@ -1442,7 +1465,8 @@ void ShibokenGenerator::writeUnusedVariableCast(QTextStream& s, const QString& v AbstractMetaFunctionList ShibokenGenerator::filterFunctions(const AbstractMetaClass* metaClass) { AbstractMetaFunctionList result; - foreach (AbstractMetaFunction *func, metaClass->functions()) { + const AbstractMetaFunctionList &funcs = metaClass->functions(); + for (AbstractMetaFunction *func : funcs) { if (func->isSignal() || func->isDestructor() || func->usesRValueReferences() || (func->isModifiedRemoved() && !func->isAbstract() && (!avoidProtectedHack() || !func->isProtected()))) @@ -1455,11 +1479,13 @@ AbstractMetaFunctionList ShibokenGenerator::filterFunctions(const AbstractMetaCl ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverters() const { ExtendedConverterData extConvs; - foreach (const AbstractMetaClass* metaClass, classes()) { + const AbstractMetaClassList &classList = classes(); + for (const AbstractMetaClass *metaClass : classList) { // Use only the classes for the current module. if (!shouldGenerate(metaClass)) continue; - foreach (AbstractMetaFunction* convOp, metaClass->operatorOverloads(AbstractMetaClass::ConversionOp)) { + const AbstractMetaFunctionList &overloads = metaClass->operatorOverloads(AbstractMetaClass::ConversionOp); + for (AbstractMetaFunction *convOp : overloads) { // Get only the conversion operators that return a type from another module, // that are value-types and were not removed in the type system. const TypeEntry* convType = convOp->type()->typeEntry(); @@ -1473,10 +1499,11 @@ ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverter return extConvs; } -QList<const CustomConversion*> ShibokenGenerator::getPrimitiveCustomConversions() +QVector<const CustomConversion *> ShibokenGenerator::getPrimitiveCustomConversions() { - QList<const CustomConversion*> conversions; - foreach (const PrimitiveTypeEntry* type, primitiveTypes()) { + QVector<const CustomConversion*> conversions; + const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes(); + for (const PrimitiveTypeEntry *type : primitiveTypeList) { if (!shouldGenerateTypeEntry(type) || !isUserPrimitive(type) || !type->customConversion()) continue; @@ -1519,7 +1546,7 @@ QString ShibokenGenerator::getCodeSnippets(const CodeSnipList& codeSnips, { QString code; QTextStream c(&code); - foreach (const CodeSnip &snip, codeSnips) { + for (const CodeSnip &snip : codeSnips) { if ((position != TypeSystem::CodeSnipPositionAny && snip.position != position) || !(snip.language & language)) continue; QString snipCode; @@ -1620,6 +1647,17 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, s << INDENT << "// End of code injection" << endl; } +static QString msgWrongIndex(const char *varName, const QString &capture, const AbstractMetaFunction *func) +{ + QString result; + QTextStream str(&result); + str << "Wrong index for " << varName << " variable (" << capture << ") on "; + if (const AbstractMetaClass *c = func->implementingClass()) + str << c->name() << "::"; + str << func->signature(); + return result; +} + void ShibokenGenerator::writeCodeSnips(QTextStream& s, const CodeSnipList& codeSnips, TypeSystem::CodeSnipPosition position, @@ -1644,15 +1682,18 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, // Replace %PYARG_# variables. code.replace(QLatin1String("%PYARG_0"), QLatin1String(PYTHON_RETURN_VAR)); - static QRegExp pyArgsRegex(QLatin1String("%PYARG_(\\d+)")); + static const QRegularExpression pyArgsRegex(QStringLiteral("%PYARG_(\\d+)")); + Q_ASSERT(pyArgsRegex.isValid()); if (language == TypeSystem::TargetLangCode) { if (usePyArgs) { code.replace(pyArgsRegex, QLatin1String(PYTHON_ARGS"[\\1-1]")); } else { - static QRegExp pyArgsRegexCheck(QLatin1String("%PYARG_([2-9]+)")); - if (pyArgsRegexCheck.indexIn(code) != -1) { + static const QRegularExpression pyArgsRegexCheck(QStringLiteral("%PYARG_([2-9]+)")); + Q_ASSERT(pyArgsRegexCheck.isValid()); + const QRegularExpressionMatch match = pyArgsRegexCheck.match(code); + if (match.hasMatch()) { qCWarning(lcShiboken).noquote().nospace() - << "Wrong index for %PYARG variable (" << pyArgsRegexCheck.cap(1) << ") on " << func->signature(); + << msgWrongIndex("%PYARG", match.captured(1), func); return; } code.replace(QLatin1String("%PYARG_1"), QLatin1String(PYTHON_ARG)); @@ -1660,25 +1701,27 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, } else { // Replaces the simplest case of attribution to a // Python argument on the binding virtual method. - static QRegExp pyArgsAttributionRegex(QLatin1String("%PYARG_(\\d+)\\s*=[^=]\\s*([^;]+)")); + static const QRegularExpression pyArgsAttributionRegex(QStringLiteral("%PYARG_(\\d+)\\s*=[^=]\\s*([^;]+)")); + Q_ASSERT(pyArgsAttributionRegex.isValid()); code.replace(pyArgsAttributionRegex, QLatin1String("PyTuple_SET_ITEM(" PYTHON_ARGS ", \\1-1, \\2)")); code.replace(pyArgsRegex, QLatin1String("PyTuple_GET_ITEM(" PYTHON_ARGS ", \\1-1)")); } // Replace %ARG#_TYPE variables. - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { QString argTypeVar = QStringLiteral("%ARG%1_TYPE").arg(arg->argumentIndex() + 1); QString argTypeVal = arg->type()->cppSignature(); code.replace(argTypeVar, argTypeVal); } - int pos = 0; - static QRegExp cppArgTypeRegexCheck(QLatin1String("%ARG(\\d+)_TYPE")); - while ((pos = cppArgTypeRegexCheck.indexIn(code, pos)) != -1) { + static const QRegularExpression cppArgTypeRegexCheck(QStringLiteral("%ARG(\\d+)_TYPE")); + Q_ASSERT(cppArgTypeRegexCheck.isValid()); + QRegularExpressionMatchIterator rit = cppArgTypeRegexCheck.globalMatch(code); + while (rit.hasNext()) { + QRegularExpressionMatch match = rit.next(); qCWarning(lcShiboken).noquote().nospace() - << "Wrong index for %ARG#_TYPE variable (" << cppArgTypeRegexCheck.cap(1) - << ") on " << func->signature(); - pos += cppArgTypeRegexCheck.matchedLength(); + << msgWrongIndex("%ARG#_TYPE", match.captured(1), func); } // Replace template variable for return variable name. @@ -1759,17 +1802,17 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, // Replaces template %ARGUMENT_NAMES and %# variables by argument variables and values. // Replaces template variables %# for individual arguments. - ArgumentVarReplacementList argReplacements = getArgumentReplacement(func, usePyArgs, language, lastArg); + const ArgumentVarReplacementList &argReplacements = getArgumentReplacement(func, usePyArgs, language, lastArg); QStringList args; - foreach (const ArgumentVarReplacementPair &pair, argReplacements) { + for (const ArgumentVarReplacementPair &pair : argReplacements) { if (pair.second.startsWith(QLatin1String(CPP_ARG_REMOVED))) continue; args << pair.second; } code.replace(QLatin1String("%ARGUMENT_NAMES"), args.join(QLatin1String(", "))); - foreach (const ArgumentVarReplacementPair &pair, argReplacements) { + for (const ArgumentVarReplacementPair &pair : argReplacements) { const AbstractMetaArgument* arg = pair.first; int idx = arg->argumentIndex() + 1; AbstractMetaType* type = arg->type(); @@ -1786,7 +1829,7 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, if (type->referenceType() == LValueReference || isPointer(type)) code.replace(QString::fromLatin1("%%1.").arg(idx), replacement + QLatin1String("->")); } - code.replace(QRegExp(QString::fromLatin1("%%1\\b").arg(idx)), pair.second); + code.replace(placeHolderRegex(idx), pair.second); } if (language == TypeSystem::NativeCode) { @@ -1808,7 +1851,8 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, // dispatcher. bool hasProtectedOverload = false; if (func->isUserAdded()) { - foreach (const AbstractMetaFunction* f, getFunctionOverloads(func->ownerClass(), func->name())) + const AbstractMetaFunctionList &funcs = getFunctionOverloads(func->ownerClass(), func->name()); + for (const AbstractMetaFunction *f : funcs) hasProtectedOverload |= f->isProtected(); } @@ -1839,8 +1883,9 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, // and false if it is a variable. static bool isVariable(const QString& code) { - static QRegExp expr(QLatin1String("\\s*\\*?\\s*[A-Za-z_][A-Za-z_0-9.]*\\s*(?:\\[[^\\[]+\\])*")); - return expr.exactMatch(code.trimmed()); + static const QRegularExpression expr(QStringLiteral("^\\s*\\*?\\s*[A-Za-z_][A-Za-z_0-9.]*\\s*(?:\\[[^\\[]+\\])*$")); + Q_ASSERT(expr.isValid()); + return expr.match(code.trimmed()).hasMatch(); } // A miniature normalizer that puts a type string into a format @@ -1890,12 +1935,11 @@ static QString getConverterTypeSystemVariableArgument(const QString& code, int p typedef QPair<QString, QString> StringPair; void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVariable converterVariable, QString& code) { - QRegExp& regex = m_typeSystemConvRegEx[converterVariable]; - int pos = 0; - QList<StringPair> replacements; - while ((pos = regex.indexIn(code, pos)) != -1) { - pos += regex.matchedLength(); - QStringList list = regex.capturedTexts(); + QVector<StringPair> replacements; + QRegularExpressionMatchIterator rit = m_typeSystemConvRegEx[converterVariable].globalMatch(code); + while (rit.hasNext()) { + const QRegularExpressionMatch match = rit.next(); + const QStringList list = match.capturedTexts(); QString conversionString = list.first(); QString conversionTypeName = list.last(); const AbstractMetaType* conversionType = buildAbstractMetaTypeFromString(conversionTypeName); @@ -1909,7 +1953,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa QTextStream c(&conversion); switch (converterVariable) { case TypeSystemToCppFunction: { - int end = pos - list.first().count(); + int end = match.capturedStart(); int start = end; while (start > 0 && code.at(start) != QLatin1Char('\n')) --start; @@ -1938,7 +1982,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa } else { prefix = QLatin1Char('&'); } - QString arg = getConverterTypeSystemVariableArgument(code, pos); + QString arg = getConverterTypeSystemVariableArgument(code, match.capturedEnd()); conversionString += arg; c << arg << ", " << prefix << '(' << varName << ')'; break; @@ -1958,7 +2002,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa if (conversion.isEmpty()) conversion = cpythonToPythonConversionFunction(conversionType); default: { - QString arg = getConverterTypeSystemVariableArgument(code, pos); + QString arg = getConverterTypeSystemVariableArgument(code, match.capturedEnd()); conversionString += arg; if (converterVariable == TypeSystemToPythonFunction && !isVariable(arg)) { qFatal(qPrintable(QString::fromLatin1("Only variables are acceptable as argument to %%CONVERTTOPYTHON type system variable on code snippet: '%1'") @@ -1974,14 +2018,14 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa } replacements.append(qMakePair(conversionString, conversion)); } - foreach (const StringPair &rep, replacements) + for (const StringPair &rep : qAsConst(replacements)) code.replace(rep.first, rep.second); } bool ShibokenGenerator::injectedCodeUsesCppSelf(const AbstractMetaFunction* func) { CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode); - foreach (const CodeSnip &snip, snips) { + for (const CodeSnip &snip : qAsConst(snips)) { if (snip.code().contains(QLatin1String("%CPPSELF"))) return true; } @@ -1991,7 +2035,7 @@ bool ShibokenGenerator::injectedCodeUsesCppSelf(const AbstractMetaFunction* func bool ShibokenGenerator::injectedCodeUsesPySelf(const AbstractMetaFunction* func) { CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::NativeCode); - foreach (const CodeSnip &snip, snips) { + for (const CodeSnip &snip : qAsConst(snips)) { if (snip.code().contains(QLatin1String("%PYSELF"))) return true; } @@ -2007,7 +2051,7 @@ bool ShibokenGenerator::injectedCodeCallsCppFunction(const AbstractMetaFunction* wrappedCtorCall = QStringLiteral("new %1(").arg(wrapperName(func->ownerClass())); } CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode); - foreach (const CodeSnip &snip, snips) { + for (const CodeSnip &snip : qAsConst(snips)) { if (snip.code().contains(QLatin1String("%FUNCTION_NAME(")) || snip.code().contains(funcCall) || (func->isConstructor() && ((func->ownerClass()->isPolymorphic() && snip.code().contains(wrappedCtorCall)) @@ -2020,10 +2064,11 @@ bool ShibokenGenerator::injectedCodeCallsCppFunction(const AbstractMetaFunction* bool ShibokenGenerator::injectedCodeCallsPythonOverride(const AbstractMetaFunction* func) { - static QRegExp overrideCallRegexCheck(QLatin1String("PyObject_Call\\s*\\(\\s*%PYTHON_METHOD_OVERRIDE\\s*,")); + static const QRegularExpression overrideCallRegexCheck(QStringLiteral("PyObject_Call\\s*\\(\\s*%PYTHON_METHOD_OVERRIDE\\s*,")); + Q_ASSERT(overrideCallRegexCheck.isValid()); CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::NativeCode); - foreach (const CodeSnip &snip, snips) { - if (overrideCallRegexCheck.indexIn(snip.code()) != -1) + for (const CodeSnip &snip : qAsConst(snips)) { + if (snip.code().contains(overrideCallRegexCheck)) return true; } return false; @@ -2031,15 +2076,17 @@ bool ShibokenGenerator::injectedCodeCallsPythonOverride(const AbstractMetaFuncti bool ShibokenGenerator::injectedCodeHasReturnValueAttribution(const AbstractMetaFunction* func, TypeSystem::Language language) { - static QRegExp retValAttributionRegexCheck_native(QLatin1String("%0\\s*=[^=]\\s*.+")); - static QRegExp retValAttributionRegexCheck_target(QLatin1String("%PYARG_0\\s*=[^=]\\s*.+")); + static const QRegularExpression retValAttributionRegexCheck_native(QStringLiteral("%0\\s*=[^=]\\s*.+")); + Q_ASSERT(retValAttributionRegexCheck_native.isValid()); + static const QRegularExpression retValAttributionRegexCheck_target(QStringLiteral("%PYARG_0\\s*=[^=]\\s*.+")); + Q_ASSERT(retValAttributionRegexCheck_target.isValid()); CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, language); - foreach (const CodeSnip &snip, snips) { + for (const CodeSnip &snip : qAsConst(snips)) { if (language == TypeSystem::TargetLangCode) { - if (retValAttributionRegexCheck_target.indexIn(snip.code()) != -1) + if (snip.code().contains(retValAttributionRegexCheck_target)) return true; } else { - if (retValAttributionRegexCheck_native.indexIn(snip.code()) != -1) + if (snip.code().contains(retValAttributionRegexCheck_native)) return true; } } @@ -2049,11 +2096,10 @@ bool ShibokenGenerator::injectedCodeHasReturnValueAttribution(const AbstractMeta bool ShibokenGenerator::injectedCodeUsesArgument(const AbstractMetaFunction* func, int argumentIndex) { CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny); - foreach (const CodeSnip &snip, snips) { + const QRegularExpression argRegEx = placeHolderRegex(argumentIndex + 1); + for (const CodeSnip &snip : qAsConst(snips)) { QString code = snip.code(); - if (code.contains(QLatin1String("%ARGUMENT_NAMES"))) - return true; - if (code.contains(QRegExp(QStringLiteral("%%1\\b").arg(argumentIndex + 1)))) + if (code.contains(QLatin1String("%ARGUMENT_NAMES")) || code.contains(argRegEx)) return true; } return false; @@ -2080,7 +2126,7 @@ bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass* meta const FunctionGroupMap &functionGroup = getFunctionGroups(metaClass); for (FunctionGroupMapIt it = functionGroup.cbegin(), end = functionGroup.cend(); it != end; ++it) { AbstractMetaFunctionList overloads; - foreach (AbstractMetaFunction* func, it.value()) { + for (AbstractMetaFunction *func : qAsConst(it.value())) { if (func->isAssignmentOperator() || func->isCastOperator() || func->isModifiedRemoved() || func->isPrivate() || func->ownerClass() != func->implementingClass() || func->isConstructor() || func->isOperatorOverload()) @@ -2111,7 +2157,7 @@ AbstractMetaFunctionList ShibokenGenerator::getMethodsWithBothStaticAndNonStatic const FunctionGroupMap &functionGroups = getFunctionGroups(metaClass); for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { AbstractMetaFunctionList overloads; - foreach (AbstractMetaFunction* func, it.value()) { + for (AbstractMetaFunction *func : qAsConst(it.value())) { if (func->isAssignmentOperator() || func->isCastOperator() || func->isModifiedRemoved() || func->isPrivate() || func->ownerClass() != func->implementingClass() || func->isConstructor() || func->isOperatorOverload()) @@ -2131,7 +2177,8 @@ AbstractMetaClassList ShibokenGenerator::getBaseClasses(const AbstractMetaClass* { AbstractMetaClassList baseClasses; if (metaClass) { - foreach (const QString &parent, metaClass->baseClassNames()) { + const QStringList &baseClassNames = metaClass->baseClassNames(); + for (const QString &parent : baseClassNames) { AbstractMetaClass *clazz = AbstractMetaClass::findClass(classes(), parent); if (clazz) baseClasses << clazz; @@ -2154,7 +2201,7 @@ AbstractMetaClassList ShibokenGenerator::getAllAncestors(const AbstractMetaClass AbstractMetaClassList result; if (metaClass) { AbstractMetaClassList baseClasses = getBaseClasses(metaClass); - foreach (AbstractMetaClass* base, baseClasses) { + for (AbstractMetaClass *base : qAsConst(baseClasses)) { result.append(base); result.append(getAllAncestors(base)); } @@ -2265,7 +2312,7 @@ AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ metaType->setReferenceType(refType); metaType->setConstant(isConst); metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); - foreach (const QString& instantiation, instantiatedTypes) { + for (const QString &instantiation : qAsConst(instantiatedTypes)) { AbstractMetaType* tmplArgType = buildAbstractMetaTypeFromString(instantiation); metaType->addInstantiation(tmplArgType); } @@ -2300,7 +2347,7 @@ AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromAbstractMetaClass( static void dumpFunction(AbstractMetaFunctionList lst) { qDebug() << "DUMP FUNCTIONS: "; - foreach (AbstractMetaFunction *func, lst) + for (AbstractMetaFunction *func : qAsConst(lst)) qDebug() << "*" << func->ownerClass()->name() << func->signature() << "Private: " << func->isPrivate() @@ -2328,7 +2375,7 @@ QMap< QString, AbstractMetaFunctionList > ShibokenGenerator::getFunctionGroups(c AbstractMetaFunctionList lst = scope ? scope->functions() : globalFunctions(); QMap<QString, AbstractMetaFunctionList> results; - foreach (AbstractMetaFunction* func, lst) { + for (AbstractMetaFunction *func : qAsConst(lst)) { if (isGroupable(func)) results[func->name()].append(func); } @@ -2367,7 +2414,7 @@ AbstractMetaFunctionList ShibokenGenerator::getFunctionOverloads(const AbstractM AbstractMetaFunctionList results; QSet<QString> seenSignatures; - foreach (AbstractMetaFunction* func, lst) { + for (AbstractMetaFunction *func : qAsConst(lst)) { if (func->name() != functionName) continue; if (isGroupable(func)) { @@ -2384,9 +2431,10 @@ QPair< int, int > ShibokenGenerator::getMinMaxArguments(const AbstractMetaFuncti int minArgs = std::numeric_limits<int>::max(); int maxArgs = 0; - foreach (const AbstractMetaFunction* func, overloads) { + for (const AbstractMetaFunction* func : qAsConst(overloads)) { int numArgs = 0; - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (!func->argumentRemoved(arg->argumentIndex() + 1)) numArgs++; } @@ -2416,7 +2464,7 @@ QMap<QString, QString> ShibokenGenerator::options() const static void getCode(QStringList& code, const CodeSnipList& codeSnips) { - foreach (const CodeSnip& snip, codeSnips) + for (const CodeSnip &snip : qAsConst(codeSnips)) code.append(snip.code()); } @@ -2435,7 +2483,7 @@ static void getCode(QStringList& code, const TypeEntry* type) if (toCppConversions.isEmpty()) return; - foreach (CustomConversion::TargetToNativeConversion* toNative, toCppConversions) + for (CustomConversion::TargetToNativeConversion *toNative : qAsConst(toCppConversions)) code.append(toNative->conversion()); } @@ -2450,20 +2498,23 @@ bool ShibokenGenerator::doSetup(const QMap<QString, QString>& args) TypeDatabase* td = TypeDatabase::instance(); QStringList snips; - foreach (const PrimitiveTypeEntry* type, primitiveTypes()) + const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes(); + for (const PrimitiveTypeEntry *type : primitiveTypeList) getCode(snips, type); - foreach (const ContainerTypeEntry* type, containerTypes()) + const ContainerTypeEntryList &containerTypeList = containerTypes(); + for (const ContainerTypeEntry *type : containerTypeList) getCode(snips, type); - foreach (const AbstractMetaClass* metaClass, classes()) + const AbstractMetaClassList &classList = classes(); + for (const AbstractMetaClass *metaClass : classList) getCode(snips, metaClass->typeEntry()); getCode(snips, td->findType(packageName())); const FunctionGroupMap &functionGroups = getFunctionGroups(); for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { - foreach (AbstractMetaFunction* func, it.value()) + for (AbstractMetaFunction *func : it.value()) getCode(snips, func->injectedCodeSnips()); } - foreach (const QString& code, snips) { + for (const QString &code : qAsConst(snips)) { collectContainerTypesFromConverterMacros(code, true); collectContainerTypesFromConverterMacros(code, false); } @@ -2533,7 +2584,8 @@ QString ShibokenGenerator::convertersVariableName(const QString& moduleName) con static QString processInstantiationsVariableName(const AbstractMetaType* type) { QString res = QLatin1Char('_') + _fixedCppTypeName(type->typeEntry()->qualifiedCppName()).toUpper(); - foreach (const AbstractMetaType* instantiation, type->instantiations()) { + const AbstractMetaTypeList &instantiations = type->instantiations(); + for (const AbstractMetaType *instantiation : instantiations) { res += instantiation->isContainer() ? processInstantiationsVariableName(instantiation) : QLatin1Char('_') + _fixedCppTypeName(instantiation->cppSignature()).toUpper(); @@ -2548,7 +2600,8 @@ QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClass* met return QString(); QString base = _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper(); QString instantiations; - foreach (const AbstractMetaType* instantiation, metaClass->templateBaseClassInstantiations()) + const AbstractMetaTypeList &templateBaseClassInstantiations = metaClass->templateBaseClassInstantiations(); + for (const AbstractMetaType *instantiation : templateBaseClassInstantiations) instantiations += processInstantiationsVariableName(instantiation); return QString::fromLatin1("SBK_%1%2_IDX").arg(base, instantiations); } @@ -2612,8 +2665,9 @@ QString ShibokenGenerator::getDefaultValue(const AbstractMetaFunction* func, co return arg->defaultValueExpression(); //Check modifications - foreach(FunctionModification m, func->modifications()) { - foreach(ArgumentModification am, m.argument_mods) { + const FunctionModificationList &mods = func->modifications(); + for (const FunctionModification &m : mods) { + for (const ArgumentModification &am : m.argument_mods) { if (am.index == (arg->argumentIndex() + 1)) return am.replacedDefaultExpression; } diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h index 837e7d640..1be56edc8 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h @@ -56,6 +56,8 @@ #include "typesystem.h" +#include <QtCore/QRegularExpression> + class DocParser; class CodeSnip; class OverloadData; @@ -132,7 +134,7 @@ public: void writeArgumentNames(QTextStream &s, const AbstractMetaFunction* func, - Options options = NoOption) const; + Options options = NoOption) const override; /** * Function used to write the fucntion arguments on the class buffer. @@ -143,32 +145,32 @@ public: */ void writeFunctionArguments(QTextStream &s, const AbstractMetaFunction* func, - Options options = NoOption) const; + Options options = NoOption) const override; QString functionReturnType(const AbstractMetaFunction* func, Options options = NoOption) const; /// Utility function for writeCodeSnips. typedef QPair<const AbstractMetaArgument*, QString> ArgumentVarReplacementPair; - typedef QList<ArgumentVarReplacementPair> ArgumentVarReplacementList; + typedef QVector<ArgumentVarReplacementPair> ArgumentVarReplacementList; ArgumentVarReplacementList getArgumentReplacement(const AbstractMetaFunction* func, bool usePyArgs, TypeSystem::Language language, const AbstractMetaArgument* lastArg); /// Write user's custom code snippets at class or module level. void writeCodeSnips(QTextStream& s, - const QList<CodeSnip>& codeSnips, + const QVector<CodeSnip> & codeSnips, TypeSystem::CodeSnipPosition position, TypeSystem::Language language, const AbstractMetaClass* context = 0); /// Write user's custom code snippets at function level. void writeCodeSnips(QTextStream& s, - const QList<CodeSnip>& codeSnips, + const QVector<CodeSnip> & codeSnips, TypeSystem::CodeSnipPosition position, TypeSystem::Language language, const AbstractMetaFunction* func, const AbstractMetaArgument* lastArg = 0); /// Returns a string with the user's custom code snippets that comply with \p position and \p language. - QString getCodeSnippets(const QList<CodeSnip>& codeSnips, TypeSystem::CodeSnipPosition position, TypeSystem::Language language); + QString getCodeSnippets(const QVector<CodeSnip> & codeSnips, TypeSystem::CodeSnipPosition position, TypeSystem::Language language); /// Replaces variables for the user's custom code at global or class level. void processCodeSnip(QString& code, const AbstractMetaClass* context = 0); @@ -427,7 +429,7 @@ public: QString extendedIsConvertibleFunctionName(const TypeEntry* targetType) const; QString extendedToCppFunctionName(const TypeEntry* targetType) const; - QMap< QString, QString > options() const; + QMap< QString, QString > options() const override; /// Returns true if the user enabled the so called "parent constructor heuristic". bool useCtorHeuristic() const; @@ -512,12 +514,12 @@ protected: // All data about extended converters: the type entries of the target type, and a // list of AbstractMetaClasses accepted as argument for the conversion. - typedef QHash<const TypeEntry*, QList<const AbstractMetaClass*> > ExtendedConverterData; + typedef QHash<const TypeEntry *, QVector<const AbstractMetaClass *> > ExtendedConverterData; /// Returns all extended conversions for the current module. ExtendedConverterData getExtendedConverters() const; /// Returns a list of converters for the non wrapper types of the current module. - QList<const CustomConversion*> getPrimitiveCustomConversions(); + QVector<const CustomConversion *> getPrimitiveCustomConversions(); /// Returns true if the Python wrapper for the received OverloadData must accept a list of arguments. static bool pythonFunctionWrapperUsesListOfArguments(const OverloadData& overloadData); @@ -548,7 +550,7 @@ private: /// Type system converter variable replacement names and regular expressions. QString m_typeSystemConvName[TypeSystemConverterVariables]; - QRegExp m_typeSystemConvRegEx[TypeSystemConverterVariables]; + QRegularExpression m_typeSystemConvRegEx[TypeSystemConverterVariables]; }; #endif // SHIBOKENGENERATOR_H diff --git a/sources/shiboken2/libshiboken/CMakeLists.txt b/sources/shiboken2/libshiboken/CMakeLists.txt index 9ec49d5bd..e2e5eb427 100644 --- a/sources/shiboken2/libshiboken/CMakeLists.txt +++ b/sources/shiboken2/libshiboken/CMakeLists.txt @@ -10,14 +10,6 @@ endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sbkversion.h.in" "${CMAKE_CURRENT_BINARY_DIR}/sbkversion.h" @ONLY) -#Find installed sparsehash -find_path(SPARSEHASH_INCLUDE_PATH sparseconfig.h PATH_SUFFIXES "/google/sparsehash") -if(SPARSEHASH_INCLUDE_PATH) - message(STATUS "Using system hash found in: ${SPARSEHASH_INCLUDE_PATH}") -else() - set(SPARSEHASH_INCLUDE_PATH ${CMAKE_SOURCE_DIR}/ext/sparsehash) -endif() - set(libshiboken_MAJOR_VERSION ${shiboken_MAJOR_VERSION}) set(libshiboken_MINOR_VERSION ${shiboken_MINOR_VERSION}) set(libshiboken_MICRO_VERSION ${shiboken_MICRO_VERSION}) @@ -41,13 +33,13 @@ shibokenbuffer.cpp include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} - ${SBK_PYTHON_INCLUDE_DIR} - ${SPARSEHASH_INCLUDE_PATH}) + ${SBK_PYTHON_INCLUDE_DIR}) add_library(libshiboken SHARED ${libshiboken_SRC}) target_link_libraries(libshiboken ${SBK_PYTHON_LIBRARIES}) set_target_properties(libshiboken PROPERTIES OUTPUT_NAME "shiboken2${shiboken2_SUFFIX}${PYTHON_EXTENSION_SUFFIX}" VERSION ${libshiboken_VERSION} SOVERSION ${libshiboken_SOVERSION} + CXX_STANDARD 11 DEFINE_SYMBOL LIBSHIBOKEN_EXPORTS) install(FILES diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp index b3f99a8a5..5ecda1eaf 100644 --- a/sources/shiboken2/libshiboken/basewrapper.cpp +++ b/sources/shiboken2/libshiboken/basewrapper.cpp @@ -505,7 +505,6 @@ void DeallocVisitor::done() DtorCallerVisitor::done(); } -namespace Module { void init(); } namespace Conversions { void init(); } void init() @@ -514,7 +513,6 @@ void init() if (shibokenAlreadInitialised) return; - Module::init(); Conversions::init(); initTypeResolver(); diff --git a/sources/shiboken2/libshiboken/bindingmanager.cpp b/sources/shiboken2/libshiboken/bindingmanager.cpp index d7e122cd7..3308ef972 100644 --- a/sources/shiboken2/libshiboken/bindingmanager.cpp +++ b/sources/shiboken2/libshiboken/bindingmanager.cpp @@ -40,7 +40,6 @@ #include "basewrapper.h" #include "basewrapper_p.h" #include "bindingmanager.h" -#include "google/dense_hash_map" #include "sbkdbg.h" #include "gilstate.h" #include "sbkstring.h" @@ -48,23 +47,23 @@ #include <cstddef> #include <fstream> +#include <unordered_map> namespace Shiboken { -typedef google::dense_hash_map<const void*, SbkObject*> WrapperMap; +typedef std::unordered_map<const void *, SbkObject *> WrapperMap; class Graph { public: typedef std::list<SbkObjectType*> NodeList; - typedef google::dense_hash_map<SbkObjectType*, NodeList> Edges; + typedef std::unordered_map<SbkObjectType *, NodeList> Edges; Edges m_edges; Graph() { - m_edges.set_empty_key(0); } void addEdge(SbkObjectType* from, SbkObjectType* to) @@ -172,8 +171,6 @@ void BindingManager::BindingManagerPrivate::assignWrapper(SbkObject* wrapper, co BindingManager::BindingManager() { m_d = new BindingManager::BindingManagerPrivate; - m_d->wrapperMapper.set_empty_key((WrapperMap::key_type)0); - m_d->wrapperMapper.set_deleted_key((WrapperMap::key_type)1); #ifdef SHIBOKEN_INSTALL_FREE_DEBUG_HOOK debugInstallFreeHook(); diff --git a/sources/shiboken2/libshiboken/sbkconverter.cpp b/sources/shiboken2/libshiboken/sbkconverter.cpp index e7e9995b4..b22b33705 100644 --- a/sources/shiboken2/libshiboken/sbkconverter.cpp +++ b/sources/shiboken2/libshiboken/sbkconverter.cpp @@ -40,14 +40,15 @@ #include "sbkconverter.h" #include "sbkconverter_p.h" #include "basewrapper_p.h" -#include "google/dense_hash_map" #include "autodecref.h" #include "sbkdbg.h" #include "helper.h" +#include <unordered_map> + static SbkConverter** PrimitiveTypeConverters; -typedef google::dense_hash_map<std::string, SbkConverter*> ConvertersMap; +typedef std::unordered_map<std::string, SbkConverter *> ConvertersMap; static ConvertersMap converters; namespace Shiboken { @@ -77,8 +78,6 @@ void init() PrimitiveTypeConverters = primitiveTypeConverters; assert(converters.empty()); - converters.set_empty_key(""); - converters.set_deleted_key("?"); converters["PY_LONG_LONG"] = primitiveTypeConverters[SBK_PY_LONG_LONG_IDX]; converters["bool"] = primitiveTypeConverters[SBK_BOOL_IDX_1]; converters["char"] = primitiveTypeConverters[SBK_CHAR_IDX]; diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp index 009d9ab2f..0902077ed 100644 --- a/sources/shiboken2/libshiboken/sbkenum.cpp +++ b/sources/shiboken2/libshiboken/sbkenum.cpp @@ -487,12 +487,7 @@ bool createGlobalEnumItem(PyTypeObject* enumType, PyObject* module, const char* if (enumItem) { if (PyModule_AddObject(module, itemName, enumItem) < 0) return false; - // @TODO This Py_DECREF causes crashes on exit with a debug Python interpreter, essentially - // causing a use-after-free in the GC. This is now commented out to cause a memory leak - // instead of a crash. Proper memory management of Enum types and items should be - // implemented. See PYSIDE-488. This will require proper allocation and deallocation of - // the underlying Enum PyHeapType, which is currently just deallocated at application exit. - // Py_DECREF(enumItem); + Py_DECREF(enumItem); return true; } return false; diff --git a/sources/shiboken2/libshiboken/sbkmodule.cpp b/sources/shiboken2/libshiboken/sbkmodule.cpp index 084e23efa..2ea9d56ac 100644 --- a/sources/shiboken2/libshiboken/sbkmodule.cpp +++ b/sources/shiboken2/libshiboken/sbkmodule.cpp @@ -40,17 +40,13 @@ #include "sbkmodule.h" #include "basewrapper.h" #include "bindingmanager.h" - -// TODO: for performance reasons this should be a sparse_hash_map, -// because there'll be very few modules as keys. The sparse_hash_map -// is missing from the code added in ../ext/sparsehash/google directory. -#include "google/dense_hash_map" +#include <unordered_map> /// This hash maps module objects to arrays of Python types. -typedef google::dense_hash_map<PyObject*, PyTypeObject**> ModuleTypesMap; +typedef std::unordered_map<PyObject *, PyTypeObject **> ModuleTypesMap; /// This hash maps module objects to arrays of converters. -typedef google::dense_hash_map<PyObject*, SbkConverter**> ModuleConvertersMap; +typedef std::unordered_map<PyObject *, SbkConverter **> ModuleConvertersMap; /// All types produced in imported modules are mapped here. static ModuleTypesMap moduleTypes; @@ -61,15 +57,6 @@ namespace Shiboken namespace Module { -void init() -{ - // Initializes type registry for modules. - moduleTypes.set_empty_key((ModuleTypesMap::key_type)0); - moduleTypes.set_deleted_key((ModuleTypesMap::key_type)1); - moduleConverters.set_empty_key((ModuleConvertersMap::key_type)0); - moduleConverters.set_deleted_key((ModuleConvertersMap::key_type)1); -} - PyObject* import(const char* moduleName) { PyObject* sysModules = PyImport_GetModuleDict(); diff --git a/sources/shiboken2/libshiboken/typeresolver.cpp b/sources/shiboken2/libshiboken/typeresolver.cpp index 3939fff5f..b23eb6371 100644 --- a/sources/shiboken2/libshiboken/typeresolver.cpp +++ b/sources/shiboken2/libshiboken/typeresolver.cpp @@ -38,15 +38,15 @@ ****************************************************************************/ #include "typeresolver.h" -#include "google/dense_hash_map" #include "sbkdbg.h" #include <cstdlib> #include <string> +#include <unordered_map> #include "basewrapper_p.h" using namespace Shiboken; -typedef google::dense_hash_map<std::string, TypeResolver*> TypeResolverMap; +typedef std::unordered_map<std::string, TypeResolver *> TypeResolverMap; static TypeResolverMap typeResolverMap; struct TypeResolver::TypeResolverPrivate @@ -66,8 +66,6 @@ static void deinitTypeResolver() void Shiboken::initTypeResolver() { assert(typeResolverMap.empty()); - typeResolverMap.set_empty_key(""); - typeResolverMap.set_deleted_key("?"); std::atexit(deinitTypeResolver); } diff --git a/sources/shiboken2/tests/dumpcodemodel/main.cpp b/sources/shiboken2/tests/dumpcodemodel/main.cpp index 9e62faa16..13dab6e8a 100644 --- a/sources/shiboken2/tests/dumpcodemodel/main.cpp +++ b/sources/shiboken2/tests/dumpcodemodel/main.cpp @@ -37,6 +37,8 @@ #include <QtCore/QFile> #include <iostream> +#include <algorithm> +#include <iterator> int main(int argc, char **argv) { @@ -53,22 +55,19 @@ int main(int argc, char **argv) parser.addPositionalArgument(QStringLiteral("file"), QStringLiteral("C++ source file")); parser.process(app); - if (parser.positionalArguments().isEmpty()) + const QStringList &positionalArguments = parser.positionalArguments(); + if (positionalArguments.isEmpty()) parser.showHelp(1); - const QString sourceFileName = parser.positionalArguments().at(0); - QFile sourceFile(sourceFileName); - if (!sourceFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - QString message = QLatin1String("Cannot open \"") + QDir::toNativeSeparators(sourceFileName) - + QLatin1String("\": ") + sourceFile.errorString(); + QByteArrayList arguments; + std::transform(positionalArguments.cbegin(), positionalArguments.cend(), + std::back_inserter(arguments), QFile::encodeName); + const FileModelItem dom = AbstractMetaBuilderPrivate::buildDom(arguments, 0); + if (dom.isNull()) { + QString message = QLatin1String("Unable to parse ") + positionalArguments.join(QLatin1Char(' ')); std::cerr << qPrintable(message) << '\n'; - return -1; - } - - const FileModelItem dom = AbstractMetaBuilderPrivate::buildDom(&sourceFile); - sourceFile.close(); - if (dom.isNull()) return -2; + } QString output; { diff --git a/sources/shiboken2/tests/test_generator/dummygenerator.cpp b/sources/shiboken2/tests/test_generator/dummygenerator.cpp index 51d2b33da..40d9fb771 100644 --- a/sources/shiboken2/tests/test_generator/dummygenerator.cpp +++ b/sources/shiboken2/tests/test_generator/dummygenerator.cpp @@ -52,7 +52,8 @@ DummyGenerator::doSetup(const QMap<QString, QString>& args) QFile logFile(args["dump-arguments"]); logFile.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream out(&logFile); - foreach (const QString& key, args.keys()) { + for (QMap<QString, QString>::const_iterator it = args.cbegin(), end = args.cend(); it != end; ++it) { + const QString& key = it.key(); if (key == "arg-1") out << "header-file"; else if (key == "arg-2") |