Пример #1
0
std::string TranslationUnit::GetTypeAtLocation(
  int line,
  int column,
  const std::vector< UnsavedFile > &unsaved_files,
  bool reparse ) {

  if ( reparse )
    Reparse( unsaved_files );

  unique_lock< mutex > lock( clang_access_mutex_ );

  if ( !clang_translation_unit_ )
    return "Internal error: no translation unit";

  CXCursor cursor = GetCursor( line, column );

  if ( !CursorIsValid( cursor ) )
    return "Internal error: cursor not valid";

  CXType type = clang_getCursorType( cursor );

  std::string type_description =
    CXStringToString( clang_getTypeSpelling( type ) );

  if ( type_description.empty() )
    return "Unknown type";

  // We have a choice here; libClang provides clang_getCanonicalType which will
  // return the "underlying" type for the type returned by clang_getCursorType
  // e.g. for a typedef
  //     type = clang_getCanonicalType( type );
  //
  // Without the above, something like the following would return "MyType"
  // rather than int:
  //     typedef int MyType;
  //     MyType i = 100; <-- type = MyType, canonical type = int
  //
  // There is probably more semantic value in calling it MyType. Indeed, if we
  // opt for the more specific type, we can get very long or
  // confusing STL types even for simple usage. e.g. the following:
  //     std::string test = "test"; <-- type = std::string;
  //                                    canonical type = std::basic_string<char>
  //
  // So as a compromise, we return both if and only if the types differ, like
  //     std::string => std::basic_string<char>

  CXType canonical_type = clang_getCanonicalType( type );

  if ( !clang_equalTypes( type, canonical_type ) ) {
    type_description += " => ";
    type_description += CXStringToString(
                          clang_getTypeSpelling( canonical_type ) );
  }

  return type_description;
}
Пример #2
0
std::ostream& operator<<( std::ostream& os, CXType type )
{
    auto typestr = clang_getTypeSpelling( type );
    os << "Type: " << clang_getCString( typestr ) << "\n";
    clang_disposeString( typestr );
    return os;
}
Пример #3
0
	static CXChildVisitResult parseFunctionMember (CXCursor cursor, CXCursor parent, CXClientData clientData) {
		auto functionDef = static_cast<FunctionDefinition*>(clientData);
		auto displayName = CXStringToString(clang_getCursorDisplayName(cursor));
		auto kind = clang_getCursorKind(cursor);

		std::map<std::string, std::string> location;
		getSourceLocation(cursor, functionDef->getContext(), location);
//		std::cerr << "function: " << displayName << " kind: " << kind << ", " << hyperloop::toJSON(location) << std::endl;

		switch (kind) {
			case CXCursor_ParmDecl: {
				auto argType = clang_getCursorType(cursor);
				auto typeValue= CXStringToString(clang_getTypeSpelling(argType));
				auto encoding = CXStringToString(clang_getDeclObjCTypeEncoding(cursor));
				functionDef->addArgument(displayName, argType, typeValue, encoding);
				break;
			}
			case CXCursor_ObjCClassRef:
			case CXCursor_TypeRef:
			case CXCursor_UnexposedAttr:
			case CXCursor_CompoundStmt:
			case CXCursor_AsmLabelAttr:
			case CXCursor_ConstAttr:
			case CXCursor_PureAttr: {
				break;
			}
			default: {
				std::cerr << "not handled, function: " << displayName << " kind: " << kind << std::endl;
				break;
			}
		}
		return CXChildVisit_Continue;
	}
Пример #4
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);
}
    std::string translation_unit::type_at(uint32_t row, uint32_t col) {
        CXCursor cursor = get_cursor_at(row, col);

        if (clang_Cursor_isNull(cursor) || clang_isInvalid(clang_getCursorKind(cursor)))
            return "";

        CXType type = clang_getCursorType(cursor);
        CXType real_type = clang_getCanonicalType( type );

        std::string ret = cx2std(clang_getTypeSpelling(type));

        if (!clang_equalTypes(type, real_type)) {
            ret.append(" - ");
            ret.append(cx2std(clang_getTypeSpelling(real_type)));
        }

        return ret;
    }
Пример #6
0
	CXChildVisitResult FunctionDefinition::executeParse (CXCursor cursor, ParserContext *context) {
		auto returnType = clang_getCursorResultType(cursor);
		auto returnTypeValue = CXStringToString(clang_getTypeSpelling(clang_getCursorResultType(cursor)));
		this->returnType = new Type(context, returnType, returnTypeValue);
		this->variadic = clang_isFunctionTypeVariadic(clang_getCursorType(cursor));
		addBlockIfFound(context, this, this->getFramework(), this->returnType, "");
		context->getParserTree()->addFunction(this);
		clang_visitChildren(cursor, parseFunctionMember, this);
		return CXChildVisit_Continue;
	}
