Updated to Clang 3.5a.
Change-Id: I8127eb568f674c2e72635b639a3295381fe8af82
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index fef0adc..58be615 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -2,6 +2,7 @@
add_subdirectory(driver)
if(CLANG_ENABLE_REWRITER)
add_subdirectory(clang-format)
+ add_subdirectory(clang-format-vs)
endif()
if(CLANG_ENABLE_ARCMT)
diff --git a/tools/arcmt-test/CMakeLists.txt b/tools/arcmt-test/CMakeLists.txt
index 3d85d05..0cb2c0f 100644
--- a/tools/arcmt-test/CMakeLists.txt
+++ b/tools/arcmt-test/CMakeLists.txt
@@ -1,9 +1,5 @@
set(LLVM_LINK_COMPONENTS
- ${LLVM_TARGETS_TO_BUILD}
- asmparser
- bitreader
support
- mc
)
add_clang_executable(arcmt-test
@@ -12,6 +8,7 @@
target_link_libraries(arcmt-test
clangARCMigrate
- clangEdit
- clangRewriteCore
+ clangBasic
+ clangFrontend
+ clangLex
)
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
index 50426e3..28331c2 100644
--- a/tools/arcmt-test/arcmt-test.cpp
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -83,17 +83,17 @@
PrintTransforms(raw_ostream &OS)
: Ctx(0), OS(OS) { }
- virtual void start(ASTContext &ctx) { Ctx = &ctx; }
- virtual void finish() { Ctx = 0; }
+ void start(ASTContext &ctx) override { Ctx = &ctx; }
+ void finish() override { Ctx = 0; }
- virtual void insert(SourceLocation loc, StringRef text) {
+ void insert(SourceLocation loc, StringRef text) override {
assert(Ctx);
OS << "Insert: ";
printSourceLocation(loc, *Ctx, OS);
OS << " \"" << text << "\"\n";
}
- virtual void remove(CharSourceRange range) {
+ void remove(CharSourceRange range) override {
assert(Ctx);
OS << "Remove: ";
printSourceRange(range, *Ctx, OS);
@@ -178,7 +178,7 @@
origCI.getMigratorOpts().NoFinalizeRemoval);
assert(!transforms.empty());
- OwningPtr<PrintTransforms> transformPrinter;
+ std::unique_ptr<PrintTransforms> transformPrinter;
if (OutputTransformations)
transformPrinter.reset(new PrintTransforms(llvm::outs()));
@@ -207,12 +207,12 @@
static bool filesCompareEqual(StringRef fname1, StringRef fname2) {
using namespace llvm;
- OwningPtr<MemoryBuffer> file1;
+ std::unique_ptr<MemoryBuffer> file1;
MemoryBuffer::getFile(fname1, file1);
if (!file1)
return false;
-
- OwningPtr<MemoryBuffer> file2;
+
+ std::unique_ptr<MemoryBuffer> file2;
MemoryBuffer::getFile(fname2, file2);
if (!file2)
return false;
@@ -238,7 +238,7 @@
resultMap[sys::path::stem(fname)] = fname;
}
- OwningPtr<MemoryBuffer> inputBuf;
+ std::unique_ptr<MemoryBuffer> inputBuf;
if (RemappingsFile.empty())
MemoryBuffer::getSTDIN(inputBuf);
else
diff --git a/tools/c-arcmt-test/CMakeLists.txt b/tools/c-arcmt-test/CMakeLists.txt
index 1e72261..9014ccc 100644
--- a/tools/c-arcmt-test/CMakeLists.txt
+++ b/tools/c-arcmt-test/CMakeLists.txt
@@ -1,8 +1,3 @@
-set( LLVM_LINK_COMPONENTS
- support
- mc
- )
-
add_clang_executable(c-arcmt-test
c-arcmt-test.c
)
diff --git a/tools/c-arcmt-test/Makefile b/tools/c-arcmt-test/Makefile
index 4a01c72..6ac5e20 100644
--- a/tools/c-arcmt-test/Makefile
+++ b/tools/c-arcmt-test/Makefile
@@ -30,6 +30,7 @@
clangRewriteFrontend.a \
clangRewriteCore.a \
clangIndex.a clangFrontend.a clangDriver.a \
+ clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
clangSerialization.a clangParse.a clangSema.a \
clangAnalysis.a clangEdit.a clangAST.a clangLex.a clangBasic.a
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index d850411..113172a 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -1,8 +1,3 @@
-set( LLVM_LINK_COMPONENTS
- support
- mc
- )
-
add_clang_executable(c-index-test
c-index-test.c
)
@@ -10,7 +5,7 @@
if(NOT MSVC)
set_property(
SOURCE c-index-test.c
- PROPERTY COMPILE_FLAGS "-std=c89"
+ PROPERTY COMPILE_FLAGS "-std=gnu89"
)
endif()
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 90a6528..f6b5510 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -2,6 +2,7 @@
#include "clang-c/Index.h"
#include "clang-c/CXCompilationDatabase.h"
+#include "clang-c/BuildSystem.h"
#include "llvm/Config/config.h"
#include <ctype.h>
#include <stdlib.h>
@@ -78,8 +79,33 @@
return options;
}
+/** \brief Returns 0 in case of success, non-zero in case of a failure. */
static int checkForErrors(CXTranslationUnit TU);
+static void describeLibclangFailure(enum CXErrorCode Err) {
+ switch (Err) {
+ case CXError_Success:
+ fprintf(stderr, "Success\n");
+ return;
+
+ case CXError_Failure:
+ fprintf(stderr, "Failure (no details available)\n");
+ return;
+
+ case CXError_Crashed:
+ fprintf(stderr, "Failure: libclang crashed\n");
+ return;
+
+ case CXError_InvalidArguments:
+ fprintf(stderr, "Failure: invalid arguments passed to a libclang routine\n");
+ return;
+
+ case CXError_ASTReadError:
+ fprintf(stderr, "Failure: AST deserialization error occurred\n");
+ return;
+ }
+}
+
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,
@@ -88,10 +114,11 @@
static unsigned CreateTranslationUnit(CXIndex Idx, const char *file,
CXTranslationUnit *TU) {
-
- *TU = clang_createTranslationUnit(Idx, file);
- if (!*TU) {
+ enum CXErrorCode Err = clang_createTranslationUnit2(Idx, file, TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to load translation unit from '%s'!\n", file);
+ describeLibclangFailure(Err);
+ *TU = 0;
return 0;
}
return 1;
@@ -107,20 +134,25 @@
free(unsaved_files);
}
-int parse_remapped_files(int argc, const char **argv, int start_arg,
- struct CXUnsavedFile **unsaved_files,
- int *num_unsaved_files) {
+static int parse_remapped_files_with_opt(const char *opt_name,
+ 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=");
+ int prefix_len = strlen(opt_name);
+ int arg_indices[20];
*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;
+ if (strncmp(argv[arg], opt_name, prefix_len))
+ continue;
+ assert(*num_unsaved_files < (int)(sizeof(arg_indices)/sizeof(int)));
+ arg_indices[*num_unsaved_files] = arg;
++*num_unsaved_files;
}
@@ -130,17 +162,17 @@
*unsaved_files
= (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *
*num_unsaved_files);
- for (arg = start_arg, i = 0; i != *num_unsaved_files; ++i, ++arg) {
+ for (i = 0; i != *num_unsaved_files; ++i) {
struct CXUnsavedFile *unsaved = *unsaved_files + i;
- const char *arg_string = argv[arg] + prefix_len;
+ const char *arg_string = argv[arg_indices[i]] + prefix_len;
int filename_len;
char *filename;
char *contents;
FILE *to_file;
- const char *semi = strchr(arg_string, ';');
- if (!semi) {
+ const char *sep = strchr(arg_string, ',');
+ if (!sep) {
fprintf(stderr,
- "error: -remap-file=from;to argument is missing semicolon\n");
+ "error: %sfrom:to argument is missing comma\n", opt_name);
free_remapped_files(*unsaved_files, i);
*unsaved_files = 0;
*num_unsaved_files = 0;
@@ -148,10 +180,10 @@
}
/* Open the file that we're remapping to. */
- to_file = fopen(semi + 1, "rb");
+ to_file = fopen(sep + 1, "rb");
if (!to_file) {
fprintf(stderr, "error: cannot open file %s that we are remapping to\n",
- semi + 1);
+ sep + 1);
free_remapped_files(*unsaved_files, i);
*unsaved_files = 0;
*num_unsaved_files = 0;
@@ -167,7 +199,7 @@
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);
+ (feof(to_file) ? "EOF" : "error"), sep + 1);
fclose(to_file);
free_remapped_files(*unsaved_files, i);
free(contents);
@@ -182,7 +214,7 @@
fclose(to_file);
/* Copy the file name that we're remapping from. */
- filename_len = semi - arg_string;
+ filename_len = sep - arg_string;
filename = (char *)malloc(filename_len + 1);
memcpy(filename, arg_string, filename_len);
filename[filename_len] = 0;
@@ -192,6 +224,48 @@
return 0;
}
+static int parse_remapped_files(int argc, const char **argv, int start_arg,
+ struct CXUnsavedFile **unsaved_files,
+ int *num_unsaved_files) {
+ return parse_remapped_files_with_opt("-remap-file=", argc, argv, start_arg,
+ unsaved_files, num_unsaved_files);
+}
+
+static int parse_remapped_files_with_try(int try_idx,
+ int argc, const char **argv,
+ int start_arg,
+ struct CXUnsavedFile **unsaved_files,
+ int *num_unsaved_files) {
+ struct CXUnsavedFile *unsaved_files_no_try_idx;
+ int num_unsaved_files_no_try_idx;
+ struct CXUnsavedFile *unsaved_files_try_idx;
+ int num_unsaved_files_try_idx;
+ int ret;
+ char opt_name[32];
+
+ ret = parse_remapped_files(argc, argv, start_arg,
+ &unsaved_files_no_try_idx, &num_unsaved_files_no_try_idx);
+ if (ret)
+ return ret;
+
+ sprintf(opt_name, "-remap-file-%d=", try_idx);
+ ret = parse_remapped_files_with_opt(opt_name, argc, argv, start_arg,
+ &unsaved_files_try_idx, &num_unsaved_files_try_idx);
+ if (ret)
+ return ret;
+
+ *num_unsaved_files = num_unsaved_files_no_try_idx + num_unsaved_files_try_idx;
+ *unsaved_files
+ = (struct CXUnsavedFile *)realloc(unsaved_files_no_try_idx,
+ sizeof(struct CXUnsavedFile) *
+ *num_unsaved_files);
+ memcpy(*unsaved_files + num_unsaved_files_no_try_idx,
+ unsaved_files_try_idx, sizeof(struct CXUnsavedFile) *
+ num_unsaved_files_try_idx);
+ free(unsaved_files_try_idx);
+ return 0;
+}
+
static const char *parse_comments_schema(int argc, const char **argv) {
const char *CommentsSchemaArg = "-comments-xml-schema=";
const char *CommentSchemaFile = NULL;
@@ -1189,11 +1263,11 @@
}
/* Print the argument types if they exist. */
{
- int numArgs = clang_Cursor_getNumArguments(cursor);
- if (numArgs != -1 && numArgs != 0) {
+ int NumArgs = clang_Cursor_getNumArguments(cursor);
+ if (NumArgs != -1 && NumArgs != 0) {
int i;
printf(" [args=");
- for (i = 0; i < numArgs; ++i) {
+ for (i = 0; i < NumArgs; ++i) {
CXType T = clang_getCursorType(clang_Cursor_getArgument(cursor, i));
if (T.kind != CXType_Invalid) {
PrintTypeAndTypeKind(T, " [%s] [%s]");
@@ -1202,6 +1276,21 @@
printf("]");
}
}
+ /* Print the template argument types if they exist. */
+ {
+ int NumTArgs = clang_Type_getNumTemplateArguments(T);
+ if (NumTArgs != -1 && NumTArgs != 0) {
+ int i;
+ printf(" [templateargs/%d=", NumTArgs);
+ for (i = 0; i < NumTArgs; ++i) {
+ CXType TArg = clang_Type_getTemplateArgumentAsType(T, i);
+ if (TArg.kind != CXType_Invalid) {
+ PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]");
+ }
+ }
+ printf("]");
+ }
+ }
/* Print if this is a non-POD type. */
printf(" [isPOD=%d]", clang_isPODType(T));
@@ -1240,7 +1329,7 @@
CXCursor Parent, Root;
if (clang_getCursorKind(cursor) == CXCursor_FieldDecl ) {
const char *RootParentName;
- Root = Parent = p;
+ Parent = p;
do {
Root = Parent;
RootParentName = clang_getCString(clang_getCursorSpelling(Root));
@@ -1372,8 +1461,9 @@
const char *CommentSchemaFile;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ enum CXErrorCode Err;
int result;
-
+
Idx = clang_createIndex(/* excludeDeclsFromPCH */
(!strcmp(filter, "local") ||
!strcmp(filter, "local-display"))? 1 : 0,
@@ -1389,13 +1479,14 @@
return -1;
}
- TU = clang_parseTranslationUnit(Idx, 0,
- argv + num_unsaved_files,
- argc - num_unsaved_files,
- unsaved_files, num_unsaved_files,
- getDefaultParsingOptions());
- if (!TU) {
+ Err = clang_parseTranslationUnit2(Idx, 0,
+ argv + num_unsaved_files,
+ argc - num_unsaved_files,
+ unsaved_files, num_unsaved_files,
+ getDefaultParsingOptions(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to load translation unit!\n");
+ describeLibclangFailure(Err);
free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
return 1;
@@ -1415,7 +1506,9 @@
CXTranslationUnit TU;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
- int result;
+ int compiler_arg_idx = 0;
+ enum CXErrorCode Err;
+ int result, i;
int trial;
int remap_after_trial = 0;
char *endptr = 0;
@@ -1428,15 +1521,25 @@
clang_disposeIndex(Idx);
return -1;
}
+
+ for (i = 0; i < argc; ++i) {
+ if (strcmp(argv[i], "--") == 0)
+ break;
+ }
+ if (i < argc)
+ compiler_arg_idx = i+1;
+ if (num_unsaved_files > compiler_arg_idx)
+ compiler_arg_idx = num_unsaved_files;
/* 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) {
+ Err = clang_parseTranslationUnit2(Idx, 0,
+ argv + compiler_arg_idx,
+ argc - compiler_arg_idx,
+ 0, 0, getDefaultParsingOptions(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to load translation unit!\n");
+ describeLibclangFailure(Err);
free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
return 1;
@@ -1451,11 +1554,22 @@
}
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))) {
+ free_remapped_files(unsaved_files, num_unsaved_files);
+ if (parse_remapped_files_with_try(trial, argc, argv, 0,
+ &unsaved_files, &num_unsaved_files)) {
+ clang_disposeTranslationUnit(TU);
+ clang_disposeIndex(Idx);
+ return -1;
+ }
+
+ Err = clang_reparseTranslationUnit(
+ TU,
+ trial >= remap_after_trial ? num_unsaved_files : 0,
+ trial >= remap_after_trial ? unsaved_files : 0,
+ clang_defaultReparseOptions(TU));
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to reparse translation unit!\n");
+ describeLibclangFailure(Err);
clang_disposeTranslationUnit(TU);
free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
@@ -1877,7 +1991,8 @@
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
CXCodeCompleteResults *results = 0;
- CXTranslationUnit TU = 0;
+ enum CXErrorCode Err;
+ CXTranslationUnit TU;
unsigned I, Repeats = 1;
unsigned completionOptions = clang_defaultCodeCompleteOptions();
@@ -1902,21 +2017,27 @@
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) {
+
+ Err = clang_parseTranslationUnit2(CIdx, 0,
+ argv + num_unsaved_files + 2,
+ argc - num_unsaved_files - 2,
+ 0, 0, getDefaultParsingOptions(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to load translation unit!\n");
+ describeLibclangFailure(Err);
return 1;
}
- if (clang_reparseTranslationUnit(TU, 0, 0, clang_defaultReparseOptions(TU))) {
+ Err = clang_reparseTranslationUnit(TU, 0, 0,
+ clang_defaultReparseOptions(TU));
+
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to reparse translation init!\n");
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
return 1;
}
-
+
for (I = 0; I != Repeats; ++I) {
results = clang_codeCompleteAt(TU, filename, line, column,
unsaved_files, num_unsaved_files,
@@ -2003,6 +2124,7 @@
int errorCode;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ enum CXErrorCode Err;
CXTranslationUnit TU;
CXCursor Cursor;
CursorSourceLocation *Locations = 0;
@@ -2036,15 +2158,15 @@
/* 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) {
+ Err = clang_parseTranslationUnit2(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(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "unable to parse input\n");
+ describeLibclangFailure(Err);
return -1;
}
@@ -2052,11 +2174,14 @@
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 (Repeats > 1) {
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(TU));
+ if (Err != CXError_Success) {
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
+ return 1;
+ }
}
if (checkForErrors(TU) != 0)
@@ -2169,6 +2294,7 @@
int errorCode;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ enum CXErrorCode Err;
CXTranslationUnit TU;
CXCursor Cursor;
CursorSourceLocation *Locations = 0;
@@ -2202,15 +2328,16 @@
/* 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) {
+ Err = clang_parseTranslationUnit2(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(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "unable to parse input\n");
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
return -1;
}
@@ -2218,11 +2345,14 @@
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 (Repeats > 1) {
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(TU));
+ if (Err != CXError_Success) {
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
+ return 1;
+ }
}
if (checkForErrors(TU) != 0)
@@ -2273,6 +2403,7 @@
CXIndex CIdx;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ enum CXErrorCode Err;
CXTranslationUnit TU;
const char **Filenames = 0;
unsigned NumFilenames = 0;
@@ -2302,15 +2433,17 @@
/* 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 + NumFilenames,
- argc - num_unsaved_files - 2 - NumFilenames,
- unsaved_files,
- Repeats > 1? 0 : num_unsaved_files,
- getDefaultParsingOptions());
+ Err = clang_parseTranslationUnit2(
+ CIdx, argv[argc - 1],
+ argv + num_unsaved_files + 1 + NumFilenames,
+ argc - num_unsaved_files - 2 - NumFilenames,
+ unsaved_files,
+ Repeats > 1 ? 0 : num_unsaved_files, getDefaultParsingOptions(), &TU);
- if (!TU) {
+ if (Err != CXError_Success) {
fprintf(stderr, "unable to parse input\n");
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
return -1;
}
@@ -2318,11 +2451,14 @@
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 (Repeats > 1) {
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(TU));
+ if (Err != CXError_Success) {
+ describeLibclangFailure(Err);
+ clang_disposeTranslationUnit(TU);
+ return 1;
+ }
}
if (checkForErrors(TU) != 0)
@@ -2867,6 +3003,9 @@
&IndexCB,sizeof(IndexCB), index_opts,
0, args, num_args, 0, 0, 0,
getDefaultParsingOptions());
+ if (result != CXError_Success)
+ describeLibclangFailure(result);
+
if (index_data.fail_for_error)
result = -1;
@@ -3118,6 +3257,8 @@
CXSourceLocation startLoc, endLoc;
CXFile file = 0;
CXCursor *cursors = 0;
+ CXSourceRangeList *skipped_ranges = 0;
+ enum CXErrorCode Err;
unsigned i;
input += strlen("-test-annotate-tokens=");
@@ -3131,14 +3272,15 @@
}
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) {
+ Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],
+ argv + num_unsaved_files + 2,
+ argc - num_unsaved_files - 3,
+ unsaved_files,
+ num_unsaved_files,
+ getDefaultParsingOptions(), &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "unable to parse input\n");
+ describeLibclangFailure(Err);
clang_disposeIndex(CIdx);
free(filename);
free_remapped_files(unsaved_files, num_unsaved_files);
@@ -3153,9 +3295,11 @@
if (getenv("CINDEXTEST_EDITING")) {
for (i = 0; i < 5; ++i) {
- if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
- clang_defaultReparseOptions(TU))) {
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(TU));
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to reparse translation unit!\n");
+ describeLibclangFailure(Err);
errorCode = -1;
goto teardown;
}
@@ -3206,6 +3350,19 @@
goto teardown;
}
+ skipped_ranges = clang_getSkippedRanges(TU, file);
+ for (i = 0; i != skipped_ranges->count; ++i) {
+ unsigned start_line, start_column, end_line, end_column;
+ clang_getSpellingLocation(clang_getRangeStart(skipped_ranges->ranges[i]),
+ 0, &start_line, &start_column, 0);
+ clang_getSpellingLocation(clang_getRangeEnd(skipped_ranges->ranges[i]),
+ 0, &end_line, &end_column, 0);
+ printf("Skipping: ");
+ PrintExtent(stdout, start_line, start_column, end_line, end_column);
+ printf("\n");
+ }
+ clang_disposeSourceRangeList(skipped_ranges);
+
for (i = 0; i != num_tokens; ++i) {
const char *kind = "<unknown>";
CXString spelling = clang_getTokenSpelling(TU, tokens[i]);
@@ -3506,6 +3663,7 @@
CXTranslationUnit TU;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ enum CXErrorCode Err;
int result = 0;
Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnostics=*/1);
@@ -3514,18 +3672,19 @@
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 |
- CXTranslationUnit_DetailedPreprocessingRecord|
- CXTranslationUnit_ForSerialization);
- if (!TU) {
+
+ Err = clang_parseTranslationUnit2(
+ Idx, 0, argv + num_unsaved_files, argc - num_unsaved_files,
+ unsaved_files, num_unsaved_files,
+ CXTranslationUnit_Incomplete |
+ CXTranslationUnit_DetailedPreprocessingRecord |
+ CXTranslationUnit_ForSerialization,
+ &TU);
+ if (Err != CXError_Success) {
fprintf(stderr, "Unable to load translation unit!\n");
+ describeLibclangFailure(Err);
free_remapped_files(unsaved_files, num_unsaved_files);
+ clang_disposeTranslationUnit(TU);
clang_disposeIndex(Idx);
return 1;
}
@@ -3577,6 +3736,7 @@
static const char *getSeverityString(enum CXDiagnosticSeverity severity) {
switch (severity) {
case CXDiagnostic_Note: return "note";
+ case CXDiagnostic_Remark: return "remark";
case CXDiagnostic_Error: return "error";
case CXDiagnostic_Fatal: return "fatal";
case CXDiagnostic_Ignored: return "ignored";
@@ -3721,6 +3881,11 @@
return 0;
}
+static int perform_print_build_session_timestamp(void) {
+ printf("%lld\n", clang_getBuildSessionTimestamp());
+ return 0;
+}
+
/******************************************************************************/
/* Command line processing. */
/******************************************************************************/
@@ -3777,6 +3942,8 @@
fprintf(stderr,
" c-index-test -compilation-db [lookup <filename>] database\n");
fprintf(stderr,
+ " c-index-test -print-build-session-timestamp\n");
+ fprintf(stderr,
" c-index-test -read-diagnostics <file>\n\n");
fprintf(stderr,
" <symbol filter> values:\n%s",
@@ -3876,6 +4043,8 @@
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);
+ else if (argc == 2 && strcmp(argv[1], "-print-build-session-timestamp") == 0)
+ return perform_print_build_session_timestamp();
print_usage();
return 1;
diff --git a/tools/clang-check/CMakeLists.txt b/tools/clang-check/CMakeLists.txt
index 2070de3..8b9cd88 100644
--- a/tools/clang-check/CMakeLists.txt
+++ b/tools/clang-check/CMakeLists.txt
@@ -1,9 +1,6 @@
set(LLVM_LINK_COMPONENTS
- ${LLVM_TARGETS_TO_BUILD}
- asmparser
- bitreader
- support
- mc
+ Option
+ Support
)
add_clang_executable(clang-check
@@ -11,10 +8,13 @@
)
target_link_libraries(clang-check
- clangTooling
+ clangAST
clangBasic
+ clangDriver
+ clangFrontend
clangRewriteFrontend
clangStaticAnalyzerFrontend
+ clangTooling
)
install(TARGETS clang-check
diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp
index 701db52..4fc970c 100644
--- a/tools/clang-check/ClangCheck.cpp
+++ b/tools/clang-check/ClangCheck.cpp
@@ -20,20 +20,18 @@
#include "clang/Driver/Options.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/CompilerInstance.h"
-#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "clang/Rewrite/Frontend/FixItRewriter.h"
#include "clang/Rewrite/Frontend/FrontendActions.h"
+#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Option/OptTable.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
-#include "llvm/Option/OptTable.h"
using namespace clang::driver;
using namespace clang::tooling;
using namespace llvm;
-using namespace llvm::opt;
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::extrahelp MoreHelp(
@@ -51,34 +49,42 @@
"\n"
);
-static OwningPtr<OptTable> Options(createDriverOptTable());
-static cl::opt<bool> ASTDump(
- "ast-dump",
- cl::desc(Options->getOptionHelpText(options::OPT_ast_dump)));
-static cl::opt<bool> ASTList(
- "ast-list",
- cl::desc(Options->getOptionHelpText(options::OPT_ast_list)));
-static cl::opt<bool> ASTPrint(
- "ast-print",
- cl::desc(Options->getOptionHelpText(options::OPT_ast_print)));
+static cl::OptionCategory ClangCheckCategory("clang-check options");
+static std::unique_ptr<opt::OptTable> Options(createDriverOptTable());
+static cl::opt<bool>
+ASTDump("ast-dump", cl::desc(Options->getOptionHelpText(options::OPT_ast_dump)),
+ cl::cat(ClangCheckCategory));
+static cl::opt<bool>
+ASTList("ast-list", cl::desc(Options->getOptionHelpText(options::OPT_ast_list)),
+ cl::cat(ClangCheckCategory));
+static cl::opt<bool>
+ASTPrint("ast-print",
+ cl::desc(Options->getOptionHelpText(options::OPT_ast_print)),
+ cl::cat(ClangCheckCategory));
static cl::opt<std::string> ASTDumpFilter(
"ast-dump-filter",
- cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)));
-static cl::opt<bool> Analyze(
- "analyze",
- cl::desc(Options->getOptionHelpText(options::OPT_analyze)));
+ cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)),
+ cl::cat(ClangCheckCategory));
+static cl::opt<bool>
+Analyze("analyze", cl::desc(Options->getOptionHelpText(options::OPT_analyze)),
+ cl::cat(ClangCheckCategory));
-static cl::opt<bool> Fixit(
- "fixit",
- cl::desc(Options->getOptionHelpText(options::OPT_fixit)));
+static cl::opt<bool>
+Fixit("fixit", cl::desc(Options->getOptionHelpText(options::OPT_fixit)),
+ cl::cat(ClangCheckCategory));
static cl::opt<bool> FixWhatYouCan(
"fix-what-you-can",
- cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)));
+ cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)),
+ cl::cat(ClangCheckCategory));
-static cl::list<std::string> ArgsAfter("extra-arg",
- cl::desc("Additional argument to append to the compiler command line"));
-static cl::list<std::string> ArgsBefore("extra-arg-before",
- cl::desc("Additional argument to prepend to the compiler command line"));
+static cl::list<std::string> ArgsAfter(
+ "extra-arg",
+ cl::desc("Additional argument to append to the compiler command line"),
+ cl::cat(ClangCheckCategory));
+static cl::list<std::string> ArgsBefore(
+ "extra-arg-before",
+ cl::desc("Additional argument to prepend to the compiler command line"),
+ cl::cat(ClangCheckCategory));
namespace {
@@ -90,7 +96,7 @@
FixWhatYouCan = ::FixWhatYouCan;
}
- std::string RewriteFilename(const std::string& filename, int &fd) {
+ std::string RewriteFilename(const std::string& filename, int &fd) override {
assert(llvm::sys::path::is_absolute(filename) &&
"clang-fixit expects absolute paths only.");
@@ -117,15 +123,15 @@
: clang::FixItRewriter(Diags, SourceMgr, LangOpts, FixItOpts) {
}
- virtual bool IncludeInDiagnosticCounts() const { return false; }
+ bool IncludeInDiagnosticCounts() const override { return false; }
};
/// \brief Subclasses \c clang::FixItAction so that we can install the custom
/// \c FixItRewriter.
class FixItAction : public clang::FixItAction {
public:
- virtual bool BeginSourceFileAction(clang::CompilerInstance& CI,
- StringRef Filename) {
+ bool BeginSourceFileAction(clang::CompilerInstance& CI,
+ StringRef Filename) override {
FixItOpts.reset(new FixItOptions);
Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
CI.getLangOpts(), FixItOpts.get()));
@@ -146,7 +152,7 @@
}
virtual CommandLineArguments
- Adjust(const CommandLineArguments &Args) LLVM_OVERRIDE {
+ Adjust(const CommandLineArguments &Args) override {
CommandLineArguments Return(Args);
CommandLineArguments::iterator I;
@@ -187,7 +193,7 @@
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
- CommonOptionsParser OptionsParser(argc, argv);
+ CommonOptionsParser OptionsParser(argc, argv, ClangCheckCategory);
ClangTool Tool(OptionsParser.getCompilations(),
OptionsParser.getSourcePathList());
diff --git a/tools/clang-format-vs/CMakeLists.txt b/tools/clang-format-vs/CMakeLists.txt
new file mode 100644
index 0000000..f883a98
--- /dev/null
+++ b/tools/clang-format-vs/CMakeLists.txt
@@ -0,0 +1,16 @@
+option(BUILD_CLANG_FORMAT_VS_PLUGIN "Build clang-format VS plugin" OFF)
+if (BUILD_CLANG_FORMAT_VS_PLUGIN)
+ add_custom_target(clang_format_exe_for_vsix
+ ${CMAKE_COMMAND} -E copy_if_different
+ "${LLVM_TOOLS_BINARY_DIR}/${CMAKE_CFG_INTDIR}/clang-format.exe"
+ "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/clang-format.exe"
+ DEPENDS clang-format)
+
+ add_custom_target(clang_format_vsix ALL
+ devenv "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat.sln" /Build Release
+ DEPENDS clang_format_exe_for_vsix
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/bin/Release/ClangFormat.vsix"
+ "${LLVM_TOOLS_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ClangFormat.vsix"
+ DEPENDS clang_format_exe_for_vsix)
+endif()
diff --git a/tools/clang-format-vs/ClangFormat/ClangFormat.csproj b/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
index 65ccaba..2f49221 100644
--- a/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
+++ b/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
@@ -178,6 +178,9 @@
<None Include="Resources\Images_32bit.bmp" />
</ItemGroup>
<ItemGroup>
+ <Content Include="clang-format.exe">
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
<Content Include="Resources\Package.ico" />
</ItemGroup>
<ItemGroup>
diff --git a/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs b/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
index 797d467..c3aa8fe 100644
--- a/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
+++ b/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
@@ -22,6 +22,7 @@
using System.ComponentModel;
using System.ComponentModel.Design;
using System.IO;
+using System.Reflection;
using System.Runtime.InteropServices;
using System.Xml.Linq;
@@ -128,9 +129,12 @@
/// </summary>
private string RunClangFormat(string text, int offset, int length, string path)
{
+ string vsixPath = Path.GetDirectoryName(
+ typeof(ClangFormatPackage).Assembly.Location);
+
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.UseShellExecute = false;
- process.StartInfo.FileName = "clang-format.exe";
+ process.StartInfo.FileName = vsixPath + "\\clang-format.exe";
// Poor man's escaping - this will not work when quotes are already escaped
// in the input (but we don't need more).
string style = GetStyle().Replace("\"", "\\\"");
diff --git a/tools/clang-format-vs/README.txt b/tools/clang-format-vs/README.txt
index 6d4ebb3..b87df6e 100644
--- a/tools/clang-format-vs/README.txt
+++ b/tools/clang-format-vs/README.txt
@@ -3,4 +3,11 @@
Build prerequisites are:
- Visual Studio 2012 Professional
-- Visual Studio SDK (http://www.microsoft.com/en-us/download/details.aspx?id=30668)
+- Visual Studio 2010 Professional
+- Visual Studio 2010 SDK.
+
+clang-format.exe must be copied into the ClangFormat/ directory before building.
+It will be bundled into the .vsix file.
+
+The extension can be built manually from ClangFormat.sln (e.g. by opening it in
+Visual Studio), or with cmake by setting the BUILD_CLANG_FORMAT_VS_PLUGIN flag.
diff --git a/tools/clang-format/CMakeLists.txt b/tools/clang-format/CMakeLists.txt
index 7bb3fbf..b029f71 100644
--- a/tools/clang-format/CMakeLists.txt
+++ b/tools/clang-format/CMakeLists.txt
@@ -1,15 +1,15 @@
set(LLVM_LINK_COMPONENTS support)
-set(LLVM_USED_LIBS clangFormat clangTooling clangBasic clangAST)
add_clang_executable(clang-format
ClangFormat.cpp
)
target_link_libraries(clang-format
- clangFormat
- clangTooling
clangBasic
- clangRewriteFrontend
+ clangFormat
+ clangLex
+ clangRewriteCore
+ clangTooling
)
install(TARGETS clang-format RUNTIME DESTINATION bin)
diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
index 768165b..6f94461 100644
--- a/tools/clang-format/ClangFormat.cpp
+++ b/tools/clang-format/ClangFormat.cpp
@@ -17,13 +17,14 @@
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Version.h"
#include "clang/Format/Format.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Signals.h"
-#include "llvm/ADT/StringMap.h"
using namespace llvm;
@@ -31,7 +32,7 @@
// Mark all our options with this category, everything else (except for -version
// and -help) will be hidden.
-cl::OptionCategory ClangFormatCategory("Clang-format options");
+static cl::OptionCategory ClangFormatCategory("Clang-format options");
static cl::list<unsigned>
Offsets("offset",
@@ -62,6 +63,13 @@
Style("style",
cl::desc(clang::format::StyleOptionHelpDescription),
cl::init("file"), cl::cat(ClangFormatCategory));
+static cl::opt<std::string>
+FallbackStyle("fallback-style",
+ cl::desc("The name of the predefined style used as a\n"
+ "fallback in case clang-format is invoked with\n"
+ "-style=file, but can not find the .clang-format\n"
+ "file to use."),
+ cl::init("LLVM"), cl::cat(ClangFormatCategory));
static cl::opt<std::string>
AssumeFilename("assume-filename",
@@ -173,6 +181,26 @@
return false;
}
+static void outputReplacementXML(StringRef Text) {
+ size_t From = 0;
+ size_t Index;
+ while ((Index = Text.find_first_of("\n\r", From)) != StringRef::npos) {
+ llvm::outs() << Text.substr(From, Index - From);
+ switch (Text[Index]) {
+ case '\n':
+ llvm::outs() << " ";
+ break;
+ case '\r':
+ llvm::outs() << " ";
+ break;
+ default:
+ llvm_unreachable("Unexpected character encountered!");
+ }
+ From = Index + 1;
+ }
+ llvm::outs() << Text.substr(From);
+}
+
// Returns true on error.
static bool format(StringRef FileName) {
FileManager Files((FileSystemOptions()));
@@ -180,7 +208,7 @@
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
new DiagnosticOptions);
SourceManager Sources(Diagnostics, Files);
- OwningPtr<MemoryBuffer> Code;
+ std::unique_ptr<MemoryBuffer> Code;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
llvm::errs() << ec.message() << "\n";
return true;
@@ -192,8 +220,8 @@
if (fillRanges(Sources, ID, Code.get(), Ranges))
return true;
- FormatStyle FormatStyle =
- getStyle(Style, (FileName == "-") ? AssumeFilename : FileName);
+ FormatStyle FormatStyle = getStyle(
+ Style, (FileName == "-") ? AssumeFilename : FileName, FallbackStyle);
Lexer Lex(ID, Sources.getBuffer(ID), Sources,
getFormattingLangOpts(FormatStyle.Standard));
tooling::Replacements Replaces = reformat(FormatStyle, Lex, Sources, Ranges);
@@ -205,8 +233,9 @@
I != E; ++I) {
llvm::outs() << "<replacement "
<< "offset='" << I->getOffset() << "' "
- << "length='" << I->getLength() << "'>"
- << I->getReplacementText() << "</replacement>\n";
+ << "length='" << I->getLength() << "'>";
+ outputReplacementXML(I->getReplacementText());
+ llvm::outs() << "</replacement>\n";
}
llvm::outs() << "</replacements>\n";
} else {
@@ -228,6 +257,11 @@
} // namespace format
} // namespace clang
+static void PrintVersion() {
+ raw_ostream &OS = outs();
+ OS << clang::getClangToolFullVersion("clang-format") << '\n';
+}
+
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
@@ -241,6 +275,7 @@
I->second->setHiddenFlag(cl::ReallyHidden);
}
+ cl::SetVersionPrinter(PrintVersion);
cl::ParseCommandLineOptions(
argc, argv,
"A tool to format C/C++/Obj-C code.\n\n"
@@ -256,7 +291,8 @@
if (DumpConfig) {
std::string Config =
clang::format::configurationAsText(clang::format::getStyle(
- Style, FileNames.empty() ? AssumeFilename : FileNames[0]));
+ Style, FileNames.empty() ? AssumeFilename : FileNames[0],
+ FallbackStyle));
llvm::outs() << Config << "\n";
return 0;
}
diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py
index 60b8fb7..376257b 100755
--- a/tools/clang-format/clang-format-diff.py
+++ b/tools/clang-format/clang-format-diff.py
@@ -37,12 +37,20 @@
def main():
parser = argparse.ArgumentParser(description=
'Reformat changed lines in diff. Without -i '
- 'option just output the diff that would be'
+ 'option just output the diff that would be '
'introduced.')
parser.add_argument('-i', action='store_true', default=False,
help='apply edits to files instead of displaying a diff')
- parser.add_argument('-p', default=0,
+ parser.add_argument('-p', metavar='NUM', default=0,
help='strip the smallest prefix containing P slashes')
+ parser.add_argument('-regex', metavar='PATTERN', default=None,
+ help='custom pattern selecting file paths to reformat '
+ '(case sensitive, overrides -iregex)')
+ parser.add_argument('-iregex', metavar='PATTERN', default=
+ r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc|js|proto'
+ r'|protodevel)',
+ help='custom pattern selecting file paths to reformat '
+ '(case insensitive, overridden by -regex)')
parser.add_argument(
'-style',
help=
@@ -59,10 +67,12 @@
if filename == None:
continue
- # FIXME: Add other types containing C++/ObjC code.
- if not (filename.endswith(".cpp") or filename.endswith(".cc") or
- filename.endswith(".h")):
- continue
+ if args.regex is not None:
+ if not re.match('^%s$' % args.regex, filename):
+ continue
+ else:
+ if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
+ continue
match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
if match:
@@ -85,11 +95,8 @@
if args.style:
command.extend(['-style', args.style])
p = subprocess.Popen(command, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- stdin=subprocess.PIPE)
+ stderr=None, stdin=subprocess.PIPE)
stdout, stderr = p.communicate()
- if stderr:
- print stderr
if p.returncode != 0:
sys.exit(p.returncode);
@@ -102,7 +109,7 @@
'(before formatting)', '(after formatting)')
diff_string = string.join(diff, '')
if len(diff_string) > 0:
- print diff_string
+ sys.stdout.write(diff_string)
if __name__ == '__main__':
main()
diff --git a/tools/clang-format/clang-format.py b/tools/clang-format/clang-format.py
index f5a5756..0c0da6e 100644
--- a/tools/clang-format/clang-format.py
+++ b/tools/clang-format/clang-format.py
@@ -32,48 +32,51 @@
# used.
style = 'file'
-# Get the current text.
-buf = vim.current.buffer
-text = '\n'.join(buf)
+def main():
+ # Get the current text.
+ buf = vim.current.buffer
+ text = '\n'.join(buf)
-# Determine range to format.
-cursor = int(vim.eval('line2byte(line("."))+col(".")')) - 2
-lines = '%s:%s' % (vim.current.range.start + 1, vim.current.range.end + 1)
+ # Determine range to format.
+ cursor = int(vim.eval('line2byte(line("."))+col(".")')) - 2
+ lines = '%s:%s' % (vim.current.range.start + 1, vim.current.range.end + 1)
-# Avoid flashing an ugly, ugly cmd prompt on Windows when invoking clang-format.
-startupinfo = None
-if sys.platform.startswith('win32'):
- startupinfo = subprocess.STARTUPINFO()
- startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
- startupinfo.wShowWindow = subprocess.SW_HIDE
+ # Avoid flashing an ugly, ugly cmd prompt on Windows when invoking clang-format.
+ startupinfo = None
+ if sys.platform.startswith('win32'):
+ startupinfo = subprocess.STARTUPINFO()
+ startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
+ startupinfo.wShowWindow = subprocess.SW_HIDE
-# Call formatter.
-command = [binary, '-lines', lines, '-style', style, '-cursor', str(cursor)]
-if vim.current.buffer.name:
- command.extend(['-assume-filename', vim.current.buffer.name])
-p = subprocess.Popen(command,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- stdin=subprocess.PIPE, startupinfo=startupinfo)
-stdout, stderr = p.communicate(input=text)
+ # Call formatter.
+ command = [binary, '-lines', lines, '-style', style, '-cursor', str(cursor)]
+ if vim.current.buffer.name:
+ command.extend(['-assume-filename', vim.current.buffer.name])
+ p = subprocess.Popen(command,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ stdin=subprocess.PIPE, startupinfo=startupinfo)
+ stdout, stderr = p.communicate(input=text)
-# If successful, replace buffer contents.
-if stderr:
- message = stderr.splitlines()[0]
- parts = message.split(' ', 2)
- if len(parts) > 2:
- message = parts[2]
- print 'Formatting failed: %s (total %d warnings, %d errors)' % (
- message, stderr.count('warning:'), stderr.count('error:'))
+ # If successful, replace buffer contents.
+ if stderr:
+ message = stderr.splitlines()[0]
+ parts = message.split(' ', 2)
+ if len(parts) > 2:
+ message = parts[2]
+ print 'Formatting failed: %s (total %d warnings, %d errors)' % (
+ message, stderr.count('warning:'), stderr.count('error:'))
-if not stdout:
- print ('No output from clang-format (crashed?).\n' +
- 'Please report to bugs.llvm.org.')
-else:
- lines = stdout.split('\n')
- output = json.loads(lines[0])
- lines = lines[1:]
- sequence = difflib.SequenceMatcher(None, vim.current.buffer, lines)
- for op in reversed(sequence.get_opcodes()):
- if op[0] is not 'equal':
- vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]]
- vim.command('goto %d' % (output['Cursor'] + 1))
+ if not stdout:
+ print ('No output from clang-format (crashed?).\n' +
+ 'Please report to bugs.llvm.org.')
+ else:
+ lines = stdout.split('\n')
+ output = json.loads(lines[0])
+ lines = lines[1:]
+ sequence = difflib.SequenceMatcher(None, vim.current.buffer, lines)
+ for op in reversed(sequence.get_opcodes()):
+ if op[0] is not 'equal':
+ vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]]
+ vim.command('goto %d' % (output['Cursor'] + 1))
+
+main()
diff --git a/tools/diag-build/diag-build.sh b/tools/diag-build/diag-build.sh
index 4fef8fb..018288d 100755
--- a/tools/diag-build/diag-build.sh
+++ b/tools/diag-build/diag-build.sh
@@ -1,5 +1,14 @@
#!/bin/bash
+# diag-build: a tool showing enabled warnings in a project.
+#
+# diag-build acts as a wrapper for 'diagtool show-enabled', in the same way
+# that scan-build acts as a wrapper for the static analyzer. The common case is
+# simple: use 'diag-build make' or 'diag-build xcodebuild' to list the warnings
+# enabled for the first compilation command we see. Other build systems require
+# you to manually specify "dry-run" and "use $CC and $CXX"; if there is a build
+# system you are interested in, please add it to the switch statement.
+
print_usage () {
echo 'Usage: diag-build.sh [-v] xcodebuild [flags]'
echo ' diag-build.sh [-v] make [flags]'
diff --git a/tools/diagtool/CMakeLists.txt b/tools/diagtool/CMakeLists.txt
index 8aa2d21..e88c2ab 100644
--- a/tools/diagtool/CMakeLists.txt
+++ b/tools/diagtool/CMakeLists.txt
@@ -1,9 +1,5 @@
set(LLVM_LINK_COMPONENTS
- ${LLVM_TARGETS_TO_BUILD}
- asmparser
- bitreader
- support
- mc
+ Support
)
add_clang_executable(diagtool
@@ -15,14 +11,8 @@
TreeView.cpp
)
-add_dependencies(diagtool
- ClangDiagnosticIndexName
- )
-
target_link_libraries(diagtool
clangBasic
- clangLex
- clangSema
clangFrontend
)
diff --git a/tools/diagtool/DiagTool.h b/tools/diagtool/DiagTool.h
index 93d531b..b1e69f3 100644
--- a/tools/diagtool/DiagTool.h
+++ b/tools/diagtool/DiagTool.h
@@ -62,7 +62,7 @@
public:\
CLSNAME() : DiagTool(NAME, DESC) {}\
virtual ~CLSNAME() {}\
- virtual int run(unsigned argc, char *argv[], llvm::raw_ostream &out);\
+ int run(unsigned argc, char *argv[], llvm::raw_ostream &out) override;\
};\
diagtool::RegisterDiagTool<CLSNAME> Register##CLSNAME;\
}
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
index bcc7520..ad56b03 100644
--- a/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -44,6 +44,7 @@
switch (Level) {
case DiagnosticsEngine::Ignored: return ' ';
case DiagnosticsEngine::Note: return '-';
+ case DiagnosticsEngine::Remark: return 'R';
case DiagnosticsEngine::Warning: return 'W';
case DiagnosticsEngine::Error: return 'E';
case DiagnosticsEngine::Fatal: return 'F';
@@ -63,9 +64,9 @@
new DiagnosticsEngine(DiagIDs, new DiagnosticOptions(), DiagsBuffer));
// Try to build a CompilerInvocation.
- OwningPtr<CompilerInvocation> Invocation(
- createInvocationFromCommandLine(ArrayRef<const char *>(argv, argc),
- InterimDiags));
+ std::unique_ptr<CompilerInvocation> Invocation(
+ createInvocationFromCommandLine(ArrayRef<const char *>(argv, argc),
+ InterimDiags));
if (!Invocation)
return NULL;
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index c94bc77..f60162f 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -1,16 +1,29 @@
set( LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
- asmparser
- bitreader
- bitwriter
- irreader
- codegen
- instrumentation
- ipo
- linker
- selectiondag
+ Analysis
+ Core
+ IPA
+ IPO
+ InstCombine
+ Instrumentation
+ MC
+ MCParser
+ ObjCARCOpts
+ Option
+ ScalarOpts
+ Support
+ TransformUtils
+ Vectorize
)
+option(CLANG_PLUGIN_SUPPORT "Build clang with plugin support" ON)
+
+# Support plugins. This must be before add_clang_executable as it reads
+# LLVM_NO_DEAD_STRIP.
+if(CLANG_PLUGIN_SUPPORT)
+ set(LLVM_NO_DEAD_STRIP 1)
+endif()
+
add_clang_executable(clang
driver.cpp
cc1_main.cpp
@@ -18,44 +31,18 @@
)
target_link_libraries(clang
- clangFrontendTool
- clangAST
- clangAnalysis
clangBasic
- clangCodeGen
clangDriver
- clangEdit
clangFrontend
- clangLex
- clangParse
- clangEdit
- clangSema
- clangSerialization
+ clangFrontendTool
)
-if(CLANG_ENABLE_STATIC_ANALYZER)
- target_link_libraries(clang
- clangStaticAnalyzerFrontend
- clangStaticAnalyzerCheckers
- clangStaticAnalyzerCore
- )
-endif()
-
-if(CLANG_ENABLE_ARCMT)
- target_link_libraries(clang
- clangARCMigrate
- )
-endif()
-
-if(CLANG_ENABLE_REWRITER)
- target_link_libraries(clang
- clangRewriteCore
- clangRewriteFrontend
- )
-endif()
-
set_target_properties(clang PROPERTIES VERSION ${CLANG_EXECUTABLE_VERSION})
-set_target_properties(clang PROPERTIES ENABLE_EXPORTS 1)
+
+# Support plugins.
+if(CLANG_PLUGIN_SUPPORT)
+ set_target_properties(clang PROPERTIES ENABLE_EXPORTS 1)
+endif()
add_dependencies(clang clang-headers)
@@ -65,21 +52,23 @@
set(clang_binary "clang${CMAKE_EXECUTABLE_SUFFIX}")
else()
set(CLANGXX_LINK_OR_COPY copy)
- set(clang_binary "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}")
+ set(clang_binary "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}")
endif()
# Create the clang++ symlink in the build directory.
-set(clang_pp "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}")
+set(clang_pp "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}")
add_custom_command(TARGET clang POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${clang_binary}" "${clang_pp}")
+ COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${clang_binary}" "${clang_pp}"
+ WORKING_DIRECTORY "${LLVM_RUNTIME_OUTPUT_INTDIR}")
set_property(DIRECTORY APPEND
PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${clang_pp})
# Create the clang-cl symlink in the build directory.
-set(clang_cl "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX}")
+set(clang_cl "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX}")
add_custom_command(TARGET clang POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${clang_binary}" "${clang_cl}")
+ COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${clang_binary}" "${clang_cl}"
+ WORKING_DIRECTORY "${LLVM_RUNTIME_OUTPUT_INTDIR}")
set_property(DIRECTORY APPEND
PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${clang_cl})
@@ -121,3 +110,11 @@
target_link_libraries(clang "-Wl,-order_file,${CLANG_ORDER_FILE}")
endif()
+if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
+ target_link_libraries(clang Polly)
+ if(POLLY_LINK_LIBS)
+ foreach(lib ${POLLY_LINK_LIBS})
+ target_link_libraries(clang ${lib})
+ endforeach(lib)
+ endif(POLLY_LINK_LIBS)
+endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
diff --git a/tools/driver/Makefile b/tools/driver/Makefile
index f7a9f8f..d75b19c 100644
--- a/tools/driver/Makefile
+++ b/tools/driver/Makefile
@@ -11,12 +11,6 @@
TOOLNAME = clang
TOOLALIAS = clang++
-# We don't currently expect production Clang builds to be interested in
-# plugins. This is important for startup performance.
-ifdef CLANG_IS_PRODUCTION
-TOOL_NO_EXPORTS := 1
-endif
-
ifdef CLANG_ORDER_FILE
TOOL_ORDER_FILE := $(CLANG_ORDER_FILE)
endif
@@ -29,8 +23,17 @@
# LINK_COMPONENTS before including Makefile.rules
include $(CLANG_LEVEL)/../../Makefile.config
+# Have the option of not supporting plugins. This is important for startup
+# performance.
+ifeq ($(CLANG_PLUGIN_SUPPORT), 1)
+NO_DEAD_STRIP := 1
+else
+TOOL_NO_EXPORTS := 1
+endif
+
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \
- instrumentation ipo irreader linker selectiondag option
+ instrumentation ipo irreader linker objcarcopts option \
+ selectiondag
USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
clangSerialization.a clangCodeGen.a clangParse.a clangSema.a
@@ -47,7 +50,7 @@
USEDLIBS += clangRewriteFrontend.a clangRewriteCore.a
endif
-USEDLIBS += clangAnalysis.a clangEdit.a clangAST.a clangBasic.a clangLex.a
+USEDLIBS += clangAnalysis.a clangEdit.a clangAST.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index 5b3b5ad..990c4fc 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -21,6 +21,7 @@
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Frontend/Utils.h"
#include "clang/FrontendTool/Utils.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/LinkAllPasses.h"
@@ -56,9 +57,15 @@
exit(GenCrashDiag ? 70 : 1);
}
+#ifdef LINK_POLLY_INTO_TOOLS
+namespace polly {
+void initializePollyPasses(llvm::PassRegistry &Registry);
+}
+#endif
+
int cc1_main(const char **ArgBegin, const char **ArgEnd,
const char *Argv0, void *MainAddr) {
- OwningPtr<CompilerInstance> Clang(new CompilerInstance());
+ std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
// Initialize targets first, so that --version shows registered targets.
@@ -67,6 +74,11 @@
llvm::InitializeAllAsmPrinters();
llvm::InitializeAllAsmParsers();
+#ifdef LINK_POLLY_INTO_TOOLS
+ llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
+ polly::initializePollyPasses(Registry);
+#endif
+
// Buffer diagnostics from argument parsing so that we can output them using a
// well formed diagnostic object.
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
@@ -112,7 +124,7 @@
if (Clang->getFrontendOpts().DisableFree) {
if (llvm::AreStatisticsEnabled() || Clang->getFrontendOpts().ShowStats)
llvm::PrintStatistics();
- Clang.take();
+ BuryPointer(Clang.release());
return !Success;
}
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 31cd236..8521c2a 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -20,7 +20,6 @@
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/DataLayout.h"
@@ -54,6 +53,7 @@
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
+#include <memory>
using namespace clang;
using namespace clang::driver;
using namespace llvm;
@@ -85,6 +85,7 @@
unsigned NoInitialTextSection : 1;
unsigned SaveTemporaryLabels : 1;
unsigned GenDwarfForAssembly : 1;
+ unsigned CompressDebugSections : 1;
std::string DwarfDebugFlags;
std::string DwarfDebugProducer;
std::string DebugCompilationDir;
@@ -151,10 +152,10 @@
bool Success = true;
// Parse the arguments.
- OwningPtr<OptTable> OptTbl(createCC1AsOptTable());
+ std::unique_ptr<OptTable> OptTbl(createCC1AsOptTable());
unsigned MissingArgIndex, MissingArgCount;
- OwningPtr<InputArgList> Args(
- OptTbl->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount));
+ std::unique_ptr<InputArgList> Args(
+ OptTbl->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount));
// Check for missing argument error.
if (MissingArgCount) {
@@ -186,6 +187,7 @@
Opts.NoInitialTextSection = Args->hasArg(OPT_n);
Opts.SaveTemporaryLabels = Args->hasArg(OPT_msave_temp_labels);
Opts.GenDwarfForAssembly = Args->hasArg(OPT_g);
+ Opts.CompressDebugSections = Args->hasArg(OPT_compress_debug_sections);
Opts.DwarfDebugFlags = Args->getLastArgValue(OPT_dwarf_debug_flags);
Opts.DwarfDebugProducer = Args->getLastArgValue(OPT_dwarf_debug_producer);
Opts.DebugCompilationDir = Args->getLastArgValue(OPT_fdebug_compilation_dir);
@@ -251,7 +253,7 @@
std::string Error;
raw_fd_ostream *Out =
new raw_fd_ostream(Opts.OutputPath.c_str(), Error,
- (Binary ? sys::fs::F_Binary : sys::fs::F_None));
+ (Binary ? sys::fs::F_None : sys::fs::F_Text));
if (!Error.empty()) {
Diags.Report(diag::err_fe_unable_to_open_output)
<< Opts.OutputPath << Error;
@@ -271,13 +273,13 @@
return false;
}
- OwningPtr<MemoryBuffer> BufferPtr;
+ std::unique_ptr<MemoryBuffer> BufferPtr;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, BufferPtr)) {
Error = ec.message();
Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
return false;
}
- MemoryBuffer *Buffer = BufferPtr.take();
+ MemoryBuffer *Buffer = BufferPtr.release();
SourceMgr SrcMgr;
@@ -288,12 +290,17 @@
// it later.
SrcMgr.setIncludeDirs(Opts.IncludePaths);
- OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
+ std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
assert(MRI && "Unable to create target register info!");
- OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
+ std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
assert(MAI && "Unable to create target asm info!");
+ // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
+ // may be created with a combination of default and explicit settings.
+ if (Opts.CompressDebugSections)
+ MAI->setCompressDebugSections(true);
+
bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary);
if (!Out)
@@ -301,7 +308,8 @@
// FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
// MCObjectFileInfo needs a MCContext reference in order to initialize itself.
- OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
+ std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
+
MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
// FIXME: Assembler behavior can change with -static.
MOFI->InitMCObjectFileInfo(Opts.Triple,
@@ -327,11 +335,11 @@
FS += "," + Opts.Features[i];
}
- OwningPtr<MCStreamer> Str;
+ std::unique_ptr<MCStreamer> Str;
- OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
- OwningPtr<MCSubtargetInfo>
- STI(TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
+ std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
+ std::unique_ptr<MCSubtargetInfo> STI(
+ TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
@@ -345,7 +353,6 @@
MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU);
}
Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
- /*useLoc*/ true,
/*useCFI*/ true,
/*useDwarfDirectory*/ true,
IP, CE, MAB,
@@ -359,14 +366,15 @@
MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
Opts.CPU);
Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out,
- CE, Opts.RelaxAll,
+ CE, *STI, Opts.RelaxAll,
Opts.NoExecStack));
Str.get()->InitSections();
}
- OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
- *Str.get(), *MAI));
- OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser, *MCII));
+ std::unique_ptr<MCAsmParser> Parser(
+ createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
+ std::unique_ptr<MCTargetAsmParser> TAP(
+ TheTarget->createMCAsmParser(*STI, *Parser, *MCII));
if (!TAP) {
Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
return false;
@@ -428,7 +436,7 @@
// Honor -help.
if (Asm.ShowHelp) {
- OwningPtr<OptTable> Opts(driver::createCC1AsOptTable());
+ std::unique_ptr<OptTable> Opts(driver::createCC1AsOptTable());
Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler");
return 0;
}
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 3a6a09b..beb271f 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -22,10 +22,10 @@
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
@@ -46,6 +46,7 @@
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
+#include <memory>
using namespace clang;
using namespace clang::driver;
using namespace llvm::opt;
@@ -169,7 +170,7 @@
OS = &llvm::nulls();
}
- *OS << "### QA_OVERRIDE_GCC3_OPTIONS: " << OverrideStr << "\n";
+ *OS << "### CCC_OVERRIDE_OPTIONS: " << OverrideStr << "\n";
// This does not need to be efficient.
@@ -227,8 +228,11 @@
{ "++", "--driver-mode=g++" },
};
std::string ProgName(llvm::sys::path::stem(ArgVector[0]));
+#ifdef LLVM_ON_WIN32
+ // Transform to lowercase for case insensitive file systems.
std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
toLowercase);
+#endif
StringRef ProgNameRef(ProgName);
StringRef Prefix;
@@ -281,7 +285,7 @@
class StringSetSaver : public llvm::cl::StringSaver {
public:
StringSetSaver(std::set<std::string> &Storage) : Storage(Storage) {}
- const char *SaveString(const char *Str) LLVM_OVERRIDE {
+ const char *SaveString(const char *Str) override {
return SaveStringInSet(Storage, Str);
}
private:
@@ -330,9 +334,9 @@
}
}
- // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a
- // command line behind the scenes.
- if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) {
+ // Handle CCC_OVERRIDE_OPTIONS, used for editing a command line behind the
+ // scenes.
+ if (const char *OverrideStr = ::getenv("CCC_OVERRIDE_OPTIONS")) {
// FIXME: Driver shouldn't take extra initial argument.
ApplyQAOverride(argv, OverrideStr, SavedStrings);
}
@@ -341,11 +345,10 @@
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions;
{
- OwningPtr<OptTable> Opts(createDriverOptTable());
+ std::unique_ptr<OptTable> Opts(createDriverOptTable());
unsigned MissingArgIndex, MissingArgCount;
- OwningPtr<InputArgList> Args(Opts->ParseArgs(argv.begin()+1, argv.end(),
- MissingArgIndex,
- MissingArgCount));
+ std::unique_ptr<InputArgList> Args(Opts->ParseArgs(
+ argv.begin() + 1, argv.end(), MissingArgIndex, MissingArgCount));
// We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
// Any errors that would be diagnosed here will also be diagnosed later,
// when the DiagnosticsEngine actually exists.
@@ -408,7 +411,7 @@
if (TheDriver.CCLogDiagnostics)
TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE");
- OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv));
+ std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
int Res = 0;
SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
if (C.get())
@@ -443,7 +446,7 @@
llvm::llvm_shutdown();
-#ifdef _WIN32
+#ifdef LLVM_ON_WIN32
// Exit status should not be negative on Win32, unless abnormal termination.
// Once abnormal termiation was caught, negative status should not be
// propagated.
diff --git a/tools/libclang/ARCMigrate.cpp b/tools/libclang/ARCMigrate.cpp
index 3941794..dbb604d 100644
--- a/tools/libclang/ARCMigrate.cpp
+++ b/tools/libclang/ARCMigrate.cpp
@@ -55,7 +55,7 @@
}
TextDiagnosticBuffer diagBuffer;
- OwningPtr<Remap> remap(new Remap());
+ std::unique_ptr<Remap> remap(new Remap());
bool err = arcmt::getFileRemappings(remap->Vec, migrate_dir_path,&diagBuffer);
@@ -70,20 +70,20 @@
return 0;
}
- return remap.take();
+ return remap.release();
}
CXRemapping clang_getRemappingsFromFileList(const char **filePaths,
unsigned numFiles) {
bool Logging = ::getenv("LIBCLANG_LOGGING");
- OwningPtr<Remap> remap(new Remap());
+ std::unique_ptr<Remap> remap(new Remap());
if (numFiles == 0) {
if (Logging)
llvm::errs() << "clang_getRemappingsFromFileList was called with "
"numFiles=0\n";
- return remap.take();
+ return remap.release();
}
if (!filePaths) {
@@ -108,10 +108,10 @@
I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I)
llvm::errs() << I->second << '\n';
}
- return remap.take();
+ return remap.release();
}
- return remap.take();
+ return remap.release();
}
unsigned clang_remap_getNumFiles(CXRemapping map) {
diff --git a/tools/libclang/BuildSystem.cpp b/tools/libclang/BuildSystem.cpp
new file mode 100644
index 0000000..89c6e91
--- /dev/null
+++ b/tools/libclang/BuildSystem.cpp
@@ -0,0 +1,279 @@
+//===- BuildSystem.cpp - Utilities for use by build systems ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements various utilities for use by build systems.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-c/BuildSystem.h"
+#include "CXString.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/TimeValue.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace llvm::sys;
+
+unsigned long long clang_getBuildSessionTimestamp(void) {
+ return llvm::sys::TimeValue::now().toEpochTime();
+}
+
+struct CXVirtualFileOverlayImpl {
+ std::vector<std::pair<std::string, std::string> > Mappings;
+ Optional<bool> IsCaseSensitive;
+};
+
+CXVirtualFileOverlay clang_VirtualFileOverlay_create(unsigned) {
+ return new CXVirtualFileOverlayImpl();
+}
+
+enum CXErrorCode
+clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO,
+ const char *virtualPath,
+ const char *realPath) {
+ if (!VFO || !virtualPath || !realPath)
+ return CXError_InvalidArguments;
+ if (!path::is_absolute(virtualPath))
+ return CXError_InvalidArguments;
+ if (!path::is_absolute(realPath))
+ return CXError_InvalidArguments;
+
+ for (path::const_iterator
+ PI = path::begin(virtualPath),
+ PE = path::end(virtualPath); PI != PE; ++PI) {
+ StringRef Comp = *PI;
+ if (Comp == "." || Comp == "..")
+ return CXError_InvalidArguments;
+ }
+
+ VFO->Mappings.push_back(std::make_pair(virtualPath, realPath));
+ return CXError_Success;
+}
+
+enum CXErrorCode
+clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO,
+ int caseSensitive) {
+ if (!VFO)
+ return CXError_InvalidArguments;
+
+ VFO->IsCaseSensitive = caseSensitive;
+ return CXError_Success;
+}
+
+namespace {
+struct EntryTy {
+ std::string VPath;
+ std::string RPath;
+
+ friend bool operator < (const EntryTy &LHS, const EntryTy &RHS) {
+ return LHS.VPath < RHS.VPath;
+ }
+};
+
+class JSONVFSPrinter {
+ llvm::raw_ostream &OS;
+ CXVirtualFileOverlay VFO;
+
+public:
+ JSONVFSPrinter(llvm::raw_ostream &OS, CXVirtualFileOverlay VFO)
+ : OS(OS), VFO(VFO) {}
+
+ /// Entries must be sorted.
+ void print(ArrayRef<EntryTy> Entries) {
+ OS << "{\n"
+ " 'version': 0,\n";
+ if (VFO->IsCaseSensitive.hasValue()) {
+ OS << " 'case-sensitive': '";
+ if (VFO->IsCaseSensitive.getValue())
+ OS << "true";
+ else
+ OS << "false";
+ OS << "',\n";
+ }
+ OS << " 'roots': [\n";
+ printDirNodes(Entries, "", 4);
+ OS << " ]\n"
+ "}\n";
+ }
+
+private:
+ ArrayRef<EntryTy> printDirNodes(ArrayRef<EntryTy> Entries,
+ StringRef ParentPath,
+ unsigned Indent) {
+ while (!Entries.empty()) {
+ const EntryTy &Entry = Entries.front();
+ OS.indent(Indent) << "{\n";
+ Indent += 2;
+ OS.indent(Indent) << "'type': 'directory',\n";
+ OS.indent(Indent) << "'name': \"";
+ StringRef DirName = containedPart(ParentPath,
+ path::parent_path(Entry.VPath));
+ OS.write_escaped(DirName) << "\",\n";
+ OS.indent(Indent) << "'contents': [\n";
+ Entries = printContents(Entries, Indent + 2);
+ OS.indent(Indent) << "]\n";
+ Indent -= 2;
+ OS.indent(Indent) << '}';
+ if (Entries.empty()) {
+ OS << '\n';
+ break;
+ }
+ StringRef NextVPath = Entries.front().VPath;
+ if (!containedIn(ParentPath, NextVPath)) {
+ OS << '\n';
+ break;
+ }
+ OS << ",\n";
+ }
+ return Entries;
+ }
+
+ ArrayRef<EntryTy> printContents(ArrayRef<EntryTy> Entries,
+ unsigned Indent) {
+ while (!Entries.empty()) {
+ const EntryTy &Entry = Entries.front();
+ Entries = Entries.slice(1);
+ StringRef ParentPath = path::parent_path(Entry.VPath);
+ StringRef VName = path::filename(Entry.VPath);
+ OS.indent(Indent) << "{\n";
+ Indent += 2;
+ OS.indent(Indent) << "'type': 'file',\n";
+ OS.indent(Indent) << "'name': \"";
+ OS.write_escaped(VName) << "\",\n";
+ OS.indent(Indent) << "'external-contents': \"";
+ OS.write_escaped(Entry.RPath) << "\"\n";
+ Indent -= 2;
+ OS.indent(Indent) << '}';
+ if (Entries.empty()) {
+ OS << '\n';
+ break;
+ }
+ StringRef NextVPath = Entries.front().VPath;
+ if (!containedIn(ParentPath, NextVPath)) {
+ OS << '\n';
+ break;
+ }
+ OS << ",\n";
+ if (path::parent_path(NextVPath) != ParentPath) {
+ Entries = printDirNodes(Entries, ParentPath, Indent);
+ }
+ }
+ return Entries;
+ }
+
+ bool containedIn(StringRef Parent, StringRef Path) {
+ return Path.startswith(Parent);
+ }
+
+ StringRef containedPart(StringRef Parent, StringRef Path) {
+ assert(containedIn(Parent, Path));
+ if (Parent.empty())
+ return Path;
+ return Path.slice(Parent.size()+1, StringRef::npos);
+ }
+};
+}
+
+enum CXErrorCode
+clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned,
+ char **out_buffer_ptr,
+ unsigned *out_buffer_size) {
+ if (!VFO || !out_buffer_ptr || !out_buffer_size)
+ return CXError_InvalidArguments;
+
+ llvm::SmallVector<EntryTy, 16> Entries;
+ for (unsigned i = 0, e = VFO->Mappings.size(); i != e; ++i) {
+ EntryTy Entry;
+ Entry.VPath = VFO->Mappings[i].first;
+ Entry.RPath = VFO->Mappings[i].second;
+ Entries.push_back(Entry);
+ }
+
+ // FIXME: We should add options to determine if the paths are case sensitive
+ // or not. The following assumes that if paths are case-insensitive the caller
+ // did not mix cases in the virtual paths it provided.
+
+ std::sort(Entries.begin(), Entries.end());
+
+ llvm::SmallString<256> Buf;
+ llvm::raw_svector_ostream OS(Buf);
+ JSONVFSPrinter Printer(OS, VFO);
+ Printer.print(Entries);
+
+ StringRef Data = OS.str();
+ *out_buffer_ptr = (char*)malloc(Data.size());
+ *out_buffer_size = Data.size();
+ memcpy(*out_buffer_ptr, Data.data(), Data.size());
+ return CXError_Success;
+}
+
+void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) {
+ delete VFO;
+}
+
+
+struct CXModuleMapDescriptorImpl {
+ std::string ModuleName;
+ std::string UmbrellaHeader;
+};
+
+CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned) {
+ return new CXModuleMapDescriptorImpl();
+}
+
+enum CXErrorCode
+clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor MMD,
+ const char *name) {
+ if (!MMD || !name)
+ return CXError_InvalidArguments;
+
+ MMD->ModuleName = name;
+ return CXError_Success;
+}
+
+enum CXErrorCode
+clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor MMD,
+ const char *name) {
+ if (!MMD || !name)
+ return CXError_InvalidArguments;
+
+ MMD->UmbrellaHeader = name;
+ return CXError_Success;
+}
+
+enum CXErrorCode
+clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD, unsigned,
+ char **out_buffer_ptr,
+ unsigned *out_buffer_size) {
+ if (!MMD || !out_buffer_ptr || !out_buffer_size)
+ return CXError_InvalidArguments;
+
+ llvm::SmallString<256> Buf;
+ llvm::raw_svector_ostream OS(Buf);
+ OS << "framework module " << MMD->ModuleName << " {\n";
+ OS << " umbrella header \"";
+ OS.write_escaped(MMD->UmbrellaHeader) << "\"\n";
+ OS << '\n';
+ OS << " export *\n";
+ OS << " module * { export * }\n";
+ OS << "}\n";
+
+ StringRef Data = OS.str();
+ *out_buffer_ptr = (char*)malloc(Data.size());
+ *out_buffer_size = Data.size();
+ memcpy(*out_buffer_ptr, Data.data(), Data.size());
+ return CXError_Success;
+}
+
+void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) {
+ delete MMD;
+}
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index f53e5c1..04797a9 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -25,6 +25,8 @@
#include "clang/AST/Attr.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticCategories.h"
+#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/Version.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
@@ -34,6 +36,7 @@
#include "clang/Lex/Lexer.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Serialization/SerializationDiagnostic.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
@@ -62,6 +65,7 @@
CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
if (!AU)
return 0;
+ assert(CIdx);
CXTranslationUnit D = new CXTranslationUnitImpl();
D->CIdx = CIdx;
D->TheASTUnit = AU;
@@ -72,6 +76,18 @@
return D;
}
+bool cxtu::isASTReadError(ASTUnit *AU) {
+ for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
+ DEnd = AU->stored_diag_end();
+ D != DEnd; ++D) {
+ if (D->getLevel() >= DiagnosticsEngine::Error &&
+ DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
+ diag::DiagCat_AST_Deserialization_Issue)
+ return true;
+ }
+ return false;
+}
+
cxtu::CXTUOwner::~CXTUOwner() {
if (TU)
clang_disposeTranslationUnit(TU);
@@ -298,7 +314,7 @@
if (Outer.isInvalid())
return false;
- llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
+ std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Length = 0;
Unit->findFileRegionDecls(File, Offset, Length, Decls);
}
@@ -769,7 +785,7 @@
// If we have a function declared directly (without the use of a typedef),
// visit just the return type. Otherwise, just visit the function's type
// now.
- if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
+ if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
(!FTL && Visit(TL)))
return true;
@@ -779,8 +795,9 @@
return true;
// Visit the declaration name.
- if (VisitDeclarationNameInfo(ND->getNameInfo()))
- return true;
+ if (!isa<CXXDestructorDecl>(ND))
+ if (VisitDeclarationNameInfo(ND->getNameInfo()))
+ return true;
// FIXME: Visit explicitly-specified template arguments!
@@ -795,13 +812,11 @@
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
// Find the initializers that were written in the source.
SmallVector<CXXCtorInitializer *, 4> WrittenInits;
- for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
- IEnd = Constructor->init_end();
- I != IEnd; ++I) {
- if (!(*I)->isWritten())
+ for (auto *I : Constructor->inits()) {
+ if (!I->isWritten())
continue;
- WrittenInits.push_back(*I);
+ WrittenInits.push_back(I);
}
// Sort the initializers in source order
@@ -895,14 +910,12 @@
}
bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
- if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
+ if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
if (Visit(TSInfo->getTypeLoc()))
return true;
- for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
- PEnd = ND->param_end();
- P != PEnd; ++P) {
- if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
+ for (const auto *P : ND->params()) {
+ if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
return true;
}
@@ -934,19 +947,6 @@
}
}
-namespace {
- struct ContainerDeclsSort {
- SourceManager &SM;
- ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
- bool operator()(Decl *A, Decl *B) {
- SourceLocation L_A = A->getLocStart();
- SourceLocation L_B = B->getLocStart();
- assert(L_A.isValid() && L_B.isValid());
- return SM.isBeforeInTranslationUnit(L_A, L_B);
- }
- };
-}
-
bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
// FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
// an @implementation can lexically contain Decls that are not properly
@@ -978,18 +978,21 @@
// Get all the Decls in the DeclContext, and sort them with the
// additional ones we've collected. Then visit them.
- for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
- I!=E; ++I) {
- Decl *subDecl = *I;
- if (!subDecl || subDecl->getLexicalDeclContext() != D ||
- subDecl->getLocStart().isInvalid())
+ for (auto *SubDecl : D->decls()) {
+ if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
+ SubDecl->getLocStart().isInvalid())
continue;
- DeclsInContainer.push_back(subDecl);
+ DeclsInContainer.push_back(SubDecl);
}
// Now sort the Decls so that they appear in lexical order.
std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
- ContainerDeclsSort(SM));
+ [&SM](Decl *A, Decl *B) {
+ SourceLocation L_A = A->getLocStart();
+ SourceLocation L_B = B->getLocStart();
+ assert(L_A.isValid() && L_B.isValid());
+ return SM.isBeforeInTranslationUnit(L_A, L_B);
+ });
// Now visit the decls.
for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
@@ -1517,11 +1520,11 @@
bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
bool SkipResultType) {
- if (!SkipResultType && Visit(TL.getResultLoc()))
+ if (!SkipResultType && Visit(TL.getReturnLoc()))
return true;
- for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
- if (Decl *D = TL.getArg(I))
+ for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
+ if (Decl *D = TL.getParam(I))
if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
return true;
@@ -1542,6 +1545,10 @@
return Visit(TL.getOriginalLoc());
}
+bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
+ return Visit(TL.getOriginalLoc());
+}
+
bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
// Visit the template name.
@@ -1651,9 +1658,8 @@
return true;
if (D->isCompleteDefinition()) {
- for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
- E = D->bases_end(); I != E; ++I) {
- if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
+ for (const auto &I : D->bases()) {
+ if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
return true;
}
}
@@ -1662,9 +1668,8 @@
}
bool CursorVisitor::VisitAttributes(Decl *D) {
- for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
- i != e; ++i)
- if (Visit(MakeCXCursor(*i, D, TU)))
+ for (const auto *I : D->attrs())
+ if (Visit(MakeCXCursor(I, D, TU)))
return true;
return false;
@@ -1835,8 +1840,6 @@
void VisitStmt(const Stmt *S);
void VisitSwitchStmt(const SwitchStmt *S);
void VisitWhileStmt(const WhileStmt *W);
- void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
- void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
void VisitTypeTraitExpr(const TypeTraitExpr *E);
void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
@@ -1848,6 +1851,7 @@
void VisitLambdaExpr(const LambdaExpr *E);
void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
void VisitOMPParallelDirective(const OMPParallelDirective *D);
+ void VisitOMPSimdDirective(const OMPSimdDirective *D);
private:
void AddDeclarationNameInfo(const Stmt *S);
@@ -1920,14 +1924,24 @@
#include "clang/Basic/OpenMPKinds.def"
};
+void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
+ Visitor->AddStmt(C->getCondition());
+}
+
+void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
+ Visitor->AddStmt(C->getNumThreads());
+}
+
+void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
+ Visitor->AddStmt(C->getSafelen());
+}
+
void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
template<typename T>
void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
- for (typename T::varlist_const_iterator I = Node->varlist_begin(),
- E = Node->varlist_end();
- I != E; ++I)
- Visitor->AddStmt(*I);
+ for (const auto *I : Node->varlists())
+ Visitor->AddStmt(I);
}
void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
@@ -1940,6 +1954,9 @@
void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
+ VisitOMPClauseList(C);
+}
}
void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
@@ -2062,9 +2079,8 @@
void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
unsigned size = WL.size();
bool isFirst = true;
- for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
- D != DEnd; ++D) {
- AddDecl(*D, isFirst);
+ for (const auto *D : S->decls()) {
+ AddDecl(D, isFirst);
isFirst = false;
}
if (size == WL.size())
@@ -2181,15 +2197,6 @@
AddDecl(W->getConditionVariable());
}
-void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
- AddTypeLoc(E->getQueriedTypeSourceInfo());
-}
-
-void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
- AddTypeLoc(E->getRhsTypeSourceInfo());
- AddTypeLoc(E->getLhsTypeSourceInfo());
-}
-
void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
for (unsigned I = E->getNumArgs(); I > 0; --I)
AddTypeLoc(E->getArg(I-1));
@@ -2243,6 +2250,10 @@
VisitOMPExecutableDirective(D);
}
+void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
}
@@ -2444,12 +2455,12 @@
TL.getAs<FunctionProtoTypeLoc>()) {
if (E->hasExplicitParameters()) {
// Visit parameters.
- for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
- if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
+ if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
return true;
} else {
// Visit result type.
- if (Visit(Proto.getResultLoc()))
+ if (Visit(Proto.getReturnLoc()))
return true;
}
}
@@ -2544,7 +2555,8 @@
int displayDiagnostics) {
// We use crash recovery to make some of our APIs more reliable, implicitly
// enable it.
- llvm::CrashRecoveryContext::Enable();
+ if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
+ llvm::CrashRecoveryContext::Enable();
// Enable support for multithreading in LLVM.
{
@@ -2594,11 +2606,26 @@
else
llvm::CrashRecoveryContext::Disable();
}
-
+
CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
const char *ast_filename) {
- if (!CIdx || !ast_filename)
- return 0;
+ CXTranslationUnit TU;
+ enum CXErrorCode Result =
+ clang_createTranslationUnit2(CIdx, ast_filename, &TU);
+ (void)Result;
+ assert((TU && Result == CXError_Success) ||
+ (!TU && Result != CXError_Success));
+ return TU;
+}
+
+enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
+ const char *ast_filename,
+ CXTranslationUnit *out_TU) {
+ if (out_TU)
+ *out_TU = NULL;
+
+ if (!CIdx || !ast_filename || !out_TU)
+ return CXError_InvalidArguments;
LOG_FUNC_SECTION {
*Log << ast_filename;
@@ -2608,20 +2635,20 @@
FileSystemOptions FileSystemOpts;
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
- ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
- CXXIdx->getOnlyLocalDecls(),
- 0, 0,
- /*CaptureDiagnostics=*/true,
- /*AllowPCHWithCompilerErrors=*/true,
- /*UserFilesAreVolatile=*/true);
- return MakeCXTranslationUnit(CXXIdx, TU);
+ ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
+ CXXIdx->getOnlyLocalDecls(), None,
+ /*CaptureDiagnostics=*/true,
+ /*AllowPCHWithCompilerErrors=*/true,
+ /*UserFilesAreVolatile=*/true);
+ *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
+ return *out_TU ? CXError_Success : CXError_Failure;
}
unsigned clang_defaultEditingTranslationUnitOptions() {
return CXTranslationUnit_PrecompiledPreamble |
CXTranslationUnit_CacheCompletionResults;
}
-
+
CXTranslationUnit
clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
const char *source_filename,
@@ -2644,7 +2671,8 @@
struct CXUnsavedFile *unsaved_files;
unsigned num_unsaved_files;
unsigned options;
- CXTranslationUnit result;
+ CXTranslationUnit *out_TU;
+ CXErrorCode result;
};
static void clang_parseTranslationUnit_Impl(void *UserData) {
ParseTranslationUnitInfo *PTUI =
@@ -2656,10 +2684,19 @@
struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
unsigned num_unsaved_files = PTUI->num_unsaved_files;
unsigned options = PTUI->options;
- PTUI->result = 0;
+ CXTranslationUnit *out_TU = PTUI->out_TU;
- if (!CIdx)
+ // Set up the initial return values.
+ if (out_TU)
+ *out_TU = NULL;
+ PTUI->result = CXError_Failure;
+
+ // Check arguments.
+ if (!CIdx || !out_TU ||
+ (unsaved_files == NULL && num_unsaved_files != 0)) {
+ PTUI->result = CXError_InvalidArguments;
return;
+ }
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
@@ -2670,7 +2707,7 @@
// FIXME: Add a flag for modules.
TranslationUnitKind TUKind
= (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
- bool CacheCodeCompetionResults
+ bool CacheCodeCompletionResults
= options & CXTranslationUnit_CacheCompletionResults;
bool IncludeBriefCommentsInCodeCompletion
= options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
@@ -2686,8 +2723,8 @@
llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
DiagCleanup(Diags.getPtr());
- OwningPtr<std::vector<ASTUnit::RemappedFile> >
- RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
+ std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
+ new std::vector<ASTUnit::RemappedFile>());
// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<
@@ -2701,8 +2738,8 @@
Buffer));
}
- OwningPtr<std::vector<const char *> >
- Args(new std::vector<const char*>());
+ std::unique_ptr<std::vector<const char *>> Args(
+ new std::vector<const char *>());
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
@@ -2742,27 +2779,15 @@
}
unsigned NumErrors = Diags->getClient()->getNumErrors();
- OwningPtr<ASTUnit> ErrUnit;
- OwningPtr<ASTUnit> Unit(
- ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
- /* vector::data() not portable */,
- Args->size() ? (&(*Args)[0] + Args->size()) :0,
- Diags,
- CXXIdx->getClangResourcesPath(),
- CXXIdx->getOnlyLocalDecls(),
- /*CaptureDiagnostics=*/true,
- RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
- RemappedFiles->size(),
- /*RemappedFilesKeepOriginalName=*/true,
- PrecompilePreamble,
- TUKind,
- CacheCodeCompetionResults,
- IncludeBriefCommentsInCodeCompletion,
- /*AllowPCHWithCompilerErrors=*/true,
- SkipFunctionBodies,
- /*UserFilesAreVolatile=*/true,
- ForSerialization,
- &ErrUnit));
+ std::unique_ptr<ASTUnit> ErrUnit;
+ std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
+ Args->data(), Args->data() + Args->size(), Diags,
+ CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
+ /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
+ /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
+ CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
+ /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
+ /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
if (NumErrors != Diags->getClient()->getNumErrors()) {
// Make sure to check that 'Unit' is non-NULL.
@@ -2770,15 +2795,41 @@
printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
}
- PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
+ if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
+ PTUI->result = CXError_ASTReadError;
+ } else {
+ *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
+ PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
+ }
}
-CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
- const char *source_filename,
- const char * const *command_line_args,
- int num_command_line_args,
- struct CXUnsavedFile *unsaved_files,
- unsigned num_unsaved_files,
- unsigned options) {
+
+CXTranslationUnit
+clang_parseTranslationUnit(CXIndex CIdx,
+ const char *source_filename,
+ const char *const *command_line_args,
+ int num_command_line_args,
+ struct CXUnsavedFile *unsaved_files,
+ unsigned num_unsaved_files,
+ unsigned options) {
+ CXTranslationUnit TU;
+ enum CXErrorCode Result = clang_parseTranslationUnit2(
+ CIdx, source_filename, command_line_args, num_command_line_args,
+ unsaved_files, num_unsaved_files, options, &TU);
+ (void)Result;
+ assert((TU && Result == CXError_Success) ||
+ (!TU && Result != CXError_Success));
+ return TU;
+}
+
+enum CXErrorCode clang_parseTranslationUnit2(
+ CXIndex CIdx,
+ const char *source_filename,
+ const char *const *command_line_args,
+ int num_command_line_args,
+ struct CXUnsavedFile *unsaved_files,
+ unsigned num_unsaved_files,
+ unsigned options,
+ CXTranslationUnit *out_TU) {
LOG_FUNC_SECTION {
*Log << source_filename << ": ";
for (int i = 0; i != num_command_line_args; ++i)
@@ -2787,7 +2838,8 @@
ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
num_command_line_args, unsaved_files,
- num_unsaved_files, options, 0 };
+ num_unsaved_files, options, out_TU,
+ CXError_Failure };
llvm::CrashRecoveryContext CRC;
if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
@@ -2810,10 +2862,11 @@
fprintf(stderr, "],\n");
fprintf(stderr, " 'options' : %d,\n", options);
fprintf(stderr, "}\n");
-
- return 0;
+
+ return CXError_Crashed;
} else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
- PrintLibclangResourceUsage(PTUI.result);
+ if (CXTranslationUnit *TU = PTUI.out_TU)
+ PrintLibclangResourceUsage(*TU);
}
return PTUI.result;
@@ -2852,8 +2905,10 @@
*Log << TU << ' ' << FileName;
}
- if (!TU)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return CXSaveError_InvalidTU;
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
@@ -2896,7 +2951,8 @@
if (CTUnit) {
// If the translation unit has been marked as unsafe to free, just discard
// it.
- if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
+ ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
+ if (Unit && Unit->isUnsafeToFree())
return;
delete cxtu::getASTUnit(CTUnit);
@@ -2923,19 +2979,28 @@
static void clang_reparseTranslationUnit_Impl(void *UserData) {
ReparseTranslationUnitInfo *RTUI =
static_cast<ReparseTranslationUnitInfo*>(UserData);
+ RTUI->result = CXError_Failure;
+
CXTranslationUnit TU = RTUI->TU;
- if (!TU)
- return;
-
- // Reset the associated diagnostics.
- delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
- TU->Diagnostics = 0;
-
unsigned num_unsaved_files = RTUI->num_unsaved_files;
struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
unsigned options = RTUI->options;
(void) options;
- RTUI->result = 1;
+
+ // Check arguments.
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ RTUI->result = CXError_InvalidArguments;
+ return;
+ }
+ if (unsaved_files == NULL && num_unsaved_files != 0) {
+ RTUI->result = CXError_InvalidArguments;
+ return;
+ }
+
+ // Reset the associated diagnostics.
+ delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
+ TU->Diagnostics = 0;
CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
@@ -2943,10 +3008,10 @@
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
-
- OwningPtr<std::vector<ASTUnit::RemappedFile> >
- RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
-
+
+ std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
+ new std::vector<ASTUnit::RemappedFile>());
+
// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
@@ -2958,10 +3023,11 @@
RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
Buffer));
}
-
- if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
- RemappedFiles->size()))
- RTUI->result = 0;
+
+ if (!CXXUnit->Reparse(*RemappedFiles.get()))
+ RTUI->result = CXError_Success;
+ else if (isASTReadError(CXXUnit))
+ RTUI->result = CXError_ASTReadError;
}
int clang_reparseTranslationUnit(CXTranslationUnit TU,
@@ -2973,7 +3039,7 @@
}
ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
- options, 0 };
+ options, CXError_Failure };
if (getenv("LIBCLANG_NOTHREADS")) {
clang_reparseTranslationUnit_Impl(&RTUI);
@@ -2985,7 +3051,7 @@
if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
fprintf(stderr, "libclang: crash detected during reparsing\n");
cxtu::getASTUnit(TU)->setUnsafeToFree(true);
- return 1;
+ return CXError_Crashed;
} else if (getenv("LIBCLANG_RESOURCE_USAGE"))
PrintLibclangResourceUsage(TU);
@@ -2994,16 +3060,20 @@
CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
- if (!CTUnit)
+ if (isNotUsableTU(CTUnit)) {
+ LOG_BAD_TU(CTUnit);
return cxstring::createEmpty();
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
}
CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
- if (!TU)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return clang_getNullCursor();
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
@@ -3033,8 +3103,10 @@
}
CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
- if (!TU)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return 0;
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
@@ -3042,8 +3114,14 @@
return const_cast<FileEntry *>(FMgr.getFile(file_name));
}
-unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
- if (!TU || !file)
+unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
+ CXFile file) {
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return 0;
+ }
+
+ if (!file)
return 0;
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
@@ -3309,6 +3387,22 @@
}
if (clang_isExpression(C.kind)) {
+ const Expr *E = getCursorExpr(C);
+
+ if (C.kind == CXCursor_ObjCStringLiteral ||
+ C.kind == CXCursor_StringLiteral) {
+ const StringLiteral *SLit;
+ if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
+ SLit = OSL->getString();
+ } else {
+ SLit = cast<StringLiteral>(E);
+ }
+ SmallString<256> Buf;
+ llvm::raw_svector_ostream OS(Buf);
+ SLit->outputString(OS);
+ return cxstring::createDup(OS.str());
+ }
+
const Decl *D = getDeclFromExpr(getCursorExpr(C));
if (D)
return getDeclSpelling(D);
@@ -3819,7 +3913,9 @@
case CXCursor_ModuleImportDecl:
return cxstring::createRef("ModuleImport");
case CXCursor_OMPParallelDirective:
- return cxstring::createRef("OMPParallelDirective");
+ return cxstring::createRef("OMPParallelDirective");
+ case CXCursor_OMPSimdDirective:
+ return cxstring::createRef("OMPSimdDirective");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -3936,8 +4032,10 @@
}
CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
- if (!TU)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return clang_getNullCursor();
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
@@ -4897,6 +4995,11 @@
break;
}
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return cxstring::createEmpty();
+ }
+
// We have to find the starting buffer pointer the hard way, by
// deconstructing the source location.
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
@@ -4916,6 +5019,11 @@
}
CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return clang_getNullLocation();
+ }
+
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
return clang_getNullLocation();
@@ -4925,6 +5033,11 @@
}
CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return clang_getNullRange();
+ }
+
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
return clang_getNullRange();
@@ -5016,8 +5129,10 @@
if (NumTokens)
*NumTokens = 0;
- if (!TU)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return;
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit || !Tokens || !NumTokens)
@@ -5075,18 +5190,26 @@
unsigned BeforeChildrenTokenIdx;
};
SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
-
+
+ CXToken &getTok(unsigned Idx) {
+ assert(Idx < NumTokens);
+ return Tokens[Idx];
+ }
+ const CXToken &getTok(unsigned Idx) const {
+ assert(Idx < NumTokens);
+ return Tokens[Idx];
+ }
bool MoreTokens() const { return TokIdx < NumTokens; }
unsigned NextToken() const { return TokIdx; }
void AdvanceToken() { ++TokIdx; }
SourceLocation GetTokenLoc(unsigned tokI) {
- return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
+ return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
}
bool isFunctionMacroToken(unsigned tokI) const {
- return Tokens[tokI].int_data[3] != 0;
+ return getTok(tokI).int_data[3] != 0;
}
SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
- return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
+ return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
}
void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
@@ -5223,10 +5346,8 @@
if (Method->getObjCDeclQualifier())
HasContextSensitiveKeywords = true;
else {
- for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
- PEnd = Method->param_end();
- P != PEnd; ++P) {
- if ((*P)->getObjCDeclQualifier()) {
+ for (const auto *P : Method->params()) {
+ if (P->getObjCDeclQualifier()) {
HasContextSensitiveKeywords = true;
break;
}
@@ -5333,7 +5454,7 @@
// This can happen for C++ constructor expressions whose range generally
// include the variable declaration, e.g.:
// MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
- if (clang_isExpression(cursorK)) {
+ if (clang_isExpression(cursorK) && MoreTokens()) {
const Expr *E = getCursorExpr(cursor);
if (const Decl *D = getCursorParentDecl(cursor)) {
const unsigned I = NextToken();
@@ -5455,14 +5576,23 @@
}
private:
+ CXToken &getTok(unsigned Idx) {
+ assert(Idx < NumTokens);
+ return Tokens[Idx];
+ }
+ const CXToken &getTok(unsigned Idx) const {
+ assert(Idx < NumTokens);
+ return Tokens[Idx];
+ }
+
SourceLocation getTokenLoc(unsigned tokI) {
- return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
+ return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
}
void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
// The third field is reserved and currently not used. Use it here
// to mark macro arg expanded tokens with their expanded locations.
- Tokens[tokI].int_data[3] = loc.getRawEncoding();
+ getTok(tokI).int_data[3] = loc.getRawEncoding();
}
};
@@ -5720,7 +5850,11 @@
void clang_annotateTokens(CXTranslationUnit TU,
CXToken *Tokens, unsigned NumTokens,
CXCursor *Cursors) {
- if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return;
+ }
+ if (NumTokens == 0 || !Tokens || !Cursors) {
LOG_FUNC_SECTION { *Log << "<null input>"; }
return;
}
@@ -5890,9 +6024,8 @@
int availability_size) {
bool HadAvailAttr = false;
int N = 0;
- for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
- ++A) {
- if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
+ for (auto A : D->attrs()) {
+ if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
HadAvailAttr = true;
if (always_deprecated)
*always_deprecated = 1;
@@ -5901,7 +6034,7 @@
continue;
}
- if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
+ if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
HadAvailAttr = true;
if (always_unavailable)
*always_unavailable = 1;
@@ -5911,7 +6044,7 @@
continue;
}
- if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
+ if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
HadAvailAttr = true;
if (N < availability_size) {
availability[N].Platform
@@ -6223,7 +6356,11 @@
unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
CXModule CXMod) {
- if (!TU || !CXMod)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return 0;
+ }
+ if (!CXMod)
return 0;
Module *Mod = static_cast<Module*>(CXMod);
FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
@@ -6233,7 +6370,11 @@
CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
CXModule CXMod, unsigned Index) {
- if (!TU || !CXMod)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return 0;
+ }
+ if (!CXMod)
return 0;
Module *Mod = static_cast<Module*>(CXMod);
FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
@@ -6256,13 +6397,9 @@
if (!clang_isDeclaration(C.kind))
return 0;
- const CXXMethodDecl *Method = 0;
const Decl *D = cxcursor::getCursorDecl(C);
- if (const FunctionTemplateDecl *FunTmpl =
- dyn_cast_or_null<FunctionTemplateDecl>(D))
- Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
- else
- Method = dyn_cast_or_null<CXXMethodDecl>(D);
+ const CXXMethodDecl *Method =
+ D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
}
@@ -6270,13 +6407,9 @@
if (!clang_isDeclaration(C.kind))
return 0;
- const CXXMethodDecl *Method = 0;
const Decl *D = cxcursor::getCursorDecl(C);
- if (const FunctionTemplateDecl *FunTmpl =
- dyn_cast_or_null<FunctionTemplateDecl>(D))
- Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
- else
- Method = dyn_cast_or_null<CXXMethodDecl>(D);
+ const CXXMethodDecl *Method =
+ D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
return (Method && Method->isStatic()) ? 1 : 0;
}
@@ -6284,13 +6417,9 @@
if (!clang_isDeclaration(C.kind))
return 0;
- const CXXMethodDecl *Method = 0;
const Decl *D = cxcursor::getCursorDecl(C);
- if (const FunctionTemplateDecl *FunTmpl =
- dyn_cast_or_null<FunctionTemplateDecl>(D))
- Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
- else
- Method = dyn_cast_or_null<CXXMethodDecl>(D);
+ const CXXMethodDecl *Method =
+ D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
return (Method && Method->isVirtual()) ? 1 : 0;
}
} // end: extern "C"
@@ -6376,13 +6505,14 @@
}
CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
- if (!TU) {
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
CXTUResourceUsage usage = { (void*) 0, 0, 0 };
return usage;
}
ASTUnit *astUnit = cxtu::getASTUnit(TU);
- OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
+ std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
ASTContext &astContext = astUnit->getASTContext();
// How much memory is used by AST nodes and types?
@@ -6463,7 +6593,7 @@
CXTUResourceUsage usage = { (void*) entries.get(),
(unsigned) entries->size(),
entries->size() ? &(*entries)[0] : 0 };
- entries.take();
+ entries.release();
return usage;
}
@@ -6472,6 +6602,52 @@
delete (MemUsageEntries*) usage.data;
}
+CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
+ CXSourceRangeList *skipped = new CXSourceRangeList;
+ skipped->count = 0;
+ skipped->ranges = 0;
+
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return skipped;
+ }
+
+ if (!file)
+ return skipped;
+
+ ASTUnit *astUnit = cxtu::getASTUnit(TU);
+ PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
+ if (!ppRec)
+ return skipped;
+
+ ASTContext &Ctx = astUnit->getASTContext();
+ SourceManager &sm = Ctx.getSourceManager();
+ FileEntry *fileEntry = static_cast<FileEntry *>(file);
+ FileID wantedFileID = sm.translateFile(fileEntry);
+
+ const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
+ std::vector<SourceRange> wantedRanges;
+ for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
+ i != ei; ++i) {
+ if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
+ wantedRanges.push_back(*i);
+ }
+
+ skipped->count = wantedRanges.size();
+ skipped->ranges = new CXSourceRange[skipped->count];
+ for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
+ skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
+
+ return skipped;
+}
+
+void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
+ if (ranges) {
+ delete[] ranges->ranges;
+ delete ranges;
+ }
+}
+
} // end extern "C"
void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
@@ -6655,9 +6831,9 @@
LogOS << " (" << Unit->getASTFileName() << ')';
return *this;
}
+ } else {
+ LogOS << "<NULL TU>";
}
-
- LogOS << "<NULL TU>";
return *this;
}
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 865bb58..5912945 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -30,13 +30,13 @@
#include "clang/Sema/Sema.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Atomic.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
+#include <atomic>
#include <cstdio>
#include <cstdlib>
#include <string>
@@ -315,7 +315,7 @@
/// currently active.
///
/// Used for debugging purposes only.
-static llvm::sys::cas_flag CodeCompletionResultObjects;
+static std::atomic<unsigned> CodeCompletionResultObjects;
AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
const FileSystemOptions& FileSystemOpts)
@@ -332,10 +332,9 @@
ContainerKind(CXCursor_InvalidCode),
ContainerIsIncomplete(1)
{
- if (getenv("LIBCLANG_OBJTRACKING")) {
- llvm::sys::AtomicIncrement(&CodeCompletionResultObjects);
- fprintf(stderr, "+++ %d completion results\n", CodeCompletionResultObjects);
- }
+ if (getenv("LIBCLANG_OBJTRACKING"))
+ fprintf(stderr, "+++ %u completion results\n",
+ ++CodeCompletionResultObjects);
}
AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
@@ -346,10 +345,9 @@
for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
delete TemporaryBuffers[I];
- if (getenv("LIBCLANG_OBJTRACKING")) {
- llvm::sys::AtomicDecrement(&CodeCompletionResultObjects);
- fprintf(stderr, "--- %d completion results\n", CodeCompletionResultObjects);
- }
+ if (getenv("LIBCLANG_OBJTRACKING"))
+ fprintf(stderr, "--- %u completion results\n",
+ --CodeCompletionResultObjects);
}
} // end extern "C"
@@ -539,11 +537,11 @@
AllocatedResults(Results), CCTUInfo(Results.CodeCompletionAllocator),
TU(TranslationUnit) { }
~CaptureCompletionResults() { Finish(); }
-
- virtual void ProcessCodeCompleteResults(Sema &S,
- CodeCompletionContext Context,
- CodeCompletionResult *Results,
- unsigned NumResults) {
+
+ void ProcessCodeCompleteResults(Sema &S,
+ CodeCompletionContext Context,
+ CodeCompletionResult *Results,
+ unsigned NumResults) override {
StoredResults.reserve(StoredResults.size() + NumResults);
for (unsigned I = 0; I != NumResults; ++I) {
CodeCompletionString *StoredCompletion
@@ -616,10 +614,10 @@
AllocatedResults.ContainerIsIncomplete = 1;
}
}
-
- virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
- OverloadCandidate *Candidates,
- unsigned NumCandidates) {
+
+ void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+ OverloadCandidate *Candidates,
+ unsigned NumCandidates) override {
StoredResults.reserve(StoredResults.size() + NumCandidates);
for (unsigned I = 0; I != NumCandidates; ++I) {
CodeCompletionString *StoredCompletion
@@ -632,13 +630,13 @@
StoredResults.push_back(R);
}
}
-
- virtual CodeCompletionAllocator &getAllocator() {
+
+ CodeCompletionAllocator &getAllocator() override {
return *AllocatedResults.CodeCompletionAllocator;
}
- virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; }
-
+ CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;}
+
private:
void Finish() {
AllocatedResults.Results = new CXCompletionResult [StoredResults.size()];
@@ -680,7 +678,12 @@
#endif
bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
-
+
+ if (cxtu::isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return;
+ }
+
ASTUnit *AST = cxtu::getASTUnit(TU);
if (!AST)
return;
@@ -718,7 +721,7 @@
// Perform completion.
AST->CodeComplete(complete_filename, complete_line, complete_column,
- RemappedFiles.data(), RemappedFiles.size(),
+ RemappedFiles,
(options & CXCodeComplete_IncludeMacros),
(options & CXCodeComplete_IncludeCodePatterns),
IncludeBriefComments,
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 0e9dde8..cf9dc6f 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -51,32 +51,35 @@
Message(Msg), Loc(L) {}
virtual ~CXDiagnosticCustomNoteImpl() {}
-
- CXDiagnosticSeverity getSeverity() const {
+
+ CXDiagnosticSeverity getSeverity() const override {
return CXDiagnostic_Note;
}
-
- CXSourceLocation getLocation() const {
+
+ CXSourceLocation getLocation() const override {
return Loc;
}
-
- CXString getSpelling() const {
+
+ CXString getSpelling() const override {
return cxstring::createRef(Message.c_str());
}
-
- CXString getDiagnosticOption(CXString *Disable) const {
+
+ CXString getDiagnosticOption(CXString *Disable) const override {
if (Disable)
*Disable = cxstring::createEmpty();
return cxstring::createEmpty();
}
-
- unsigned getCategory() const { return 0; }
- CXString getCategoryText() const { return cxstring::createEmpty(); }
- unsigned getNumRanges() const { return 0; }
- CXSourceRange getRange(unsigned Range) const { return clang_getNullRange(); }
- unsigned getNumFixIts() const { return 0; }
- CXString getFixIt(unsigned FixIt, CXSourceRange *ReplacementRange) const {
+ unsigned getCategory() const override { return 0; }
+ CXString getCategoryText() const override { return cxstring::createEmpty(); }
+
+ unsigned getNumRanges() const override { return 0; }
+ CXSourceRange getRange(unsigned Range) const override {
+ return clang_getNullRange();
+ }
+ unsigned getNumFixIts() const override { return 0; }
+ CXString getFixIt(unsigned FixIt,
+ CXSourceRange *ReplacementRange) const override {
if (ReplacementRange)
*ReplacementRange = clang_getNullRange();
return cxstring::createEmpty();
@@ -93,9 +96,9 @@
virtual ~CXDiagnosticRenderer() {}
- virtual void beginDiagnostic(DiagOrStoredDiag D,
- DiagnosticsEngine::Level Level) {
-
+ void beginDiagnostic(DiagOrStoredDiag D,
+ DiagnosticsEngine::Level Level) override {
+
const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
if (!SD)
return;
@@ -109,13 +112,13 @@
if (Level != DiagnosticsEngine::Note)
CurrentSet = &CD->getChildDiagnostics();
}
-
- virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
- DiagnosticsEngine::Level Level,
- StringRef Message,
- ArrayRef<CharSourceRange> Ranges,
- const SourceManager *SM,
- DiagOrStoredDiag D) {
+
+ void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level,
+ StringRef Message,
+ ArrayRef<CharSourceRange> Ranges,
+ const SourceManager *SM,
+ DiagOrStoredDiag D) override {
if (!D.isNull())
return;
@@ -127,20 +130,20 @@
CXDiagnosticImpl *CD = new CXDiagnosticCustomNoteImpl(Message, L);
CurrentSet->appendDiagnostic(CD);
}
-
- virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
- DiagnosticsEngine::Level Level,
- ArrayRef<CharSourceRange> Ranges,
- const SourceManager &SM) {}
- virtual void emitCodeContext(SourceLocation Loc,
- DiagnosticsEngine::Level Level,
- SmallVectorImpl<CharSourceRange>& Ranges,
- ArrayRef<FixItHint> Hints,
- const SourceManager &SM) {}
-
- virtual void emitNote(SourceLocation Loc, StringRef Message,
- const SourceManager *SM) {
+ void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level,
+ ArrayRef<CharSourceRange> Ranges,
+ const SourceManager &SM) override {}
+
+ void emitCodeContext(SourceLocation Loc,
+ DiagnosticsEngine::Level Level,
+ SmallVectorImpl<CharSourceRange>& Ranges,
+ ArrayRef<FixItHint> Hints,
+ const SourceManager &SM) override {}
+
+ void emitNote(SourceLocation Loc, StringRef Message,
+ const SourceManager *SM) override {
CXSourceLocation L;
if (SM)
L = translateSourceLocation(*SM, LangOpts, Loc);
@@ -208,12 +211,21 @@
extern "C" {
unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
+ if (cxtu::isNotUsableTU(Unit)) {
+ LOG_BAD_TU(Unit);
+ return 0;
+ }
if (!cxtu::getASTUnit(Unit))
return 0;
return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
}
CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
+ if (cxtu::isNotUsableTU(Unit)) {
+ LOG_BAD_TU(Unit);
+ return 0;
+ }
+
CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
if (!D)
return 0;
@@ -224,8 +236,12 @@
return Diags->getDiagnostic(Index);
}
-
+
CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
+ if (cxtu::isNotUsableTU(Unit)) {
+ LOG_BAD_TU(Unit);
+ return 0;
+ }
if (!cxtu::getASTUnit(Unit))
return 0;
return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
@@ -292,6 +308,7 @@
switch (Severity) {
case CXDiagnostic_Ignored: llvm_unreachable("impossible");
case CXDiagnostic_Note: Out << "note: "; break;
+ case CXDiagnostic_Remark: Out << "remark: "; break;
case CXDiagnostic_Warning: Out << "warning: "; break;
case CXDiagnostic_Error: Out << "error: "; break;
case CXDiagnostic_Fatal: Out << "fatal error: "; break;
@@ -437,9 +454,10 @@
}
void clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
- CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags);
- if (D->isExternallyManaged())
- delete D;
+ if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl *>(Diags)) {
+ if (D->isExternallyManaged())
+ delete D;
+ }
}
CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
diff --git a/tools/libclang/CIndexDiagnostic.h b/tools/libclang/CIndexDiagnostic.h
index b1c3978..31ae902 100644
--- a/tools/libclang/CIndexDiagnostic.h
+++ b/tools/libclang/CIndexDiagnostic.h
@@ -121,35 +121,35 @@
virtual ~CXStoredDiagnostic() {}
/// \brief Return the severity of the diagnostic.
- virtual CXDiagnosticSeverity getSeverity() const;
-
+ CXDiagnosticSeverity getSeverity() const override;
+
/// \brief Return the location of the diagnostic.
- virtual CXSourceLocation getLocation() const;
+ CXSourceLocation getLocation() const override;
/// \brief Return the spelling of the diagnostic.
- virtual CXString getSpelling() const;
+ CXString getSpelling() const override;
/// \brief Return the text for the diagnostic option.
- virtual CXString getDiagnosticOption(CXString *Disable) const;
-
+ CXString getDiagnosticOption(CXString *Disable) const override;
+
/// \brief Return the category of the diagnostic.
- virtual unsigned getCategory() const;
-
+ unsigned getCategory() const override;
+
/// \brief Return the category string of the diagnostic.
- virtual CXString getCategoryText() const;
+ CXString getCategoryText() const override;
/// \brief Return the number of source ranges for the diagnostic.
- virtual unsigned getNumRanges() const;
-
+ unsigned getNumRanges() const override;
+
/// \brief Return the source ranges for the diagnostic.
- virtual CXSourceRange getRange(unsigned Range) const;
+ CXSourceRange getRange(unsigned Range) const override;
/// \brief Return the number of FixIts.
- virtual unsigned getNumFixIts() const;
+ unsigned getNumFixIts() const override;
/// \brief Return the FixIt information (source range and inserted text).
- virtual CXString getFixIt(unsigned FixIt,
- CXSourceRange *ReplacementRange) const;
+ CXString getFixIt(unsigned FixIt,
+ CXSourceRange *ReplacementRange) const override;
static bool classof(const CXDiagnosticImpl *D) {
return D->getKind() == StoredDiagnosticKind;
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
index c772dbb..322f723 100644
--- a/tools/libclang/CIndexHigh.cpp
+++ b/tools/libclang/CIndexHigh.cpp
@@ -480,13 +480,12 @@
CXResult clang_findIncludesInFile(CXTranslationUnit TU, CXFile file,
CXCursorAndRangeVisitor visitor) {
- LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
-
- if (!TU) {
- if (Log)
- *Log << "Null CXTranslationUnit";
+ if (cxtu::isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return CXResult_Invalid;
}
+
+ LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
if (!file) {
if (Log)
*Log << "Null file";
diff --git a/tools/libclang/CIndexInclusionStack.cpp b/tools/libclang/CIndexInclusionStack.cpp
index a6d3115..365609b 100644
--- a/tools/libclang/CIndexInclusionStack.cpp
+++ b/tools/libclang/CIndexInclusionStack.cpp
@@ -24,7 +24,11 @@
extern "C" {
void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
CXClientData clientData) {
-
+ if (cxtu::isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return;
+ }
+
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
SourceManager &SM = CXXUnit->getSourceManager();
ASTContext &Ctx = CXXUnit->getASTContext();
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 2b43c5b..25881c3 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -14,8 +14,10 @@
#include "CIndexer.h"
#include "CXCursor.h"
#include "CXString.h"
+#include "CXTranslationUnit.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Frontend/ASTUnit.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
@@ -73,10 +75,16 @@
if (!buf)
return cxstring::createEmpty();
- buf->Data += getUSRSpacePrefix();
- buf->Data += "macro@";
- buf->Data +=
- cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
+ bool Ignore = generateUSRForMacro(cxcursor::getCursorMacroDefinition(C),
+ cxtu::getASTUnit(TU)->getSourceManager(),
+ buf->Data);
+ if (Ignore) {
+ buf->dispose();
+ return cxstring::createEmpty();
+ }
+
+ // Return the C-string, but don't make a copy since it is already in
+ // the string buffer.
buf->Data.push_back('\0');
return createCXString(buf);
}
diff --git a/tools/libclang/CLog.h b/tools/libclang/CLog.h
index 57e01ae..fe6c218 100644
--- a/tools/libclang/CLog.h
+++ b/tools/libclang/CLog.h
@@ -10,6 +10,7 @@
#ifndef LLVM_LIBCLANG_CLOG_H
#define LLVM_LIBCLANG_CLOG_H
+#include "clang-c/Index.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallString.h"
@@ -95,7 +96,8 @@
/// *Log << "blah";
/// }
/// \endcode
-#define LOG_SECTION(NAME) if (LogRef Log = clang::cxindex::Logger::make(NAME))
+#define LOG_SECTION(NAME) \
+ if (clang::cxindex::LogRef Log = clang::cxindex::Logger::make(NAME))
#define LOG_FUNC_SECTION LOG_SECTION(LLVM_FUNCTION_NAME)
#endif
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index b7bde69..d6bbbf8 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -1,99 +1,103 @@
-set(LLVM_LINK_COMPONENTS
- ${LLVM_TARGETS_TO_BUILD}
- asmparser
- support
- bitreader
- mc
- )
-
set(SOURCES
ARCMigrate.cpp
+ BuildSystem.cpp
CIndex.cpp
CIndexCXX.cpp
CIndexCodeCompletion.cpp
CIndexDiagnostic.cpp
- CIndexDiagnostic.h
CIndexHigh.cpp
CIndexInclusionStack.cpp
CIndexUSRs.cpp
CIndexer.cpp
- CIndexer.h
CXComment.cpp
CXCursor.cpp
- CXCursor.h
CXCompilationDatabase.cpp
CXLoadedDiagnostic.cpp
- CXLoadedDiagnostic.h
CXSourceLocation.cpp
- CXSourceLocation.h
CXStoredDiagnostic.cpp
CXString.cpp
- CXString.h
- CXTranslationUnit.h
CXType.cpp
- CXType.h
IndexBody.cpp
IndexDecl.cpp
IndexTypeSourceInfo.cpp
- Index_Internal.h
Indexing.cpp
IndexingContext.cpp
+
+ ADDITIONAL_HEADERS
+ CIndexDiagnostic.h
+ CIndexer.h
+ CXCursor.h
+ CXLoadedDiagnostic.h
+ CXSourceLocation.h
+ CXString.h
+ CXTranslationUnit.h
+ CXType.h
+ Index_Internal.h
IndexingContext.h
../../include/clang-c/Index.h
)
-set(LIBRARIES
- clangIndex
- clangARCMigrate
- clangRewriteCore
- clangRewriteFrontend
- clangFrontend
- clangDriver
- clangSerialization
- clangSema
- clangEdit
- clangAST
- clangLex
- clangTooling
- clangBasic
- )
+option(LIBCLANG_BUILD_STATIC
+ "Build libclang as a static library (in addition to a shared one)" OFF)
-set(GENERATED_HEADERS
- ClangAttrClasses
- ClangAttrList
- ClangAttrParsedAttrList
- ClangCommentNodes
- ClangDiagnosticCommon
- ClangDiagnosticFrontend
- ClangDeclNodes
- ClangStmtNodes
- )
+set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libclang.exports)
-set(EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libclang.exports)
+if(MSVC)
+ # Avoid LNK4197 not to spceify libclang.def here.
+ # Each functions is exported as "dllexport" in include/clang-c.
+ # KB835326
+ set(LLVM_EXPORTED_SYMBOL_FILE)
+endif()
if( LLVM_ENABLE_PIC )
- set(SHARED_LIBRARY TRUE)
- add_clang_library(libclang ${SOURCES})
- target_link_libraries(libclang ${LIBRARIES})
- add_dependencies(libclang ${GENERATED_HEADERS} clang-headers)
+ set(ENABLE_SHARED SHARED)
+endif()
+if((NOT LLVM_ENABLE_PIC OR LIBCLANG_BUILD_STATIC) AND NOT WIN32)
+ set(ENABLE_STATIC STATIC)
+endif()
+
+if(WIN32)
+ set(output_name "libclang")
+else()
+ set(output_name "clang")
+endif()
+
+add_clang_library(libclang ${ENABLE_SHARED} ${ENABLE_STATIC}
+ OUTPUT_NAME ${output_name}
+ ${SOURCES}
+ DEPENDS clang-headers
+
+ LINK_LIBS
+ clangARCMigrate
+ clangAST
+ clangBasic
+ clangFrontend
+ clangIndex
+ clangLex
+ clangSema
+ clangTooling
+
+ LINK_COMPONENTS
+ BitReader
+ Support
+ )
+
+if(ENABLE_SHARED)
if(WIN32)
set_target_properties(libclang
PROPERTIES
- OUTPUT_NAME "libclang"
VERSION ${LIBCLANG_LIBRARY_VERSION}
DEFINE_SYMBOL _CINDEX_LIB_)
else()
set_target_properties(libclang
PROPERTIES
- OUTPUT_NAME "clang"
VERSION ${LIBCLANG_LIBRARY_VERSION}
DEFINE_SYMBOL _CINDEX_LIB_)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
- set(LIBCLANG_LINK_FLAGS
- " -Wl,-compatibility_version -Wl,1 -Wl,-dead_strip")
+ set(LIBCLANG_LINK_FLAGS " -Wl,-compatibility_version -Wl,1")
if (DEFINED ${LLVM_SUBMIT_VERSION})
set(LIBCLANG_LINK_FLAGS
"${LIBCLANG_LINK_FLAGS} -Wl,-current_version -Wl,${LLVM_SUBMIT_VERSION}.${LLVM_SUBMIT_SUBVERSION}")
@@ -101,26 +105,5 @@
set_property(TARGET libclang APPEND_STRING PROPERTY
LINK_FLAGS ${LIBCLANG_LINK_FLAGS})
- set_target_properties(libclang
- PROPERTIES
- INSTALL_NAME_DIR "@rpath")
endif()
-
-
- set(LIBCLANG_STATIC_TARGET_NAME libclang_static)
-else()
- set(LIBCLANG_STATIC_TARGET_NAME libclang)
-endif()
-
-option(LIBCLANG_BUILD_STATIC
- "Build libclang as a static library (in addition to a shared one)" OFF)
-
-if( (NOT LLVM_ENABLE_PIC OR LIBCLANG_BUILD_STATIC) AND NOT WIN32 )
- add_clang_library(${LIBCLANG_STATIC_TARGET_NAME} STATIC ${SOURCES})
- target_link_libraries(${LIBCLANG_STATIC_TARGET_NAME} ${LIBRARIES})
- add_dependencies(${LIBCLANG_STATIC_TARGET_NAME} ${GENERATED_HEADERS} clang-headers)
-
- set_target_properties(${LIBCLANG_STATIC_TARGET_NAME}
- PROPERTIES
- OUTPUT_NAME "clang")
endif()
diff --git a/tools/libclang/CXCompilationDatabase.cpp b/tools/libclang/CXCompilationDatabase.cpp
index 433caec..f4728fe 100644
--- a/tools/libclang/CXCompilationDatabase.cpp
+++ b/tools/libclang/CXCompilationDatabase.cpp
@@ -8,7 +8,7 @@
extern "C" {
-// FIXME: do something more usefull with the error message
+// FIXME: do something more useful with the error message
CXCompilationDatabase
clang_CompilationDatabase_fromDirectory(const char *BuildDir,
CXCompilationDatabase_Error *ErrorCode)
@@ -40,9 +40,8 @@
{
std::vector<CompileCommand> CCmd;
- AllocatedCXCompileCommands(const std::vector<CompileCommand>& Cmd)
- : CCmd(Cmd)
- { }
+ AllocatedCXCompileCommands(std::vector<CompileCommand> Cmd)
+ : CCmd(std::move(Cmd)) {}
};
CXCompileCommands
@@ -50,10 +49,9 @@
const char *CompleteFileName)
{
if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
- const std::vector<CompileCommand>
- CCmd(db->getCompileCommands(CompleteFileName));
+ std::vector<CompileCommand> CCmd(db->getCompileCommands(CompleteFileName));
if (!CCmd.empty())
- return new AllocatedCXCompileCommands( CCmd );
+ return new AllocatedCXCompileCommands(std::move(CCmd));
}
return 0;
@@ -62,9 +60,9 @@
CXCompileCommands
clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
- const std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
+ std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
if (!CCmd.empty())
- return new AllocatedCXCompileCommands( CCmd );
+ return new AllocatedCXCompileCommands(std::move(CCmd));
}
return 0;
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index c75c061..d682986 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -213,7 +213,6 @@
case Stmt::AsTypeExprClass:
case Stmt::AtomicExprClass:
case Stmt::BinaryConditionalOperatorClass:
- case Stmt::BinaryTypeTraitExprClass:
case Stmt::TypeTraitExprClass:
case Stmt::CXXBindTemporaryExprClass:
case Stmt::CXXDefaultArgExprClass:
@@ -236,7 +235,6 @@
case Stmt::ShuffleVectorExprClass:
case Stmt::ConvertVectorExprClass:
case Stmt::UnaryExprOrTypeTraitExprClass:
- case Stmt::UnaryTypeTraitExprClass:
case Stmt::VAArgExprClass:
case Stmt::ObjCArrayLiteralClass:
case Stmt::ObjCDictionaryLiteralClass:
@@ -511,9 +509,11 @@
case Stmt::OMPParallelDirectiveClass:
K = CXCursor_OMPParallelDirective;
break;
-
+ case Stmt::OMPSimdDirectiveClass:
+ K = CXCursor_OMPSimdDirective;
+ break;
}
-
+
CXCursor C = { K, 0, { Parent, S, TU } };
return C;
}
diff --git a/tools/libclang/CXLoadedDiagnostic.cpp b/tools/libclang/CXLoadedDiagnostic.cpp
index b02fdd6..679c528 100644
--- a/tools/libclang/CXLoadedDiagnostic.cpp
+++ b/tools/libclang/CXLoadedDiagnostic.cpp
@@ -15,13 +15,13 @@
#include "CXString.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Frontend/SerializedDiagnosticPrinter.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/ADT/Optional.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
using namespace clang;
@@ -67,13 +67,20 @@
//===----------------------------------------------------------------------===//
CXDiagnosticSeverity CXLoadedDiagnostic::getSeverity() const {
- // FIXME: possibly refactor with logic in CXStoredDiagnostic.
- switch (severity) {
- case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored;
- case DiagnosticsEngine::Note: return CXDiagnostic_Note;
- case DiagnosticsEngine::Warning: return CXDiagnostic_Warning;
- case DiagnosticsEngine::Error: return CXDiagnostic_Error;
- case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal;
+ // FIXME: Fail more softly if the diagnostic level is unknown?
+ auto severityAsLevel = static_cast<serialized_diags::Level>(severity);
+ assert(severity == static_cast<unsigned>(severityAsLevel) &&
+ "unknown serialized diagnostic level");
+
+ switch (severityAsLevel) {
+#define CASE(X) case serialized_diags::X: return CXDiagnostic_##X;
+ CASE(Ignored)
+ CASE(Note)
+ CASE(Warning)
+ CASE(Error)
+ CASE(Fatal)
+ CASE(Remark)
+#undef CASE
}
llvm_unreachable("Invalid diagnostic level");
@@ -175,7 +182,7 @@
// Deserialize diagnostics.
//===----------------------------------------------------------------------===//
-enum { MaxSupportedVersion = 1 };
+enum { MaxSupportedVersion = 2 };
typedef SmallVector<uint64_t, 64> RecordData;
enum LoadResult { Failure = 1, Success = 0 };
enum StreamResult { Read_EndOfStream,
@@ -252,7 +259,7 @@
FileSystemOptions FO;
FileManager FileMgr(FO);
- OwningPtr<llvm::MemoryBuffer> Buffer;
+ std::unique_ptr<llvm::MemoryBuffer> Buffer;
Buffer.reset(FileMgr.getBufferForFile(file));
if (!Buffer) {
@@ -277,7 +284,8 @@
return 0;
}
- OwningPtr<CXLoadedDiagnosticSetImpl> Diags(new CXLoadedDiagnosticSetImpl());
+ std::unique_ptr<CXLoadedDiagnosticSetImpl> Diags(
+ new CXLoadedDiagnosticSetImpl());
while (true) {
unsigned BlockID = 0;
@@ -285,7 +293,7 @@
BlockID, true);
switch (Res) {
case Read_EndOfStream:
- return (CXDiagnosticSet) Diags.take();
+ return (CXDiagnosticSet)Diags.release();
case Read_Failure:
return 0;
case Read_Record:
@@ -532,8 +540,8 @@
reportInvalidFile("malformed diagnostic block");
return Failure;
}
-
- OwningPtr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic());
+
+ std::unique_ptr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic());
RecordData Record;
while (true) {
@@ -560,7 +568,7 @@
continue;
}
case Read_BlockEnd:
- Diags.appendDiagnostic(D.take());
+ Diags.appendDiagnostic(D.release());
return Success;
case Read_Record:
break;
diff --git a/tools/libclang/CXLoadedDiagnostic.h b/tools/libclang/CXLoadedDiagnostic.h
index d4b11d5..c281f9b 100644
--- a/tools/libclang/CXLoadedDiagnostic.h
+++ b/tools/libclang/CXLoadedDiagnostic.h
@@ -29,36 +29,36 @@
virtual ~CXLoadedDiagnostic();
/// \brief Return the severity of the diagnostic.
- virtual CXDiagnosticSeverity getSeverity() const;
-
+ CXDiagnosticSeverity getSeverity() const override;
+
/// \brief Return the location of the diagnostic.
- virtual CXSourceLocation getLocation() const;
-
+ CXSourceLocation getLocation() const override;
+
/// \brief Return the spelling of the diagnostic.
- virtual CXString getSpelling() const;
-
+ CXString getSpelling() const override;
+
/// \brief Return the text for the diagnostic option.
- virtual CXString getDiagnosticOption(CXString *Disable) const;
-
+ CXString getDiagnosticOption(CXString *Disable) const override;
+
/// \brief Return the category of the diagnostic.
- virtual unsigned getCategory() const;
-
+ unsigned getCategory() const override;
+
/// \brief Return the category string of the diagnostic.
- virtual CXString getCategoryText() const;
-
+ CXString getCategoryText() const override;
+
/// \brief Return the number of source ranges for the diagnostic.
- virtual unsigned getNumRanges() const;
-
+ unsigned getNumRanges() const override;
+
/// \brief Return the source ranges for the diagnostic.
- virtual CXSourceRange getRange(unsigned Range) const;
-
+ CXSourceRange getRange(unsigned Range) const override;
+
/// \brief Return the number of FixIts.
- virtual unsigned getNumFixIts() const;
-
+ unsigned getNumFixIts() const override;
+
/// \brief Return the FixIt information (source range and inserted text).
- virtual CXString getFixIt(unsigned FixIt,
- CXSourceRange *ReplacementRange) const;
-
+ CXString getFixIt(unsigned FixIt,
+ CXSourceRange *ReplacementRange) const override;
+
static bool classof(const CXDiagnosticImpl *D) {
return D->getKind() == LoadedDiagnosticKind;
}
diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp
index 7371177..f78b687 100644
--- a/tools/libclang/CXSourceLocation.cpp
+++ b/tools/libclang/CXSourceLocation.cpp
@@ -122,7 +122,11 @@
CXFile file,
unsigned line,
unsigned column) {
- if (!TU || !file)
+ if (cxtu::isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return clang_getNullLocation();
+ }
+ if (!file)
return clang_getNullLocation();
if (line == 0 || column == 0)
return clang_getNullLocation();
@@ -151,9 +155,13 @@
CXSourceLocation clang_getLocationForOffset(CXTranslationUnit TU,
CXFile file,
unsigned offset) {
- if (!TU || !file)
+ if (cxtu::isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return clang_getNullLocation();
-
+ }
+ if (!file)
+ return clang_getNullLocation();
+
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
SourceLocation SLoc
diff --git a/tools/libclang/CXStoredDiagnostic.cpp b/tools/libclang/CXStoredDiagnostic.cpp
index 9731616..45ce39b 100644
--- a/tools/libclang/CXStoredDiagnostic.cpp
+++ b/tools/libclang/CXStoredDiagnostic.cpp
@@ -31,6 +31,7 @@
switch (Diag.getLevel()) {
case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored;
case DiagnosticsEngine::Note: return CXDiagnostic_Note;
+ case DiagnosticsEngine::Remark: return CXDiagnostic_Remark;
case DiagnosticsEngine::Warning: return CXDiagnostic_Warning;
case DiagnosticsEngine::Error: return CXDiagnostic_Error;
case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal;
diff --git a/tools/libclang/CXString.h b/tools/libclang/CXString.h
index 7032033..ac04259 100644
--- a/tools/libclang/CXString.h
+++ b/tools/libclang/CXString.h
@@ -19,8 +19,8 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
-#include <vector>
#include <string>
+#include <vector>
namespace clang {
namespace cxstring {
diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index c0014c0..13183be 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -14,8 +14,9 @@
#ifndef LLVM_CLANG_CXTRANSLATIONUNIT_H
#define LLVM_CLANG_CXTRANSLATIONUNIT_H
-#include "clang-c/Index.h"
+#include "CLog.h"
#include "CXString.h"
+#include "clang-c/Index.h"
namespace clang {
class ASTUnit;
@@ -45,6 +46,21 @@
return TU->TheASTUnit;
}
+/// \returns true if the ASTUnit has a diagnostic about the AST file being
+/// corrupted.
+bool isASTReadError(ASTUnit *AU);
+
+static inline bool isNotUsableTU(CXTranslationUnit TU) {
+ return !TU;
+}
+
+#define LOG_BAD_TU(TU) \
+ do { \
+ LOG_FUNC_SECTION { \
+ *Log << "called with a bad TU: " << TU; \
+ } \
+ } while(false)
+
class CXTUOwner {
CXTranslationUnitImpl *TU;
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 1e2cb18..82c30bf 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -538,7 +538,7 @@
return -1;
if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
- return FD->getNumArgs();
+ return FD->getNumParams();
}
if (T->getAs<FunctionNoProtoType>()) {
@@ -554,11 +554,11 @@
return MakeCXType(QualType(), GetTU(X));
if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
- unsigned numArgs = FD->getNumArgs();
- if (i >= numArgs)
+ unsigned numParams = FD->getNumParams();
+ if (i >= numParams)
return MakeCXType(QualType(), GetTU(X));
-
- return MakeCXType(FD->getArgType(i), GetTU(X));
+
+ return MakeCXType(FD->getParamType(i), GetTU(X));
}
return MakeCXType(QualType(), GetTU(X));
@@ -570,8 +570,8 @@
return MakeCXType(QualType(), GetTU(X));
if (const FunctionType *FD = T->getAs<FunctionType>())
- return MakeCXType(FD->getResultType(), GetTU(X));
-
+ return MakeCXType(FD->getReturnType(), GetTU(X));
+
return MakeCXType(QualType(), GetTU(X));
}
@@ -579,7 +579,7 @@
if (clang_isDeclaration(C.kind)) {
const Decl *D = cxcursor::getCursorDecl(C);
if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
- return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
+ return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
return clang_getResultType(clang_getCursorType(C));
}
@@ -752,15 +752,14 @@
}
static long long visitRecordForValidation(const RecordDecl *RD) {
- for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
- I != E; ++I){
- QualType FQT = (*I)->getType();
+ for (const auto *I : RD->fields()){
+ QualType FQT = I->getType();
if (FQT->isIncompleteType())
return CXTypeLayoutError_Incomplete;
if (FQT->isDependentType())
return CXTypeLayoutError_Dependent;
// recurse
- if (const RecordType *ChildType = (*I)->getType()->getAs<RecordType>()) {
+ if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
if (const RecordDecl *Child = ChildType->getDecl()) {
long long ret = visitRecordForValidation(Child);
if (ret < 0)
@@ -871,4 +870,38 @@
return cxstring::createDup(encoding);
}
+int clang_Type_getNumTemplateArguments(CXType CT) {
+ QualType T = GetQualType(CT);
+ if (T.isNull())
+ return -1;
+ const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
+ if (!RecordDecl)
+ return -1;
+ const ClassTemplateSpecializationDecl *TemplateDecl =
+ dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
+ if (!TemplateDecl)
+ return -1;
+ return TemplateDecl->getTemplateArgs().size();
+}
+
+CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) {
+ QualType T = GetQualType(CT);
+ if (T.isNull())
+ return MakeCXType(QualType(), GetTU(CT));
+ const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
+ if (!RecordDecl)
+ return MakeCXType(QualType(), GetTU(CT));
+ const ClassTemplateSpecializationDecl *TemplateDecl =
+ dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
+ if (!TemplateDecl)
+ return MakeCXType(QualType(), GetTU(CT));
+ const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs();
+ if (TA.size() <= i)
+ return MakeCXType(QualType(), GetTU(CT));
+ const TemplateArgument &A = TA.get(i);
+ if (A.getKind() != TemplateArgument::Type)
+ return MakeCXType(QualType(), GetTU(CT));
+ return MakeCXType(A.getAsType(), GetTU(CT));
+}
+
} // end: extern "C"
diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp
index e08a346..6cc8062 100644
--- a/tools/libclang/IndexBody.cpp
+++ b/tools/libclang/IndexBody.cpp
@@ -8,19 +8,19 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
-#include "RecursiveASTVisitor.h"
+#include "clang/AST/DataRecursiveASTVisitor.h"
using namespace clang;
using namespace cxindex;
namespace {
-class BodyIndexer : public cxindex::RecursiveASTVisitor<BodyIndexer> {
+class BodyIndexer : public DataRecursiveASTVisitor<BodyIndexer> {
IndexingContext &IndexCtx;
const NamedDecl *Parent;
const DeclContext *ParentDC;
- typedef RecursiveASTVisitor<BodyIndexer> base;
+ typedef DataRecursiveASTVisitor<BodyIndexer> base;
public:
BodyIndexer(IndexingContext &indexCtx,
const NamedDecl *Parent, const DeclContext *DC)
diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp
index 89feb96..64052ed 100644
--- a/tools/libclang/IndexDecl.cpp
+++ b/tools/libclang/IndexDecl.cpp
@@ -41,10 +41,8 @@
if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
IndexCtx.handleVar(Parm);
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- for (FunctionDecl::param_const_iterator PI = FD->param_begin(),
- PE = FD->param_end();
- PI != PE; ++PI) {
- IndexCtx.handleVar(*PI);
+ for (auto PI : FD->params()) {
+ IndexCtx.handleVar(PI);
}
}
}
@@ -55,11 +53,9 @@
if (D->isImplicit())
return;
- IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D);
- for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
- E = D->param_end();
- I != E; ++I)
- handleDeclarator(*I, D);
+ IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
+ for (const auto *I : D->params())
+ handleDeclarator(I, D);
if (D->isThisDeclarationADefinition()) {
const Stmt *Body = D->getBody();
@@ -75,10 +71,7 @@
if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
// Constructor initializers.
- for (CXXConstructorDecl::init_const_iterator I = Ctor->init_begin(),
- E = Ctor->init_end();
- I != E; ++I) {
- CXXCtorInitializer *Init = *I;
+ for (const auto *Init : Ctor->inits()) {
if (Init->isWritten()) {
IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
if (const FieldDecl *Member = Init->getAnyMember())
@@ -172,15 +165,11 @@
// Index the ivars first to make sure the synthesized ivars are indexed
// before indexing the methods that can reference them.
- for (ObjCImplementationDecl::ivar_iterator
- IvarI = D->ivar_begin(),
- IvarE = D->ivar_end(); IvarI != IvarE; ++IvarI) {
- IndexCtx.indexDecl(*IvarI);
- }
- for (DeclContext::decl_iterator
- I = D->decls_begin(), E = D->decls_end(); I != E; ++I) {
- if (!isa<ObjCIvarDecl>(*I))
- IndexCtx.indexDecl(*I);
+ for (const auto *IvarI : D->ivars())
+ IndexCtx.indexDecl(IvarI);
+ for (const auto *I : D->decls()) {
+ if (!isa<ObjCIvarDecl>(I))
+ IndexCtx.indexDecl(I);
}
return true;
@@ -268,11 +257,9 @@
// we should do better.
IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
- for (UsingDecl::shadow_iterator
- I = D->shadow_begin(), E = D->shadow_end(); I != E; ++I) {
- IndexCtx.handleReference((*I)->getUnderlyingDecl(), D->getLocation(),
- D, D->getLexicalDeclContext());
- }
+ for (const auto *I : D->shadows())
+ IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), D,
+ D->getLexicalDeclContext());
return true;
}
@@ -341,10 +328,8 @@
}
void IndexingContext::indexDeclContext(const DeclContext *DC) {
- for (DeclContext::decl_iterator
- I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
- indexDecl(*I);
- }
+ for (const auto *I : DC->decls())
+ indexDecl(I);
}
void IndexingContext::indexTopLevelDecl(const Decl *D) {
diff --git a/tools/libclang/IndexTypeSourceInfo.cpp b/tools/libclang/IndexTypeSourceInfo.cpp
index 2c771c8..4f8d4e5 100644
--- a/tools/libclang/IndexTypeSourceInfo.cpp
+++ b/tools/libclang/IndexTypeSourceInfo.cpp
@@ -8,14 +8,14 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
-#include "RecursiveASTVisitor.h"
+#include "clang/AST/DataRecursiveASTVisitor.h"
using namespace clang;
using namespace cxindex;
namespace {
-class TypeIndexer : public cxindex::RecursiveASTVisitor<TypeIndexer> {
+class TypeIndexer : public DataRecursiveASTVisitor<TypeIndexer> {
IndexingContext &IndexCtx;
const NamedDecl *Parent;
const DeclContext *ParentDC;
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 99fcdb6..55e6e79 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -219,7 +219,7 @@
assert(RegionLoc.isFileID());
FileID RegionFID;
unsigned RegionOffset;
- llvm::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
+ std::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
if (RegionFID != FID) {
if (isParsedOnceInclude(FE)) {
@@ -253,8 +253,8 @@
IndexPPCallbacks(Preprocessor &PP, IndexingContext &indexCtx)
: PP(PP), IndexCtx(indexCtx), IsMainFileEntered(false) { }
- virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
- SrcMgr::CharacteristicKind FileType, FileID PrevFID) {
+ void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+ SrcMgr::CharacteristicKind FileType, FileID PrevFID) override {
if (IsMainFileEntered)
return;
@@ -267,15 +267,11 @@
}
}
- virtual void InclusionDirective(SourceLocation HashLoc,
- const Token &IncludeTok,
- StringRef FileName,
- bool IsAngled,
- CharSourceRange FilenameRange,
- const FileEntry *File,
- StringRef SearchPath,
- StringRef RelativePath,
- const Module *Imported) {
+ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+ StringRef FileName, bool IsAngled,
+ CharSourceRange FilenameRange, const FileEntry *File,
+ StringRef SearchPath, StringRef RelativePath,
+ const Module *Imported) override {
bool isImport = (IncludeTok.is(tok::identifier) &&
IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import);
IndexCtx.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled,
@@ -283,25 +279,21 @@
}
/// MacroDefined - This hook is called whenever a macro definition is seen.
- virtual void MacroDefined(const Token &Id, const MacroDirective *MD) {
- }
+ void MacroDefined(const Token &Id, const MacroDirective *MD) override {}
/// MacroUndefined - This hook is called whenever a macro #undef is seen.
/// MI is released immediately following this callback.
- virtual void MacroUndefined(const Token &MacroNameTok,
- const MacroDirective *MD) {
- }
+ void MacroUndefined(const Token &MacroNameTok,
+ const MacroDirective *MD) override {}
/// MacroExpands - This is called by when a macro invocation is found.
- virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
- SourceRange Range, const MacroArgs *Args) {
- }
+ void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
+ SourceRange Range, const MacroArgs *Args) override {}
/// SourceRangeSkipped - This hook is called when a source range is skipped.
/// \param Range The SourceRange that was skipped. The range begins at the
/// #if/#else directive and ends after the #endif/#else directive.
- virtual void SourceRangeSkipped(SourceRange Range) {
- }
+ void SourceRangeSkipped(SourceRange Range) override {}
};
//===----------------------------------------------------------------------===//
@@ -318,24 +310,24 @@
// ASTConsumer Implementation
- virtual void Initialize(ASTContext &Context) {
+ void Initialize(ASTContext &Context) override {
IndexCtx.setASTContext(Context);
IndexCtx.startedTranslationUnit();
}
- virtual void HandleTranslationUnit(ASTContext &Ctx) {
+ void HandleTranslationUnit(ASTContext &Ctx) override {
if (SKCtrl)
SKCtrl->finished();
}
- virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
+ bool HandleTopLevelDecl(DeclGroupRef DG) override {
IndexCtx.indexDeclGroupRef(DG);
return !IndexCtx.shouldAbort();
}
/// \brief Handle the specified top-level declaration that occurred inside
/// and ObjC container.
- virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
+ void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
// They will be handled after the interface is seen first.
IndexCtx.addTUDeclInObjCContainer(D);
}
@@ -343,9 +335,9 @@
/// \brief This is called by the AST reader when deserializing things.
/// The default implementation forwards to HandleTopLevelDecl but we don't
/// care about them when indexing, so have an empty definition.
- virtual void HandleInterestingDecl(DeclGroupRef D) {}
+ void HandleInterestingDecl(DeclGroupRef D) override {}
- virtual void HandleTagDeclDefinition(TagDecl *D) {
+ void HandleTagDeclDefinition(TagDecl *D) override {
if (!IndexCtx.shouldIndexImplicitTemplateInsts())
return;
@@ -353,14 +345,14 @@
IndexCtx.indexDecl(D);
}
- virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {
+ void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override {
if (!IndexCtx.shouldIndexImplicitTemplateInsts())
return;
IndexCtx.indexDecl(D);
}
- virtual bool shouldSkipFunctionBody(Decl *D) {
+ bool shouldSkipFunctionBody(Decl *D) override {
if (!SKCtrl) {
// Always skip bodies.
return true;
@@ -375,7 +367,7 @@
FileID FID;
unsigned Offset;
- llvm::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
+ std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
// Don't skip bodies from main files; this may be revisited.
if (SM.getMainFileID() == FID)
return false;
@@ -395,8 +387,8 @@
SmallVector<StoredDiagnostic, 4> Errors;
public:
- virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
- const Diagnostic &Info) {
+ void HandleDiagnostic(DiagnosticsEngine::Level level,
+ const Diagnostic &Info) override {
if (level >= DiagnosticsEngine::Error)
Errors.push_back(StoredDiagnostic(level, Info));
}
@@ -411,7 +403,7 @@
CXTranslationUnit CXTU;
SessionSkipBodyData *SKData;
- OwningPtr<TUSkipBodyControl> SKCtrl;
+ std::unique_ptr<TUSkipBodyControl> SKCtrl;
public:
IndexingFrontendAction(CXClientData clientData,
@@ -422,8 +414,8 @@
: IndexCtx(clientData, indexCallbacks, indexOptions, cxTU),
CXTU(cxTU), SKData(skData) { }
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) {
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override {
PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
if (!PPOpts.ImplicitPCHInclude.empty()) {
@@ -446,17 +438,17 @@
return new IndexingConsumer(IndexCtx, SKCtrl.get());
}
- virtual void EndSourceFileAction() {
+ void EndSourceFileAction() override {
indexDiagnostics(CXTU, IndexCtx);
}
- virtual TranslationUnitKind getTranslationUnitKind() {
+ TranslationUnitKind getTranslationUnitKind() override {
if (IndexCtx.shouldIndexImplicitTemplateInsts())
return TU_Complete;
else
return TU_Prefix;
}
- virtual bool hasCodeCompletionSupport() const { return false; }
+ bool hasCodeCompletionSupport() const override { return false; }
};
//===----------------------------------------------------------------------===//
@@ -465,7 +457,7 @@
struct IndexSessionData {
CXIndex CIdx;
- OwningPtr<SessionSkipBodyData> SkipBodyData;
+ std::unique_ptr<SessionSkipBodyData> SkipBodyData;
explicit IndexSessionData(CXIndex cIdx)
: CIdx(cIdx), SkipBodyData(new SessionSkipBodyData) {}
@@ -514,16 +506,22 @@
unsigned num_unsaved_files = ITUI->num_unsaved_files;
CXTranslationUnit *out_TU = ITUI->out_TU;
unsigned TU_options = ITUI->TU_options;
- ITUI->result = 1; // init as error.
-
+
+ // Set up the initial return value.
+ ITUI->result = CXError_Failure;
+
if (out_TU)
*out_TU = 0;
- bool requestedToGetTU = (out_TU != 0);
+ bool requestedToGetTU = (out_TU != 0);
- if (!cxIdxAction)
+ if (!cxIdxAction) {
+ ITUI->result = CXError_InvalidArguments;
return;
- if (!client_index_callbacks || index_callbacks_size == 0)
+ }
+ if (!client_index_callbacks || index_callbacks_size == 0) {
+ ITUI->result = CXError_InvalidArguments;
return;
+ }
IndexerCallbacks CB;
memset(&CB, 0, sizeof(CB));
@@ -553,9 +551,9 @@
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
DiagCleanup(Diags.getPtr());
-
- OwningPtr<std::vector<const char *> >
- Args(new std::vector<const char*>());
+
+ std::unique_ptr<std::vector<const char *>> Args(
+ new std::vector<const char *>());
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
@@ -586,7 +584,7 @@
if (CInvok->getFrontendOpts().Inputs.empty())
return;
- OwningPtr<MemBufferOwner> BufOwner(new MemBufferOwner());
+ std::unique_ptr<MemBufferOwner> BufOwner(new MemBufferOwner());
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner>
@@ -612,7 +610,8 @@
ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags,
CaptureDiagnostics,
/*UserFilesAreVolatile=*/true);
- OwningPtr<CXTUOwner> CXTU(new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
+ std::unique_ptr<CXTUOwner> CXTU(
+ new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
@@ -625,7 +624,7 @@
if (SkipBodies)
CInvok->getFrontendOpts().SkipFunctionBodies = true;
- OwningPtr<IndexingFrontendAction> IndexAction;
+ std::unique_ptr<IndexingFrontendAction> IndexAction;
IndexAction.reset(new IndexingFrontendAction(client_data, CB,
index_options, CXTU->getTU(),
SkipBodies ? IdxSession->SkipBodyData.get() : 0));
@@ -671,13 +670,18 @@
if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())
printDiagsToStderr(Unit);
+ if (isASTReadError(Unit)) {
+ ITUI->result = CXError_ASTReadError;
+ return;
+ }
+
if (!Success)
return;
if (out_TU)
*out_TU = CXTU->takeTU();
- ITUI->result = 0; // success.
+ ITUI->result = CXError_Success;
}
//===----------------------------------------------------------------------===//
@@ -706,7 +710,7 @@
// FIXME: Only deserialize inclusion directives.
PreprocessingRecord::iterator I, E;
- llvm::tie(I, E) = Unit.getLocalPreprocessingEntities();
+ std::tie(I, E) = Unit.getLocalPreprocessingEntities();
bool isModuleFile = Unit.isModuleFile();
for (; I != E; ++I) {
@@ -754,12 +758,20 @@
IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
unsigned index_callbacks_size = ITUI->index_callbacks_size;
unsigned index_options = ITUI->index_options;
- ITUI->result = 1; // init as error.
- if (!TU)
+ // Set up the initial return value.
+ ITUI->result = CXError_Failure;
+
+ // Check arguments.
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ ITUI->result = CXError_InvalidArguments;
return;
- if (!client_index_callbacks || index_callbacks_size == 0)
+ }
+ if (!client_index_callbacks || index_callbacks_size == 0) {
+ ITUI->result = CXError_InvalidArguments;
return;
+ }
CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
@@ -771,14 +783,14 @@
? index_callbacks_size : sizeof(CB);
memcpy(&CB, client_index_callbacks, ClientCBSize);
- OwningPtr<IndexingContext> IndexCtx;
+ std::unique_ptr<IndexingContext> IndexCtx;
IndexCtx.reset(new IndexingContext(client_data, CB, index_options, TU));
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<IndexingContext>
IndexCtxCleanup(IndexCtx.get());
- OwningPtr<IndexingConsumer> IndexConsumer;
+ std::unique_ptr<IndexingConsumer> IndexConsumer;
IndexConsumer.reset(new IndexingConsumer(*IndexCtx, 0));
// Recover resources if we crash before exiting this method.
@@ -807,7 +819,7 @@
indexTranslationUnit(*Unit, *IndexCtx);
indexDiagnostics(TU, *IndexCtx);
- ITUI->result = 0;
+ ITUI->result = CXError_Success;
}
//===----------------------------------------------------------------------===//
@@ -979,7 +991,8 @@
index_callbacks_size, index_options,
source_filename, command_line_args,
num_command_line_args, unsaved_files,
- num_unsaved_files, out_TU, TU_options, 0 };
+ num_unsaved_files, out_TU, TU_options,
+ CXError_Failure };
if (getenv("LIBCLANG_NOTHREADS")) {
clang_indexSourceFile_Impl(&ITUI);
diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp
index 41ed6ea..1637843 100644
--- a/tools/libclang/IndexingContext.cpp
+++ b/tools/libclang/IndexingContext.cpp
@@ -67,9 +67,7 @@
if (!D->hasAttrs())
return;
- for (AttrVec::const_iterator AttrI = D->attr_begin(), AttrE = D->attr_end();
- AttrI != AttrE; ++AttrI) {
- const Attr *A = *AttrI;
+ for (const auto *A : D->attrs()) {
CXCursor C = MakeCXCursor(A, D, IdxCtx.CXTU);
CXIdxLoc Loc = IdxCtx.getIndexLoc(A->getLocation());
switch (C.kind) {
@@ -125,9 +123,7 @@
IndexingContext::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
IndexingContext &IdxCtx,
ScratchAlloc &SA) {
- for (CXXRecordDecl::base_class_const_iterator
- I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
- const CXXBaseSpecifier &Base = *I;
+ for (const auto &Base : D->bases()) {
BaseEntities.push_back(EntityInfo());
const NamedDecl *BaseD = 0;
QualType T = Base.getType();
@@ -268,7 +264,6 @@
Module *Mod = ImportD->getImportedModule();
if (!Mod)
return;
- std::string ModuleName = Mod->getFullModuleName();
CXIdxImportedASTFileInfo Info = {
static_cast<CXFile>(
@@ -803,9 +798,9 @@
const FileEntry *FE = SM.getFileEntryForID(FID);
if (!FE)
return true;
- RefFileOccurence RefOccur(FE, D);
- std::pair<llvm::DenseSet<RefFileOccurence>::iterator, bool>
- res = RefFileOccurences.insert(RefOccur);
+ RefFileOccurrence RefOccur(FE, D);
+ std::pair<llvm::DenseSet<RefFileOccurrence>::iterator, bool>
+ res = RefFileOccurrences.insert(RefOccur);
if (!res.second)
return true; // already in map.
diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h
index 3437d55..88d623f 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -286,8 +286,8 @@
ContainerMapTy ContainerMap;
EntityMapTy EntityMap;
- typedef std::pair<const FileEntry *, const Decl *> RefFileOccurence;
- llvm::DenseSet<RefFileOccurence> RefFileOccurences;
+ typedef std::pair<const FileEntry *, const Decl *> RefFileOccurrence;
+ llvm::DenseSet<RefFileOccurrence> RefFileOccurrences;
std::deque<DeclGroupRef> TUDeclsInObjCContainer;
@@ -335,7 +335,7 @@
unsigned indexOptions, CXTranslationUnit cxTU)
: Ctx(0), ClientData(clientData), CB(indexCallbacks),
IndexOptions(indexOptions), CXTU(cxTU),
- StrScratch(/*size=*/1024), StrAdapterCount(0) { }
+ StrScratch(), StrAdapterCount(0) { }
ASTContext &getASTContext() const { return *Ctx; }
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
index 43ecbd1..41d5166 100644
--- a/tools/libclang/Makefile
+++ b/tools/libclang/Makefile
@@ -17,14 +17,18 @@
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
-USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a \
+USEDLIBS = clangIndex.a clangARCMigrate.a \
+ clangRewriteFrontend.a \
+ clangFormat.a \
clangTooling.a \
+ clangFrontend.a clangDriver.a \
clangSerialization.a \
clangParse.a clangSema.a \
- clangARCMigrate.a clangRewriteFrontend.a clangRewriteCore.a \
+ clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
+ clangRewriteCore.a \
clangAnalysis.a clangEdit.a \
+ clangASTMatchers.a \
clangAST.a clangLex.a clangBasic.a \
- clangFormat.a
include $(CLANG_LEVEL)/Makefile
@@ -46,16 +50,6 @@
-Wl,$(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION)
endif
- # Extra options to override libtool defaults.
- LLVMLibsOptions += -Wl,-dead_strip
-
- # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line
- DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/')
- ifneq ($(DARWIN_VERS),8)
- LLVMLibsOptions += -Wl,-install_name \
- -Wl,"@rpath/lib$(LIBRARYNAME)$(SHLIBEXT)"
- endif
-
# If we're doing an Apple-style build, add the LTO object path.
ifeq ($(RC_XBS),YES)
TempFile := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/clang-lto.XXXXXX)
diff --git a/tools/libclang/RecursiveASTVisitor.h b/tools/libclang/RecursiveASTVisitor.h
deleted file mode 100644
index 3ad5acb..0000000
--- a/tools/libclang/RecursiveASTVisitor.h
+++ /dev/null
@@ -1,2384 +0,0 @@
-//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the RecursiveASTVisitor interface, which recursively
-// traverses the entire AST.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
-#define LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclOpenMP.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
-#include "clang/AST/StmtOpenMP.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/TypeLoc.h"
-
-// The following three macros are used for meta programming. The code
-// using them is responsible for defining macro OPERATOR().
-
-// All unary operators.
-#define UNARYOP_LIST() \
- OPERATOR(PostInc) OPERATOR(PostDec) \
- OPERATOR(PreInc) OPERATOR(PreDec) \
- OPERATOR(AddrOf) OPERATOR(Deref) \
- OPERATOR(Plus) OPERATOR(Minus) \
- OPERATOR(Not) OPERATOR(LNot) \
- OPERATOR(Real) OPERATOR(Imag) \
- OPERATOR(Extension)
-
-// All binary operators (excluding compound assign operators).
-#define BINOP_LIST() \
- OPERATOR(PtrMemD) OPERATOR(PtrMemI) \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) \
- OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) \
- OPERATOR(Shr) \
- \
- OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) \
- OPERATOR(GE) OPERATOR(EQ) OPERATOR(NE) \
- OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \
- OPERATOR(LAnd) OPERATOR(LOr) \
- \
- OPERATOR(Assign) \
- OPERATOR(Comma)
-
-// All compound assign operators.
-#define CAO_LIST() \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
- OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
-
-namespace clang {
-namespace cxindex {
-
-// A helper macro to implement short-circuiting when recursing. It
-// invokes CALL_EXPR, which must be a method call, on the derived
-// object (s.t. a user of RecursiveASTVisitor can override the method
-// in CALL_EXPR).
-#define TRY_TO(CALL_EXPR) \
- do { if (!getDerived().CALL_EXPR) return false; } while (0)
-
-/// \brief A class that does preorder depth-first traversal on the
-/// entire Clang AST and visits each node.
-///
-/// This class performs three distinct tasks:
-/// 1. traverse the AST (i.e. go to each node);
-/// 2. at a given node, walk up the class hierarchy, starting from
-/// the node's dynamic type, until the top-most class (e.g. Stmt,
-/// Decl, or Type) is reached.
-/// 3. given a (node, class) combination, where 'class' is some base
-/// class of the dynamic type of 'node', call a user-overridable
-/// function to actually visit the node.
-///
-/// These tasks are done by three groups of methods, respectively:
-/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
-/// for traversing an AST rooted at x. This method simply
-/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
-/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
-/// then recursively visits the child nodes of x.
-/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
-/// similarly.
-/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
-/// any child node of x. Instead, it first calls WalkUpFromBar(x)
-/// where Bar is the direct parent class of Foo (unless Foo has
-/// no parent), and then calls VisitFoo(x) (see the next list item).
-/// 3. VisitFoo(Foo *x) does task #3.
-///
-/// These three method groups are tiered (Traverse* > WalkUpFrom* >
-/// Visit*). A method (e.g. Traverse*) may call methods from the same
-/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
-/// It may not call methods from a higher tier.
-///
-/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
-/// is Foo's super class) before calling VisitFoo(), the result is
-/// that the Visit*() methods for a given node are called in the
-/// top-down order (e.g. for a node of type NamedDecl, the order will
-/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
-///
-/// This scheme guarantees that all Visit*() calls for the same AST
-/// node are grouped together. In other words, Visit*() methods for
-/// different nodes are never interleaved.
-///
-/// Stmts are traversed internally using a data queue to avoid a stack overflow
-/// with hugely nested ASTs.
-///
-/// Clients of this visitor should subclass the visitor (providing
-/// themselves as the template argument, using the curiously recurring
-/// template pattern) and override any of the Traverse*, WalkUpFrom*,
-/// and Visit* methods for declarations, types, statements,
-/// expressions, or other AST nodes where the visitor should customize
-/// behavior. Most users only need to override Visit*. Advanced
-/// users may override Traverse* and WalkUpFrom* to implement custom
-/// traversal strategies. Returning false from one of these overridden
-/// functions will abort the entire traversal.
-///
-/// By default, this visitor tries to visit every part of the explicit
-/// source code exactly once. The default policy towards templates
-/// is to descend into the 'pattern' class or function body, not any
-/// explicit or implicit instantiations. Explicit specializations
-/// are still visited, and the patterns of partial specializations
-/// are visited separately. This behavior can be changed by
-/// overriding shouldVisitTemplateInstantiations() in the derived class
-/// to return true, in which case all known implicit and explicit
-/// instantiations will be visited at the same time as the pattern
-/// from which they were produced.
-template<typename Derived>
-class RecursiveASTVisitor {
-public:
- /// \brief Return a reference to the derived class.
- Derived &getDerived() { return *static_cast<Derived*>(this); }
-
- /// \brief Return whether this visitor should recurse into
- /// template instantiations.
- bool shouldVisitTemplateInstantiations() const { return false; }
-
- /// \brief Return whether this visitor should recurse into the types of
- /// TypeLocs.
- bool shouldWalkTypesOfTypeLocs() const { return true; }
-
- /// \brief Recursively visit a statement or expression, by
- /// dispatching to Traverse*() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is NULL).
- bool TraverseStmt(Stmt *S);
-
- /// \brief Recursively visit a type, by dispatching to
- /// Traverse*Type() based on the argument's getTypeClass() property.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type).
- bool TraverseType(QualType T);
-
- /// \brief Recursively visit a type with location, by dispatching to
- /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type location).
- bool TraverseTypeLoc(TypeLoc TL);
-
- /// \brief Recursively visit a declaration, by dispatching to
- /// Traverse*Decl() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is NULL).
- bool TraverseDecl(Decl *D);
-
- /// \brief Recursively visit a C++ nested-name-specifier.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
-
- /// \brief Recursively visit a C++ nested-name-specifier with location
- /// information.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
-
- /// \brief Recursively visit a name with its location information.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
-
- /// \brief Recursively visit a template name and dispatch to the
- /// appropriate method.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseTemplateName(TemplateName Template);
-
- /// \brief Recursively visit a template argument and dispatch to the
- /// appropriate method for the argument type.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- // FIXME: migrate callers to TemplateArgumentLoc instead.
- bool TraverseTemplateArgument(const TemplateArgument &Arg);
-
- /// \brief Recursively visit a template argument location and dispatch to the
- /// appropriate method for the argument type.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
-
- /// \brief Recursively visit a set of template arguments.
- /// This can be overridden by a subclass, but it's not expected that
- /// will be needed -- this visitor always dispatches to another.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
- bool TraverseTemplateArguments(const TemplateArgument *Args,
- unsigned NumArgs);
-
- /// \brief Recursively visit a constructor initializer. This
- /// automatically dispatches to another visitor for the initializer
- /// expression, but not for the name of the initializer, so may
- /// be overridden for clients that need access to the name.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
-
- /// \brief Recursively visit a lambda capture.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaCapture(LambdaExpr::Capture C);
-
- // ---- Methods on Stmts ----
-
- // Declare Traverse*() for all concrete Stmt classes.
-#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- bool Traverse##CLASS(CLASS *S);
-#include "clang/AST/StmtNodes.inc"
- // The above header #undefs ABSTRACT_STMT and STMT upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
- bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
- bool VisitStmt(Stmt *S) { return true; }
-#define STMT(CLASS, PARENT) \
- bool WalkUpFrom##CLASS(CLASS *S) { \
- TRY_TO(WalkUpFrom##PARENT(S)); \
- TRY_TO(Visit##CLASS(S)); \
- return true; \
- } \
- bool Visit##CLASS(CLASS *S) { return true; }
-#include "clang/AST/StmtNodes.inc"
-
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
- // operator methods. Unary operators are not classes in themselves
- // (they're all opcodes in UnaryOperator) but do have visitors.
-#define OPERATOR(NAME) \
- bool TraverseUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnary##NAME(S)); \
- StmtQueueAction StmtQueue(*this); \
- StmtQueue.queue(S->getSubExpr()); \
- return true; \
- } \
- bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnaryOperator(S)); \
- TRY_TO(VisitUnary##NAME(S)); \
- return true; \
- } \
- bool VisitUnary##NAME(UnaryOperator *S) { return true; }
-
- UNARYOP_LIST()
-#undef OPERATOR
-
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
- // operator methods. Binary operators are not classes in themselves
- // (they're all opcodes in BinaryOperator) but do have visitors.
-#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
- bool TraverseBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFromBin##NAME(S)); \
- StmtQueueAction StmtQueue(*this); \
- StmtQueue.queue(S->getLHS()); \
- StmtQueue.queue(S->getRHS()); \
- return true; \
- } \
- bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
- TRY_TO(VisitBin##NAME(S)); \
- return true; \
- } \
- bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
-
-#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
- BINOP_LIST()
-#undef OPERATOR
-
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
- // assignment methods. Compound assignment operators are not
- // classes in themselves (they're all opcodes in
- // CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME) \
- GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
-
- CAO_LIST()
-#undef OPERATOR
-#undef GENERAL_BINOP_FALLBACK
-
- // ---- Methods on Types ----
- // FIXME: revamp to take TypeLoc's rather than Types.
-
- // Declare Traverse*() for all concrete Type classes.
-#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
- bool Traverse##CLASS##Type(CLASS##Type *T);
-#include "clang/AST/TypeNodes.def"
- // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all Type classes.
- bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
- bool VisitType(Type *T) { return true; }
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
- TRY_TO(WalkUpFrom##BASE(T)); \
- TRY_TO(Visit##CLASS##Type(T)); \
- return true; \
- } \
- bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
-#include "clang/AST/TypeNodes.def"
-
- // ---- Methods on TypeLocs ----
- // FIXME: this currently just calls the matching Type methods
-
- // Declare Traverse*() for all concrete Type classes.
-#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
- bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
-#include "clang/AST/TypeLocNodes.def"
- // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
- bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
- bool VisitTypeLoc(TypeLoc TL) { return true; }
-
- // QualifiedTypeLoc and UnqualTypeLoc are not declared in
- // TypeNodes.def and thus need to be handled specially.
- bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
- return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
- }
- bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
- bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
- return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
- }
- bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
-
- // Note that BASE includes trailing 'Type' which CLASS doesn't.
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
- TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
- TRY_TO(Visit##CLASS##TypeLoc(TL)); \
- return true; \
- } \
- bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
-#include "clang/AST/TypeNodes.def"
-
- // ---- Methods on Decls ----
-
- // Declare Traverse*() for all concrete Decl classes.
-#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
- bool Traverse##CLASS##Decl(CLASS##Decl *D);
-#include "clang/AST/DeclNodes.inc"
- // The above header #undefs ABSTRACT_DECL and DECL upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
- bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
- bool VisitDecl(Decl *D) { return true; }
-#define DECL(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
- TRY_TO(WalkUpFrom##BASE(D)); \
- TRY_TO(Visit##CLASS##Decl(D)); \
- return true; \
- } \
- bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
-#include "clang/AST/DeclNodes.inc"
-
-private:
- // These are helper methods used by more than one Traverse* method.
- bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
- bool TraverseClassInstantiations(ClassTemplateDecl *D);
- bool TraverseVariableInstantiations(VarTemplateDecl *D);
- bool TraverseFunctionInstantiations(FunctionTemplateDecl *D) ;
- bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
- unsigned Count);
- bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
- bool TraverseRecordHelper(RecordDecl *D);
- bool TraverseCXXRecordHelper(CXXRecordDecl *D);
- bool TraverseDeclaratorHelper(DeclaratorDecl *D);
- bool TraverseDeclContextHelper(DeclContext *DC);
- bool TraverseFunctionHelper(FunctionDecl *D);
- bool TraverseVarHelper(VarDecl *D);
- bool TraverseOMPClause(OMPClause *C);
-#define OPENMP_CLAUSE(Name, Class) \
- bool Visit##Class(Class *C);
-#include "clang/Basic/OpenMPKinds.def"
- /// \brief Process clauses with list of variables.
- template <typename T>
- void VisitOMPClauseList(T *Node);
-
- typedef SmallVector<Stmt *, 16> StmtsTy;
- typedef SmallVector<StmtsTy *, 4> QueuesTy;
-
- QueuesTy Queues;
-
- class NewQueueRAII {
- RecursiveASTVisitor &RAV;
- public:
- NewQueueRAII(StmtsTy &queue, RecursiveASTVisitor &RAV) : RAV(RAV) {
- RAV.Queues.push_back(&queue);
- }
- ~NewQueueRAII() {
- RAV.Queues.pop_back();
- }
- };
-
- StmtsTy &getCurrentQueue() {
- assert(!Queues.empty() && "base TraverseStmt was never called?");
- return *Queues.back();
- }
-
-public:
- class StmtQueueAction {
- StmtsTy &CurrQueue;
- public:
- explicit StmtQueueAction(RecursiveASTVisitor &RAV)
- : CurrQueue(RAV.getCurrentQueue()) { }
-
- void queue(Stmt *S) {
- CurrQueue.push_back(S);
- }
- };
-};
-
-#define DISPATCH(NAME, CLASS, VAR) \
- return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR))
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
- if (!S)
- return true;
-
- StmtsTy Queue, StmtsToEnqueu;
- Queue.push_back(S);
- NewQueueRAII NQ(StmtsToEnqueu, *this);
-
- while (!Queue.empty()) {
- S = Queue.pop_back_val();
- if (!S)
- continue;
-
- StmtsToEnqueu.clear();
-
-#define DISPATCH_STMT(NAME, CLASS, VAR) \
- TRY_TO(Traverse##NAME(static_cast<CLASS*>(VAR))); break
-
- // If we have a binary expr, dispatch to the subcode of the binop. A smart
- // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
- // below.
- if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
- switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case BO_##NAME: DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
-
- BINOP_LIST()
-#undef OPERATOR
-#undef BINOP_LIST
-
-#define OPERATOR(NAME) \
- case BO_##NAME##Assign: \
- DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
-
- CAO_LIST()
-#undef OPERATOR
-#undef CAO_LIST
- }
- } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
- switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case UO_##NAME: DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
-
- UNARYOP_LIST()
-#undef OPERATOR
-#undef UNARYOP_LIST
- }
- } else {
-
- // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
- switch (S->getStmtClass()) {
- case Stmt::NoStmtClass: break;
-#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- case Stmt::CLASS##Class: DISPATCH_STMT(CLASS, CLASS, S);
-#include "clang/AST/StmtNodes.inc"
- }
- }
-
- for (SmallVectorImpl<Stmt *>::reverse_iterator
- RI = StmtsToEnqueu.rbegin(),
- RE = StmtsToEnqueu.rend(); RI != RE; ++RI)
- Queue.push_back(*RI);
- }
-
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
- if (T.isNull())
- return true;
-
- switch (T->getTypeClass()) {
-#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
- case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, \
- const_cast<Type*>(T.getTypePtr()));
-#include "clang/AST/TypeNodes.def"
- }
-
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
- if (TL.isNull())
- return true;
-
- switch (TL.getTypeLocClass()) {
-#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
- case TypeLoc::CLASS: \
- return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
-#include "clang/AST/TypeLocNodes.def"
- }
-
- return true;
-}
-
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
- if (!D)
- return true;
-
- // As a syntax visitor, we want to ignore declarations for
- // implicitly-defined declarations (ones not typed explicitly by the
- // user).
- if (D->isImplicit())
- return true;
-
- switch (D->getKind()) {
-#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
- case Decl::CLASS: DISPATCH(CLASS##Decl, CLASS##Decl, D);
-#include "clang/AST/DeclNodes.inc"
- }
-
- return true;
-}
-
-#undef DISPATCH
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
- NestedNameSpecifier *NNS) {
- if (!NNS)
- return true;
-
- if (NNS->getPrefix())
- TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
-
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- return true;
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
- }
-
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
- NestedNameSpecifierLoc NNS) {
- if (!NNS)
- return true;
-
- if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
- TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
-
- switch (NNS.getNestedNameSpecifier()->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- return true;
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
- break;
- }
-
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
- DeclarationNameInfo NameInfo) {
- switch (NameInfo.getName().getNameKind()) {
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
- TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
-
- break;
-
- case DeclarationName::Identifier:
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::CXXOperatorName:
- case DeclarationName::CXXLiteralOperatorName:
- case DeclarationName::CXXUsingDirective:
- break;
- }
-
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
- if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
- TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
- else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
- TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
-
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
- const TemplateArgument &Arg) {
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- case TemplateArgument::NullPtr:
- return true;
-
- case TemplateArgument::Type:
- return getDerived().TraverseType(Arg.getAsType());
-
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
-
- case TemplateArgument::Expression:
- return getDerived().TraverseStmt(Arg.getAsExpr());
-
- case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
- }
-
- return true;
-}
-
-// FIXME: no template name location?
-// FIXME: no source locations for a template argument pack?
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
- const TemplateArgumentLoc &ArgLoc) {
- const TemplateArgument &Arg = ArgLoc.getArgument();
-
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- case TemplateArgument::NullPtr:
- return true;
-
- case TemplateArgument::Type: {
- // FIXME: how can TSI ever be NULL?
- if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
- return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
- else
- return getDerived().TraverseType(Arg.getAsType());
- }
-
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- if (ArgLoc.getTemplateQualifierLoc())
- TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
- ArgLoc.getTemplateQualifierLoc()));
- return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
-
- case TemplateArgument::Expression:
- return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
-
- case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
- }
-
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
- const TemplateArgument *Args,
- unsigned NumArgs) {
- for (unsigned I = 0; I != NumArgs; ++I) {
- TRY_TO(TraverseTemplateArgument(Args[I]));
- }
-
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
- CXXCtorInitializer *Init) {
- if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-
- if (Init->isWritten())
- TRY_TO(TraverseStmt(Init->getInit()));
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr::Capture C){
- return true;
-}
-
-// ----------------- Type traversal -----------------
-
-// This macro makes available a variable T, the passed-in type.
-#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
- template<typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE (TYPE *T) { \
- TRY_TO(WalkUpFrom##TYPE (T)); \
- { CODE; } \
- return true; \
- }
-
-DEF_TRAVERSE_TYPE(BuiltinType, { })
-
-DEF_TRAVERSE_TYPE(ComplexType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
-
-DEF_TRAVERSE_TYPE(PointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
-
-DEF_TRAVERSE_TYPE(BlockPointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
-
-DEF_TRAVERSE_TYPE(LValueReferenceType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
-
-DEF_TRAVERSE_TYPE(RValueReferenceType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
-
-DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseType(QualType(T->getClass(), 0)));
- TRY_TO(TraverseType(T->getPointeeType()));
- })
-
-DEF_TRAVERSE_TYPE(DecayedType, {
- TRY_TO(TraverseType(T->getOriginalType()));
- })
-
-DEF_TRAVERSE_TYPE(ConstantArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
-
-DEF_TRAVERSE_TYPE(IncompleteArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
-
-DEF_TRAVERSE_TYPE(VariableArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- })
-
-DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- })
-
-DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- TRY_TO(TraverseType(T->getElementType()));
- })
-
-DEF_TRAVERSE_TYPE(VectorType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
-
-DEF_TRAVERSE_TYPE(ExtVectorType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
-
-DEF_TRAVERSE_TYPE(FunctionNoProtoType, {
- TRY_TO(TraverseType(T->getResultType()));
- })
-
-DEF_TRAVERSE_TYPE(FunctionProtoType, {
- TRY_TO(TraverseType(T->getResultType()));
-
- for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
- AEnd = T->arg_type_end();
- A != AEnd; ++A) {
- TRY_TO(TraverseType(*A));
- }
-
- for (FunctionProtoType::exception_iterator E = T->exception_begin(),
- EEnd = T->exception_end();
- E != EEnd; ++E) {
- TRY_TO(TraverseType(*E));
- }
- })
-
-DEF_TRAVERSE_TYPE(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPE(TypedefType, { })
-
-DEF_TRAVERSE_TYPE(TypeOfExprType, {
- TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
- })
-
-DEF_TRAVERSE_TYPE(TypeOfType, {
- TRY_TO(TraverseType(T->getUnderlyingType()));
- })
-
-DEF_TRAVERSE_TYPE(DecltypeType, {
- TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
- })
-
-DEF_TRAVERSE_TYPE(UnaryTransformType, {
- TRY_TO(TraverseType(T->getBaseType()));
- TRY_TO(TraverseType(T->getUnderlyingType()));
- })
-
-DEF_TRAVERSE_TYPE(AutoType, {
- TRY_TO(TraverseType(T->getDeducedType()));
- })
-
-DEF_TRAVERSE_TYPE(RecordType, { })
-DEF_TRAVERSE_TYPE(EnumType, { })
-DEF_TRAVERSE_TYPE(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, { })
-
-DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
- })
-
-DEF_TRAVERSE_TYPE(InjectedClassNameType, { })
-
-DEF_TRAVERSE_TYPE(AttributedType, {
- TRY_TO(TraverseType(T->getModifiedType()));
- })
-
-DEF_TRAVERSE_TYPE(ParenType, {
- TRY_TO(TraverseType(T->getInnerType()));
- })
-
-DEF_TRAVERSE_TYPE(ElaboratedType, {
- if (T->getQualifier()) {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- }
- TRY_TO(TraverseType(T->getNamedType()));
- })
-
-DEF_TRAVERSE_TYPE(DependentNameType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- })
-
-DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
- })
-
-DEF_TRAVERSE_TYPE(PackExpansionType, {
- TRY_TO(TraverseType(T->getPattern()));
- })
-
-DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })
-
-DEF_TRAVERSE_TYPE(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (T->getBaseType().getTypePtr() != T)
- TRY_TO(TraverseType(T->getBaseType()));
- })
-
-DEF_TRAVERSE_TYPE(ObjCObjectPointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
-
-DEF_TRAVERSE_TYPE(AtomicType, {
- TRY_TO(TraverseType(T->getValueType()));
- })
-
-#undef DEF_TRAVERSE_TYPE
-
-// ----------------- TypeLoc traversal -----------------
-
-// This macro makes available a variable TL, the passed-in TypeLoc.
-// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
-// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
-// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
-// continue to work.
-#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
- template<typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
- if (getDerived().shouldWalkTypesOfTypeLocs()) \
- TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE*>(TL.getTypePtr()))); \
- TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
- { CODE; } \
- return true; \
- }
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(
- QualifiedTypeLoc TL) {
- // Move this over to the 'main' typeloc tree. Note that this is a
- // move -- we pretend that we were really looking at the unqualified
- // typeloc all along -- rather than a recursion, so we don't follow
- // the normal CRTP plan of going through
- // getDerived().TraverseTypeLoc. If we did, we'd be traversing
- // twice for the same type (once as a QualifiedTypeLoc version of
- // the type, once as an UnqualifiedTypeLoc version of the type),
- // which in effect means we'd call VisitTypeLoc twice with the
- // 'same' type. This solves that problem, at the cost of never
- // seeing the qualified version of the type (unless the client
- // subclasses TraverseQualifiedTypeLoc themselves). It's not a
- // perfect solution. A perfect solution probably requires making
- // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
- // wrapper around Type* -- rather than being its own class in the
- // type hierarchy.
- return TraverseTypeLoc(TL.getUnqualifiedLoc());
-}
-
-DEF_TRAVERSE_TYPELOC(BuiltinType, { })
-
-// FIXME: ComplexTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(ComplexType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
-
-DEF_TRAVERSE_TYPELOC(PointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(BlockPointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(LValueReferenceType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(RValueReferenceType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
-
-// FIXME: location of base class?
-// We traverse this in the type case as well, but how is it not reached through
-// the pointee type?
-DEF_TRAVERSE_TYPELOC(MemberPointerType, {
- TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(DecayedType, {
- TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
- })
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
- // This isn't available for ArrayType, but is for the ArrayTypeLoc.
- TRY_TO(TraverseStmt(TL.getSizeExpr()));
- return true;
-}
-
-DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
-
-DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
-
-DEF_TRAVERSE_TYPELOC(VariableArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
-
-DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
-
-// FIXME: order? why not size expr first?
-// FIXME: base VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
- if (TL.getTypePtr()->getSizeExpr())
- TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
-
-// FIXME: VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(VectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
-
-// FIXME: size and attributes
-// FIXME: base VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(ExtVectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
-
-DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
- })
-
-// FIXME: location of exception specifications (attributes?)
-DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
-
- const FunctionProtoType *T = TL.getTypePtr();
-
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- if (TL.getArg(I)) {
- TRY_TO(TraverseDecl(TL.getArg(I)));
- } else if (I < T->getNumArgs()) {
- TRY_TO(TraverseType(T->getArgType(I)));
- }
- }
-
- for (FunctionProtoType::exception_iterator E = T->exception_begin(),
- EEnd = T->exception_end();
- E != EEnd; ++E) {
- TRY_TO(TraverseType(*E));
- }
- })
-
-DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPELOC(TypedefType, { })
-
-DEF_TRAVERSE_TYPELOC(TypeOfExprType, {
- TRY_TO(TraverseStmt(TL.getUnderlyingExpr()));
- })
-
-DEF_TRAVERSE_TYPELOC(TypeOfType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
- })
-
-// FIXME: location of underlying expr
-DEF_TRAVERSE_TYPELOC(DecltypeType, {
- TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
- })
-
-DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(AutoType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
- })
-
-DEF_TRAVERSE_TYPELOC(RecordType, { })
-DEF_TRAVERSE_TYPELOC(EnumType, { })
-DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, { })
-
-// FIXME: use the loc for the template name?
-DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
-
-DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { })
-
-DEF_TRAVERSE_TYPELOC(ParenType, {
- TRY_TO(TraverseTypeLoc(TL.getInnerLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(AttributedType, {
- TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(ElaboratedType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
- TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(DependentNameType, {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
-
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
-
-DEF_TRAVERSE_TYPELOC(PackExpansionType, {
- TRY_TO(TraverseTypeLoc(TL.getPatternLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { })
-
-DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
- TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
-
-DEF_TRAVERSE_TYPELOC(AtomicType, {
- TRY_TO(TraverseTypeLoc(TL.getValueLoc()));
- })
-
-#undef DEF_TRAVERSE_TYPELOC
-
-// ----------------- Decl traversal -----------------
-//
-// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
-// the children that come from the DeclContext associated with it.
-// Therefore each Traverse* only needs to worry about children other
-// than those.
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
- if (!DC)
- return true;
-
- for (DeclContext::decl_iterator Child = DC->decls_begin(),
- ChildEnd = DC->decls_end();
- Child != ChildEnd; ++Child) {
- // BlockDecls and CapturedDecls are traversed through BlockExprs and
- // CapturedStmts respectively.
- if (!isa<BlockDecl>(*Child) && !isa<CapturedDecl>(*Child))
- TRY_TO(TraverseDecl(*Child));
- }
-
- return true;
-}
-
-// This macro makes available a variable D, the passed-in decl.
-#define DEF_TRAVERSE_DECL(DECL, CODE) \
-template<typename Derived> \
-bool RecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) { \
- TRY_TO(WalkUpFrom##DECL (D)); \
- { CODE; } \
- TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
- return true; \
-}
-
-DEF_TRAVERSE_DECL(AccessSpecDecl, { })
-
-DEF_TRAVERSE_DECL(BlockDecl, {
- if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
- TRY_TO(TraverseStmt(D->getBody()));
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
- })
-
-DEF_TRAVERSE_DECL(CapturedDecl, {
- TRY_TO(TraverseStmt(D->getBody()));
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
- })
-
-DEF_TRAVERSE_DECL(EmptyDecl, { })
-
-DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
- TRY_TO(TraverseStmt(D->getAsmString()));
- })
-
-DEF_TRAVERSE_DECL(ImportDecl, { })
-
-DEF_TRAVERSE_DECL(FriendDecl, {
- // Friend is either decl or a type.
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
- })
-
-DEF_TRAVERSE_DECL(FriendTemplateDecl, {
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
- for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
- TemplateParameterList *TPL = D->getTemplateParameterList(I);
- for (TemplateParameterList::iterator ITPL = TPL->begin(),
- ETPL = TPL->end();
- ITPL != ETPL; ++ITPL) {
- TRY_TO(TraverseDecl(*ITPL));
- }
- }
- })
-
-DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
- TRY_TO(TraverseDecl(D->getSpecialization()));
- })
-
-DEF_TRAVERSE_DECL(LinkageSpecDecl, { })
-
-DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {
- // FIXME: implement this
- })
-
-DEF_TRAVERSE_DECL(StaticAssertDecl, {
- TRY_TO(TraverseStmt(D->getAssertExpr()));
- TRY_TO(TraverseStmt(D->getMessage()));
- })
-
-DEF_TRAVERSE_DECL(TranslationUnitDecl, {
- // Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
-
-DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
- // We shouldn't traverse an aliased namespace, since it will be
- // defined (and, therefore, traversed) somewhere else.
- //
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
- })
-
-DEF_TRAVERSE_DECL(LabelDecl, {
- // There is no code in a LabelDecl.
-})
-
-
-DEF_TRAVERSE_DECL(NamespaceDecl, {
- // Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
-
-DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {
- // FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
- // FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {
- // FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCImplementationDecl, {
- // FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
- // FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
- // FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCMethodDecl, {
- if (D->getResultTypeSourceInfo()) {
- TRY_TO(TraverseTypeLoc(D->getResultTypeSourceInfo()->getTypeLoc()));
- }
- for (ObjCMethodDecl::param_iterator
- I = D->param_begin(), E = D->param_end(); I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
- }
- if (D->isThisDeclarationADefinition()) {
- TRY_TO(TraverseStmt(D->getBody()));
- }
- return true;
- })
-
-DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
- // FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(UsingDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
- })
-
-DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- })
-
-DEF_TRAVERSE_DECL(UsingShadowDecl, { })
-
-DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
- for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
- E = D->varlist_end();
- I != E; ++I) {
- TRY_TO(TraverseStmt(*I));
- }
- })
-
-// A helper method for TemplateDecl's children.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
- TemplateParameterList *TPL) {
- if (TPL) {
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
- }
- }
- return true;
-}
-
-// A helper method for traversing the implicit instantiations of a
-// class template.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseClassInstantiations(
- ClassTemplateDecl *D) {
- ClassTemplateDecl::spec_iterator end = D->spec_end();
- for (ClassTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) {
- ClassTemplateSpecializationDecl* SD = *it;
-
- switch (SD->getSpecializationKind()) {
- // Visit the implicit instantiations with the requested pattern.
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- TRY_TO(TraverseDecl(SD));
- break;
-
- // We don't need to do anything on an explicit instantiation
- // or explicit specialization because there will be an explicit
- // node for it elsewhere.
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- case TSK_ExplicitSpecialization:
- break;
- }
- }
-
- return true;
-}
-
-DEF_TRAVERSE_DECL(ClassTemplateDecl, {
- CXXRecordDecl* TempDecl = D->getTemplatedDecl();
- TRY_TO(TraverseDecl(TempDecl));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-
- // By default, we do not traverse the instantiations of
- // class templates since they do not appear in the user code. The
- // following code optionally traverses them.
- //
- // We only traverse the class instantiations when we see the canonical
- // declaration of the template, to ensure we only visit them once.
- if (getDerived().shouldVisitTemplateInstantiations() &&
- D == D->getCanonicalDecl())
- TRY_TO(TraverseClassInstantiations(D));
-
- // Note that getInstantiatedFromMemberTemplate() is just a link
- // from a template instantiation back to the template from which
- // it was instantiated, and thus should not be traversed.
- })
-
-// A helper method for traversing the implicit instantiations of a
-// class template.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseVariableInstantiations(
- VarTemplateDecl *D) {
- VarTemplateDecl::spec_iterator end = D->spec_end();
- for (VarTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) {
- VarTemplateSpecializationDecl *SD = *it;
-
- switch (SD->getSpecializationKind()) {
- // Visit the implicit instantiations with the requested pattern.
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- TRY_TO(TraverseDecl(SD));
- break;
-
- // We don't need to do anything on an explicit instantiation
- // or explicit specialization because there will be an explicit
- // node for it elsewhere.
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- case TSK_ExplicitSpecialization:
- break;
- }
- }
-
- return true;
-}
-
-DEF_TRAVERSE_DECL(
- VarTemplateDecl,
- {
- VarDecl *TempDecl = D->getTemplatedDecl();
- TRY_TO(TraverseDecl(TempDecl));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-
- // By default, we do not traverse the instantiations of
- // variable templates since they do not appear in the user code. The
- // following code optionally traverses them.
- //
- // We only traverse the variable instantiations when we see the canonical
- // declaration of the template, to ensure we only visit them once.
- if (getDerived().shouldVisitTemplateInstantiations() &&
- D == D->getCanonicalDecl())
- TRY_TO(TraverseVariableInstantiations(D));
-
- // Note that getInstantiatedFromMemberTemplate() is just a link
- // from a template instantiation back to the template from which
- // it was instantiated, and thus should not be traversed.
-})
-
-// A helper method for traversing the instantiations of a
-// function while skipping its specializations.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations(
- FunctionTemplateDecl *D) {
- FunctionTemplateDecl::spec_iterator end = D->spec_end();
- for (FunctionTemplateDecl::spec_iterator it = D->spec_begin(); it != end;
- ++it) {
- FunctionDecl* FD = *it;
- switch (FD->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- // We don't know what kind of FunctionDecl this is.
- TRY_TO(TraverseDecl(FD));
- break;
-
- // No need to visit explicit instantiations, we'll find the node
- // eventually.
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- break;
-
- case TSK_ExplicitSpecialization:
- break;
- }
- }
-
- return true;
-}
-
-DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-
- // By default, we do not traverse the instantiations of
- // function templates since they do not appear in the user code. The
- // following code optionally traverses them.
- //
- // We only traverse the function instantiations when we see the canonical
- // declaration of the template, to ensure we only visit them once.
- if (getDerived().shouldVisitTemplateInstantiations() &&
- D == D->getCanonicalDecl())
- TRY_TO(TraverseFunctionInstantiations(D));
- })
-
-DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
- // D is the "T" in something like
- // template <template <typename> class T> class container { };
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- if (D->hasDefaultArgument()) {
- TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
- }
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- })
-
-DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
- // D is the "T" in something like "template<typename T> class vector;"
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
- if (D->hasDefaultArgument())
- TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_DECL(TypedefDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the typedef, not something that was written in the
- // source.
- })
-
-DEF_TRAVERSE_DECL(TypeAliasDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type alias, not something that was written in the
- // source.
- })
-
-DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- })
-
-DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
- // A dependent using declaration which was marked with 'typename'.
- // template<class T> class A : public B<T> { using typename B<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type, not something that was written in the
- // source.
- })
-
-DEF_TRAVERSE_DECL(EnumDecl, {
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // The enumerators are already traversed by
- // decls_begin()/decls_end().
- })
-
-
-// Helper methods for RecordDecl and its children.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(
- RecordDecl *D) {
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type, not something that was written in the source.
-
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(
- CXXRecordDecl *D) {
- if (!TraverseRecordHelper(D))
- return false;
- if (D->isCompleteDefinition()) {
- for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
- E = D->bases_end();
- I != E; ++I) {
- TRY_TO(TraverseTypeLoc(I->getTypeSourceInfo()->getTypeLoc()));
- }
- // We don't traverse the friends or the conversions, as they are
- // already in decls_begin()/decls_end().
- }
- return true;
-}
-
-DEF_TRAVERSE_DECL(RecordDecl, {
- TRY_TO(TraverseRecordHelper(D));
- })
-
-DEF_TRAVERSE_DECL(CXXRecordDecl, {
- TRY_TO(TraverseCXXRecordHelper(D));
- })
-
-DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, {
- // For implicit instantiations ("set<int> x;"), we don't want to
- // recurse at all, since the instatiated class isn't written in
- // the source code anywhere. (Note the instatiated *type* --
- // set<int> -- is written, and will still get a callback of
- // TemplateSpecializationType). For explicit instantiations
- // ("template set<int>;"), we do need a callback, since this
- // is the only callback that's made for this instantiation.
- // We use getTypeAsWritten() to distinguish.
- if (TypeSourceInfo *TSI = D->getTypeAsWritten())
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
-
- if (!getDerived().shouldVisitTemplateInstantiations() &&
- D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
- // Returning from here skips traversing the
- // declaration context of the ClassTemplateSpecializationDecl
- // (embedded in the DEF_TRAVERSE_DECL() macro)
- // which contains the instantiated members of the class.
- return true;
- })
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
- const TemplateArgumentLoc *TAL, unsigned Count) {
- for (unsigned I = 0; I < Count; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
- }
- return true;
-}
-
-DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, {
- // The partial specialization.
- if (TemplateParameterList *TPL = D->getTemplateParameters()) {
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
- }
- }
- // The args that remains unspecialized.
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- D->getTemplateArgsAsWritten()->getTemplateArgs(),
- D->getTemplateArgsAsWritten()->NumTemplateArgs));
-
- // Don't need the ClassTemplatePartialSpecializationHelper, even
- // though that's our parent class -- we already visit all the
- // template args here.
- TRY_TO(TraverseCXXRecordHelper(D));
-
- // Instantiations will have been visited with the primary template.
- })
-
-DEF_TRAVERSE_DECL(EnumConstantDecl, {
- TRY_TO(TraverseStmt(D->getInitExpr()));
- })
-
-DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
- // Like UnresolvedUsingTypenameDecl, but without the 'typename':
- // template <class T> Class A : public Base<T> { using Base<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
- })
-
-DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- if (D->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- else
- TRY_TO(TraverseType(D->getType()));
- return true;
-}
-
-DEF_TRAVERSE_DECL(FieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- else if (D->hasInClassInitializer())
- TRY_TO(TraverseStmt(D->getInClassInitializer()));
- })
-
-DEF_TRAVERSE_DECL(MSPropertyDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- })
-
-DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
- })
-
-DEF_TRAVERSE_DECL(ObjCIvarDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
- })
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-
- // If we're an explicit template specialization, iterate over the
- // template args that were explicitly specified. If we were doing
- // this in typing order, we'd do it between the return type and
- // the function args, but both are handled by the FunctionTypeLoc
- // above, so we have to choose one side. I've decided to do before.
- if (const FunctionTemplateSpecializationInfo *FTSI =
- D->getTemplateSpecializationInfo()) {
- if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
- FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
- // A specialization might not have explicit template arguments if it has
- // a templated return type and concrete arguments.
- if (const ASTTemplateArgumentListInfo *TALI =
- FTSI->TemplateArgumentsAsWritten) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
- TALI->NumTemplateArgs));
- }
- }
- }
-
- // Visit the function type itself, which can be either
- // FunctionNoProtoType or FunctionProtoType, or a typedef. This
- // also covers the return type and the function parameters,
- // including exception specifications.
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
-
- if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
- // Constructor initializers.
- for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),
- E = Ctor->init_end();
- I != E; ++I) {
- TRY_TO(TraverseConstructorInitializer(*I));
- }
- }
-
- if (D->isThisDeclarationADefinition()) {
- TRY_TO(TraverseStmt(D->getBody())); // Function body.
- }
- return true;
-}
-
-DEF_TRAVERSE_DECL(FunctionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
-
-DEF_TRAVERSE_DECL(CXXMethodDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
-
-DEF_TRAVERSE_DECL(CXXConstructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
-
-// CXXConversionDecl is the declaration of a type conversion operator.
-// It's not a cast expression.
-DEF_TRAVERSE_DECL(CXXConversionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
-
-DEF_TRAVERSE_DECL(CXXDestructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
- TRY_TO(TraverseDeclaratorHelper(D));
- // Default params are taken care of when we traverse the ParmVarDecl.
- if (!isa<ParmVarDecl>(D))
- TRY_TO(TraverseStmt(D->getInit()));
- return true;
-}
-
-DEF_TRAVERSE_DECL(VarDecl, {
- TRY_TO(TraverseVarHelper(D));
- })
-
-DEF_TRAVERSE_DECL(VarTemplateSpecializationDecl, {
- // For implicit instantiations, we don't want to
- // recurse at all, since the instatiated class isn't written in
- // the source code anywhere.
- if (TypeSourceInfo *TSI = D->getTypeAsWritten())
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
-
- if (!getDerived().shouldVisitTemplateInstantiations() &&
- D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
- // Returning from here skips traversing the
- // declaration context of the VarTemplateSpecializationDecl
- // (embedded in the DEF_TRAVERSE_DECL() macro).
- return true;
-})
-
-DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl,
- {
- // The partial specialization.
- if (TemplateParameterList *TPL = D->getTemplateParameters()) {
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
- }
- }
- // The args that remains unspecialized.
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- D->getTemplateArgsAsWritten()->getTemplateArgs(),
- D->getTemplateArgsAsWritten()->NumTemplateArgs));
-
- // Don't need the VarTemplatePartialSpecializationHelper, even
- // though that's our parent class -- we already visit all the
- // template args here.
- TRY_TO(TraverseVarHelper(D));
-
- // Instantiations will have been visited with the primary
- // template.
-})
-
-DEF_TRAVERSE_DECL(ImplicitParamDecl, {
- TRY_TO(TraverseVarHelper(D));
- })
-
-DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
- // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
- TRY_TO(TraverseDeclaratorHelper(D));
- TRY_TO(TraverseStmt(D->getDefaultArgument()));
- })
-
-DEF_TRAVERSE_DECL(ParmVarDecl, {
- TRY_TO(TraverseVarHelper(D));
-
- if (D->hasDefaultArg() &&
- D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
-
- if (D->hasDefaultArg() &&
- !D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getDefaultArg()));
- })
-
-#undef DEF_TRAVERSE_DECL
-
-// ----------------- Stmt traversal -----------------
-//
-// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
-// over the children defined in children() (every stmt defines these,
-// though sometimes the range is empty). Each individual Traverse*
-// method only needs to worry about children other than those. To see
-// what children() does for a given class, see, e.g.,
-// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
-
-// This macro makes available a variable S, the passed-in stmt.
-#define DEF_TRAVERSE_STMT(STMT, CODE) \
-template<typename Derived> \
-bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) { \
- TRY_TO(WalkUpFrom##STMT(S)); \
- StmtQueueAction StmtQueue(*this); \
- { CODE; } \
- for (Stmt::child_range range = S->children(); range; ++range) { \
- StmtQueue.queue(*range); \
- } \
- return true; \
-}
-
-DEF_TRAVERSE_STMT(GCCAsmStmt, {
- StmtQueue.queue(S->getAsmString());
- for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
- StmtQueue.queue(S->getInputConstraintLiteral(I));
- }
- for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
- StmtQueue.queue(S->getOutputConstraintLiteral(I));
- }
- for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
- StmtQueue.queue(S->getClobberStringLiteral(I));
- }
- // children() iterates over inputExpr and outputExpr.
- })
-
-DEF_TRAVERSE_STMT(MSAsmStmt, {
- // FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
- // added this needs to be implemented.
- })
-
-DEF_TRAVERSE_STMT(CXXCatchStmt, {
- TRY_TO(TraverseDecl(S->getExceptionDecl()));
- // children() iterates over the handler block.
- })
-
-DEF_TRAVERSE_STMT(DeclStmt, {
- for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
- }
- // Suppress the default iteration over children() by
- // returning. Here's why: A DeclStmt looks like 'type var [=
- // initializer]'. The decls above already traverse over the
- // initializers, so we don't have to do it again (which
- // children() would do).
- return true;
- })
-
-
-// These non-expr stmts (most of them), do not need any action except
-// iterating over the children.
-DEF_TRAVERSE_STMT(BreakStmt, { })
-DEF_TRAVERSE_STMT(CXXTryStmt, { })
-DEF_TRAVERSE_STMT(CaseStmt, { })
-DEF_TRAVERSE_STMT(CompoundStmt, { })
-DEF_TRAVERSE_STMT(ContinueStmt, { })
-DEF_TRAVERSE_STMT(DefaultStmt, { })
-DEF_TRAVERSE_STMT(DoStmt, { })
-DEF_TRAVERSE_STMT(ForStmt, { })
-DEF_TRAVERSE_STMT(GotoStmt, { })
-DEF_TRAVERSE_STMT(IfStmt, { })
-DEF_TRAVERSE_STMT(IndirectGotoStmt, { })
-DEF_TRAVERSE_STMT(LabelStmt, { })
-DEF_TRAVERSE_STMT(AttributedStmt, { })
-DEF_TRAVERSE_STMT(NullStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtCatchStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
-DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
-DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, { })
-DEF_TRAVERSE_STMT(CXXForRangeStmt, { })
-DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
-})
-DEF_TRAVERSE_STMT(ReturnStmt, { })
-DEF_TRAVERSE_STMT(SwitchStmt, { })
-DEF_TRAVERSE_STMT(WhileStmt, { })
-
-DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getTemplateArgs(), S->getNumTemplateArgs()));
- }
- })
-
-DEF_TRAVERSE_STMT(DeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getTemplateArgs(), S->getNumTemplateArgs()));
- })
-
-DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getExplicitTemplateArgs().getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
- })
-
-DEF_TRAVERSE_STMT(MemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getTemplateArgs(), S->getNumTemplateArgs()));
- })
-
-DEF_TRAVERSE_STMT(ImplicitCastExpr, {
- // We don't traverse the cast type, as it's not written in the
- // source code.
- })
-
-DEF_TRAVERSE_STMT(CStyleCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(CXXConstCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
-
-// InitListExpr is a tricky one, because we want to do all our work on
-// the syntactic form of the listexpr, but this method takes the
-// semantic form by default. We can't use the macro helper because it
-// calls WalkUp*() on the semantic form, before our code can convert
-// to the syntactic form.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
- if (InitListExpr *Syn = S->getSyntacticForm())
- S = Syn;
- TRY_TO(WalkUpFromInitListExpr(S));
- StmtQueueAction StmtQueue(*this);
- // All we need are the default actions. FIXME: use a helper function.
- for (Stmt::child_range range = S->children(); range; ++range) {
- StmtQueue.queue(*range);
- }
- return true;
-}
-
-// GenericSelectionExpr is a special case because the types and expressions
-// are interleaved. We also need to watch out for null types (default
-// generic associations).
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::
-TraverseGenericSelectionExpr(GenericSelectionExpr *S) {
- TRY_TO(WalkUpFromGenericSelectionExpr(S));
- StmtQueueAction StmtQueue(*this);
- StmtQueue.queue(S->getControllingExpr());
- for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
- if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
- TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
- StmtQueue.queue(S->getAssocExpr(i));
- }
- return true;
-}
-
-// PseudoObjectExpr is a special case because of the wierdness with
-// syntactic expressions and opaque values.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::
-TraversePseudoObjectExpr(PseudoObjectExpr *S) {
- TRY_TO(WalkUpFromPseudoObjectExpr(S));
- StmtQueueAction StmtQueue(*this);
- StmtQueue.queue(S->getSyntacticForm());
- for (PseudoObjectExpr::semantics_iterator
- i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i) {
- Expr *sub = *i;
- if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
- sub = OVE->getSourceExpr();
- StmtQueue.queue(sub);
- }
- return true;
-}
-
-DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
- // This is called for code like 'return T()' where T is a built-in
- // (i.e. non-class) type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(CXXNewExpr, {
- // The child-iterator will pick up the other arguments.
- TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(OffsetOfExpr, {
- // The child-iterator will pick up the expression representing
- // the field.
- // FIMXE: for code like offsetof(Foo, a.b.c), should we get
- // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isArgumentType())
- TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(CXXTypeidExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(CXXUuidofExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, {
- TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(BinaryTypeTraitExpr, {
- TRY_TO(TraverseTypeLoc(S->getLhsTypeSourceInfo()->getTypeLoc()));
- TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(TypeTraitExpr, {
- for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
- TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
- TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(ExpressionTraitExpr, {
- StmtQueue.queue(S->getQueriedExpression());
- })
-
-DEF_TRAVERSE_STMT(VAArgExpr, {
- // The child-iterator will pick up the expression argument.
- TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
- // This is called for code like 'return T()' where T is a class type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
-
-// Walk only the visible parts of lambda expressions.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
- TRY_TO(WalkUpFromLambdaExpr(S));
-
- for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
- CEnd = S->explicit_capture_end();
- C != CEnd; ++C) {
- TRY_TO(TraverseLambdaCapture(*C));
- }
-
- if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
- // Visit the whole type.
- TRY_TO(TraverseTypeLoc(TL));
- } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
- if (S->hasExplicitParameters()) {
- // Visit parameters.
- for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) {
- TRY_TO(TraverseDecl(Proto.getArg(I)));
- }
- } else {
- TRY_TO(TraverseTypeLoc(Proto.getResultLoc()));
- }
- }
- }
-
- StmtQueueAction StmtQueue(*this);
- StmtQueue.queue(S->getBody());
- return true;
-}
-
-DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
- // This is called for code like 'T()', where T is a template argument.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
-
-// These expressions all might take explicit template arguments.
-// We traverse those if so. FIXME: implement these.
-DEF_TRAVERSE_STMT(CXXConstructExpr, { })
-DEF_TRAVERSE_STMT(CallExpr, { })
-DEF_TRAVERSE_STMT(CXXMemberCallExpr, { })
-
-// These exprs (most of them), do not need any action except iterating
-// over the children.
-DEF_TRAVERSE_STMT(AddrLabelExpr, { })
-DEF_TRAVERSE_STMT(ArraySubscriptExpr, { })
-DEF_TRAVERSE_STMT(BlockExpr, {
- TRY_TO(TraverseDecl(S->getBlockDecl()));
- return true; // no child statements to loop through.
-})
-DEF_TRAVERSE_STMT(ChooseExpr, { })
-DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
-DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
-DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { })
-DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
-DEF_TRAVERSE_STMT(ExprWithCleanups, { })
-DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { })
-DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
- TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
- if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
- TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(CXXThisExpr, { })
-DEF_TRAVERSE_STMT(CXXThrowExpr, { })
-DEF_TRAVERSE_STMT(UserDefinedLiteral, { })
-DEF_TRAVERSE_STMT(DesignatedInitExpr, { })
-DEF_TRAVERSE_STMT(ExtVectorElementExpr, { })
-DEF_TRAVERSE_STMT(GNUNullExpr, { })
-DEF_TRAVERSE_STMT(ImplicitValueInitExpr, { })
-DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, { })
-DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
- if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ObjCIsaExpr, { })
-DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCMessageExpr, {
- if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
-DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
-DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, { })
-DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ParenExpr, { })
-DEF_TRAVERSE_STMT(ParenListExpr, { })
-DEF_TRAVERSE_STMT(PredefinedExpr, { })
-DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
-DEF_TRAVERSE_STMT(ConvertVectorExpr, { })
-DEF_TRAVERSE_STMT(StmtExpr, { })
-DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
-})
-
-DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
-})
-
-DEF_TRAVERSE_STMT(MSPropertyRefExpr, {})
-DEF_TRAVERSE_STMT(SEHTryStmt, {})
-DEF_TRAVERSE_STMT(SEHExceptStmt, {})
-DEF_TRAVERSE_STMT(SEHFinallyStmt,{})
-DEF_TRAVERSE_STMT(CapturedStmt, {
- TRY_TO(TraverseDecl(S->getCapturedDecl()));
-})
-
-DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
-DEF_TRAVERSE_STMT(OpaqueValueExpr, { })
-DEF_TRAVERSE_STMT(CUDAKernelCallExpr, { })
-
-// These operators (all of them) do not need any action except
-// iterating over the children.
-DEF_TRAVERSE_STMT(BinaryConditionalOperator, { })
-DEF_TRAVERSE_STMT(ConditionalOperator, { })
-DEF_TRAVERSE_STMT(UnaryOperator, { })
-DEF_TRAVERSE_STMT(BinaryOperator, { })
-DEF_TRAVERSE_STMT(CompoundAssignOperator, { })
-DEF_TRAVERSE_STMT(CXXNoexceptExpr, { })
-DEF_TRAVERSE_STMT(PackExpansionExpr, { })
-DEF_TRAVERSE_STMT(SizeOfPackExpr, { })
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { })
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { })
-DEF_TRAVERSE_STMT(FunctionParmPackExpr, { })
-DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { })
-DEF_TRAVERSE_STMT(AtomicExpr, { })
-
-// These literals (all of them) do not need any action.
-DEF_TRAVERSE_STMT(IntegerLiteral, { })
-DEF_TRAVERSE_STMT(CharacterLiteral, { })
-DEF_TRAVERSE_STMT(FloatingLiteral, { })
-DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
-DEF_TRAVERSE_STMT(StringLiteral, { })
-DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
-DEF_TRAVERSE_STMT(ObjCBoxedExpr, { })
-DEF_TRAVERSE_STMT(ObjCArrayLiteral, { })
-DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { })
-
-// Traverse OpenCL: AsType, Convert.
-DEF_TRAVERSE_STMT(AsTypeExpr, { })
-
-// OpenMP directives.
-DEF_TRAVERSE_STMT(OMPParallelDirective, {
- ArrayRef<OMPClause *> Clauses = S->clauses();
- for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
- I != E; ++I)
- if (!TraverseOMPClause(*I)) return false;
-})
-
-// OpenMP clauses.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
- if (!C) return true;
- switch (C->getClauseKind()) {
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_##Name: \
- return getDerived().Visit##Class(static_cast<Class*>(C));
-#include "clang/Basic/OpenMPKinds.def"
- default: break;
- }
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
- return true;
-}
-
-template<typename Derived>
-template<typename T>
-void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
- for (typename T::varlist_iterator I = Node->varlist_begin(),
- E = Node->varlist_end();
- I != E; ++I)
- TraverseStmt(*I);
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
- VisitOMPClauseList(C);
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
- OMPFirstprivateClause *C) {
- VisitOMPClauseList(C);
- return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
- VisitOMPClauseList(C);
- return true;
-}
-
-// FIXME: look at the following tricky-seeming exprs to see if we
-// need to recurse on anything. These are ones that have methods
-// returning decls or qualtypes or nestednamespecifier -- though I'm
-// not sure if they own them -- or just seemed very complicated, or
-// had lots of sub-types to explore.
-//
-// VisitOverloadExpr and its children: recurse on template args? etc?
-
-// FIXME: go through all the stmts and exprs again, and see which of them
-// create new types, and recurse on the types (TypeLocs?) of those.
-// Candidates:
-//
-// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
-// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
-// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
-// Every class that has getQualifier.
-
-#undef DEF_TRAVERSE_STMT
-
-#undef TRY_TO
-
-} // end namespace cxindex
-} // end namespace clang
-
-#endif // LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 9bf26c9..37b6159 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -64,6 +64,8 @@
clang_Type_getClassType
clang_Type_getSizeOf
clang_Type_getOffsetOf
+clang_Type_getNumTemplateArguments
+clang_Type_getTemplateArgumentAsType
clang_Type_getCXXRefQualifier
clang_VerbatimBlockLineComment_getText
clang_VerbatimLineComment_getText
@@ -87,6 +89,7 @@
clang_createCXCursorSet
clang_createIndex
clang_createTranslationUnit
+clang_createTranslationUnit2
clang_createTranslationUnitFromSourceFile
clang_defaultCodeCompleteOptions
clang_defaultDiagnosticDisplayOptions
@@ -101,6 +104,7 @@
clang_disposeIndex
clang_disposeOverriddenCursors
clang_disposeCXPlatformAvailability
+clang_disposeSourceRangeList
clang_disposeString
clang_disposeTokens
clang_disposeTranslationUnit
@@ -118,6 +122,7 @@
clang_getArgType
clang_getArrayElementType
clang_getArraySize
+clang_getBuildSessionTimestamp
clang_getCString
clang_getCXTUResourceUsage
clang_getCXXAccessSpecifier
@@ -207,6 +212,7 @@
clang_getRemappings
clang_getRemappingsFromFileList
clang_getResultType
+clang_getSkippedRanges
clang_getSpecializedCursorTemplate
clang_getSpellingLocation
clang_getTUResourceUsageName
@@ -259,6 +265,7 @@
clang_Location_isInSystemHeader
clang_Location_isFromMainFile
clang_parseTranslationUnit
+clang_parseTranslationUnit2
clang_remap_dispose
clang_remap_getFilenames
clang_remap_getNumFiles
@@ -279,3 +286,13 @@
clang_CompileCommand_getArg
clang_visitChildren
clang_visitChildrenWithBlock
+clang_ModuleMapDescriptor_create
+clang_ModuleMapDescriptor_dispose
+clang_ModuleMapDescriptor_setFrameworkModuleName
+clang_ModuleMapDescriptor_setUmbrellaHeader
+clang_ModuleMapDescriptor_writeToBuffer
+clang_VirtualFileOverlay_addFileMapping
+clang_VirtualFileOverlay_create
+clang_VirtualFileOverlay_dispose
+clang_VirtualFileOverlay_setCaseSensitivity
+clang_VirtualFileOverlay_writeToBuffer
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index b463ec0..b5445e6 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -29,8 +29,9 @@
my $Clang;
my $DefaultCCompiler;
my $DefaultCXXCompiler;
+my $IsCXX;
-if (`uname -a` =~ m/Darwin/) {
+if (`uname -a` =~ m/Darwin/) {
$DefaultCCompiler = 'clang';
$DefaultCXXCompiler = 'clang++';
} else {
@@ -40,17 +41,21 @@
if ($FindBin::Script =~ /c\+\+-analyzer/) {
$Compiler = $ENV{'CCC_CXX'};
- if (!defined $Compiler) { $Compiler = $DefaultCXXCompiler; }
-
+ if (!defined $Compiler || ! -x $Compiler) { $Compiler = $DefaultCXXCompiler; }
+
$Clang = $ENV{'CLANG_CXX'};
- if (!defined $Clang) { $Clang = 'clang++'; }
+ if (!defined $Clang || ! -x $Clang) { $Clang = 'clang++'; }
+
+ $IsCXX = 1
}
else {
$Compiler = $ENV{'CCC_CC'};
- if (!defined $Compiler) { $Compiler = $DefaultCCompiler; }
+ if (!defined $Compiler || ! -x $Compiler) { $Compiler = $DefaultCCompiler; }
$Clang = $ENV{'CLANG'};
- if (!defined $Clang) { $Clang = 'clang'; }
+ if (!defined $Clang || ! -x $Clang) { $Clang = 'clang'; }
+
+ $IsCXX = 0
}
##===----------------------------------------------------------------------===##
@@ -64,7 +69,7 @@
my $ResultFile;
# Remove any stale files at exit.
-END {
+END {
if (defined $ResultFile && -z $ResultFile) {
`rm -f $ResultFile`;
}
@@ -95,7 +100,7 @@
my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
my $Dir = "$HtmlDir/failures";
mkpath $Dir;
-
+
my $prefix = "clang_crash";
if ($ErrorType eq $ParserRejects) {
$prefix = "clang_parser_rejects";
@@ -113,7 +118,7 @@
DIR => $Dir);
system $Clang, @$Args, "-E", "-o", $PPFile;
close ($PPH);
-
+
# Create the info file.
open (OUT, ">", "$PPFile.info.txt") or die "Cannot open $PPFile.info.txt\n";
print OUT abs_path($file), "\n";
@@ -133,7 +138,7 @@
sub GetCCArgs {
my $mode = shift;
my $Args = shift;
-
+
pipe (FROM_CHILD, TO_PARENT);
my $pid = fork();
if ($pid == 0) {
@@ -141,21 +146,20 @@
open(STDOUT,">&", \*TO_PARENT);
open(STDERR,">&", \*TO_PARENT);
exec $Clang, "-###", $mode, @$Args;
- }
+ }
close(TO_PARENT);
my $line;
while (<FROM_CHILD>) {
- next if (!/-cc1/);
+ next if (!/\s"?-cc1"?\s/);
$line = $_;
}
waitpid($pid,0);
close(FROM_CHILD);
-
+
die "could not find clang line\n" if (!defined $line);
- # Strip the newline and initial whitspace
- chomp $line;
- $line =~ s/^\s+//;
+ # Strip leading and trailing whitespace characters.
+ $line =~ s/^\s+|\s+$//g;
my @items = quotewords('\s+', 0, $line);
my $cmd = shift @items;
die "cannot find 'clang' in 'clang' command\n" if (!($cmd =~ /clang/));
@@ -203,7 +207,7 @@
}
# Display Ubiviz graph?
- if (defined $ENV{'CCC_UBI'}) {
+ if (defined $ENV{'CCC_UBI'}) {
push @Args, "-Xclang", "-analyzer-viz-egraph-ubigraph";
}
@@ -224,7 +228,7 @@
}
if ($Verbose == 1) {
# We MUST print to stderr. Some clients use the stdout output of
- # gcc for various purposes.
+ # gcc for various purposes.
print STDERR join(' ', @PrintArgs);
print STDERR "\n";
}
@@ -235,7 +239,7 @@
# Capture the STDERR of clang and send it to a temporary file.
# Capture the STDOUT of clang and reroute it to ccc-analyzer's STDERR.
# We save the output file in the 'crashes' directory if clang encounters
- # any problems with the file.
+ # any problems with the file.
pipe (FROM_CHILD, TO_PARENT);
my $pid = fork();
if ($pid == 0) {
@@ -247,7 +251,7 @@
close TO_PARENT;
my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir);
-
+
while (<FROM_CHILD>) {
print $ofh $_;
print STDERR $_;
@@ -289,15 +293,15 @@
# Have we already spotted this unhandled attribute?
next if (defined $attributes_not_handled{$1});
$attributes_not_handled{$1} = 1;
-
+
# Get the name of the attribute file.
my $dir = "$HtmlDir/failures";
my $afile = "$dir/attribute_ignored_$1.txt";
-
+
# Only create another preprocessed file if the attribute file
# doesn't exist yet.
next if (-e $afile);
-
+
# Add this file to the list of files that contained this attribute.
# Generate a preprocessed file if we haven't already.
if (!(defined $ppfile)) {
@@ -315,7 +319,7 @@
}
}
}
-
+
unlink($ofile);
}
@@ -377,22 +381,23 @@
);
my %LangMap = (
- 'c' => 'c',
+ 'c' => $IsCXX ? 'c++' : 'c',
'cp' => 'c++',
'cpp' => 'c++',
'cxx' => 'c++',
'txx' => 'c++',
'cc' => 'c++',
'C' => 'c++',
- 'ii' => 'c++',
- 'i' => 'c-cpp-output',
+ 'ii' => 'c++-cpp-output',
+ 'i' => $IsCXX ? 'c++-cpp-output' : 'c-cpp-output',
'm' => 'objective-c',
'mi' => 'objective-c-cpp-output',
- 'mm' => 'objective-c++'
+ 'mm' => 'objective-c++',
+ 'mii' => 'objective-c++-cpp-output',
);
my %UniqueOptions = (
- '-isysroot' => 0
+ '-isysroot' => 0
);
##----------------------------------------------------------------------------##
@@ -403,7 +408,10 @@
"objective-c" => 1,
"c" => 1,
"c++" => 1,
- "objective-c++" => 1
+ "objective-c++" => 1,
+ "c-cpp-output" => 1,
+ "objective-c-cpp-output" => 1,
+ "c++-cpp-output" => 1
);
##----------------------------------------------------------------------------##
@@ -444,6 +452,9 @@
my $OutputFormat = $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'};
if (!defined $OutputFormat) { $OutputFormat = "html"; }
+# Get the config options.
+my $ConfigOptions = $ENV{'CCC_ANALYZER_CONFIG'};
+
# Determine the level of verbosity.
my $Verbose = 0;
if (defined $ENV{'CCC_ANALYZER_VERBOSE'}) { $Verbose = 1; }
@@ -458,7 +469,7 @@
# Process the arguments.
foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
- my $Arg = $ARGV[$i];
+ my $Arg = $ARGV[$i];
my ($ArgKey) = split /=/,$Arg,2;
# Modes ccc-analyzer supports
@@ -485,7 +496,7 @@
next;
}
# Handle the case where there isn't a space after -iquote
- if ($Arg =~ /-iquote.*/) {
+ if ($Arg =~ /^-iquote.*/) {
push @CompileOpts,$Arg;
next;
}
@@ -502,7 +513,7 @@
# and the linker.
if (defined $CompilerLinkerOptionMap{$ArgKey}) {
my $Cnt = $CompilerLinkerOptionMap{$ArgKey};
-
+
# Check if this is an option that should have a unique value, and if so
# determine if the value was checked before.
if ($UniqueOptions{$Arg}) {
@@ -512,8 +523,8 @@
}
$Uniqued{$Arg} = 1;
}
-
- push @CompileOpts,$Arg;
+
+ push @CompileOpts,$Arg;
push @LinkOpts,$Arg;
while ($Cnt > 0) {
@@ -523,7 +534,7 @@
}
next;
}
-
+
# Ignored options.
if (defined $IgnoredOptionMap{$ArgKey}) {
my $Cnt = $IgnoredOptionMap{$ArgKey};
@@ -532,10 +543,10 @@
}
next;
}
-
+
# Compile mode flags.
if ($Arg =~ /^-[D,I,U](.*)$/) {
- my $Tmp = $Arg;
+ my $Tmp = $Arg;
if ($1 eq '') {
# FIXME: Check if we are going off the end.
++$i;
@@ -544,12 +555,12 @@
push @CompileOpts,$Tmp;
next;
}
-
- if ($Arg =~ /-m.*/) {
+
+ if ($Arg =~ /^-m.*/) {
push @CompileOpts,$Arg;
next;
}
-
+
# Language.
if ($Arg eq '-x') {
$Lang = $ARGV[$i+1];
@@ -562,7 +573,7 @@
$Output = $ARGV[$i];
next;
}
-
+
# Get the link mode.
if ($Arg =~ /^-[l,L,O]/) {
if ($Arg eq '-O') { push @LinkOpts,'-O1'; }
@@ -573,12 +584,12 @@
if ($Arg =~ /^-O/) { push @CompileOpts,$Arg; }
next;
}
-
+
if ($Arg =~ /^-std=/) {
push @CompileOpts,$Arg;
next;
}
-
+
# Get the compiler/link mode.
if ($Arg =~ /^-F(.+)$/) {
my $Tmp = $Arg;
@@ -601,13 +612,13 @@
++$i;
next;
}
-
+
if ($Arg =~ /^-f/) {
push @CompileOpts,$Arg;
push @LinkOpts,$Arg;
next;
}
-
+
# Handle -Wno-. We don't care about extra warnings, but
# we should suppress ones that we don't want to see.
if ($Arg =~ /^-Wno-/) {
@@ -636,7 +647,7 @@
$FileLang = $LangMap{$1};
}
}
-
+
# FileLang still not defined? Skip the file.
next if (!defined $FileLang);
@@ -644,8 +655,8 @@
next if (!defined $LangsAccepted{$FileLang});
my @CmdArgs;
- my @AnalyzeArgs;
-
+ my @AnalyzeArgs;
+
if ($FileLang ne 'unknown') {
push @CmdArgs, '-x', $FileLang;
}
@@ -661,7 +672,7 @@
if (defined $InternalStats) {
push @AnalyzeArgs, "-analyzer-stats";
}
-
+
if (defined $Analyses) {
push @AnalyzeArgs, split '\s+', $Analyses;
}
@@ -677,12 +688,15 @@
my ($h, $f) = tempfile("report-XXXXXX", SUFFIX => ".plist",
DIR => $HtmlDir);
$ResultFile = $f;
- # If the HtmlDir is not set, we sould clean up the plist files.
+ # If the HtmlDir is not set, we should clean up the plist files.
if (!defined $HtmlDir || -z $HtmlDir) {
$CleanupFile = $f;
}
}
}
+ if (defined $ConfigOptions) {
+ push @AnalyzeArgs, split '\s+', $ConfigOptions;
+ }
push @CmdArgs, @CompileOpts;
push @CmdArgs, $file;
@@ -704,4 +718,3 @@
}
exit($Status >> 8);
-
diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build
index 0f119f6..31dbfb4 100755
--- a/tools/scan-build/scan-build
+++ b/tools/scan-build/scan-build
@@ -32,7 +32,7 @@
my $UseColor = (defined $TERM and $TERM =~ 'xterm-.*color' and -t STDOUT
and defined $ENV{'SCAN_BUILD_COLOR'});
-# Portability: getpwuid is not implemented for Win32 (see Perl language
+# Portability: getpwuid is not implemented for Win32 (see Perl language
# reference, perlport), use getlogin instead.
my $UserName = HtmlEscape(getlogin() || getpwuid($<) || 'unknown');
my $HostName = HtmlEscape(hostname() || 'unknown');
@@ -57,7 +57,7 @@
}
else {
print "$Prog: @_";
- }
+ }
}
sub ErrorDiag {
@@ -67,7 +67,7 @@
print STDERR RESET;
} else {
print STDERR "$Prog: @_";
- }
+ }
}
sub DiagCrashes {
@@ -118,20 +118,20 @@
# GetHTMLRunDir - Construct an HTML directory name for the current sub-run.
##----------------------------------------------------------------------------##
-sub GetHTMLRunDir {
- die "Not enough arguments." if (@_ == 0);
- my $Dir = shift @_;
+sub GetHTMLRunDir {
+ die "Not enough arguments." if (@_ == 0);
+ my $Dir = shift @_;
my $TmpMode = 0;
if (!defined $Dir) {
$Dir = $ENV{'TMPDIR'} || $ENV{'TEMP'} || $ENV{'TMP'} || "/tmp";
$TmpMode = 1;
}
-
+
# Chop off any trailing '/' characters.
while ($Dir =~ /\/$/) { chop $Dir; }
# Get current date and time.
- my @CurrentTime = localtime();
+ my @CurrentTime = localtime();
my $year = $CurrentTime[5] + 1900;
my $day = $CurrentTime[3];
my $month = $CurrentTime[4] + 1;
@@ -142,16 +142,16 @@
my $TimeString = sprintf("%02d%02d%02d", $hour, $min, $sec);
my $DateString = sprintf("%d-%02d-%02d-%s-$$",
$year, $month, $day, $TimeString);
-
- # Determine the run number.
+
+ # Determine the run number.
my $RunNumber;
-
- if (-d $Dir) {
+
+ if (-d $Dir) {
if (! -r $Dir) {
DieDiag("directory '$Dir' exists but is not readable.\n");
- }
- # Iterate over all files in the specified directory.
- my $max = 0;
+ }
+ # Iterate over all files in the specified directory.
+ my $max = 0;
opendir(DIR, $Dir);
my @FILES = grep { -d "$Dir/$_" } readdir(DIR);
closedir(DIR);
@@ -170,16 +170,16 @@
next if ($x[2] != $day);
next if ($x[3] != $TimeString);
next if ($x[4] != $$);
-
+
if ($x[5] > $max) {
$max = $x[5];
- }
+ }
}
-
+
$RunNumber = $max + 1;
}
else {
-
+
if (-x $Dir) {
DieDiag("'$Dir' exists but is not a directory.\n");
}
@@ -188,14 +188,14 @@
DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n");
}
- # $Dir does not exist. It will be automatically created by the
- # clang driver. Set the run number to 1.
+ # $Dir does not exist. It will be automatically created by the
+ # clang driver. Set the run number to 1.
$RunNumber = 1;
}
-
+
die "RunNumber must be defined!" if (!defined $RunNumber);
-
+
# Append the run number.
my $NewDir;
if ($TmpMode) {
@@ -209,24 +209,24 @@
}
sub SetHtmlEnv {
-
+
die "Wrong number of arguments." if (scalar(@_) != 2);
-
+
my $Args = shift;
my $Dir = shift;
-
+
die "No build command." if (scalar(@$Args) == 0);
-
+
my $Cmd = $$Args[0];
if ($Cmd =~ /configure/ || $Cmd =~ /autogen/) {
return;
}
-
+
if ($Verbose) {
Diag("Emitting reports for this run to '$Dir'.\n");
}
-
+
$ENV{'CCC_ANALYZER_HTML'} = $Dir;
}
@@ -236,18 +236,18 @@
sub ComputeDigest {
my $FName = shift;
- DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName);
-
+ DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName);
+
# Use Digest::MD5. We don't have to be cryptographically secure. We're
# just looking for duplicate files that come from a non-malicious source.
# We use Digest::MD5 because it is a standard Perl module that should
- # come bundled on most systems.
+ # come bundled on most systems.
open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n");
binmode FILE;
my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest;
close(FILE);
-
- # Return the digest.
+
+ # Return the digest.
return $Result;
}
@@ -266,7 +266,7 @@
$Prefix = $x;
return;
}
-
+
chop $Prefix while (!($x =~ /^\Q$Prefix/));
}
@@ -339,15 +339,15 @@
my %AlreadyScanned;
sub ScanFile {
-
+
my $Index = shift;
my $Dir = shift;
my $FName = shift;
my $Stats = shift;
-
+
# Compute a digest for the report file. Determine if we have already
# scanned a file that looks just like it.
-
+
my $digest = ComputeDigest("$Dir/$FName");
if (defined $AlreadyScanned{$digest}) {
@@ -355,12 +355,12 @@
system ("rm", "-f", "$Dir/$FName");
return;
}
-
+
$AlreadyScanned{$digest} = 1;
-
+
# At this point the report file is not world readable. Make it happen.
system ("chmod", "644", "$Dir/$FName");
-
+
# Scan the report file for tags.
open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n");
@@ -385,7 +385,7 @@
$BugPathLength = $1;
}
elsif (/<!-- BUGLINE (.*) -->$/) {
- $BugLine = $1;
+ $BugLine = $1;
}
elsif (/<!-- BUGCATEGORY (.*) -->$/) {
$BugCategory = $1;
@@ -396,7 +396,7 @@
}
close(IN);
-
+
if (!defined $BugCategory) {
$BugCategory = "Other";
}
@@ -406,7 +406,7 @@
AddStatLine($BugDescription, $Stats, $BugFile);
return;
}
-
+
push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine,
$BugPathLength ];
}
@@ -420,17 +420,17 @@
my $Dir = shift;
my $JS = Cwd::realpath("$RealBin/sorttable.js");
-
+
DieDiag("Cannot find 'sorttable.js'.\n")
- if (! -r $JS);
+ if (! -r $JS);
system ("cp", $JS, "$Dir");
DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n")
if (! -r "$Dir/sorttable.js");
-
+
my $CSS = Cwd::realpath("$RealBin/scanview.css");
-
+
DieDiag("Cannot find 'scanview.css'.\n")
if (! -r $CSS);
@@ -493,7 +493,7 @@
my @filesFound;
my $baseDir;
-sub FileWanted {
+sub FileWanted {
my $baseDirRegEx = quotemeta $baseDir;
my $file = $File::Find::name;
if ($file =~ /report-.*\.html$/) {
@@ -504,14 +504,14 @@
}
sub Postprocess {
-
+
my $Dir = shift;
my $BaseDir = shift;
my $AnalyzerStats = shift;
my $KeepEmpty = shift;
-
+
die "No directory specified." if (!defined $Dir);
-
+
if (! -d $Dir) {
Diag("No bugs found.\n");
return 0;
@@ -528,12 +528,12 @@
Diag("No bugs found.\n");
return 0;
}
-
- # Scan each report file and build an index.
+
+ # Scan each report file and build an index.
my @Index;
my @Stats;
foreach my $file (@filesFound) { ScanFile(\@Index, $Dir, $file, \@Stats); }
-
+
# Scan the failures directory and use the information in the .info files
# to update the common prefix directory.
my @failures;
@@ -542,7 +542,7 @@
opendir(DIR, "$Dir/failures");
@failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR);
closedir(DIR);
- opendir(DIR, "$Dir/failures");
+ opendir(DIR, "$Dir/failures");
@attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR);
closedir(DIR);
foreach my $file (@failures) {
@@ -550,15 +550,15 @@
my $Path = <IN>;
if (defined $Path) { UpdatePrefix($Path); }
close IN;
- }
+ }
}
-
- # Generate an index.html file.
- my $FName = "$Dir/index.html";
+
+ # Generate an index.html file.
+ my $FName = "$Dir/index.html";
open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n");
-
+
# Print out the header.
-
+
print OUT <<ENDTEXT;
<html>
<head>
@@ -589,13 +589,13 @@
}
function returnObjById( id ) {
- if (document.getElementById)
+ if (document.getElementById)
var returnVar = document.getElementById(id);
else if (document.all)
var returnVar = document.all[id];
- else if (document.layers)
+ else if (document.layers)
var returnVar = document.layers[id];
- return returnVar;
+ return returnVar;
}
var NumUnchecked = 0;
@@ -652,14 +652,14 @@
if (defined $BuildName) {
print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n"
}
-
+
my $TotalBugs = scalar(@Index);
print OUT <<ENDTEXT;
<table>
<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead>
<tr style="font-weight:bold"><td class="SUMM_DESC">All Bugs</td><td class="Q">$TotalBugs</td><td><center><input type="checkbox" id="AllBugsCheck" onClick="CopyCheckedStateToCheckButtons(this);" checked/></center></td></tr>
ENDTEXT
-
+
my $last_category;
for my $key (
@@ -669,14 +669,14 @@
my $res = $x->[1] cmp $y->[1];
$res = $x->[2] cmp $y->[2] if ($res == 0);
$res
- } keys %Totals )
+ } keys %Totals )
{
my $val = $Totals{$key};
my $category = $val->[1];
if (!defined $last_category or $last_category ne $category) {
$last_category = $category;
print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n";
- }
+ }
my $x = lc $key;
$x =~ s/[ ,'":\/()]+/_/g;
print OUT "<tr><td class=\"SUMM_DESC\">";
@@ -709,19 +709,19 @@
my $regex;
my $InFileRegex;
my $InFilePrefix = "File:</td><td>";
-
- if (defined $prefix) {
- $regex = qr/^\Q$prefix\E/is;
+
+ if (defined $prefix) {
+ $regex = qr/^\Q$prefix\E/is;
$InFileRegex = qr/\Q$InFilePrefix$prefix\E/is;
- }
+ }
for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) {
my $x = "$row->[1]:$row->[2]";
$x = lc $x;
$x =~ s/[ ,'":\/()]+/_/g;
-
+
my $ReportFile = $row->[0];
-
+
print OUT "<tr class=\"bt_$x\">";
print OUT "<td class=\"DESC\">";
print OUT $row->[1];
@@ -729,16 +729,16 @@
print OUT "<td class=\"DESC\">";
print OUT $row->[2];
print OUT "</td>";
-
- # Update the file prefix.
+
+ # Update the file prefix.
my $fname = $row->[3];
if (defined $regex) {
$fname =~ s/$regex//;
UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix)
}
-
- print OUT "<td>";
+
+ print OUT "<td>";
my @fname = split /\//,$fname;
if ($#fname > 0) {
while ($#fname >= 0) {
@@ -751,14 +751,14 @@
}
else {
print OUT $fname;
- }
+ }
print OUT "</td>";
-
+
# Print out the quantities.
for my $j ( 4 .. 5 ) {
- print OUT "<td class=\"Q\">$row->[$j]</td>";
+ print OUT "<td class=\"Q\">$row->[$j]</td>";
}
-
+
# Print the rest of the columns.
for (my $j = 6; $j <= $#{$row}; ++$j) {
print OUT "<td>$row->[$j]</td>"
@@ -766,20 +766,20 @@
# Emit the "View" link.
print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>";
-
+
# Emit REPORTBUG markers.
print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n";
-
+
# End the row.
print OUT "</tr>\n";
}
-
+
print OUT "</tbody>\n</table>\n\n";
}
if (scalar (@failures) || scalar(@attributes_ignored)) {
print OUT "<h2>Analyzer Failures</h2>\n";
-
+
if (scalar @attributes_ignored) {
print OUT "The analyzer's parser ignored the following attributes:<p>\n";
print OUT "<table>\n";
@@ -809,7 +809,7 @@
}
print OUT "</table>\n";
}
-
+
if (scalar @failures) {
print OUT "<p>The analyzer had problems processing the following files:</p>\n";
print OUT "<table>\n";
@@ -835,11 +835,11 @@
print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n";
}
print OUT "</table>\n";
- }
+ }
print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang-analyzer.llvm.org/filing_bugs.html\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n";
}
-
- print OUT "</body></html>\n";
+
+ print OUT "</body></html>\n";
close(OUT);
CopyFiles($Dir);
@@ -855,9 +855,9 @@
if ($Num > 0 && -r "$Dir/index.html") {
Diag("Run 'scan-view $Dir' to examine bug reports.\n");
}
-
+
DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored);
-
+
return $Num;
}
@@ -867,16 +867,16 @@
sub AddIfNotPresent {
my $Args = shift;
- my $Arg = shift;
+ my $Arg = shift;
my $found = 0;
-
+
foreach my $k (@$Args) {
if ($k eq $Arg) {
$found = 1;
last;
}
}
-
+
if ($found == 0) {
push @$Args, $Arg;
}
@@ -885,7 +885,8 @@
sub SetEnv {
my $Options = shift @_;
foreach my $opt ('CC', 'CXX', 'CLANG', 'CLANG_CXX',
- 'CCC_ANALYZER_ANALYSIS', 'CCC_ANALYZER_PLUGINS') {
+ 'CCC_ANALYZER_ANALYSIS', 'CCC_ANALYZER_PLUGINS',
+ 'CCC_ANALYZER_CONFIG') {
die "$opt is undefined\n" if (!defined $opt);
$ENV{$opt} = $Options->{$opt};
}
@@ -906,7 +907,7 @@
}
# The flag corresponding to the --override-compiler command line option.
-my $OverrideCompiler = 0;
+my $OverrideCompiler = 0;
sub RunXcodebuild {
my $Args = shift;
@@ -939,13 +940,13 @@
}
}
close(DETECT_XCODE);
-
- # If --override-compiler is explicitely requested, resort to the old
+
+ # If --override-compiler is explicitely requested, resort to the old
# behavior regardless of Xcode version.
if ($OverrideCompiler) {
$oldBehavior = 1;
}
-
+
if ($oldBehavior == 0) {
my $OutputDir = $Options->{"OUTPUT_DIR"};
my $CLANG = $Options->{"CLANG"};
@@ -959,10 +960,10 @@
return (system(@$Args) >> 8);
}
-
+
# Default to old behavior where we insert a bogus compiler.
SetEnv($Options);
-
+
# Check if using iPhone SDK 3.0 (simulator). If so the compiler being
# used should be gcc-4.2.
if (!defined $ENV{"CCC_CC"}) {
@@ -978,16 +979,16 @@
# Disable PCH files until clang supports them.
AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO");
-
+
# When 'CC' is set, xcodebuild uses it to do all linking, even if we are
# linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'
# (via c++-analyzer) when linking such files.
$ENV{"LDPLUSPLUS"} = $CXXAnalyzer;
-
- return (system(@$Args) >> 8);
+
+ return (system(@$Args) >> 8);
}
-sub RunBuildCommand {
+sub RunBuildCommand {
my $Args = shift;
my $IgnoreErrors = shift;
my $Cmd = $Args->[0];
@@ -1001,28 +1002,28 @@
# Setup the environment.
SetEnv($Options);
-
- if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or
+
+ if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or
$Cmd =~ /(.*\/?cc[^\/]*$)/ or
$Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or
- $Cmd =~ /(.*\/?clang$)/ or
+ $Cmd =~ /(.*\/?clang$)/ or
$Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) {
if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) {
- $ENV{"CCC_CC"} = $1;
+ $ENV{"CCC_CC"} = $1;
}
-
+
shift @$Args;
unshift @$Args, $CCAnalyzer;
}
- elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or
+ elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or
$Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or
$Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or
$Cmd =~ /(.*\/?clang\+\+$)/ or
$Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) {
if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) {
- $ENV{"CCC_CXX"} = $1;
- }
+ $ENV{"CCC_CXX"} = $1;
+ }
shift @$Args;
unshift @$Args, $CXXAnalyzer;
}
@@ -1033,7 +1034,7 @@
AddIfNotPresent($Args,"-k");
AddIfNotPresent($Args,"-i");
}
- }
+ }
return (system(@$Args) >> 8);
}
@@ -1043,7 +1044,7 @@
##----------------------------------------------------------------------------##
sub DisplayHelp {
-
+
print <<ENDTEXT;
USAGE: $Prog [options] <build command> [build options]
@@ -1057,25 +1058,25 @@
OPTIONS:
-analyze-headers
-
+
Also analyze functions in #included files. By default, such functions
are skipped unless they are called by functions within the main source file.
-
+
-o <output location>
-
+
Specifies the output directory for analyzer reports. Subdirectories will be
created as needed to represent separate "runs" of the analyzer. If this
option is not specified, a directory is created in /tmp (TMPDIR on Mac OS X)
to store the reports.
- -h
+ -h
--help
Display this message.
-k
--keep-going
-
+
Add a "keep on going" option to the specified build command. This option
currently supports make and xcodebuild. This is a convenience option; one
can specify this behavior directly using build options.
@@ -1087,41 +1088,41 @@
title will be used.
-plist
-
+
By default the output of scan-build is a set of HTML files. This option
outputs the results as a set of .plist files.
-
+
-plist-html
-
+
By default the output of scan-build is a set of HTML files. This option
outputs the results as a set of HTML and .plist files.
-
+
--status-bugs
-
+
By default, the exit status of scan-build is the same as the executed build
command. Specifying this option causes the exit status of scan-build to be 1
if it found potential bugs and 0 otherwise.
- --use-cc [compiler path]
+ --use-cc [compiler path]
--use-cc=[compiler path]
-
+
scan-build analyzes a project by interposing a "fake compiler", which
executes a real compiler for compilation and the static analyzer for analysis.
Because of the current implementation of interposition, scan-build does not
know what compiler your project normally uses. Instead, it simply overrides
the CC environment variable, and guesses your default compiler.
-
+
In the future, this interposition mechanism to be improved, but if you need
scan-build to use a specific compiler for *compilation* then you can use
this option to specify a path to that compiler.
--use-c++ [compiler path]
--use-c++=[compiler path]
-
+
This is the same as "-use-cc" but for C++ code.
-
+
-v
-
+
Enable verbose output from scan-build. A second and third '-v' increases
verbosity.
@@ -1133,26 +1134,26 @@
ADVANCED OPTIONS:
-no-failure-reports
-
+
Do not create a 'failures' subdirectory that includes analyzer crash reports
and preprocessed source files.
-stats
-
+
Generates visitation statistics for the project being analyzed.
-maxloop <loop count>
-
+
Specifiy the number of times a block can be visited before giving up.
Default is 4. Increase for more comprehensive coverage at a cost of speed.
-
+
-internal-stats
-
+
Generate internal analyzer statistics.
-
- --use-analyzer [Xcode|path to clang]
+
+ --use-analyzer [Xcode|path to clang]
--use-analyzer=[Xcode|path to clang]
-
+
scan-build uses the 'clang' executable relative to itself for static
analysis. One can override this behavior with this option by using the
'clang' packaged with Xcode (on OS X) or from the PATH.
@@ -1161,10 +1162,14 @@
Don't remove the build results directory even if no issues were reported.
- --override-compiler
- Always resort to the ccc-analyzer even when better interposition methods
+ --override-compiler
+ Always resort to the ccc-analyzer even when better interposition methods
are available.
-
+
+ -analyzer-config <options>
+
+ Provide options to pass through to the analyzer's -analyzer-config flag.
+
CONTROLLING CHECKERS:
A default group of checkers are always run unless explicitly disabled.
@@ -1172,7 +1177,7 @@
-enable-checker [checker name]
-disable-checker [checker name]
-
+
LOADING CHECKERS:
Loading external checkers using the clang plugin interface:
@@ -1197,7 +1202,7 @@
close FROM_CHILD;
open(STDOUT,">&", \*TO_PARENT);
open(STDERR,">&", \*TO_PARENT);
- exec $Clang, ( @PluginLoadCommandline_xclang, '--analyze', '-x', $lang, '-', '-###');
+ exec $Clang, ( @PluginLoadCommandline_xclang, '--analyze', '-x', $lang, '-', '-###');
}
close(TO_PARENT);
while(<FROM_CHILD>) {
@@ -1260,7 +1265,7 @@
# append a dot, if an additional domain is added in the next iteration
$aggregate .= ".";
}
-
+
if ($enabled) {
print " + ";
}
@@ -1288,7 +1293,7 @@
EXAMPLE
scan-build -o /tmp/myhtmldir make -j4
-
+
The above example causes analysis reports to be deposited into a subdirectory
of "/tmp/myhtmldir" and to run "make" with the "-j4" option. A different
subdirectory is created each time scan-build analyzes a project. The analyzer
@@ -1336,6 +1341,7 @@
my $StoreModel;
my $ConstraintsModel;
my $InternalStats;
+my @ConfigOptions;
my $OutputFormat = "html";
my $AnalyzerStats = 0;
my $MaxLoop = 0;
@@ -1348,9 +1354,9 @@
}
while (@ARGV) {
-
+
# Scan for options we recognize.
-
+
my $arg = $ARGV[0];
if ($arg eq "-h" or $arg eq "--help") {
@@ -1358,24 +1364,24 @@
shift @ARGV;
next;
}
-
+
if ($arg eq '-analyze-headers') {
- shift @ARGV;
+ shift @ARGV;
$AnalyzeHeaders = 1;
next;
}
-
+
if ($arg eq "-o") {
shift @ARGV;
-
+
if (!@ARGV) {
DieDiag("'-o' option requires a target directory name.\n");
}
-
+
# Construct an absolute path. Uses the current working directory
# as a base if the original path was not absolute.
$HtmlDir = abs_path(shift @ARGV);
-
+
next;
}
@@ -1394,7 +1400,7 @@
next;
}
-
+
if ($arg eq "-k" or $arg eq "--keep-going") {
shift @ARGV;
$IgnoreErrors = 1;
@@ -1404,7 +1410,7 @@
if ($arg =~ /^--use-cc(=(.+))?$/) {
shift @ARGV;
my $cc;
-
+
if (!defined $2 || $2 eq "") {
if (!@ARGV) {
DieDiag("'--use-cc' option requires a compiler executable name.\n");
@@ -1414,15 +1420,15 @@
else {
$cc = $2;
}
-
+
$ENV{"CCC_CC"} = $cc;
next;
}
-
+
if ($arg =~ /^--use-c\+\+(=(.+))?$/) {
shift @ARGV;
- my $cxx;
-
+ my $cxx;
+
if (!defined $2 || $2 eq "") {
if (!@ARGV) {
DieDiag("'--use-c++' option requires a compiler executable name.\n");
@@ -1432,23 +1438,23 @@
else {
$cxx = $2;
}
-
+
$ENV{"CCC_CXX"} = $cxx;
next;
}
-
+
if ($arg eq "-v") {
shift @ARGV;
$Verbose++;
next;
}
-
+
if ($arg eq "-V" or $arg eq "--view") {
shift @ARGV;
- $ViewResults = 1;
+ $ViewResults = 1;
next;
}
-
+
if ($arg eq "--status-bugs") {
shift @ARGV;
$ExitStatusFoundBugs = 1;
@@ -1460,7 +1466,7 @@
$StoreModel = shift @ARGV;
next;
}
-
+
if ($arg eq "-constraints") {
shift @ARGV;
$ConstraintsModel = shift @ARGV;
@@ -1472,7 +1478,7 @@
$InternalStats = 1;
next;
}
-
+
if ($arg eq "-plist") {
shift @ARGV;
$OutputFormat = "plist";
@@ -1483,7 +1489,13 @@
$OutputFormat = "plist-html";
next;
}
-
+
+ if ($arg eq "-analyzer-config") {
+ shift @ARGV;
+ push @ConfigOptions, "-analyzer-config", shift @ARGV;
+ next;
+ }
+
if ($arg eq "-no-failure-reports") {
$ENV{"CCC_REPORT_FAILURES"} = 0;
next;
@@ -1534,9 +1546,9 @@
$OverrideCompiler = 1;
next;
}
-
+
DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/);
-
+
last;
}
@@ -1557,8 +1569,8 @@
" Consider using --use-analyzer to pick a version of 'clang' to use for static analysis.\n");
}
}
-}
-else {
+}
+else {
if ($AnalyzerDiscoveryMethod =~ /^[Xx]code$/) {
my $xcrun = `which xcrun`;
chomp $xcrun;
@@ -1566,9 +1578,9 @@
DieDiag("Cannot find 'xcrun' to find 'clang' for analysis.\n");
}
$Clang = `$xcrun -toolchain XcodeDefault -find clang`;
- chomp $Clang;
+ chomp $Clang;
if ($Clang eq "") {
- DieDiag("No 'clang' executable found by 'xcrun'\n");
+ DieDiag("No 'clang' executable found by 'xcrun'\n");
}
}
else {
@@ -1612,9 +1624,9 @@
my $Cmd = "$AbsRealBin/libexec/ccc-analyzer";
my $CmdCXX = "$AbsRealBin/libexec/c++-analyzer";
-# Portability: use less strict but portable check -e (file exists) instead of
+# Portability: use less strict but portable check -e (file exists) instead of
# non-portable -x (file is executable). On some windows ports -x just checks
-# file extension to determine if a file is executable (see Perl language
+# file extension to determine if a file is executable (see Perl language
# reference, perlport)
if (!defined $Cmd || ! -e $Cmd) {
$Cmd = "$AbsRealBin/ccc-analyzer";
@@ -1636,6 +1648,7 @@
# interposition.
my $CCC_ANALYZER_ANALYSIS = join ' ',@AnalysesToRun;
my $CCC_ANALYZER_PLUGINS = join ' ',@PluginsToLoad;
+my $CCC_ANALYZER_CONFIG = join ' ',@ConfigOptions;
my %Options = (
'CC' => $Cmd,
'CXX' => $CmdCXX,
@@ -1644,6 +1657,7 @@
'VERBOSE' => $Verbose,
'CCC_ANALYZER_ANALYSIS' => $CCC_ANALYZER_ANALYSIS,
'CCC_ANALYZER_PLUGINS' => $CCC_ANALYZER_PLUGINS,
+ 'CCC_ANALYZER_CONFIG' => $CCC_ANALYZER_CONFIG,
'OUTPUT_DIR' => $HtmlDir
);
@@ -1689,4 +1703,3 @@
}
exit $ExitStatus;
-
diff --git a/tools/scan-build/scan-build.1 b/tools/scan-build/scan-build.1
index 10ddc7f..3d3a9f8 100644
--- a/tools/scan-build/scan-build.1
+++ b/tools/scan-build/scan-build.1
@@ -3,7 +3,7 @@
.\" $Id$
.Dd May 25, 2012
.Dt SCAN-BUILD 1
-.Os "clang" "3.1"
+.Os "clang" "3.5"
.Sh NAME
.Nm scan-build
.Nd Clang static analyzer
diff --git a/tools/scan-build/scanview.css b/tools/scan-build/scanview.css
index a0406f3..cf8a5a6 100644
--- a/tools/scan-build/scanview.css
+++ b/tools/scan-build/scanview.css
@@ -10,7 +10,7 @@
text-align:center;
font-weight: bold; font-family: Verdana;
white-space:nowrap;
-}
+}
.W { font-size:0px }
th, td { padding:5px; padding-left:8px; text-align:left }
td.SUMM_DESC { padding-left:12px }
@@ -21,7 +21,7 @@
table.form_group {
background-color: #ccc;
- border: 1px solid #333;
+ border: 1px solid #333;
padding: 2px;
}
@@ -33,7 +33,7 @@
table.form {
background-color: #999;
- border: 1px solid #333;
+ border: 1px solid #333;
padding: 2px;
}
diff --git a/tools/scan-build/set-xcode-analyzer b/tools/scan-build/set-xcode-analyzer
index 3076b39..5ac5c18 100755
--- a/tools/scan-build/set-xcode-analyzer
+++ b/tools/scan-build/set-xcode-analyzer
@@ -8,7 +8,7 @@
if sys.version_info < (2, 7):
print "set-xcode-analyzer requires Python 2.7 or later"
sys.exit(1)
-
+
import os
import subprocess
import re
@@ -65,7 +65,7 @@
parser.set_description(__doc__)
parser.add_option("--use-checker-build", dest="path",
help="Use the Clang located at the provided absolute path, e.g. /Users/foo/checker-1")
- parser.add_option("--use-xcode-clang", action="store_const",
+ parser.add_option("--use-xcode-clang", action="store_const",
const="$(CLANG)", dest="default",
help="Use the Clang bundled with Xcode")
(options, args) = parser.parse_args()
@@ -91,7 +91,7 @@
print "(+) Using the Clang bundled with Xcode"
path = options.default
isBuiltinAnalyzer = True
-
+
try:
xcode_path = subprocess.check_output(["xcode-select", "-print-path"])
except AttributeError:
@@ -101,15 +101,14 @@
# Cut off the 'Developer' dir, as the xcspec lies in another part
# of the Xcode.app subtree.
xcode_path = os.path.dirname(xcode_path)
-
+
foundSpec = False
for x in FindClangSpecs(xcode_path):
foundSpec = True
ModifySpec(x, isBuiltinAnalyzer, path)
-
+
if foundSpec == False:
print "(-) No compiler configuration file was found. Xcode's analyzer has not been updated."
if __name__ == '__main__':
main()
-
diff --git a/tools/scan-build/sorttable.js b/tools/scan-build/sorttable.js
index 4352d3b..03ebd92 100644
--- a/tools/scan-build/sorttable.js
+++ b/tools/scan-build/sorttable.js
@@ -3,19 +3,19 @@
version 2
7th April 2007
Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
-
+
Instructions:
Download this file
Add <script src="sorttable.js"></script> to your HTML
Add class="sortable" to any table you'd like to make sortable
Click on the headers to sort
-
+
Thanks to many, many people for contributions and suggestions.
Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
This basically means: do what you want with it.
*/
-
+
var stIsIE = /*@cc_on!@*/false;
sorttable = {
@@ -26,19 +26,19 @@
arguments.callee.done = true;
// kill the timer
if (_timer) clearInterval(_timer);
-
+
if (!document.createElement || !document.getElementsByTagName) return;
-
+
sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
-
+
forEach(document.getElementsByTagName('table'), function(table) {
if (table.className.search(/\bsortable\b/) != -1) {
sorttable.makeSortable(table);
}
});
-
+
},
-
+
makeSortable: function(table) {
if (table.getElementsByTagName('thead').length == 0) {
// table doesn't have a tHead. Since it should have, create one and
@@ -49,9 +49,9 @@
}
// Safari doesn't support table.tHead, sigh
if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
-
+
if (table.tHead.rows.length != 1) return; // can't cope with two header rows
-
+
// Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
// "total" rows, for example). This is B&R, since what you're supposed
// to do is put them in a tfoot. So, if there are sortbottom rows,
@@ -73,7 +73,7 @@
}
delete sortbottomrows;
}
-
+
// work through each column and calculate its type
headrow = table.tHead.rows[0].cells;
for (var i=0; i<headrow.length; i++) {
@@ -92,7 +92,7 @@
dean_addEvent(headrow[i],"click", function(e) {
if (this.className.search(/\bsorttable_sorted\b/) != -1) {
- // if we're already sorted by this column, just
+ // if we're already sorted by this column, just
// reverse the table, which is quicker
sorttable.reverse(this.sorttable_tbody);
this.className = this.className.replace('sorttable_sorted',
@@ -105,7 +105,7 @@
return;
}
if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
- // if we're already sorted by this column in reverse, just
+ // if we're already sorted by this column in reverse, just
// re-reverse the table, which is quicker
sorttable.reverse(this.sorttable_tbody);
this.className = this.className.replace('sorttable_sorted_reverse',
@@ -117,7 +117,7 @@
this.appendChild(sortfwdind);
return;
}
-
+
// remove sorttable_sorted classes
theadrow = this.parentNode;
forEach(theadrow.childNodes, function(cell) {
@@ -130,7 +130,7 @@
if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
sortrevind = document.getElementById('sorttable_sortrevind');
if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
-
+
this.className += ' sorttable_sorted';
sortfwdind = document.createElement('span');
sortfwdind.id = "sorttable_sortfwdind";
@@ -151,18 +151,18 @@
sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
/* and comment out this one */
//row_array.sort(this.sorttable_sortfunction);
-
+
tb = this.sorttable_tbody;
for (var j=0; j<row_array.length; j++) {
tb.appendChild(row_array[j][1]);
}
-
+
delete row_array;
});
}
}
},
-
+
guessType: function(table, column) {
// guess the type of a column based on its first non-blank row
sortfn = sorttable.sort_alpha;
@@ -172,7 +172,7 @@
if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
return sorttable.sort_numeric;
}
- // check for a date: dd/mm/yyyy or dd/mm/yy
+ // check for a date: dd/mm/yyyy or dd/mm/yy
// can have / or . or - as separator
// can be mm/dd as well
possdate = text.match(sorttable.DATE_RE)
@@ -195,17 +195,17 @@
}
return sortfn;
},
-
+
getInnerText: function(node) {
// gets the text we want to use for sorting for a cell.
// strips leading and trailing whitespace.
// this is *not* a generic getInnerText function; it's special to sorttable.
// for example, you can override the cell text with a customkey attribute.
// it also gets .value for <input> fields.
-
+
hasInputs = (typeof node.getElementsByTagName == 'function') &&
node.getElementsByTagName('input').length;
-
+
if (node.getAttribute("sorttable_customkey") != null) {
return node.getAttribute("sorttable_customkey");
}
@@ -240,7 +240,7 @@
}
}
},
-
+
reverse: function(tbody) {
// reverse the rows in a tbody
newrows = [];
@@ -252,14 +252,14 @@
}
delete newrows;
},
-
+
/* sort functions
each sort function takes two parameters, a and b
you are comparing a[0] and b[0] */
sort_numeric: function(a,b) {
aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
if (isNaN(aa)) aa = 0;
- bb = parseFloat(b[0].replace(/[^0-9.-]/g,''));
+ bb = parseFloat(b[0].replace(/[^0-9.-]/g,''));
if (isNaN(bb)) bb = 0;
return aa-bb;
},
@@ -298,7 +298,7 @@
if (dt1<dt2) return -1;
return 1;
},
-
+
shaker_sort: function(list, comp_func) {
// A stable sort function to allow multi-level sorting of data
// see: http://en.wikipedia.org/wiki/Cocktail_sort
@@ -328,7 +328,7 @@
b++;
} // while(swap)
- }
+ }
}
/* ******************************************************************
@@ -490,4 +490,3 @@
resolve.forEach(object, block, context);
}
};
-