1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905 |
- /* c-index-test.c */
- #include "clang-c/Index.h"
- #include <ctype.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- /******************************************************************************/
- /* Utility functions. */
- /******************************************************************************/
- #ifdef _MSC_VER
- char *basename(const char* path)
- {
- char* base1 = (char*)strrchr(path, '/');
- char* base2 = (char*)strrchr(path, '\\');
- if (base1 && base2)
- return((base1 > base2) ? base1 + 1 : base2 + 1);
- else if (base1)
- return(base1 + 1);
- else if (base2)
- return(base2 + 1);
- return((char*)path);
- }
- #else
- extern char *basename(const char *);
- #endif
- /** \brief Return the default parsing options. */
- static unsigned getDefaultParsingOptions() {
- unsigned options = CXTranslationUnit_DetailedPreprocessingRecord;
- if (getenv("CINDEXTEST_EDITING"))
- options |= clang_defaultEditingTranslationUnitOptions();
- if (getenv("CINDEXTEST_COMPLETION_CACHING"))
- options |= CXTranslationUnit_CacheCompletionResults;
- if (getenv("CINDEXTEST_COMPLETION_NO_CACHING"))
- options &= ~CXTranslationUnit_CacheCompletionResults;
- if (getenv("CINDEXTEST_SKIP_FUNCTION_BODIES"))
- options |= CXTranslationUnit_SkipFunctionBodies;
-
- return options;
- }
- static int checkForErrors(CXTranslationUnit TU);
- static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column,
- unsigned end_line, unsigned end_column) {
- fprintf(out, "[%d:%d - %d:%d]", begin_line, begin_column,
- end_line, end_column);
- }
- static unsigned CreateTranslationUnit(CXIndex Idx, const char *file,
- CXTranslationUnit *TU) {
- *TU = clang_createTranslationUnit(Idx, file);
- if (!*TU) {
- fprintf(stderr, "Unable to load translation unit from '%s'!\n", file);
- return 0;
- }
- return 1;
- }
- void free_remapped_files(struct CXUnsavedFile *unsaved_files,
- int num_unsaved_files) {
- int i;
- for (i = 0; i != num_unsaved_files; ++i) {
- free((char *)unsaved_files[i].Filename);
- free((char *)unsaved_files[i].Contents);
- }
- free(unsaved_files);
- }
- int parse_remapped_files(int argc, const char **argv, int start_arg,
- struct CXUnsavedFile **unsaved_files,
- int *num_unsaved_files) {
- int i;
- int arg;
- int prefix_len = strlen("-remap-file=");
- *unsaved_files = 0;
- *num_unsaved_files = 0;
- /* Count the number of remapped files. */
- for (arg = start_arg; arg < argc; ++arg) {
- if (strncmp(argv[arg], "-remap-file=", prefix_len))
- break;
- ++*num_unsaved_files;
- }
- if (*num_unsaved_files == 0)
- return 0;
- *unsaved_files
- = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *
- *num_unsaved_files);
- for (arg = start_arg, i = 0; i != *num_unsaved_files; ++i, ++arg) {
- struct CXUnsavedFile *unsaved = *unsaved_files + i;
- const char *arg_string = argv[arg] + prefix_len;
- int filename_len;
- char *filename;
- char *contents;
- FILE *to_file;
- const char *semi = strchr(arg_string, ';');
- if (!semi) {
- fprintf(stderr,
- "error: -remap-file=from;to argument is missing semicolon\n");
- free_remapped_files(*unsaved_files, i);
- *unsaved_files = 0;
- *num_unsaved_files = 0;
- return -1;
- }
- /* Open the file that we're remapping to. */
- to_file = fopen(semi + 1, "rb");
- if (!to_file) {
- fprintf(stderr, "error: cannot open file %s that we are remapping to\n",
- semi + 1);
- free_remapped_files(*unsaved_files, i);
- *unsaved_files = 0;
- *num_unsaved_files = 0;
- return -1;
- }
- /* Determine the length of the file we're remapping to. */
- fseek(to_file, 0, SEEK_END);
- unsaved->Length = ftell(to_file);
- fseek(to_file, 0, SEEK_SET);
- /* Read the contents of the file we're remapping to. */
- contents = (char *)malloc(unsaved->Length + 1);
- if (fread(contents, 1, unsaved->Length, to_file) != unsaved->Length) {
- fprintf(stderr, "error: unexpected %s reading 'to' file %s\n",
- (feof(to_file) ? "EOF" : "error"), semi + 1);
- fclose(to_file);
- free_remapped_files(*unsaved_files, i);
- *unsaved_files = 0;
- *num_unsaved_files = 0;
- return -1;
- }
- contents[unsaved->Length] = 0;
- unsaved->Contents = contents;
- /* Close the file. */
- fclose(to_file);
- /* Copy the file name that we're remapping from. */
- filename_len = semi - arg_string;
- filename = (char *)malloc(filename_len + 1);
- memcpy(filename, arg_string, filename_len);
- filename[filename_len] = 0;
- unsaved->Filename = filename;
- }
- return 0;
- }
- /******************************************************************************/
- /* Pretty-printing. */
- /******************************************************************************/
- static void PrintRange(CXSourceRange R, const char *str) {
- CXFile begin_file, end_file;
- unsigned begin_line, begin_column, end_line, end_column;
- clang_getSpellingLocation(clang_getRangeStart(R),
- &begin_file, &begin_line, &begin_column, 0);
- clang_getSpellingLocation(clang_getRangeEnd(R),
- &end_file, &end_line, &end_column, 0);
- if (!begin_file || !end_file)
- return;
- if (str)
- printf(" %s=", str);
- PrintExtent(stdout, begin_line, begin_column, end_line, end_column);
- }
- int want_display_name = 0;
- static void printVersion(const char *Prefix, CXVersion Version) {
- if (Version.Major < 0)
- return;
- printf("%s%d", Prefix, Version.Major);
-
- if (Version.Minor < 0)
- return;
- printf(".%d", Version.Minor);
- if (Version.Subminor < 0)
- return;
- printf(".%d", Version.Subminor);
- }
- static void PrintCursor(CXCursor Cursor) {
- CXTranslationUnit TU = clang_Cursor_getTranslationUnit(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;
- CXCursor *overridden;
- unsigned num_overridden;
- unsigned RefNameRangeNr;
- CXSourceRange CursorExtent;
- CXSourceRange RefNameRange;
- int AlwaysUnavailable;
- int AlwaysDeprecated;
- CXString UnavailableMessage;
- CXString DeprecatedMessage;
- CXPlatformAvailability PlatformAvailability[2];
- int NumPlatformAvailability;
- int I;
- CXString Comment;
- const char *CommentCString;
- ks = clang_getCursorKindSpelling(Cursor.kind);
- string = want_display_name? clang_getCursorDisplayName(Cursor)
- : 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())) {
- if (clang_getCursorKind(Referenced) == CXCursor_OverloadedDeclRef) {
- unsigned I, N = clang_getNumOverloadedDecls(Referenced);
- printf("[");
- for (I = 0; I != N; ++I) {
- CXCursor Ovl = clang_getOverloadedDecl(Referenced, I);
- CXSourceLocation Loc;
- if (I)
- printf(", ");
-
- Loc = clang_getCursorLocation(Ovl);
- clang_getSpellingLocation(Loc, 0, &line, &column, 0);
- printf("%d:%d", line, column);
- }
- printf("]");
- } else {
- CXSourceLocation Loc = clang_getCursorLocation(Referenced);
- clang_getSpellingLocation(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;
- case CXAvailability_NotAccessible:
- printf(" (inaccessible)");
- break;
- }
-
- NumPlatformAvailability
- = clang_getCursorPlatformAvailability(Cursor,
- &AlwaysDeprecated,
- &DeprecatedMessage,
- &AlwaysUnavailable,
- &UnavailableMessage,
- PlatformAvailability, 2);
- if (AlwaysUnavailable) {
- printf(" (always unavailable: \"%s\")",
- clang_getCString(UnavailableMessage));
- } else if (AlwaysDeprecated) {
- printf(" (always deprecated: \"%s\")",
- clang_getCString(DeprecatedMessage));
- } else {
- for (I = 0; I != NumPlatformAvailability; ++I) {
- if (I >= 2)
- break;
-
- printf(" (%s", clang_getCString(PlatformAvailability[I].Platform));
- if (PlatformAvailability[I].Unavailable)
- printf(", unavailable");
- else {
- printVersion(", introduced=", PlatformAvailability[I].Introduced);
- printVersion(", deprecated=", PlatformAvailability[I].Deprecated);
- printVersion(", obsoleted=", PlatformAvailability[I].Obsoleted);
- }
- if (clang_getCString(PlatformAvailability[I].Message)[0])
- printf(", message=\"%s\"",
- clang_getCString(PlatformAvailability[I].Message));
- printf(")");
- }
- }
- for (I = 0; I != NumPlatformAvailability; ++I) {
- if (I >= 2)
- break;
- clang_disposeCXPlatformAvailability(PlatformAvailability + I);
- }
-
- clang_disposeString(DeprecatedMessage);
- clang_disposeString(UnavailableMessage);
-
- if (clang_CXXMethod_isStatic(Cursor))
- printf(" (static)");
- if (clang_CXXMethod_isVirtual(Cursor))
- printf(" (virtual)");
-
- 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_getSpellingLocation(Loc, 0, &line, &column, 0);
- printf(" [Specialization of %s:%d:%d]",
- clang_getCString(Name), line, column);
- clang_disposeString(Name);
- }
- clang_getOverriddenCursors(Cursor, &overridden, &num_overridden);
- if (num_overridden) {
- unsigned I;
- printf(" [Overrides ");
- for (I = 0; I != num_overridden; ++I) {
- CXSourceLocation Loc = clang_getCursorLocation(overridden[I]);
- clang_getSpellingLocation(Loc, 0, &line, &column, 0);
- if (I)
- printf(", ");
- printf("@%d:%d", line, column);
- }
- printf("]");
- clang_disposeOverriddenCursors(overridden);
- }
-
- if (Cursor.kind == CXCursor_InclusionDirective) {
- CXFile File = clang_getIncludedFile(Cursor);
- CXString Included = clang_getFileName(File);
- printf(" (%s)", clang_getCString(Included));
- clang_disposeString(Included);
-
- if (clang_isFileMultipleIncludeGuarded(TU, File))
- printf(" [multi-include guarded]");
- }
-
- CursorExtent = clang_getCursorExtent(Cursor);
- RefNameRange = clang_getCursorReferenceNameRange(Cursor,
- CXNameRange_WantQualifier
- | CXNameRange_WantSinglePiece
- | CXNameRange_WantTemplateArgs,
- 0);
- if (!clang_equalRanges(CursorExtent, RefNameRange))
- PrintRange(RefNameRange, "SingleRefName");
-
- for (RefNameRangeNr = 0; 1; RefNameRangeNr++) {
- RefNameRange = clang_getCursorReferenceNameRange(Cursor,
- CXNameRange_WantQualifier
- | CXNameRange_WantTemplateArgs,
- RefNameRangeNr);
- if (clang_equalRanges(clang_getNullRange(), RefNameRange))
- break;
- if (!clang_equalRanges(CursorExtent, RefNameRange))
- PrintRange(RefNameRange, "RefName");
- }
- Comment = clang_Cursor_getRawCommentText(Cursor);
- CommentCString = clang_getCString(Comment);
- if (CommentCString != NULL && CommentCString[0] != '\0') {
- printf(" Comment=[");
- for ( ; *CommentCString; ++CommentCString) {
- if (*CommentCString != '\n')
- putchar(*CommentCString);
- else
- printf("\\n");
- }
- printf("]");
- PrintRange(clang_Cursor_getCommentRange(Cursor), "CommentRange");
- }
- clang_disposeString(Comment);
- }
- }
- static const char* GetCursorSource(CXCursor Cursor) {
- CXSourceLocation Loc = clang_getCursorLocation(Cursor);
- CXString source;
- CXFile file;
- clang_getExpansionLocation(Loc, &file, 0, 0, 0);
- source = clang_getFileName(file);
- if (!clang_getCString(source)) {
- clang_disposeString(source);
- return "<invalid loc>";
- }
- else {
- const char *b = basename(clang_getCString(source));
- clang_disposeString(source);
- return b;
- }
- }
- /******************************************************************************/
- /* Callbacks. */
- /******************************************************************************/
- typedef void (*PostVisitTU)(CXTranslationUnit);
- void PrintDiagnostic(CXDiagnostic Diagnostic) {
- FILE *out = stderr;
- CXFile file;
- CXString Msg;
- unsigned display_opts = CXDiagnostic_DisplaySourceLocation
- | CXDiagnostic_DisplayColumn | CXDiagnostic_DisplaySourceRanges
- | CXDiagnostic_DisplayOption;
- unsigned i, num_fixits;
- if (clang_getDiagnosticSeverity(Diagnostic) == CXDiagnostic_Ignored)
- return;
- Msg = clang_formatDiagnostic(Diagnostic, display_opts);
- fprintf(stderr, "%s\n", clang_getCString(Msg));
- clang_disposeString(Msg);
- clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
- &file, 0, 0, 0);
- if (!file)
- return;
- num_fixits = clang_getDiagnosticNumFixIts(Diagnostic);
- fprintf(stderr, "Number FIX-ITs = %d\n", num_fixits);
- for (i = 0; i != num_fixits; ++i) {
- CXSourceRange range;
- CXString insertion_text = clang_getDiagnosticFixIt(Diagnostic, i, &range);
- CXSourceLocation start = clang_getRangeStart(range);
- CXSourceLocation end = clang_getRangeEnd(range);
- unsigned start_line, start_column, end_line, end_column;
- CXFile start_file, end_file;
- clang_getSpellingLocation(start, &start_file, &start_line,
- &start_column, 0);
- clang_getSpellingLocation(end, &end_file, &end_line, &end_column, 0);
- if (clang_equalLocations(start, end)) {
- /* Insertion. */
- if (start_file == file)
- fprintf(out, "FIX-IT: Insert \"%s\" at %d:%d\n",
- clang_getCString(insertion_text), start_line, start_column);
- } else if (strcmp(clang_getCString(insertion_text), "") == 0) {
- /* Removal. */
- if (start_file == file && end_file == file) {
- fprintf(out, "FIX-IT: Remove ");
- PrintExtent(out, start_line, start_column, end_line, end_column);
- fprintf(out, "\n");
- }
- } else {
- /* Replacement. */
- if (start_file == end_file) {
- fprintf(out, "FIX-IT: Replace ");
- PrintExtent(out, start_line, start_column, end_line, end_column);
- fprintf(out, " with \"%s\"\n", clang_getCString(insertion_text));
- }
- break;
- }
- clang_disposeString(insertion_text);
- }
- }
- void PrintDiagnosticSet(CXDiagnosticSet Set) {
- int i = 0, n = clang_getNumDiagnosticsInSet(Set);
- for ( ; i != n ; ++i) {
- CXDiagnostic Diag = clang_getDiagnosticInSet(Set, i);
- CXDiagnosticSet ChildDiags = clang_getChildDiagnostics(Diag);
- PrintDiagnostic(Diag);
- if (ChildDiags)
- PrintDiagnosticSet(ChildDiags);
- }
- }
- void PrintDiagnostics(CXTranslationUnit TU) {
- CXDiagnosticSet TUSet = clang_getDiagnosticSetFromTU(TU);
- PrintDiagnosticSet(TUSet);
- clang_disposeDiagnosticSet(TUSet);
- }
- void PrintMemoryUsage(CXTranslationUnit TU) {
- unsigned long total = 0;
- unsigned i = 0;
- CXTUResourceUsage usage = clang_getCXTUResourceUsage(TU);
- fprintf(stderr, "Memory usage:\n");
- for (i = 0 ; i != usage.numEntries; ++i) {
- const char *name = clang_getTUResourceUsageName(usage.entries[i].kind);
- unsigned long amount = usage.entries[i].amount;
- total += amount;
- fprintf(stderr, " %s : %ld bytes (%f MBytes)\n", name, amount,
- ((double) amount)/(1024*1024));
- }
- fprintf(stderr, " TOTAL = %ld bytes (%f MBytes)\n", total,
- ((double) total)/(1024*1024));
- clang_disposeCXTUResourceUsage(usage);
- }
- /******************************************************************************/
- /* Logic for testing traversal. */
- /******************************************************************************/
- static const char *FileCheckPrefix = "CHECK";
- static void PrintCursorExtent(CXCursor C) {
- CXSourceRange extent = clang_getCursorExtent(C);
- PrintRange(extent, "Extent");
- }
- /* Data used by all of the visitors. */
- typedef struct {
- CXTranslationUnit TU;
- enum CXCursorKind *Filter;
- } VisitorData;
- enum CXChildVisitResult FilteredPrintingVisitor(CXCursor Cursor,
- CXCursor Parent,
- CXClientData ClientData) {
- VisitorData *Data = (VisitorData *)ClientData;
- if (!Data->Filter || (Cursor.kind == *(enum CXCursorKind *)Data->Filter)) {
- CXSourceLocation Loc = clang_getCursorLocation(Cursor);
- unsigned line, column;
- clang_getSpellingLocation(Loc, 0, &line, &column, 0);
- printf("// %s: %s:%d:%d: ", FileCheckPrefix,
- GetCursorSource(Cursor), line, column);
- PrintCursor(Cursor);
- PrintCursorExtent(Cursor);
- printf("\n");
- return CXChildVisit_Recurse;
- }
- return CXChildVisit_Continue;
- }
- static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor,
- CXCursor Parent,
- CXClientData ClientData) {
- const char *startBuf, *endBuf;
- unsigned startLine, startColumn, endLine, endColumn, curLine, curColumn;
- CXCursor Ref;
- VisitorData *Data = (VisitorData *)ClientData;
- if (Cursor.kind != CXCursor_FunctionDecl ||
- !clang_isCursorDefinition(Cursor))
- return CXChildVisit_Continue;
- clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf,
- &startLine, &startColumn,
- &endLine, &endColumn);
- /* Probe the entire body, looking for both decls and refs. */
- curLine = startLine;
- curColumn = startColumn;
- while (startBuf < endBuf) {
- CXSourceLocation Loc;
- CXFile file;
- CXString source;
- if (*startBuf == '\n') {
- startBuf++;
- curLine++;
- curColumn = 1;
- } else if (*startBuf != '\t')
- curColumn++;
- Loc = clang_getCursorLocation(Cursor);
- clang_getSpellingLocation(Loc, &file, 0, 0, 0);
- source = clang_getFileName(file);
- if (clang_getCString(source)) {
- CXSourceLocation RefLoc
- = clang_getLocation(Data->TU, file, curLine, curColumn);
- Ref = clang_getCursor(Data->TU, RefLoc);
- if (Ref.kind == CXCursor_NoDeclFound) {
- /* Nothing found here; that's fine. */
- } else if (Ref.kind != CXCursor_FunctionDecl) {
- printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref),
- curLine, curColumn);
- PrintCursor(Ref);
- printf("\n");
- }
- }
- clang_disposeString(source);
- startBuf++;
- }
- return CXChildVisit_Continue;
- }
- /******************************************************************************/
- /* USR testing. */
- /******************************************************************************/
- enum CXChildVisitResult USRVisitor(CXCursor C, CXCursor parent,
- CXClientData ClientData) {
- VisitorData *Data = (VisitorData *)ClientData;
- if (!Data->Filter || (C.kind == *(enum CXCursorKind *)Data->Filter)) {
- CXString USR = clang_getCursorUSR(C);
- const char *cstr = clang_getCString(USR);
- if (!cstr || cstr[0] == '\0') {
- clang_disposeString(USR);
- return CXChildVisit_Recurse;
- }
- printf("// %s: %s %s", FileCheckPrefix, GetCursorSource(C), cstr);
- PrintCursorExtent(C);
- printf("\n");
- clang_disposeString(USR);
- return CXChildVisit_Recurse;
- }
- return CXChildVisit_Continue;
- }
- /******************************************************************************/
- /* Inclusion stack testing. */
- /******************************************************************************/
- void InclusionVisitor(CXFile includedFile, CXSourceLocation *includeStack,
- unsigned includeStackLen, CXClientData data) {
- unsigned i;
- CXString fname;
- fname = clang_getFileName(includedFile);
- printf("file: %s\nincluded by:\n", clang_getCString(fname));
- clang_disposeString(fname);
- for (i = 0; i < includeStackLen; ++i) {
- CXFile includingFile;
- unsigned line, column;
- clang_getSpellingLocation(includeStack[i], &includingFile, &line,
- &column, 0);
- fname = clang_getFileName(includingFile);
- printf(" %s:%d:%d\n", clang_getCString(fname), line, column);
- clang_disposeString(fname);
- }
- printf("\n");
- }
- void PrintInclusionStack(CXTranslationUnit TU) {
- clang_getInclusions(TU, InclusionVisitor, NULL);
- }
- /******************************************************************************/
- /* Linkage testing. */
- /******************************************************************************/
- static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p,
- CXClientData d) {
- const char *linkage = 0;
- if (clang_isInvalid(clang_getCursorKind(cursor)))
- return CXChildVisit_Recurse;
- switch (clang_getCursorLinkage(cursor)) {
- case CXLinkage_Invalid: break;
- case CXLinkage_NoLinkage: linkage = "NoLinkage"; break;
- case CXLinkage_Internal: linkage = "Internal"; break;
- case CXLinkage_UniqueExternal: linkage = "UniqueExternal"; break;
- case CXLinkage_External: linkage = "External"; break;
- }
- if (linkage) {
- PrintCursor(cursor);
- printf("linkage=%s\n", linkage);
- }
- return CXChildVisit_Recurse;
- }
- /******************************************************************************/
- /* Typekind testing. */
- /******************************************************************************/
- static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
- CXClientData d) {
- if (!clang_isInvalid(clang_getCursorKind(cursor))) {
- CXType T = clang_getCursorType(cursor);
- CXString S = clang_getTypeKindSpelling(T.kind);
- PrintCursor(cursor);
- printf(" typekind=%s", clang_getCString(S));
- if (clang_isConstQualifiedType(T))
- printf(" const");
- if (clang_isVolatileQualifiedType(T))
- printf(" volatile");
- if (clang_isRestrictQualifiedType(T))
- printf(" restrict");
- clang_disposeString(S);
- /* Print the canonical type if it is different. */
- {
- CXType CT = clang_getCanonicalType(T);
- if (!clang_equalTypes(T, CT)) {
- CXString CS = clang_getTypeKindSpelling(CT.kind);
- printf(" [canonical=%s]", clang_getCString(CS));
- clang_disposeString(CS);
- }
- }
- /* Print the return type if it exists. */
- {
- CXType RT = clang_getCursorResultType(cursor);
- if (RT.kind != CXType_Invalid) {
- CXString RS = clang_getTypeKindSpelling(RT.kind);
- printf(" [result=%s]", clang_getCString(RS));
- clang_disposeString(RS);
- }
- }
- /* Print the argument types if they exist. */
- {
- int numArgs = clang_Cursor_getNumArguments(cursor);
- if (numArgs != -1 && numArgs != 0) {
- int i;
- printf(" [args=");
- for (i = 0; i < numArgs; ++i) {
- CXType T = clang_getCursorType(clang_Cursor_getArgument(cursor, i));
- if (T.kind != CXType_Invalid) {
- CXString S = clang_getTypeKindSpelling(T.kind);
- printf(" %s", clang_getCString(S));
- clang_disposeString(S);
- }
- }
- printf("]");
- }
- }
- /* Print if this is a non-POD type. */
- printf(" [isPOD=%d]", clang_isPODType(T));
- printf("\n");
- }
- return CXChildVisit_Recurse;
- }
- /******************************************************************************/
- /* Loading ASTs/source. */
- /******************************************************************************/
- static int perform_test_load(CXIndex Idx, CXTranslationUnit TU,
- const char *filter, const char *prefix,
- CXCursorVisitor Visitor,
- PostVisitTU PV) {
- if (prefix)
- FileCheckPrefix = prefix;
- if (Visitor) {
- enum CXCursorKind K = CXCursor_NotImplemented;
- enum CXCursorKind *ck = &K;
- VisitorData Data;
- /* Perform some simple filtering. */
- if (!strcmp(filter, "all") || !strcmp(filter, "local")) ck = NULL;
- else if (!strcmp(filter, "all-display") ||
- !strcmp(filter, "local-display")) {
- ck = NULL;
- want_display_name = 1;
- }
- else if (!strcmp(filter, "none")) K = (enum CXCursorKind) ~0;
- else if (!strcmp(filter, "category")) K = CXCursor_ObjCCategoryDecl;
- else if (!strcmp(filter, "interface")) K = CXCursor_ObjCInterfaceDecl;
- else if (!strcmp(filter, "protocol")) K = CXCursor_ObjCProtocolDecl;
- else if (!strcmp(filter, "function")) K = CXCursor_FunctionDecl;
- else if (!strcmp(filter, "typedef")) K = CXCursor_TypedefDecl;
- else if (!strcmp(filter, "scan-function")) Visitor = FunctionScanVisitor;
- else {
- fprintf(stderr, "Unknown filter for -test-load-tu: %s\n", filter);
- return 1;
- }
- Data.TU = TU;
- Data.Filter = ck;
- clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data);
- }
- if (PV)
- PV(TU);
- PrintDiagnostics(TU);
- if (checkForErrors(TU) != 0) {
- clang_disposeTranslationUnit(TU);
- return -1;
- }
- clang_disposeTranslationUnit(TU);
- return 0;
- }
- int perform_test_load_tu(const char *file, const char *filter,
- const char *prefix, CXCursorVisitor Visitor,
- PostVisitTU PV) {
- CXIndex Idx;
- CXTranslationUnit TU;
- int result;
- Idx = clang_createIndex(/* excludeDeclsFromPCH */
- !strcmp(filter, "local") ? 1 : 0,
- /* displayDiagnosics=*/1);
- if (!CreateTranslationUnit(Idx, file, &TU)) {
- clang_disposeIndex(Idx);
- return 1;
- }
- result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV);
- clang_disposeIndex(Idx);
- return result;
- }
- int perform_test_load_source(int argc, const char **argv,
- const char *filter, CXCursorVisitor Visitor,
- PostVisitTU PV) {
- CXIndex Idx;
- CXTranslationUnit TU;
- struct CXUnsavedFile *unsaved_files = 0;
- int num_unsaved_files = 0;
- int result;
-
- Idx = clang_createIndex(/* excludeDeclsFromPCH */
- (!strcmp(filter, "local") ||
- !strcmp(filter, "local-display"))? 1 : 0,
- /* displayDiagnosics=*/0);
- if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
- clang_disposeIndex(Idx);
- return -1;
- }
- TU = clang_parseTranslationUnit(Idx, 0,
- argv + num_unsaved_files,
- argc - num_unsaved_files,
- unsaved_files, num_unsaved_files,
- getDefaultParsingOptions());
- if (!TU) {
- fprintf(stderr, "Unable to load translation unit!\n");
- free_remapped_files(unsaved_files, num_unsaved_files);
- clang_disposeIndex(Idx);
- return 1;
- }
- result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV);
- free_remapped_files(unsaved_files, num_unsaved_files);
- clang_disposeIndex(Idx);
- return result;
- }
- int perform_test_reparse_source(int argc, const char **argv, int trials,
- const char *filter, CXCursorVisitor Visitor,
- PostVisitTU PV) {
- CXIndex Idx;
- CXTranslationUnit TU;
- struct CXUnsavedFile *unsaved_files = 0;
- int num_unsaved_files = 0;
- int result;
- int trial;
- int remap_after_trial = 0;
- char *endptr = 0;
-
- Idx = clang_createIndex(/* excludeDeclsFromPCH */
- !strcmp(filter, "local") ? 1 : 0,
- /* displayDiagnosics=*/0);
-
- if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
- clang_disposeIndex(Idx);
- return -1;
- }
-
- /* Load the initial translation unit -- we do this without honoring remapped
- * files, so that we have a way to test results after changing the source. */
- TU = clang_parseTranslationUnit(Idx, 0,
- argv + num_unsaved_files,
- argc - num_unsaved_files,
- 0, 0, getDefaultParsingOptions());
- if (!TU) {
- fprintf(stderr, "Unable to load translation unit!\n");
- free_remapped_files(unsaved_files, num_unsaved_files);
- clang_disposeIndex(Idx);
- return 1;
- }
-
- if (checkForErrors(TU) != 0)
- return -1;
- if (getenv("CINDEXTEST_REMAP_AFTER_TRIAL")) {
- remap_after_trial =
- strtol(getenv("CINDEXTEST_REMAP_AFTER_TRIAL"), &endptr, 10);
- }
- for (trial = 0; trial < trials; ++trial) {
- if (clang_reparseTranslationUnit(TU,
- trial >= remap_after_trial ? num_unsaved_files : 0,
- trial >= remap_after_trial ? unsaved_files : 0,
- clang_defaultReparseOptions(TU))) {
- fprintf(stderr, "Unable to reparse translation unit!\n");
- clang_disposeTranslationUnit(TU);
- free_remapped_files(unsaved_files, num_unsaved_files);
- clang_disposeIndex(Idx);
- return -1;
- }
- if (checkForErrors(TU) != 0)
- return -1;
- }
-
- result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV);
- free_remapped_files(unsaved_files, num_unsaved_files);
- clang_disposeIndex(Idx);
- return result;
- }
- /******************************************************************************/
- /* Logic for testing clang_getCursor(). */
- /******************************************************************************/
- static void print_cursor_file_scan(CXTranslationUnit TU, CXCursor cursor,
- unsigned start_line, unsigned start_col,
- unsigned end_line, unsigned end_col,
- const char *prefix) {
- printf("// %s: ", FileCheckPrefix);
- if (prefix)
- printf("-%s", prefix);
- PrintExtent(stdout, start_line, start_col, end_line, end_col);
- printf(" ");
- PrintCursor(cursor);
- printf("\n");
- }
- static int perform_file_scan(const char *ast_file, const char *source_file,
- const char *prefix) {
- CXIndex Idx;
- CXTranslationUnit TU;
- FILE *fp;
- CXCursor prevCursor = clang_getNullCursor();
- CXFile file;
- unsigned line = 1, col = 1;
- unsigned start_line = 1, start_col = 1;
- if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
- /* displayDiagnosics=*/1))) {
- fprintf(stderr, "Could not create Index\n");
- return 1;
- }
- if (!CreateTranslationUnit(Idx, ast_file, &TU))
- return 1;
- if ((fp = fopen(source_file, "r")) == NULL) {
- fprintf(stderr, "Could not open '%s'\n", source_file);
- return 1;
- }
- file = clang_getFile(TU, source_file);
- for (;;) {
- CXCursor cursor;
- int c = fgetc(fp);
- if (c == '\n') {
- ++line;
- col = 1;
- } else
- ++col;
- /* Check the cursor at this position, and dump the previous one if we have
- * found something new.
- */
- cursor = clang_getCursor(TU, clang_getLocation(TU, file, line, col));
- if ((c == EOF || !clang_equalCursors(cursor, prevCursor)) &&
- prevCursor.kind != CXCursor_InvalidFile) {
- print_cursor_file_scan(TU, prevCursor, start_line, start_col,
- line, col, prefix);
- start_line = line;
- start_col = col;
- }
- if (c == EOF)
- break;
- prevCursor = cursor;
- }
- fclose(fp);
- clang_disposeTranslationUnit(TU);
- clang_disposeIndex(Idx);
- return 0;
- }
- /******************************************************************************/
- /* Logic for testing clang code completion. */
- /******************************************************************************/
- /* Parse file:line:column from the input string. Returns 0 on success, non-zero
- on failure. If successful, the pointer *filename will contain newly-allocated
- memory (that will be owned by the caller) to store the file name. */
- int parse_file_line_column(const char *input, char **filename, unsigned *line,
- unsigned *column, unsigned *second_line,
- unsigned *second_column) {
- /* Find the second colon. */
- const char *last_colon = strrchr(input, ':');
- unsigned values[4], i;
- unsigned num_values = (second_line && second_column)? 4 : 2;
- char *endptr = 0;
- if (!last_colon || last_colon == input) {
- if (num_values == 4)
- fprintf(stderr, "could not parse filename:line:column:line:column in "
- "'%s'\n", input);
- else
- fprintf(stderr, "could not parse filename:line:column in '%s'\n", input);
- return 1;
- }
- for (i = 0; i != num_values; ++i) {
- const char *prev_colon;
- /* Parse the next line or column. */
- values[num_values - i - 1] = strtol(last_colon + 1, &endptr, 10);
- if (*endptr != 0 && *endptr != ':') {
- fprintf(stderr, "could not parse %s in '%s'\n",
- (i % 2 ? "column" : "line"), input);
- return 1;
- }
- if (i + 1 == num_values)
- break;
- /* Find the previous colon. */
- prev_colon = last_colon - 1;
- while (prev_colon != input && *prev_colon != ':')
- --prev_colon;
- if (prev_colon == input) {
- fprintf(stderr, "could not parse %s in '%s'\n",
- (i % 2 == 0? "column" : "line"), input);
- return 1;
- }
- last_colon = prev_colon;
- }
- *line = values[0];
- *column = values[1];
- if (second_line && second_column) {
- *second_line = values[2];
- *second_column = values[3];
- }
- /* Copy the file name. */
- *filename = (char*)malloc(last_colon - input + 1);
- memcpy(*filename, input, last_colon - input);
- (*filename)[last_colon - input] = 0;
- return 0;
- }
- const char *
- clang_getCompletionChunkKindSpelling(enum CXCompletionChunkKind Kind) {
- switch (Kind) {
- case CXCompletionChunk_Optional: return "Optional";
- case CXCompletionChunk_TypedText: return "TypedText";
- case CXCompletionChunk_Text: return "Text";
- case CXCompletionChunk_Placeholder: return "Placeholder";
- case CXCompletionChunk_Informative: return "Informative";
- case CXCompletionChunk_CurrentParameter: return "CurrentParameter";
- case CXCompletionChunk_LeftParen: return "LeftParen";
- case CXCompletionChunk_RightParen: return "RightParen";
- case CXCompletionChunk_LeftBracket: return "LeftBracket";
- case CXCompletionChunk_RightBracket: return "RightBracket";
- case CXCompletionChunk_LeftBrace: return "LeftBrace";
- case CXCompletionChunk_RightBrace: return "RightBrace";
- case CXCompletionChunk_LeftAngle: return "LeftAngle";
- case CXCompletionChunk_RightAngle: return "RightAngle";
- case CXCompletionChunk_Comma: return "Comma";
- case CXCompletionChunk_ResultType: return "ResultType";
- case CXCompletionChunk_Colon: return "Colon";
- case CXCompletionChunk_SemiColon: return "SemiColon";
- case CXCompletionChunk_Equal: return "Equal";
- case CXCompletionChunk_HorizontalSpace: return "HorizontalSpace";
- case CXCompletionChunk_VerticalSpace: return "VerticalSpace";
- }
- return "Unknown";
- }
- static int checkForErrors(CXTranslationUnit TU) {
- unsigned Num, i;
- CXDiagnostic Diag;
- CXString DiagStr;
- if (!getenv("CINDEXTEST_FAILONERROR"))
- return 0;
- Num = clang_getNumDiagnostics(TU);
- for (i = 0; i != Num; ++i) {
- Diag = clang_getDiagnostic(TU, i);
- if (clang_getDiagnosticSeverity(Diag) >= CXDiagnostic_Error) {
- DiagStr = clang_formatDiagnostic(Diag,
- clang_defaultDiagnosticDisplayOptions());
- fprintf(stderr, "%s\n", clang_getCString(DiagStr));
- clang_disposeString(DiagStr);
- clang_disposeDiagnostic(Diag);
- return -1;
- }
- clang_disposeDiagnostic(Diag);
- }
- return 0;
- }
- void print_completion_string(CXCompletionString completion_string, FILE *file) {
- int I, N;
- N = clang_getNumCompletionChunks(completion_string);
- for (I = 0; I != N; ++I) {
- CXString text;
- const char *cstr;
- enum CXCompletionChunkKind Kind
- = clang_getCompletionChunkKind(completion_string, I);
- if (Kind == CXCompletionChunk_Optional) {
- fprintf(file, "{Optional ");
- print_completion_string(
- clang_getCompletionChunkCompletionString(completion_string, I),
- file);
- fprintf(file, "}");
- continue;
- }
- if (Kind == CXCompletionChunk_VerticalSpace) {
- fprintf(file, "{VerticalSpace }");
- continue;
- }
- text = clang_getCompletionChunkText(completion_string, I);
- cstr = clang_getCString(text);
- fprintf(file, "{%s %s}",
- clang_getCompletionChunkKindSpelling(Kind),
- cstr ? cstr : "");
- clang_disposeString(text);
- }
- }
- void print_completion_result(CXCompletionResult *completion_result,
- CXClientData client_data) {
- FILE *file = (FILE *)client_data;
- CXString ks = clang_getCursorKindSpelling(completion_result->CursorKind);
- unsigned annotationCount;
- enum CXCursorKind ParentKind;
- CXString ParentName;
-
- fprintf(file, "%s:", clang_getCString(ks));
- clang_disposeString(ks);
- print_completion_string(completion_result->CompletionString, file);
- fprintf(file, " (%u)",
- clang_getCompletionPriority(completion_result->CompletionString));
- switch (clang_getCompletionAvailability(completion_result->CompletionString)){
- case CXAvailability_Available:
- break;
-
- case CXAvailability_Deprecated:
- fprintf(file, " (deprecated)");
- break;
-
- case CXAvailability_NotAvailable:
- fprintf(file, " (unavailable)");
- break;
- case CXAvailability_NotAccessible:
- fprintf(file, " (inaccessible)");
- break;
- }
- annotationCount = clang_getCompletionNumAnnotations(
- completion_result->CompletionString);
- if (annotationCount) {
- unsigned i;
- fprintf(file, " (");
- for (i = 0; i < annotationCount; ++i) {
- if (i != 0)
- fprintf(file, ", ");
- fprintf(file, "\"%s\"",
- clang_getCString(clang_getCompletionAnnotation(
- completion_result->CompletionString, i)));
- }
- fprintf(file, ")");
- }
- if (!getenv("CINDEXTEST_NO_COMPLETION_PARENTS")) {
- ParentName = clang_getCompletionParent(completion_result->CompletionString,
- &ParentKind);
- if (ParentKind != CXCursor_NotImplemented) {
- CXString KindSpelling = clang_getCursorKindSpelling(ParentKind);
- fprintf(file, " (parent: %s '%s')",
- clang_getCString(KindSpelling),
- clang_getCString(ParentName));
- clang_disposeString(KindSpelling);
- }
- clang_disposeString(ParentName);
- }
-
- fprintf(file, "\n");
- }
- void print_completion_contexts(unsigned long long contexts, FILE *file) {
- fprintf(file, "Completion contexts:\n");
- if (contexts == CXCompletionContext_Unknown) {
- fprintf(file, "Unknown\n");
- }
- if (contexts & CXCompletionContext_AnyType) {
- fprintf(file, "Any type\n");
- }
- if (contexts & CXCompletionContext_AnyValue) {
- fprintf(file, "Any value\n");
- }
- if (contexts & CXCompletionContext_ObjCObjectValue) {
- fprintf(file, "Objective-C object value\n");
- }
- if (contexts & CXCompletionContext_ObjCSelectorValue) {
- fprintf(file, "Objective-C selector value\n");
- }
- if (contexts & CXCompletionContext_CXXClassTypeValue) {
- fprintf(file, "C++ class type value\n");
- }
- if (contexts & CXCompletionContext_DotMemberAccess) {
- fprintf(file, "Dot member access\n");
- }
- if (contexts & CXCompletionContext_ArrowMemberAccess) {
- fprintf(file, "Arrow member access\n");
- }
- if (contexts & CXCompletionContext_ObjCPropertyAccess) {
- fprintf(file, "Objective-C property access\n");
- }
- if (contexts & CXCompletionContext_EnumTag) {
- fprintf(file, "Enum tag\n");
- }
- if (contexts & CXCompletionContext_UnionTag) {
- fprintf(file, "Union tag\n");
- }
- if (contexts & CXCompletionContext_StructTag) {
- fprintf(file, "Struct tag\n");
- }
- if (contexts & CXCompletionContext_ClassTag) {
- fprintf(file, "Class name\n");
- }
- if (contexts & CXCompletionContext_Namespace) {
- fprintf(file, "Namespace or namespace alias\n");
- }
- if (contexts & CXCompletionContext_NestedNameSpecifier) {
- fprintf(file, "Nested name specifier\n");
- }
- if (contexts & CXCompletionContext_ObjCInterface) {
- fprintf(file, "Objective-C interface\n");
- }
- if (contexts & CXCompletionContext_ObjCProtocol) {
- fprintf(file, "Objective-C protocol\n");
- }
- if (contexts & CXCompletionContext_ObjCCategory) {
- fprintf(file, "Objective-C category\n");
- }
- if (contexts & CXCompletionContext_ObjCInstanceMessage) {
- fprintf(file, "Objective-C instance method\n");
- }
- if (contexts & CXCompletionContext_ObjCClassMessage) {
- fprintf(file, "Objective-C class method\n");
- }
- if (contexts & CXCompletionContext_ObjCSelectorName) {
- fprintf(file, "Objective-C selector name\n");
- }
- if (contexts & CXCompletionContext_MacroName) {
- fprintf(file, "Macro name\n");
- }
- if (contexts & CXCompletionContext_NaturalLanguage) {
- fprintf(file, "Natural language\n");
- }
- }
- int my_stricmp(const char *s1, const char *s2) {
- while (*s1 && *s2) {
- int c1 = tolower((unsigned char)*s1), c2 = tolower((unsigned char)*s2);
- if (c1 < c2)
- return -1;
- else if (c1 > c2)
- return 1;
-
- ++s1;
- ++s2;
- }
-
- if (*s1)
- return 1;
- else if (*s2)
- return -1;
- return 0;
- }
- int perform_code_completion(int argc, const char **argv, int timing_only) {
- const char *input = argv[1];
- char *filename = 0;
- unsigned line;
- unsigned column;
- CXIndex CIdx;
- int errorCode;
- struct CXUnsavedFile *unsaved_files = 0;
- int num_unsaved_files = 0;
- CXCodeCompleteResults *results = 0;
- CXTranslationUnit TU = 0;
- unsigned I, Repeats = 1;
- unsigned completionOptions = clang_defaultCodeCompleteOptions();
-
- if (getenv("CINDEXTEST_CODE_COMPLETE_PATTERNS"))
- completionOptions |= CXCodeComplete_IncludeCodePatterns;
-
- if (timing_only)
- input += strlen("-code-completion-timing=");
- else
- input += strlen("-code-completion-at=");
- if ((errorCode = parse_file_line_column(input, &filename, &line, &column,
- 0, 0)))
- return errorCode;
- if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
- return -1;
- CIdx = clang_createIndex(0, 0);
-
- if (getenv("CINDEXTEST_EDITING"))
- Repeats = 5;
-
- TU = clang_parseTranslationUnit(CIdx, 0,
- argv + num_unsaved_files + 2,
- argc - num_unsaved_files - 2,
- 0, 0, getDefaultParsingOptions());
- if (!TU) {
- fprintf(stderr, "Unable to load translation unit!\n");
- return 1;
- }
- if (clang_reparseTranslationUnit(TU, 0, 0, clang_defaultReparseOptions(TU))) {
- fprintf(stderr, "Unable to reparse translation init!\n");
- return 1;
- }
-
- for (I = 0; I != Repeats; ++I) {
- results = clang_codeCompleteAt(TU, filename, line, column,
- unsaved_files, num_unsaved_files,
- completionOptions);
- if (!results) {
- fprintf(stderr, "Unable to perform code completion!\n");
- return 1;
- }
- if (I != Repeats-1)
- clang_disposeCodeCompleteResults(results);
- }
- if (results) {
- unsigned i, n = results->NumResults, containerIsIncomplete = 0;
- unsigned long long contexts;
- enum CXCursorKind containerKind;
- CXString objCSelector;
- const char *selectorString;
- if (!timing_only) {
- /* Sort the code-completion results based on the typed text. */
- clang_sortCodeCompletionResults(results->Results, results->NumResults);
- for (i = 0; i != n; ++i)
- print_completion_result(results->Results + i, stdout);
- }
- n = clang_codeCompleteGetNumDiagnostics(results);
- for (i = 0; i != n; ++i) {
- CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i);
- PrintDiagnostic(diag);
- clang_disposeDiagnostic(diag);
- }
-
- contexts = clang_codeCompleteGetContexts(results);
- print_completion_contexts(contexts, stdout);
-
- containerKind = clang_codeCompleteGetContainerKind(results,
- &containerIsIncomplete);
-
- if (containerKind != CXCursor_InvalidCode) {
- /* We have found a container */
- CXString containerUSR, containerKindSpelling;
- containerKindSpelling = clang_getCursorKindSpelling(containerKind);
- printf("Container Kind: %s\n", clang_getCString(containerKindSpelling));
- clang_disposeString(containerKindSpelling);
-
- if (containerIsIncomplete) {
- printf("Container is incomplete\n");
- }
- else {
- printf("Container is complete\n");
- }
-
- containerUSR = clang_codeCompleteGetContainerUSR(results);
- printf("Container USR: %s\n", clang_getCString(containerUSR));
- clang_disposeString(containerUSR);
- }
-
- objCSelector = clang_codeCompleteGetObjCSelector(results);
- selectorString = clang_getCString(objCSelector);
- if (selectorString && strlen(selectorString) > 0) {
- printf("Objective-C selector: %s\n", selectorString);
- }
- clang_disposeString(objCSelector);
-
- clang_disposeCodeCompleteResults(results);
- }
- clang_disposeTranslationUnit(TU);
- clang_disposeIndex(CIdx);
- free(filename);
- free_remapped_files(unsaved_files, num_unsaved_files);
- return 0;
- }
- typedef struct {
- char *filename;
- unsigned line;
- unsigned column;
- } CursorSourceLocation;
- static int inspect_cursor_at(int argc, const char **argv) {
- CXIndex CIdx;
- int errorCode;
- struct CXUnsavedFile *unsaved_files = 0;
- int num_unsaved_files = 0;
- CXTranslationUnit TU;
- CXCursor Cursor;
- CursorSourceLocation *Locations = 0;
- unsigned NumLocations = 0, Loc;
- unsigned Repeats = 1;
- unsigned I;
-
- /* Count the number of locations. */
- while (strstr(argv[NumLocations+1], "-cursor-at=") == argv[NumLocations+1])
- ++NumLocations;
- /* Parse the locations. */
- assert(NumLocations > 0 && "Unable to count locations?");
- Locations = (CursorSourceLocation *)malloc(
- NumLocations * sizeof(CursorSourceLocation));
- for (Loc = 0; Loc < NumLocations; ++Loc) {
- const char *input = argv[Loc + 1] + strlen("-cursor-at=");
- if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename,
- &Locations[Loc].line,
- &Locations[Loc].column, 0, 0)))
- return errorCode;
- }
- if (parse_remapped_files(argc, argv, NumLocations + 1, &unsaved_files,
- &num_unsaved_files))
- return -1;
- if (getenv("CINDEXTEST_EDITING"))
- Repeats = 5;
- /* Parse the translation unit. When we're testing clang_getCursor() after
- reparsing, don't remap unsaved files until the second parse. */
- CIdx = clang_createIndex(1, 1);
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
- argv + num_unsaved_files + 1 + NumLocations,
- argc - num_unsaved_files - 2 - NumLocations,
- unsaved_files,
- Repeats > 1? 0 : num_unsaved_files,
- getDefaultParsingOptions());
-
- if (!TU) {
- fprintf(stderr, "unable to parse input\n");
- return -1;
- }
- if (checkForErrors(TU) != 0)
- return -1;
- for (I = 0; I != Repeats; ++I) {
- if (Repeats > 1 &&
- clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
- clang_defaultReparseOptions(TU))) {
- clang_disposeTranslationUnit(TU);
- return 1;
- }
- if (checkForErrors(TU) != 0)
- return -1;
-
- for (Loc = 0; Loc < NumLocations; ++Loc) {
- CXFile file = clang_getFile(TU, Locations[Loc].filename);
- if (!file)
- continue;
- Cursor = clang_getCursor(TU,
- clang_getLocation(TU, file, Locations[Loc].line,
- Locations[Loc].column));
- if (checkForErrors(TU) != 0)
- return -1;
- if (I + 1 == Repeats) {
- CXCompletionString completionString = clang_getCursorCompletionString(
- Cursor);
- CXSourceLocation CursorLoc = clang_getCursorLocation(Cursor);
- CXString Spelling;
- const char *cspell;
- unsigned line, column;
- clang_getSpellingLocation(CursorLoc, 0, &line, &column, 0);
- printf("%d:%d ", line, column);
- PrintCursor(Cursor);
- PrintCursorExtent(Cursor);
- Spelling = clang_getCursorSpelling(Cursor);
- cspell = clang_getCString(Spelling);
- if (cspell && strlen(cspell) != 0) {
- unsigned pieceIndex;
- printf(" Spelling=%s (", cspell);
- for (pieceIndex = 0; ; ++pieceIndex) {
- CXSourceRange range =
- clang_Cursor_getSpellingNameRange(Cursor, pieceIndex, 0);
- if (clang_Range_isNull(range))
- break;
- PrintRange(range, 0);
- }
- printf(")");
- }
- clang_disposeString(Spelling);
- if (clang_Cursor_getObjCSelectorIndex(Cursor) != -1)
- printf(" Selector index=%d",clang_Cursor_getObjCSelectorIndex(Cursor));
- if (completionString != NULL) {
- printf("\nCompletion string: ");
- print_completion_string(completionString, stdout);
- }
- printf("\n");
- free(Locations[Loc].filename);
- }
- }
- }
-
- PrintDiagnostics(TU);
- clang_disposeTranslationUnit(TU);
- clang_disposeIndex(CIdx);
- free(Locations);
- free_remapped_files(unsaved_files, num_unsaved_files);
- return 0;
- }
- static enum CXVisitorResult findFileRefsVisit(void *context,
- CXCursor cursor, CXSourceRange range) {
- if (clang_Range_isNull(range))
- return CXVisit_Continue;
- PrintCursor(cursor);
- PrintRange(range, "");
- printf("\n");
- return CXVisit_Continue;
- }
- static int find_file_refs_at(int argc, const char **argv) {
- CXIndex CIdx;
- int errorCode;
- struct CXUnsavedFile *unsaved_files = 0;
- int num_unsaved_files = 0;
- CXTranslationUnit TU;
- CXCursor Cursor;
- CursorSourceLocation *Locations = 0;
- unsigned NumLocations = 0, Loc;
- unsigned Repeats = 1;
- unsigned I;
-
- /* Count the number of locations. */
- while (strstr(argv[NumLocations+1], "-file-refs-at=") == argv[NumLocations+1])
- ++NumLocations;
- /* Parse the locations. */
- assert(NumLocations > 0 && "Unable to count locations?");
- Locations = (CursorSourceLocation *)malloc(
- NumLocations * sizeof(CursorSourceLocation));
- for (Loc = 0; Loc < NumLocations; ++Loc) {
- const char *input = argv[Loc + 1] + strlen("-file-refs-at=");
- if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename,
- &Locations[Loc].line,
- &Locations[Loc].column, 0, 0)))
- return errorCode;
- }
- if (parse_remapped_files(argc, argv, NumLocations + 1, &unsaved_files,
- &num_unsaved_files))
- return -1;
- if (getenv("CINDEXTEST_EDITING"))
- Repeats = 5;
- /* Parse the translation unit. When we're testing clang_getCursor() after
- reparsing, don't remap unsaved files until the second parse. */
- CIdx = clang_createIndex(1, 1);
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
- argv + num_unsaved_files + 1 + NumLocations,
- argc - num_unsaved_files - 2 - NumLocations,
- unsaved_files,
- Repeats > 1? 0 : num_unsaved_files,
- getDefaultParsingOptions());
-
- if (!TU) {
- fprintf(stderr, "unable to parse input\n");
- return -1;
- }
- if (checkForErrors(TU) != 0)
- return -1;
- for (I = 0; I != Repeats; ++I) {
- if (Repeats > 1 &&
- clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
- clang_defaultReparseOptions(TU))) {
- clang_disposeTranslationUnit(TU);
- return 1;
- }
- if (checkForErrors(TU) != 0)
- return -1;
-
- for (Loc = 0; Loc < NumLocations; ++Loc) {
- CXFile file = clang_getFile(TU, Locations[Loc].filename);
- if (!file)
- continue;
- Cursor = clang_getCursor(TU,
- clang_getLocation(TU, file, Locations[Loc].line,
- Locations[Loc].column));
- if (checkForErrors(TU) != 0)
- return -1;
- if (I + 1 == Repeats) {
- CXCursorAndRangeVisitor visitor = { 0, findFileRefsVisit };
- PrintCursor(Cursor);
- printf("\n");
- clang_findReferencesInFile(Cursor, file, visitor);
- free(Locations[Loc].filename);
- if (checkForErrors(TU) != 0)
- return -1;
- }
- }
- }
-
- PrintDiagnostics(TU);
- clang_disposeTranslationUnit(TU);
- clang_disposeIndex(CIdx);
- free(Locations);
- free_remapped_files(unsaved_files, num_unsaved_files);
- return 0;
- }
- typedef struct {
- const char *check_prefix;
- int first_check_printed;
- int fail_for_error;
- int abort;
- const char *main_filename;
- } IndexData;
- static void printCheck(IndexData *data) {
- if (data->check_prefix) {
- if (data->first_check_printed) {
- printf("// %s-NEXT: ", data->check_prefix);
- } else {
- printf("// %s : ", data->check_prefix);
- data->first_check_printed = 1;
- }
- }
- }
- static void printCXIndexFile(CXIdxClientFile file) {
- CXString filename = clang_getFileName((CXFile)file);
- printf("%s", clang_getCString(filename));
- clang_disposeString(filename);
- }
- static void printCXIndexLoc(CXIdxLoc loc, CXClientData client_data) {
- IndexData *index_data;
- CXString filename;
- const char *cname;
- CXIdxClientFile file;
- unsigned line, column;
- int isMainFile;
-
- index_data = (IndexData *)client_data;
- clang_indexLoc_getFileLocation(loc, &file, 0, &line, &column, 0);
- if (line == 0) {
- printf("<null loc>");
- return;
- }
- if (!file) {
- printf("<no idxfile>");
- return;
- }
- filename = clang_getFileName((CXFile)file);
- cname = clang_getCString(filename);
- if (strcmp(cname, index_data->main_filename) == 0)
- isMainFile = 1;
- else
- isMainFile = 0;
- clang_disposeString(filename);
- if (!isMainFile) {
- printCXIndexFile(file);
- printf(":");
- }
- printf("%d:%d", line, column);
- }
- static unsigned digitCount(unsigned val) {
- unsigned c = 1;
- while (1) {
- if (val < 10)
- return c;
- ++c;
- val /= 10;
- }
- }
- static CXIdxClientContainer makeClientContainer(const CXIdxEntityInfo *info,
- CXIdxLoc loc) {
- const char *name;
- char *newStr;
- CXIdxClientFile file;
- unsigned line, column;
-
- name = info->name;
- if (!name)
- name = "<anon-tag>";
- clang_indexLoc_getFileLocation(loc, &file, 0, &line, &column, 0);
- /* FIXME: free these.*/
- newStr = (char *)malloc(strlen(name) +
- digitCount(line) + digitCount(column) + 3);
- sprintf(newStr, "%s:%d:%d", name, line, column);
- return (CXIdxClientContainer)newStr;
- }
- static void printCXIndexContainer(const CXIdxContainerInfo *info) {
- CXIdxClientContainer container;
- container = clang_index_getClientContainer(info);
- if (!container)
- printf("[<<NULL>>]");
- else
- printf("[%s]", (const char *)container);
- }
- static const char *getEntityKindString(CXIdxEntityKind kind) {
- switch (kind) {
- case CXIdxEntity_Unexposed: return "<<UNEXPOSED>>";
- case CXIdxEntity_Typedef: return "typedef";
- case CXIdxEntity_Function: return "function";
- case CXIdxEntity_Variable: return "variable";
- case CXIdxEntity_Field: return "field";
- case CXIdxEntity_EnumConstant: return "enumerator";
- case CXIdxEntity_ObjCClass: return "objc-class";
- case CXIdxEntity_ObjCProtocol: return "objc-protocol";
- case CXIdxEntity_ObjCCategory: return "objc-category";
- case CXIdxEntity_ObjCInstanceMethod: return "objc-instance-method";
- case CXIdxEntity_ObjCClassMethod: return "objc-class-method";
- case CXIdxEntity_ObjCProperty: return "objc-property";
- case CXIdxEntity_ObjCIvar: return "objc-ivar";
- case CXIdxEntity_Enum: return "enum";
- case CXIdxEntity_Struct: return "struct";
- case CXIdxEntity_Union: return "union";
- case CXIdxEntity_CXXClass: return "c++-class";
- case CXIdxEntity_CXXNamespace: return "namespace";
- case CXIdxEntity_CXXNamespaceAlias: return "namespace-alias";
- case CXIdxEntity_CXXStaticVariable: return "c++-static-var";
- case CXIdxEntity_CXXStaticMethod: return "c++-static-method";
- case CXIdxEntity_CXXInstanceMethod: return "c++-instance-method";
- case CXIdxEntity_CXXConstructor: return "constructor";
- case CXIdxEntity_CXXDestructor: return "destructor";
- case CXIdxEntity_CXXConversionFunction: return "conversion-func";
- case CXIdxEntity_CXXTypeAlias: return "type-alias";
- }
- assert(0 && "Garbage entity kind");
- return 0;
- }
- static const char *getEntityTemplateKindString(CXIdxEntityCXXTemplateKind kind) {
- switch (kind) {
- case CXIdxEntity_NonTemplate: return "";
- case CXIdxEntity_Template: return "-template";
- case CXIdxEntity_TemplatePartialSpecialization:
- return "-template-partial-spec";
- case CXIdxEntity_TemplateSpecialization: return "-template-spec";
- }
- assert(0 && "Garbage entity kind");
- return 0;
- }
- static const char *getEntityLanguageString(CXIdxEntityLanguage kind) {
- switch (kind) {
- case CXIdxEntityLang_None: return "<none>";
- case CXIdxEntityLang_C: return "C";
- case CXIdxEntityLang_ObjC: return "ObjC";
- case CXIdxEntityLang_CXX: return "C++";
- }
- assert(0 && "Garbage language kind");
- return 0;
- }
- static void printEntityInfo(const char *cb,
- CXClientData client_data,
- const CXIdxEntityInfo *info) {
- const char *name;
- IndexData *index_data;
- unsigned i;
- index_data = (IndexData *)client_data;
- printCheck(index_data);
- if (!info) {
- printf("%s: <<NULL>>", cb);
- return;
- }
- name = info->name;
- if (!name)
- name = "<anon-tag>";
- printf("%s: kind: %s%s", cb, getEntityKindString(info->kind),
- getEntityTemplateKindString(info->templateKind));
- printf(" | name: %s", name);
- printf(" | USR: %s", info->USR);
- printf(" | lang: %s", getEntityLanguageString(info->lang));
- for (i = 0; i != info->numAttributes; ++i) {
- const CXIdxAttrInfo *Attr = info->attributes[i];
- printf(" <attribute>: ");
- PrintCursor(Attr->cursor);
- }
- }
- static void printBaseClassInfo(CXClientData client_data,
- const CXIdxBaseClassInfo *info) {
- printEntityInfo(" <base>", client_data, info->base);
- printf(" | cursor: ");
- PrintCursor(info->cursor);
- printf(" | loc: ");
- printCXIndexLoc(info->loc, client_data);
- }
- static void printProtocolList(const CXIdxObjCProtocolRefListInfo *ProtoInfo,
- CXClientData client_data) {
- unsigned i;
- for (i = 0; i < ProtoInfo->numProtocols; ++i) {
- printEntityInfo(" <protocol>", client_data,
- ProtoInfo->protocols[i]->protocol);
- printf(" | cursor: ");
- PrintCursor(ProtoInfo->protocols[i]->cursor);
- printf(" | loc: ");
- printCXIndexLoc(ProtoInfo->protocols[i]->loc, client_data);
- printf("\n");
- }
- }
- static void index_diagnostic(CXClientData client_data,
- CXDiagnosticSet diagSet, void *reserved) {
- CXString str;
- const char *cstr;
- unsigned numDiags, i;
- CXDiagnostic diag;
- IndexData *index_data;
- index_data = (IndexData *)client_data;
- printCheck(index_data);
- numDiags = clang_getNumDiagnosticsInSet(diagSet);
- for (i = 0; i != numDiags; ++i) {
- diag = clang_getDiagnosticInSet(diagSet, i);
- str = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions());
- cstr = clang_getCString(str);
- printf("[diagnostic]: %s\n", cstr);
- clang_disposeString(str);
-
- if (getenv("CINDEXTEST_FAILONERROR") &&
- clang_getDiagnosticSeverity(diag) >= CXDiagnostic_Error) {
- index_data->fail_for_error = 1;
- }
- }
- }
- static CXIdxClientFile index_enteredMainFile(CXClientData client_data,
- CXFile file, void *reserved) {
- IndexData *index_data;
- CXString filename;
- index_data = (IndexData *)client_data;
- printCheck(index_data);
- filename = clang_getFileName(file);
- index_data->main_filename = clang_getCString(filename);
- clang_disposeString(filename);
- printf("[enteredMainFile]: ");
- printCXIndexFile((CXIdxClientFile)file);
- printf("\n");
- return (CXIdxClientFile)file;
- }
- static CXIdxClientFile index_ppIncludedFile(CXClientData client_data,
- const CXIdxIncludedFileInfo *info) {
- IndexData *index_data;
- index_data = (IndexData *)client_data;
- printCheck(index_data);
- printf("[ppIncludedFile]: ");
- printCXIndexFile((CXIdxClientFile)info->file);
- printf(" | name: \"%s\"", info->filename);
- printf(" | hash loc: ");
- printCXIndexLoc(info->hashLoc, client_data);
- printf(" | isImport: %d | isAngled: %d\n", info->isImport, info->isAngled);
- return (CXIdxClientFile)info->file;
- }
- static CXIdxClientContainer index_startedTranslationUnit(CXClientData client_data,
- void *reserved) {
- IndexData *index_data;
- index_data = (IndexData *)client_data;
- printCheck(index_data);
- printf("[startedTranslationUnit]\n");
- return (CXIdxClientContainer)"TU";
- }
- static void index_indexDeclaration(CXClientData client_data,
- const CXIdxDeclInfo *info) {
- IndexData *index_data;
- const CXIdxObjCCategoryDeclInfo *CatInfo;
- const CXIdxObjCInterfaceDeclInfo *InterInfo;
- const CXIdxObjCProtocolRefListInfo *ProtoInfo;
- const CXIdxObjCPropertyDeclInfo *PropInfo;
- const CXIdxCXXClassDeclInfo *CXXClassInfo;
- unsigned i;
- index_data = (IndexData *)client_data;
- printEntityInfo("[indexDeclaration]", client_data, info->entityInfo);
- printf(" | cursor: ");
- PrintCursor(info->cursor);
- printf(" | loc: ");
- printCXIndexLoc(info->loc, client_data);
- printf(" | semantic-container: ");
- printCXIndexContainer(info->semanticContainer);
- printf(" | lexical-container: ");
- printCXIndexContainer(info->lexicalContainer);
- printf(" | isRedecl: %d", info->isRedeclaration);
- printf(" | isDef: %d", info->isDefinition);
- printf(" | isContainer: %d", info->isContainer);
- printf(" | isImplicit: %d\n", info->isImplicit);
- for (i = 0; i != info->numAttributes; ++i) {
- const CXIdxAttrInfo *Attr = info->attributes[i];
- printf(" <attribute>: ");
- PrintCursor(Attr->cursor);
- printf("\n");
- }
- if (clang_index_isEntityObjCContainerKind(info->entityInfo->kind)) {
- const char *kindName = 0;
- CXIdxObjCContainerKind K = clang_index_getObjCContainerDeclInfo(info)->kind;
- switch (K) {
- case CXIdxObjCContainer_ForwardRef:
- kindName = "forward-ref"; break;
- case CXIdxObjCContainer_Interface:
- kindName = "interface"; break;
- case CXIdxObjCContainer_Implementation:
- kindName = "implementation"; break;
- }
- printCheck(index_data);
- printf(" <ObjCContainerInfo>: kind: %s\n", kindName);
- }
- if ((CatInfo = clang_index_getObjCCategoryDeclInfo(info))) {
- printEntityInfo(" <ObjCCategoryInfo>: class", client_data,
- CatInfo->objcClass);
- printf(" | cursor: ");
- PrintCursor(CatInfo->classCursor);
- printf(" | loc: ");
- printCXIndexLoc(CatInfo->classLoc, client_data);
- printf("\n");
- }
- if ((InterInfo = clang_index_getObjCInterfaceDeclInfo(info))) {
- if (InterInfo->superInfo) {
- printBaseClassInfo(client_data, InterInfo->superInfo);
- printf("\n");
- }
- }
- if ((ProtoInfo = clang_index_getObjCProtocolRefListInfo(info))) {
- printProtocolList(ProtoInfo, client_data);
- }
- if ((PropInfo = clang_index_getObjCPropertyDeclInfo(info))) {
- if (PropInfo->getter) {
- printEntityInfo(" <getter>", client_data, PropInfo->getter);
- printf("\n");
- }
- if (PropInfo->setter) {
- printEntityInfo(" <setter>", client_data, PropInfo->setter);
- printf("\n");
- }
- }
- if ((CXXClassInfo = clang_index_getCXXClassDeclInfo(info))) {
- for (i = 0; i != CXXClassInfo->numBases; ++i) {
- printBaseClassInfo(client_data, CXXClassInfo->bases[i]);
- printf("\n");
- }
- }
- if (info->declAsContainer)
- clang_index_setClientContainer(info->declAsContainer,
- makeClientContainer(info->entityInfo, info->loc));
- }
- static void index_indexEntityReference(CXClientData client_data,
- const CXIdxEntityRefInfo *info) {
- printEntityInfo("[indexEntityReference]", client_data, info->referencedEntity);
- printf(" | cursor: ");
- PrintCursor(info->cursor);
- printf(" | loc: ");
- printCXIndexLoc(info->loc, client_data);
- printEntityInfo(" | <parent>:", client_data, info->parentEntity);
- printf(" | container: ");
- printCXIndexContainer(info->container);
- printf(" | refkind: ");
- switch (info->kind) {
- case CXIdxEntityRef_Direct: printf("direct"); break;
- case CXIdxEntityRef_Implicit: printf("implicit"); break;
- }
- printf("\n");
- }
- static int index_abortQuery(CXClientData client_data, void *reserved) {
- IndexData *index_data;
- index_data = (IndexData *)client_data;
- return index_data->abort;
- }
- static IndexerCallbacks IndexCB = {
- index_abortQuery,
- index_diagnostic,
- index_enteredMainFile,
- index_ppIncludedFile,
- 0, /*importedASTFile*/
- index_startedTranslationUnit,
- index_indexDeclaration,
- index_indexEntityReference
- };
- static unsigned getIndexOptions(void) {
- unsigned index_opts;
- index_opts = 0;
- if (getenv("CINDEXTEST_SUPPRESSREFS"))
- index_opts |= CXIndexOpt_SuppressRedundantRefs;
- if (getenv("CINDEXTEST_INDEXLOCALSYMBOLS"))
- index_opts |= CXIndexOpt_IndexFunctionLocalSymbols;
- return index_opts;
- }
- static int index_file(int argc, const char **argv) {
- const char *check_prefix;
- CXIndex Idx;
- CXIndexAction idxAction;
- IndexData index_data;
- unsigned index_opts;
- int result;
- check_prefix = 0;
- if (argc > 0) {
- if (strstr(argv[0], "-check-prefix=") == argv[0]) {
- check_prefix = argv[0] + strlen("-check-prefix=");
- ++argv;
- --argc;
- }
- }
- if (argc == 0) {
- fprintf(stderr, "no compiler arguments\n");
- return -1;
- }
- if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
- /* displayDiagnosics=*/1))) {
- fprintf(stderr, "Could not create Index\n");
- return 1;
- }
- idxAction = 0;
- result = 1;
- index_data.check_prefix = check_prefix;
- index_data.first_check_printed = 0;
- index_data.fail_for_error = 0;
- index_data.abort = 0;
- index_opts = getIndexOptions();
- idxAction = clang_IndexAction_create(Idx);
- result = clang_indexSourceFile(idxAction, &index_data,
- &IndexCB,sizeof(IndexCB), index_opts,
- 0, argv, argc, 0, 0, 0, 0);
- if (index_data.fail_for_error)
- result = -1;
- clang_IndexAction_dispose(idxAction);
- clang_disposeIndex(Idx);
- return result;
- }
- static int index_tu(int argc, const char **argv) {
- CXIndex Idx;
- CXIndexAction idxAction;
- CXTranslationUnit TU;
- const char *check_prefix;
- IndexData index_data;
- unsigned index_opts;
- int result;
- check_prefix = 0;
- if (argc > 0) {
- if (strstr(argv[0], "-check-prefix=") == argv[0]) {
- check_prefix = argv[0] + strlen("-check-prefix=");
- ++argv;
- --argc;
- }
- }
- if (argc == 0) {
- fprintf(stderr, "no ast file\n");
- return -1;
- }
- if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
- /* displayDiagnosics=*/1))) {
- fprintf(stderr, "Could not create Index\n");
- return 1;
- }
- idxAction = 0;
- result = 1;
- if (!CreateTranslationUnit(Idx, argv[0], &TU))
- goto finished;
- index_data.check_prefix = check_prefix;
- index_data.first_check_printed = 0;
- index_data.fail_for_error = 0;
- index_data.abort = 0;
- index_opts = getIndexOptions();
- idxAction = clang_IndexAction_create(Idx);
- result = clang_indexTranslationUnit(idxAction, &index_data,
- &IndexCB,sizeof(IndexCB),
- index_opts, TU);
- if (index_data.fail_for_error)
- goto finished;
- finished:
- clang_IndexAction_dispose(idxAction);
- clang_disposeIndex(Idx);
-
- return result;
- }
- int perform_token_annotation(int argc, const char **argv) {
- const char *input = argv[1];
- char *filename = 0;
- unsigned line, second_line;
- unsigned column, second_column;
- CXIndex CIdx;
- CXTranslationUnit TU = 0;
- int errorCode;
- struct CXUnsavedFile *unsaved_files = 0;
- int num_unsaved_files = 0;
- CXToken *tokens;
- unsigned num_tokens;
- CXSourceRange range;
- CXSourceLocation startLoc, endLoc;
- CXFile file = 0;
- CXCursor *cursors = 0;
- unsigned i;
- input += strlen("-test-annotate-tokens=");
- if ((errorCode = parse_file_line_column(input, &filename, &line, &column,
- &second_line, &second_column)))
- return errorCode;
- if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
- return -1;
- CIdx = clang_createIndex(0, 1);
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
- argv + num_unsaved_files + 2,
- argc - num_unsaved_files - 3,
- unsaved_files,
- num_unsaved_files,
- getDefaultParsingOptions());
- if (!TU) {
- fprintf(stderr, "unable to parse input\n");
- clang_disposeIndex(CIdx);
- free(filename);
- free_remapped_files(unsaved_files, num_unsaved_files);
- return -1;
- }
- errorCode = 0;
- if (checkForErrors(TU) != 0)
- return -1;
- if (getenv("CINDEXTEST_EDITING")) {
- for (i = 0; i < 5; ++i) {
- if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
- clang_defaultReparseOptions(TU))) {
- fprintf(stderr, "Unable to reparse translation unit!\n");
- errorCode = -1;
- goto teardown;
- }
- }
- }
- if (checkForErrors(TU) != 0) {
- errorCode = -1;
- goto teardown;
- }
- file = clang_getFile(TU, filename);
- if (!file) {
- fprintf(stderr, "file %s is not in this translation unit\n", filename);
- errorCode = -1;
- goto teardown;
- }
- startLoc = clang_getLocation(TU, file, line, column);
- if (clang_equalLocations(clang_getNullLocation(), startLoc)) {
- fprintf(stderr, "invalid source location %s:%d:%d\n", filename, line,
- column);
- errorCode = -1;
- goto teardown;
- }
- endLoc = clang_getLocation(TU, file, second_line, second_column);
- if (clang_equalLocations(clang_getNullLocation(), endLoc)) {
- fprintf(stderr, "invalid source location %s:%d:%d\n", filename,
- second_line, second_column);
- errorCode = -1;
- goto teardown;
- }
- range = clang_getRange(startLoc, endLoc);
- clang_tokenize(TU, range, &tokens, &num_tokens);
- if (checkForErrors(TU) != 0) {
- errorCode = -1;
- goto teardown;
- }
- cursors = (CXCursor *)malloc(num_tokens * sizeof(CXCursor));
- clang_annotateTokens(TU, tokens, num_tokens, cursors);
- if (checkForErrors(TU) != 0) {
- errorCode = -1;
- goto teardown;
- }
- for (i = 0; i != num_tokens; ++i) {
- const char *kind = "<unknown>";
- CXString spelling = clang_getTokenSpelling(TU, tokens[i]);
- CXSourceRange extent = clang_getTokenExtent(TU, tokens[i]);
- unsigned start_line, start_column, end_line, end_column;
- switch (clang_getTokenKind(tokens[i])) {
- case CXToken_Punctuation: kind = "Punctuation"; break;
- case CXToken_Keyword: kind = "Keyword"; break;
- case CXToken_Identifier: kind = "Identifier"; break;
- case CXToken_Literal: kind = "Literal"; break;
- case CXToken_Comment: kind = "Comment"; break;
- }
- clang_getSpellingLocation(clang_getRangeStart(extent),
- 0, &start_line, &start_column, 0);
- clang_getSpellingLocation(clang_getRangeEnd(extent),
- 0, &end_line, &end_column, 0);
- printf("%s: \"%s\" ", kind, clang_getCString(spelling));
- clang_disposeString(spelling);
- PrintExtent(stdout, start_line, start_column, end_line, end_column);
- if (!clang_isInvalid(cursors[i].kind)) {
- printf(" ");
- PrintCursor(cursors[i]);
- }
- printf("\n");
- }
- free(cursors);
- clang_disposeTokens(TU, tokens, num_tokens);
- teardown:
- PrintDiagnostics(TU);
- clang_disposeTranslationUnit(TU);
- clang_disposeIndex(CIdx);
- free(filename);
- free_remapped_files(unsaved_files, num_unsaved_files);
- return errorCode;
- }
- /******************************************************************************/
- /* USR printing. */
- /******************************************************************************/
- static int insufficient_usr(const char *kind, const char *usage) {
- fprintf(stderr, "USR for '%s' requires: %s\n", kind, usage);
- return 1;
- }
- static unsigned isUSR(const char *s) {
- return s[0] == 'c' && s[1] == ':';
- }
- static int not_usr(const char *s, const char *arg) {
- fprintf(stderr, "'%s' argument ('%s') is not a USR\n", s, arg);
- return 1;
- }
- static void print_usr(CXString usr) {
- const char *s = clang_getCString(usr);
- printf("%s\n", s);
- clang_disposeString(usr);
- }
- static void display_usrs() {
- fprintf(stderr, "-print-usrs options:\n"
- " ObjCCategory <class name> <category name>\n"
- " ObjCClass <class name>\n"
- " ObjCIvar <ivar name> <class USR>\n"
- " ObjCMethod <selector> [0=class method|1=instance method] "
- "<class USR>\n"
- " ObjCProperty <property name> <class USR>\n"
- " ObjCProtocol <protocol name>\n");
- }
- int print_usrs(const char **I, const char **E) {
- while (I != E) {
- const char *kind = *I;
- unsigned len = strlen(kind);
- switch (len) {
- case 8:
- if (memcmp(kind, "ObjCIvar", 8) == 0) {
- if (I + 2 >= E)
- return insufficient_usr(kind, "<ivar name> <class USR>");
- if (!isUSR(I[2]))
- return not_usr("<class USR>", I[2]);
- else {
- CXString x;
- x.data = (void*) I[2];
- x.private_flags = 0;
- print_usr(clang_constructUSR_ObjCIvar(I[1], x));
- }
- I += 3;
- continue;
- }
- break;
- case 9:
- if (memcmp(kind, "ObjCClass", 9) == 0) {
- if (I + 1 >= E)
- return insufficient_usr(kind, "<class name>");
- print_usr(clang_constructUSR_ObjCClass(I[1]));
- I += 2;
- continue;
- }
- break;
- case 10:
- if (memcmp(kind, "ObjCMethod", 10) == 0) {
- if (I + 3 >= E)
- return insufficient_usr(kind, "<method selector> "
- "[0=class method|1=instance method] <class USR>");
- if (!isUSR(I[3]))
- return not_usr("<class USR>", I[3]);
- else {
- CXString x;
- x.data = (void*) I[3];
- x.private_flags = 0;
- print_usr(clang_constructUSR_ObjCMethod(I[1], atoi(I[2]), x));
- }
- I += 4;
- continue;
- }
- break;
- case 12:
- if (memcmp(kind, "ObjCCategory", 12) == 0) {
- if (I + 2 >= E)
- return insufficient_usr(kind, "<class name> <category name>");
- print_usr(clang_constructUSR_ObjCCategory(I[1], I[2]));
- I += 3;
- continue;
- }
- if (memcmp(kind, "ObjCProtocol", 12) == 0) {
- if (I + 1 >= E)
- return insufficient_usr(kind, "<protocol name>");
- print_usr(clang_constructUSR_ObjCProtocol(I[1]));
- I += 2;
- continue;
- }
- if (memcmp(kind, "ObjCProperty", 12) == 0) {
- if (I + 2 >= E)
- return insufficient_usr(kind, "<property name> <class USR>");
- if (!isUSR(I[2]))
- return not_usr("<class USR>", I[2]);
- else {
- CXString x;
- x.data = (void*) I[2];
- x.private_flags = 0;
- print_usr(clang_constructUSR_ObjCProperty(I[1], x));
- }
- I += 3;
- continue;
- }
- break;
- default:
- break;
- }
- break;
- }
- if (I != E) {
- fprintf(stderr, "Invalid USR kind: %s\n", *I);
- display_usrs();
- return 1;
- }
- return 0;
- }
- int print_usrs_file(const char *file_name) {
- char line[2048];
- const char *args[128];
- unsigned numChars = 0;
- FILE *fp = fopen(file_name, "r");
- if (!fp) {
- fprintf(stderr, "error: cannot open '%s'\n", file_name);
- return 1;
- }
- /* This code is not really all that safe, but it works fine for testing. */
- while (!feof(fp)) {
- char c = fgetc(fp);
- if (c == '\n') {
- unsigned i = 0;
- const char *s = 0;
- if (numChars == 0)
- continue;
- line[numChars] = '\0';
- numChars = 0;
- if (line[0] == '/' && line[1] == '/')
- continue;
- s = strtok(line, " ");
- while (s) {
- args[i] = s;
- ++i;
- s = strtok(0, " ");
- }
- if (print_usrs(&args[0], &args[i]))
- return 1;
- }
- else
- line[numChars++] = c;
- }
- fclose(fp);
- return 0;
- }
- /******************************************************************************/
- /* Command line processing. */
- /******************************************************************************/
- int write_pch_file(const char *filename, int argc, const char *argv[]) {
- CXIndex Idx;
- CXTranslationUnit TU;
- struct CXUnsavedFile *unsaved_files = 0;
- int num_unsaved_files = 0;
- int result = 0;
-
- Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnosics=*/1);
-
- if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
- clang_disposeIndex(Idx);
- return -1;
- }
-
- TU = clang_parseTranslationUnit(Idx, 0,
- argv + num_unsaved_files,
- argc - num_unsaved_files,
- unsaved_files,
- num_unsaved_files,
- CXTranslationUnit_Incomplete);
- if (!TU) {
- fprintf(stderr, "Unable to load translation unit!\n");
- free_remapped_files(unsaved_files, num_unsaved_files);
- clang_disposeIndex(Idx);
- return 1;
- }
- switch (clang_saveTranslationUnit(TU, filename,
- clang_defaultSaveOptions(TU))) {
- case CXSaveError_None:
- break;
- case CXSaveError_TranslationErrors:
- fprintf(stderr, "Unable to write PCH file %s: translation errors\n",
- filename);
- result = 2;
- break;
- case CXSaveError_InvalidTU:
- fprintf(stderr, "Unable to write PCH file %s: invalid translation unit\n",
- filename);
- result = 3;
- break;
- case CXSaveError_Unknown:
- default:
- fprintf(stderr, "Unable to write PCH file %s: unknown error \n", filename);
- result = 1;
- break;
- }
-
- clang_disposeTranslationUnit(TU);
- free_remapped_files(unsaved_files, num_unsaved_files);
- clang_disposeIndex(Idx);
- return result;
- }
- /******************************************************************************/
- /* Serialized diagnostics. */
- /******************************************************************************/
- static const char *getDiagnosticCodeStr(enum CXLoadDiag_Error error) {
- switch (error) {
- case CXLoadDiag_CannotLoad: return "Cannot Load File";
- case CXLoadDiag_None: break;
- case CXLoadDiag_Unknown: return "Unknown";
- case CXLoadDiag_InvalidFile: return "Invalid File";
- }
- return "None";
- }
- static const char *getSeverityString(enum CXDiagnosticSeverity severity) {
- switch (severity) {
- case CXDiagnostic_Note: return "note";
- case CXDiagnostic_Error: return "error";
- case CXDiagnostic_Fatal: return "fatal";
- case CXDiagnostic_Ignored: return "ignored";
- case CXDiagnostic_Warning: return "warning";
- }
- return "unknown";
- }
- static void printIndent(unsigned indent) {
- if (indent == 0)
- return;
- fprintf(stderr, "+");
- --indent;
- while (indent > 0) {
- fprintf(stderr, "-");
- --indent;
- }
- }
- static void printLocation(CXSourceLocation L) {
- CXFile File;
- CXString FileName;
- unsigned line, column, offset;
-
- clang_getExpansionLocation(L, &File, &line, &column, &offset);
- FileName = clang_getFileName(File);
-
- fprintf(stderr, "%s:%d:%d", clang_getCString(FileName), line, column);
- clang_disposeString(FileName);
- }
- static void printRanges(CXDiagnostic D, unsigned indent) {
- unsigned i, n = clang_getDiagnosticNumRanges(D);
-
- for (i = 0; i < n; ++i) {
- CXSourceLocation Start, End;
- CXSourceRange SR = clang_getDiagnosticRange(D, i);
- Start = clang_getRangeStart(SR);
- End = clang_getRangeEnd(SR);
-
- printIndent(indent);
- fprintf(stderr, "Range: ");
- printLocation(Start);
- fprintf(stderr, " ");
- printLocation(End);
- fprintf(stderr, "\n");
- }
- }
- static void printFixIts(CXDiagnostic D, unsigned indent) {
- unsigned i, n = clang_getDiagnosticNumFixIts(D);
- fprintf(stderr, "Number FIXITs = %d\n", n);
- for (i = 0 ; i < n; ++i) {
- CXSourceRange ReplacementRange;
- CXString text;
- text = clang_getDiagnosticFixIt(D, i, &ReplacementRange);
-
- printIndent(indent);
- fprintf(stderr, "FIXIT: (");
- printLocation(clang_getRangeStart(ReplacementRange));
- fprintf(stderr, " - ");
- printLocation(clang_getRangeEnd(ReplacementRange));
- fprintf(stderr, "): \"%s\"\n", clang_getCString(text));
- clang_disposeString(text);
- }
- }
- static void printDiagnosticSet(CXDiagnosticSet Diags, unsigned indent) {
- unsigned i, n;
- if (!Diags)
- return;
-
- n = clang_getNumDiagnosticsInSet(Diags);
- for (i = 0; i < n; ++i) {
- CXSourceLocation DiagLoc;
- CXDiagnostic D;
- CXFile File;
- CXString FileName, DiagSpelling, DiagOption, DiagCat;
- unsigned line, column, offset;
- const char *DiagOptionStr = 0, *DiagCatStr = 0;
-
- D = clang_getDiagnosticInSet(Diags, i);
- DiagLoc = clang_getDiagnosticLocation(D);
- clang_getExpansionLocation(DiagLoc, &File, &line, &column, &offset);
- FileName = clang_getFileName(File);
- DiagSpelling = clang_getDiagnosticSpelling(D);
-
- printIndent(indent);
-
- fprintf(stderr, "%s:%d:%d: %s: %s",
- clang_getCString(FileName),
- line,
- column,
- getSeverityString(clang_getDiagnosticSeverity(D)),
- clang_getCString(DiagSpelling));
- DiagOption = clang_getDiagnosticOption(D, 0);
- DiagOptionStr = clang_getCString(DiagOption);
- if (DiagOptionStr) {
- fprintf(stderr, " [%s]", DiagOptionStr);
- }
-
- DiagCat = clang_getDiagnosticCategoryText(D);
- DiagCatStr = clang_getCString(DiagCat);
- if (DiagCatStr) {
- fprintf(stderr, " [%s]", DiagCatStr);
- }
-
- fprintf(stderr, "\n");
-
- printRanges(D, indent);
- printFixIts(D, indent);
-
- /* Print subdiagnostics. */
- printDiagnosticSet(clang_getChildDiagnostics(D), indent+2);
- clang_disposeString(FileName);
- clang_disposeString(DiagSpelling);
- clang_disposeString(DiagOption);
- }
- }
- static int read_diagnostics(const char *filename) {
- enum CXLoadDiag_Error error;
- CXString errorString;
- CXDiagnosticSet Diags = 0;
-
- Diags = clang_loadDiagnostics(filename, &error, &errorString);
- if (!Diags) {
- fprintf(stderr, "Trouble deserializing file (%s): %s\n",
- getDiagnosticCodeStr(error),
- clang_getCString(errorString));
- clang_disposeString(errorString);
- return 1;
- }
-
- printDiagnosticSet(Diags, 0);
- fprintf(stderr, "Number of diagnostics: %d\n",
- clang_getNumDiagnosticsInSet(Diags));
- clang_disposeDiagnosticSet(Diags);
- return 0;
- }
- /******************************************************************************/
- /* Command line processing. */
- /******************************************************************************/
- static CXCursorVisitor GetVisitor(const char *s) {
- if (s[0] == '\0')
- return FilteredPrintingVisitor;
- if (strcmp(s, "-usrs") == 0)
- return USRVisitor;
- if (strncmp(s, "-memory-usage", 13) == 0)
- return GetVisitor(s + 13);
- return NULL;
- }
- static void print_usage(void) {
- fprintf(stderr,
- "usage: c-index-test -code-completion-at=<site> <compiler arguments>\n"
- " c-index-test -code-completion-timing=<site> <compiler arguments>\n"
- " c-index-test -cursor-at=<site> <compiler arguments>\n"
- " c-index-test -file-refs-at=<site> <compiler arguments>\n"
- " c-index-test -index-file [-check-prefix=<FileCheck prefix>] <compiler arguments>\n"
- " c-index-test -index-tu [-check-prefix=<FileCheck prefix>] <AST file>\n"
- " c-index-test -test-file-scan <AST file> <source file> "
- "[FileCheck prefix]\n");
- fprintf(stderr,
- " c-index-test -test-load-tu <AST file> <symbol filter> "
- "[FileCheck prefix]\n"
- " c-index-test -test-load-tu-usrs <AST file> <symbol filter> "
- "[FileCheck prefix]\n"
- " c-index-test -test-load-source <symbol filter> {<args>}*\n");
- fprintf(stderr,
- " c-index-test -test-load-source-memory-usage "
- "<symbol filter> {<args>}*\n"
- " c-index-test -test-load-source-reparse <trials> <symbol filter> "
- " {<args>}*\n"
- " c-index-test -test-load-source-usrs <symbol filter> {<args>}*\n"
- " c-index-test -test-load-source-usrs-memory-usage "
- "<symbol filter> {<args>}*\n"
- " c-index-test -test-annotate-tokens=<range> {<args>}*\n"
- " c-index-test -test-inclusion-stack-source {<args>}*\n"
- " c-index-test -test-inclusion-stack-tu <AST file>\n");
- fprintf(stderr,
- " c-index-test -test-print-linkage-source {<args>}*\n"
- " c-index-test -test-print-typekind {<args>}*\n"
- " c-index-test -print-usr [<CursorKind> {<args>}]*\n"
- " c-index-test -print-usr-file <file>\n"
- " c-index-test -write-pch <file> <compiler arguments>\n");
- fprintf(stderr,
- " c-index-test -read-diagnostics <file>\n\n");
- fprintf(stderr,
- " <symbol filter> values:\n%s",
- " all - load all symbols, including those from PCH\n"
- " local - load all symbols except those in PCH\n"
- " category - only load ObjC categories (non-PCH)\n"
- " interface - only load ObjC interfaces (non-PCH)\n"
- " protocol - only load ObjC protocols (non-PCH)\n"
- " function - only load functions (non-PCH)\n"
- " typedef - only load typdefs (non-PCH)\n"
- " scan-function - scan function bodies (non-PCH)\n\n");
- }
- /***/
- int cindextest_main(int argc, const char **argv) {
- clang_enableStackTraces();
- if (argc > 2 && strcmp(argv[1], "-read-diagnostics") == 0)
- return read_diagnostics(argv[2]);
- if (argc > 2 && strstr(argv[1], "-code-completion-at=") == argv[1])
- return perform_code_completion(argc, argv, 0);
- if (argc > 2 && strstr(argv[1], "-code-completion-timing=") == argv[1])
- return perform_code_completion(argc, argv, 1);
- if (argc > 2 && strstr(argv[1], "-cursor-at=") == argv[1])
- return inspect_cursor_at(argc, argv);
- if (argc > 2 && strstr(argv[1], "-file-refs-at=") == argv[1])
- return find_file_refs_at(argc, argv);
- if (argc > 2 && strcmp(argv[1], "-index-file") == 0)
- return index_file(argc - 2, argv + 2);
- if (argc > 2 && strcmp(argv[1], "-index-tu") == 0)
- return index_tu(argc - 2, argv + 2);
- else if (argc >= 4 && strncmp(argv[1], "-test-load-tu", 13) == 0) {
- CXCursorVisitor I = GetVisitor(argv[1] + 13);
- if (I)
- return perform_test_load_tu(argv[2], argv[3], argc >= 5 ? argv[4] : 0, I,
- NULL);
- }
- else if (argc >= 5 && strncmp(argv[1], "-test-load-source-reparse", 25) == 0){
- CXCursorVisitor I = GetVisitor(argv[1] + 25);
- if (I) {
- int trials = atoi(argv[2]);
- return perform_test_reparse_source(argc - 4, argv + 4, trials, argv[3], I,
- NULL);
- }
- }
- else if (argc >= 4 && strncmp(argv[1], "-test-load-source", 17) == 0) {
- CXCursorVisitor I = GetVisitor(argv[1] + 17);
-
- PostVisitTU postVisit = 0;
- if (strstr(argv[1], "-memory-usage"))
- postVisit = PrintMemoryUsage;
-
- if (I)
- return perform_test_load_source(argc - 3, argv + 3, argv[2], I,
- postVisit);
- }
- else if (argc >= 4 && strcmp(argv[1], "-test-file-scan") == 0)
- return perform_file_scan(argv[2], argv[3],
- argc >= 5 ? argv[4] : 0);
- else if (argc > 2 && strstr(argv[1], "-test-annotate-tokens=") == argv[1])
- return perform_token_annotation(argc, argv);
- else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-source") == 0)
- return perform_test_load_source(argc - 2, argv + 2, "all", NULL,
- PrintInclusionStack);
- else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-tu") == 0)
- return perform_test_load_tu(argv[2], "all", NULL, NULL,
- PrintInclusionStack);
- else if (argc > 2 && strcmp(argv[1], "-test-print-linkage-source") == 0)
- return perform_test_load_source(argc - 2, argv + 2, "all", PrintLinkage,
- NULL);
- else if (argc > 2 && strcmp(argv[1], "-test-print-typekind") == 0)
- return perform_test_load_source(argc - 2, argv + 2, "all",
- PrintTypeKind, 0);
- else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) {
- if (argc > 2)
- return print_usrs(argv + 2, argv + argc);
- else {
- display_usrs();
- return 1;
- }
- }
- else if (argc > 2 && strcmp(argv[1], "-print-usr-file") == 0)
- return print_usrs_file(argv[2]);
- else if (argc > 2 && strcmp(argv[1], "-write-pch") == 0)
- return write_pch_file(argv[2], argc - 3, argv + 3);
-
- print_usage();
- return 1;
- }
- /***/
- /* We intentionally run in a separate thread to ensure we at least minimal
- * testing of a multithreaded environment (for example, having a reduced stack
- * size). */
- typedef struct thread_info {
- int argc;
- const char **argv;
- int result;
- } thread_info;
- void thread_runner(void *client_data_v) {
- thread_info *client_data = client_data_v;
- client_data->result = cindextest_main(client_data->argc, client_data->argv);
- #ifdef __CYGWIN__
- fflush(stdout); /* stdout is not flushed on Cygwin. */
- #endif
- }
- int main(int argc, const char **argv) {
- thread_info client_data;
- if (getenv("CINDEXTEST_NOTHREADS"))
- return cindextest_main(argc, argv);
- client_data.argc = argc;
- client_data.argv = argv;
- clang_executeOnThread(thread_runner, &client_data, 0);
- return client_data.result;
- }
|