diff --git a/doc/api/qtcreator-api.qdocconf b/doc/api/qtcreator-api.qdocconf index 9396d1262571fd6bcb7f93b661b63f87e2e3a58f..bd0212e989c370c1647c6cd631fc8bd087103011 100644 --- a/doc/api/qtcreator-api.qdocconf +++ b/doc/api/qtcreator-api.qdocconf @@ -5,6 +5,7 @@ language = Cpp headerdirs = . \ ../../src/libs/aggregation \ + ../../src/libs/cplusplus \ ../../src/libs/extensionsystem \ ../../src/plugins/coreplugin \ ../../src/plugins/find \ @@ -12,6 +13,7 @@ headerdirs = . \ sourcedirs = . \ ../../src/libs/aggregation \ + ../../src/libs/cplusplus \ ../../src/libs/extensionsystem \ ../../src/plugins/coreplugin \ ../../src/plugins/find \ diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index c984e71e42ac3ef6e6d3fbeea96782a5dbaa1f1a..5aca5dc1668083b387b063f62933a6f504921b7b 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.5.3 +# Doxyfile 1.5.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project @@ -14,75 +14,76 @@ # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file that -# follow. The default is UTF-8 which is also the encoding used for all text before -# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into -# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of -# possible encodings. +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. -PROJECT_NAME = QWorkbench +PROJECT_NAME = Qt Creator -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1 +PROJECT_NUMBER = -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = . -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = YES -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, -# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, -# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, -# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, +# Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class " \ @@ -97,496 +98,588 @@ ABBREVIATE_BRIEF = "The $name class " \ an \ the -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the # path to strip. -STRIP_FROM_PATH = +STRIP_FROM_PATH = -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. -SHORT_NAMES = YES +SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) -JAVADOC_AUTOBRIEF = NO +JAVADOC_AUTOBRIEF = YES -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) -QT_AUTOBRIEF = NO +QT_AUTOBRIEF = YES -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. -TAB_SIZE = 8 +TAB_SIZE = 4 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to -# include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. -BUILTIN_STL_SUPPORT = NO +BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES -# If the EXTRACT_STATIC tag is set to YES all static members of a file +# If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO -# If this flag is set to YES, the members of anonymous namespaces will be extracted -# and appear in the documentation as a namespace called 'anonymous_namespace{file}', -# where file will be replaced with the base name of the file that contains the anonymous -# namespace. By default anonymous namespace are hidden. +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. -INTERNAL_DOCS = NO +INTERNAL_DOCS = YES -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the +# Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES -# The ENABLED_SECTIONS tag can be used to enable conditional +# The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. -ENABLED_SECTIONS = +ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command <command> <input-file>, where <command> is the value of -# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file -# provided by doxygen. Whatever the program writes to standard output +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated +# The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text " -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written # to stderr. -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = ../../src -# This tag can be used to specify the character encoding of the source files that -# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default -# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. -# See http://www.gnu.org/software/libiconv for the list of possible encodings. +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. INPUT_ENCODING = UTF-8 -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 -FILE_PATTERNS = *.cpp *.h +FILE_PATTERNS = *.cpp \ + *.h -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = moc_* \ ui_* \ Ui_* -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the output. -# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, -# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = +EXAMPLE_PATH = -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see # the \image command). -IMAGE_PATH = +IMAGE_PATH = -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be # ignored. -INPUT_FILTER = +INPUT_FILTER = -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. -FILTER_PATTERNS = +FILTER_PATTERNS = -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO @@ -595,34 +688,32 @@ FILTER_SOURCE_FILES = NO # configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH -# then you must also enable this option. If you don't then doxygen will produce -# a warning and turn it on anyway +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES -# Setting the INLINE_SOURCES tag to YES will include the body +# Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES @@ -630,239 +721,337 @@ REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. +# link to the source code. +# Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. -VERBATIM_HEADERS = NO +VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a # standard header. -HTML_HEADER = +HTML_HEADER = -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a # standard footer. -HTML_FOOTER = +HTML_FOOTER = -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! -HTML_STYLESHEET = +HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). -GENERATE_HTMLHELP = NO +HTML_DYNAMIC_SECTIONS = YES -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = YES + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Qt Creator API" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = com.qtsoftware.qt-creator -HTML_DYNAMIC_SECTIONS = NO +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be # written to the html output directory. -CHM_FILE = +CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. -HHC_LOCATION = +HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members +# The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = YES + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = ../qch/qt-creator-api.qch + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = com.qtsoftware.qt-creator.1 + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = qt-creator-api + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = qhelpgenerator + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO -# This tag can be used to set the number of enum values (range [1..20]) +# This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to FRAME, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. Other possible values +# for this tag are: HIERARCHIES, which will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list; +# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which +# disables this behavior completely. For backwards compatibility with previous +# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE +# respectively. GENERATE_TREEVIEW = NO -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. -EXTRA_PACKAGES = +EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! -LATEX_HEADER = +LATEX_HEADER = -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO @@ -871,68 +1060,68 @@ LATEX_HIDE_INDICES = NO # configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = -# Set optional variables used in the generation of an rtf document. +# Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man -# The MAN_EXTENSION tag determines the extension that is added to +# The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO @@ -941,33 +1130,33 @@ MAN_LINKS = NO # configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_SCHEMA = +XML_SCHEMA = -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_DTD = +XML_DTD = -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES @@ -976,10 +1165,10 @@ XML_PROGRAMLISTING = YES # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO @@ -988,319 +1177,347 @@ GENERATE_AUTOGEN_DEF = NO # configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- -# Configuration options related to the preprocessor +# Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by # the preprocessor. -INCLUDE_PATH = +INCLUDE_PATH = -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- -# Configuration::additions related to external references +# Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen +# If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = -# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. -GENERATE_TAGFILE = +GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES -# The PERL_PATH should be the absolute path and name of the perl script +# The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to -# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to -# specify the directory where the mscgen tool resides. If left empty the tool is assumed to -# be found in the default search path. +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. -MSCGEN_PATH = +MSCGEN_PATH = -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = NO -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = YES -# If set to YES, the inheritance and collaboration graphs will show the +# If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = NO -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = NO -# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. CALL_GRAPH = NO -# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will -# generate a caller dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png -# The tag DOT_PATH can be used to specify the path where the dot tool can be +# The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. -DOT_PATH = +DOT_PATH = -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the # \dotfile command). -DOTFILE_DIRS = +DOTFILE_DIRS = -# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the number -# of direct children of the root node in a graph is already larger than -# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 1000 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = YES -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- -# Configuration::additions related to the search engine +# Options related to the search engine #--------------------------------------------------------------------------- -# The SEARCHENGINE tag specifies whether or not a search engine should be +# The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = YES diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 9faabe29b13fde6f762878112c520c11bf393753..675cf6edf91a6a95ae683e2084ac0cc3be241c68 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -44,6 +44,11 @@ #include <QtCore/QBitArray> #include <QtCore/QtDebug> +/*! + \namespace CPlusPlus + The namespace for C++ related tools. +*/ + using namespace CPlusPlus; namespace { @@ -101,6 +106,7 @@ private: } // anonymous namespace + Document::Document(const QString &fileName) : _fileName(fileName), _globalNamespace(0), @@ -166,9 +172,10 @@ void Document::appendMacro(const Macro ¯o) } void Document::addMacroUse(const Macro ¯o, unsigned offset, unsigned length, - const QVector<MacroArgumentReference> &actuals) + const QVector<MacroArgumentReference> &actuals, bool inCondition) { MacroUse use(macro, offset, offset + length); + use.setInCondition(inCondition); foreach (const MacroArgumentReference &actual, actuals) { const Block arg(actual.position(), actual.position() + actual.length()); @@ -179,6 +186,60 @@ void Document::addMacroUse(const Macro ¯o, unsigned offset, unsigned length, _macroUses.append(use); } +void Document::addUndefinedMacroUse(const QByteArray &name, unsigned offset) +{ + QByteArray copy(name.data(), name.size()); + UndefinedMacroUse use(copy, offset); + _undefinedMacroUses.append(use); +} + +/*! + \class Document::MacroUse + \brief Represents the usage of a macro in a \l {Document}. + \sa Document::UndefinedMacroUse +*/ + +/*! + \class Document::UndefinedMacroUse + \brief Represents a macro that was looked up, but not found. + + Holds data about the reference to a macro in an \tt{#ifdef} or \tt{#ifndef} + or argument to the \tt{defined} operator inside an \tt{#if} or \tt{#elif} that does + not exist. + + \sa Document::undefinedMacroUses(), Document::MacroUse, Macro +*/ + +/*! + \fn QByteArray Document::UndefinedMacroUse::name() const + + Returns the name of the macro that was not found. +*/ + +/*! + \fn QList<UndefinedMacroUse> Document::undefinedMacroUses() const + + Returns a list of referenced but undefined macros. + + \sa Document::macroUses(), Document::definedMacros(), Macro +*/ + +/*! + \fn QList<MacroUse> Document::macroUses() const + + Returns a list of macros used. + + \sa Document::undefinedMacroUses(), Document::definedMacros(), Macro +*/ + +/*! + \fn QList<Macro> Document::definedMacros() const + + Returns the list of macros defined. + + \sa Document::macroUses(), Document::undefinedMacroUses() +*/ + TranslationUnit *Document::translationUnit() const { return _translationUnit; diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index 7308e04e6007db324fd25ff21135ef7f760cb609..ca15bd1986d761cfa29b215fe6940638b296f2de 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -70,7 +70,8 @@ public: void appendMacro(const Macro ¯o); void addMacroUse(const Macro ¯o, unsigned offset, unsigned length, - const QVector<MacroArgumentReference> &range); + const QVector<MacroArgumentReference> &range, bool inCondition); + void addUndefinedMacroUse(const QByteArray &name, unsigned offset); Control *control() const; TranslationUnit *translationUnit() const; @@ -220,13 +221,15 @@ public: class MacroUse: public Block { Macro _macro; QVector<Block> _arguments; + bool _inCondition; public: inline MacroUse(const Macro ¯o, unsigned begin = 0, unsigned end = 0) : Block(begin, end), - _macro(macro) + _macro(macro), + _inCondition(false) { } const Macro ¯o() const @@ -238,11 +241,37 @@ public: QVector<Block> arguments() const { return _arguments; } + bool isInCondition() const + { return _inCondition; } + + private: void setArguments(const QVector<Block> &arguments) { _arguments = arguments; } void addArgument(const Block &block) { _arguments.append(block); } + + void setInCondition(bool set) + { _inCondition = set; } + + friend class Document; + }; + + class UndefinedMacroUse: public Block { + QByteArray _name; + + public: + inline UndefinedMacroUse( + const QByteArray &name, + unsigned begin = 0) + : Block(begin, begin + name.length()), + _name(name) + { } + + QByteArray name() const + { + return _name; + } }; QList<Include> includes() const @@ -254,6 +283,9 @@ public: QList<MacroUse> macroUses() const { return _macroUses; } + QList<UndefinedMacroUse> undefinedMacroUses() const + { return _undefinedMacroUses; } + private: Symbol *findSymbolAt(unsigned line, unsigned column, Scope *scope) const; @@ -267,6 +299,7 @@ private: QList<Macro> _definedMacros; QList<Block> _skippedBlocks; QList<MacroUse> _macroUses; + QList<UndefinedMacroUse> _undefinedMacroUses; QByteArray _source; unsigned _revision; diff --git a/src/libs/cplusplus/FastPreprocessor.h b/src/libs/cplusplus/FastPreprocessor.h index 0d82d54253f69175a6126de19abf227fef5c73f6..36f3685fc13915d42b742f4a6240336050680fd0 100644 --- a/src/libs/cplusplus/FastPreprocessor.h +++ b/src/libs/cplusplus/FastPreprocessor.h @@ -58,9 +58,13 @@ public: virtual void macroAdded(const Macro &) {} + virtual void passedMacroDefinitionCheck(unsigned, const Macro &) {} + virtual void failedMacroDefinitionCheck(unsigned, const QByteArray &) {} + virtual void startExpandingMacro(unsigned, const Macro &, const QByteArray &, + bool, const QVector<MacroArgumentReference> &) {} virtual void stopExpandingMacro(unsigned, const Macro &) {} diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 6bf59fb44a2b31febb2a297c17ccbe9ddef37ed6..f0bbb4ffca806afc579076cfc8028c6540cfd5de 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -467,7 +467,7 @@ void LookupContext::expandFunction(Function *function, } void LookupContext::expandObjCMethod(ObjCMethod *method, - const QList<Scope *> &visibleScopes, + const QList<Scope *> &, QList<Scope *> *expandedScopes) const { if (! expandedScopes->contains(method->arguments())) @@ -495,3 +495,51 @@ void LookupContext::expand(Scope *scope, expandObjCMethod(meth, visibleScopes, expandedScopes); } } + +Symbol *LookupContext::canonicalSymbol(Symbol *symbol) +{ + Symbol *canonical = symbol; + for (; symbol; symbol = symbol->next()) { + if (symbol->name() == canonical->name()) + canonical = symbol; + } + return canonical; +} + +Symbol *LookupContext::canonicalSymbol(const QList<Symbol *> &candidates) +{ + if (candidates.isEmpty()) + return 0; + + Symbol *candidate = candidates.first(); + if (candidate->scope()->isClassScope() && candidate->type()->isFunctionType()) { + Function *function = 0; + + for (int i = 0; i < candidates.size(); ++i) { + Symbol *c = candidates.at(i); + + if (! c->scope()->isClassScope()) + continue; + + else if (Function *f = c->type()->asFunctionType()) { + if (f->isVirtual()) + function = f; + } + } + + if (function) + return canonicalSymbol(function); + } + + return canonicalSymbol(candidate); +} + +Symbol *LookupContext::canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &results) +{ + QList<Symbol *> candidates; + QPair<FullySpecifiedType, Symbol *> result; + foreach (result, results) { + candidates.append(result.second); // ### not exacly. + } + return canonicalSymbol(candidates); +} diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index d648fa71a781c61c46101d7e91905c5281bce676..bb5b053926898de5e618b3d46c89eec60e6cff13 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -54,6 +54,10 @@ public: Document::Ptr document(const QString &fileName) const; Snapshot snapshot() const; + static Symbol *canonicalSymbol(Symbol *symbol); + static Symbol *canonicalSymbol(const QList<Symbol *> &candidates); + static Symbol *canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &candidates); // ### FIXME + QList<Symbol *> resolve(Name *name) const { return resolve(name, visibleScopes()); } diff --git a/src/libs/cplusplus/PreprocessorClient.cpp b/src/libs/cplusplus/PreprocessorClient.cpp index 6fe1b2a75b9eadf00c2e5fbc5e89ca24c44e4b0b..5b57baa7b2eb0a65863f5f70d42ab86983b73ba9 100644 --- a/src/libs/cplusplus/PreprocessorClient.cpp +++ b/src/libs/cplusplus/PreprocessorClient.cpp @@ -31,6 +31,44 @@ using namespace CPlusPlus; +/*! + \class Client + \brief A notification interface for for C++ preprocessor. +*/ + +/*! + \fn void Client::macroAdded(const Macro ¯o) + + Called whenever a new macro is defined. +*/ + +/*! + \fn void Client::passedMacroDefinitionCheck(unsigned offset, const Macro ¯o) + + Called when the preprocessor checks whether a macro is defined or not and the + result is positive. + + \sa failedMacroDefinitionCheck() +*/ + +/*! + \fn void Client::failedMacroDefinitionCheck(unsigned offset, const QByteArray &name) + + Called when the preprocessor checks whether a macro is defined or not and the + result is negative. + + \sa passedMacroDefinitionCheck() +*/ + +/*! + \fn void Client::startExpandingMacro(unsigned offset, const Macro ¯o, const QByteArray &originalText, bool inCondition = false, const QVector<MacroArgumentReference> &actuals = QVector<MacroArgumentReference>()) + + Called when starting to expand a macro. The parameter \a inCondition indicates whether the + expansion is happening inside a preprocessor conditional. + + \sa stopExpandingMacro() +*/ + Client::Client() { } diff --git a/src/libs/cplusplus/PreprocessorClient.h b/src/libs/cplusplus/PreprocessorClient.h index 84cb0b73ac372c0d980f8ab4eeee512d5d74aa21..d89ce71355d6bd17152c152d293a555b0d8fa562 100644 --- a/src/libs/cplusplus/PreprocessorClient.h +++ b/src/libs/cplusplus/PreprocessorClient.h @@ -75,12 +75,14 @@ public: virtual ~Client(); virtual void macroAdded(const Macro ¯o) = 0; - virtual void sourceNeeded(QString &fileName, IncludeType mode, - unsigned line) = 0; // ### FIX the signature. + + virtual void passedMacroDefinitionCheck(unsigned offset, const Macro ¯o) = 0; + virtual void failedMacroDefinitionCheck(unsigned offset, const QByteArray &name) = 0; virtual void startExpandingMacro(unsigned offset, const Macro ¯o, const QByteArray &originalText, + bool inCondition = false, const QVector<MacroArgumentReference> &actuals = QVector<MacroArgumentReference>()) = 0; @@ -89,6 +91,9 @@ public: virtual void startSkippingBlocks(unsigned offset) = 0; virtual void stopSkippingBlocks(unsigned offset) = 0; + + virtual void sourceNeeded(QString &fileName, IncludeType mode, + unsigned line) = 0; // ### FIX the signature. }; } // namespace CPlusPlus diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index 347f4999d26d2eb2e8d1bf62138552ec802ff726..dcb6d4932223f7df5b1adb2da49583e1a2932e9b 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -138,6 +138,18 @@ using namespace CPlusPlus; namespace { +bool isMacroDefined(QByteArray name, unsigned offset, Environment *env, Client *client) +{ + Macro *m = env->resolve(name); + if (client) { + if (m) + client->passedMacroDefinitionCheck(offset, *m); + else + client->failedMacroDefinitionCheck(offset, name); + } + return m != 0; +} + class RangeLexer { const Token *first; @@ -193,8 +205,8 @@ class ExpressionEvaluator void operator = (const ExpressionEvaluator &other); public: - ExpressionEvaluator(Environment *env) - : env(env), _lex(0) + ExpressionEvaluator(Client *client, Environment *env) + : client(client), env(env), _lex(0) { } Value operator()(const Token *firstToken, const Token *lastToken, @@ -255,13 +267,13 @@ protected: } else if (isTokenDefined()) { ++(*_lex); if ((*_lex)->is(T_IDENTIFIER)) { - _value.set_long(env->resolve(tokenSpell()) != 0); + _value.set_long(isMacroDefined(tokenSpell(), (*_lex)->offset, env, client)); ++(*_lex); return true; } else if ((*_lex)->is(T_LPAREN)) { ++(*_lex); if ((*_lex)->is(T_IDENTIFIER)) { - _value.set_long(env->resolve(tokenSpell()) != 0); + _value.set_long(isMacroDefined(tokenSpell(), (*_lex)->offset, env, client)); ++(*_lex); if ((*_lex)->is(T_RPAREN)) { ++(*_lex); @@ -519,6 +531,7 @@ protected: } private: + Client *client; Environment *env; QByteArray source; RangeLexer *_lex; @@ -983,7 +996,7 @@ void Preprocessor::expandObjectLikeMacro(TokenIterator identifierToken, { if (client) client->startExpandingMacro(identifierToken->offset, - *m, spell); + *m, spell, false); m->setHidden(true); expand(m->definition(), result); @@ -1007,7 +1020,7 @@ void Preprocessor::expandFunctionLikeMacro(TokenIterator identifierToken, endOfText - beginOfText); client->startExpandingMacro(identifierToken->offset, - *m, text, actuals); + *m, text, false, actuals); } const bool was = markGeneratedTokens(true, identifierToken); @@ -1253,7 +1266,7 @@ void Preprocessor::processIf(TokenIterator firstToken, TokenIterator lastToken) const char *first = startOfToken(*tk); const char *last = startOfToken(*lastToken); - MacroExpander expandCondition (env); + MacroExpander expandCondition (env, 0, client, tk.dot()->offset); QByteArray condition; condition.reserve(256); expandCondition(first, last, &condition); @@ -1297,7 +1310,7 @@ void Preprocessor::processElif(TokenIterator firstToken, TokenIterator lastToken const char *first = startOfToken(*tk); const char *last = startOfToken(*lastToken); - MacroExpander expandCondition (env); + MacroExpander expandCondition (env, 0, client, tk.dot()->offset); QByteArray condition; condition.reserve(256); expandCondition(first, last, &condition); @@ -1338,7 +1351,7 @@ void Preprocessor::processIfdef(bool checkUndefined, if (testIfLevel()) { if (tk->is(T_IDENTIFIER)) { const QByteArray macroName = tokenSpell(*tk); - bool value = env->resolve(macroName) != 0 || env->isBuiltinMacro(macroName); + bool value = isMacroDefined(macroName, tk->offset, env, client) || env->isBuiltinMacro(macroName); if (checkUndefined) value = ! value; @@ -1437,7 +1450,7 @@ int Preprocessor::skipping() const Value Preprocessor::evalExpression(TokenIterator firstToken, TokenIterator lastToken, const QByteArray &source) const { - ExpressionEvaluator eval(env); + ExpressionEvaluator eval(client, env); const Value result = eval(firstToken, lastToken, source); return result; } diff --git a/src/libs/cplusplus/pp-macro-expander.cpp b/src/libs/cplusplus/pp-macro-expander.cpp index 4902158c761e00afc10c28f93a4a5e391e1538b6..42be634562d445eafebffe413820cd8c969d2300 100644 --- a/src/libs/cplusplus/pp-macro-expander.cpp +++ b/src/libs/cplusplus/pp-macro-expander.cpp @@ -66,9 +66,11 @@ inline static bool comment_p (const char *__first, const char *__last) return (*__first == '/' || *__first == '*'); } -MacroExpander::MacroExpander(Environment *env, pp_frame *frame) +MacroExpander::MacroExpander(Environment *env, pp_frame *frame, Client *client, unsigned start_offset) : env(env), frame(frame), + client(client), + start_offset(start_offset), lines(0) { } @@ -97,6 +99,7 @@ const char *MacroExpander::operator()(const char *first, const char *last, const char *MacroExpander::expand(const char *__first, const char *__last, QByteArray *__result) { + const char *start = __first; __first = skip_blanks (__first, __last); lines = skip_blanks.lines; @@ -284,6 +287,9 @@ const char *MacroExpander::expand(const char *__first, const char *__last, if (! macro->definition().isEmpty()) { + if (client) + client->startExpandingMacro(start_offset + (name_begin-start), *macro, fast_name, true); + macro->setHidden(true); QByteArray __tmp; @@ -310,6 +316,9 @@ const char *MacroExpander::expand(const char *__first, const char *__last, } macro->setHidden(false); + + if (client) + client->stopExpandingMacro(start_offset + (name_begin-start), *macro); } if (! m) @@ -330,6 +339,7 @@ const char *MacroExpander::expand(const char *__first, const char *__last, } QVector<QByteArray> actuals; + QVector<MacroArgumentReference> actuals_ref; actuals.reserve (5); ++arg_it; // skip '(' @@ -338,6 +348,7 @@ const char *MacroExpander::expand(const char *__first, const char *__last, const char *arg_end = skip_argument_variadics (actuals, macro, arg_it, __last); if (arg_it != arg_end) { + actuals_ref.append(MacroArgumentReference(start_offset + (arg_it-start), arg_end - arg_it)); const QByteArray actual (arg_it, arg_end - arg_it); QByteArray expanded; expand_actual (actual.constBegin (), actual.constEnd (), &expanded); @@ -350,6 +361,7 @@ const char *MacroExpander::expand(const char *__first, const char *__last, ++arg_it; // skip ',' arg_end = skip_argument_variadics (actuals, macro, arg_it, __last); + actuals_ref.append(MacroArgumentReference(start_offset + (arg_it-start), arg_end - arg_it)); const QByteArray actual (arg_it, arg_end - arg_it); QByteArray expanded; expand_actual (actual.constBegin (), actual.constEnd (), &expanded); @@ -363,11 +375,17 @@ const char *MacroExpander::expand(const char *__first, const char *__last, ++arg_it; // skip ')' __first = arg_it; + if (client) + client->startExpandingMacro(start_offset + (name_begin-start), *macro, fast_name, true, actuals_ref); + pp_frame frame (macro, actuals); MacroExpander expand_macro (env, &frame); macro->setHidden(true); expand_macro (macro->definition(), __result); macro->setHidden(false); + + if (client) + client->stopExpandingMacro(start_offset + (name_begin-start), *macro); } else __result->append(*__first++); diff --git a/src/libs/cplusplus/pp-macro-expander.h b/src/libs/cplusplus/pp-macro-expander.h index f566ca809bb0488d4ffc109a165b094fc8a1c5a2..4f8730d2db8e92f0a5cd90a322bdbd6129774c8a 100644 --- a/src/libs/cplusplus/pp-macro-expander.h +++ b/src/libs/cplusplus/pp-macro-expander.h @@ -56,6 +56,7 @@ namespace CPlusPlus { class Environment; +class Client; struct pp_frame; @@ -63,6 +64,8 @@ class MacroExpander { Environment *env; pp_frame *frame; + Client *client; + unsigned start_offset; pp_skip_number skip_number; pp_skip_identifier skip_identifier; @@ -76,7 +79,7 @@ class MacroExpander const QByteArray *resolve_formal(const QByteArray &name); public: - MacroExpander(Environment *env, pp_frame *frame = 0); + MacroExpander(Environment *env, pp_frame *frame = 0, Client *client = 0, unsigned start_offset = 0); const char *operator()(const char *first, const char *last, QByteArray *result); diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index 3862e1440f873c1480efe1c629c5581eafa08f24..fdd9b62b0d549abf8c5845010340c081323d2ca8 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -205,17 +205,17 @@ public slots: bool closeAllEditors(bool askAboutModifiedEditors = true); void openInExternalEditor(); -private slots: bool saveFile(Core::IEditor *editor = 0); bool saveFileAs(Core::IEditor *editor = 0); + void revertToSaved(); void closeEditor(); void closeOtherEditors(); +private slots: void gotoNextDocHistory(); void gotoPreviousDocHistory(); void handleContextChange(Core::IContext *context); void updateActions(); - void revertToSaved(); void makeCurrentEditorWritable(); public slots: diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 4015bf6fc062caffdd41f8173dc9e2eceb78765c..e16c9008feddd36b0e4ce4e474aa69be9197a98f 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -857,22 +857,9 @@ void CPPEditor::findReferences() lastVisibleSymbol, TypeOfExpression::Preprocess); - if (! results.isEmpty()) { - TypeOfExpression::Result result = results.first(); - Symbol *symbol = result.second; - qDebug() << "result:" << symbol->fileName() << symbol->line() << symbol->column(); - m_modelManager->findReferences(symbol); + if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(results)) { + m_modelManager->findReferences(canonicalSymbol); } - - -#if 0 - LookupContext context( - Overview oo; - qDebug() << "==============> filename:" << symbol->fileName() - << "name:" << oo(symbol->name()); - m_modelManager->findReferences(symbol); - } -#endif } void CPPEditor::renameSymbolUnderCursor() @@ -1345,6 +1332,39 @@ bool CPPEditor::isElectricCharacter(const QChar &ch) const return false; } + +static void countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen) +{ + if (c == open) + ++*stillopen; + else if (c == close) + --*stillopen; + + if (*stillopen < 0) { + *errors += -1 * (*stillopen); + *stillopen = 0; + } +} + +void countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close, int *errors, int *stillopen) +{ + cursor.setPosition(from); + QTextBlock block = cursor.block(); + while (block.isValid() && block.position() < end) { + TextEditor::Parentheses parenList = TextEditor::TextEditDocumentLayout::parentheses(block); + if (!parenList.isEmpty() && !TextEditor::TextEditDocumentLayout::ifdefedOut(block)) { + for (int i = 0; i < parenList.count(); ++i) { + TextEditor::Parenthesis paren = parenList.at(i); + int position = block.position() + paren.pos; + if (position < from || position >= end) + continue; + countBracket(open, close, paren.chr, errors, stillopen); + } + } + block = block.next(); + } +} + QString CPPEditor::autoComplete(QTextCursor &cursor, const QString &textToInsert) const { const bool checkBlockEnd = m_allowSkippingOfBlockEnd; @@ -1356,6 +1376,33 @@ QString CPPEditor::autoComplete(QTextCursor &cursor, const QString &textToInsert QString text = textToInsert; const QChar lookAhead = characterAt(cursor.selectionEnd()); + QChar character = textToInsert.at(0); + QString parentheses = QLatin1String("()"); + QString brackets = QLatin1String("[]"); + if (parentheses.contains(character) || brackets.contains(character)) { + QTextCursor tmp= cursor; + TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); + int blockStart = tmp.isNull() ? 0 : tmp.position(); + tmp = cursor; + TextEditor::TextBlockUserData::findNextBlockClosingParenthesis(&tmp); + int blockEnd = tmp.isNull() ? (cursor.document()->characterCount()-1) : tmp.position(); + QChar openChar = parentheses.contains(character) ? QLatin1Char('(') : QLatin1Char('['); + QChar closeChar = parentheses.contains(character) ? QLatin1Char(')') : QLatin1Char(']'); + + int errors = 0; + int stillopen = 0; + countBrackets(cursor, blockStart, blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsBeforeInsertion = errors + stillopen; + errors = 0; + stillopen = 0; + countBrackets(cursor, blockStart, cursor.position(), openChar, closeChar, &errors, &stillopen); + countBracket(openChar, closeChar, character, &errors, &stillopen); + countBrackets(cursor, cursor.position(), blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsAfterInsertion = errors + stillopen; + if (errorsAfterInsertion < errorsBeforeInsertion) + return QString(); // insertion fixes parentheses or bracket errors, do not auto complete + } + MatchingText matchingText; int skippedChars = 0; const QString autoText = matchingText.insertMatchingBrace(cursor, text, lookAhead, &skippedChars); @@ -1392,6 +1439,32 @@ bool CPPEditor::autoBackspace(QTextCursor &cursor) QChar lookAhead = characterAt(pos); QChar lookBehind = characterAt(pos-1); QChar lookFurtherBehind = characterAt(pos-2); + + QChar character = lookBehind; + if (character == QLatin1Char('(') || character == QLatin1Char('[')) { + QTextCursor tmp = cursor; + TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); + int blockStart = tmp.isNull() ? 0 : tmp.position(); + tmp = cursor; + TextEditor::TextBlockUserData::findNextBlockClosingParenthesis(&tmp); + int blockEnd = tmp.isNull() ? (cursor.document()->characterCount()-1) : tmp.position(); + QChar openChar = character; + QChar closeChar = (character == QLatin1Char('(')) ? QLatin1Char(')') : QLatin1Char(']'); + + int errors = 0; + int stillopen = 0; + countBrackets(cursor, blockStart, blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsBeforeDeletion = errors + stillopen; + errors = 0; + stillopen = 0; + countBrackets(cursor, blockStart, pos - 1, openChar, closeChar, &errors, &stillopen); + countBrackets(cursor, pos, blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsAfterDeletion = errors + stillopen; + + if (errorsAfterDeletion < errorsBeforeDeletion) + return false; // insertion fixes parentheses or bracket errors, do not auto complete + } + if ((lookBehind == QLatin1Char('(') && lookAhead == QLatin1Char(')')) || (lookBehind == QLatin1Char('[') && lookAhead == QLatin1Char(']')) || (lookBehind == QLatin1Char('"') && lookAhead == QLatin1Char('"') diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp index 03a4701b2102b3a331b0136345a71c80019cbc0e..ed5d82d2796c960400be35cb75197864e5a65f0c 100644 --- a/src/plugins/cppeditor/cpphighlighter.cpp +++ b/src/plugins/cppeditor/cpphighlighter.cpp @@ -52,12 +52,13 @@ void CppHighlighter::highlightBlock(const QString &text) QTextCharFormat emptyFormat; const int previousState = previousBlockState(); - int state = 0, braceDepth = 0; + int state = 0, initialBraceDepth = 0; if (previousState != -1) { state = previousState & 0xff; - braceDepth = previousState >> 8; + initialBraceDepth = previousState >> 8; } + int braceDepth = initialBraceDepth; SimpleLexer tokenize; tokenize.setQtMocRunEnabled(false); @@ -211,6 +212,10 @@ void CppHighlighter::highlightBlock(const QString &text) TextEditDocumentLayout::setParentheses(currentBlock(), parentheses); + // if the block is ifdefed out, we only store the parentheses, but + // do not adjust the brace depth. + if (TextEditDocumentLayout::ifdefedOut(currentBlock())) + braceDepth = initialBraceDepth; // optimization: if only the brace depth changes, we adjust subsequent blocks // to have QSyntaxHighlighter stop the rehighlighting @@ -222,12 +227,7 @@ void CppHighlighter::highlightBlock(const QString &text) int delta = braceDepth - oldBraceDepth; QTextBlock block = currentBlock().next(); while (block.isValid()) { - currentState = block.userState(); - if (currentState != -1) { - oldState = currentState & 0xff; - oldBraceDepth = currentState >> 8; - block.setUserState(((oldBraceDepth + delta) << 8 ) | oldState); - } + TextEditDocumentLayout::changeBraceDepth(block, delta); block = block.next(); } } diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index b0097b206614ee73156b4c1127aa110ce5c6cce7..d56b4e64aa1e18343ba337133ee692ea6af379bb 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -44,10 +44,13 @@ #include <Literals.h> #include <TranslationUnit.h> #include <Symbols.h> +#include <Names.h> +#include <Scope.h> #include <cplusplus/CppDocument.h> #include <cplusplus/ExpressionUnderCursor.h> #include <cplusplus/ResolveExpression.h> +#include <cplusplus/Overview.h> #include <QtCore/QTime> #include <QtCore/QtConcurrentRun> @@ -69,13 +72,16 @@ public: _future(future), _doc(doc), _snapshot(snapshot), - _source(_doc->source()) - { } + _source(_doc->source()), + _sem(doc->control()) + { + _snapshot.insert(_doc); + } - void operator()(Identifier *id, AST *ast) + void operator()(Symbol *symbol, Identifier *id, AST *ast) { + _declSymbol = symbol; _id = id; - _currentSymbol = _doc->globalNamespace(); _exprDoc = Document::create("<references>"); accept(ast); } @@ -122,55 +128,63 @@ protected: line, lineText, col, len)); } - LookupContext currentContext() const - { - return LookupContext(_currentSymbol, _exprDoc, _doc, _snapshot); - } - - virtual bool visit(ClassSpecifierAST *ast) + bool checkCandidates(const QList<Symbol *> &candidates) const { - _currentSymbol = ast->symbol; + // ### FIXME return isDeclSymbol(LookupContext::canonicalSymbol(candidates)); return true; } - virtual bool visit(NamespaceAST *ast) + bool isDeclSymbol(Symbol *symbol) const { - _currentSymbol = ast->symbol; - return true; - } + if (! symbol) + return false; - virtual bool visit(CompoundStatementAST *ast) - { - _currentSymbol = ast->symbol; - return true; + else if (symbol == _declSymbol) + return true; + + else if (symbol->line() == _declSymbol->line() && symbol->column() == _declSymbol->column()) { + if (! qstrcmp(symbol->fileName(), _declSymbol->fileName())) + return true; + } + + return false; } - virtual bool visit(FunctionDefinitionAST *ast) + LookupContext currentContext(AST *ast) const { - _currentSymbol = ast->symbol; - return true; + unsigned line, column; + getTokenStartPosition(ast->firstToken(), &line, &column); + Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); + return LookupContext(lastVisibleSymbol, _exprDoc, _doc, _snapshot); } virtual bool visit(QualifiedNameAST *ast) { - return true; + if (! ast->name) { + //qWarning() << "invalid AST at" << _doc->fileName() << line << column; + ast->name = _sem.check(ast, /*scope */ static_cast<Scope *>(0)); + } + + Q_ASSERT(ast->name != 0); + Identifier *id = ast->name->identifier(); + if (id == _id && ast->unqualified_name) { + LookupContext context = currentContext(ast); + const QList<Symbol *> candidates = context.resolve(ast->name); + if (checkCandidates(candidates)) + reportResult(ast->unqualified_name->firstToken()); + } + + return false; } virtual bool visit(SimpleNameAST *ast) { Identifier *id = identifier(ast->identifier_token); if (id == _id) { -#if 0 - LookupContext context = currentContext(); - ResolveExpression resolveExpression(context); - QList<ResolveExpression::Result> results = resolveExpression(ast); - if (! results.isEmpty()) { - ResolveExpression::Result result = results.first(); - Symbol *resolvedSymbol = result.second; - qDebug() << "resolves to:" << resolvedSymbol->fileName() << resolvedSymbol->line(); - } -#endif - reportResult(ast->identifier_token); + LookupContext context = currentContext(ast); + const QList<Symbol *> candidates = context.resolve(ast->name); + if (checkCandidates(candidates)) + reportResult(ast->identifier_token); } return false; @@ -179,20 +193,25 @@ protected: virtual bool visit(TemplateIdAST *ast) { Identifier *id = identifier(ast->identifier_token); - if (id == _id) - reportResult(ast->identifier_token); + if (id == _id) { + LookupContext context = currentContext(ast); + const QList<Symbol *> candidates = context.resolve(ast->name); + if (checkCandidates(candidates)) + reportResult(ast->identifier_token); + } - return true; + return false; } private: QFutureInterface<Core::Utils::FileSearchResult> &_future; - Identifier *_id; + Identifier *_id; // ### remove me + Symbol *_declSymbol; Document::Ptr _doc; Snapshot _snapshot; QByteArray _source; - Symbol *_currentSymbol; Document::Ptr _exprDoc; + Semantic _sem; }; } // end of anonymous namespace @@ -217,6 +236,9 @@ static void find_helper(QFutureInterface<Core::Utils::FileSearchResult> &future, QTime tm; tm.start(); + Identifier *symbolId = symbol->identifier(); + Q_ASSERT(symbolId != 0); + const QString fileName = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()); QStringList files(fileName); @@ -229,24 +251,30 @@ static void find_helper(QFutureInterface<Core::Utils::FileSearchResult> &future, for (int i = 0; i < files.size(); ++i) { const QString &fn = files.at(i); future.setProgressValueAndText(i, QFileInfo(fn).fileName()); + + Document::Ptr previousDoc = snapshot.value(fn); + if (previousDoc) { + Control *control = previousDoc->control(); + Identifier *id = control->findIdentifier(symbolId->chars(), symbolId->size()); + if (! id) + continue; // skip this document, it's not using symbolId. + } + QFile f(fn); if (! f.open(QFile::ReadOnly)) continue; - const QString source = QTextStream(&f).readAll(); + const QString source = QTextStream(&f).readAll(); // ### FIXME const QByteArray preprocessedCode = snapshot.preprocessedCode(source, fn); Document::Ptr doc = snapshot.documentFromSource(preprocessedCode, fn); doc->tokenize(); - Identifier *symbolId = symbol->identifier(); - Q_ASSERT(symbolId != 0); - Control *control = doc->control(); if (Identifier *id = control->findIdentifier(symbolId->chars(), symbolId->size())) { doc->check(); TranslationUnit *unit = doc->translationUnit(); Process process(future, doc, snapshot); - process(id, unit->ast()); + process(symbol, id, unit->ast()); } } future.setProgressValue(files.size()); @@ -259,9 +287,7 @@ void CppFindReferences::findAll(const Snapshot &snapshot, Symbol *symbol) Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager(); - QFuture<Core::Utils::FileSearchResult> result = - QtConcurrent::run(&find_helper, snapshot, symbol); - + QFuture<Core::Utils::FileSearchResult> result = QtConcurrent::run(&find_helper, snapshot, symbol); m_watcher.setFuture(result); Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."), diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 5d76824ff9b017a9e574a006ac6a5066389a80dd..6a859d16cc7bc04f9991f1f15e2745015e81bb24 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -196,9 +196,12 @@ protected: void mergeEnvironment(CPlusPlus::Document::Ptr doc); virtual void macroAdded(const Macro ¯o); + virtual void passedMacroDefinitionCheck(unsigned offset, const Macro ¯o); + virtual void failedMacroDefinitionCheck(unsigned offset, const QByteArray &name); virtual void startExpandingMacro(unsigned offset, const Macro ¯o, const QByteArray &originalText, + bool inCondition, const QVector<MacroArgumentReference> &actuals); virtual void stopExpandingMacro(unsigned offset, const Macro ¯o); virtual void startSkippingBlocks(unsigned offset); @@ -446,16 +449,34 @@ void CppPreprocessor::macroAdded(const Macro ¯o) m_currentDoc->appendMacro(macro); } +void CppPreprocessor::passedMacroDefinitionCheck(unsigned offset, const Macro ¯o) +{ + if (! m_currentDoc) + return; + + m_currentDoc->addMacroUse(macro, offset, macro.name().length(), + QVector<MacroArgumentReference>(), true); +} + +void CppPreprocessor::failedMacroDefinitionCheck(unsigned offset, const QByteArray &name) +{ + if (! m_currentDoc) + return; + + m_currentDoc->addUndefinedMacroUse(name, offset); +} + void CppPreprocessor::startExpandingMacro(unsigned offset, const Macro ¯o, const QByteArray &originalText, + bool inCondition, const QVector<MacroArgumentReference> &actuals) { if (! m_currentDoc) return; - //qDebug() << "start expanding:" << macro.name << "text:" << originalText; - m_currentDoc->addMacroUse(macro, offset, originalText.length(), actuals); + //qDebug() << "start expanding:" << macro.name() << "text:" << originalText; + m_currentDoc->addMacroUse(macro, offset, originalText.length(), actuals, inCondition); } void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &) diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h index d02800625caccd13ed2dcc4ec5b8b2ab1bd4792e..0e5fbbbfb116dc0919d98390bac04490ad075824 100644 --- a/src/plugins/debugger/breakhandler.h +++ b/src/plugins/debugger/breakhandler.h @@ -36,11 +36,11 @@ #include <QtCore/QAbstractItemModel> namespace Debugger { +class DebuggerManager; namespace Internal { class BreakpointMarker; class BreakHandler; -class DebuggerManager; ////////////////////////////////////////////////////////////////// // diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index 1a0f8424d459517e15738eebfb0be7e61e843ade..2d1915fe03f7237ca89ca0c693effbc791574dc9 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.cpp +++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp @@ -52,6 +52,7 @@ #include <utils/qtcassert.h> #include <utils/winutils.h> #include <utils/consoleprocess.h> +#include <utils/fancymainwindow.h> #include <texteditor/itexteditor.h> #include <QtCore/QDebug> @@ -367,7 +368,7 @@ bool CdbDebugEnginePrivate::init(QString *errorMessage) return true; } -IDebuggerEngine *CdbDebugEngine::create(DebuggerManager *manager, +IDebuggerEngine *CdbDebugEngine::create(Debugger::DebuggerManager *manager, const QSharedPointer<CdbOptions> &options, QString *errorMessage) { diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h index 18b660416520f01f54ffbf6d9cecba4aa65a4733..cbd52105cbde5d14193e453c6defecd04e4e9719 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.h +++ b/src/plugins/debugger/cdb/cdbdebugengine.h @@ -36,9 +36,10 @@ #include <QtCore/QSharedPointer> namespace Debugger { +class DebuggerManager; + namespace Internal { -class DebuggerManager; class DisassemblerViewAgent; class CdbDebugEventCallback; class CdbDebugOutput; diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h index 9cf9f8661b0b3ddb6037ae5ab8218ce014322d56..55c1d9717bc8095213e648d8e0895b8c2336305e 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine_p.h +++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h @@ -42,9 +42,10 @@ #include <QtCore/QMap> namespace Debugger { +class DebuggerManager; + namespace Internal { -class DebuggerManager; class WatchHandler; class CdbStackFrameContext; class CdbStackTraceContext; diff --git a/src/plugins/debugger/cdb/cdbdebugeventcallback.h b/src/plugins/debugger/cdb/cdbdebugeventcallback.h index 81f5226ddadfa59a60059b70fd2225b36da732e7..b9de88e1745650a667a22c2ba794aae4f1f69937 100644 --- a/src/plugins/debugger/cdb/cdbdebugeventcallback.h +++ b/src/plugins/debugger/cdb/cdbdebugeventcallback.h @@ -35,8 +35,10 @@ #include <QtCore/QStringList> namespace Debugger { -namespace Internal { class DebuggerManager; + +namespace Internal { + class CdbDebugEngine; // Base class for event callbacks that takes care diff --git a/src/plugins/debugger/cdb/cdbdumperhelper.h b/src/plugins/debugger/cdb/cdbdumperhelper.h index a1fc4a3be49383ffd20f498a5fcfa4744d5ace74..eaa7a1db7b2b38e39ce7129aa2baf68e43317190 100644 --- a/src/plugins/debugger/cdb/cdbdumperhelper.h +++ b/src/plugins/debugger/cdb/cdbdumperhelper.h @@ -37,10 +37,10 @@ #include <QtCore/QMap> namespace Debugger { -namespace Internal { +class DebuggerManager; +namespace Internal { struct CdbComInterfaces; -class DebuggerManager; /* For code clarity, all the stuff related to custom dumpers goes here. * "Custom dumper" is a library compiled against the current diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index 7b3208dda629737d29371f850af9fe900e1af93c..55d30c36cc3a42324ae0c83661a281b19c3e0d54 100644 --- a/src/plugins/debugger/debugger.pro +++ b/src/plugins/debugger/debugger.pro @@ -4,14 +4,12 @@ TARGET = Debugger # DEFINES += QT_USE_FAST_OPERATOR_PLUS # DEFINES += QT_USE_FAST_CONCATENATION # CONFIG += single + include(../../qtcreatorplugin.pri) -include(../../plugins/coreplugin/coreplugin.pri) -include(../../plugins/cpptools/cpptools.pri) -include(../../plugins/find/find.pri) -include(../../plugins/projectexplorer/projectexplorer.pri) -include(../../plugins/texteditor/texteditor.pri) -include(../../libs/cplusplus/cplusplus.pri) -include(../../libs/utils/utils.pri) +include(debugger_dependencies.pri) + +DEFINES += DEBUGGER_LIBRARY + INCLUDEPATH += $$PWD/../../libs/utils QT += gui \ network \ @@ -23,10 +21,12 @@ HEADERS += breakhandler.h \ debuggerconstants.h \ debuggerdialogs.h \ debuggermanager.h \ + debugger_global.h \ debuggeroutputwindow.h \ debuggerplugin.h \ debuggerrunner.h \ debuggertooltip.h \ + debuggerstringutils.h \ watchutils.h \ idebuggerengine.h \ imports.h \ diff --git a/src/plugins/debugger/debugger_dependencies.pri b/src/plugins/debugger/debugger_dependencies.pri new file mode 100644 index 0000000000000000000000000000000000000000..2701df45bab5a994eafca663a9513b1307dc1721 --- /dev/null +++ b/src/plugins/debugger/debugger_dependencies.pri @@ -0,0 +1,7 @@ +include(../../plugins/coreplugin/coreplugin.pri) +include(../../plugins/cpptools/cpptools.pri) +include(../../plugins/find/find.pri) +include(../../plugins/projectexplorer/projectexplorer.pri) +include(../../plugins/texteditor/texteditor.pri) +include(../../libs/cplusplus/cplusplus.pri) +include(../../libs/utils/utils.pri) diff --git a/src/plugins/debugger/debugger_global.h b/src/plugins/debugger/debugger_global.h new file mode 100644 index 0000000000000000000000000000000000000000..f01fd3aa070619107ad2d848aa10739e45af72fe --- /dev/null +++ b/src/plugins/debugger/debugger_global.h @@ -0,0 +1,41 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef DEBUGGERGLOBAL_H +#define DEBUGGERGLOBAL_H + +#include <QtCore/QtGlobal> + +#if defined(DEBUGGER_LIBRARY) +# define DEBUGGER_EXPORT Q_DECL_EXPORT +#else +# define DEBUGGER_EXPORT Q_DECL_IMPORT +#endif + +#endif // DEBUGGERGLOBAL_H diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h index 07cac69e80bc32423f72ce0935b10444f35a500c..37089b79b7cf7543de681b4e4fec6dacced671ed 100644 --- a/src/plugins/debugger/debuggeractions.h +++ b/src/plugins/debugger/debuggeractions.h @@ -127,6 +127,22 @@ Core::Utils::SavedAction *theDebuggerAction(int code); bool theDebuggerBoolSetting(int code); QString theDebuggerStringSetting(int code); +struct DebuggerManagerActions { + QAction *continueAction; + QAction *stopAction; + QAction *resetAction; // FIXME: Should not be needed in a stable release + QAction *stepAction; + QAction *stepOutAction; + QAction *runToLineAction; + QAction *runToFunctionAction; + QAction *jumpToLineAction; + QAction *nextAction; + QAction *watchAction; + QAction *breakAction; + QAction *sepAction; + QAction *reverseDirectionAction; +}; + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggeragents.cpp b/src/plugins/debugger/debuggeragents.cpp index cb6e358bc791de024be2d4c2d3fdd6d05d2650c6..b3e4a8e9a8b76df5c78abdb6266fb3bc819c04e8 100644 --- a/src/plugins/debugger/debuggeragents.cpp +++ b/src/plugins/debugger/debuggeragents.cpp @@ -28,6 +28,7 @@ **************************************************************************/ #include "debuggeragents.h" +#include "debuggerstringutils.h" #include "idebuggerengine.h" #include <coreplugin/coreconstants.h> @@ -193,6 +194,7 @@ DisassemblerViewAgent::~DisassemblerViewAgent() if (d->editor) d->editor->deleteLater(); delete d; + d = 0; } void DisassemblerViewAgent::setFrame(const StackFrame &frame) @@ -206,12 +208,10 @@ void DisassemblerViewAgent::setFrame(const StackFrame &frame) void DisassemblerViewAgent::setContents(const QString &contents) { + QTC_ASSERT(d, return); using namespace Core; using namespace TextEditor; - if (!d->editor) - return; - QPlainTextEdit *plainTextEdit = 0; EditorManager *editorManager = EditorManager::instance(); if (!d->editor) { diff --git a/src/plugins/debugger/debuggeragents.h b/src/plugins/debugger/debuggeragents.h index 7e52f96fae9e2d98d54b00cd1fe48ebb7eee2301..ba993b0efdfc3d17f27c3c9a674424f33c70438d 100644 --- a/src/plugins/debugger/debuggeragents.h +++ b/src/plugins/debugger/debuggeragents.h @@ -42,9 +42,9 @@ namespace Debugger { +class DebuggerManager; namespace Internal { -class DebuggerManager; struct DisassemblerViewAgentPrivate; class MemoryViewAgent : public QObject diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index 59bc87faa24b228ada7930a0964dc14851843a64..2367ce402e5e6bd5bfddf2767e6cc826673c1cca 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -60,8 +60,6 @@ namespace Internal { } } // namespace Constants -namespace Internal { - enum DebuggerState { DebuggerNotReady, // Debugger not started @@ -118,7 +116,6 @@ enum LogChannel LogMisc }; -} // namespace Internal } // namespace Debugger #endif // DEBUGGERCONSTANTS_H diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index f3ad84600dd4226fa9c13b803e97d5b78ff2c80d..1666bd7445112db03c8f59a7276fa86f5a6aaadd 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -33,6 +33,7 @@ #include "debuggerrunner.h" #include "debuggerconstants.h" #include "idebuggerengine.h" +#include "debuggerstringutils.h" #include "breakwindow.h" #include "debuggeroutputwindow.h" @@ -43,6 +44,7 @@ #include "threadswindow.h" #include "watchwindow.h" + #include "breakhandler.h" #include "moduleshandler.h" #include "registerhandler.h" @@ -153,8 +155,9 @@ IDebuggerEngine *createWinEngine(DebuggerManager *, bool /* cmdLineEnabled */, Q { return 0; } #endif +} // namespace Internal -QDebug operator<<(QDebug str, const DebuggerStartParameters &p) +DEBUGGER_EXPORT QDebug operator<<(QDebug str, const DebuggerStartParameters &p) { QDebug nospace = str.nospace(); const QString sep = QString(QLatin1Char(',')); @@ -171,6 +174,7 @@ QDebug operator<<(QDebug str, const DebuggerStartParameters &p) } using namespace Constants; +using namespace Debugger::Internal; static const QString tooltipIName = "tooltip"; @@ -242,15 +246,70 @@ void DebuggerStartParameters::clear() // /////////////////////////////////////////////////////////////////////// -static IDebuggerEngine *gdbEngine = 0; -static IDebuggerEngine *scriptEngine = 0; -static IDebuggerEngine *tcfEngine = 0; -static IDebuggerEngine *winEngine = 0; - -DebuggerManager::DebuggerManager() - : m_startParameters(new DebuggerStartParameters), +static Debugger::Internal::IDebuggerEngine *gdbEngine = 0; +static Debugger::Internal::IDebuggerEngine *scriptEngine = 0; +static Debugger::Internal::IDebuggerEngine *tcfEngine = 0; +static Debugger::Internal::IDebuggerEngine *winEngine = 0; + +struct DebuggerManagerPrivate { + + DebuggerManagerPrivate(); + + static DebuggerManager *instance; + + // FIXME: Remove engine-specific state + DebuggerStartParametersPtr m_startParameters; + qint64 m_inferiorPid; + /// Views + Core::Utils::FancyMainWindow *m_mainWindow; + QLabel *m_statusLabel; + QDockWidget *m_breakDock; + QDockWidget *m_modulesDock; + QDockWidget *m_outputDock; + QDockWidget *m_registerDock; + QDockWidget *m_stackDock; + QDockWidget *m_sourceFilesDock; + QDockWidget *m_threadsDock; + QDockWidget *m_watchDock; + + BreakHandler *m_breakHandler; + ModulesHandler *m_modulesHandler; + RegisterHandler *m_registerHandler; + StackHandler *m_stackHandler; + ThreadsHandler *m_threadsHandler; + WatchHandler *m_watchHandler; + SourceFilesWindow *m_sourceFilesWindow; + + DebuggerManagerActions m_actions; + + QWidget *m_breakWindow; + QWidget *m_localsWindow; + QWidget *m_registerWindow; + QWidget *m_modulesWindow; + QWidget *m_stackWindow; + QWidget *m_threadsWindow; + QWidget *m_watchersWindow; + DebuggerOutputWindow *m_outputWindow; + + bool m_busy; + QTimer *m_statusTimer; + QString m_lastPermanentStatusMessage; + + IDebuggerEngine *m_engine; + DebuggerState m_state; +}; + +DebuggerManager *DebuggerManagerPrivate::instance = 0; + +DebuggerManagerPrivate::DebuggerManagerPrivate() : + m_startParameters(new DebuggerStartParameters), m_inferiorPid(0) { +} + +DebuggerManager::DebuggerManager() : d(new DebuggerManagerPrivate) +{ + DebuggerManagerPrivate::instance = this; init(); } @@ -262,40 +321,46 @@ DebuggerManager::~DebuggerManager() doDelete(tcfEngine); doDelete(winEngine); #undef doDelete + DebuggerManagerPrivate::instance = 0; + delete d; +} + +DebuggerManager *DebuggerManager::instance() +{ + return DebuggerManagerPrivate::instance; } void DebuggerManager::init() { - m_state = DebuggerState(-1); - m_busy = false; + d->m_state = DebuggerState(-1); + d->m_busy = false; - m_modulesHandler = 0; - m_registerHandler = 0; + d->m_modulesHandler = 0; + d->m_registerHandler = 0; - m_statusLabel = new QLabel; - m_statusLabel->setMinimumSize(QSize(30, 10)); + d->m_statusLabel = new QLabel; + d->m_statusLabel->setMinimumSize(QSize(30, 10)); - m_breakWindow = new BreakWindow; - m_modulesWindow = new ModulesWindow(this); - m_outputWindow = new DebuggerOutputWindow; - m_registerWindow = new RegisterWindow(this); - m_stackWindow = new StackWindow(this); - m_sourceFilesWindow = new SourceFilesWindow; - m_threadsWindow = new ThreadsWindow; - m_localsWindow = new WatchWindow(WatchWindow::LocalsType, this); - m_watchersWindow = new WatchWindow(WatchWindow::WatchersType, this); - //m_tooltipWindow = new WatchWindow(WatchWindow::TooltipType, this); - m_statusTimer = new QTimer(this); + d->m_breakWindow = new BreakWindow; + d->m_modulesWindow = new ModulesWindow(this); + d->m_outputWindow = new DebuggerOutputWindow; + d->m_registerWindow = new RegisterWindow(this); + d->m_stackWindow = new StackWindow(this); + d->m_sourceFilesWindow = new SourceFilesWindow; + d->m_threadsWindow = new ThreadsWindow; + d->m_localsWindow = new WatchWindow(WatchWindow::LocalsType, this); + d->m_watchersWindow = new WatchWindow(WatchWindow::WatchersType, this); + d->m_statusTimer = new QTimer(this); - m_mainWindow = new Core::Utils::FancyMainWindow; - m_mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); - m_mainWindow->setDocumentMode(true); + d->m_mainWindow = new Core::Utils::FancyMainWindow; + d->m_mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); + d->m_mainWindow->setDocumentMode(true); // Stack - m_stackHandler = new StackHandler; + d->m_stackHandler = new StackHandler; QAbstractItemView *stackView = - qobject_cast<QAbstractItemView *>(m_stackWindow); - stackView->setModel(m_stackHandler->stackModel()); + qobject_cast<QAbstractItemView *>(d->m_stackWindow); + stackView->setModel(d->m_stackHandler->stackModel()); connect(stackView, SIGNAL(frameActivated(int)), this, SLOT(activateFrame(int))); connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()), @@ -304,22 +369,22 @@ void DebuggerManager::init() this, SLOT(reloadFullStack())); // Threads - m_threadsHandler = new ThreadsHandler; + d->m_threadsHandler = new ThreadsHandler; QAbstractItemView *threadsView = - qobject_cast<QAbstractItemView *>(m_threadsWindow); - threadsView->setModel(m_threadsHandler->threadsModel()); + qobject_cast<QAbstractItemView *>(d->m_threadsWindow); + threadsView->setModel(d->m_threadsHandler->threadsModel()); connect(threadsView, SIGNAL(threadSelected(int)), this, SLOT(selectThread(int))); // Breakpoints - m_breakHandler = new BreakHandler(this); + d->m_breakHandler = new BreakHandler(this); QAbstractItemView *breakView = - qobject_cast<QAbstractItemView *>(m_breakWindow); - breakView->setModel(m_breakHandler->model()); + qobject_cast<QAbstractItemView *>(d->m_breakWindow); + breakView->setModel(d->m_breakHandler->model()); connect(breakView, SIGNAL(breakpointActivated(int)), - m_breakHandler, SLOT(activateBreakpoint(int))); + d->m_breakHandler, SLOT(activateBreakpoint(int))); connect(breakView, SIGNAL(breakpointDeleted(int)), - m_breakHandler, SLOT(removeBreakpoint(int))); + d->m_breakHandler, SLOT(removeBreakpoint(int))); connect(breakView, SIGNAL(breakpointSynchronizationRequested()), this, SLOT(attemptBreakpointSynchronization())); connect(breakView, SIGNAL(breakByFunctionRequested(QString)), @@ -329,9 +394,9 @@ void DebuggerManager::init() // Modules QAbstractItemView *modulesView = - qobject_cast<QAbstractItemView *>(m_modulesWindow); - m_modulesHandler = new ModulesHandler; - modulesView->setModel(m_modulesHandler->model()); + qobject_cast<QAbstractItemView *>(d->m_modulesWindow); + d->m_modulesHandler = new ModulesHandler; + modulesView->setModel(d->m_modulesHandler->model()); connect(modulesView, SIGNAL(reloadModulesRequested()), this, SLOT(reloadModules())); connect(modulesView, SIGNAL(loadSymbolsRequested(QString)), @@ -344,10 +409,10 @@ void DebuggerManager::init() this, SLOT(createNewDock(QWidget*))); // Source Files - //m_sourceFilesHandler = new SourceFilesHandler; + //d->m_sourceFilesHandler = new SourceFilesHandler; QAbstractItemView *sourceFilesView = - qobject_cast<QAbstractItemView *>(m_sourceFilesWindow); - //sourceFileView->setModel(m_stackHandler->stackModel()); + qobject_cast<QAbstractItemView *>(d->m_sourceFilesWindow); + //sourceFileView->setModel(d->m_stackHandler->stackModel()); connect(sourceFilesView, SIGNAL(reloadSourceFilesRequested()), this, SLOT(reloadSourceFiles())); connect(sourceFilesView, SIGNAL(fileOpenRequested(QString)), @@ -355,104 +420,88 @@ void DebuggerManager::init() // Registers QAbstractItemView *registerView = - qobject_cast<QAbstractItemView *>(m_registerWindow); - m_registerHandler = new RegisterHandler; - registerView->setModel(m_registerHandler->model()); + qobject_cast<QAbstractItemView *>(d->m_registerWindow); + d->m_registerHandler = new RegisterHandler; + registerView->setModel(d->m_registerHandler->model()); // Locals - m_watchHandler = new WatchHandler; - QTreeView *localsView = qobject_cast<QTreeView *>(m_localsWindow); - localsView->setModel(m_watchHandler->model(LocalsWatch)); + d->m_watchHandler = new WatchHandler; + QTreeView *localsView = qobject_cast<QTreeView *>(d->m_localsWindow); + localsView->setModel(d->m_watchHandler->model(LocalsWatch)); // Watchers - QTreeView *watchersView = qobject_cast<QTreeView *>(m_watchersWindow); - watchersView->setModel(m_watchHandler->model(WatchersWatch)); - connect(m_watchHandler, SIGNAL(sessionValueRequested(QString,QVariant*)), + QTreeView *watchersView = qobject_cast<QTreeView *>(d->m_watchersWindow); + watchersView->setModel(d->m_watchHandler->model(WatchersWatch)); + connect(d->m_watchHandler, SIGNAL(sessionValueRequested(QString,QVariant*)), this, SIGNAL(sessionValueRequested(QString,QVariant*))); - connect(m_watchHandler, SIGNAL(setSessionValueRequested(QString,QVariant)), + connect(d->m_watchHandler, SIGNAL(setSessionValueRequested(QString,QVariant)), this, SIGNAL(setSessionValueRequested(QString,QVariant))); connect(theDebuggerAction(AssignValue), SIGNAL(triggered()), this, SLOT(assignValueInDebugger()), Qt::QueuedConnection); // Tooltip - //QTreeView *tooltipView = qobject_cast<QTreeView *>(m_tooltipWindow); - //tooltipView->setModel(m_watchHandler->model(TooltipsWatch)); - //qRegisterMetaType<WatchData>("Debugger::Internal::WatchData"); + //QTreeView *tooltipView = qobject_cast<QTreeView *>(d->m_tooltipWindow); + //tooltipView->setModel(d->m_watchHandler->model(TooltipsWatch)); + //qRegisterMetaType<WatchData>("WatchData"); qRegisterMetaType<WatchData>("WatchData"); - connect(m_watchHandler, SIGNAL(watchDataUpdateNeeded(WatchData)), - this, SLOT(updateWatchData(WatchData))); + connect(d->m_watchHandler, SIGNAL(watchDataUpdateNeeded(Debugger::Internal::WatchData)), + this, SLOT(updateWatchData(Debugger::Internal::WatchData))); - m_continueAction = new QAction(this); - m_continueAction->setText(tr("Continue")); - m_continueAction->setIcon(QIcon(":/debugger/images/debugger_continue_small.png")); + d->m_actions.continueAction = new QAction(tr("Continue"), this); + d->m_actions.continueAction->setIcon(QIcon(":/debugger/images/debugger_continue_small.png")); - m_stopAction = new QAction(this); - m_stopAction->setText(tr("Interrupt")); - m_stopAction->setIcon(QIcon(":/debugger/images/debugger_interrupt_small.png")); + d->m_actions.stopAction = new QAction(tr("Interrupt"), this); + d->m_actions.stopAction->setIcon(QIcon(":/debugger/images/debugger_interrupt_small.png")); - m_resetAction = new QAction(this); - m_resetAction->setText(tr("Reset Debugger")); + d->m_actions.resetAction = new QAction(tr("Reset Debugger"), this); - m_nextAction = new QAction(this); - m_nextAction->setText(tr("Step Over")); - //m_nextAction->setShortcut(QKeySequence(tr("F6"))); - m_nextAction->setIcon(QIcon(":/debugger/images/debugger_stepover_small.png")); + d->m_actions.nextAction = new QAction(tr("Step Over"), this); + d->m_actions.nextAction->setIcon(QIcon(":/debugger/images/debugger_stepover_small.png")); - m_stepAction = new QAction(this); - m_stepAction->setText(tr("Step Into")); - //m_stepAction->setShortcut(QKeySequence(tr("F7"))); - m_stepAction->setIcon(QIcon(":/debugger/images/debugger_stepinto_small.png")); + d->m_actions.stepAction = new QAction(tr("Step Into"), this); + d->m_actions.stepAction->setIcon(QIcon(":/debugger/images/debugger_stepinto_small.png")); - m_stepOutAction = new QAction(this); - m_stepOutAction->setText(tr("Step Out")); - //m_stepOutAction->setShortcut(QKeySequence(tr("Shift+F7"))); - m_stepOutAction->setIcon(QIcon(":/debugger/images/debugger_stepout_small.png")); + d->m_actions.stepOutAction = new QAction(tr("Step Out"), this); + d->m_actions.stepOutAction->setIcon(QIcon(":/debugger/images/debugger_stepout_small.png")); - m_runToLineAction = new QAction(this); - m_runToLineAction->setText(tr("Run to Line")); + d->m_actions.runToLineAction = new QAction(tr("Run to Line"), this); - m_runToFunctionAction = new QAction(this); - m_runToFunctionAction->setText(tr("Run to Outermost Function")); + d->m_actions.runToFunctionAction = new QAction(tr("Run to Outermost Function"), this); - m_jumpToLineAction = new QAction(this); - m_jumpToLineAction->setText(tr("Jump to Line")); + d->m_actions.jumpToLineAction = new QAction(tr("Jump to Line"), this); - m_breakAction = new QAction(this); - m_breakAction->setText(tr("Toggle Breakpoint")); + d->m_actions.breakAction = new QAction(tr("Toggle Breakpoint"), this); - m_watchAction = new QAction(this); - m_watchAction->setText(tr("Add to Watch Window")); + d->m_actions.watchAction = new QAction(tr("Add to Watch Window"), this); - m_reverseDirectionAction = new QAction(this); - m_reverseDirectionAction->setText(tr("Reverse Direction")); - m_reverseDirectionAction->setCheckable(true); - m_reverseDirectionAction->setChecked(false); - //m_reverseDirectionAction->setIcon(QIcon(":/debugger/images/debugger_stepoverproc_small.png")); + d->m_actions.reverseDirectionAction = new QAction(tr("Reverse Direction"), this); + d->m_actions.reverseDirectionAction->setCheckable(true); + d->m_actions.reverseDirectionAction->setChecked(false); - connect(m_continueAction, SIGNAL(triggered()), + connect(d->m_actions.continueAction, SIGNAL(triggered()), this, SLOT(continueExec())); - connect(m_stopAction, SIGNAL(triggered()), + connect(d->m_actions.stopAction, SIGNAL(triggered()), this, SLOT(interruptDebuggingRequest())); - connect(m_resetAction, SIGNAL(triggered()), + connect(d->m_actions.resetAction, SIGNAL(triggered()), this, SLOT(exitDebugger())); - connect(m_nextAction, SIGNAL(triggered()), + connect(d->m_actions.nextAction, SIGNAL(triggered()), this, SLOT(nextExec())); - connect(m_stepAction, SIGNAL(triggered()), + connect(d->m_actions.stepAction, SIGNAL(triggered()), this, SLOT(stepExec())); - connect(m_stepOutAction, SIGNAL(triggered()), + connect(d->m_actions.stepOutAction, SIGNAL(triggered()), this, SLOT(stepOutExec())); - connect(m_runToLineAction, SIGNAL(triggered()), + connect(d->m_actions.runToLineAction, SIGNAL(triggered()), this, SLOT(runToLineExec())); - connect(m_runToFunctionAction, SIGNAL(triggered()), + connect(d->m_actions.runToFunctionAction, SIGNAL(triggered()), this, SLOT(runToFunctionExec())); - connect(m_jumpToLineAction, SIGNAL(triggered()), + connect(d->m_actions.jumpToLineAction, SIGNAL(triggered()), this, SLOT(jumpToLineExec())); - connect(m_watchAction, SIGNAL(triggered()), + connect(d->m_actions.watchAction, SIGNAL(triggered()), this, SLOT(addToWatchWindow())); - connect(m_breakAction, SIGNAL(triggered()), + connect(d->m_actions.breakAction, SIGNAL(triggered()), this, SLOT(toggleBreakpoint())); - connect(m_statusTimer, SIGNAL(timeout()), + connect(d->m_statusTimer, SIGNAL(timeout()), this, SLOT(clearStatusMessage())); connect(theDebuggerAction(ExecuteCommand), SIGNAL(triggered()), @@ -465,35 +514,35 @@ void DebuggerManager::init() this, SLOT(stepByInstructionTriggered())); - m_breakDock = m_mainWindow->addDockForWidget(m_breakWindow); + d->m_breakDock = d->m_mainWindow->addDockForWidget(d->m_breakWindow); - m_modulesDock = m_mainWindow->addDockForWidget(m_modulesWindow); - connect(m_modulesDock->toggleViewAction(), SIGNAL(toggled(bool)), + d->m_modulesDock = d->m_mainWindow->addDockForWidget(d->m_modulesWindow); + connect(d->m_modulesDock->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(reloadModules()), Qt::QueuedConnection); - m_registerDock = m_mainWindow->addDockForWidget(m_registerWindow); - connect(m_registerDock->toggleViewAction(), SIGNAL(toggled(bool)), + d->m_registerDock = d->m_mainWindow->addDockForWidget(d->m_registerWindow); + connect(d->m_registerDock->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(reloadRegisters()), Qt::QueuedConnection); - m_outputDock = m_mainWindow->addDockForWidget(m_outputWindow); + d->m_outputDock = d->m_mainWindow->addDockForWidget(d->m_outputWindow); - m_stackDock = m_mainWindow->addDockForWidget(m_stackWindow); + d->m_stackDock = d->m_mainWindow->addDockForWidget(d->m_stackWindow); - m_sourceFilesDock = m_mainWindow->addDockForWidget(m_sourceFilesWindow); - connect(m_sourceFilesDock->toggleViewAction(), SIGNAL(toggled(bool)), + d->m_sourceFilesDock = d->m_mainWindow->addDockForWidget(d->m_sourceFilesWindow); + connect(d->m_sourceFilesDock->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(reloadSourceFiles()), Qt::QueuedConnection); - m_threadsDock = m_mainWindow->addDockForWidget(m_threadsWindow); + d->m_threadsDock = d->m_mainWindow->addDockForWidget(d->m_threadsWindow); QSplitter *localsAndWatchers = new QSplitter(Qt::Vertical, 0); - localsAndWatchers->setWindowTitle(m_localsWindow->windowTitle()); - localsAndWatchers->addWidget(m_localsWindow); - localsAndWatchers->addWidget(m_watchersWindow); - //localsAndWatchers->addWidget(m_tooltipWindow); + localsAndWatchers->setWindowTitle(d->m_localsWindow->windowTitle()); + localsAndWatchers->addWidget(d->m_localsWindow); + localsAndWatchers->addWidget(d->m_watchersWindow); + //localsAndWatchers->addWidget(d->m_tooltipWindow); localsAndWatchers->setStretchFactor(0, 3); localsAndWatchers->setStretchFactor(1, 1); localsAndWatchers->setStretchFactor(2, 1); - m_watchDock = m_mainWindow->addDockForWidget(localsAndWatchers); + d->m_watchDock = d->m_mainWindow->addDockForWidget(localsAndWatchers); setState(DebuggerNotReady); } @@ -519,77 +568,132 @@ QList<Core::IOptionsPage*> DebuggerManager::initializeEngines(unsigned enabledTy tcfEngine->addOptionPages(&rc); } - m_engine = 0; + d->m_engine = 0; STATE_DEBUG(gdbEngine << winEngine << scriptEngine << rc.size()); return rc; } -IDebuggerEngine *DebuggerManager::engine() +DebuggerManagerActions DebuggerManager::debuggerManagerActions() const +{ + return d->m_actions; +} + +Core::Utils::FancyMainWindow *DebuggerManager::mainWindow() const +{ + return d->m_mainWindow; +} + +QLabel *DebuggerManager::statusLabel() const { - return m_engine; + return d->m_statusLabel; +} + +IDebuggerEngine *DebuggerManager::currentEngine() const +{ + return d->m_engine; +} + +ModulesHandler *DebuggerManager::modulesHandler() const +{ + return d->m_modulesHandler; +} + +BreakHandler *DebuggerManager::breakHandler() const +{ + return d->m_breakHandler; +} + +RegisterHandler *DebuggerManager::registerHandler() const +{ + return d->m_registerHandler; +} + +StackHandler *DebuggerManager::stackHandler() const +{ + return d->m_stackHandler; +} + +ThreadsHandler *DebuggerManager::threadsHandler() const +{ + return d->m_threadsHandler; +} + +WatchHandler *DebuggerManager::watchHandler() const +{ + return d->m_watchHandler; +} + +SourceFilesWindow *DebuggerManager::sourceFileWindow() const +{ + return d->m_sourceFilesWindow; +} + +QWidget *DebuggerManager::threadsWindow() const +{ + return d->m_threadsWindow; } void DebuggerManager::createNewDock(QWidget *widget) { - QDockWidget *dockWidget = new QDockWidget(widget->windowTitle(), m_mainWindow); + QDockWidget *dockWidget = new QDockWidget(widget->windowTitle(), d->m_mainWindow); dockWidget->setObjectName(widget->windowTitle()); dockWidget->setFeatures(QDockWidget::DockWidgetClosable); dockWidget->setWidget(widget); - m_mainWindow->addDockWidget(Qt::TopDockWidgetArea, dockWidget); + d->m_mainWindow->addDockWidget(Qt::TopDockWidgetArea, dockWidget); dockWidget->show(); } void DebuggerManager::setSimpleDockWidgetArrangement() { - m_mainWindow->setTrackingEnabled(false); - QList<QDockWidget *> dockWidgets = m_mainWindow->dockWidgets(); + d->m_mainWindow->setTrackingEnabled(false); + QList<QDockWidget *> dockWidgets = d->m_mainWindow->dockWidgets(); foreach (QDockWidget *dockWidget, dockWidgets) { dockWidget->setFloating(false); - m_mainWindow->removeDockWidget(dockWidget); + d->m_mainWindow->removeDockWidget(dockWidget); } foreach (QDockWidget *dockWidget, dockWidgets) { - m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dockWidget); + d->m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dockWidget); dockWidget->show(); } - m_mainWindow->tabifyDockWidget(m_watchDock, m_breakDock); - m_mainWindow->tabifyDockWidget(m_watchDock, m_modulesDock); - m_mainWindow->tabifyDockWidget(m_watchDock, m_outputDock); - m_mainWindow->tabifyDockWidget(m_watchDock, m_registerDock); - m_mainWindow->tabifyDockWidget(m_watchDock, m_threadsDock); - m_mainWindow->tabifyDockWidget(m_watchDock, m_sourceFilesDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_breakDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_modulesDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_outputDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_registerDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_threadsDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_sourceFilesDock); // They following views are rarely used in ordinary debugging. Hiding them // saves cycles since the corresponding information won't be retrieved. - m_sourceFilesDock->hide(); - m_registerDock->hide(); - m_modulesDock->hide(); - m_outputDock->hide(); - m_mainWindow->setTrackingEnabled(true); + d->m_sourceFilesDock->hide(); + d->m_registerDock->hide(); + d->m_modulesDock->hide(); + d->m_outputDock->hide(); + d->m_mainWindow->setTrackingEnabled(true); } QAbstractItemModel *DebuggerManager::threadsModel() { - return qobject_cast<ThreadsWindow*>(m_threadsWindow)->model(); + return qobject_cast<ThreadsWindow*>(d->m_threadsWindow)->model(); } void DebuggerManager::clearStatusMessage() { - m_statusLabel->setText(m_lastPermanentStatusMessage); + d->m_statusLabel->setText(d->m_lastPermanentStatusMessage); } void DebuggerManager::showStatusMessage(const QString &msg, int timeout) { Q_UNUSED(timeout) showDebuggerOutput(LogStatus, msg); - m_statusLabel->setText(QLatin1String(" ") + msg); + d->m_statusLabel->setText(QLatin1String(" ") + msg); if (timeout > 0) { - m_statusTimer->setSingleShot(true); - m_statusTimer->start(timeout); + d->m_statusTimer->setSingleShot(true); + d->m_statusTimer->start(timeout); } else { - m_lastPermanentStatusMessage = msg; - m_statusTimer->stop(); + d->m_lastPermanentStatusMessage = msg; + d->m_statusTimer->stop(); } } @@ -614,10 +718,10 @@ void DebuggerManager::notifyInferiorExited() void DebuggerManager::notifyInferiorPidChanged(qint64 pid) { - STATE_DEBUG(m_inferiorPid << pid); + STATE_DEBUG(d->m_inferiorPid << pid); - if (m_inferiorPid != pid) { - m_inferiorPid = pid; + if (d->m_inferiorPid != pid) { + d->m_inferiorPid = pid; emit inferiorPidChanged(pid); } } @@ -629,10 +733,10 @@ void DebuggerManager::showApplicationOutput(const QString &str) void DebuggerManager::shutdown() { - STATE_DEBUG(m_engine); - if (m_engine) - m_engine->shutdown(); - m_engine = 0; + STATE_DEBUG(d->m_engine); + if (d->m_engine) + d->m_engine->shutdown(); + d->m_engine = 0; #define doDelete(ptr) delete ptr; ptr = 0 doDelete(scriptEngine); @@ -642,32 +746,32 @@ void DebuggerManager::shutdown() // Delete these manually before deleting the manager // (who will delete the models for most views) - doDelete(m_breakWindow); - doDelete(m_modulesWindow); - doDelete(m_outputWindow); - doDelete(m_registerWindow); - doDelete(m_stackWindow); - doDelete(m_sourceFilesWindow); - doDelete(m_threadsWindow); - //doDelete(m_tooltipWindow); - doDelete(m_watchersWindow); - doDelete(m_localsWindow); - - doDelete(m_breakHandler); - doDelete(m_threadsHandler); - doDelete(m_modulesHandler); - doDelete(m_registerHandler); - doDelete(m_stackHandler); - doDelete(m_watchHandler); + doDelete(d->m_breakWindow); + doDelete(d->m_modulesWindow); + doDelete(d->m_outputWindow); + doDelete(d->m_registerWindow); + doDelete(d->m_stackWindow); + doDelete(d->m_sourceFilesWindow); + doDelete(d->m_threadsWindow); + //doDelete(d->m_tooltipWindow); + doDelete(d->m_watchersWindow); + doDelete(d->m_localsWindow); + + doDelete(d->m_breakHandler); + doDelete(d->m_threadsHandler); + doDelete(d->m_modulesHandler); + doDelete(d->m_registerHandler); + doDelete(d->m_stackHandler); + doDelete(d->m_watchHandler); #undef doDelete } BreakpointData *DebuggerManager::findBreakpoint(const QString &fileName, int lineNumber) { - if (!m_breakHandler) + if (!d->m_breakHandler) return 0; - int index = m_breakHandler->findBreakpoint(fileName, lineNumber); - return index == -1 ? 0 : m_breakHandler->at(index); + int index = d->m_breakHandler->findBreakpoint(fileName, lineNumber); + return index == -1 ? 0 : d->m_breakHandler->at(index); } void DebuggerManager::toggleBreakpoint() @@ -683,7 +787,7 @@ void DebuggerManager::toggleBreakpoint() void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber) { STATE_DEBUG(fileName << lineNumber); - QTC_ASSERT(m_breakHandler, return); + QTC_ASSERT(d->m_breakHandler, return); if (state() != InferiorRunning && state() != InferiorStopped && state() != DebuggerNotReady) { @@ -692,11 +796,11 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber) return; } - int index = m_breakHandler->findBreakpoint(fileName, lineNumber); + int index = d->m_breakHandler->findBreakpoint(fileName, lineNumber); if (index == -1) - m_breakHandler->setBreakpoint(fileName, lineNumber); + d->m_breakHandler->setBreakpoint(fileName, lineNumber); else - m_breakHandler->removeBreakpoint(index); + d->m_breakHandler->removeBreakpoint(index); attemptBreakpointSynchronization(); } @@ -704,7 +808,7 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber) void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineNumber) { STATE_DEBUG(fileName << lineNumber); - QTC_ASSERT(m_breakHandler, return); + QTC_ASSERT(d->m_breakHandler, return); if (state() != InferiorRunning && state() != InferiorStopped && state() != DebuggerNotReady) { @@ -713,27 +817,27 @@ void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineN return; } - m_breakHandler->toggleBreakpointEnabled(fileName, lineNumber); + d->m_breakHandler->toggleBreakpointEnabled(fileName, lineNumber); attemptBreakpointSynchronization(); } void DebuggerManager::attemptBreakpointSynchronization() { - if (m_engine) - m_engine->attemptBreakpointSynchronization(); + if (d->m_engine) + d->m_engine->attemptBreakpointSynchronization(); } void DebuggerManager::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos) { - if (m_engine) - m_engine->setToolTipExpression(mousePos, editor, cursorPos); + if (d->m_engine) + d->m_engine->setToolTipExpression(mousePos, editor, cursorPos); } -void DebuggerManager::updateWatchData(const WatchData &data) +void DebuggerManager::updateWatchData(const Debugger::Internal::WatchData &data) { - if (m_engine) - m_engine->updateWatchData(data); + if (d->m_engine) + d->m_engine->updateWatchData(data); } static QString msgEngineNotAvailable(const char *engine) @@ -851,10 +955,10 @@ static IDebuggerEngine *determineDebuggerEngine(int /* pid */, void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp) { - m_startParameters = sp; - m_inferiorPid = m_startParameters->attachPID > 0 - ? m_startParameters->attachPID : 0; - const QString toolChainName = ProjectExplorer::ToolChain::toolChainName(static_cast<ProjectExplorer::ToolChain::ToolChainType>(m_startParameters->toolChainType)); + d->m_startParameters = sp; + d->m_inferiorPid = d->m_startParameters->attachPID > 0 + ? d->m_startParameters->attachPID : 0; + const QString toolChainName = ProjectExplorer::ToolChain::toolChainName(static_cast<ProjectExplorer::ToolChain::ToolChainType>(d->m_startParameters->toolChainType)); emit debugModeRequested(); showDebuggerOutput(LogStatus, @@ -863,28 +967,28 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp) QString errorMessage; QString settingsIdHint; - switch (m_startParameters->startMode) { + switch (d->m_startParameters->startMode) { case AttachExternal: case AttachCrashedExternal: - m_engine = determineDebuggerEngine(m_startParameters->attachPID, - m_startParameters->toolChainType, &errorMessage); + d->m_engine = determineDebuggerEngine(d->m_startParameters->attachPID, + d->m_startParameters->toolChainType, &errorMessage); break; case AttachTcf: - m_engine = tcfEngine; + d->m_engine = tcfEngine; break; default: - m_engine = determineDebuggerEngine(m_startParameters->executable, - m_startParameters->toolChainType, &errorMessage, &settingsIdHint); + d->m_engine = determineDebuggerEngine(d->m_startParameters->executable, + d->m_startParameters->toolChainType, &errorMessage, &settingsIdHint); break; } - if (!m_engine) { + if (!d->m_engine) { emit debuggingFinished(); // Create Message box with possibility to go to settings QAbstractButton *settingsButton = 0; QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), tr("Cannot debug '%1' (tool chain: '%2'): %3"). - arg(m_startParameters->executable, toolChainName, errorMessage), + arg(d->m_startParameters->executable, toolChainName, errorMessage), QMessageBox::Ok); if (!settingsIdHint.isEmpty()) settingsButton = msgBox.addButton(tr("Settings..."), QMessageBox::AcceptRole); @@ -895,16 +999,16 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp) return; } - STATE_DEBUG(m_startParameters->executable << m_engine); + STATE_DEBUG(d->m_startParameters->executable << d->m_engine); setBusyCursor(false); setState(EngineStarting); - connect(m_engine, SIGNAL(startFailed()), this, SLOT(startFailed())); - m_engine->startDebugger(m_startParameters); + connect(d->m_engine, SIGNAL(startFailed()), this, SLOT(startFailed())); + d->m_engine->startDebugger(d->m_startParameters); } void DebuggerManager::startFailed() { - disconnect(m_engine, SIGNAL(startFailed()), this, SLOT(startFailed())); + disconnect(d->m_engine, SIGNAL(startFailed()), this, SLOT(startFailed())); setState(DebuggerNotReady); emit debuggingFinished(); } @@ -918,26 +1022,26 @@ void DebuggerManager::cleanupViews() modulesHandler()->removeAll(); watchHandler()->cleanup(); registerHandler()->removeAll(); - m_sourceFilesWindow->removeAll(); + d->m_sourceFilesWindow->removeAll(); } void DebuggerManager::exitDebugger() { STATE_DEBUG(""); - if (m_engine) - m_engine->exitDebugger(); + if (d->m_engine) + d->m_engine->exitDebugger(); cleanupViews(); setState(DebuggerNotReady); } DebuggerStartParametersPtr DebuggerManager::startParameters() const { - return m_startParameters; + return d->m_startParameters; } qint64 DebuggerManager::inferiorPid() const { - return m_inferiorPid; + return d->m_inferiorPid; } void DebuggerManager::assignValueInDebugger() @@ -952,72 +1056,72 @@ void DebuggerManager::assignValueInDebugger() void DebuggerManager::assignValueInDebugger(const QString &expr, const QString &value) { - QTC_ASSERT(m_engine, return); - m_engine->assignValueInDebugger(expr, value); + QTC_ASSERT(d->m_engine, return); + d->m_engine->assignValueInDebugger(expr, value); } void DebuggerManager::activateFrame(int index) { - QTC_ASSERT(m_engine, return); - m_engine->activateFrame(index); + QTC_ASSERT(d->m_engine, return); + d->m_engine->activateFrame(index); } void DebuggerManager::selectThread(int index) { - QTC_ASSERT(m_engine, return); - m_engine->selectThread(index); + QTC_ASSERT(d->m_engine, return); + d->m_engine->selectThread(index); } void DebuggerManager::loadAllSymbols() { - QTC_ASSERT(m_engine, return); - m_engine->loadAllSymbols(); + QTC_ASSERT(d->m_engine, return); + d->m_engine->loadAllSymbols(); } void DebuggerManager::loadSymbols(const QString &module) { - QTC_ASSERT(m_engine, return); - m_engine->loadSymbols(module); + QTC_ASSERT(d->m_engine, return); + d->m_engine->loadSymbols(module); } QList<Symbol> DebuggerManager::moduleSymbols(const QString &moduleName) { - QTC_ASSERT(m_engine, return QList<Symbol>()); - return m_engine->moduleSymbols(moduleName); + QTC_ASSERT(d->m_engine, return QList<Symbol>()); + return d->m_engine->moduleSymbols(moduleName); } void DebuggerManager::stepExec() { - QTC_ASSERT(m_engine, return); + QTC_ASSERT(d->m_engine, return); resetLocation(); if (theDebuggerBoolSetting(StepByInstruction)) - m_engine->stepIExec(); + d->m_engine->stepIExec(); else - m_engine->stepExec(); + d->m_engine->stepExec(); } void DebuggerManager::stepOutExec() { - QTC_ASSERT(m_engine, return); + QTC_ASSERT(d->m_engine, return); resetLocation(); - m_engine->stepOutExec(); + d->m_engine->stepOutExec(); } void DebuggerManager::nextExec() { - QTC_ASSERT(m_engine, return); + QTC_ASSERT(d->m_engine, return); resetLocation(); if (theDebuggerBoolSetting(StepByInstruction)) - m_engine->nextIExec(); + d->m_engine->nextIExec(); else - m_engine->nextExec(); + d->m_engine->nextExec(); } void DebuggerManager::watchPoint() { if (QAction *action = qobject_cast<QAction *>(sender())) - if (m_engine) - m_engine->watchPoint(action->data().toPoint()); + if (d->m_engine) + d->m_engine->watchPoint(action->data().toPoint()); } void DebuggerManager::executeDebuggerCommand() @@ -1029,8 +1133,8 @@ void DebuggerManager::executeDebuggerCommand() void DebuggerManager::executeDebuggerCommand(const QString &command) { STATE_DEBUG(command); - QTC_ASSERT(m_engine, return); - m_engine->executeDebuggerCommand(command); + QTC_ASSERT(d->m_engine, return); + d->m_engine->executeDebuggerCommand(command); } void DebuggerManager::sessionLoaded() @@ -1044,8 +1148,8 @@ void DebuggerManager::sessionLoaded() void DebuggerManager::aboutToUnloadSession() { cleanupViews(); - if (m_engine) - m_engine->shutdown(); + if (d->m_engine) + d->m_engine->shutdown(); setState(DebuggerNotReady); setBusyCursor(false); } @@ -1057,14 +1161,14 @@ void DebuggerManager::aboutToSaveSession() void DebuggerManager::loadSessionData() { - m_breakHandler->loadSessionData(); - m_watchHandler->loadSessionData(); + d->m_breakHandler->loadSessionData(); + d->m_watchHandler->loadSessionData(); } void DebuggerManager::saveSessionData() { - m_breakHandler->saveSessionData(); - m_watchHandler->saveSessionData(); + d->m_breakHandler->saveSessionData(); + d->m_watchHandler->saveSessionData(); } void DebuggerManager::dumpLog() @@ -1077,9 +1181,9 @@ void DebuggerManager::dumpLog() if (!file.open(QIODevice::WriteOnly)) return; QTextStream ts(&file); - ts << m_outputWindow->inputContents(); + ts << d->m_outputWindow->inputContents(); ts << "\n\n=======================================\n\n"; - ts << m_outputWindow->combinedContents(); + ts << d->m_outputWindow->combinedContents(); } void DebuggerManager::addToWatchWindow() @@ -1097,8 +1201,8 @@ void DebuggerManager::addToWatchWindow() void DebuggerManager::setBreakpoint(const QString &fileName, int lineNumber) { STATE_DEBUG(Q_FUNC_INFO << fileName << lineNumber); - QTC_ASSERT(m_breakHandler, return); - m_breakHandler->setBreakpoint(fileName, lineNumber); + QTC_ASSERT(d->m_breakHandler, return); + d->m_breakHandler->setBreakpoint(fileName, lineNumber); attemptBreakpointSynchronization(); } @@ -1114,29 +1218,29 @@ void DebuggerManager::breakByFunctionMain() void DebuggerManager::breakByFunction(const QString &functionName) { - QTC_ASSERT(m_breakHandler, return); - m_breakHandler->breakByFunction(functionName); + QTC_ASSERT(d->m_breakHandler, return); + d->m_breakHandler->breakByFunction(functionName); attemptBreakpointSynchronization(); } void DebuggerManager::setBusyCursor(bool busy) { - //STATE_DEBUG("BUSY FROM: " << m_busy << " TO: " << m_busy); - if (busy == m_busy) + //STATE_DEBUG("BUSY FROM: " << d->m_busy << " TO: " << d->m_busy); + if (busy == d->m_busy) return; - m_busy = busy; + d->m_busy = busy; QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor); - m_breakWindow->setCursor(cursor); - m_localsWindow->setCursor(cursor); - m_modulesWindow->setCursor(cursor); - m_outputWindow->setCursor(cursor); - m_registerWindow->setCursor(cursor); - m_stackWindow->setCursor(cursor); - m_sourceFilesWindow->setCursor(cursor); - m_threadsWindow->setCursor(cursor); - //m_tooltipWindow->setCursor(cursor); - m_watchersWindow->setCursor(cursor); + d->m_breakWindow->setCursor(cursor); + d->m_localsWindow->setCursor(cursor); + d->m_modulesWindow->setCursor(cursor); + d->m_outputWindow->setCursor(cursor); + d->m_registerWindow->setCursor(cursor); + d->m_stackWindow->setCursor(cursor); + d->m_sourceFilesWindow->setCursor(cursor); + d->m_threadsWindow->setCursor(cursor); + //d->m_tooltipWindow->setCursor(cursor); + d->m_watchersWindow->setCursor(cursor); } void DebuggerManager::queryCurrentTextEditor(QString *fileName, int *lineNumber, @@ -1147,26 +1251,26 @@ void DebuggerManager::queryCurrentTextEditor(QString *fileName, int *lineNumber, void DebuggerManager::continueExec() { - if (m_engine) - m_engine->continueInferior(); + if (d->m_engine) + d->m_engine->continueInferior(); } void DebuggerManager::detachDebugger() { - if (m_engine) - m_engine->detachDebugger(); + if (d->m_engine) + d->m_engine->detachDebugger(); } void DebuggerManager::interruptDebuggingRequest() { STATE_DEBUG(state()); - if (!m_engine) + if (!d->m_engine) return; bool interruptIsExit = (state() != InferiorRunning); if (interruptIsExit) { exitDebugger(); } else { - m_engine->interruptInferior(); + d->m_engine->interruptInferior(); } } @@ -1175,9 +1279,9 @@ void DebuggerManager::runToLineExec() QString fileName; int lineNumber = -1; emit currentTextEditorRequested(&fileName, &lineNumber, 0); - if (m_engine && !fileName.isEmpty()) { + if (d->m_engine && !fileName.isEmpty()) { STATE_DEBUG(fileName << lineNumber); - m_engine->runToLineExec(fileName, lineNumber); + d->m_engine->runToLineExec(fileName, lineNumber); } } @@ -1210,8 +1314,8 @@ void DebuggerManager::runToFunctionExec() } STATE_DEBUG(functionName); - if (m_engine && !functionName.isEmpty()) - m_engine->runToFunctionExec(functionName); + if (d->m_engine && !functionName.isEmpty()) + d->m_engine->runToFunctionExec(functionName); } void DebuggerManager::jumpToLineExec() @@ -1219,9 +1323,9 @@ void DebuggerManager::jumpToLineExec() QString fileName; int lineNumber = -1; emit currentTextEditorRequested(&fileName, &lineNumber, 0); - if (m_engine && !fileName.isEmpty()) { + if (d->m_engine && !fileName.isEmpty()) { STATE_DEBUG(fileName << lineNumber); - m_engine->jumpToLineExec(fileName, lineNumber); + d->m_engine->jumpToLineExec(fileName, lineNumber); } } @@ -1231,7 +1335,7 @@ void DebuggerManager::resetLocation() emit resetLocationRequested(); } -void DebuggerManager::gotoLocation(const StackFrame &frame, bool setMarker) +void DebuggerManager::gotoLocation(const Debugger::Internal::StackFrame &frame, bool setMarker) { // connected to the plugin emit gotoLocationRequested(frame, setMarker); @@ -1248,8 +1352,8 @@ void DebuggerManager::fileOpen(const QString &fileName) void DebuggerManager::stepByInstructionTriggered() { - QTC_ASSERT(m_stackHandler, return); - StackFrame frame = m_stackHandler->currentFrame(); + QTC_ASSERT(d->m_stackHandler, return); + StackFrame frame = d->m_stackHandler->currentFrame(); gotoLocation(frame, true); } @@ -1262,8 +1366,8 @@ void DebuggerManager::stepByInstructionTriggered() void DebuggerManager::reloadSourceFiles() { - if (m_engine && m_sourceFilesDock && m_sourceFilesDock->isVisible()) - m_engine->reloadSourceFiles(); + if (d->m_engine && d->m_sourceFilesDock && d->m_sourceFilesDock->isVisible()) + d->m_engine->reloadSourceFiles(); } void DebuggerManager::sourceFilesDockToggled(bool on) @@ -1281,8 +1385,8 @@ void DebuggerManager::sourceFilesDockToggled(bool on) void DebuggerManager::reloadModules() { - if (m_engine && m_modulesDock && m_modulesDock->isVisible()) - m_engine->reloadModules(); + if (d->m_engine && d->m_modulesDock && d->m_modulesDock->isVisible()) + d->m_engine->reloadModules(); } void DebuggerManager::modulesDockToggled(bool on) @@ -1300,16 +1404,16 @@ void DebuggerManager::modulesDockToggled(bool on) void DebuggerManager::showDebuggerOutput(int channel, const QString &msg) { - if (m_outputWindow) - m_outputWindow->showOutput(channel, msg); + if (d->m_outputWindow) + d->m_outputWindow->showOutput(channel, msg); else qDebug() << "OUTPUT: " << channel << msg; } void DebuggerManager::showDebuggerInput(int channel, const QString &msg) { - if (m_outputWindow) - m_outputWindow->showInput(channel, msg); + if (d->m_outputWindow) + d->m_outputWindow->showInput(channel, msg); else qDebug() << "INPUT: " << channel << msg; } @@ -1329,8 +1433,8 @@ void DebuggerManager::registerDockToggled(bool on) void DebuggerManager::reloadRegisters() { - if (m_engine && m_registerDock && m_registerDock->isVisible()) - m_engine->reloadRegisters(); + if (d->m_engine && d->m_registerDock && d->m_registerDock->isVisible()) + d->m_engine->reloadRegisters(); } ////////////////////////////////////////////////////////////////////// @@ -1351,7 +1455,7 @@ QString DebuggerManager::qtDumperLibraryName() const { if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool()) return theDebuggerAction(CustomDebuggingHelperLocation)->value().toString(); - return m_startParameters->dumperLibrary; + return d->m_startParameters->dumperLibrary; } QStringList DebuggerManager::qtDumperLibraryLocations() const @@ -1363,7 +1467,7 @@ QStringList DebuggerManager::qtDumperLibraryLocations() const tr("%1 (explicitly set in the Debugger Options)").arg(customLocation); return QStringList(location); } - return m_startParameters->dumperLibraryLocations; + return d->m_startParameters->dumperLibraryLocations; } void DebuggerManager::showQtDumperLibraryWarning(const QString &details) @@ -1397,19 +1501,19 @@ void DebuggerManager::showQtDumperLibraryWarning(const QString &details) void DebuggerManager::reloadFullStack() { - if (m_engine) - m_engine->reloadFullStack(); + if (d->m_engine) + d->m_engine->reloadFullStack(); } void DebuggerManager::setRegisterValue(int nr, const QString &value) { - if (m_engine) - m_engine->setRegisterValue(nr, value); + if (d->m_engine) + d->m_engine->setRegisterValue(nr, value); } bool DebuggerManager::isReverseDebugging() const { - return m_reverseDirectionAction->isChecked(); + return d->m_actions.reverseDirectionAction->isChecked(); } QVariant DebuggerManager::sessionValue(const QString &name) @@ -1436,7 +1540,7 @@ void DebuggerManager::showMessageBox(int icon, DebuggerState DebuggerManager::state() const { - return m_state; + return d->m_state; } static bool isAllowedTransition(int from, int to) @@ -1499,27 +1603,27 @@ static bool isAllowedTransition(int from, int to) void DebuggerManager::setState(DebuggerState state) { - //STATE_DEBUG("STATUS CHANGE: FROM " << stateName(m_state) + //STATE_DEBUG("STATUS CHANGE: FROM " << stateName(d->m_state) // << " TO " << stateName(state)); QString msg = _("State changed from %1(%2) to %3(%4).") - .arg(stateName(m_state)).arg(m_state).arg(stateName(state)).arg(state); + .arg(stateName(d->m_state)).arg(d->m_state).arg(stateName(state)).arg(state); qDebug() << msg; - if (!isAllowedTransition(m_state, state)) + if (!isAllowedTransition(d->m_state, state)) qDebug() << "UNEXPECTED STATE TRANSITION: " << msg; showDebuggerOutput(LogDebug, msg); resetLocation(); - if (state == m_state) + if (state == d->m_state) return; - m_state = state; + d->m_state = state; - if (m_state == InferiorStopped) + if (d->m_state == InferiorStopped) resetLocation(); - if (m_state == DebuggerNotReady) { + if (d->m_state == DebuggerNotReady) { setBusyCursor(false); emit debuggingFinished(); } @@ -1532,35 +1636,35 @@ void DebuggerManager::setState(DebuggerState state) const bool running = state == InferiorRunning; const bool ready = state == InferiorStopped - && m_startParameters->startMode != AttachCore; + && d->m_startParameters->startMode != AttachCore; if (ready) QApplication::alert(mainWindow(), 3000); - m_watchAction->setEnabled(ready); - m_breakAction->setEnabled(true); + d->m_actions.watchAction->setEnabled(ready); + d->m_actions.breakAction->setEnabled(true); bool interruptIsExit = !running; if (interruptIsExit) { - m_stopAction->setIcon(QIcon(":/debugger/images/debugger_stop_small.png")); - m_stopAction->setText(tr("Stop Debugger")); + d->m_actions.stopAction->setIcon(QIcon(":/debugger/images/debugger_stop_small.png")); + d->m_actions.stopAction->setText(tr("Stop Debugger")); } else { - m_stopAction->setIcon(QIcon(":/debugger/images/debugger_interrupt_small.png")); - m_stopAction->setText(tr("Interrupt")); + d->m_actions.stopAction->setIcon(QIcon(":/debugger/images/debugger_interrupt_small.png")); + d->m_actions.stopAction->setText(tr("Interrupt")); } - m_stopAction->setEnabled(started); - m_resetAction->setEnabled(true); + d->m_actions.stopAction->setEnabled(started); + d->m_actions.resetAction->setEnabled(true); - m_stepAction->setEnabled(ready); - m_stepOutAction->setEnabled(ready); - m_runToLineAction->setEnabled(ready); - m_runToFunctionAction->setEnabled(ready); - m_jumpToLineAction->setEnabled(ready); - m_nextAction->setEnabled(ready); + d->m_actions.stepAction->setEnabled(ready); + d->m_actions.stepOutAction->setEnabled(ready); + d->m_actions.runToLineAction->setEnabled(ready); + d->m_actions.runToFunctionAction->setEnabled(ready); + d->m_actions.jumpToLineAction->setEnabled(ready); + d->m_actions.nextAction->setEnabled(ready); //showStatusMessage(QString("started: %1, running: %2") // .arg(started).arg(running)); - emit stateChanged(m_state); + emit stateChanged(d->m_state); const bool notbusy = ready || state == DebuggerNotReady; setBusyCursor(!notbusy); } @@ -1599,12 +1703,11 @@ void IDebuggerEngine::setState(DebuggerState state) void DebuggerManager::runTest(const QString &fileName) { - m_startParameters->executable = fileName; - m_startParameters->processArgs = QStringList() << "--run-debuggee"; - m_startParameters->workingDir.clear(); + d->m_startParameters->executable = fileName; + d->m_startParameters->processArgs = QStringList() << "--run-debuggee"; + d->m_startParameters->workingDir.clear(); //startNewDebugger(StartInternal); } -} // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index 92c0c9bc9dfcbc6b4fe895cd1e79c4d2b2b4d8e4..6b3fde9732323222dfbf0125adc1c963629c9ffc 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -30,31 +30,29 @@ #ifndef DEBUGGER_DEBUGGERMANAGER_H #define DEBUGGER_DEBUGGERMANAGER_H +#include "debugger_global.h" #include "debuggerconstants.h" -#include <utils/fancymainwindow.h> - -#include <QtCore/QByteArray> #include <QtCore/QObject> +#include <QtCore/QSharedPointer> #include <QtCore/QStringList> #include <QtCore/QVariant> -#include <QtCore/QSharedPointer> QT_BEGIN_NAMESPACE class QAction; -class QAbstractItemModel; class QDockWidget; class QLabel; -class QMessageBox; -class QModelIndex; -class QPoint; -class QTimer; -class QWidget; class QDebug; +class QAbstractItemModel; +class QPoint; +class QVariant; QT_END_NAMESPACE namespace Core { class IOptionsPage; +namespace Utils { +class FancyMainWindow; +} } // namespace Core namespace TextEditor { @@ -64,15 +62,8 @@ class ITextEditor; namespace Debugger { namespace Internal { -typedef QLatin1Char _c; -typedef QLatin1String __; -inline QString _(const char *s) { return QString::fromLatin1(s); } -inline QString _(const QByteArray &ba) { return QString::fromLatin1(ba, ba.size()); } - class DebuggerOutputWindow; -class DebuggerRunControl; class DebuggerPlugin; -class DebugMode; class BreakHandler; class BreakpointData; @@ -85,8 +76,23 @@ class Symbol; class ThreadsHandler; class WatchData; class WatchHandler; +class IDebuggerEngine; +class GdbEngine; +class ScriptEngine; +class CdbDebugEngine; +struct CdbDebugEnginePrivate; +struct DebuggerManagerActions; +class DebuggerPlugin; +class CdbDebugEventCallback; +class CdbDumperHelper; +class CdbExceptionLoggerEventCallback; +class GdbEngine; +class TcfEngine; +class CdbDebugEngine; +struct CdbDebugEnginePrivate; +} // namespace Internal -class DebuggerStartParameters +class DEBUGGER_EXPORT DebuggerStartParameters { public: DebuggerStartParameters(); @@ -113,13 +119,8 @@ public: }; typedef QSharedPointer<DebuggerStartParameters> DebuggerStartParametersPtr; -QDebug operator<<(QDebug str, const DebuggerStartParameters &); -class IDebuggerEngine; -class GdbEngine; -class ScriptEngine; -class CdbDebugEngine; -struct CdbDebugEnginePrivate; +DEBUGGER_EXPORT QDebug operator<<(QDebug str, const DebuggerStartParameters &); // Flags for initialization enum DebuggerEngineTypeFlags @@ -140,7 +141,9 @@ QDebug operator<<(QDebug d, DebuggerState state); // DebuggerManager // -class DebuggerManager : public QObject +struct DebuggerManagerPrivate; + +class DEBUGGER_EXPORT DebuggerManager : public QObject { Q_OBJECT @@ -148,26 +151,30 @@ public: DebuggerManager(); ~DebuggerManager(); - friend class CdbDebugEngine; - friend class CdbDebugEventCallback; - friend class CdbDumperHelper; - friend class CdbExceptionLoggerEventCallback; - friend class GdbEngine; - friend class ScriptEngine; - friend class TcfEngine; - friend struct CdbDebugEnginePrivate; + friend class Internal::IDebuggerEngine; + friend class Internal::DebuggerPlugin; + friend class Internal::CdbDebugEventCallback; + friend class Internal::CdbDumperHelper; + friend class Internal::CdbExceptionLoggerEventCallback; + friend class Internal::GdbEngine; + friend class Internal::ScriptEngine; + friend class Internal::TcfEngine; + friend class Internal::CdbDebugEngine; + friend struct Internal::CdbDebugEnginePrivate; QList<Core::IOptionsPage*> initializeEngines(unsigned enabledTypeFlags); - Core::Utils::FancyMainWindow *mainWindow() const { return m_mainWindow; } - QLabel *statusLabel() const { return m_statusLabel; } - IDebuggerEngine *currentEngine() const { return m_engine; } + Core::Utils::FancyMainWindow *mainWindow() const; + QLabel *statusLabel() const; + Internal::IDebuggerEngine *currentEngine() const; - virtual DebuggerStartParametersPtr startParameters() const; - virtual qint64 inferiorPid() const; + DebuggerStartParametersPtr startParameters() const; + qint64 inferiorPid() const; void showMessageBox(int icon, const QString &title, const QString &text); + static DebuggerManager *instance(); + public slots: void startNewDebugger(const DebuggerStartParametersPtr &sp); void exitDebugger(); @@ -177,7 +184,7 @@ public slots: void setBusyCursor(bool on); void queryCurrentTextEditor(QString *fileName, int *lineNumber, QObject **ed); - void gotoLocation(const StackFrame &frame, bool setLocationMarker); + void gotoLocation(const Debugger::Internal::StackFrame &frame, bool setLocationMarker); void fileOpen(const QString &file); void resetLocation(); @@ -200,7 +207,7 @@ public slots: void detachDebugger(); void addToWatchWindow(); - void updateWatchData(const WatchData &data); + void updateWatchData(const Debugger::Internal::WatchData &data); void sessionLoaded(); void aboutToUnloadSession(); @@ -243,14 +250,15 @@ private slots: void startFailed(); private: - ModulesHandler *modulesHandler() { return m_modulesHandler; } - BreakHandler *breakHandler() { return m_breakHandler; } - RegisterHandler *registerHandler() { return m_registerHandler; } - StackHandler *stackHandler() { return m_stackHandler; } - ThreadsHandler *threadsHandler() { return m_threadsHandler; } - WatchHandler *watchHandler() { return m_watchHandler; } - SourceFilesWindow *sourceFileWindow() { return m_sourceFilesWindow; } - QWidget *threadsWindow() const { return m_threadsWindow; } + Internal::ModulesHandler *modulesHandler() const; + Internal::BreakHandler *breakHandler() const; + Internal::RegisterHandler *registerHandler() const; + Internal::StackHandler *stackHandler() const; + Internal::ThreadsHandler *threadsHandler() const; + Internal::WatchHandler *watchHandler() const; + Internal::SourceFilesWindow *sourceFileWindow() const; + QWidget *threadsWindow() const; + Internal::DebuggerManagerActions debuggerManagerActions() const; void notifyInferiorStopped(); void notifyInferiorRunning(); @@ -261,7 +269,6 @@ private: DebuggerState state() const; void setState(DebuggerState state); - DebuggerState m_state; // // internal implementation @@ -280,8 +287,7 @@ private: public: // stuff in this block should be made private by moving it to // one of the interfaces - int status() const { return m_status; } - QList<Symbol> moduleSymbols(const QString &moduleName); + QList<Internal::Symbol> moduleSymbols(const QString &moduleName); signals: void debuggingFinished(); @@ -290,7 +296,7 @@ signals: void debugModeRequested(); void previousModeRequested(); void statusMessageRequested(const QString &msg, int timeout); // -1 for 'forever' - void gotoLocationRequested(const StackFrame &frame, bool setLocationMarker); + void gotoLocationRequested(const Debugger::Internal::StackFrame &frame, bool setLocationMarker); void resetLocationRequested(); void currentTextEditorRequested(QString *fileName, int *lineNumber, QObject **ob); void sessionValueRequested(const QString &name, QVariant *value); @@ -308,71 +314,13 @@ private: void toggleBreakpoint(const QString &fileName, int lineNumber); void toggleBreakpointEnabled(const QString &fileName, int lineNumber); - BreakpointData *findBreakpoint(const QString &fileName, int lineNumber); + Internal::BreakpointData *findBreakpoint(const QString &fileName, int lineNumber); void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); - // FIXME: Remove engine-specific state - DebuggerStartParametersPtr m_startParameters; - qint64 m_inferiorPid; - - - /// Views - Core::Utils::FancyMainWindow *m_mainWindow; - QLabel *m_statusLabel; - QDockWidget *m_breakDock; - QDockWidget *m_modulesDock; - QDockWidget *m_outputDock; - QDockWidget *m_registerDock; - QDockWidget *m_stackDock; - QDockWidget *m_sourceFilesDock; - QDockWidget *m_threadsDock; - QDockWidget *m_watchDock; - - BreakHandler *m_breakHandler; - ModulesHandler *m_modulesHandler; - RegisterHandler *m_registerHandler; - StackHandler *m_stackHandler; - ThreadsHandler *m_threadsHandler; - WatchHandler *m_watchHandler; - SourceFilesWindow *m_sourceFilesWindow; - - /// Actions - friend class DebuggerPlugin; - friend class IDebuggerEngine; - QAction *m_continueAction; - QAction *m_stopAction; - QAction *m_resetAction; // FIXME: Should not be needed in a stable release - QAction *m_stepAction; - QAction *m_stepOutAction; - QAction *m_runToLineAction; - QAction *m_runToFunctionAction; - QAction *m_jumpToLineAction; - QAction *m_nextAction; - QAction *m_watchAction; - QAction *m_breakAction; - QAction *m_sepAction; - QAction *m_reverseDirectionAction; - - QWidget *m_breakWindow; - QWidget *m_localsWindow; - QWidget *m_registerWindow; - QWidget *m_modulesWindow; - QWidget *m_stackWindow; - QWidget *m_threadsWindow; - QWidget *m_watchersWindow; - DebuggerOutputWindow *m_outputWindow; - - int m_status; - bool m_busy; - QTimer *m_statusTimer; - QString m_lastPermanentStatusMessage; - - IDebuggerEngine *engine(); - IDebuggerEngine *m_engine; + DebuggerManagerPrivate *d; }; -} // namespace Internal } // namespace Debugger #endif // DEBUGGER_DEBUGGERMANAGER_H diff --git a/src/plugins/debugger/debuggeroutputwindow.cpp b/src/plugins/debugger/debuggeroutputwindow.cpp index 54e1b1b141f7871e4e595df1afe5d2f60a1d3faf..b248c95b1b5bccc417ff0182c53e481921a0d1a3 100644 --- a/src/plugins/debugger/debuggeroutputwindow.cpp +++ b/src/plugins/debugger/debuggeroutputwindow.cpp @@ -55,6 +55,7 @@ using namespace Find; #endif // GDBDEBUGGERLEAN +using namespace Debugger; using namespace Debugger::Internal; static QChar charForChannel(int channel) diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 24a0da228009bef2edc88170ea9c924be7856303..03eebb88ba916edc2fc22cb24ef418007fb25672 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -37,6 +37,7 @@ #include "debuggermanager.h" #include "debuggerrunner.h" #include "stackframe.h" +#include "debuggerstringutils.h" #include "ui_commonoptionspage.h" #include "ui_dumperoptionpage.h" @@ -619,7 +620,8 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess am->actionContainer(ProjectExplorer::Constants::M_DEBUG_STARTDEBUGGING); Core::Command *cmd = 0; - cmd = am->registerAction(m_manager->m_continueAction, + const DebuggerManagerActions actions = m_manager->debuggerManagerActions(); + cmd = am->registerAction(actions.continueAction, ProjectExplorer::Constants::DEBUG, QList<int>() << m_gdbRunningContext); mstart->addAction(cmd, Core::Constants::G_DEFAULT_ONE); @@ -648,7 +650,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess Constants::DETACH, globalcontext); mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); - cmd = am->registerAction(m_manager->m_stopAction, + cmd = am->registerAction(actions.stopAction, Constants::INTERRUPT, globalcontext); cmd->setAttribute(Core::Command::CA_UpdateText); cmd->setAttribute(Core::Command::CA_UpdateIcon); @@ -656,7 +658,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess cmd->setDefaultText(tr("Stop Debugger/Interrupt Debugger")); mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); - cmd = am->registerAction(m_manager->m_resetAction, + cmd = am->registerAction(actions.resetAction, Constants::RESET, globalcontext); cmd->setAttribute(Core::Command::CA_UpdateText); cmd->setDefaultKeySequence(QKeySequence(Constants::RESET_KEY)); @@ -668,17 +670,17 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess cmd = am->registerAction(sep, QLatin1String("Debugger.Sep.Step"), globalcontext); mdebug->addAction(cmd); - cmd = am->registerAction(m_manager->m_nextAction, + cmd = am->registerAction(actions.nextAction, Constants::NEXT, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::NEXT_KEY)); mdebug->addAction(cmd); - cmd = am->registerAction(m_manager->m_stepAction, + cmd = am->registerAction(actions.stepAction, Constants::STEP, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::STEP_KEY)); mdebug->addAction(cmd); - cmd = am->registerAction(m_manager->m_stepOutAction, + cmd = am->registerAction(actions.stepOutAction, Constants::STEPOUT, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::STEPOUT_KEY)); mdebug->addAction(cmd); @@ -687,22 +689,22 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess Constants::STEP_BY_INSTRUCTION, debuggercontext); mdebug->addAction(cmd); - cmd = am->registerAction(m_manager->m_runToLineAction, + cmd = am->registerAction(actions.runToLineAction, Constants::RUN_TO_LINE, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_LINE_KEY)); mdebug->addAction(cmd); - cmd = am->registerAction(m_manager->m_runToFunctionAction, + cmd = am->registerAction(actions.runToFunctionAction, Constants::RUN_TO_FUNCTION, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_FUNCTION_KEY)); mdebug->addAction(cmd); - cmd = am->registerAction(m_manager->m_jumpToLineAction, + cmd = am->registerAction(actions.jumpToLineAction, Constants::JUMP_TO_LINE, debuggercontext); mdebug->addAction(cmd); #ifdef USE_REVERSE_DEBUGGING - cmd = am->registerAction(m_manager->m_reverseDirectionAction, + cmd = am->registerAction(actions.reverseDirectionAction, Constants::REVERSE, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::REVERSE_KEY)); mdebug->addAction(cmd); @@ -713,7 +715,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess cmd = am->registerAction(sep, QLatin1String("Debugger.Sep.Break"), globalcontext); mdebug->addAction(cmd); - cmd = am->registerAction(m_manager->m_breakAction, + cmd = am->registerAction(actions.breakAction, Constants::TOGGLE_BREAK, cppeditorcontext); cmd->setDefaultKeySequence(QKeySequence(Constants::TOGGLE_BREAK_KEY)); mdebug->addAction(cmd); @@ -724,7 +726,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess cmd = am->registerAction(sep, QLatin1String("Debugger.Sep.Watch"), globalcontext); mdebug->addAction(cmd); - cmd = am->registerAction(m_manager->m_watchAction, + cmd = am->registerAction(actions.watchAction, Constants::ADD_TO_WATCH, cppeditorcontext); //cmd->setDefaultKeySequence(QKeySequence(tr("ALT+D,ALT+W"))); mdebug->addAction(cmd); @@ -885,8 +887,8 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess connect(m_manager, SIGNAL(resetLocationRequested()), this, SLOT(resetLocation())); - connect(m_manager, SIGNAL(gotoLocationRequested(StackFrame,bool)), - this, SLOT(gotoLocation(StackFrame,bool))); + connect(m_manager, SIGNAL(gotoLocationRequested(Debugger::Internal::StackFrame,bool)), + this, SLOT(gotoLocation(Debugger::Internal::StackFrame,bool))); connect(m_manager, SIGNAL(stateChanged(int)), this, SLOT(handleStateChanged(int))); connect(m_manager, SIGNAL(previousModeRequested()), @@ -1088,7 +1090,7 @@ void DebuggerPlugin::resetLocation() m_locationMark = 0; } -void DebuggerPlugin::gotoLocation(const StackFrame &frame, bool setMarker) +void DebuggerPlugin::gotoLocation(const Debugger::Internal::StackFrame &frame, bool setMarker) { if (theDebuggerBoolSetting(StepByInstruction) || !frame.isUsable()) { if (!m_disassemblerViewAgent) diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h index a0777d7f284d7d52313cd8c33f7e837d9934b38c..007fbe0fd146e59bbb7d9b92a6cb4d8eaee7ffb4 100644 --- a/src/plugins/debugger/debuggerplugin.h +++ b/src/plugins/debugger/debuggerplugin.h @@ -55,10 +55,11 @@ class BaseTextMark; } namespace Debugger { +class DebuggerManager; + namespace Internal { class BreakpointData; -class DebuggerManager; class DebuggerRunControlFactory; class DebugMode; class DisassemblerViewAgent; @@ -96,7 +97,7 @@ private slots: int lineNumber, QMenu *menu); void resetLocation(); - void gotoLocation(const StackFrame &frame, bool setMarker); + void gotoLocation(const Debugger::Internal::StackFrame &frame, bool setMarker); void breakpointSetRemoveMarginActionTriggered(); void breakpointEnableDisableMarginActionTriggered(); @@ -119,10 +120,10 @@ private: QString *errorMessage); void attachExternalApplication(qint64 pid, const QString &crashParameter = QString()); - friend class DebuggerManager; + friend class Debugger::DebuggerManager; friend class GdbOptionPage; friend class DebuggingHelperOptionPage; - friend class DebugMode; // FIXME: Just a hack now so that it can access the views + friend class Debugger::Internal::DebugMode; // FIXME: Just a hack now so that it can access the views DebuggerManager *m_manager; DebugMode *m_debugMode; diff --git a/src/plugins/debugger/debuggerrunner.h b/src/plugins/debugger/debuggerrunner.h index dcb996afe8306f1887cbb0b62a6a30b55325c698..196d7ee123b7415d7d90ccea6162221d34cf42bd 100644 --- a/src/plugins/debugger/debuggerrunner.h +++ b/src/plugins/debugger/debuggerrunner.h @@ -40,9 +40,9 @@ class LocalApplicationRunConfiguration; } namespace Debugger { -namespace Internal { - class DebuggerManager; + +namespace Internal { class StartData; typedef QSharedPointer<ProjectExplorer::RunConfiguration> diff --git a/src/plugins/debugger/debuggerstringutils.h b/src/plugins/debugger/debuggerstringutils.h new file mode 100644 index 0000000000000000000000000000000000000000..bfa426c3472898fad80a39f8b661a371c239c9e6 --- /dev/null +++ b/src/plugins/debugger/debuggerstringutils.h @@ -0,0 +1,45 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef DEBUGGERSTRINGUTILS_H +#define DEBUGGERSTRINGUTILS_H + +#include <QtCore/QString> + +namespace Debugger { +namespace Internal { + +typedef QLatin1Char _c; +typedef QLatin1String __; +inline QString _(const char *s) { return QString::fromLatin1(s); } +inline QString _(const QByteArray &ba) { return QString::fromLatin1(ba, ba.size()); } + +} // namespace Internal +} // namespace Debugger +#endif // DEBUGGERSTRINGUTILS_H diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp index d0f7f6366936ed4de881694cf3dc44f573c85cf7..75757dc45ffc1748895d0f4f51048457e0900238 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.cpp +++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp @@ -32,6 +32,7 @@ #include "debuggeractions.h" #include "gdbengine.h" #include "procinterrupt.h" +#include "debuggerstringutils.h" #include <utils/qtcassert.h> diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp index a923335abb3760cdb2ab6bb49684689fe9e38977..3eda30cef03e07cfe3fac52e200d2b4ffac715bc 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.cpp +++ b/src/plugins/debugger/gdb/coregdbadapter.cpp @@ -31,6 +31,7 @@ #include "debuggeractions.h" #include "gdbengine.h" +#include "debuggerstringutils.h" #include <utils/qtcassert.h> diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 4e0578c66c8fb118a70eea9f2893668232c93933..898a746af9364cb39d4c002e65008c81c4e8066a 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -46,6 +46,7 @@ #include "debuggerconstants.h" #include "debuggermanager.h" #include "debuggertooltip.h" +#include "debuggerstringutils.h" #include "gdbmi.h" #include "breakhandler.h" @@ -58,6 +59,7 @@ #include "debuggerdialogs.h" #include <utils/qtcassert.h> +#include <utils/fancymainwindow.h> #include <texteditor/itexteditor.h> #include <coreplugin/icore.h> @@ -224,6 +226,11 @@ DebuggerStartMode GdbEngine::startMode() const return m_startParameters->startMode; } +QMainWindow *GdbEngine::mainWindow() const +{ + return m_manager->mainWindow(); +} + GdbEngine::~GdbEngine() { // prevent sending error messages afterwards @@ -783,15 +790,22 @@ void GdbEngine::handleResultRecord(const GdbResponse &response) // In theory this should not happen, in practice it does. debugMessage(_("COOKIE FOR TOKEN %1 ALREADY EATEN. " "TWO RESPONSES FOR ONE COMMAND?").arg(token)); - // Handle a case known to occur on Linux/gdb 6.8 when debugging moc - // with helpers enabled. In this case we get a second response with - // msg="Cannot find new threads: generic error" if (response.resultClass == GdbResultError) { QByteArray msg = response.data.findChild("msg").data(); showMessageBox(QMessageBox::Critical, tr("Executable failed"), QString::fromLocal8Bit(msg)); showStatusMessage(tr("Process failed to start.")); - shutdown(); + // Handle a case known to occur on Linux/gdb 6.8 when debugging moc + // with helpers enabled. In this case we get a second response with + // msg="Cannot find new threads: generic error" + if (msg == "Cannot find new threads: generic error") + shutdown(); + // Handle a case known to appear on gdb 6.4 symbianelf when + // the stack is cut due to access to protected memory. + if (msg == "\"finish\" not meaningful in the outermost frame.") { + setState(InferiorStopping); + setState(InferiorStopped); + } } return; } @@ -1303,6 +1317,11 @@ void GdbEngine::handleStop2(const GdbResponse &response) void GdbEngine::handleStop2(const GdbMi &data) { + if (state() == InferiorRunning) { + // Stop triggered by a breakpoint or otherwise not directly + // initiated by the user. + setState(InferiorStopping); + } setState(InferiorStopped); showStatusMessage(tr("Stopped."), 5000); @@ -3808,7 +3827,7 @@ struct MemoryAgentCookie MemoryAgentCookie(MemoryViewAgent *agent_, quint64 address_) : agent(agent_), address(address_) {} - MemoryViewAgent *agent; + QPointer<MemoryViewAgent> agent; quint64 address; }; @@ -3851,7 +3870,7 @@ struct DisassemblerAgentCookie DisassemblerAgentCookie(DisassemblerViewAgent *agent_) : agent(agent_) {} - DisassemblerViewAgent *agent; + QPointer<DisassemblerViewAgent> agent; }; void GdbEngine::fetchDisassembler(DisassemblerViewAgent *agent, diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index d67864bd14f3f9ff791eb94ffa37cd11841d1198..6bfc7444fb04b812f6b0e9fcddffd89d0570fbc9 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -51,14 +51,14 @@ QT_BEGIN_NAMESPACE class QAction; class QAbstractItemModel; class QWidget; +class QMainWindow; QT_END_NAMESPACE namespace Debugger { +class DebuggerManager; namespace Internal { class AbstractGdbAdapter; -class DebuggerManager; -class IDebuggerManagerAccessForEngines; class GdbResponse; class GdbMi; @@ -271,7 +271,7 @@ private: bool showToolTip(); // Convenience - QMainWindow *mainWindow() const { return m_manager->mainWindow(); } + QMainWindow *mainWindow() const; DebuggerStartMode startMode() const; qint64 inferiorPid() const { return m_manager->inferiorPid(); } diff --git a/src/plugins/debugger/gdb/plaingdbadapter.cpp b/src/plugins/debugger/gdb/plaingdbadapter.cpp index 9075dadea43e76d59c91e82e3b6fa6799d35f1ca..d7765e58cc11b39c6868190b3f3d73734ab34b21 100644 --- a/src/plugins/debugger/gdb/plaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/plaingdbadapter.cpp @@ -32,11 +32,14 @@ #include "debuggeractions.h" #include "gdbengine.h" #include "procinterrupt.h" +#include "debuggerstringutils.h" #include <utils/qtcassert.h> +#include <utils/fancymainwindow.h> #include <coreplugin/icore.h> #include <QtCore/QFileInfo> +#include <QtCore/QVariant> #include <QtGui/QMessageBox> namespace Debugger { diff --git a/src/plugins/debugger/gdb/remotegdbadapter.cpp b/src/plugins/debugger/gdb/remotegdbadapter.cpp index 656a08ee4738015718d8a24b16ce7e8cb523c715..842f08daaa2974818976dd05b868e9da7850daa3 100644 --- a/src/plugins/debugger/gdb/remotegdbadapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbadapter.cpp @@ -28,11 +28,12 @@ **************************************************************************/ #include "remotegdbadapter.h" - +#include "debuggerstringutils.h" #include "debuggeractions.h" #include "gdbengine.h" #include <utils/qtcassert.h> +#include <utils/fancymainwindow.h> #include <QtCore/QFileInfo> #include <QtGui/QMessageBox> diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 0b48483bc442d2b682a50a8d7018a7154829bd20..daaa4fa066c045950b8a5b209bbeeb883b8fd1de 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -29,6 +29,7 @@ #include "trkgdbadapter.h" #include "trkoptions.h" +#include "debuggerstringutils.h" #ifndef STANDALONE_RUNNER #include "gdbengine.h" #endif @@ -199,7 +200,7 @@ QByteArray TrkGdbAdapter::trkContinueMessage() return ba; } -QByteArray TrkGdbAdapter::trkReadRegisterMessage() +QByteArray TrkGdbAdapter::trkReadRegistersMessage() { QByteArray ba; appendByte(&ba, 0); // Register set, only 0 supported @@ -210,6 +211,18 @@ QByteArray TrkGdbAdapter::trkReadRegisterMessage() return ba; } +QByteArray TrkGdbAdapter::trkWriteRegisterMessage(byte reg, uint value) +{ + QByteArray ba; + appendByte(&ba, 0); // ? + appendShort(&ba, reg); + appendShort(&ba, reg); + appendInt(&ba, m_session.pid); + appendInt(&ba, m_session.tid); + appendInt(&ba, value); + return ba; +} + QByteArray TrkGdbAdapter::trkReadMemoryMessage(uint addr, uint len) { QByteArray ba; @@ -574,6 +587,7 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd) sendGdbServerMessage("E20", "Error " + cmd); } } + else if (cmd.startsWith("p")) { logMessage(msgGdbPacket(QLatin1String("read register"))); // 0xf == current instruction pointer? @@ -599,6 +613,21 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd) } } + else if (cmd.startsWith("P")) { + logMessage(msgGdbPacket(QLatin1String("write register"))); + // $Pe=70f96678#d3 + sendGdbServerAck(); + int pos = cmd.indexOf('='); + QByteArray regName = cmd.mid(1, pos - 1); + QByteArray valueName = cmd.mid(pos + 1); + bool ok = false; + const uint registerNumber = regName.toInt(&ok, 16); + const uint value = swapEndian(valueName.toInt(&ok, 16)); + QByteArray ba = trkWriteRegisterMessage(registerNumber, value); + sendTrkMessage(0x13, TrkCB(handleWriteRegister), ba, "Write register"); + // Note that App TRK refuses to write registers 13 and 14 + } + else if (cmd == "qAttached") { //$qAttached#8f // 1: attached to an existing process @@ -861,7 +890,7 @@ void TrkGdbAdapter::handleTrkResult(const TrkResult &result) //sendGdbServerMessage("S05", "Target stopped"); sendTrkMessage(0x12, TrkCB(handleAndReportReadRegistersAfterStop), - trkReadRegisterMessage()); + trkReadRegistersMessage()); break; } case 0x91: { // Notify Exception (obsolete) @@ -1020,6 +1049,17 @@ void TrkGdbAdapter::handleReadRegisters(const TrkResult &result) m_snapshot.registers[i] = extractInt(data + 4 * i); } +void TrkGdbAdapter::handleWriteRegister(const TrkResult &result) +{ + logMessage(" RESULT: " + result.toString() + result.cookie.toString()); + if (result.errorCode()) { + logMessage("ERROR: " + result.errorString()); + sendGdbServerMessage("E01"); + return; + } + sendGdbServerMessage("OK"); +} + void TrkGdbAdapter::reportRegisters() { QByteArray ba; diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h index a29c368c7b50bae7c2198d8e48cac862be03aece..fb8420446fd46f27401cdbeebb96e3b8ace5336f 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.h +++ b/src/plugins/debugger/gdb/trkgdbadapter.h @@ -156,7 +156,8 @@ public: void reportRegisters(); QByteArray memoryReadLogMessage(uint addr, uint len, const QByteArray &ba) const; QByteArray trkContinueMessage(); - QByteArray trkReadRegisterMessage(); + QByteArray trkReadRegistersMessage(); + QByteArray trkWriteRegisterMessage(byte reg, uint value); QByteArray trkReadMemoryMessage(uint addr, uint len); QByteArray trkBreakpointMessage(uint addr, uint len, bool armMode = true); QByteArray trkStepRangeMessage(byte option); @@ -169,6 +170,7 @@ public: void handleStepOver2(const TrkResult &result); void handleReadRegisters(const TrkResult &result); void reportReadMemoryBuffered(const TrkResult &result); + void handleWriteRegister(const TrkResult &result); void reportToGdb(const TrkResult &result); void readMemory(uint addr, uint len); diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h index d204dc5f6faf919b94f2ad60bbbc018c1505a0ef..db990fa9389b98feb7a311b3eaf3a948104c12b6 100644 --- a/src/plugins/debugger/idebuggerengine.h +++ b/src/plugins/debugger/idebuggerengine.h @@ -50,22 +50,23 @@ class IOptionsPage; } namespace Debugger { +class DebuggerManager; +class DebuggerStartParameters; namespace Internal { -class DebuggerStartParameters; -class DebuggerManager; class DisassemblerViewAgent; class MemoryViewAgent; struct StackFrame; class Symbol; class WatchData; -typedef QSharedPointer<DebuggerStartParameters> DebuggerStartParametersPtr; class IDebuggerEngine : public QObject { Q_OBJECT public: + typedef QSharedPointer<DebuggerStartParameters> DebuggerStartParametersPtr; + IDebuggerEngine(DebuggerManager *manager, QObject *parent = 0) : QObject(parent), m_manager(manager) {} diff --git a/src/plugins/debugger/moduleswindow.h b/src/plugins/debugger/moduleswindow.h index 3c8505076f8d115ed934452ad5cc1284614ca226..4114cddf5ca8aba497b4d2138aa2306e373b965a 100644 --- a/src/plugins/debugger/moduleswindow.h +++ b/src/plugins/debugger/moduleswindow.h @@ -33,10 +33,10 @@ #include <QTreeView> namespace Debugger { -namespace Internal { - class DebuggerManager; +namespace Internal { + class ModulesWindow : public QTreeView { Q_OBJECT diff --git a/src/plugins/debugger/registerwindow.h b/src/plugins/debugger/registerwindow.h index f29283f3b5422e378ffebeb5e8ad9fac87185f1a..394a1ca3c916078c816ea1b42cfdc8f110f2dbe4 100644 --- a/src/plugins/debugger/registerwindow.h +++ b/src/plugins/debugger/registerwindow.h @@ -30,13 +30,12 @@ #ifndef DEBUGGER_REGISTERWINDOW_H #define DEBUGGER_REGISTERWINDOW_H -#include <QTreeView> +#include <QtGui/QTreeView> namespace Debugger { -namespace Internal { - class DebuggerManager; +namespace Internal { class RegisterWindow : public QTreeView { Q_OBJECT diff --git a/src/plugins/debugger/stackwindow.h b/src/plugins/debugger/stackwindow.h index 2703735420ee045a046b3981b192da4c10a87a30..52390bcc342b89639c3693083f7add52f8c05fc2 100644 --- a/src/plugins/debugger/stackwindow.h +++ b/src/plugins/debugger/stackwindow.h @@ -39,9 +39,9 @@ class QModelIndex; QT_END_NAMESPACE namespace Debugger { -namespace Internal { - class DebuggerManager; + +namespace Internal { class DisassemblerViewAgent; class StackWindow : public QTreeView diff --git a/src/plugins/debugger/tcf/tcfengine.cpp b/src/plugins/debugger/tcf/tcfengine.cpp index e274102d75a1c1193c88ee505e415586bac36e92..760bc49d9ce71128fd5fdcdb78c6766906bb8f2d 100644 --- a/src/plugins/debugger/tcf/tcfengine.cpp +++ b/src/plugins/debugger/tcf/tcfengine.cpp @@ -29,6 +29,7 @@ #include "tcfengine.h" +#include "debuggerstringutils.h" #include "debuggerdialogs.h" #include "breakhandler.h" #include "debuggerconstants.h" diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 8f6590484b92f33fc46b0576599114ea68ae4546..285f004d8f017afb05fee790b5756384a1a2e1a6 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -262,7 +262,7 @@ public: static QString watcherEditPlaceHolder(); signals: - void watchDataUpdateNeeded(const WatchData &data); + void watchDataUpdateNeeded(const Debugger::Internal::WatchData &data); void sessionValueRequested(const QString &name, QVariant *value); void setSessionValueRequested(const QString &name, const QVariant &value); diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index edb3c9bbaf8aadd2cb2515116e7bffd207a6445a..707126fa197c6e7bedba3dd8972199399e6051c9 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -33,6 +33,7 @@ #include "debuggeractions.h" #include "debuggeragents.h" #include "debuggerdialogs.h" +#include "debuggermanager.h" #include <utils/qtcassert.h> @@ -50,6 +51,7 @@ #include <QtGui/QMenu> #include <QtGui/QResizeEvent> +using namespace Debugger; using namespace Debugger::Internal; ///////////////////////////////////////////////////////////////////// diff --git a/src/plugins/debugger/watchwindow.h b/src/plugins/debugger/watchwindow.h index 582ffdcd6fab1fb5e5d0d33462c466f6f469caee..3e497e6895ef1ce3e4add742e9505d30a7cdc2f5 100644 --- a/src/plugins/debugger/watchwindow.h +++ b/src/plugins/debugger/watchwindow.h @@ -33,6 +33,8 @@ #include <QtGui/QTreeView> namespace Debugger { +class DebuggerManager; + namespace Internal { ///////////////////////////////////////////////////////////////////// @@ -41,8 +43,6 @@ namespace Internal { // ///////////////////////////////////////////////////////////////////// -class DebuggerManager; - class WatchWindow : public QTreeView { Q_OBJECT diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index b0741ce867a92155b57e8e7d3e8bbab96f91d62f..0324e1b7c80f8d288543cdc4420b60c8569976a2 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -129,7 +129,6 @@ GitPlugin::GitPlugin() : m_showAction(0), m_stageAction(0), m_unstageAction(0), - m_revertAction(0), m_commitAction(0), m_pullAction(0), m_pushAction(0), @@ -298,12 +297,6 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) connect(m_unstageAction, SIGNAL(triggered()), this, SLOT(unstageFile())); gitContainer->addAction(command); - m_revertAction = new Core::Utils::ParameterAction(tr("Revert..."), tr("Revert \"%1\"..."), Core::Utils::ParameterAction::AlwaysEnabled, this); - command = actionManager->registerAction(m_revertAction, "Git.Revert", globalcontext); - command->setAttribute(Core::Command::CA_UpdateText); - connect(m_revertAction, SIGNAL(triggered()), this, SLOT(revertFile())); - gitContainer->addAction(command); - gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Project"), this)); m_diffProjectAction = new Core::Utils::ParameterAction(tr("Diff Current Project"), tr("Diff Project \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this); @@ -756,7 +749,6 @@ void GitPlugin::updateActions() m_undoFileAction->setParameter(fileName); m_stageAction->setParameter(fileName); m_unstageAction->setParameter(fileName); - m_revertAction->setParameter(fileName); bool enabled = !fileName.isEmpty() && !repository.isEmpty(); m_diffAction->setEnabled(enabled); @@ -766,7 +758,6 @@ void GitPlugin::updateActions() m_undoFileAction->setEnabled(enabled); m_stageAction->setEnabled(enabled); m_unstageAction->setEnabled(enabled); - m_revertAction->setEnabled(enabled); if (repository.isEmpty()) { // If the file is not in a repository, the corresponding project will diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index bf3eb3e28ff7ec81d05b3b014fde03e0110e98d9..116d8f6638bb120ef77bac5bb18fb1ac4477fa7a 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -145,7 +145,6 @@ private: QAction *m_showAction; Core::Utils::ParameterAction *m_stageAction; Core::Utils::ParameterAction *m_unstageAction; - Core::Utils::ParameterAction *m_revertAction; QAction *m_commitAction; QAction *m_pullAction; QAction *m_pushAction; diff --git a/src/plugins/qt4projectmanager/profilereader.cpp b/src/plugins/qt4projectmanager/profilereader.cpp index 76c78138866c5968f2f397e5aa8261431723ea3d..333f43ff27a398f892f3d673a06a0fd8ead4575a 100644 --- a/src/plugins/qt4projectmanager/profilereader.cpp +++ b/src/plugins/qt4projectmanager/profilereader.cpp @@ -122,9 +122,5 @@ void ProFileReader::errorMessage(const QString &message) ProFile *ProFileReader::proFileFor(const QString &name) { - QMap<QString, ProFile *>::const_iterator it = m_includeFiles.constFind(name); - if (it == m_includeFiles.constEnd()) - return 0; - else - return it.value(); + return m_includeFiles.value(name); } diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp index fc1000f38e101e7b2896d4b1938c3f277f178985..88f2c344149e44bfc2042c3a64788294ee7a4a18 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp @@ -644,6 +644,7 @@ void S60DeviceRunControl::signsisProcessFinished() connect(m_launcher, SIGNAL(installingStarted()), this, SLOT(printInstallingNotice())); connect(m_launcher, SIGNAL(startingApplication()), this, SLOT(printStartingNotice())); connect(m_launcher, SIGNAL(applicationRunning(uint)), this, SLOT(printRunNotice(uint))); + connect(m_launcher, SIGNAL(canNotRun(QString)), this, SLOT(printRunFailNotice(QString))); connect(m_launcher, SIGNAL(applicationOutputReceived(QString)), this, SLOT(printApplicationOutput(QString))); connect(m_launcher, SIGNAL(copyProgress(int)), this, SLOT(printCopyProgress(int))); @@ -692,6 +693,10 @@ void S60DeviceRunControl::printRunNotice(uint pid) emit addToOutputWindow(this, tr("Application running with pid %1.").arg(pid)); } +void S60DeviceRunControl::printRunFailNotice(const QString &errorMessage) { + emit addToOutputWindow(this, tr("Could not start application: %1").arg(errorMessage)); +} + void S60DeviceRunControl::printApplicationOutput(const QString &output) { emit addToOutputWindowInline(this, output); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h index 626b9625148a0f2b64617759416866a364a55853..5ac7e7be091ae3f681ffdd21019be046cfb8b8df 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h @@ -164,6 +164,7 @@ private slots: void printInstallingNotice(); void printStartingNotice(); void printRunNotice(uint pid); + void printRunFailNotice(const QString &errorMessage); void printApplicationOutput(const QString &output); void runFinished(); diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 6592506d57b6751989fcb1a6a366e8e97b69c13f..c38f4df4334d67a07187dffa677504eacb99d8fa 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -1528,6 +1528,18 @@ int TextBlockUserData::collapseAtPos() const return Parenthesis::collapseAtPos(m_parentheses); } +int TextBlockUserData::braceDepthDelta() const +{ + int delta = 0; + for (int i = 0; i < m_parentheses.size(); ++i) { + switch (m_parentheses.at(i).chr.unicode()) { + case '{': case '+': ++delta; break; + case '}': case '-': --delta; break; + default: break; + } + } + return delta; +} void TextEditDocumentLayout::setParentheses(const QTextBlock &block, const Parentheses &parentheses) { @@ -1553,6 +1565,35 @@ bool TextEditDocumentLayout::hasParentheses(const QTextBlock &block) return false; } +int TextEditDocumentLayout::braceDepthDelta(const QTextBlock &block) +{ + if (TextBlockUserData *userData = testUserData(block)) + return userData->braceDepthDelta(); + return 0; +} + +int TextEditDocumentLayout::braceDepth(const QTextBlock &block) +{ + int state = block.userState(); + if (state == -1) + return 0; + return state >> 8; +} + +void TextEditDocumentLayout::setBraceDepth(QTextBlock &block, int depth) +{ + int state = block.userState(); + if (state == -1) + state = 0; + state = state & 0xff; + block.setUserState((depth << 8) | state); +} + +void TextEditDocumentLayout::changeBraceDepth(QTextBlock &block, int delta) +{ + if (delta) + setBraceDepth(block, braceDepth(block) + delta); +} bool TextEditDocumentLayout::setIfdefedOut(const QTextBlock &block) { @@ -2683,6 +2724,11 @@ void BaseTextEditor::updateCurrentLineHighlight() void BaseTextEditor::slotCursorPositionChanged() { +#if 0 + qDebug() << "block" << textCursor().blockNumber()+1 + << "depth:" << TextEditDocumentLayout::braceDepth(textCursor().block()) + << "/" << TextEditDocumentLayout::braceDepth(document()->lastBlock()); +#endif if (!d->m_contentsChanged && d->m_lastCursorChangeWasInteresting) { Core::EditorManager::instance()->addCurrentPositionToNavigationHistory(editableInterface(), d->m_tempNavigationState); d->m_lastCursorChangeWasInteresting = false; @@ -4026,21 +4072,36 @@ void BaseTextEditor::setIfdefedOutBlocks(const QList<BaseTextEditor::BlockRange> QTextBlock block = doc->firstBlock(); int rangeNumber = 0; + int braceDepthDelta = 0; while (block.isValid()) { + bool cleared = false; + bool set = false; if (rangeNumber < blocks.size()) { const BlockRange &range = blocks.at(rangeNumber); if (block.position() >= range.first && (block.position() <= range.last || !range.last)) { - needUpdate |= TextEditDocumentLayout::setIfdefedOut(block); + set = TextEditDocumentLayout::setIfdefedOut(block); } else { - needUpdate |= TextEditDocumentLayout::clearIfdefedOut(block); + cleared = TextEditDocumentLayout::clearIfdefedOut(block); } if (block.contains(range.last)) ++rangeNumber; } else { - needUpdate |= TextEditDocumentLayout::clearIfdefedOut(block); + cleared = TextEditDocumentLayout::clearIfdefedOut(block); } + if (cleared || set) { + needUpdate = true; + int delta = TextEditDocumentLayout::braceDepthDelta(block); + if (cleared) + braceDepthDelta += delta; + else if (set) + braceDepthDelta -= delta; + } + + if (braceDepthDelta) + TextEditDocumentLayout::changeBraceDepth(block,braceDepthDelta); + block = block.next(); } diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 2466fe7f4a4bf425f6ff16278fa8d889434c50f8..ab2a6ec27634d9a230abe3d724b5e9d45b4ea6dc 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -128,6 +128,7 @@ public: inline void clearParentheses() { m_parentheses.clear(); } inline const Parentheses &parentheses() const { return m_parentheses; } inline bool hasParentheses() const { return !m_parentheses.isEmpty(); } + int braceDepthDelta() const; inline bool setIfdefedOut() { bool result = m_ifdefedOut; m_ifdefedOut = true; return !result; } inline bool clearIfdefedOut() { bool result = m_ifdefedOut; m_ifdefedOut = false; return result;} @@ -215,6 +216,10 @@ public: static bool setIfdefedOut(const QTextBlock &block); static bool clearIfdefedOut(const QTextBlock &block); static bool ifdefedOut(const QTextBlock &block); + static int braceDepthDelta(const QTextBlock &block); + static int braceDepth(const QTextBlock &block); + static void setBraceDepth(QTextBlock &block, int depth); + static void changeBraceDepth(QTextBlock &block, int delta); static TextBlockUserData *testUserData(const QTextBlock &block) { return static_cast<TextBlockUserData*>(block.userData()); diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp index 65d66be020710fac31659c81f73dce7a6e2787cc..69e645b1be981c3f5815fe8b5e5a49ca0d44253f 100644 --- a/src/shared/cplusplus/CheckDeclaration.cpp +++ b/src/shared/cplusplus/CheckDeclaration.cpp @@ -316,6 +316,7 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast) translationUnit()->error(ast->ctor_initializer->firstToken(), "only constructors take base initializers"); } + accept(ast->ctor_initializer); } const int previousVisibility = semantic()->switchVisibility(Symbol::Public); diff --git a/src/shared/cplusplus/CheckDeclarator.cpp b/src/shared/cplusplus/CheckDeclarator.cpp index 95181e4c7a0f712ab7b98dfa827acc901f00b231..5186055bca9b0f160539df659269d0ebd62ed247 100644 --- a/src/shared/cplusplus/CheckDeclarator.cpp +++ b/src/shared/cplusplus/CheckDeclarator.cpp @@ -168,6 +168,9 @@ bool CheckDeclarator::visit(FunctionDeclaratorAST *ast) ast->symbol = fun; fun->setReturnType(_fullySpecifiedType); + if (_fullySpecifiedType.isVirtual()) + fun->setVirtual(true); + if (ast->parameters) { DeclarationListAST *parameter_declarations = ast->parameters->parameter_declarations; for (DeclarationListAST *decl = parameter_declarations; decl; decl = decl->next) { diff --git a/src/shared/cplusplus/Symbols.cpp b/src/shared/cplusplus/Symbols.cpp index 2496454d0417be78577c882ba1926c4e5683eb6b..c5259c9fe8396482400bcbea87a1e4fb0b44a631 100644 --- a/src/shared/cplusplus/Symbols.cpp +++ b/src/shared/cplusplus/Symbols.cpp @@ -259,6 +259,12 @@ bool Function::hasArguments() const (argumentCount() == 1 && argumentAt(0)->type()->isVoidType())); } +bool Function::isVirtual() const +{ return f._isVirtual; } + +void Function::setVirtual(bool isVirtual) +{ f._isVirtual = isVirtual; } + bool Function::isVariadic() const { return f._isVariadic; } diff --git a/src/shared/cplusplus/Symbols.h b/src/shared/cplusplus/Symbols.h index 7ed4cf30f9a5c78be7118a610df2ee82abede33e..3ac7182c9a0e1f200e3294a343bd925fe126fbb1 100644 --- a/src/shared/cplusplus/Symbols.h +++ b/src/shared/cplusplus/Symbols.h @@ -307,6 +307,9 @@ public: /** Convenience function that returns whether the function receives any arguments. */ bool hasArguments() const; + bool isVirtual() const; + void setVirtual(bool isVirtual); + bool isVariadic() const; void setVariadic(bool isVariadic); @@ -348,6 +351,7 @@ private: TemplateParameters *_templateParameters; FullySpecifiedType _returnType; struct Flags { + unsigned _isVirtual: 1; unsigned _isVariadic: 1; unsigned _isPureVirtual: 1; unsigned _isConst: 1; diff --git a/src/shared/trk/launcher.cpp b/src/shared/trk/launcher.cpp index 0ff118ec12c87234ee522205f9beb6cfaada989e..7a9342740c759feb292946cc7c2c71ecd3352dcf 100644 --- a/src/shared/trk/launcher.cpp +++ b/src/shared/trk/launcher.cpp @@ -368,6 +368,11 @@ void Launcher::handleCpuType(const TrkResult &result) void Launcher::handleCreateProcess(const TrkResult &result) { + if (result.errorCode()) { + emit canNotRun(errorMessage(result.errorCode())); + emit finished(); + return; + } // 40 00 00] //logMessage(" RESULT: " + result.toString()); // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] diff --git a/src/shared/trk/launcher.h b/src/shared/trk/launcher.h index 7a2eccf1cb22d9e697950a9574dff382b916b83d..b24ed7d73d0ed3a590ee0483fdf5a949b8140bef 100644 --- a/src/shared/trk/launcher.h +++ b/src/shared/trk/launcher.h @@ -60,6 +60,7 @@ signals: void installingStarted(); void startingApplication(); void applicationRunning(uint pid); + void canNotRun(const QString &errorMessage); void finished(); void applicationOutputReceived(const QString &output); void copyProgress(int percent); @@ -71,8 +72,6 @@ private slots: void handleResult(const trk::TrkResult &data); private: - void tryTrkRead(); - // kill process and breakpoints void cleanUp(); @@ -89,7 +88,6 @@ private: void handleTrkVersion(const TrkResult &result); void waitForTrkFinished(const TrkResult &data); - void handleAndReportCreateProcess(const TrkResult &result); void copyFileToRemote(); void installRemotePackageSilently(const QString &filename); void installAndRun(); diff --git a/src/shared/trk/trkdevice.cpp b/src/shared/trk/trkdevice.cpp index 4885a72a4328aa4da225cb8fe4850ab4a479eb7c..775b7727960924776c73b525352deb60378af22b 100644 --- a/src/shared/trk/trkdevice.cpp +++ b/src/shared/trk/trkdevice.cpp @@ -119,6 +119,7 @@ TrkMessage::TrkMessage(byte c, byte t, TrkCallback cb) : } // namespace trk Q_DECLARE_METATYPE(trk::TrkMessage) +Q_DECLARE_METATYPE(trk::TrkResult) namespace trk { @@ -408,7 +409,7 @@ static inline bool overlappedSyncWrite(HANDLE file, const char *data, bool WriterThread::write(const QByteArray &data, QString *errorMessage) { - QMutexLocker(&m_context->mutex); + QMutexLocker locker(&m_context->mutex); #ifdef Q_OS_WIN DWORD charsWritten; if (!overlappedSyncWrite(m_context->device, data.data(), data.size(), &charsWritten, &m_context->writeOverlapped)) { @@ -465,6 +466,65 @@ void WriterThread::slotHandleResult(const TrkResult &result) tryWrite(); // Have messages been enqueued in-between? } +/////////////////////////////////////////////////////////////////////// +// +// ReaderThreadBase: Base class for a thread that reads data from +// the device, decodes the messages and emit signals for the messages. +// A Qt::BlockingQueuedConnection should be used for the message signal +// to ensure messages are processed in the correct sequence. +// +/////////////////////////////////////////////////////////////////////// + +class ReaderThreadBase : public QThread { + Q_OBJECT + Q_DISABLE_COPY(ReaderThreadBase) +public: + +signals: + void messageReceived(const trk::TrkResult &result, const QByteArray &rawData); + +protected: + explicit ReaderThreadBase(const QSharedPointer<DeviceContext> &context); + void processData(const QByteArray &a); + void processData(char c); + + const QSharedPointer<DeviceContext> m_context; + +private: + void readMessages(); + + QByteArray m_trkReadBuffer; +}; + +ReaderThreadBase::ReaderThreadBase(const QSharedPointer<DeviceContext> &context) : + m_context(context) +{ + static const int trkResultMetaId = qRegisterMetaType<trk::TrkResult>(); + Q_UNUSED(trkResultMetaId) +} + +void ReaderThreadBase::processData(const QByteArray &a) +{ + m_trkReadBuffer += a; + readMessages(); +} + +void ReaderThreadBase::processData(char c) +{ + m_trkReadBuffer += c; + if (m_trkReadBuffer.size() > 1) + readMessages(); +} + +void ReaderThreadBase::readMessages() +{ + TrkResult r; + QByteArray rawData; + while (extractResult(&m_trkReadBuffer, m_context->serialFrame, &r, &rawData)) { + emit messageReceived(r, rawData); + } +} + #ifdef Q_OS_WIN /////////////////////////////////////////////////////////////////////// // @@ -474,7 +534,7 @@ void WriterThread::slotHandleResult(const TrkResult &result) // /////////////////////////////////////////////////////////////////////// -class WinReaderThread : public QThread { +class WinReaderThread : public ReaderThreadBase { Q_OBJECT Q_DISABLE_COPY(WinReaderThread) public: @@ -485,8 +545,6 @@ public: signals: void error(const QString &); - void dataReceived(char c); - void dataReceived(const QByteArray &data); public slots: void terminate(); @@ -496,12 +554,11 @@ private: inline int tryRead(); - const QSharedPointer<DeviceContext> m_context; HANDLE m_handles[HandleCount]; }; WinReaderThread::WinReaderThread(const QSharedPointer<DeviceContext> &context) : - m_context(context) + ReaderThreadBase(context) { m_handles[FileHandle] = NULL; m_handles[TerminateEventHandle] = CreateEvent(NULL, FALSE, FALSE, NULL); @@ -528,9 +585,9 @@ int WinReaderThread::tryRead() DWORD bytesRead = 0; if (ReadFile(m_context->device, &buffer, bytesToRead, &bytesRead, &m_context->readOverlapped)) { if (bytesRead == 1) { - emit dataReceived(buffer[0]); + processData(buffer[0]); } else { - emit dataReceived(QByteArray(buffer, bytesRead)); + processData(QByteArray(buffer, bytesRead)); } return 0; } @@ -554,9 +611,9 @@ int WinReaderThread::tryRead() return -3; } if (bytesRead == 1) { - emit dataReceived(buffer[0]); + processData(buffer[0]); } else { - emit dataReceived(QByteArray(buffer, bytesRead)); + processData(QByteArray(buffer, bytesRead)); } return 0; } @@ -564,8 +621,7 @@ int WinReaderThread::tryRead() void WinReaderThread::run() { m_handles[FileHandle] = m_context->readOverlapped.hEvent; - int readResult; - while ( (readResult = tryRead()) == 0) ; + while ( tryRead() == 0) ; } void WinReaderThread::terminate() @@ -593,7 +649,7 @@ static inline QString msgUnixCallFailedErrno(const char *func, int errorNumber) return QString::fromLatin1("Call to %1() failed: %2").arg(QLatin1String(func), QString::fromLocal8Bit(strerror(errorNumber))); } -class UnixReaderThread : public QThread { +class UnixReaderThread : public ReaderThreadBase { Q_OBJECT Q_DISABLE_COPY(UnixReaderThread) public: @@ -604,7 +660,6 @@ public: signals: void error(const QString &); - void dataReceived(const QByteArray &); public slots: void terminate(); @@ -612,12 +667,11 @@ public slots: private: inline int tryRead(); - const QSharedPointer<DeviceContext> m_context; int m_terminatePipeFileDescriptors[2]; }; -UnixReaderThread::UnixReaderThread(const QSharedPointer<DeviceContext> &context) : - m_context(context) +UnixReaderThread::UnixReaderThread(const QSharedPointer<DeviceContext> &context) : + ReaderThreadBase(context) { m_terminatePipeFileDescriptors[0] = m_terminatePipeFileDescriptors[1] = -1; // Set up pipes for termination. Should not fail @@ -675,15 +729,14 @@ int UnixReaderThread::tryRead() m_context->mutex.lock(); const QByteArray data = m_context->file.read(numBytes); m_context->mutex.unlock(); - emit dataReceived(data); + processData(data); return 0; } void UnixReaderThread::run() { - int readResult; // Read loop - while ( (readResult = tryRead()) == 0) ; + while ( tryRead() == 0) ; } void UnixReaderThread::terminate() @@ -801,12 +854,9 @@ bool TrkDevice::open(const QString &port, QString *errorMessage) d->readerThread = QSharedPointer<ReaderThread>(new ReaderThread(d->deviceContext)); connect(d->readerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), Qt::QueuedConnection); -#ifdef Q_OS_WIN - connect(d->readerThread.data(), SIGNAL(dataReceived(char)), - this, SLOT(dataReceived(char)), Qt::QueuedConnection); -#endif - connect(d->readerThread.data(), SIGNAL(dataReceived(QByteArray)), - this, SLOT(dataReceived(QByteArray)), Qt::QueuedConnection); + connect(d->readerThread.data(), SIGNAL(messageReceived(trk::TrkResult,QByteArray)), + this, SLOT(slotMessageReceived(trk::TrkResult,QByteArray)), + Qt::BlockingQueuedConnection); d->readerThread->start(); d->writerThread = QSharedPointer<WriterThread>(new WriterThread(d->deviceContext)); @@ -872,30 +922,12 @@ void TrkDevice::setVerbose(int b) d->verbose = b; } -void TrkDevice::dataReceived(char c) +void TrkDevice::slotMessageReceived(const trk::TrkResult &result, const QByteArray &rawData) { - d->trkReadBuffer += c; - readMessages(); -} - -void TrkDevice::dataReceived(const QByteArray &data) -{ - d->trkReadBuffer += data; - readMessages(); -} - -void TrkDevice::readMessages() -{ - TrkResult r; - QByteArray rawData; - while (extractResult(&d->trkReadBuffer, d->deviceContext->serialFrame, &r, &rawData)) { - if (d->verbose > 1) - emitLogMessage("Read TrkResult " + r.data.toHex()); - d->writerThread->slotHandleResult(r); - emit messageReceived(r); - if (!rawData.isEmpty()) - emit rawDataReceived(rawData); - } + d->writerThread->slotHandleResult(result); + emit messageReceived(result); + if (!rawData.isEmpty()) + emit rawDataReceived(rawData); } void TrkDevice::emitError(const QString &s) @@ -908,8 +940,11 @@ void TrkDevice::emitError(const QString &s) void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, const QByteArray &data, const QVariant &cookie) { - if (!d->writerThread.isNull()) + if (!d->writerThread.isNull()) { + if (d->verbose > 1) + qDebug() << "Sending " << code << data.toHex(); d->writerThread->queueTrkMessage(code, callback, data, cookie); + } } void TrkDevice::sendTrkInitialPing() diff --git a/src/shared/trk/trkdevice.h b/src/shared/trk/trkdevice.h index a9640f83002cb5b324071d1bbd38be1a51a29389..579d32acf3bc0f1fc9294e6f30430fa809aa076e 100644 --- a/src/shared/trk/trkdevice.h +++ b/src/shared/trk/trkdevice.h @@ -95,8 +95,6 @@ public: // Send an Ack synchronously, bypassing the queue bool sendTrkAck(unsigned char token); - void tryTrkRead(); // TODO: Why public? - signals: void messageReceived(const trk::TrkResult &result); // Emitted with the contents of messages enclosed in 07e, not for log output @@ -105,8 +103,7 @@ signals: void logMessage(const QString &msg); private slots: - void dataReceived(char c); - void dataReceived(const QByteArray &a); + void slotMessageReceived(const trk::TrkResult &result, const QByteArray &a); protected slots: void emitError(const QString &msg);