Пример #7
0
QASTField::QASTField(
        QAnnotatedTokenSet *tokenSet,
        QSourceLocation* cursorLocation,
        QSourceLocation* rangeStartLocation,
        QSourceLocation* rangeEndLocation,
        QASTNode* parent)

    : QASTNode("field", tokenSet, cursorLocation, rangeStartLocation, rangeEndLocation, parent){

    // Get Identifier
    // --------------

    CXString id = clang_getCursorSpelling(tokenSet->cursor());
    setIdentifier(clang_getCString(id));

    // Get Field Type
    // ---------------

    CXType type           = clang_getCursorType(tokenSet->cursor());
    CXString typeSpelling = clang_getTypeSpelling(type);
    m_fieldType           = clang_getCString(typeSpelling);
    clang_disposeString(typeSpelling);

    // Determine field type
    // --------------------

    if ( type.kind == CXType_Unexposed || type.kind == CXType_Invalid || m_fieldType.contains("int") ){
        m_fieldType = "";

        bool doubleColonFlag = false;
        for ( QAnnotatedTokenSet::Iterator it = tokenSet->begin(); it != tokenSet->end(); ++it ){

            CXToken t              = (*it)->token().token;
            CXString tSpelling     = clang_getTokenSpelling(tokenSet->translationUnit(), t);
            const char* tCSpelling = clang_getCString(tSpelling);
            CXTokenKind tKind      = clang_getTokenKind(t);

            if ( tKind == CXToken_Identifier && std::string(clang_getCString(id)) == tCSpelling ){
                break;
            } else if ( tKind == CXToken_Punctuation && std::string("::") == tCSpelling ){
                doubleColonFlag = true;
                m_fieldType    += tCSpelling;
            } else if ( ( tKind == CXToken_Identifier || tKind == CXToken_Keyword ) &&
                        !m_fieldType.isEmpty() && !doubleColonFlag ){
                m_fieldType    += QString(" ") + tCSpelling;
            } else {
                doubleColonFlag = false;
                m_fieldType    += tCSpelling;
            }
        }
    }

    clang_disposeString(id);
}
Пример #8
0
DocumentationData::DocumentationData( const CXCursor& cursor )
  : raw_comment( CXStringToString( clang_Cursor_getRawCommentText( cursor ) ) )
  , brief_comment( CXStringToString(
                                 clang_Cursor_getBriefCommentText( cursor ) ) )
  , canonical_type( CXStringToString(
                    clang_getTypeSpelling( clang_getCursorType( cursor ) ) ) )
  , display_name( CXStringToString( clang_getCursorSpelling( cursor ) ) ) {


  CXComment parsed_comment = clang_Cursor_getParsedComment( cursor );
  if ( CXCommentValid( parsed_comment ) ) {
    comment_xml = CXStringToString(
                                clang_FullComment_getAsXML( parsed_comment ) );
  }
}
Пример #9
0
static enum CXChildVisitResult
visitor_struct_cb(CXCursor cursor, CXCursor parent, CXClientData client_data) {
  ERL_NIF_TERM name;
  ERL_NIF_TERM typename;

  CXString tmp;
  CXType type;
  ERL_NIF_TERM etmp;
  unsigned len;
  SubData *data = (SubData*)client_data;
  ErlNifEnv *env = data->env;

  switch (clang_getCursorKind(cursor)) {
  case CXCursor_FieldDecl: {
    enif_get_list_length(env, data->data, &len);

    tmp = clang_getCursorSpelling(cursor);
    name = enif_make_string(env, clang_getCString(tmp), ERL_NIF_LATIN1);
    clang_disposeString(tmp);

    type = clang_getCursorType(cursor);
    tmp = clang_getTypeSpelling(type);
    typename = enif_make_string(env, clang_getCString(tmp), ERL_NIF_LATIN1);
    data->types = enif_make_list_cell(env, typename, data->types);
    clang_disposeString(tmp);

    etmp = enif_make_tuple4(env,
			    enif_make_atom(env, "field"),
			    name,
			    typename,
			    enif_make_uint(env, len));
    data->data = enif_make_list_cell(env, etmp, data->data);
    return CXChildVisit_Continue;
  }
  default: {
    return CXChildVisit_Continue;
  }
  }
}
Пример #10
0
void Irony::getType(unsigned line, unsigned col) const {
  if (activeTu_ == nullptr) {
    std::clog << "W: get-type - parse wasn't called\n";

    std::cout << "nil\n";
    return;
  }

  CXFile cxFile = clang_getFile(activeTu_, file_.c_str());
  CXSourceLocation sourceLoc = clang_getLocation(activeTu_, cxFile, line, col);
  CXCursor cursor = clang_getCursor(activeTu_, sourceLoc);

  if (clang_Cursor_isNull(cursor)) {
    // TODO: "error: no type at point"?
    std::cout << "nil";
    return;
  }

  CXType cxTypes[2];
  cxTypes[0] = clang_getCursorType(cursor);
  cxTypes[1] = clang_getCanonicalType(cxTypes[0]);

  std::cout << "(";

  for (const CXType &cxType : cxTypes) {
    CXString typeDescr = clang_getTypeSpelling(cxType);
    std::string typeStr = clang_getCString(typeDescr);
    clang_disposeString(typeDescr);

    if (typeStr.empty())
      break;

    std::cout << support::quoted(typeStr) << " ";
  }

  std::cout << ")\n";
}
Пример #11
0
bool Type::Build(const CXType &cxType)
{
  bool result = true;

  auto arraySize = clang_getArraySize(cxType);
  m_ArraySize = arraySize > 0 ? static_cast<int>(arraySize) : 0;

  int numTemplateArgs = clang_Type_getNumTemplateArguments(cxType);

  for (int i = 0; i < numTemplateArgs; ++i)
  {
    CXType tempType = clang_Type_getTemplateArgumentAsType(cxType, static_cast<unsigned>(i));
    const char *tempTypeSpelling = clang_getCString(clang_getTypeSpelling(tempType));
    std::unique_ptr<Type> t = std::unique_ptr<Type>(CreateFromString(this, tempTypeSpelling));
    if (t->Build(tempType))
    {
      m_TemplateArgs.push_back(std::move(t));
    }
    else
      result = false;
  }

  return result;
}
Пример #12
0
std::string cursor::type::spelling()
{
    return string(clang_getTypeSpelling(ctype)).str();
}
Пример #13
0
enum CXChildVisitResult
	visitor(
		CXCursor cursor,
		CXCursor parent,
		CXClientData client_data
	)
{
	enum CXCursorKind kind = clang_getCursorKind(cursor);
#if 0
	CXString str = clang_getCursorKindSpelling(kind);
	printf("%s\n", getCString(str));
	disposeString(str);
#endif
	if (kind != CXCursor_FunctionDecl) {
		return CXChildVisit_Recurse;
	}

	CXString str;
	CXType retType = clang_getCursorResultType(cursor);
	str = clang_getTypeSpelling(retType);
	printf("%s\n", clang_getCString(str));
	clang_disposeString(str);

	CXString funcSpelling = clang_getCursorSpelling(cursor);
	const char* funcSpellingCStr = clang_getCString(funcSpelling);
	const char* prefix = (const char*) client_data;
	size_t prefixLen = strlen(prefix);
	if (strncmp(prefix, funcSpellingCStr, prefixLen) == 0) {
		funcSpellingCStr += prefixLen;
	}
	printf("\t%s(\n", funcSpellingCStr);

	int nArgs = clang_Cursor_getNumArguments(cursor);
	argNames.resize(nArgs);
	char nameBuff[32];
	for (int i=0; i<nArgs; ++i) {
		CXCursor arg = clang_Cursor_getArgument(cursor, i);
		CXType type = clang_getCursorType(arg);
		CXString typeSpelling = clang_getTypeSpelling(type);
		CXString name = clang_getCursorDisplayName(arg);
		argNames[i] = name;
		const char* nameStr = getArgNameCString(nameBuff, name, i);
		printf("\t\t%s %s", clang_getCString(typeSpelling), nameStr);
		clang_disposeString(typeSpelling);
		if (i+1 != nArgs) {
			printf(",");
		}
		printf("\n");
	}
	printf("\t)\n");
	printf("{\n");
	printf("\t");
	if (retType.kind != CXType_Void) {
		printf("return ");
	}
	printf("%s(", funcSpelling);

	for (int i=0; i<nArgs; ++i) {
		const char* nameStr = getArgNameCString(nameBuff, argNames[i], i);
		printf("%s", nameStr);
		if (i+1 != nArgs) {
			printf(", ");
		}
		clang_disposeString(argNames[i]);
	}

	printf(");\n");
	printf("}\n");
	clang_disposeString(funcSpelling);
	return CXChildVisit_Continue;
}
Пример #14
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 );
}
Пример #15
0
 String Type::GetSpelling() const
 {
     return clang_getTypeSpelling(type_);
 }
Пример #16
0
Utf8String Type::utf8Spelling() const
{
    return  ClangString(clang_getTypeSpelling(m_cxType));
}