Esempio n. 1
0
int main(int argc, char **argv)
{
    LogLevel logLevel = LogLevel::Error;
    Path file;
    for (int i=1; i<argc; ++i) {
        if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) {
            ++logLevel;
        } else {
            file = argv[i];
        }
    }

    setenv("LIBCLANG_NOTHREADS", "1", 0);
    signal(SIGSEGV, sigHandler);
    signal(SIGABRT, sigHandler);
    signal(SIGBUS, sigHandler);

    Flags<LogMode> logType = LogStderr;
    std::shared_ptr<SyslogCloser> closer;
    if (ClangIndexer::serverOpts() & Server::RPLogToSyslog) {
        logType |= LogSyslog;
        closer.reset(new SyslogCloser);
    }
    initLogging(argv[0], logType, logLevel);
    (void)closer;

    RTags::initMessages();
    std::shared_ptr<EventLoop> eventLoop(new EventLoop);
    eventLoop->init(EventLoop::MainEventLoop);
    String data;

    if (!file.isEmpty()) {
        data = file.readAll();
    } else {
        uint32_t size;
        if (!fread(&size, sizeof(size), 1, stdin)) {
            error() << "Failed to read from stdin";
            return 1;
        }
        data.resize(size);
        if (!fread(&data[0], size, 1, stdin)) {
            error() << "Failed to read from stdin";
            return 2;
        }
        // FILE *f = fopen("/tmp/data", "w");
        // fwrite(data.constData(), data.size(), 1, f);
        // fclose(f);
    }
    ClangIndexer indexer;
    if (!indexer.exec(data)) {
        error() << "ClangIndexer error";
        return 3;
    }

    return 0;
}
Esempio n. 2
0
void ClangIndexer::inclusionVisitor(CXFile includedFile,
                                    CXSourceLocation *includeStack,
                                    unsigned includeLen,
                                    CXClientData userData)
{
    ClangIndexer *indexer = static_cast<ClangIndexer*>(userData);
    const Location l = indexer->createLocation(includedFile, 1, 1);

    const uint32_t fileId = l.fileId();
    if (!includeLen) {
        indexer->mData->dependencies[fileId].insert(fileId);
    } else {
        for (unsigned i=0; i<includeLen; ++i) {
            CXFile originatingFile;
            clang_getSpellingLocation(includeStack[i], &originatingFile, 0, 0, 0);
            const Location loc = indexer->createLocation(originatingFile, 1, 1);
            const uint32_t f = loc.fileId();
            if (f)
                indexer->mData->dependencies[fileId].insert(f);
        }
    }
}
Esempio n. 3
0
int main(int argc, char **argv)
{
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
    LogLevel logLevel = LogLevel::Error;
    Path file;
    bool logToSyslog = false;
    bool daemon = false;

    for (int i=1; i<argc; ++i) {
        if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) {
            ++logLevel;
        } else if (!strcmp(argv[i], "--priority")) { // ignore, only for wrapping purposes
            ++i;
        } else if (!strcmp(argv[i], "--log-to-syslog")) {
            logToSyslog = true;
        } else if (!strcmp(argv[i], "--daemon")) {
            daemon = true;
        } else {
            file = argv[i];
        }
    }

    if (const char *env = getenv("TMPDIR")) { // should really always be set by rdm
        Path path = Path(env).ensureTrailingSlash();
        path += String::number(getpid());
        path.mkdir(Path::Recursive);
        setenv("TMPDIR", path.c_str(), 1);
    }
    if (!daemon)
        setenv("LIBCLANG_NOTHREADS", "1", 0);
    signal(SIGSEGV, sigHandler);
    signal(SIGABRT, sigHandler);
    signal(SIGBUS, sigHandler);
    signal(SIGALRM, [](int) {
        ClangIndexer::transition(ClangIndexer::Stopped);
    });

    Flags<LogFlag> logFlags = LogStderr;
    std::shared_ptr<SyslogCloser> closer;
    if (logToSyslog & Server::RPLogToSyslog) {
        logFlags |= LogSyslog;
        closer.reset(new SyslogCloser);
    }
    initLogging(argv[0], logFlags, logLevel);
    (void)closer;

    RTags::initMessages();
    auto eventLoop = std::make_shared<EventLoop>();
    eventLoop->init(EventLoop::MainEventLoop);
    ClangIndexer indexer;
    while (true) {
        String data;

        if (!file.isEmpty()) {
            data = file.readAll();
        } else {
            uint32_t size;
            if (!fread(&size, sizeof(size), 1, stdin)) {
                error() << "Failed to read from stdin";
                return 1;
            }
            data.resize(size);
            if (!fread(&data[0], size, 1, stdin)) {
                error() << "Failed to read from stdin";
                return 2;
            }
            // FILE *f = fopen("/tmp/data", "w");
            // fwrite(data.constData(), data.size(), 1, f);
            // fclose(f);
        }
        if (!indexer.exec(data)) {
            error() << "ClangIndexer error";
            return 3;
        }

        if (daemon) {
            if (ClangIndexer::state() == ClangIndexer::Running) {
                printf("@FINISHED@");
                fflush(stdout);
            }
            ClangIndexer::transition(ClangIndexer::NotStarted);
        } else {
            break;
        }
    }

    return 0;
}
Esempio n. 4
0
CXChildVisitResult ClangIndexer::indexVisitor(CXCursor cursor, CXCursor parent, CXClientData data)
{
    ClangIndexer *indexer = static_cast<ClangIndexer*>(data);
    // error() << "indexVisitor" << cursor;
    // FILE *f = fopen("/tmp/clangindex.log", "a");
    // String str;
    // Log(&str) << cursor;
    // fwrite(str.constData(), 1, str.size(), f);
    // fwrite("\n", 1, 1, f);
    // fclose(f);
    const LastCursorUpdater updater(indexer->mLastCursor, cursor);

    const CXCursorKind kind = clang_getCursorKind(cursor);
    const RTags::CursorType type = RTags::cursorType(kind);
    if (type == RTags::Other)
        return CXChildVisit_Recurse;

    bool blocked = false;

    Location loc = indexer->createLocation(cursor, &blocked);
    if (blocked) {
        // error() << "blocked" << cursor;
        ++indexer->mBlocked;
        return CXChildVisit_Continue;
    } else if (loc.isNull()) {
        // error() << "Got null" << cursor;
        return CXChildVisit_Recurse;
    }
    ++indexer->mAllowed;
    if (indexer->mLogFile) {
        String out;
        Log(&out) << cursor;
        fwrite(out.constData(), 1, out.size(), indexer->mLogFile);
        fwrite("\n", 1, 1, indexer->mLogFile);
    }

    if (testLog(VerboseDebug)) {
        Log log(VerboseDebug);
        log << cursor;
        CXCursor ref = clang_getCursorReferenced(cursor);
        if (!clang_isInvalid(clang_getCursorKind(ref)) && !clang_equalCursors(ref, cursor)) {
            log << "refs" << ref;
        }
    }
    switch (type) {
    case RTags::Cursor:
        indexer->handleCursor(cursor, kind, loc);
        break;
    case RTags::Include:
        indexer->handleInclude(cursor, kind, loc);
        break;
    case RTags::Reference:
        switch (kind) {
        case CXCursor_OverloadedDeclRef: {
            const int count = clang_getNumOverloadedDecls(cursor);
            for (int i=0; i<count; ++i) {
                const CXCursor ref = clang_getOverloadedDecl(cursor, i);
                indexer->handleReference(cursor, kind, loc, ref, parent);
            }
            break; }
        case CXCursor_CXXDeleteExpr:
            indexer->handleReference(cursor, kind, loc, findDestructorForDelete(cursor), parent);
            break;
        case CXCursor_CallExpr: {
            // uglehack, see rtags/tests/nestedClassConstructorCallUgleHack/
            const CXCursor ref = clang_getCursorReferenced(cursor);
            if (clang_getCursorKind(ref) == CXCursor_Constructor
                && clang_getCursorKind(indexer->mLastCursor) == CXCursor_TypeRef
                && clang_getCursorKind(parent) != CXCursor_VarDecl) {
                loc = indexer->createLocation(indexer->mLastCursor);
                indexer->handleReference(indexer->mLastCursor, kind, loc, ref, parent);
            } else {
                indexer->handleReference(cursor, kind, loc, ref, parent);
            }
            break; }
        default:
            indexer->handleReference(cursor, kind, loc, clang_getCursorReferenced(cursor), parent);
            break;
        }
        break;
    case RTags::Other:
        assert(0);
        break;
    }
    return CXChildVisit_Recurse;
}