@@ -45,6 +45,7 @@ class TranslationUnit
45
45
Reparse (0 , nullptr ); // seems to improve performance for some reason?
46
46
47
47
clang_visitChildren (clang_getTranslationUnitCursor (m_ClTranslUnit), ClAST_Visitor, database);
48
+ database->Shrink ();
48
49
}
49
50
50
51
// move ctor
@@ -617,11 +618,18 @@ ClangProxy::~ClangProxy()
617
618
void ClangProxy::CreateTranslationUnit (const wxString& filename, const wxString& commands)
618
619
{
619
620
wxStringTokenizer tokenizer (commands);
621
+ std::vector<wxString> unknownOptions;
622
+ unknownOptions.push_back (wxT (" -Wno-unused-local-typedefs" ));
623
+ unknownOptions.push_back (wxT (" -Wzero-as-null-pointer-constant" ));
624
+ std::sort (unknownOptions.begin (), unknownOptions.end ());
620
625
std::vector<wxCharBuffer> argsBuffer;
621
626
std::vector<const char *> args;
622
627
while (tokenizer.HasMoreTokens ())
623
628
{
624
- argsBuffer.push_back (tokenizer.GetNextToken ().ToUTF8 ());
629
+ const wxString& compilerSwitch = tokenizer.GetNextToken ();
630
+ if (std::binary_search (unknownOptions.begin (), unknownOptions.end (), compilerSwitch))
631
+ continue ;
632
+ argsBuffer.push_back (compilerSwitch.ToUTF8 ());
625
633
args.push_back (argsBuffer.back ().data ());
626
634
}
627
635
m_TranslUnits.push_back (TranslationUnit (filename, args, m_ClIndex, &m_Database));
@@ -973,6 +981,188 @@ void ClangProxy::RefineTokenType(int translId, int tknId, int& tknType)
973
981
}
974
982
}
975
983
984
+ static CXChildVisitResult ClCallTipCtorAST_Visitor (CXCursor cursor, CXCursor parent, CXClientData client_data)
985
+ {
986
+ switch (cursor.kind )
987
+ {
988
+ case CXCursor_Constructor:
989
+ {
990
+ std::vector<CXCursor>* tokenSet = static_cast <std::vector<CXCursor>*>(client_data);
991
+ tokenSet->push_back (cursor);
992
+ break ;
993
+ }
994
+
995
+ case CXCursor_FunctionDecl:
996
+ case CXCursor_CXXMethod:
997
+ case CXCursor_FunctionTemplate:
998
+ {
999
+ CXString str = clang_getCursorSpelling (cursor);
1000
+ if (strcmp (clang_getCString (str), " operator()" ) == 0 )
1001
+ {
1002
+ std::vector<CXCursor>* tokenSet = static_cast <std::vector<CXCursor>*>(client_data);
1003
+ tokenSet->push_back (cursor);
1004
+ }
1005
+ clang_disposeString (str);
1006
+ break ;
1007
+ }
1008
+
1009
+ default :
1010
+ break ;
1011
+ }
1012
+ return CXChildVisit_Continue;
1013
+ }
1014
+
1015
+ void ClangProxy::GetCallTipsAt (const wxString& filename, int line, int column, int translId, const wxString& tokenStr, std::vector<wxStringVec>& results)
1016
+ {
1017
+ std::vector<CXCursor> tokenSet;
1018
+ if (column > static_cast <int >(tokenStr.Length ()))
1019
+ {
1020
+ column -= tokenStr.Length () / 2 ;
1021
+ CXCursor token = m_TranslUnits[translId].GetTokensAt (filename, line, column);
1022
+ if (!clang_Cursor_isNull (token))
1023
+ {
1024
+ CXCursor resolve = clang_getCursorDefinition (token);
1025
+ if (clang_Cursor_isNull (resolve) || clang_isInvalid (token.kind ))
1026
+ {
1027
+ resolve = clang_getCursorReferenced (token);
1028
+ if (!clang_Cursor_isNull (resolve) && !clang_isInvalid (token.kind ))
1029
+ token = resolve;
1030
+ }
1031
+ else
1032
+ token = resolve;
1033
+ tokenSet.push_back (token);
1034
+ }
1035
+ }
1036
+ // TODO: searching the database is very inexact, but necessary, as clang
1037
+ // does not resolve the token when the code is invalid (incomplete)
1038
+ std::vector<TokenId> tknIds = m_Database.GetTokenMatches (tokenStr);
1039
+ for (std::vector<TokenId>::const_iterator itr = tknIds.begin (); itr != tknIds.end (); ++itr)
1040
+ {
1041
+ const AbstractToken& aTkn = m_Database.GetToken (*itr);
1042
+ CXCursor token = m_TranslUnits[translId].GetTokensAt (m_Database.GetFilename (aTkn.fileId ), aTkn.line , aTkn.column );
1043
+ if (!clang_Cursor_isNull (token) && !clang_isInvalid (token.kind ))
1044
+ tokenSet.push_back (token);
1045
+ }
1046
+ std::set<wxString> uniqueTips;
1047
+ for (size_t tknIdx = 0 ; tknIdx < tokenSet.size (); ++tknIdx)
1048
+ {
1049
+ CXCursor token = tokenSet[tknIdx];
1050
+ switch (GetTokenCategory (token.kind , CX_CXXPublic))
1051
+ {
1052
+ case tcVarPublic:
1053
+ {
1054
+ token = clang_getTypeDeclaration (clang_getCursorResultType (token));
1055
+ if (!clang_Cursor_isNull (token) && !clang_isInvalid (token.kind ))
1056
+ tokenSet.push_back (token);
1057
+ break ;
1058
+ }
1059
+
1060
+ case tcTypedefPublic:
1061
+ {
1062
+ token = clang_getTypeDeclaration (clang_getTypedefDeclUnderlyingType (token));
1063
+ if (!clang_Cursor_isNull (token) && !clang_isInvalid (token.kind ))
1064
+ tokenSet.push_back (token);
1065
+ break ;
1066
+ }
1067
+
1068
+ case tcClassPublic:
1069
+ {
1070
+ // search for constructors and 'operator()'
1071
+ clang_visitChildren (token, &ClCallTipCtorAST_Visitor, &tokenSet);
1072
+ break ;
1073
+ }
1074
+
1075
+ case tcCtorPublic:
1076
+ {
1077
+ if (clang_getCXXAccessSpecifier (token) == CX_CXXPrivate)
1078
+ break ;
1079
+ // fall through
1080
+ }
1081
+ case tcFuncPublic:
1082
+ {
1083
+ const CXCompletionString& clCompStr = clang_getCursorCompletionString (token);
1084
+ wxStringVec entry;
1085
+ int upperBound = clang_getNumCompletionChunks (clCompStr);
1086
+ entry.push_back (wxEmptyString);
1087
+ for (int chunkIdx = 0 ; chunkIdx < upperBound; ++chunkIdx)
1088
+ {
1089
+ CXCompletionChunkKind kind = clang_getCompletionChunkKind (clCompStr, chunkIdx);
1090
+ if (kind == CXCompletionChunk_TypedText)
1091
+ {
1092
+ CXString str = clang_getCompletionParent (clCompStr, nullptr );
1093
+ wxString parent = wxString::FromUTF8 (clang_getCString (str));
1094
+ if (!parent.IsEmpty ())
1095
+ entry[0 ] += parent + wxT (" ::" );
1096
+ clang_disposeString (str);
1097
+ }
1098
+ else if (kind == CXCompletionChunk_LeftParen)
1099
+ {
1100
+ if (entry[0 ].IsEmpty () || !entry[0 ].EndsWith (wxT (" operator" )))
1101
+ break ;
1102
+ }
1103
+ CXString str = clang_getCompletionChunkText (clCompStr, chunkIdx);
1104
+ entry[0 ] += wxString::FromUTF8 (clang_getCString (str));
1105
+ if (kind == CXCompletionChunk_ResultType)
1106
+ {
1107
+ if (entry[0 ].Length () > 2 && entry[0 ][entry[0 ].Length () - 2 ] == wxT (' ' ))
1108
+ entry[0 ].RemoveLast (2 ) += entry[0 ].Last ();
1109
+ entry[0 ] += wxT (' ' );
1110
+ }
1111
+ clang_disposeString (str);
1112
+ }
1113
+ entry[0 ] += wxT (' (' );
1114
+ int numArgs = clang_Cursor_getNumArguments (token);
1115
+ for (int argIdx = 0 ; argIdx < numArgs; ++argIdx)
1116
+ {
1117
+ CXCursor arg = clang_Cursor_getArgument (token, argIdx);
1118
+
1119
+ wxString tknStr;
1120
+ const CXCompletionString& argStr = clang_getCursorCompletionString (arg);
1121
+ upperBound = clang_getNumCompletionChunks (argStr);
1122
+ for (int chunkIdx = 0 ; chunkIdx < upperBound; ++chunkIdx)
1123
+ {
1124
+ CXCompletionChunkKind kind = clang_getCompletionChunkKind (argStr, chunkIdx);
1125
+ if (kind == CXCompletionChunk_TypedText)
1126
+ {
1127
+ CXString str = clang_getCompletionParent (argStr, nullptr );
1128
+ wxString parent = wxString::FromUTF8 (clang_getCString (str));
1129
+ if (!parent.IsEmpty ())
1130
+ tknStr += parent + wxT (" ::" );
1131
+ clang_disposeString (str);
1132
+ }
1133
+ CXString str = clang_getCompletionChunkText (argStr, chunkIdx);
1134
+ tknStr += wxString::FromUTF8 (clang_getCString (str));
1135
+ if (kind == CXCompletionChunk_ResultType)
1136
+ {
1137
+ if (tknStr.Length () > 2 && tknStr[tknStr.Length () - 2 ] == wxT (' ' ))
1138
+ tknStr.RemoveLast (2 ) += tknStr.Last ();
1139
+ tknStr += wxT (' ' );
1140
+ }
1141
+ clang_disposeString (str);
1142
+ }
1143
+
1144
+ entry.push_back (tknStr.Trim ());
1145
+ }
1146
+ entry.push_back (wxT (' )' ));
1147
+ wxString composit;
1148
+ for (wxStringVec::const_iterator itr = entry.begin ();
1149
+ itr != entry.end (); ++itr)
1150
+ {
1151
+ composit += *itr;
1152
+ }
1153
+ if (uniqueTips.find (composit) != uniqueTips.end ())
1154
+ break ;
1155
+ uniqueTips.insert (composit);
1156
+ results.push_back (entry);
1157
+ break ;
1158
+ }
1159
+
1160
+ default :
1161
+ break ;
1162
+ }
1163
+ }
1164
+ }
1165
+
976
1166
void ClangProxy::GetTokensAt (const wxString& filename, int line, int column, int translId, wxStringVec& results)
977
1167
{
978
1168
CXCursor token = m_TranslUnits[translId].GetTokensAt (filename, line, column);
0 commit comments