Пример #1
0
void
ast_json::record_extent(json_t& obj, CXSourceRange extent)
{
    CXSourceLocation startlocation = clang_getRangeStart( extent );
    CXSourceLocation endlocation   = clang_getRangeEnd( extent );

    // Get exact source locations
    unsigned int startline = 0, startcolumn = 0, startoffset = 0;
    unsigned int endline   = 0, endcolumn   = 0, endoffset   = 0;

    clang_getSpellingLocation(
        startlocation, nullptr, &startline, &startcolumn, &startoffset );

    clang_getSpellingLocation(
          endlocation, nullptr,   &endline,   &endcolumn,   &endoffset );

    // Record source location
    obj[node::START_LINE] = startline;
    obj[node::START_COLUMN] = startcolumn;
    obj[node::START_OFFSET] = startoffset;

    obj[node::END_LINE] = endline;
    obj[node::END_COLUMN] = endcolumn;
    obj[node::END_OFFSET] = endoffset;
}
Пример #2
0
Diagnostic DiagnosticWrapToDiagnostic( DiagnosticWrap diagnostic_wrap ) {
  Diagnostic diagnostic;

  if ( !diagnostic_wrap )
    return diagnostic;

  diagnostic.kind_ = DiagnosticSeverityToType(
                       clang_getDiagnosticSeverity( diagnostic_wrap.get() ) );

  // If this is an "ignored" diagnostic, there's no point in continuing since we
  // won't display those to the user
  if ( diagnostic.kind_ == 'I' )
    return diagnostic;

  CXSourceLocation location = clang_getDiagnosticLocation( diagnostic_wrap.get() );
  CXFile file;
  uint unused_offset;
  clang_getSpellingLocation( location,
                             &file,
                             &diagnostic.line_number_,
                             &diagnostic.column_number_,
                             &unused_offset );

  diagnostic.filename_ = CXFileToFilepath( file );
  diagnostic.text_ = CXStringToString(
                       clang_getDiagnosticSpelling( diagnostic_wrap.get() ) );
  diagnostic.long_formatted_text_ = FullDiagnosticText( diagnostic_wrap.get() );

  return diagnostic;
}
Пример #3
0
static CXCursor getCursorUsingTokens(CXTranslationUnit tu, CXCursor cursor,
        unsigned int desiredOffset)
    {
    // The following does not return a more definitive cursor.
    // For example, if a compound statement is returned, this does not find
    // any variables in the statement.
    CXSourceRange range = clang_getCursorExtent(cursor);
    CXToken *tokens;
    unsigned numTokens;
    clang_tokenize(tu, range, &tokens, &numTokens);
    unsigned int closestOffset = 0;
    for(unsigned int i=0; i<numTokens; i++)
        {
        CXSourceLocation loc = clang_getTokenLocation(tu, tokens[i]);
        unsigned int offset;
        CXFile file;
        clang_getSpellingLocation(loc, &file, nullptr, nullptr, &offset);
        if(offset < desiredOffset && offset > closestOffset)
            {
            closestOffset = offset;
            cursor = clang_getCursor(tu, loc);
            }
        }
    clang_disposeTokens(tu, tokens, numTokens);
    return cursor;
    }
