summaryrefslogtreecommitdiffstats
path: root/tools/c-index-test/c-index-test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/c-index-test/c-index-test.c')
-rw-r--r--tools/c-index-test/c-index-test.c606
1 files changed, 576 insertions, 30 deletions
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index eb2a406..5df21ec 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1,12 +1,20 @@
/* c-index-test.c */
#include "clang-c/Index.h"
+#include "clang-c/CXCompilationDatabase.h"
+#include "llvm/Config/config.h"
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
+#ifdef CLANG_HAVE_LIBXML
+#include <libxml/parser.h>
+#include <libxml/relaxng.h>
+#include <libxml/xmlerror.h>
+#endif
+
/******************************************************************************/
/* Utility functions. */
/******************************************************************************/
@@ -25,8 +33,25 @@ char *basename(const char* path)
return((char*)path);
}
+char *dirname(char* path)
+{
+ char* base1 = (char*)strrchr(path, '/');
+ char* base2 = (char*)strrchr(path, '\\');
+ if (base1 && base2)
+ if (base1 > base2)
+ *base1 = 0;
+ else
+ *base2 = 0;
+ else if (base1)
+ *base1 = 0;
+ else if (base2)
+ *base2 = 0;
+
+ return path;
+}
#else
extern char *basename(const char *);
+extern char *dirname(char *);
#endif
/** \brief Return the default parsing options. */
@@ -41,6 +66,8 @@ static unsigned getDefaultParsingOptions() {
options &= ~CXTranslationUnit_CacheCompletionResults;
if (getenv("CINDEXTEST_SKIP_FUNCTION_BODIES"))
options |= CXTranslationUnit_SkipFunctionBodies;
+ if (getenv("CINDEXTEST_COMPLETION_BRIEF_COMMENTS"))
+ options |= CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
return options;
}
@@ -137,6 +164,7 @@ int parse_remapped_files(int argc, const char **argv, int start_arg,
(feof(to_file) ? "EOF" : "error"), semi + 1);
fclose(to_file);
free_remapped_files(*unsaved_files, i);
+ free(contents);
*unsaved_files = 0;
*num_unsaved_files = 0;
return -1;
@@ -158,10 +186,62 @@ int parse_remapped_files(int argc, const char **argv, int start_arg,
return 0;
}
+static const char *parse_comments_schema(int argc, const char **argv) {
+ const char *CommentsSchemaArg = "-comments-xml-schema=";
+ const char *CommentSchemaFile = NULL;
+
+ if (argc == 0)
+ return CommentSchemaFile;
+
+ if (!strncmp(argv[0], CommentsSchemaArg, strlen(CommentsSchemaArg)))
+ CommentSchemaFile = argv[0] + strlen(CommentsSchemaArg);
+
+ return CommentSchemaFile;
+}
+
/******************************************************************************/
/* Pretty-printing. */
/******************************************************************************/
+static const char *FileCheckPrefix = "CHECK";
+
+static void PrintCString(const char *CStr) {
+ if (CStr != NULL && CStr[0] != '\0') {
+ for ( ; *CStr; ++CStr) {
+ const char C = *CStr;
+ switch (C) {
+ case '\n': printf("\\n"); break;
+ case '\r': printf("\\r"); break;
+ case '\t': printf("\\t"); break;
+ case '\v': printf("\\v"); break;
+ case '\f': printf("\\f"); break;
+ default: putchar(C); break;
+ }
+ }
+ }
+}
+
+static void PrintCStringWithPrefix(const char *Prefix, const char *CStr) {
+ printf(" %s=[", Prefix);
+ PrintCString(CStr);
+ printf("]");
+}
+
+static void PrintCXStringAndDispose(CXString Str) {
+ PrintCString(clang_getCString(Str));
+ clang_disposeString(Str);
+}
+
+static void PrintCXStringWithPrefix(const char *Prefix, CXString Str) {
+ PrintCStringWithPrefix(Prefix, clang_getCString(Str));
+}
+
+static void PrintCXStringWithPrefixAndDispose(const char *Prefix,
+ CXString Str) {
+ PrintCStringWithPrefix(Prefix, clang_getCString(Str));
+ clang_disposeString(Str);
+}
+
static void PrintRange(CXSourceRange R, const char *str) {
CXFile begin_file, end_file;
unsigned begin_line, begin_column, end_line, end_column;
@@ -180,7 +260,302 @@ static void PrintRange(CXSourceRange R, const char *str) {
int want_display_name = 0;
-static void PrintCursor(CXCursor Cursor) {
+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);
+}
+
+struct CommentASTDumpingContext {
+ int IndentLevel;
+};
+
+static void DumpCXCommentInternal(struct CommentASTDumpingContext *Ctx,
+ CXComment Comment) {
+ unsigned i;
+ unsigned e;
+ enum CXCommentKind Kind = clang_Comment_getKind(Comment);
+
+ Ctx->IndentLevel++;
+ for (i = 0, e = Ctx->IndentLevel; i != e; ++i)
+ printf(" ");
+
+ printf("(");
+ switch (Kind) {
+ case CXComment_Null:
+ printf("CXComment_Null");
+ break;
+ case CXComment_Text:
+ printf("CXComment_Text");
+ PrintCXStringWithPrefixAndDispose("Text",
+ clang_TextComment_getText(Comment));
+ if (clang_Comment_isWhitespace(Comment))
+ printf(" IsWhitespace");
+ if (clang_InlineContentComment_hasTrailingNewline(Comment))
+ printf(" HasTrailingNewline");
+ break;
+ case CXComment_InlineCommand:
+ printf("CXComment_InlineCommand");
+ PrintCXStringWithPrefixAndDispose(
+ "CommandName",
+ clang_InlineCommandComment_getCommandName(Comment));
+ switch (clang_InlineCommandComment_getRenderKind(Comment)) {
+ case CXCommentInlineCommandRenderKind_Normal:
+ printf(" RenderNormal");
+ break;
+ case CXCommentInlineCommandRenderKind_Bold:
+ printf(" RenderBold");
+ break;
+ case CXCommentInlineCommandRenderKind_Monospaced:
+ printf(" RenderMonospaced");
+ break;
+ case CXCommentInlineCommandRenderKind_Emphasized:
+ printf(" RenderEmphasized");
+ break;
+ }
+ for (i = 0, e = clang_InlineCommandComment_getNumArgs(Comment);
+ i != e; ++i) {
+ printf(" Arg[%u]=", i);
+ PrintCXStringAndDispose(
+ clang_InlineCommandComment_getArgText(Comment, i));
+ }
+ if (clang_InlineContentComment_hasTrailingNewline(Comment))
+ printf(" HasTrailingNewline");
+ break;
+ case CXComment_HTMLStartTag: {
+ unsigned NumAttrs;
+ printf("CXComment_HTMLStartTag");
+ PrintCXStringWithPrefixAndDispose(
+ "Name",
+ clang_HTMLTagComment_getTagName(Comment));
+ NumAttrs = clang_HTMLStartTag_getNumAttrs(Comment);
+ if (NumAttrs != 0) {
+ printf(" Attrs:");
+ for (i = 0; i != NumAttrs; ++i) {
+ printf(" ");
+ PrintCXStringAndDispose(clang_HTMLStartTag_getAttrName(Comment, i));
+ printf("=");
+ PrintCXStringAndDispose(clang_HTMLStartTag_getAttrValue(Comment, i));
+ }
+ }
+ if (clang_HTMLStartTagComment_isSelfClosing(Comment))
+ printf(" SelfClosing");
+ if (clang_InlineContentComment_hasTrailingNewline(Comment))
+ printf(" HasTrailingNewline");
+ break;
+ }
+ case CXComment_HTMLEndTag:
+ printf("CXComment_HTMLEndTag");
+ PrintCXStringWithPrefixAndDispose(
+ "Name",
+ clang_HTMLTagComment_getTagName(Comment));
+ if (clang_InlineContentComment_hasTrailingNewline(Comment))
+ printf(" HasTrailingNewline");
+ break;
+ case CXComment_Paragraph:
+ printf("CXComment_Paragraph");
+ if (clang_Comment_isWhitespace(Comment))
+ printf(" IsWhitespace");
+ break;
+ case CXComment_BlockCommand:
+ printf("CXComment_BlockCommand");
+ PrintCXStringWithPrefixAndDispose(
+ "CommandName",
+ clang_BlockCommandComment_getCommandName(Comment));
+ for (i = 0, e = clang_BlockCommandComment_getNumArgs(Comment);
+ i != e; ++i) {
+ printf(" Arg[%u]=", i);
+ PrintCXStringAndDispose(
+ clang_BlockCommandComment_getArgText(Comment, i));
+ }
+ break;
+ case CXComment_ParamCommand:
+ printf("CXComment_ParamCommand");
+ switch (clang_ParamCommandComment_getDirection(Comment)) {
+ case CXCommentParamPassDirection_In:
+ printf(" in");
+ break;
+ case CXCommentParamPassDirection_Out:
+ printf(" out");
+ break;
+ case CXCommentParamPassDirection_InOut:
+ printf(" in,out");
+ break;
+ }
+ if (clang_ParamCommandComment_isDirectionExplicit(Comment))
+ printf(" explicitly");
+ else
+ printf(" implicitly");
+ PrintCXStringWithPrefixAndDispose(
+ "ParamName",
+ clang_ParamCommandComment_getParamName(Comment));
+ if (clang_ParamCommandComment_isParamIndexValid(Comment))
+ printf(" ParamIndex=%u", clang_ParamCommandComment_getParamIndex(Comment));
+ else
+ printf(" ParamIndex=Invalid");
+ break;
+ case CXComment_TParamCommand:
+ printf("CXComment_TParamCommand");
+ PrintCXStringWithPrefixAndDispose(
+ "ParamName",
+ clang_TParamCommandComment_getParamName(Comment));
+ if (clang_TParamCommandComment_isParamPositionValid(Comment)) {
+ printf(" ParamPosition={");
+ for (i = 0, e = clang_TParamCommandComment_getDepth(Comment);
+ i != e; ++i) {
+ printf("%u", clang_TParamCommandComment_getIndex(Comment, i));
+ if (i != e - 1)
+ printf(", ");
+ }
+ printf("}");
+ } else
+ printf(" ParamPosition=Invalid");
+ break;
+ case CXComment_VerbatimBlockCommand:
+ printf("CXComment_VerbatimBlockCommand");
+ PrintCXStringWithPrefixAndDispose(
+ "CommandName",
+ clang_BlockCommandComment_getCommandName(Comment));
+ break;
+ case CXComment_VerbatimBlockLine:
+ printf("CXComment_VerbatimBlockLine");
+ PrintCXStringWithPrefixAndDispose(
+ "Text",
+ clang_VerbatimBlockLineComment_getText(Comment));
+ break;
+ case CXComment_VerbatimLine:
+ printf("CXComment_VerbatimLine");
+ PrintCXStringWithPrefixAndDispose(
+ "Text",
+ clang_VerbatimLineComment_getText(Comment));
+ break;
+ case CXComment_FullComment:
+ printf("CXComment_FullComment");
+ break;
+ }
+ if (Kind != CXComment_Null) {
+ const unsigned NumChildren = clang_Comment_getNumChildren(Comment);
+ unsigned i;
+ for (i = 0; i != NumChildren; ++i) {
+ printf("\n// %s: ", FileCheckPrefix);
+ DumpCXCommentInternal(Ctx, clang_Comment_getChild(Comment, i));
+ }
+ }
+ printf(")");
+ Ctx->IndentLevel--;
+}
+
+static void DumpCXComment(CXComment Comment) {
+ struct CommentASTDumpingContext Ctx;
+ Ctx.IndentLevel = 1;
+ printf("\n// %s: CommentAST=[\n// %s:", FileCheckPrefix, FileCheckPrefix);
+ DumpCXCommentInternal(&Ctx, Comment);
+ printf("]");
+}
+
+typedef struct {
+ const char *CommentSchemaFile;
+#ifdef CLANG_HAVE_LIBXML
+ xmlRelaxNGParserCtxtPtr RNGParser;
+ xmlRelaxNGPtr Schema;
+#endif
+} CommentXMLValidationData;
+
+static void ValidateCommentXML(const char *Str,
+ CommentXMLValidationData *ValidationData) {
+#ifdef CLANG_HAVE_LIBXML
+ xmlDocPtr Doc;
+ xmlRelaxNGValidCtxtPtr ValidationCtxt;
+ int status;
+
+ if (!ValidationData || !ValidationData->CommentSchemaFile)
+ return;
+
+ if (!ValidationData->RNGParser) {
+ ValidationData->RNGParser =
+ xmlRelaxNGNewParserCtxt(ValidationData->CommentSchemaFile);
+ ValidationData->Schema = xmlRelaxNGParse(ValidationData->RNGParser);
+ }
+ if (!ValidationData->RNGParser) {
+ printf(" libXMLError");
+ return;
+ }
+
+ Doc = xmlParseDoc((const xmlChar *) Str);
+
+ if (!Doc) {
+ xmlErrorPtr Error = xmlGetLastError();
+ printf(" CommentXMLInvalid [not well-formed XML: %s]", Error->message);
+ return;
+ }
+
+ ValidationCtxt = xmlRelaxNGNewValidCtxt(ValidationData->Schema);
+ status = xmlRelaxNGValidateDoc(ValidationCtxt, Doc);
+ if (!status)
+ printf(" CommentXMLValid");
+ else if (status > 0) {
+ xmlErrorPtr Error = xmlGetLastError();
+ printf(" CommentXMLInvalid [not vaild XML: %s]", Error->message);
+ } else
+ printf(" libXMLError");
+
+ xmlRelaxNGFreeValidCtxt(ValidationCtxt);
+ xmlFreeDoc(Doc);
+#endif
+}
+
+static void PrintCursorComments(CXTranslationUnit TU,
+ CXCursor Cursor,
+ CommentXMLValidationData *ValidationData) {
+ {
+ CXString RawComment;
+ const char *RawCommentCString;
+ CXString BriefComment;
+ const char *BriefCommentCString;
+
+ RawComment = clang_Cursor_getRawCommentText(Cursor);
+ RawCommentCString = clang_getCString(RawComment);
+ if (RawCommentCString != NULL && RawCommentCString[0] != '\0') {
+ PrintCStringWithPrefix("RawComment", RawCommentCString);
+ PrintRange(clang_Cursor_getCommentRange(Cursor), "RawCommentRange");
+
+ BriefComment = clang_Cursor_getBriefCommentText(Cursor);
+ BriefCommentCString = clang_getCString(BriefComment);
+ if (BriefCommentCString != NULL && BriefCommentCString[0] != '\0')
+ PrintCStringWithPrefix("BriefComment", BriefCommentCString);
+ clang_disposeString(BriefComment);
+ }
+ clang_disposeString(RawComment);
+ }
+
+ {
+ CXComment Comment = clang_Cursor_getParsedComment(Cursor);
+ if (clang_Comment_getKind(Comment) != CXComment_Null) {
+ PrintCXStringWithPrefixAndDispose("FullCommentAsHTML",
+ clang_FullComment_getAsHTML(Comment));
+ {
+ CXString XML;
+ XML = clang_FullComment_getAsXML(TU, Comment);
+ PrintCXStringWithPrefix("FullCommentAsXML", XML);
+ ValidateCommentXML(clang_getCString(XML), ValidationData);
+ clang_disposeString(XML);
+ }
+
+ DumpCXComment(Comment);
+ }
+ }
+}
+
+static void PrintCursor(CXCursor Cursor,
+ CommentXMLValidationData *ValidationData) {
CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
if (clang_isInvalid(Cursor.kind)) {
CXString ks = clang_getCursorKindSpelling(Cursor.kind);
@@ -197,6 +572,13 @@ static void PrintCursor(CXCursor Cursor) {
unsigned RefNameRangeNr;
CXSourceRange CursorExtent;
CXSourceRange RefNameRange;
+ int AlwaysUnavailable;
+ int AlwaysDeprecated;
+ CXString UnavailableMessage;
+ CXString DeprecatedMessage;
+ CXPlatformAvailability PlatformAvailability[2];
+ int NumPlatformAvailability;
+ int I;
ks = clang_getCursorKindSpelling(Cursor.kind);
string = want_display_name? clang_getCursorDisplayName(Cursor)
@@ -249,6 +631,47 @@ static void PrintCursor(CXCursor Cursor) {
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))
@@ -336,6 +759,8 @@ static void PrintCursor(CXCursor Cursor) {
if (!clang_equalRanges(CursorExtent, RefNameRange))
PrintRange(RefNameRange, "RefName");
}
+
+ PrintCursorComments(TU, Cursor, ValidationData);
}
}
@@ -458,17 +883,16 @@ void PrintMemoryUsage(CXTranslationUnit TU) {
/* 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 {
+/* Data used by the visitors. */
+typedef struct {
CXTranslationUnit TU;
enum CXCursorKind *Filter;
+ CommentXMLValidationData ValidationData;
} VisitorData;
@@ -482,7 +906,7 @@ enum CXChildVisitResult FilteredPrintingVisitor(CXCursor Cursor,
clang_getSpellingLocation(Loc, 0, &line, &column, 0);
printf("// %s: %s:%d:%d: ", FileCheckPrefix,
GetCursorSource(Cursor), line, column);
- PrintCursor(Cursor);
+ PrintCursor(Cursor, &Data->ValidationData);
PrintCursorExtent(Cursor);
printf("\n");
return CXChildVisit_Recurse;
@@ -535,7 +959,7 @@ static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor,
} else if (Ref.kind != CXCursor_FunctionDecl) {
printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref),
curLine, curColumn);
- PrintCursor(Ref);
+ PrintCursor(Ref, &Data->ValidationData);
printf("\n");
}
}
@@ -622,7 +1046,7 @@ static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p,
}
if (linkage) {
- PrintCursor(cursor);
+ PrintCursor(cursor, NULL);
printf("linkage=%s\n", linkage);
}
@@ -638,7 +1062,7 @@ static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
if (!clang_isInvalid(clang_getCursorKind(cursor))) {
CXType T = clang_getCursorType(cursor);
CXString S = clang_getTypeKindSpelling(T.kind);
- PrintCursor(cursor);
+ PrintCursor(cursor, NULL);
printf(" typekind=%s", clang_getCString(S));
if (clang_isConstQualifiedType(T))
printf(" const");
@@ -698,7 +1122,8 @@ static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
static int perform_test_load(CXIndex Idx, CXTranslationUnit TU,
const char *filter, const char *prefix,
CXCursorVisitor Visitor,
- PostVisitTU PV) {
+ PostVisitTU PV,
+ const char *CommentSchemaFile) {
if (prefix)
FileCheckPrefix = prefix;
@@ -729,6 +1154,11 @@ static int perform_test_load(CXIndex Idx, CXTranslationUnit TU,
Data.TU = TU;
Data.Filter = ck;
+ Data.ValidationData.CommentSchemaFile = CommentSchemaFile;
+#ifdef CLANG_HAVE_LIBXML
+ Data.ValidationData.RNGParser = NULL;
+ Data.ValidationData.Schema = NULL;
+#endif
clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data);
}
@@ -760,7 +1190,7 @@ int perform_test_load_tu(const char *file, const char *filter,
return 1;
}
- result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV);
+ result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV, NULL);
clang_disposeIndex(Idx);
return result;
}
@@ -770,6 +1200,7 @@ int perform_test_load_source(int argc, const char **argv,
PostVisitTU PV) {
CXIndex Idx;
CXTranslationUnit TU;
+ const char *CommentSchemaFile;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
int result;
@@ -779,6 +1210,11 @@ int perform_test_load_source(int argc, const char **argv,
!strcmp(filter, "local-display"))? 1 : 0,
/* displayDiagnosics=*/0);
+ if ((CommentSchemaFile = parse_comments_schema(argc, argv))) {
+ argc--;
+ argv++;
+ }
+
if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
clang_disposeIndex(Idx);
return -1;
@@ -796,7 +1232,8 @@ int perform_test_load_source(int argc, const char **argv,
return 1;
}
- result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV);
+ result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV,
+ CommentSchemaFile);
free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
return result;
@@ -860,7 +1297,7 @@ int perform_test_reparse_source(int argc, const char **argv, int trials,
return -1;
}
- result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV);
+ result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV, NULL);
free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
@@ -880,7 +1317,7 @@ static void print_cursor_file_scan(CXTranslationUnit TU, CXCursor cursor,
printf("-%s", prefix);
PrintExtent(stdout, start_line, start_col, end_line, end_col);
printf(" ");
- PrintCursor(cursor);
+ PrintCursor(cursor, NULL);
printf("\n");
}
@@ -1104,6 +1541,8 @@ void print_completion_result(CXCompletionResult *completion_result,
unsigned annotationCount;
enum CXCursorKind ParentKind;
CXString ParentName;
+ CXString BriefComment;
+ const char *BriefCommentCString;
fprintf(file, "%s:", clang_getCString(ks));
clang_disposeString(ks);
@@ -1155,6 +1594,14 @@ void print_completion_result(CXCompletionResult *completion_result,
}
clang_disposeString(ParentName);
}
+
+ BriefComment = clang_getCompletionBriefComment(
+ completion_result->CompletionString);
+ BriefCommentCString = clang_getCString(BriefComment);
+ if (BriefCommentCString && *BriefCommentCString != '\0') {
+ fprintf(file, "(brief comment: %s)", BriefCommentCString);
+ }
+ clang_disposeString(BriefComment);
fprintf(file, "\n");
}
@@ -1267,6 +1714,8 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
if (getenv("CINDEXTEST_CODE_COMPLETE_PATTERNS"))
completionOptions |= CXCodeComplete_IncludeCodePatterns;
+ if (getenv("CINDEXTEST_COMPLETION_BRIEF_COMMENTS"))
+ completionOptions |= CXCodeComplete_IncludeBriefComments;
if (timing_only)
input += strlen("-code-completion-timing=");
@@ -1465,7 +1914,7 @@ static int inspect_cursor_at(int argc, const char **argv) {
unsigned line, column;
clang_getSpellingLocation(CursorLoc, 0, &line, &column, 0);
printf("%d:%d ", line, column);
- PrintCursor(Cursor);
+ PrintCursor(Cursor, NULL);
PrintCursorExtent(Cursor);
Spelling = clang_getCursorSpelling(Cursor);
cspell = clang_getCString(Spelling);
@@ -1484,6 +1933,9 @@ static int inspect_cursor_at(int argc, const char **argv) {
clang_disposeString(Spelling);
if (clang_Cursor_getObjCSelectorIndex(Cursor) != -1)
printf(" Selector index=%d",clang_Cursor_getObjCSelectorIndex(Cursor));
+ if (clang_Cursor_isDynamicCall(Cursor))
+ printf(" Dynamic-call");
+
if (completionString != NULL) {
printf("\nCompletion string: ");
print_completion_string(completionString, stdout);
@@ -1507,7 +1959,7 @@ static enum CXVisitorResult findFileRefsVisit(void *context,
if (clang_Range_isNull(range))
return CXVisit_Continue;
- PrintCursor(cursor);
+ PrintCursor(cursor, NULL);
PrintRange(range, "");
printf("\n");
return CXVisit_Continue;
@@ -1591,7 +2043,7 @@ static int find_file_refs_at(int argc, const char **argv) {
if (I + 1 == Repeats) {
CXCursorAndRangeVisitor visitor = { 0, findFileRefsVisit };
- PrintCursor(Cursor);
+ PrintCursor(Cursor, NULL);
printf("\n");
clang_findReferencesInFile(Cursor, file, visitor);
free(Locations[Loc].filename);
@@ -1789,7 +2241,7 @@ static void printEntityInfo(const char *cb,
for (i = 0; i != info->numAttributes; ++i) {
const CXIdxAttrInfo *Attr = info->attributes[i];
printf(" <attribute>: ");
- PrintCursor(Attr->cursor);
+ PrintCursor(Attr->cursor, NULL);
}
}
@@ -1797,7 +2249,7 @@ static void printBaseClassInfo(CXClientData client_data,
const CXIdxBaseClassInfo *info) {
printEntityInfo(" <base>", client_data, info->base);
printf(" | cursor: ");
- PrintCursor(info->cursor);
+ PrintCursor(info->cursor, NULL);
printf(" | loc: ");
printCXIndexLoc(info->loc, client_data);
}
@@ -1809,7 +2261,7 @@ static void printProtocolList(const CXIdxObjCProtocolRefListInfo *ProtoInfo,
printEntityInfo(" <protocol>", client_data,
ProtoInfo->protocols[i]->protocol);
printf(" | cursor: ");
- PrintCursor(ProtoInfo->protocols[i]->cursor);
+ PrintCursor(ProtoInfo->protocols[i]->cursor, NULL);
printf(" | loc: ");
printCXIndexLoc(ProtoInfo->protocols[i]->loc, client_data);
printf("\n");
@@ -1899,7 +2351,7 @@ static void index_indexDeclaration(CXClientData client_data,
printEntityInfo("[indexDeclaration]", client_data, info->entityInfo);
printf(" | cursor: ");
- PrintCursor(info->cursor);
+ PrintCursor(info->cursor, NULL);
printf(" | loc: ");
printCXIndexLoc(info->loc, client_data);
printf(" | semantic-container: ");
@@ -1914,7 +2366,7 @@ static void index_indexDeclaration(CXClientData client_data,
for (i = 0; i != info->numAttributes; ++i) {
const CXIdxAttrInfo *Attr = info->attributes[i];
printf(" <attribute>: ");
- PrintCursor(Attr->cursor);
+ PrintCursor(Attr->cursor, NULL);
printf("\n");
}
@@ -1937,7 +2389,7 @@ static void index_indexDeclaration(CXClientData client_data,
printEntityInfo(" <ObjCCategoryInfo>: class", client_data,
CatInfo->objcClass);
printf(" | cursor: ");
- PrintCursor(CatInfo->classCursor);
+ PrintCursor(CatInfo->classCursor, NULL);
printf(" | loc: ");
printCXIndexLoc(CatInfo->classLoc, client_data);
printf("\n");
@@ -1981,7 +2433,7 @@ static void index_indexEntityReference(CXClientData client_data,
const CXIdxEntityRefInfo *info) {
printEntityInfo("[indexEntityReference]", client_data, info->referencedEntity);
printf(" | cursor: ");
- PrintCursor(info->cursor);
+ PrintCursor(info->cursor, NULL);
printf(" | loc: ");
printCXIndexLoc(info->loc, client_data);
printEntityInfo(" | <parent>:", client_data, info->parentEntity);
@@ -2051,7 +2503,6 @@ static int index_file(int argc, const char **argv) {
return 1;
}
idxAction = 0;
- result = 1;
index_data.check_prefix = check_prefix;
index_data.first_check_printed = 0;
@@ -2148,8 +2599,10 @@ int perform_token_annotation(int argc, const char **argv) {
&second_line, &second_column)))
return errorCode;
- if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
+ if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files)) {
+ free(filename);
return -1;
+ }
CIdx = clang_createIndex(0, 1);
TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
@@ -2167,8 +2620,10 @@ int perform_token_annotation(int argc, const char **argv) {
}
errorCode = 0;
- if (checkForErrors(TU) != 0)
- return -1;
+ if (checkForErrors(TU) != 0) {
+ errorCode = -1;
+ goto teardown;
+ }
if (getenv("CINDEXTEST_EDITING")) {
for (i = 0; i < 5; ++i) {
@@ -2247,7 +2702,7 @@ int perform_token_annotation(int argc, const char **argv) {
PrintExtent(stdout, start_line, start_column, end_line, end_column);
if (!clang_isInvalid(cursors[i].kind)) {
printf(" ");
- PrintCursor(cursors[i]);
+ PrintCursor(cursors[i], NULL);
}
printf("\n");
}
@@ -2263,6 +2718,89 @@ int perform_token_annotation(int argc, const char **argv) {
return errorCode;
}
+static int
+perform_test_compilation_db(const char *database, int argc, const char **argv) {
+ CXCompilationDatabase db;
+ CXCompileCommands CCmds;
+ CXCompileCommand CCmd;
+ CXCompilationDatabase_Error ec;
+ CXString wd;
+ CXString arg;
+ int errorCode = 0;
+ char *tmp;
+ unsigned len;
+ char *buildDir;
+ int i, j, a, numCmds, numArgs;
+
+ len = strlen(database);
+ tmp = (char *) malloc(len+1);
+ memcpy(tmp, database, len+1);
+ buildDir = dirname(tmp);
+
+ db = clang_CompilationDatabase_fromDirectory(buildDir, &ec);
+
+ if (db) {
+
+ if (ec!=CXCompilationDatabase_NoError) {
+ printf("unexpected error %d code while loading compilation database\n", ec);
+ errorCode = -1;
+ goto cdb_end;
+ }
+
+ for (i=0; i<argc && errorCode==0; ) {
+ if (strcmp(argv[i],"lookup")==0){
+ CCmds = clang_CompilationDatabase_getCompileCommands(db, argv[i+1]);
+
+ if (!CCmds) {
+ printf("file %s not found in compilation db\n", argv[i+1]);
+ errorCode = -1;
+ break;
+ }
+
+ numCmds = clang_CompileCommands_getSize(CCmds);
+
+ if (numCmds==0) {
+ fprintf(stderr, "should not get an empty compileCommand set for file"
+ " '%s'\n", argv[i+1]);
+ errorCode = -1;
+ break;
+ }
+
+ for (j=0; j<numCmds; ++j) {
+ CCmd = clang_CompileCommands_getCommand(CCmds, j);
+
+ wd = clang_CompileCommand_getDirectory(CCmd);
+ printf("workdir:'%s'", clang_getCString(wd));
+ clang_disposeString(wd);
+
+ printf(" cmdline:'");
+ numArgs = clang_CompileCommand_getNumArgs(CCmd);
+ for (a=0; a<numArgs; ++a) {
+ if (a) printf(" ");
+ arg = clang_CompileCommand_getArg(CCmd, a);
+ printf("%s", clang_getCString(arg));
+ clang_disposeString(arg);
+ }
+ printf("'\n");
+ }
+
+ clang_CompileCommands_dispose(CCmds);
+
+ i += 2;
+ }
+ }
+ clang_CompilationDatabase_dispose(db);
+ } else {
+ printf("database loading failed with error code %d.\n", ec);
+ errorCode = -1;
+ }
+
+cdb_end:
+ free(tmp);
+
+ return errorCode;
+}
+
/******************************************************************************/
/* USR printing. */
/******************************************************************************/
@@ -2703,6 +3241,8 @@ static void print_usage(void) {
" c-index-test -print-usr-file <file>\n"
" c-index-test -write-pch <file> <compiler arguments>\n");
fprintf(stderr,
+ " c-index-test -compilation-db [lookup <filename>] database\n");
+ fprintf(stderr,
" c-index-test -read-diagnostics <file>\n\n");
fprintf(stderr,
" <symbol filter> values:\n%s",
@@ -2788,7 +3328,9 @@ int cindextest_main(int argc, const char **argv) {
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);
-
+ else if (argc > 2 && strcmp(argv[1], "-compilation-db") == 0)
+ return perform_test_compilation_db(argv[argc-1], argc - 3, argv + 2);
+
print_usage();
return 1;
}
@@ -2815,6 +3357,10 @@ void thread_runner(void *client_data_v) {
int main(int argc, const char **argv) {
thread_info client_data;
+#ifdef CLANG_HAVE_LIBXML
+ LIBXML_TEST_VERSION
+#endif
+
if (getenv("CINDEXTEST_NOTHREADS"))
return cindextest_main(argc, argv);
OpenPOWER on IntegriCloud