Пример #1
0
String CursorInfo::toString(unsigned cursorInfoFlags, unsigned keyFlags) const
{
    String ret = String::format<1024>("SymbolName: %s\n"
                                            "Kind: %s\n"
                                            "Type: %s\n"
                                            "SymbolLength: %u\n"
                                            "%s" // range
                                            "%s" // enumValue
                                            "%s", // definition
                                            symbolName.constData(),
                                            RTags::eatString(clang_getCursorKindSpelling(kind)).constData(),
                                            RTags::eatString(clang_getTypeKindSpelling(type)).constData(),
                                            symbolLength,
                                            start != -1 && end != -1 ? String::format<32>("Range: %d-%d\n", start, end).constData() : "",
                                            kind == CXCursor_EnumConstantDecl ? String::format<32>("Enum Value: %lld\n", enumValue).constData() : "",
                                            isDefinition() ? "Definition\n" : "");

    if (!targets.isEmpty() && !(cursorInfoFlags & IgnoreTargets)) {
        ret.append("Targets:\n");
        for (Set<Location>::const_iterator tit = targets.begin(); tit != targets.end(); ++tit) {
            const Location &l = *tit;
            ret.append(String::format<128>("    %s\n", l.key(keyFlags).constData()));
        }
    }

    if (!references.isEmpty() && !(cursorInfoFlags & IgnoreReferences)) {
        ret.append("References:\n");
        for (Set<Location>::const_iterator rit = references.begin(); rit != references.end(); ++rit) {
            const Location &l = *rit;
            ret.append(String::format<128>("    %s\n", l.key(keyFlags).constData()));
        }
    }
    return ret;
}
Пример #2
0
std::string libclang_vim::stringize_type(CXType const& type) {
    CXTypeKind const type_kind = type.kind;
    cxstring_ptr type_name = clang_getTypeSpelling(type);
    cxstring_ptr type_kind_name = clang_getTypeKindSpelling(type_kind);
    return stringize_key_value("type", type_name) +
           stringize_key_value("type_kind", type_kind_name) +
           stringize_extra_type_info(type);
}
Пример #3
0
std::ostream &operator<<(std::ostream &os, const Type &type)
{
    ClangString typeKindSpelling(clang_getTypeKindSpelling(type.kind()));
    os << typeKindSpelling
       << ": \"" << type.spelling() << "\"";

    return os;
}
Пример #4
0
int main(int argc, char *argv[])
{
  auto index = clang_createIndex(0, 0);
  auto options = clang_defaultEditingTranslationUnitOptions();
  char const *args[] = { "-x", "c++", "-std=c++11" };
  auto arg_count = sizeof( args ) / sizeof( *args );
  filename = argv[1];
  
  CXUnsavedFile *unsaved_files = NULL;
  auto unsaved_file_count = 0;
  
  tu = clang_parseTranslationUnit(index, filename.c_str(), args, arg_count,
				  unsaved_files, unsaved_file_count,
				  options );
  
  if ( !tu ) {
    std::cout << "Translation Unit Parse Failed!\n";
    return -1;
  }

  std::stringstream ss( argv[2] );
  int line, col;

  ss >> line;
  ss.get();
  ss >> col;
  std::cout << "Hello " << line << ":" << col << "\n";

  auto file = clang_getFile( tu, filename.c_str() );
  auto location = clang_getLocation( tu, file, line, col );

  
  clang_visitChildren( clang_getTranslationUnitCursor( tu ), visitor,
		       reinterpret_cast<CXClientData>(0) );
  
  auto cursor = clang_getCursor( tu, location );
  auto refcursor = clang_getCursorReferenced( cursor );
  auto rrefcursor = clang_getCursorReferenced( refcursor );
  auto arf = clang_getTypeKindSpelling( clang_getCursorType( cursor ).kind );
  auto foo = clang_getCanonicalCursor( cursor );
  auto semparent = clang_getCursorSemanticParent( cursor );
  auto lexparent = clang_getCursorLexicalParent( cursor );

  std::cout << cursor << "\n";
  std::cout << refcursor << "\n";
  std::cout << rrefcursor << "\n";
  std::cout << clang_getCString(arf) << "\n";
  std::cout << foo << "\n";
  std::cout << "Parent: " << semparent << "\n";
  std::cout << "LexParent: " << lexparent << "\n";
  
  //clang_visitChildren( semparent, visitor, reinterpret_cast<CXClientData>(0) );
  clang_disposeString( arf );

  return 0;
}
Пример #5
0
String CursorInfo::toString(unsigned cursorInfoFlags, unsigned keyFlags) const
{
    String ret = String::format<1024>("SymbolName: %s\n"
                                      "Kind: %s\n"
                                      "Type: %s\n" // type
                                      "SymbolLength: %u\n"
                                      "%s" // range
                                      "%s" // enumValue
                                      "%s", // definition
                                      symbolName.constData(),
                                      kindSpelling().constData(),
                                      RTags::eatString(clang_getTypeKindSpelling(type)).constData(),
                                      symbolLength,
                                      startLine != -1 ? String::format<32>("Range: %d:%d-%d:%d\n", startLine, startColumn, endLine, endColumn).constData() : "",
#if CINDEX_VERSION_MINOR > 1
                                      kind == CXCursor_EnumConstantDecl ? String::format<32>("Enum Value: %lld\n", enumValue).constData() :
#endif
                                      "",
                                      isDefinition() ? "Definition\n" : "");

    if (!targets.isEmpty() && !(cursorInfoFlags & IgnoreTargets)) {
        ret.append("Targets:\n");
        for (auto tit = targets.begin(); tit != targets.end(); ++tit) {
            const Location &l = *tit;
            ret.append(String::format<128>("    %s\n", l.key(keyFlags).constData()));
        }
    }

    if (!references.isEmpty() && !(cursorInfoFlags & IgnoreReferences)) {
        ret.append("References:\n");
        for (auto rit = references.begin(); rit != references.end(); ++rit) {
            const Location &l = *rit;
            ret.append(String::format<128>("    %s\n", l.key(keyFlags).constData()));
        }
    }
    return ret;
}
Пример #6
0
String Symbol::toString(const std::shared_ptr<Project> &project,
                        const Flags<ToStringFlag> cursorInfoFlags,
                        Flags<Location::ToStringFlag> locationToStringFlags,
                        const Set<String> &pieceFilters) const
{
    auto filterPiece = [&pieceFilters](const char *name) { return pieceFilters.isEmpty() || pieceFilters.contains(name); };
    auto properties = [this, &filterPiece]() -> String {
        List<String> ret;
        if (isDefinition() && filterPiece("definition"))
            ret << "Definition";
        if (isContainer() && filterPiece("container"))
            ret << "Container";
        if ((flags & PureVirtualMethod) == PureVirtualMethod && filterPiece("purevirtual"))
            ret << "Pure Virtual";
        if (flags & VirtualMethod && filterPiece("virtual"))
            ret << "Virtual";

        if (flags & ConstMethod) {
            if (filterPiece("constmethod"))
                ret << "ConstMethod";
        } else if (flags & StaticMethod && filterPiece("static")) {
            ret << "Static";
        }

        if (flags & Variadic && filterPiece("variadic"))
            ret << "Variadic";
        if (flags & Auto && filterPiece("auto"))
            ret << "Auto";

        if (flags & MacroExpansion && filterPiece("macroexpansion"))
            ret << "MacroExpansion";
        if (flags & TemplateSpecialization && filterPiece("templatespecialization"))
            ret << "TemplateSpecialization";
        if (flags & TemplateReference && filterPiece("templatereference"))
            ret << "TemplateReference";

        if (ret.isEmpty())
            return String();
        return String::join(ret, ' ') + '\n';
    };

    List<String> bases;
    List<String> args;

    if (project) {
        if (filterPiece("baseclasses")) {
            for (const auto &base : baseClasses) {
                bool found = false;
                for (const auto &sym : project->findByUsr(base, location.fileId(), Project::ArgDependsOn)) {
                    bases << sym.symbolName;
                    found = true;
                    break;
                }
                if (!found) {
                    bases << base;
                }
            }
        }
        if (filterPiece("arguments")) {
            for (const auto &arg : arguments) {
                const String symName = project->findSymbol(arg.cursor).symbolName;
                if (!symName.isEmpty()) {
                    args << symName;
                } else {
                    args << arg.cursor.toString(locationToStringFlags & ~Location::ShowContext);
                }
            }
        }
    } else if (filterPiece("baseClasses")) {
        bases = baseClasses;
    }

    String ret;
    auto writePiece = [&ret, &filterPiece](const char *key, const char *filter, const String &piece) {
        if (piece.isEmpty())
            return;
        if (!filterPiece(filter))
            return;
        if (key && strlen(key))
            ret << key << ": ";
        ret << piece << "\n";
    };
    writePiece(0, "location", location.toString(locationToStringFlags));
    writePiece("SymbolName", "symbolname", symbolName);
    writePiece("Kind", "kind", kindSpelling());
    if (filterPiece("type")) {
        if (!typeName.isEmpty()) {
            ret += "Type: " + typeName + "\n";
        } else if (type != CXType_Invalid) {
            ret += "Type: " + RTags::eatString(clang_getTypeKindSpelling(type)) + "\n";
        }
    }
    writePiece("SymbolLength", "symbollength", std::to_string(symbolLength));

    if (startLine != -1)
        writePiece("Range", "range", String::format<32>("%d:%d-%d:%d", startLine, startColumn, endLine, endColumn));

#if CINDEX_VERSION_MINOR > 1
    if (kind == CXCursor_EnumConstantDecl)
        writePiece("Enum Value", "enumvalue",
                   String::format<32>("%lld/0x%0llx", static_cast<long long>(enumValue), static_cast<long long>(enumValue)));

    if (isDefinition() && RTags::isFunction(kind))
        writePiece("Stack cost", "stackcost", std::to_string(stackCost));
#endif
    writePiece(0, "linkage", linkageSpelling(linkage));
    ret += properties();
    writePiece("Usr", "usr", usr);
    if (size)
        writePiece("sizeof", "sizeof", std::to_string(size));
    if (fieldOffset >= 0)
        writePiece("Field offset (bits/bytes)", "fieldoffset",
                   String::format<32>("%d/%d", fieldOffset, fieldOffset / 8));
    if (alignment >= 0)
        writePiece("Alignment", "alignment", std::to_string(alignment));
    if (!args.isEmpty())
        writePiece("Arguments", "arguments", String::join(args, ", "));
    if (!bases.isEmpty())
        writePiece("Base classes", "baseclasses", String::join(bases, ", "));
    writePiece("Brief comment", "briefcomment", briefComment);
    writePiece("XML comment", "xmlcomment", xmlComment);

    if ((cursorInfoFlags & IncludeParents && filterPiece("parent"))
        || (cursorInfoFlags & (IncludeContainingFunction) && filterPiece("cf"))
        || (cursorInfoFlags & (IncludeContainingFunctionLocation) && filterPiece("cfl"))) {
        auto syms = project->openSymbols(location.fileId());
        uint32_t idx = -1;
        if (syms) {
            idx = syms->lowerBound(location);
            if (idx == std::numeric_limits<uint32_t>::max()) {
                idx = syms->count() - 1;
            }
        }
        const unsigned int line = location.line();
        const unsigned int column = location.column();
        while (idx-- > 0) {
            const Symbol s = syms->valueAt(idx);
            if (s.isDefinition()
                && s.isContainer()
                && comparePosition(line, column, s.startLine, s.startColumn) >= 0
                && comparePosition(line, column, s.endLine, s.endColumn) <= 0) {
                if (cursorInfoFlags & IncludeContainingFunctionLocation)
                    writePiece("Containing function location", "cfl", s.location.toString(locationToStringFlags));
                if (cursorInfoFlags & IncludeContainingFunction)
                    writePiece("Containing function", "cf", s.symbolName);
                if (cursorInfoFlags & IncludeParents)
                    writePiece("Parent", "parent", s.location.toString(locationToStringFlags)); // redundant, this is a mess
                break;
            }
        }
    }



    if (cursorInfoFlags & IncludeTargets && project && filterPiece("targets")) {
        const auto targets = project->findTargets(*this);
        if (targets.size()) {
            ret.append("Targets:\n");
            auto best = RTags::bestTarget(targets);
            ret.append(String::format<128>("    %s\n", best.location.toString(locationToStringFlags).constData()));

            for (const auto &tit : targets) {
                if (tit.location != best.location)
                    ret.append(String::format<128>("    %s\n", tit.location.toString(locationToStringFlags).constData()));
            }
        }
    }

    if (cursorInfoFlags & IncludeReferences && project && !isReference() && filterPiece("references")) {
        const auto references = project->findCallers(*this);
        if (references.size()) {
            ret.append("References:\n");
            for (const auto &r : references) {
                ret.append(String::format<128>("    %s\n", r.location.toString(locationToStringFlags).constData()));
            }
        }
    }

    return ret;
}
Пример #7
0
std::string cursor::type::kind_spelling()
{
    return string(clang_getTypeKindSpelling(ctype.kind)).str();
}
Пример #8
0
String Symbol::toString(Flags<ToStringFlag> cursorInfoFlags,
                        Flags<Location::ToStringFlag> locationToStringFlags,
                        const std::shared_ptr<Project> &project) const
{
    auto properties = [this]()
        {
            List<String> ret;
            if (isDefinition())
                ret << "Definition";
            if (isContainer())
                ret << "Container";
            if ((flags & PureVirtualMethod) == PureVirtualMethod) {
                ret << "Pure Virtual";
            } else if (flags & VirtualMethod) {
                ret << "Virtual";
            }

            if (flags & ConstMethod) {
                ret << "Const";
            } else if (flags & StaticMethod) {
                ret << "Static";
            }

            if (flags & Variadic)
                ret << "Variadic";
            if (flags & Auto)
                ret << "Auto";
            if (flags & AutoRef)
                ret << "AutoRef";

            if (flags & MacroExpansion)
                ret << "MacroExpansion";
            if (flags & TemplateSpecialization)
                ret << "TemplateSpecialization";

            if (ret.isEmpty())
                return String();
            String joined = String::join(ret, ' ');
            joined += '\n';
            return joined;
        };

    List<String> bases;
    List<String> args;
    if (project) {
        for (const auto &base : baseClasses) {
            bool found = false;
            for (const auto &sym : project->findByUsr(base, location.fileId(), Project::ArgDependsOn, location)) {
                bases << sym.symbolName;
                found = true;
                break;
            }
            if (!found) {
                bases << base;
            }
        }
        for (const auto &arg : arguments) {
            const String symName = project->findSymbol(arg.cursor).symbolName;
            if (!symName.isEmpty()) {
                args << symName;
            } else {
                args << arg.cursor.toString(locationToStringFlags & ~Location::ShowContext);
            }
        }
    } else {
        bases = baseClasses;
    }

    auto printTypeName = [this]() {
        String str;
        if (!typeName.isEmpty()) {
            str = typeName;
        } else if (type != CXType_Invalid) {
            str = RTags::eatString(clang_getTypeKindSpelling(type));
        } else {
            return String();
        }
        return String::format<128>("Type: %s\n", str.constData());
    };

    String ret = String::format<1024>("%s\n"
                                      "SymbolName: %s\n"
                                      "Kind: %s\n"
                                      "%s" // type
                                      "SymbolLength: %u\n"
                                      "%s" // range
                                      "%s" // enumValue/stackCost
                                      "%s" // linkage
                                      "%s" // properties
                                      "%s" // usr
                                      "%s" // sizeof
                                      "%s" // fieldoffset
                                      "%s" // alignment
                                      "%s" // arguments
                                      "%s" // baseclasses
                                      "%s" // briefComment
                                      "%s", // xmlComment
                                      location.toString(locationToStringFlags).constData(),
                                      symbolName.constData(),
                                      kindSpelling().constData(),
                                      printTypeName().constData(),
                                      symbolLength,
                                      startLine != -1 ? String::format<32>("Range: %d:%d-%d:%d\n", startLine, startColumn, endLine, endColumn).constData() : "",
#if CINDEX_VERSION_MINOR > 1
                                      (kind == CXCursor_EnumConstantDecl
                                       ? String::format<32>("Enum Value: %lld/0x%0llx\n",
                                                            static_cast<long long>(enumValue),
                                                            static_cast<long long>(enumValue)).constData()
                                       : (isDefinition() && RTags::isFunction(kind)
                                          ? String::format<32>("Stack cost: %d\n", stackCost).constData()
                                          : "")),
#else
                                      "",
#endif
                                      linkageSpelling(linkage),
                                      properties().constData(),
                                      usr.isEmpty() ? "" : String::format<64>("Usr: %s\n", usr.constData()).constData(),
                                      size > 0 ? String::format<16>("sizeof: %d\n", size).constData() : "",
                                      fieldOffset >= 0 ? String::format<32>("field offset (bits/bytes): %d/%d\n", fieldOffset, fieldOffset / 8).constData() : "",
                                      alignment >= 0 ? String::format<32>("alignment (bytes): %d\n", alignment).constData() : "",
                                      args.isEmpty() ? "" : String::format<1024>("Arguments: %s\n", String::join(args, ", ").constData()).constData(),
                                      bases.isEmpty() ? "" : String::format<64>("BaseClasses: %s\n", String::join(bases, ", ").constData()).constData(),
                                      briefComment.isEmpty() ? "" : String::format<1024>("Brief comment: %s\n", briefComment.constData()).constData(),
                                      xmlComment.isEmpty() ? "" : String::format<16384>("XML comment: %s\n", xmlComment.constData()).constData());
    if (cursorInfoFlags & IncludeTargets && project) {
        const auto targets = project->findTargets(*this);
        if (targets.size()) {
            ret.append("Targets:\n");
            auto best = RTags::bestTarget(targets);
            ret.append(String::format<128>("    %s\n", best.location.toString(locationToStringFlags).constData()));

            for (const auto &tit : targets) {
                if (tit.location != best.location)
                    ret.append(String::format<128>("    %s\n", tit.location.toString(locationToStringFlags).constData()));
            }
        }
    }

    if (cursorInfoFlags & IncludeReferences && project && !isReference()) {
        const auto references = project->findCallers(*this);
        if (references.size()) {
            ret.append("References:\n");
            for (const auto &r : references) {
                ret.append(String::format<128>("    %s\n", r.location.toString(locationToStringFlags).constData()));
            }
        }
    }

    return ret;
}
Пример #9
0
 String Type::GetKindSpelling(CXTypeKind kind)
 {
     return clang_getTypeKindSpelling(kind);
 }