Пример #4
0
void IndexerJob::inclusionVisitor(CXFile includedFile,
                                  CXSourceLocation *includeStack,
                                  unsigned includeLen,
                                  CXClientData userData)
{
    IndexerJob *job = static_cast<IndexerJob*>(userData);
    const Location l(includedFile, 0);

    const Path path = l.path();
    job->mData->symbolNames[path].insert(l);
    const char *fn = path.fileName();
    job->mData->symbolNames[String(fn, strlen(fn))].insert(l);

    const uint32_t fileId = l.fileId();
    if (!includeLen) {
        job->mData->dependencies[fileId].insert(fileId);
    } else {
        for (unsigned i=0; i<includeLen; ++i) {
            CXFile originatingFile;
            clang_getSpellingLocation(includeStack[i], &originatingFile, 0, 0, 0);
            Location loc(originatingFile, 0);
            const uint32_t f = loc.fileId();
            if (f)
                job->mData->dependencies[fileId].insert(f);
        }
    }
}
Пример #5
0
string CursorHelper::getFileName(CXCursor cursor)
{
  CXFile file;
  clang_getSpellingLocation(clang_getCursorLocation(cursor), &file, 0, 0, 0);
  CXString fileStr = clang_getFileName(file);
  string fileName(clang_getCString(fileStr));
  clang_disposeString(fileStr);
  return fileName;
}
Пример #6
0
void ClangIndexer::superclassTemplateMemberFunctionUgleHack(const CXCursor &cursor, CXCursorKind kind,
                                                            const Location &location, const CXCursor &ref,
                                                            const CXCursor &parent)
{
    // This is for references to superclass template functions. Awful awful
    // shit. See https://github.com/Andersbakken/rtags/issues/62 and commit
    // for details. I really should report this as a bug.
    if (kind == CXCursor_MemberRefExpr && clang_getCursorKind(parent) == CXCursor_CallExpr) {
        const CXCursor templateRef = RTags::findChild(cursor, CXCursor_TemplateRef);
        if (templateRef == CXCursor_TemplateRef) {
            const CXCursor classTemplate = clang_getCursorReferenced(templateRef);
            if (classTemplate == CXCursor_ClassTemplate) {
                FILE *f = fopen(location.path().constData(), "r");
                if (f) {
                    const CXSourceRange range = clang_getCursorExtent(cursor);
                    const CXSourceLocation end = clang_getRangeEnd(range);
                    unsigned offset;
                    clang_getSpellingLocation(end, 0, 0, 0, &offset);

                    String name;
                    while (offset > 0) {
                        fseek(f, --offset, SEEK_SET);
                        char ch = static_cast<char>(fgetc(f));
                        if (isalnum(ch) || ch == '_' || ch == '~') {
                            name.prepend(ch);
                        } else {
                            break;
                        }
                    }
                    fclose(f);
                    if (!name.isEmpty()) {
                        RTags::Filter out;
                        out.kinds.insert(CXCursor_MemberRefExpr);
                        const int argCount = RTags::children(parent, RTags::Filter(), out).size();
                        RTags::Filter in(RTags::Filter::And);
                        in.names.insert(name);
                        in.argumentCount = argCount;
                        const List<CXCursor> alternatives = RTags::children(classTemplate, in);
                        switch (alternatives.size()) {
                        case 1:
                            // ### not sure this is correct with line/col
                            handleReference(cursor, kind, Location(location.fileId(), location.line(), location.column() + 1), alternatives.first(), parent);
                            break;
                        case 0:
                            break;
                        default:
                            warning() << "Can't decide which of these cursors are right for me"
                                      << cursor << alternatives
                                      << "Need to parse types";
                            break;
                        }
                    }
                }
            }
        }
    }
}
/**
 * CXSourceLocation - 4-byte number, we need to call clang_getSpellingLocation
 * or clang_getExpansionLocation to retrieve line, column and file name.
 */
void Generator::getLocationParts(const CXSourceLocation &location, std::string &fileName, unsigned &line, unsigned &column) const
{
    CXFile file;
    unsigned offset = 0;
    clang_getSpellingLocation(location, &file, &line, &column, &offset);
    (void)offset;

    fileName = stringize(clang_getFileName(file));
}
Пример #8
0
int ClangParser::Private::getCurrentTokenLine()
{
  uint l, c;
  if (numTokens==0) return 1;
  // guard against filters that reduce the number of lines
  if (curToken>=numTokens) curToken=numTokens-1;
  CXSourceLocation start = clang_getTokenLocation(tu,tokens[curToken]);
  clang_getSpellingLocation(start, 0, &l, &c, 0);
  return l;
}
Пример #9
0
std::string libclang_vim::stringize_location(CXSourceLocation const& location) {
    CXFile file;
    unsigned int line, column, offset;
    clang_getSpellingLocation(location, &file, &line, &column, &offset);
    cxstring_ptr file_name = clang_getFileName(file);

    return "'line':" + std::to_string(line) + ",'column':" +
           std::to_string(column) + ",'offset':" + std::to_string(offset) +
           ',' + stringize_key_value("file", file_name);
}
Пример #10
0
static CXChildVisitResult visitTranslationUnit(CXCursor cursor, CXCursor parent,
        CXClientData client_data)
    {
    visitTranslationUnitData *data = static_cast<visitTranslationUnitData*>(client_data);
    CXSourceRange range = clang_getCursorExtent(cursor);
    CXSourceLocation startLoc = clang_getRangeStart(range);
    CXSourceLocation endLoc = clang_getRangeEnd(range);
    CXFile file;
    unsigned startOffset;
    unsigned endOffset;
    clang_getSpellingLocation(startLoc, &file, nullptr, nullptr, &startOffset);
    clang_getSpellingLocation(endLoc, &file, nullptr, nullptr, &endOffset);
    // Use the smallest cursor that surrounds the desired location.
    unsigned size = endOffset - startOffset;
    if(clangFilesEqual(file, data->mFile) &&
            startOffset < data->mDesiredOffset && endOffset > data->mDesiredOffset)
        {
        if(size < data->mSize)
            {
            data->mCursor = cursor;
            data->mSize = size;

            fprintf(sLog.mFp, "GOOD:\n   ");
            }
        }
    CXStringDisposer sp = clang_getCursorSpelling(cursor);
    CXStringDisposer kind = clang_getCursorKindSpelling(cursor.kind);
    std::string fn;
    if(file)
        {
        CXStringDisposer s = clang_getFileName(file);
        fn = s;
        }
    fprintf(sLog.mFp, "%s %s off %d size %d des offset %d file %s\n",
            kind.c_str(), sp.c_str(), startOffset,
            size, data->mDesiredOffset, fn.c_str());
    DUMP_PARSE("visitTU", cursor);
//    clang_visitChildren(cursor, ::visitTranslationUnit, client_data);
//    return CXChildVisit_Continue;
    return CXChildVisit_Recurse;
    }
