Skip to content

Commit

Permalink
make use of clang compilation database
Browse files Browse the repository at this point in the history
  • Loading branch information
dvj committed Apr 6, 2017
1 parent b91f466 commit 818aefc
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 3 deletions.
9 changes: 7 additions & 2 deletions CMakeLists.txt
Expand Up @@ -35,14 +35,19 @@ 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)
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()
Expand Down
13 changes: 13 additions & 0 deletions src/CMakeLists.txt
Expand Up @@ -244,6 +244,19 @@ add_library(_doxygen STATIC
)

add_executable(doxygen main.cpp)

if (use_libclang)
find_package(LLVM REQUIRED CONFIG)
find_package(Clang REQUIRED CONFIG)
target_compile_features(_doxygen PRIVATE cxx_alignof)
target_compile_options(_doxygen PRIVATE -stdlib=libc++ -std=c++11)
target_compile_features(doxygen PRIVATE cxx_alignof)
target_compile_options(doxygen PRIVATE -stdlib=libc++ -std=c++11)
llvm_map_components_to_libnames(llvm_libs support core option)
target_compile_definitions(doxygen PRIVATE ${LLVM_DEFINITIONS})
set(CLANG_LIBS ${llvm_libs} ${CLANG_LIBS} clangTooling)
endif()

target_link_libraries(doxygen
_doxygen
doxycfg
Expand Down
35 changes: 34 additions & 1 deletion src/clangparser.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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());
Expand Down
14 changes: 14 additions & 0 deletions src/config.xml
Expand Up @@ -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 equivilent 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'>
Expand Down

0 comments on commit 818aefc

Please sign in to comment.