diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2017-08-21 13:12:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-21 13:12:59 (GMT) |
commit | 0b2750ca2856f4d39953f96222ba7f07df25d683 (patch) | |
tree | 51b3649136af44028e3709af0c6f56905f919d43 | |
parent | 6b5617e5a4c87afd2c7f2f7b8cb03de2b6735627 (diff) | |
parent | 3ae2ec6fb1fb372c8acd802cc528f27800a309e3 (diff) | |
download | Doxygen-0b2750ca2856f4d39953f96222ba7f07df25d683.zip Doxygen-0b2750ca2856f4d39953f96222ba7f07df25d683.tar.gz Doxygen-0b2750ca2856f4d39953f96222ba7f07df25d683.tar.bz2 |
Merge branch 'master' into librejs_fixes
-rw-r--r-- | CMakeLists.txt | 12 | ||||
-rw-r--r-- | addon/doxyparse/CMakeLists.txt | 11 | ||||
-rw-r--r-- | addon/doxyparse/README | 5 | ||||
-rw-r--r-- | addon/doxyparse/doxyparse.cpp | 59 | ||||
-rw-r--r-- | cmake/FindLibClang.cmake | 55 | ||||
-rw-r--r-- | cmake/lang_cfg.cmake | 10 | ||||
-rw-r--r-- | doc/preprocessing.doc | 2 | ||||
-rw-r--r-- | src/CMakeLists.txt | 22 | ||||
-rw-r--r-- | src/clangparser.cpp | 35 | ||||
-rw-r--r-- | src/code.l | 54 | ||||
-rw-r--r-- | src/commentcnv.l | 70 | ||||
-rw-r--r-- | src/config.xml | 14 | ||||
-rw-r--r-- | src/index.cpp | 6 | ||||
-rw-r--r-- | src/memberdef.cpp | 11 | ||||
-rw-r--r-- | src/memberdef.h | 6 | ||||
-rw-r--r-- | src/pagedef.cpp | 7 | ||||
-rw-r--r-- | src/portable.cpp | 1 | ||||
-rw-r--r-- | src/vhdldocgen.cpp | 4 |
18 files changed, 269 insertions, 115 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d75659..ed63320 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,14 +35,20 @@ set(clang "0" CACHE INTERNAL "used in settings.h") if (use_sqlite3) set(sqlite3 "1" CACHE INTERNAL "used in settings.h") endif() + +set(MACOS_VERSION_MIN 10.5) if (use_libclang) set(clang "1" CACHE INTERNAL "used in settings.h") - find_package(LibClang REQUIRED) + find_package(LLVM CONFIG REQUIRED) + find_package(Clang CONFIG REQUIRED) + if (${CMAKE_SYSTEM} MATCHES "Darwin") + set(MACOS_VERSION_MIN 10.11) + endif() endif() if (${CMAKE_SYSTEM} MATCHES "Darwin") - set(CMAKE_CXX_FLAGS "-Wno-deprecated-register -mmacosx-version-min=10.5 ${CMAKE_CXX_FLAGS}") - set(CMAKE_C_FLAGS "-Wno-deprecated-register -mmacosx-version-min=10.5 ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-Wno-deprecated-register -mmacosx-version-min=${MACOS_VERSION_MIN} ${CMAKE_CXX_FLAGS}") + set(CMAKE_C_FLAGS "-Wno-deprecated-register -mmacosx-version-min=${MACOS_VERSION_MIN} ${CMAKE_C_FLAGS}") find_library(CORESERVICES_LIB CoreServices) set(EXTRA_LIBS ${CORESERVICES_LIB}) endif() diff --git a/addon/doxyparse/CMakeLists.txt b/addon/doxyparse/CMakeLists.txt index 24f98cb..e4f9021 100644 --- a/addon/doxyparse/CMakeLists.txt +++ b/addon/doxyparse/CMakeLists.txt @@ -1,11 +1,21 @@ if (build_parse) +# configvalues.h +add_custom_command( + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/src/configgen.py -maph ${CMAKE_SOURCE_DIR}/src/config.xml > ${GENERATED_SRC}/configvalues.h + DEPENDS ${CMAKE_SOURCE_DIR}/src/config.xml ${CMAKE_SOURCE_DIR}/src/configgen.py + OUTPUT ${GENERATED_SRC}/configvalues.h +) +set_source_files_properties(${GENERATED_SRC}/configvalues.h PROPERTIES GENERATED 1) + find_package(Iconv) include_directories( ${CMAKE_SOURCE_DIR}/src + ${GENERATED_SRC} ${CMAKE_SOURCE_DIR}/qtools ${ICONV_INCLUDE_DIR} + ${CLANG_INCLUDEDIR} ) add_executable(doxyparse @@ -21,6 +31,7 @@ ${ICONV_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${SQLITE3_LIBRARIES} ${EXTRA_LIBS} +${CLANG_LIBS} ) install(TARGETS doxyparse DESTINATION bin) diff --git a/addon/doxyparse/README b/addon/doxyparse/README index 7cbc8ff..9f7429c 100644 --- a/addon/doxyparse/README +++ b/addon/doxyparse/README @@ -5,6 +5,11 @@ This directory contains an "source parsing engine" based on doxyapp code. More info and source code repository: https://github.com/analizo/doxygen +## build + + cmake -G "Unix Makefiles" -Dbuild_parse=ON + make + AUTHORS ======= diff --git a/addon/doxyparse/doxyparse.cpp b/addon/doxyparse/doxyparse.cpp index ec1bdae..ee34e3b 100644 --- a/addon/doxyparse/doxyparse.cpp +++ b/addon/doxyparse/doxyparse.cpp @@ -103,7 +103,7 @@ static void findXRefSymbols(FileDef *fd) static bool ignoreStaticExternalCall(MemberDef *context, MemberDef *md) { if (md->isStatic()) { if(md->getFileDef()) { - if(md->getFileDef()->getFileBase() == context->getFileDef()->getFileBase()) + if(md->getFileDef()->getOutputFileBase() == context->getFileDef()->getOutputFileBase()) // TODO ignore prefix of file return false; else @@ -159,6 +159,9 @@ static void printReferenceTo(std::string type, std::string signature, std::strin printf(" type: %s\n", type.c_str()); printf(" defined_in: %s\n", defined_in.c_str()); } +static void printNumberOfConditionalPaths(MemberDef* md) { + printf(" conditional_paths: %d\n", md->numberOfFlowKeyWords()); +} static int isPartOfCStruct(MemberDef * md) { return is_c_code && md->getClassDef() != NULL; @@ -188,7 +191,7 @@ static void referenceTo(MemberDef* md) { std::string signature = ""; if (isPartOfCStruct(md)) { signature = md->getClassDef()->name().data() + std::string("::") + functionSignature(md); - defined_in = md->getClassDef()->getFileDef()->getFileBase().data(); + defined_in = md->getClassDef()->getFileDef()->getOutputFileBase().data(); } else { signature = functionSignature(md); @@ -196,7 +199,7 @@ static void referenceTo(MemberDef* md) { defined_in = md->getClassDef()->name().data(); } else if (md->getFileDef()) { - defined_in = md->getFileDef()->getFileBase().data(); + defined_in = md->getFileDef()->getOutputFileBase().data(); } } printReferenceTo(type, signature, defined_in); @@ -221,6 +224,7 @@ void functionInformation(MemberDef* md) { printNumberOfLines(size); ArgumentList *argList = md->argumentList(); printNumberOfArguments(argList->count()); + printNumberOfConditionalPaths(md); MemberSDict *defDict = md->getReferencesMembers(); if (defDict) { MemberSDict::Iterator msdi(*defDict); @@ -329,7 +333,7 @@ static void listSymbols() { printFile(fd->absFilePath().data()); MemberList *ml = fd->getMemberList(MemberListType_allMembersList); if (ml && ml->count() > 0) { - printModule(fd->getFileBase().data()); + printModule(fd->getOutputFileBase().data()); listMembers(ml); } @@ -355,37 +359,40 @@ int main(int argc,char **argv) { // initialize data structures initDoxygen(); + // check and finalize the configuration + checkConfiguration(); + adjustConfiguration(); + // setup the non-default configuration options // we need a place to put intermediate files std::ostringstream tmpdir; tmpdir << "/tmp/doxyparse-" << getpid(); - Config_getString("OUTPUT_DIRECTORY")= tmpdir.str().c_str(); - + Config_getString(OUTPUT_DIRECTORY)= tmpdir.str().c_str(); // enable HTML (fake) output to omit warning about missing output format - Config_getBool("GENERATE_HTML")=TRUE; + Config_getBool(GENERATE_HTML)=TRUE; // disable latex output - Config_getBool("GENERATE_LATEX")=FALSE; + Config_getBool(GENERATE_LATEX)=FALSE; // be quiet - Config_getBool("QUIET")=TRUE; + Config_getBool(QUIET)=TRUE; // turn off warnings - Config_getBool("WARNINGS")=FALSE; - Config_getBool("WARN_IF_UNDOCUMENTED")=FALSE; - Config_getBool("WARN_IF_DOC_ERROR")=FALSE; + Config_getBool(WARNINGS)=FALSE; + Config_getBool(WARN_IF_UNDOCUMENTED)=FALSE; + Config_getBool(WARN_IF_DOC_ERROR)=FALSE; // Extract as much as possible - Config_getBool("EXTRACT_ALL")=TRUE; - Config_getBool("EXTRACT_STATIC")=TRUE; - Config_getBool("EXTRACT_PRIVATE")=TRUE; - Config_getBool("EXTRACT_LOCAL_METHODS")=TRUE; + Config_getBool(EXTRACT_ALL)=TRUE; + Config_getBool(EXTRACT_STATIC)=TRUE; + Config_getBool(EXTRACT_PRIVATE)=TRUE; + Config_getBool(EXTRACT_LOCAL_METHODS)=TRUE; // Extract source browse information, needed // to make doxygen gather the cross reference info - Config_getBool("SOURCE_BROWSER")=TRUE; + Config_getBool(SOURCE_BROWSER)=TRUE; // find functions call between modules - Config_getBool("CALL_GRAPH")=TRUE; + Config_getBool(CALL_GRAPH)=TRUE; // loop recursive over input files - Config_getBool("RECURSIVE")=TRUE; + Config_getBool(RECURSIVE)=TRUE; // set the input - Config_getList("INPUT").clear(); + Config_getList(INPUT).clear(); for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-") == 0) { char filename[1024]; @@ -394,20 +401,16 @@ int main(int argc,char **argv) { if (feof(stdin)) { break; } - Config_getList("INPUT").append(filename); + Config_getList(INPUT).append(filename); } } else { - Config_getList("INPUT").append(argv[i]); + Config_getList(INPUT).append(argv[i]); } } - if (Config_getList("INPUT").isEmpty()) { + if (Config_getList(INPUT).isEmpty()) { exit(0); } - // check and finalize the configuration - checkConfiguration(); - adjustConfiguration(); - // parse the files parseInput(); @@ -429,7 +432,7 @@ int main(int argc,char **argv) { if (!Doxygen::objDBFileName.isEmpty()) unlink(Doxygen::objDBFileName); if (!Doxygen::entryDBFileName.isEmpty()) unlink(Doxygen::entryDBFileName); // clean up after us - rmdir(Config_getString("OUTPUT_DIRECTORY")); + rmdir(Config_getString(OUTPUT_DIRECTORY)); listSymbols(); diff --git a/cmake/FindLibClang.cmake b/cmake/FindLibClang.cmake deleted file mode 100644 index e7462d4..0000000 --- a/cmake/FindLibClang.cmake +++ /dev/null @@ -1,55 +0,0 @@ -if (NOT CLANG_ROOT) - set(CLANG_ROOT $ENV{CLANG_ROOT}) -endif () - -if (NOT LLVM_CONFIG) - set(LLVM_CONFIG $ENV{LLVM_CONFIG}) - if (NOT LLVM_CONFIG) - set(llvm_config_names llvm-config) - foreach(minor RANGE 9 1) - list(APPEND llvm_config_names "llvm-config3${minor}" "llvm-config-3.${minor}" "llvm-config-mp-3.${minor}") - endforeach () - find_program(LLVM_CONFIG NAMES ${llvm_config_names}) - endif () -endif () - -if (LLVM_CONFIG) - message(STATUS "llvm-config found at: ${LLVM_CONFIG}") -else () - message(FATAL_ERROR "Could NOT find llvm-config executable.") -endif () - -if (NOT EXISTS ${CLANG_INCLUDEDIR}) - execute_process(COMMAND ${LLVM_CONFIG} --includedir OUTPUT_VARIABLE CLANG_INCLUDEDIR OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT EXISTS ${CLANG_INCLUDEDIR}) - message(FATAL_ERROR "Could NOT find clang includedir. You can fix this by setting CLANG_INCLUDEDIR in your shell or as a cmake variable.") - endif () -endif () - -if (NOT EXISTS ${CLANG_LIBDIR}) - execute_process(COMMAND ${LLVM_CONFIG} --libdir OUTPUT_VARIABLE CLANG_LIBDIR OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT EXISTS ${CLANG_LIBDIR}) - message(FATAL_ERROR "Could NOT find clang libdir. You can fix this by setting CLANG_LIBDIR in your shell or as a cmake variable.") - endif () -endif () - -if (NOT CLANG_LIBS) - find_library(CLANG_LIB_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT NAMES clang libclang ${CLANG_ROOT}/lib ${CLANG_LIBDIR} NO_DEFAULT_PATH) - if (NOT EXISTS ${CLANG_CLANG_LIB_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT}) - find_library(CLANG_LIBS NAMES clang libclang) - if (NOT EXISTS ${CLANG_LIBS}) - if (MSVC) - set (CLANG_LIBS "${CLANG_LIBDIR}/libclang.lib") - else() - set (CLANG_LIBS "-L${CLANG_LIBDIR}" "-lclang" "-Wl,-rpath,${CLANG_LIBDIR}") - endif() - endif () - else () - set(CLANG_LIBS "${CLANG_LIB_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT}") - endif () -endif () - -execute_process(COMMAND ${LLVM_CONFIG} --version OUTPUT_VARIABLE CLANG_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) -message("-- Using Clang ${CLANG_VERSION} from ${CLANG_LIBDIR} with LIBS ${CLANG_LIBS} and CXXFLAGS ${CLANG_CXXFLAGS}") - - diff --git a/cmake/lang_cfg.cmake b/cmake/lang_cfg.cmake index c57d3ed..86c2d9a 100644 --- a/cmake/lang_cfg.cmake +++ b/cmake/lang_cfg.cmake @@ -1,10 +1,10 @@ -if(${CMAKE_ARGC} GREATER 1) - if ("${CMAKE_ARGV3}" STREQUAL "ENONLY") - message("#define ENGLISH_ONLY") +if(${CMAKE_ARGC} GREATER 2) + if ("${CMAKE_ARGV4}" STREQUAL "ENONLY") + file(APPEND ${CMAKE_ARGV3} " #define ENGLISH_ONLY") else() math(EXPR UPTO ${CMAKE_ARGC}-1) - foreach(i RANGE 3 ${UPTO}) - message("#define LANG_${CMAKE_ARGV${i}}") + foreach(i RANGE 4 ${UPTO}) + file(APPEND ${CMAKE_ARGV3} " #define LANG_${CMAKE_ARGV${i}}") endforeach() endif() endif() diff --git a/doc/preprocessing.doc b/doc/preprocessing.doc index d62bbb3..30d4cf3 100644 --- a/doc/preprocessing.doc +++ b/doc/preprocessing.doc @@ -62,7 +62,7 @@ to \c YES. Then the result after preprocessing becomes: #define VERSION #define CONST_STRING - static const char * version = "1.xx"; + static const char * version = "2.xx"; \endverbatim Note that doxygen will now expand \e all macro definitions diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 08c8439..2218e82 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -73,7 +73,7 @@ set_source_files_properties(${GENERATED_SRC}/ce_parse.h PROPERTIES GENERATED 1) # lang_cfg.h add_custom_command( COMMENT "Generating ${GENERATED_SRC}/lang_cfg.h" - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/lang_cfg.cmake ${LANG_CODES} 2> ${GENERATED_SRC}/lang_cfg.h + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/lang_cfg.cmake ${GENERATED_SRC}/lang_cfg.h ${LANG_CODES} DEPENDS ${LANGUAGE_FILES} OUTPUT ${GENERATED_SRC}/lang_cfg.h ) @@ -244,6 +244,26 @@ add_library(_doxygen STATIC ) add_executable(doxygen main.cpp) + +if (use_libclang) + find_package(LLVM REQUIRED CONFIG) + find_package(Clang REQUIRED CONFIG) + if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + target_compile_features(_doxygen PRIVATE cxx_alignof) + target_compile_features(doxygen PRIVATE cxx_alignof) + target_compile_options(_doxygen PRIVATE -stdlib=libc++ -std=c++11) + target_compile_options(doxygen PRIVATE -stdlib=libc++ -std=c++11) + elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + target_compile_options(_doxygen PRIVATE -std=c++11) + target_compile_options(doxygen PRIVATE -std=c++11) + endif() + include_directories(${LLVM_INCLUDE_DIRS}) + add_definitions(${LLVM_DEFINITIONS}) + llvm_map_components_to_libnames(llvm_libs support core option) + target_compile_definitions(doxygen PRIVATE ${LLVM_DEFINITIONS}) + set(CLANG_LIBS libclang clangTooling ${llvm_libs}) +endif() + target_link_libraries(doxygen _doxygen doxycfg diff --git a/src/clangparser.cpp b/src/clangparser.cpp index 67e754b..77151d6 100644 --- a/src/clangparser.cpp +++ b/src/clangparser.cpp @@ -4,6 +4,7 @@ #if USE_LIBCLANG #include <clang-c/Index.h> +#include "clang/Tooling/Tooling.h" #include <qfileinfo.h> #include <stdlib.h> #include "message.h" @@ -160,15 +161,46 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); static QStrList &includePath = Config_getList(INCLUDE_PATH); static QStrList clangOptions = Config_getList(CLANG_OPTIONS); + static QCString clangCompileDatabase = Config_getList(CLANG_COMPILATION_DATABASE_PATH); if (!clangAssistedParsing) return; //printf("ClangParser::start(%s)\n",fileName); p->fileName = fileName; p->index = clang_createIndex(0, 0); p->curLine = 1; p->curToken = 0; - char **argv = (char**)malloc(sizeof(char*)*(4+Doxygen::inputPaths.count()+includePath.count()+clangOptions.count())); QDictIterator<void> di(Doxygen::inputPaths); int argc=0; + std::string error; + // load a clang compilation database (https://clang.llvm.org/docs/JSONCompilationDatabase.html) + // this only needs to be loaded once, and could be refactored to a higher level function + static std::unique_ptr<clang::tooling::CompilationDatabase> db = + clang::tooling::CompilationDatabase::loadFromDirectory(clangCompileDatabase.data(), error); + int clang_option_len = 0; + std::vector<clang::tooling::CompileCommand> command; + if (strcmp(clangCompileDatabase, "0") != 0) { + if (db == nullptr) { + // user specified a path, but DB file was not found + err("%s using clang compilation database path of: \"%s\"\n", error.c_str(), + clangCompileDatabase.data()); + } else { + // check if the file we are parsing is in the DB + command = db->getCompileCommands(fileName); + if (!command.empty() ) { + // it's possible to have multiple entries for the same file, so use the last entry + clang_option_len = command[command.size()-1].CommandLine.size(); + } + } + } + char **argv = (char**)malloc(sizeof(char*)*(4+Doxygen::inputPaths.count()+includePath.count()+clangOptions.count()+clang_option_len)); + if (!command.empty() ) { + std::vector<std::string> options = command[command.size()-1].CommandLine; + // copy each compiler option used from the database. Skip the first which is compiler exe. + for (auto option = options.begin()+1; option != options.end(); option++) { + argv[argc++] = strdup(option->c_str()); + } + // this extra addition to argv is accounted for as we are skipping the first entry in + argv[argc++]=strdup("-w"); // finally, turn off warnings. + } else { // add include paths for input files for (di.toFirst();di.current();++di,++argc) { @@ -230,6 +262,7 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) // provide the input and and its dependencies as unsaved files so we can // pass the filtered versions argv[argc++]=strdup(fileName); + } static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); //printf("source %s ----------\n%s\n-------------\n\n", // fileName,p->source.data()); @@ -126,6 +126,7 @@ static bool g_lexInit = FALSE; static QStack<int> g_classScopeLengthStack; +static int g_prefixed_with_this_keyword = FALSE; static Definition *g_searchCtx; static bool g_collectXRefs; @@ -963,7 +964,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName bool isLocal=FALSE; //printf("generateClassOrGlobalLink(className=%s)\n",className.data()); - if ((lcd=g_theVarContext.findVariable(className))==0) // not a local variable + if (!g_prefixed_with_this_keyword || (lcd=g_theVarContext.findVariable(className))==0) // not a local variable { Definition *d = g_currentDefinition; //printf("d=%s g_sourceFileDef=%s\n",d?d->name().data():"<none>",g_sourceFileDef?g_sourceFileDef->name().data():"<none>"); @@ -1019,6 +1020,8 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName isLocal=TRUE; DBG_CTX((stderr,"is a local variable cd=%p!\n",cd)); } + g_prefixed_with_this_keyword = FALSE; // discard the "this" prefix for the next calls + if (cd && cd->isLinkable()) // is it a linkable class { DBG_CTX((stderr,"is linkable class %s\n",clName)); @@ -1821,7 +1824,8 @@ SCOPETNAME (((({ID}{TEMPLIST}?){BN}*)?{SEP}{BN}*)*)((~{BN}*)?{ID}) SCOPEPREFIX ({ID}{TEMPLIST}?{BN}*{SEP}{BN}*)+ KEYWORD_OBJC ("@public"|"@private"|"@protected"|"@class"|"@implementation"|"@interface"|"@end"|"@selector"|"@protocol"|"@optional"|"@required"|"@throw"|"@synthesize"|"@property") KEYWORD ("asm"|"__assume"|"auto"|"class"|"const"|"delete"|"enum"|"explicit"|"extern"|"false"|"friend"|"gcnew"|"gcroot"|"set"|"get"|"inline"|"internal"|"mutable"|"namespace"|"new"|"nullptr"|"override"|"operator"|"pin_ptr"|"private"|"protected"|"public"|"raise"|"register"|"remove"|"self"|"sizeof"|"static"|"struct"|"__super"|"function"|"template"|"generic"|"this"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|"alignas"|"alignof"|{KEYWORD_OBJC}) -FLOWKW ("break"|"case"|"catch"|"continue"|"default"|"do"|"else"|"finally"|"for"|"foreach"|"for each"|"goto"|"if"|"return"|"switch"|"throw"|"throws"|"try"|"while"|"@try"|"@catch"|"@finally") +FLOWKW ("break"|"catch"|"continue"|"default"|"do"|"else"|"finally"|"return"|"switch"|"throw"|"throws"|"@catch"|"@finally") +FLOWCONDITION ("case"|"for"|"foreach"|"for each"|"goto"|"if"|"try"|"while"|"@try") TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"object"|"short"|"signed"|"unsigned"|"void"|"wchar_t"|"size_t"|"boolean"|"id"|"SEL"|"string"|"nullptr") CASTKW ("const_cast"|"dynamic_cast"|"reinterpret_cast"|"static_cast") CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) @@ -2408,6 +2412,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <UsingName>\n { codifyLines(yytext); BEGIN(Body); } <UsingName>. { codifyLines(yytext); BEGIN(Body); } <Body,FuncCall>"$"?"this"("->"|".") { g_code->codify(yytext); // this-> for C++, this. for C# + g_prefixed_with_this_keyword = TRUE; } <Body>{KEYWORD}/([^a-z_A-Z0-9]) { startFontClass("keyword"); @@ -2449,6 +2454,18 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_inForEachExpression = (qstrcmp(yytext,"for each")==0 || qstrcmp(yytext, "foreach")==0); BEGIN(FuncCall); } +<Body>{FLOWCONDITION}/{BN}*"(" { + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->addFlowKeyWord(); + } + startFontClass("keywordflow"); + codifyLines(yytext); + endFontClass(); + g_name.resize(0);g_type.resize(0); + g_inForEachExpression = (strcmp(yytext,"for each")==0 || strcmp(yytext, "foreach")==0); + BEGIN(FuncCall); + } <Body>{FLOWKW}/([^a-z_A-Z0-9]) { startFontClass("keywordflow"); codifyLines(yytext); @@ -2458,11 +2475,33 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_inFunctionTryBlock=FALSE; } } +<Body>{FLOWCONDITION}/([^a-z_A-Z0-9]) { + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->addFlowKeyWord(); + } + startFontClass("keywordflow"); + codifyLines(yytext); + endFontClass(); + if (g_inFunctionTryBlock && (strcmp(yytext,"catch")==0 || strcmp(yytext,"finally")==0)) + { + g_inFunctionTryBlock=FALSE; + } + } <Body>{FLOWKW}/{B}* { startFontClass("keywordflow"); codifyLines(yytext); endFontClass(); } +<Body>{FLOWCONDITION}/{B}* { + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->addFlowKeyWord(); + } + startFontClass("keywordflow"); + codifyLines(yytext); + endFontClass(); + } <Body>"*"{B}*")" { // end of cast? g_code->codify(yytext); g_theCallContext.popScope(); @@ -2963,6 +3002,17 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_code->codify(yytext); endFontClass(); } +<MemberCall2,FuncCall>{FLOWCONDITION}/([^a-z_A-Z0-9]) { + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->addFlowKeyWord(); + } + addParmType(); + g_parmName=yytext; + startFontClass("keywordflow"); + g_code->codify(yytext); + endFontClass(); + } <MemberCall2,FuncCall>{ID}(({B}*"<"[^\n\[\](){}<>]*">")?({B}*"::"{B}*{ID})?)* { addParmType(); g_parmName=yytext; diff --git a/src/commentcnv.l b/src/commentcnv.l index 6fea6c9..ebee914 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -89,6 +89,8 @@ static int g_lastBlockContext; static bool g_pythonDocString; static int g_nestingCount; +static bool g_vhdl; // for VHDL old style --! comment + static SrcLangExt g_lang; static bool isFixedForm; // For Fortran @@ -250,7 +252,7 @@ void replaceComment(int offset); %% -<Scan>[^"'!\/\n\\#-,]* { /* eat anything that is not " / , or \n */ +<Scan>[^"'!\/\n\\#,\-]* { /* eat anything that is not " / , or \n */ copyToOutput(yytext,(int)yyleng); } <Scan>[,] { /* eat , so we have a nice separator in long initialization lines */ @@ -425,6 +427,7 @@ void replaceComment(int offset); } else { + g_vhdl = TRUE; copyToOutput(yytext,(int)yyleng); g_nestingCount=0; g_commentStack.clear(); /* to be on the save side */ @@ -664,7 +667,27 @@ void replaceComment(int offset); } } } -<CComment>"\n"/[ \t]*[^#] { /* end of Python comment */ + /* Python an VHDL share CComment, so special attention for ending commments is required */ +<CComment>"\n"/[ \t]*"#" { + if (g_lang!=SrcLangExt_VHDL) + { + REJECT; + } + else + { + if (g_vhdl) // inside --! comment + { + g_vhdl = FALSE; + copyToOutput(yytext,(int)yyleng); + BEGIN(Scan); + } + else // C-type comment + { + REJECT; + } + } + } +<CComment>"\n"/[ \t]*"-" { if (g_lang!=SrcLangExt_Python || g_pythonDocString) { REJECT; @@ -674,18 +697,38 @@ void replaceComment(int offset); copyToOutput(yytext,(int)yyleng); BEGIN(Scan); } - } -<CComment>"\n"/[ \t]*[^\-] { /* end of VHDL comment */ - if (g_lang!=SrcLangExt_VHDL) - { + } +<CComment>"\n"/[ \t]*[^ \t#\-] { + if (g_lang==SrcLangExt_Python) + { + if (g_pythonDocString) + { + REJECT; + } + else + { + copyToOutput(yytext,(int)yyleng); + BEGIN(Scan); + } + } + else if (g_lang==SrcLangExt_VHDL) + { + if (g_vhdl) // inside --! comment + { + g_vhdl = FALSE; + copyToOutput(yytext,(int)yyleng); + BEGIN(Scan); + } + else // C-type comment + { + REJECT; + } + } + else + { REJECT; - } - else - { - copyToOutput(yytext,(int)yyleng); - BEGIN(Scan); - } - } + } + } /* removed for bug 674842 (bug was introduced in rev 768) <CComment>"'" { g_charContext = YY_START; @@ -1001,6 +1044,7 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) g_condStack.setAutoDelete(TRUE); g_commentStack.clear(); g_commentStack.setAutoDelete(TRUE); + g_vhdl = FALSE; printlex(yy_flex_debug, TRUE, __FILE__, fileName); isFixedForm = FALSE; diff --git a/src/config.xml b/src/config.xml index 8bb6add..6cd7997 100644 --- a/src/config.xml +++ b/src/config.xml @@ -1637,6 +1637,20 @@ to disable this feature. ]]> </docs> </option> + <option type='string' id='CLANG_COMPILATION_DATABASE_PATH' setting='USE_LIBCLANG' defval='0'> + <docs> +<![CDATA[ + If clang assisted parsing is enabled you can provide the clang parser with the + path to the <a href="http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html"> + compilation database</a> used when the files were built. This is equivalent to + specifying the "-p" option to a clang tool, such as clang-check. These options + will then be pased to the parser. + + @note The availability of this option depends on whether or not doxygen + was generated with the `-Duse-libclang=ON` option for CMake. + ]]> + </docs> + </option> </group> <group name='Index' docs='Configuration options related to the alphabetical class index'> <option type='bool' id='ALPHABETICAL_INDEX' defval='1'> diff --git a/src/index.cpp b/src/index.cpp index 921ab51..3a17c29 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -4122,7 +4122,7 @@ static void writeIndexHierarchyEntries(OutputList &ol,const QList<LayoutNavEntry { if (documentedNamespaces>0 && addToIndex) { - Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0); + Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0); Doxygen::indexList->incContentsDepth(); needsClosing=TRUE; } @@ -4151,7 +4151,7 @@ static void writeIndexHierarchyEntries(OutputList &ol,const QList<LayoutNavEntry case LayoutNavEntry::Classes: if (annotatedClasses>0 && addToIndex) { - Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,"annotated",0); + Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0); Doxygen::indexList->incContentsDepth(); needsClosing=TRUE; } @@ -4189,7 +4189,7 @@ static void writeIndexHierarchyEntries(OutputList &ol,const QList<LayoutNavEntry { if (documentedHtmlFiles>0 && addToIndex) { - Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0); + Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0); Doxygen::indexList->incContentsDepth(); needsClosing=TRUE; } diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 26001a1..8403374 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -750,6 +750,7 @@ MemberDef::MemberDef(const char *df,int dl,int dc, //printf("MemberDef::MemberDef(%s)\n",na); m_impl = new MemberDefImpl; m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al); + number_of_flowkw = 1; m_isLinkableCached = 0; m_isConstructorCached = 0; m_isDestructorCached = 0; @@ -4910,6 +4911,16 @@ void MemberDef::invalidateCachedArgumentTypes() invalidateCachedTypesInArgumentList(m_impl->declArgList); } +void MemberDef::addFlowKeyWord() +{ + number_of_flowkw++; +} + +int MemberDef::numberOfFlowKeyWords() +{ + return number_of_flowkw; +} + //---------------- QCString MemberDef::displayName(bool) const diff --git a/src/memberdef.h b/src/memberdef.h index c0825b2..bf7ea9a 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -178,6 +178,7 @@ class MemberDef : public Definition bool isStrongEnumValue() const; bool livesInsideEnum() const; + int numberOfFlowKeyWords(); // derived getters bool isFriendToHide() const; bool isNotFriend() const; @@ -272,6 +273,8 @@ class MemberDef : public Definition // ---- setters ----- //----------------------------------------------------------------------------------- + void addFlowKeyWord(); + // set functions void setMemberType(MemberType t); void setDefinition(const char *d); @@ -424,6 +427,9 @@ class MemberDef : public Definition void _addToSearchIndex(); static int s_indentLevel; + + int number_of_flowkw; + // disable copying of member defs MemberDef(const MemberDef &); MemberDef &operator=(const MemberDef &); diff --git a/src/pagedef.cpp b/src/pagedef.cpp index 1210305..e797b050 100644 --- a/src/pagedef.cpp +++ b/src/pagedef.cpp @@ -169,6 +169,11 @@ void PageDef::writeDocumentation(OutputList &ol) ol.endTitleHead(manPageName, manPageName); if (si) { + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Man); + ol.writeString(" - "); + ol.popGeneratorState(); + ol.generateDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE); ol.endSection(si->label,si->type); } @@ -230,7 +235,7 @@ void PageDef::writePageDocumentation(OutputList &ol) ol.startTextBlock(); QCString docStr = documentation()+inbodyDocumentation(); - if (!docStr.isEmpty()) + if (hasBriefDescription() && !Doxygen::sectionDict->find(name())) { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Man); diff --git a/src/portable.cpp b/src/portable.cpp index 1983fe7..4ad88a4 100644 --- a/src/portable.cpp +++ b/src/portable.cpp @@ -180,6 +180,7 @@ int portable_system(const char *command,const char *args,bool commandHasConsole) } } #endif + return 1; // we should never get here } diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index d09de09..7883327 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -3995,10 +3995,10 @@ void FlowChart::createSVG() //if (m) // fprintf(stderr,"\n creating flowchart : %s %s in file %s \n",VhdlDocGen::trTypeString(m->getMemberSpecifiers()),m->name().data(),m->getFileDef()->name().data()); - QCString dir=" -o "+ov+qcs; + QCString dir=" -o \""+ov+qcs+"\""; ov+="/flow_design.dot"; - QCString vlargs="-Tsvg "+ov+dir ; + QCString vlargs="-Tsvg \""+ov+"\" "+dir ; if (portable_system("dot",vlargs)!=0) { |