Пример #11
0
Location IndexerJob::createLocation(const CXCursor &cursor)
{
    CXSourceLocation location = clang_getCursorLocation(cursor);
    if (!clang_equalLocations(location, nullLocation)) {
        CXFile file;
        unsigned start;
        clang_getSpellingLocation(location, &file, 0, 0, &start);
        if (file) {
            return Location(file, start);
        }
    }
    return Location();
}
/**
 * CXSourceLocation - 4-байтное число, для извлечения имени файла и позиции в
 * файле потребуется один из вызовов clang_getSpellingLocation или
 * clang_getExpansionLocation
 */
void decodeLocation(const CXSourceLocation &location,
                    std::string &fileName,
                    unsigned &line,
                    unsigned &column)
{
    CXFile file;
    unsigned offset;
    clang_getSpellingLocation(location, &file, &line, &column, &offset);
    (void)offset;

    CXString cxName = clang_getFileName(file);
    fileName = clang_getCString(cxName);
    clang_disposeString(cxName);
}
Пример #13
0
static void printCursor(CXCursor cursor)
{
    CXFile file;
    unsigned int off, line, col;
    CXSourceLocation location = clang_getCursorLocation(cursor);
    clang_getSpellingLocation(location, &file, &line, &col, &off);
    CXString fileName = clang_getFileName(file);
    const char *fileNameCStr = clang_getCString(fileName);
    if (fileNameCStr) {
        CXSourceRange range = clang_getCursorExtent(cursor);
        unsigned int start, end;
        clang_getSpellingLocation(clang_getRangeStart(range), 0, 0, 0, &start);
        clang_getSpellingLocation(clang_getRangeEnd(range), 0, 0, 0, &end);
        printf("%s:%d:%d (%d, %d-%d) ", fileNameCStr, line, col, off, start, end);
    }
    clang_disposeString(fileName);
    printString("kind", clang_getCursorKindSpelling(clang_getCursorKind(cursor)));
    printString("display name", clang_getCursorDisplayName(cursor));
    printString("usr", clang_getCursorUSR(cursor));
    if (clang_isCursorDefinition(cursor))
        printf("definition ");
    printf("\n");
}
Пример #14
0
void ClangUtils::GetCursorLocation(CXCursor cursor, wxString& filename, unsigned& line, unsigned& col)
{
	CXSourceLocation loc = clang_getCursorLocation(cursor);

	CXFile file;
	unsigned off;
	
	line = 1, col = 1;
	clang_getSpellingLocation(loc, &file, &line, &col, &off);

	CXString strFileName = clang_getFileName(file);
	filename = wxString(clang_getCString(strFileName), wxConvUTF8);
	clang_disposeString(strFileName);
}
Пример #15
0
location::location(const CXSourceLocation loc)
{
    CXFile file;
    unsigned line;
    unsigned column;
    unsigned offset;
    clang_getSpellingLocation(loc, &file, &line, &column, &offset);
    if (file == nullptr)
        throw exception::invalid("No file has attached to a source location");
    DCXString filename = {clang_getFileName(static_cast<CXFile>(file))};
    m_file = clang_getCString(filename);
    assert("Sanity check" && m_file.isValid() && !m_file.isEmpty());
    m_file.cleanPath();
    m_line = line;
    m_column = column;
    m_offset = offset;
}
Пример #16
0
bool filterByFilename(CXCursor cu) {
	// hardcoded to exclude anything from '/usr/include' - todo: take a list of paths to accept/ reject
	bool ret=true;
	CXSourceLocation srcLoc = clang_getCursorLocation(cu);
	CXFile file;
	clang_getSpellingLocation(srcLoc,&file,0,0,0);
	CXString filename = clang_getFileName(file);
	const char* szfilename=clang_getCString(filename);
	const char* exclude_path="/usr/include";
	if (szfilename) {
		const char* s1=szfilename,*s2=exclude_path;
		while (*s1 && *s2) { if (*s1!=*s2) break; s1++,s2++; }
		if (!*s2) ret=false;
		if (!ret) {printf("filtered out %s\n", szfilename);}
	}
	clang_disposeString(filename);

	return	ret;
}
Пример #17
0
CXChildVisitResult visitor( CXCursor cursor, CXCursor parent, CXClientData d )
{
  auto range = clang_getCursorExtent( cursor );
  auto space = reinterpret_cast<int>( d );
  if ( space > 0 )
    std::cout << std::setw( space ) << " ";
  std::cout << cursor << " " << range << "\n";
  space += 2;

  auto location = clang_getCursorLocation( cursor );
  CXFile thisfile;
  clang_getSpellingLocation( location, &thisfile, NULL, NULL, NULL );

  if ( cursor.kind != CXCursor_InclusionDirective &&
       clang_getFile( tu, filename.c_str() ) == thisfile )
    clang_visitChildren( cursor, visitor, reinterpret_cast<CXClientData>(space) );
  
  return CXChildVisit_Continue;
}
void QAnnotatedTokenSet::dump(std::string &str){
    Q_D(QAnnotatedTokenSet);
    CXString displayName = clang_getCursorDisplayName(d->cursor);
    str.append("Cursor :");
    str.append(clang_getCString(displayName));
    str.append("\n Tokens :");
    clang_disposeString(displayName);

    for ( QAnnotatedTokenSet::Iterator it = begin(); it != end(); ++it ){
        CXString tokenString           = clang_getTokenSpelling(d->translationUnit, (*it)->token().token);
        CXSourceLocation tokenLocation = clang_getTokenLocation(d->translationUnit, (*it)->token().token);
        unsigned int column, line;
        clang_getSpellingLocation(tokenLocation, 0, &line, &column, 0);
        std::stringstream stream;
        stream << " (" << line << "," << column << ") \"";
        str.append(stream.str() + clang_getCString(tokenString) + "\"");
        clang_disposeString(tokenString);
    }
    str.append("\n");
}
Пример #19
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);
        }
    }
}
Пример #20
0
Location IndexerJob::createLocation(const CXSourceLocation &location, bool *blocked)
{
    Location ret;
    if (blocked)
        *blocked = false;
    if (!clang_equalLocations(location, nullLocation)) {
        CXFile file;
        unsigned start;
        clang_getSpellingLocation(location, &file, 0, 0, &start);
        if (file) {
            String fileName = RTags::eatString(clang_getFileName(file));
            uint32_t &fileId = mFileIds[fileName];
            if (!fileId)
                fileId = Location::insertFile(Path::resolved(fileName));
            ret = Location(fileId, start);
            if (blocked) {
                if (mVisitedFiles.contains(fileId)) {
                    *blocked = false;
                } else if (mBlockedFiles.contains(fileId)) {
                    *blocked = true;
                    ret.clear();
                } else {
                    shared_ptr<Project> p = project();
                    const bool ok = p && p->visitFile(fileId);
                    *blocked = !ok;
                    if (!ok) {
                        ret.clear();
                        mBlockedFiles.insert(fileId);
                    } else {
                        mVisitedFiles.insert(fileId);
                    }
                }
            }
        }
    }
    return ret;
}
Пример #21
0
string CursorHelper::getColumnNumber(CXCursor cursor)
{
  unsigned column;
  clang_getSpellingLocation(clang_getCursorLocation(cursor), 0, 0, &column, 0);
  return itoa(column);
}
Пример #22
0
bool IndexerJob::diagnose(int build, int *errorCount)
{
    if (errorCount)
        *errorCount = 0;
    if (!mUnits.at(build).second) {
        abort();
        return false;
    }

    List<String> compilationErrors;
    const unsigned diagnosticCount = clang_getNumDiagnostics(mUnits.at(build).second);
    const unsigned options = Server::instance()->options().options;

    for (unsigned i=0; i<diagnosticCount; ++i) {
        CXDiagnostic diagnostic = clang_getDiagnostic(mUnits.at(build).second, i);
        int logLevel = INT_MAX;
        const CXDiagnosticSeverity severity = clang_getDiagnosticSeverity(diagnostic);
        switch (severity) {
        case CXDiagnostic_Fatal:
        case CXDiagnostic_Error:
            if (errorCount)
                ++*errorCount;
            logLevel = Error;
            break;
        case CXDiagnostic_Warning:
            logLevel = Warning;
            break;
        case CXDiagnostic_Note:
            logLevel = Debug;
            break;
        case CXDiagnostic_Ignored:
            break;
        }

        const unsigned diagnosticOptions = (CXDiagnostic_DisplaySourceLocation|
                                            CXDiagnostic_DisplayColumn|
                                            CXDiagnostic_DisplaySourceRanges|
                                            CXDiagnostic_DisplayOption|
                                            CXDiagnostic_DisplayCategoryId|
                                            CXDiagnostic_DisplayCategoryName);
        const uint32_t fileId = createLocation(clang_getDiagnosticLocation(diagnostic), 0).fileId();
        if (mVisitedFiles.contains(fileId)) {
            const String text = RTags::eatString(clang_formatDiagnostic(diagnostic, diagnosticOptions));
            if (testLog(logLevel) || testLog(CompilationError)) {
                log(logLevel, "%s: %s => %s", mSourceInformation.sourceFile.constData(), mClangLines.at(build).constData(), text.constData());
                compilationErrors.append(text);
            }

            const unsigned fixItCount = clang_getDiagnosticNumFixIts(diagnostic);
            RegExp rx;
            if (options & Server::IgnorePrintfFixits) {
                rx = "^%[A-Za-z0-9]\\+$";
            }
            for (unsigned f=0; f<fixItCount; ++f) {
                CXSourceRange range;
                const String string = RTags::eatString(clang_getDiagnosticFixIt(diagnostic, f, &range));
                unsigned startOffset;
                CXFile file;
                clang_getSpellingLocation(clang_getRangeStart(range), &file, 0, 0, &startOffset);
                unsigned endOffset;
                clang_getSpellingLocation(clang_getRangeEnd(range), 0, 0, 0, &endOffset);
                const Location loc(file, startOffset);
                if (options & Server::IgnorePrintfFixits && rx.indexIn(string) == 0) {
                    error("Ignored fixit for %s: Replace %d-%d with [%s]", loc.path().constData(),
                          startOffset, endOffset, string.constData());
                } else {
                    error("Fixit for %s: Replace %d-%d with [%s]", loc.path().constData(),
                          startOffset, endOffset, string.constData());
                    compilationErrors.append(String::format<128>("Fixit for %s: Replace %d-%d with [%s]", loc.path().constData(),
                                                                 startOffset, endOffset, string.constData()));
                    mData->fixIts[loc.fileId()].insert(FixIt(startOffset, endOffset, string));
                }
            }
        }

        clang_disposeDiagnostic(diagnostic);
    }
    if (testLog(CompilationError))
        sendDiagnostics(compilationErrors);
    return !isAborted();
}
Пример #23
0
bool IndexerJob::handleCursor(const CXCursor &cursor, CXCursorKind kind, const Location &location)
{
    CursorInfo &info = mData->symbols[location];
    if (!info.symbolLength || !RTags::isCursor(info.kind)) {
        CXStringScope name = clang_getCursorSpelling(cursor);
        const char *cstr = name.data();
        info.symbolLength = cstr ? strlen(cstr) : 0;
        info.type = clang_getCursorType(cursor).kind;
        if (!info.symbolLength) {
            // this is for these constructs:
            // typedef struct {
            //    int a;
            // } foobar;
            //
            // We end up not getting a spelling for the cursor

            switch (kind) {
            case CXCursor_ClassDecl:
                info.symbolLength = 5;
                info.symbolName = "class";
                break;
            case CXCursor_UnionDecl:
                info.symbolLength = 5;
                info.symbolName = "union";
                break;
            case CXCursor_StructDecl:
                info.symbolLength = 6;
                info.symbolName = "struct";
                break;
            default:
                mData->symbols.remove(location);
                return false;
            }
        } else {
            info.symbolName = addNamePermutations(cursor, location);
        }

        CXSourceRange range = clang_getCursorExtent(cursor);
        unsigned start, end;
        clang_getSpellingLocation(clang_getRangeStart(range), 0, 0, 0, &start);
        clang_getSpellingLocation(clang_getRangeEnd(range), 0, 0, 0, &end);
        info.start = start;
        info.end = end;

        if (kind == CXCursor_EnumConstantDecl) {
#if CLANG_VERSION_MINOR > 1
            info.enumValue = clang_getEnumConstantDeclValue(cursor);
#else
            info.definition = clang_isCursorDefinition(cursor);
#endif
        } else{
            info.definition = clang_isCursorDefinition(cursor);
        }
        info.kind = kind;
        const String usr = RTags::eatString(clang_getCursorUSR(cursor));
        if (!usr.isEmpty())
            mData->usrMap[usr].insert(location);

        switch (info.kind) {
        case CXCursor_Constructor:
        case CXCursor_Destructor: {
            Location parentLocation = createLocation(clang_getCursorSemanticParent(cursor));
            // consider doing this for only declaration/inline definition since
            // declaration and definition should know of one another
            if (parentLocation.isValid()) {
                CursorInfo &parent = mData->symbols[parentLocation];
                parent.references.insert(location);
                info.references.insert(parentLocation);
            }
            break; }
        case CXCursor_CXXMethod: {
            List<CursorInfo*> infos;
            infos.append(&info);
            addOverriddenCursors(cursor, location, infos);
            break; }
        default:
            break;
        }
    }

    return true;
}
Пример #24
0
void IndexerJob::handleReference(const CXCursor &cursor, CXCursorKind kind, const Location &location, const CXCursor &ref, const CXCursor &parent)
{
    const CXCursorKind refKind = clang_getCursorKind(ref);
    if (clang_isInvalid(refKind)) {
        superclassTemplateMemberFunctionUgleHack(cursor, kind, location, ref, parent);
        return;
    }

    bool isOperator = false;
    if (kind == CXCursor_CallExpr && (refKind == CXCursor_CXXMethod
                                      || refKind == CXCursor_ConversionFunction
                                      || refKind == CXCursor_FunctionDecl
                                      || refKind == CXCursor_FunctionTemplate)) {
        // these are bullshit, for this construct:
        // foo.bar();
        // the position of the cursor is at the foo, not the bar.
        // They are not interesting for followLocation, renameSymbol or find
        // references so we toss them.
        // For functions it can be the position of the namespace.
        // E.g. Foo::bar(); cursor is on Foo
        // For constructors they happen to be the only thing we have that
        // actually refs the constructor and not the class so we have to keep
        // them for that.
        return;
    }

    switch (refKind) {
    case CXCursor_Constructor:
        if (isImplicit(ref))
            return;
        break;
    case CXCursor_CXXMethod:
    case CXCursor_FunctionDecl:
    case CXCursor_FunctionTemplate: {
        CXStringScope scope = clang_getCursorDisplayName(ref);
        const char *data = scope.data();
        if (data) {
            const int len = strlen(data);
            if (len > 8 && !strncmp(data, "operator", 8) && !isalnum(data[8]) && data[8] != '_') {
                if (isImplicit(ref))
                    return; // eat implicit operator calls
                isOperator = true;
            }
        }
        break; }
    default:
        break;
    }

    const Location reffedLoc = createLocation(ref, 0);
    if (!reffedLoc.isValid())
        return;

    CursorInfo &refInfo = mData->symbols[reffedLoc];
    if (!refInfo.symbolLength && !handleCursor(ref, refKind, reffedLoc))
        return;

    refInfo.references.insert(location);

    CursorInfo &info = mData->symbols[location];
    info.targets.insert(reffedLoc);

    // We need the new cursor to replace the symbolLength. This is important
    // in the following case:
    // struct R { R(const &r); ... }
    // R foo();
    // ...
    // R r = foo();

    // The first cursor on foo() will be a reference to the copy constructor and
    // this cursor will have a symbolLength of 1. Thus you won't be able to jump
    // to foo from the o. This is fixed by making sure the newer target, if
    // better, gets to decide on the symbolLength

    // The !isCursor is var decls and field decls where we set up a target even
    // if they're not considered references

    if (!RTags::isCursor(info.kind) && (!info.symbolLength || info.bestTarget(mData->symbols).kind == refKind)) {
        CXSourceRange range = clang_getCursorExtent(cursor);
        unsigned start, end;
        clang_getSpellingLocation(clang_getRangeStart(range), 0, 0, 0, &start);
        clang_getSpellingLocation(clang_getRangeEnd(range), 0, 0, 0, &end);
        info.start = start;
        info.end = end;
        info.definition = false;
        info.kind = kind;
        info.symbolLength = isOperator ? end - start : refInfo.symbolLength;
        info.symbolName = refInfo.symbolName;
        info.type = clang_getCursorType(cursor).kind;
        switch (kind) {
        case CXCursor_CallExpr:
            nestedClassConstructorCallUgleHack(parent, info, refKind, reffedLoc);
            // see rtags/tests/nestedClassConstructorCallUgleHack/
            break;
        default:
            break;
        }
    }
    Set<Location> &val = mData->references[location];
    val.insert(reffedLoc);
}
Пример #25
0
 SourceLocation getSourceLocation(CXSourceLocation location) const
 {
     unsigned line, column;
     clang_getSpellingLocation(location, 0, &line, &column, 0);
     return std::make_pair(line, column);
 }