Пример #10
0
json_t* render_type(CXType type) {
  int i;
  CXCursor decl = clang_getTypeDeclaration(type);
  json_t* js = json_object();

  enum CXTypeKind kind = type.kind;
  if (type.kind == CXType_Unexposed) {
    // workaround for libclang bug
    if (clang_getResultType(type).kind != CXType_Invalid) {
      kind = CXType_FunctionProto;
    }
  }


  if (clang_isVolatileQualifiedType(type)) {
    json_object_set_new(js, "volatile", json_true());
  }
  if (clang_isConstQualifiedType(type)) {
    json_object_set_new(js, "const", json_true());
  }
  if (clang_isRestrictQualifiedType(type)) {
    json_object_set_new(js, "restrict", json_true());
  }

  static const struct {
    enum CXTypeKind kind;
    const char* name;
  } PRIMITIVE_TYPES[] = {
    {CXType_Void, "void"},
    {CXType_Bool, "bool"},
    {CXType_Char_U, "char"},
    {CXType_Char_S, "char"},
    {CXType_UChar, "unsigned char"},
    {CXType_SChar, "signed char"},
    {CXType_WChar, "wchar_t"},
    {CXType_Char16, "char16_t"},
    {CXType_Char32, "char32_t"},
    {CXType_Short, "short"},
    {CXType_UShort, "unsigned short"},
    {CXType_Int, "int"},
    {CXType_UInt, "unsigned int"},
    {CXType_Long, "long"},
    {CXType_ULong, "unsigned long"},
    {CXType_LongLong, "unsigned long"},
    {CXType_ULongLong, "unsigned long long"},
    {CXType_Int128, "__int128"},
    {CXType_UInt128, "unsigned __int128"},
    {CXType_Float, "float"},
    {CXType_Double, "double"},
    {CXType_LongDouble, "long double"}
  };


  switch (kind) {
  case CXType_Pointer:
    json_object_set_new(js, "kind", json_string("pointer"));
    json_object_set_new(js, "pointee", render_type(clang_getPointeeType(type)));
    return js;

  case CXType_ConstantArray:
    json_object_set_new(js, "kind", json_string("array"));
    json_object_set_new(js, "element", render_type(clang_getArrayElementType(type)));
    json_object_set_new(js, "length", json_integer(clang_getArraySize(type)));
    return js;
    
  case CXType_FunctionNoProto:
  case CXType_FunctionProto:
    json_object_set_new(js, "kind", json_string("function"));
    json_object_set_new(js, "return", render_type(clang_getResultType(type)));
    switch (clang_getFunctionTypeCallingConv(type)) {
    case CXCallingConv_C:
      json_object_set_new(js, "calling_convention", json_string("cdecl"));
      break;
    case CXCallingConv_X86StdCall:
      json_object_set_new(js, "calling_convention", json_string("stdcall"));
      break;
    case CXCallingConv_X86FastCall:
      json_object_set_new(js, "calling_convention", json_string("fastcall"));
      break;
    case CXCallingConv_X86ThisCall:
      json_object_set_new(js, "calling_convention", json_string("thiscall"));
      break;
    case CXCallingConv_X86Pascal:
      json_object_set_new(js, "calling_convention", json_string("pascal"));
      break;
    case CXCallingConv_AAPCS:
      json_object_set_new(js, "calling_convention", json_string("aapcs"));
      break;
    case CXCallingConv_AAPCS_VFP:
      json_object_set_new(js, "calling_convention", json_string("aapcs-vfp"));
      break;
    default:
      break;
    }
    json_t* arguments = json_array();
    for (i=0; i<clang_getNumArgTypes(type); i++) {
      json_array_append_new(arguments, render_type(clang_getArgType(type, i)));
    }
    json_object_set_new(js, "arguments", arguments);
    return js;

  default:
    if (clang_getCursorKind(decl) != CXCursor_NoDeclFound) {
      json_object_set_new(js, "kind", json_string("ref"));
      json_object_set_new(js, "id", render_string(clang_getCursorUSR(decl)));
    } else {
      int found = 0, i;
      for (i=0; i<sizeof(PRIMITIVE_TYPES)/sizeof(PRIMITIVE_TYPES[0]); i++) {
        if (PRIMITIVE_TYPES[i].kind == kind) {
          json_object_set_new(js, "kind", json_string("primitive"));
          json_object_set_new(js, "primitive", json_string(PRIMITIVE_TYPES[i].name));
          found = 1;
          break;
        }
      }
      if (!found) {
        json_object_set_new(js, "kind", json_string("unknown"));
        json_object_set_new(js, "clang_kind", render_string(clang_getTypeKindSpelling(kind)));
      }
    }
    return js;
  }
}
Пример #11
0
String Symbol::toString(Flags<ToStringFlag> cursorInfoFlags,
                        Flags<Location::ToStringFlag> locationToStringFlags,
                        const std::shared_ptr<Project> &project) const
{
    auto properties = [this]()
    {
        List<String> ret;
        if (isDefinition())
            ret << "Definition";
        if (isContainer())
            ret << "Container";
        if ((flags & PureVirtualMethod) == PureVirtualMethod) {
            ret << "Pure Virtual";
        } else if (flags & VirtualMethod) {
            ret << "Virtual";
        }

        if (flags & ConstMethod) {
            ret << "Const";
        } else if (flags & StaticMethod) {
            ret << "Static";
        }

        if (flags & Variadic)
            ret << "Variadic";
        if (flags & Auto)
            ret << "Auto";
        if (flags & AutoRef)
            ret << "AutoRef";

        if (flags & MacroExpansion)
            ret << "MacroExpansion";
        if (flags & TemplateSpecialization)
            ret << "TemplateSpecialization";

        if (ret.isEmpty())
            return String();
        String joined = String::join(ret, ' ');
        joined += '\n';
        return joined;
    };

    List<String> bases;
    if (project) {
        extern String findSymbolNameByUsr(const std::shared_ptr<Project> &, const String &, const Location &location);
        for (const auto &base : baseClasses) {
            const String symbolName = findSymbolNameByUsr(project, base, location);
            if (!symbolName.isEmpty()) {
                bases << symbolName;
            }
        }
    } else {
        bases = baseClasses;
    }

    auto printTypeName = [this]() {
        String str;
        if (!typeName.isEmpty()) {
            str = typeName;
        } else if (type != CXType_Invalid) {
            str = RTags::eatString(clang_getTypeKindSpelling(type));
        } else {
            return String();
        }
        return String::format<128>("Type: %s\n", str.constData());
    };

    String ret = String::format<1024>("SymbolName: %s\n"
                                      "Kind: %s\n"
                                      "%s" // type
                                      "SymbolLength: %u\n"
                                      "%s" // range
                                      "%s" // enumValue
                                      "%s" // linkage
                                      "%s" // properties
                                      "%s" // usr
                                      "%s" // sizeof
                                      "%s" // fieldoffset
                                      "%s" // baseclasses
                                      "%s" // briefComment
                                      "%s", // xmlComment
                                      symbolName.constData(),
                                      kindSpelling().constData(),
                                      printTypeName().constData(),
                                      symbolLength,
                                      startLine != -1 ? String::format<32>("Range: %d:%d-%d:%d\n", startLine, startColumn, endLine, endColumn).constData() : "",
#if CINDEX_VERSION_MINOR > 1
                                      kind == CXCursor_EnumConstantDecl ? String::format<32>("Enum Value: %lld\n", enumValue).constData() :
#endif
                                      "",
                                      linkageSpelling(linkage),
                                      properties().constData(),
                                      usr.isEmpty() ? "" : String::format<64>("Usr: %s\n", usr.constData()).constData(),
                                      size > 0 ? String::format<16>("sizeof: %d\n", size).constData() : "",
                                      fieldOffset >= 0 ? String::format<32>("field offset (bits/bytes): %d/%d\n", fieldOffset, fieldOffset / 8).constData() : "",
                                      alignment >= 0 ? String::format<32>("alignment (bytes): %d\n", alignment).constData() : "",
                                      bases.isEmpty() ? "" : String::format<64>("BaseClasses: %s\n", String::join(bases, ", ").constData()).constData(),
                                      briefComment.isEmpty() ? "" : String::format<1024>("Brief comment: %s\n", briefComment.constData()).constData(),
                                      xmlComment.isEmpty() ? "" : String::format<16384>("Xml comment: %s\n", xmlComment.constData()).constData());
    if (!(cursorInfoFlags & IgnoreTargets) && project) {
        extern Set<Symbol> findTargets(const std::shared_ptr<Project> &, const Symbol &);
        auto targets = findTargets(project, *this);
        if (targets.size()) {
            ret.append("Targets:\n");
            auto best = RTags::bestTarget(targets);
            ret.append(String::format<128>("    %s\n", best.location.toString(locationToStringFlags).constData()));

            for (const auto &tit : targets) {
                if (tit.location != best.location)
                    ret.append(String::format<128>("    %s\n", tit.location.toString(locationToStringFlags).constData()));
            }
        }
    }

    if (!(cursorInfoFlags & IgnoreReferences) && project && !isReference()) {
        extern Set<Symbol> findCallers(const std::shared_ptr<Project> &, const Symbol &);
        auto references = findCallers(project, *this);
        if (references.size()) {
            ret.append("References:\n");
            for (const auto &r : references) {
                ret.append(String::format<128>("    %s\n", r.location.toString(locationToStringFlags).constData()));
            }
        }
    }

    return ret;
}
Пример #12
0
static void PrintCursor(CXCursor Cursor) {
  if (clang_isInvalid(Cursor.kind)) {
    CXString ks = clang_getCursorKindSpelling(Cursor.kind);
    printf("Invalid Cursor => %s", clang_getCString(ks));
    clang_disposeString(ks);
  }
  else {
    CXString string, ks;
    CXCursor Referenced;
    unsigned line, column;
    CXCursor SpecializationOf;
    
    ks = clang_getCursorKindSpelling(Cursor.kind);
    string = clang_getCursorSpelling(Cursor);
    printf("%s=%s", clang_getCString(ks),
                    clang_getCString(string));
    clang_disposeString(ks);
    clang_disposeString(string);

    Referenced = clang_getCursorReferenced(Cursor);
    if (!clang_equalCursors(Referenced, clang_getNullCursor())) {
      CXSourceLocation Loc = clang_getCursorLocation(Referenced);
      clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
      printf(":%d:%d", line, column);
    }

    if (clang_isCursorDefinition(Cursor))
      printf(" (Definition)");
    
    switch (clang_getCursorAvailability(Cursor)) {
      case CXAvailability_Available:
        break;
        
      case CXAvailability_Deprecated:
        printf(" (deprecated)");
        break;
        
      case CXAvailability_NotAvailable:
        printf(" (unavailable)");
        break;
    }
    
    if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
      CXType T =
        clang_getCanonicalType(clang_getIBOutletCollectionType(Cursor));
      CXString S = clang_getTypeKindSpelling(T.kind);
      printf(" [IBOutletCollection=%s]", clang_getCString(S));
      clang_disposeString(S);
    }
    
    if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
      enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor);
      unsigned isVirtual = clang_isVirtualBase(Cursor);
      const char *accessStr = 0;

      switch (access) {
        case CX_CXXInvalidAccessSpecifier:
          accessStr = "invalid"; break;
        case CX_CXXPublic:
          accessStr = "public"; break;
        case CX_CXXProtected:
          accessStr = "protected"; break;
        case CX_CXXPrivate:
          accessStr = "private"; break;
      }      
      
      printf(" [access=%s isVirtual=%s]", accessStr,
             isVirtual ? "true" : "false");
    }
    
    SpecializationOf = clang_getSpecializedCursorTemplate(Cursor);
    if (!clang_equalCursors(SpecializationOf, clang_getNullCursor())) {
      CXSourceLocation Loc = clang_getCursorLocation(SpecializationOf);
      CXString Name = clang_getCursorSpelling(SpecializationOf);
      clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
      printf(" [Specialization of %s:%d:%d]", 
             clang_getCString(Name), line, column);
      clang_disposeString(Name);
    }
  }
}
Пример #13
0
std::ostream &operator<<(std::ostream &os, CXTypeKind typeKind)
{
    ClangString typeKindSpelling(clang_getTypeKindSpelling(typeKind));

    return os << typeKindSpelling.cString();
}