Пример #26
0
String cursorToString(CXCursor cursor, unsigned flags)
{
    const CXCursorKind kind = clang_getCursorKind(cursor);
    String ret;
    ret.reserve(256);
    ret += eatString(clang_getCursorKindSpelling(kind));
    if (clang_isInvalid(kind))
        return ret;

    switch (RTags::cursorType(kind)) {
    case Reference:
        ret += " r";
        break;
    case Cursor:
        ret += " c";
        break;
    case Other:
        ret += " o";
        break;
    case Include:
        ret += " i";
        break;
    }

    const String name = eatString(clang_getCursorDisplayName(cursor));
    const String other = eatString(clang_getCursorSpelling(cursor));
    if (!name.isEmpty())
        ret += " " + name;
    if (other != name && !other.isEmpty())
        ret += " " + other;

    if (clang_isCursorDefinition(cursor))
        ret += " def";

    if (flags & IncludeUSR)
        ret += " " + eatString(clang_getCursorUSR(cursor));

    CXFile file;
    unsigned off, line, col; //presumedLine, presumedCol, instantiationLoc, expansionLoc;
    CXSourceLocation location = clang_getCursorLocation(cursor);
    clang_getSpellingLocation(location, &file, &line, &col, &off);
    // clang_getPresumedLocation(location, 0, &presumedLine, &presumedCol);
    // clang_getInstantiationLocation(location, 0, 0, 0, &instantiationLoc);
    // clang_getExpansionLocation(location, 0, 0, 0, &expansionLoc);

    const Str fileName(clang_getFileName(file));
    if (fileName.data() && *fileName.data()) {
        ret += ' ';
        ret += fileName.data();
        ret += ',';
        ret += String::number(off);

        if (flags & IncludeRange) {
            ret += " (";
            CXSourceRange range = clang_getCursorExtent(cursor);
            unsigned start, end;
            clang_getSpellingLocation(clang_getRangeStart(range), 0, 0, 0, &start);
            clang_getSpellingLocation(clang_getRangeEnd(range), 0, 0, 0, &end);
            ret += String::number(start);
            ret += '-';
            ret += String::number(end);
            ret += ')';
        }

        // if (presumedLine != line || presumedCol != col)
        //     ret += String::snprintf<32>("presumed: %d:%d", presumedLine, presumedCol);
        // if (instantiationLoc != off)
        //     ret += String::snprintf<32>("instantiation: %d", instantiationLoc);
        // if (expansionLoc != off)
        //     ret += String::snprintf<32>("expansion: %d", expansionLoc);

    }
    return ret;
}
Пример #27
0
void source_location::spelling_location(CXFile *file, unsigned *line, unsigned *column, unsigned *offset) const
{
    clang_getSpellingLocation(loc, file, line, column, offset);
}
Пример #28
0
void TokenizeSource(CXTranslationUnit tu)
{
    CXSourceRange range =
	    clang_getCursorExtent( clang_getTranslationUnitCursor(tu) );
  
    CXToken *tokens;
    unsigned int token_count;
  
    clang_tokenize( tu, range, &tokens, &token_count );

    //CXCursor cursors[ token_count ];
    //clang_annotateTokens( tu, tokens, token_count, cursors );
    auto cursors = my_annotateTokens( tu, tokens, token_count );
  
    for ( auto t = 0u; t < token_count; ++t ) {
	auto tkind = clang_getTokenKind(tokens[t] );
	auto tspelling = tkind == CXToken_Identifier ?
		CursorKindSpelling( cursors[ t ] ) :
		TokenKindSpelling( tkind );
	auto textent = clang_getTokenExtent( tu, tokens[t] );
	auto tstartloc = clang_getRangeStart( textent );
	auto tendloc = clang_getRangeEnd( textent );

	auto tokspell = clang_getTokenSpelling( tu, tokens[ t ] );
	std::cout << "TokenSpelling: " << tokspell << "\n";
	std::cout << "Cursor: " << cursors[ t ] << "\n";

	// if ( !( cursors[t].kind >= CXCursor_FirstInvalid &&
	// 	    cursors[t].kind <= CXCursor_LastInvalid ) ) {
	//   auto rr = clang_getCursorExtent( cursors[ t ] );
	//   std::cout << "Range: " << rr << "\n";
	// }
    
	// std::cout << clang_getCursorDisplayName( cursors[ t ] ) << "\n";
	// std::cout << "USR: "******"\n";

	unsigned int startoffset, endoffset;
	clang_getSpellingLocation( tstartloc, nullptr, nullptr, nullptr, &startoffset );
	clang_getSpellingLocation( tendloc, nullptr, nullptr, nullptr, &endoffset );
    
	// TODO: testing this hack for int -> identifier instead of keyword
	// but this loses const to an identifier also! fvck!
	if ( tspelling == "Keyword" ) {
	    auto type = clang_getCursorType( cursors[ t ] );
	    auto typekind = type.kind;
	    CXString typespelling;

	    if ( cursors[t].kind == CXCursor_FunctionDecl ||
		 cursors[t].kind == CXCursor_CXXMethod ) {
		type = clang_getResultType( type );
		typekind = type.kind;
		typespelling = clang_getTypeSpelling( type );
	    }
	    else
		typespelling = clang_getTypeSpelling( type );
      
	    // std::cout << "Type = " << type << " kind: " << typekind << "\n";
	    // std::cout << clang_getCString(typespelling) << " <-> " << clang_getCString(tokspell) << "\n";
	    // std::cout << " Const? " << clang_isConstQualifiedType( type ) << "\n";
      
	    if ( (( typekind >= CXType_FirstBuiltin && typekind <= CXType_LastBuiltin ) &&
		  ( std::string(clang_getCString(typespelling)) ==
		    std::string(clang_getCString(tokspell) ) )) ||
		 //	   ( cursors[t].kind == CXCursor_VarDecl ) ||
		 ( cursors[t].kind == CXCursor_ParmDecl ) )
		tspelling = "Identifier";
	}

	//if ( tspelling != "Punctuation" )
	std::cout
		<< startoffset << ":" << endoffset << " @ "
		<< tspelling  << "\n";

	clang_disposeString( tokspell );
    }

    std::cout << "\n" << end_pattern << "\n";

    clang_disposeTokens( tu, tokens, token_count );
}
Пример #29
0
string CursorHelper::getLineNumber(CXCursor cursor)
{
  unsigned line;
  clang_getSpellingLocation(clang_getCursorLocation(cursor), 0, &line, 0, 0);
  return itoa(line);
}
Пример #30
0
void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd)
{
  TooltipManager::instance()->clearTooltips();
  // (re)set global parser state
  g_currentDefinition=0;
  g_currentMemberDef=0;
  g_currentLine=0;
  g_searchForBody=FALSE;
  g_insideBody=FALSE;
  g_bracketCount=0;

  unsigned int line=1,column=1;
  QCString lineNumber,lineAnchor;
  ol.startCodeLine(TRUE);
  writeLineNumber(ol,fd,line);
  for (unsigned int i=0;i<p->numTokens;i++)
  {
    CXSourceLocation start = clang_getTokenLocation(p->tu, p->tokens[i]);
    unsigned int l, c;
    clang_getSpellingLocation(start, 0, &l, &c, 0);
    if (l > line) column = 1;
    while (line<l) 
    { 
      line++; 
      ol.endCodeLine();
      ol.startCodeLine(TRUE);
      writeLineNumber(ol,fd,line);
    } 
    while (column<c) { ol.codify(" "); column++; }
    CXString tokenString = clang_getTokenSpelling(p->tu, p->tokens[i]);
    char const *s = clang_getCString(tokenString);
    CXCursorKind cursorKind  = clang_getCursorKind(p->cursors[i]);
    CXTokenKind tokenKind = clang_getTokenKind(p->tokens[i]);
    //printf("%d:%d %s cursorKind=%d tokenKind=%d\n",line,column,s,cursorKind,tokenKind);
    switch (tokenKind)
    {
      case CXToken_Keyword: 
        if (strcmp(s,"operator")==0)
        {
          linkIdentifier(ol,fd,line,column,s,i);
        }
        else
        {
          codifyLines(ol,fd,s,line,column,
              cursorKind==CXCursor_PreprocessingDirective ? "preprocessor" :
              keywordToType(s));
        }
        break;
      case CXToken_Literal: 
        if (cursorKind==CXCursor_InclusionDirective)
        {
          linkInclude(ol,fd,line,column,s);
        }
        else if (s[0]=='"' || s[0]=='\'') 
        {
          codifyLines(ol,fd,s,line,column,"stringliteral");
        }
        else 
        {
          codifyLines(ol,fd,s,line,column);
        }
        break;
      case CXToken_Comment: 
        codifyLines(ol,fd,s,line,column,"comment");
        break;
      default:  // CXToken_Punctuation or CXToken_Identifier
        if (tokenKind==CXToken_Punctuation)
        {
          detectFunctionBody(s);
          //printf("punct %s: %d\n",s,cursorKind);
        }
        switch (cursorKind)
        {
          case CXCursor_PreprocessingDirective:
            codifyLines(ol,fd,s,line,column,"preprocessor");
            break;
          case CXCursor_MacroDefinition:
            codifyLines(ol,fd,s,line,column,"preprocessor");
            break;
          case CXCursor_InclusionDirective:
            linkInclude(ol,fd,line,column,s);
            break;
          case CXCursor_MacroExpansion:
            linkMacro(ol,fd,line,column,s);
            break;
          default:
            if (tokenKind==CXToken_Identifier ||
                (tokenKind==CXToken_Punctuation && // for operators
                 (cursorKind==CXCursor_DeclRefExpr ||
                  cursorKind==CXCursor_MemberRefExpr ||
                  cursorKind==CXCursor_CallExpr ||
                  cursorKind==CXCursor_ObjCMessageExpr)
                 )
               )
            {
              linkIdentifier(ol,fd,line,column,s,i);
              if (Doxygen::searchIndex)
              {
                ol.addWord(s,FALSE);
              }
            }
            else
            {
              codifyLines(ol,fd,s,line,column);
            }
            break;
        }
    }
    clang_disposeString(tokenString);
  }
  ol.endCodeLine();
  TooltipManager::instance()->writeTooltips(ol);
}