aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt2
-rw-r--r--tools/Makefile4
-rw-r--r--tools/arcmt-test/CMakeLists.txt13
-rw-r--r--tools/arcmt-test/Makefile24
-rw-r--r--tools/arcmt-test/arcmt-test.cpp374
-rw-r--r--tools/c-arcmt-test/CMakeLists.txt14
-rw-r--r--tools/c-arcmt-test/Makefile25
-rw-r--r--tools/c-arcmt-test/c-arcmt-test.c91
-rw-r--r--tools/c-index-test/Makefile4
-rw-r--r--tools/c-index-test/c-index-test.c109
-rw-r--r--tools/driver/CMakeLists.txt1
-rw-r--r--tools/driver/Makefile2
-rw-r--r--tools/driver/cc1_main.cpp2
-rw-r--r--tools/driver/cc1as_main.cpp24
-rw-r--r--tools/driver/driver.cpp8
-rw-r--r--tools/libclang/ARCMigrate.cpp98
-rw-r--r--tools/libclang/CIndex.cpp125
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp192
-rw-r--r--tools/libclang/CMakeLists.txt3
-rw-r--r--tools/libclang/CXCursor.cpp23
-rw-r--r--tools/libclang/CXCursor.h13
-rw-r--r--tools/libclang/CXType.cpp6
-rw-r--r--tools/libclang/Makefile5
-rw-r--r--tools/libclang/libclang.darwin.exports6
-rw-r--r--tools/libclang/libclang.exports6
-rwxr-xr-xtools/scan-build/ccc-analyzer19
26 files changed, 1119 insertions, 74 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index ae33b782d49d..aff437fd467a 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -1,3 +1,5 @@
add_subdirectory(libclang)
add_subdirectory(c-index-test)
+add_subdirectory(arcmt-test)
+add_subdirectory(c-arcmt-test)
add_subdirectory(driver)
diff --git a/tools/Makefile b/tools/Makefile
index 000293f09c9f..bfd2a641ec1e 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -8,12 +8,12 @@
##===----------------------------------------------------------------------===##
CLANG_LEVEL := ..
-DIRS := driver libclang c-index-test
+DIRS := driver libclang c-index-test arcmt-test c-arcmt-test
include $(CLANG_LEVEL)/../../Makefile.config
ifeq ($(OS), $(filter $(OS), Minix))
-DIRS := $(filter-out libclang c-index-test, $(DIRS))
+DIRS := $(filter-out libclang c-index-test, arcmt-test, $(DIRS))
endif
include $(CLANG_LEVEL)/Makefile
diff --git a/tools/arcmt-test/CMakeLists.txt b/tools/arcmt-test/CMakeLists.txt
new file mode 100644
index 000000000000..9227f8ee63c7
--- /dev/null
+++ b/tools/arcmt-test/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(LLVM_USED_LIBS
+ clangARCMigrate
+ clangRewrite
+ )
+
+set( LLVM_LINK_COMPONENTS
+ support
+ mc
+ )
+
+add_clang_executable(arcmt-test
+ arcmt-test.cpp
+ )
diff --git a/tools/arcmt-test/Makefile b/tools/arcmt-test/Makefile
new file mode 100644
index 000000000000..c143e27f33e2
--- /dev/null
+++ b/tools/arcmt-test/Makefile
@@ -0,0 +1,24 @@
+##===- tools/arcmt-test/Makefile ---------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+CLANG_LEVEL := ../..
+
+TOOLNAME = arcmt-test
+
+# No plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+# Don't install this. It is used for tests.
+NO_INSTALL = 1
+
+LINK_COMPONENTS := support mc
+USEDLIBS = clangIndex.a clangARCMigrate.a clangRewrite.a \
+ clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
+ clangSema.a clangAnalysis.a clangAST.a clangLex.a clangBasic.a
+
+include $(CLANG_LEVEL)/Makefile
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
new file mode 100644
index 000000000000..eb0f56943f96
--- /dev/null
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -0,0 +1,374 @@
+//===-- arcmt-test.cpp - ARC Migration Tool testbed -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/ARCMigrate/ARCMT.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Frontend/VerifyDiagnosticsClient.h"
+#include "clang/Frontend/Utils.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
+
+using namespace clang;
+using namespace arcmt;
+
+static llvm::cl::opt<bool>
+CheckOnly("check-only",
+ llvm::cl::desc("Just check for issues that need to be handled manually"));
+
+//static llvm::cl::opt<bool>
+//TestResultForARC("test-result",
+//llvm::cl::desc("Test the result of transformations by parsing it in ARC mode"));
+
+static llvm::cl::opt<bool>
+OutputTransformations("output-transformations",
+ llvm::cl::desc("Print the source transformations"));
+
+static llvm::cl::opt<bool>
+VerifyDiags("verify",llvm::cl::desc("Verify emitted diagnostics and warnings"));
+
+static llvm::cl::opt<bool>
+VerboseOpt("v", llvm::cl::desc("Enable verbose output"));
+
+static llvm::cl::opt<bool>
+VerifyTransformedFiles("verify-transformed-files",
+llvm::cl::desc("Read pairs of file mappings (typically the output of "
+ "c-arcmt-test) and compare their contents with the filenames "
+ "provided in command-line"));
+
+static llvm::cl::opt<std::string>
+RemappingsFile("remappings-file",
+ llvm::cl::desc("Pairs of file mappings (typically the output of "
+ "c-arcmt-test)"));
+
+static llvm::cl::list<std::string>
+ResultFiles(llvm::cl::Positional, llvm::cl::desc("<filename>..."));
+
+static llvm::cl::extrahelp extraHelp(
+ "\nusage with compiler args: arcmt-test [options] --args [compiler flags]\n");
+
+// This function isn't referenced outside its translation unit, but it
+// can't use the "static" keyword because its address is used for
+// GetMainExecutable (since some platforms don't support taking the
+// address of main, and some platforms can't implement GetMainExecutable
+// without being given the address of a function in the main executable).
+llvm::sys::Path GetExecutablePath(const char *Argv0) {
+ // This just needs to be some symbol in the binary; C++ doesn't
+ // allow taking the address of ::main however.
+ void *MainAddr = (void*) (intptr_t) GetExecutablePath;
+ return llvm::sys::Path::GetMainExecutable(Argv0, MainAddr);
+}
+
+static void printSourceLocation(SourceLocation loc, ASTContext &Ctx,
+ llvm::raw_ostream &OS);
+static void printSourceRange(CharSourceRange range, ASTContext &Ctx,
+ llvm::raw_ostream &OS);
+
+namespace {
+
+class PrintTransforms : public MigrationProcess::RewriteListener {
+ ASTContext *Ctx;
+ llvm::raw_ostream &OS;
+
+public:
+ PrintTransforms(llvm::raw_ostream &OS)
+ : Ctx(0), OS(OS) { }
+
+ virtual void start(ASTContext &ctx) { Ctx = &ctx; }
+ virtual void finish() { Ctx = 0; }
+
+ virtual void insert(SourceLocation loc, llvm::StringRef text) {
+ assert(Ctx);
+ OS << "Insert: ";
+ printSourceLocation(loc, *Ctx, OS);
+ OS << " \"" << text << "\"\n";
+ }
+
+ virtual void remove(CharSourceRange range) {
+ assert(Ctx);
+ OS << "Remove: ";
+ printSourceRange(range, *Ctx, OS);
+ OS << '\n';
+ }
+};
+
+} // anonymous namespace
+
+static bool checkForMigration(llvm::StringRef resourcesPath,
+ llvm::ArrayRef<const char *> Args) {
+ DiagnosticClient *DiagClient =
+ new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
+ llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+ llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic(DiagID, DiagClient));
+ // Chain in -verify checker, if requested.
+ VerifyDiagnosticsClient *verifyDiag = 0;
+ if (VerifyDiags) {
+ verifyDiag = new VerifyDiagnosticsClient(*Diags, Diags->takeClient());
+ Diags->setClient(verifyDiag);
+ }
+
+ CompilerInvocation CI;
+ CompilerInvocation::CreateFromArgs(CI, Args.begin(), Args.end(), *Diags);
+
+ if (CI.getFrontendOpts().Inputs.empty()) {
+ llvm::errs() << "error: no input files\n";
+ return true;
+ }
+
+ if (!CI.getLangOpts().ObjC1)
+ return false;
+
+ arcmt::checkForManualIssues(CI,
+ CI.getFrontendOpts().Inputs[0].second,
+ CI.getFrontendOpts().Inputs[0].first,
+ Diags->getClient());
+ return Diags->getClient()->getNumErrors() > 0;
+}
+
+static void printResult(FileRemapper &remapper, llvm::raw_ostream &OS) {
+ CompilerInvocation CI;
+ remapper.applyMappings(CI);
+ PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
+ // The changed files will be in memory buffers, print them.
+ for (unsigned i = 0, e = PPOpts.RemappedFileBuffers.size(); i != e; ++i) {
+ const llvm::MemoryBuffer *mem = PPOpts.RemappedFileBuffers[i].second;
+ OS << mem->getBuffer();
+ }
+}
+
+static bool performTransformations(llvm::StringRef resourcesPath,
+ llvm::ArrayRef<const char *> Args) {
+ // Check first.
+ if (checkForMigration(resourcesPath, Args))
+ return true;
+
+ DiagnosticClient *DiagClient =
+ new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
+ llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+ llvm::IntrusiveRefCntPtr<Diagnostic> TopDiags(new Diagnostic(DiagID, DiagClient));
+
+ CompilerInvocation origCI;
+ CompilerInvocation::CreateFromArgs(origCI, Args.begin(), Args.end(),
+ *TopDiags);
+
+ if (origCI.getFrontendOpts().Inputs.empty()) {
+ llvm::errs() << "error: no input files\n";
+ return true;
+ }
+
+ if (!origCI.getLangOpts().ObjC1)
+ return false;
+
+ MigrationProcess migration(origCI, DiagClient);
+
+ std::vector<TransformFn> transforms = arcmt::getAllTransformations();
+ assert(!transforms.empty());
+
+ llvm::OwningPtr<PrintTransforms> transformPrinter;
+ if (OutputTransformations)
+ transformPrinter.reset(new PrintTransforms(llvm::outs()));
+
+ for (unsigned i=0, e = transforms.size(); i != e; ++i) {
+ bool err = migration.applyTransform(transforms[i], transformPrinter.get());
+ if (err) return true;
+
+ if (VerboseOpt) {
+ if (i == e-1)
+ llvm::errs() << "\n##### FINAL RESULT #####\n";
+ else
+ llvm::errs() << "\n##### OUTPUT AFTER "<< i+1 <<". TRANSFORMATION #####\n";
+ printResult(migration.getRemapper(), llvm::errs());
+ llvm::errs() << "\n##########################\n\n";
+ }
+ }
+
+ if (!OutputTransformations)
+ printResult(migration.getRemapper(), llvm::outs());
+
+ // FIXME: TestResultForARC
+
+ return false;
+}
+
+static bool filesCompareEqual(llvm::StringRef fname1, llvm::StringRef fname2) {
+ using namespace llvm;
+
+ OwningPtr<MemoryBuffer> file1;
+ MemoryBuffer::getFile(fname1, file1);
+ if (!file1)
+ return false;
+
+ OwningPtr<MemoryBuffer> file2;
+ MemoryBuffer::getFile(fname2, file2);
+ if (!file2)
+ return false;
+
+ return file1->getBuffer() == file2->getBuffer();
+}
+
+static bool verifyTransformedFiles(llvm::ArrayRef<std::string> resultFiles) {
+ using namespace llvm;
+
+ assert(!resultFiles.empty());
+
+ std::map<StringRef, StringRef> resultMap;
+
+ for (ArrayRef<std::string>::iterator
+ I = resultFiles.begin(), E = resultFiles.end(); I != E; ++I) {
+ StringRef fname(*I);
+ if (!fname.endswith(".result")) {
+ errs() << "error: filename '" << fname
+ << "' does not have '.result' extension\n";
+ return true;
+ }
+ resultMap[sys::path::stem(fname)] = fname;
+ }
+
+ OwningPtr<MemoryBuffer> inputBuf;
+ if (RemappingsFile.empty())
+ MemoryBuffer::getSTDIN(inputBuf);
+ else
+ MemoryBuffer::getFile(RemappingsFile, inputBuf);
+ if (!inputBuf) {
+ errs() << "error: could not read remappings input\n";
+ return true;
+ }
+
+ SmallVector<StringRef, 8> strs;
+ inputBuf->getBuffer().split(strs, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+
+ if (strs.empty()) {
+ errs() << "error: no files to verify from stdin\n";
+ return true;
+ }
+ if (strs.size() % 2 != 0) {
+ errs() << "error: files to verify are not original/result pairs\n";
+ return true;
+ }
+
+ for (unsigned i = 0, e = strs.size(); i != e; i += 2) {
+ StringRef inputOrigFname = strs[i];
+ StringRef inputResultFname = strs[i+1];
+
+ std::map<StringRef, StringRef>::iterator It;
+ It = resultMap.find(sys::path::filename(inputOrigFname));
+ if (It == resultMap.end()) {
+ errs() << "error: '" << inputOrigFname << "' is not in the list of "
+ << "transformed files to verify\n";
+ return true;
+ }
+
+ bool exists = false;
+ sys::fs::exists(It->second, exists);
+ if (!exists) {
+ errs() << "error: '" << It->second << "' does not exist\n";
+ return true;
+ }
+ sys::fs::exists(inputResultFname, exists);
+ if (!exists) {
+ errs() << "error: '" << inputResultFname << "' does not exist\n";
+ return true;
+ }
+
+ if (!filesCompareEqual(It->second, inputResultFname)) {
+ errs() << "error: '" << It->second << "' is different than "
+ << "'" << inputResultFname << "'\n";
+ return true;
+ }
+
+ resultMap.erase(It);
+ }
+
+ if (!resultMap.empty()) {
+ for (std::map<StringRef, StringRef>::iterator
+ I = resultMap.begin(), E = resultMap.end(); I != E; ++I)
+ errs() << "error: '" << I->second << "' was not verified!\n";
+ return true;
+ }
+
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Misc. functions.
+//===----------------------------------------------------------------------===//
+
+static void printSourceLocation(SourceLocation loc, ASTContext &Ctx,
+ llvm::raw_ostream &OS) {
+ SourceManager &SM = Ctx.getSourceManager();
+ PresumedLoc PL = SM.getPresumedLoc(loc);
+
+ OS << llvm::sys::path::filename(PL.getFilename());
+ OS << ":" << PL.getLine() << ":"
+ << PL.getColumn();
+}
+
+static void printSourceRange(CharSourceRange range, ASTContext &Ctx,
+ llvm::raw_ostream &OS) {
+ SourceManager &SM = Ctx.getSourceManager();
+ const LangOptions &langOpts = Ctx.getLangOptions();
+
+ PresumedLoc PL = SM.getPresumedLoc(range.getBegin());
+
+ OS << llvm::sys::path::filename(PL.getFilename());
+ OS << " [" << PL.getLine() << ":"
+ << PL.getColumn();
+ OS << " - ";
+
+ SourceLocation end = range.getEnd();
+ PL = SM.getPresumedLoc(end);
+
+ unsigned endCol = PL.getColumn() - 1;
+ if (!range.isTokenRange())
+ endCol += Lexer::MeasureTokenLength(end, SM, langOpts);
+ OS << PL.getLine() << ":" << endCol << "]";
+}
+
+//===----------------------------------------------------------------------===//
+// Command line processing.
+//===----------------------------------------------------------------------===//
+
+int main(int argc, const char **argv) {
+ using llvm::StringRef;
+ void *MainAddr = (void*) (intptr_t) GetExecutablePath;
+ llvm::sys::PrintStackTraceOnErrorSignal();
+
+ std::string
+ resourcesPath = CompilerInvocation::GetResourcesPath(argv[0], MainAddr);
+
+ int optargc = 0;
+ for (; optargc != argc; ++optargc) {
+ if (StringRef(argv[optargc]) == "--args")
+ break;
+ }
+ llvm::cl::ParseCommandLineOptions(optargc, const_cast<char **>(argv), "arcmt-test");
+
+ if (VerifyTransformedFiles) {
+ if (ResultFiles.empty()) {
+ llvm::cl::PrintHelpMessage();
+ return 1;
+ }
+ return verifyTransformedFiles(ResultFiles);
+ }
+
+ if (optargc == argc) {
+ llvm::cl::PrintHelpMessage();
+ return 1;
+ }
+
+ llvm::ArrayRef<const char*> Args(argv+optargc+1, argc-optargc-1);
+
+ if (CheckOnly)
+ return checkForMigration(resourcesPath, Args);
+
+ return performTransformations(resourcesPath, Args);
+}
diff --git a/tools/c-arcmt-test/CMakeLists.txt b/tools/c-arcmt-test/CMakeLists.txt
new file mode 100644
index 000000000000..351f4adca10f
--- /dev/null
+++ b/tools/c-arcmt-test/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(LLVM_USED_LIBS libclang)
+
+set( LLVM_LINK_COMPONENTS
+ support
+ mc
+ )
+
+add_clang_executable(c-arcmt-test
+ c-arcmt-test.c
+ )
+
+set_target_properties(c-arcmt-test
+ PROPERTIES
+ LINKER_LANGUAGE CXX)
diff --git a/tools/c-arcmt-test/Makefile b/tools/c-arcmt-test/Makefile
new file mode 100644
index 000000000000..b72a08ab53bb
--- /dev/null
+++ b/tools/c-arcmt-test/Makefile
@@ -0,0 +1,25 @@
+##===- tools/c-arcmt-test/Makefile -------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+CLANG_LEVEL := ../..
+
+TOOLNAME = c-arcmt-test
+
+# No plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+# Don't install this. It is used for tests.
+NO_INSTALL = 1
+
+LINK_COMPONENTS := support mc
+USEDLIBS = clang.a clangIndex.a clangARCMigrate.a clangRewrite.a \
+ clangFrontend.a clangDriver.a \
+ clangSerialization.a clangParse.a clangSema.a \
+ clangAnalysis.a clangAST.a clangLex.a clangBasic.a
+
+include $(CLANG_LEVEL)/Makefile
diff --git a/tools/c-arcmt-test/c-arcmt-test.c b/tools/c-arcmt-test/c-arcmt-test.c
new file mode 100644
index 000000000000..5522b33e23a5
--- /dev/null
+++ b/tools/c-arcmt-test/c-arcmt-test.c
@@ -0,0 +1,91 @@
+/* c-arcmt-test.c */
+
+#include "clang-c/Index.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#if defined(_WIN32)
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+static int print_remappings(const char *path) {
+ CXRemapping remap;
+ unsigned i, N;
+ CXString origFname;
+ CXString transFname;
+
+ remap = clang_getRemappings(path);
+ if (!remap)
+ return 1;
+
+ N = clang_remap_getNumFiles(remap);
+ for (i = 0; i != N; ++i) {
+ clang_remap_getFilenames(remap, i, &origFname, &transFname);
+
+ fprintf(stdout, "%s\n", clang_getCString(origFname));
+ fprintf(stdout, "%s\n", clang_getCString(transFname));
+
+ clang_disposeString(origFname);
+ clang_disposeString(transFname);
+ }
+
+ clang_remap_dispose(remap);
+ return 0;
+}
+
+/******************************************************************************/
+/* Command line processing. */
+/******************************************************************************/
+
+static void print_usage(void) {
+ fprintf(stderr,
+ "usage: c-arcmt-test -arcmt-migrate-directory <path>\n\n\n");
+}
+
+/***/
+
+int carcmttest_main(int argc, const char **argv) {
+ clang_enableStackTraces();
+ if (argc == 3 && strncmp(argv[1], "-arcmt-migrate-directory", 24) == 0)
+ return print_remappings(argv[2]);
+
+ print_usage();
+ return 1;
+}
+
+/***/
+
+/* We intentionally run in a separate thread to ensure we at least minimal
+ * testing of a multithreaded environment (for example, having a reduced stack
+ * size). */
+
+typedef struct thread_info {
+ int argc;
+ const char **argv;
+ int result;
+} thread_info;
+void thread_runner(void *client_data_v) {
+ thread_info *client_data = client_data_v;
+ client_data->result = carcmttest_main(client_data->argc, client_data->argv);
+}
+
+int main(int argc, const char **argv) {
+ thread_info client_data;
+
+#if defined(_WIN32)
+ if (getenv("LIBCLANG_LOGGING") == NULL)
+ putenv("LIBCLANG_LOGGING=1");
+ _setmode( _fileno(stdout), _O_BINARY );
+#else
+ setenv("LIBCLANG_LOGGING", "1", /*overwrite=*/0);
+#endif
+
+ if (getenv("CINDEXTEST_NOTHREADS"))
+ return carcmttest_main(argc, argv);
+
+ client_data.argc = argc;
+ client_data.argv = argv;
+ clang_executeOnThread(thread_runner, &client_data, 0);
+ return client_data.result;
+}
diff --git a/tools/c-index-test/Makefile b/tools/c-index-test/Makefile
index 68064041f435..5e5b8570c812 100644
--- a/tools/c-index-test/Makefile
+++ b/tools/c-index-test/Makefile
@@ -18,7 +18,7 @@ NO_INSTALL = 1
LINK_COMPONENTS := support mc
USEDLIBS = clang.a clangIndex.a clangFrontend.a clangDriver.a \
- clangSerialization.a clangParse.a clangSema.a clangAnalysis.a \
- clangAST.a clangLex.a clangBasic.a
+ clangSerialization.a clangParse.a clangSema.a \
+ clangAnalysis.a clangAST.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 837fc8929e52..6e0aaac73cc3 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -38,7 +38,7 @@ static unsigned getDefaultParsingOptions() {
if (getenv("CINDEXTEST_COMPLETION_CACHING"))
options |= CXTranslationUnit_CacheCompletionResults;
if (getenv("CINDEXTEST_NESTED_MACROS"))
- options |= CXTranslationUnit_NestedMacroInstantiations;
+ options |= CXTranslationUnit_NestedMacroExpansions;
return options;
}
@@ -1018,6 +1018,79 @@ void print_completion_result(CXCompletionResult *completion_result,
fprintf(file, "\n");
}
+void print_completion_contexts(unsigned long long contexts, FILE *file) {
+ fprintf(file, "Completion contexts:\n");
+ if (contexts == CXCompletionContext_Unknown) {
+ fprintf(file, "Unknown\n");
+ }
+ if (contexts & CXCompletionContext_AnyType) {
+ fprintf(file, "Any type\n");
+ }
+ if (contexts & CXCompletionContext_AnyValue) {
+ fprintf(file, "Any value\n");
+ }
+ if (contexts & CXCompletionContext_ObjCObjectValue) {
+ fprintf(file, "Objective-C object value\n");
+ }
+ if (contexts & CXCompletionContext_ObjCSelectorValue) {
+ fprintf(file, "Objective-C selector value\n");
+ }
+ if (contexts & CXCompletionContext_CXXClassTypeValue) {
+ fprintf(file, "C++ class type value\n");
+ }
+ if (contexts & CXCompletionContext_DotMemberAccess) {
+ fprintf(file, "Dot member access\n");
+ }
+ if (contexts & CXCompletionContext_ArrowMemberAccess) {
+ fprintf(file, "Arrow member access\n");
+ }
+ if (contexts & CXCompletionContext_ObjCPropertyAccess) {
+ fprintf(file, "Objective-C property access\n");
+ }
+ if (contexts & CXCompletionContext_EnumTag) {
+ fprintf(file, "Enum tag\n");
+ }
+ if (contexts & CXCompletionContext_UnionTag) {
+ fprintf(file, "Union tag\n");
+ }
+ if (contexts & CXCompletionContext_StructTag) {
+ fprintf(file, "Struct tag\n");
+ }
+ if (contexts & CXCompletionContext_ClassTag) {
+ fprintf(file, "Class name\n");
+ }
+ if (contexts & CXCompletionContext_Namespace) {
+ fprintf(file, "Namespace or namespace alias\n");
+ }
+ if (contexts & CXCompletionContext_NestedNameSpecifier) {
+ fprintf(file, "Nested name specifier\n");
+ }
+ if (contexts & CXCompletionContext_ObjCInterface) {
+ fprintf(file, "Objective-C interface\n");
+ }
+ if (contexts & CXCompletionContext_ObjCProtocol) {
+ fprintf(file, "Objective-C protocol\n");
+ }
+ if (contexts & CXCompletionContext_ObjCCategory) {
+ fprintf(file, "Objective-C category\n");
+ }
+ if (contexts & CXCompletionContext_ObjCInstanceMessage) {
+ fprintf(file, "Objective-C instance method\n");
+ }
+ if (contexts & CXCompletionContext_ObjCClassMessage) {
+ fprintf(file, "Objective-C class method\n");
+ }
+ if (contexts & CXCompletionContext_ObjCSelectorName) {
+ fprintf(file, "Objective-C selector name\n");
+ }
+ if (contexts & CXCompletionContext_MacroName) {
+ fprintf(file, "Macro name\n");
+ }
+ if (contexts & CXCompletionContext_NaturalLanguage) {
+ fprintf(file, "Natural language\n");
+ }
+}
+
int my_stricmp(const char *s1, const char *s2) {
while (*s1 && *s2) {
int c1 = tolower((unsigned char)*s1), c2 = tolower((unsigned char)*s2);
@@ -1099,6 +1172,7 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
if (results) {
unsigned i, n = results->NumResults;
+ unsigned long long contexts;
if (!timing_only) {
/* Sort the code-completion results based on the typed text. */
clang_sortCodeCompletionResults(results->Results, results->NumResults);
@@ -1112,6 +1186,10 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
PrintDiagnostic(diag);
clang_disposeDiagnostic(diag);
}
+
+ contexts = clang_codeCompleteGetContexts(results);
+ print_completion_contexts(contexts, stdout);
+
clang_disposeCodeCompleteResults(results);
}
clang_disposeTranslationUnit(TU);
@@ -1496,6 +1574,7 @@ int write_pch_file(const char *filename, int argc, const char *argv[]) {
CXTranslationUnit TU;
struct CXUnsavedFile *unsaved_files = 0;
int num_unsaved_files = 0;
+ int result = 0;
Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnosics=*/1);
@@ -1517,12 +1596,34 @@ int write_pch_file(const char *filename, int argc, const char *argv[]) {
return 1;
}
- if (clang_saveTranslationUnit(TU, filename, clang_defaultSaveOptions(TU)))
- fprintf(stderr, "Unable to write PCH file %s\n", filename);
+ switch (clang_saveTranslationUnit(TU, filename,
+ clang_defaultSaveOptions(TU))) {
+ case CXSaveError_None:
+ break;
+
+ case CXSaveError_TranslationErrors:
+ fprintf(stderr, "Unable to write PCH file %s: translation errors\n",
+ filename);
+ result = 2;
+ break;
+
+ case CXSaveError_InvalidTU:
+ fprintf(stderr, "Unable to write PCH file %s: invalid translation unit\n",
+ filename);
+ result = 3;
+ break;
+
+ case CXSaveError_Unknown:
+ default:
+ fprintf(stderr, "Unable to write PCH file %s: unknown error \n", filename);
+ result = 1;
+ break;
+ }
+
clang_disposeTranslationUnit(TU);
free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
- return 0;
+ return result;
}
/******************************************************************************/
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index 0c41490175e9..e6d0f1ac3763 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -9,6 +9,7 @@ set( LLVM_USED_LIBS
clangIndex
clangLex
clangParse
+ clangARCMigrate
clangRewrite
clangSema
clangSerialization
diff --git a/tools/driver/Makefile b/tools/driver/Makefile
index abe70983df42..1ba8bc24d1fb 100644
--- a/tools/driver/Makefile
+++ b/tools/driver/Makefile
@@ -41,7 +41,7 @@ USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \
clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
clangStaticAnalyzerCore.a \
- clangAnalysis.a clangIndex.a clangRewrite.a \
+ clangAnalysis.a clangIndex.a clangARCMigrate.a clangRewrite.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 535eaa9c96f8..9ad4af1436ca 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -126,6 +126,8 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd,
// Initialize targets first, so that --version shows registered targets.
llvm::InitializeAllTargets();
+ llvm::InitializeAllMCAsmInfos();
+ llvm::InitializeAllMCSubtargetInfos();
llvm::InitializeAllAsmPrinters();
llvm::InitializeAllAsmParsers();
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index f449235db4c4..358d746986c8 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -29,7 +29,9 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/ErrorHandling.h"
@@ -47,11 +49,13 @@
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetAsmParser.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetSelect.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
using namespace clang;
using namespace clang::driver;
using namespace llvm;
@@ -252,7 +256,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
// it later.
SrcMgr.setIncludeDirs(Opts.IncludePaths);
- OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(Opts.Triple));
+ OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(Opts.Triple));
assert(MAI && "Unable to create target asm info!");
bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
@@ -261,7 +265,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
return false;
// FIXME: We shouldn't need to do this (and link in codegen).
- OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(Opts.Triple, ""));
+ OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(Opts.Triple,
+ "", ""));
if (!TM) {
Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
return false;
@@ -278,14 +283,16 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
TM->getTargetLowering()->getObjFileLowering();
const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(Ctx, *TM);
+ const MCSubtargetInfo &STI = TM->getSubtarget<MCSubtargetInfo>();
+
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
MCInstPrinter *IP =
- TheTarget->createMCInstPrinter(*TM, Opts.OutputAsmVariant, *MAI);
+ TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI);
MCCodeEmitter *CE = 0;
TargetAsmBackend *TAB = 0;
if (Opts.ShowEncoding) {
- CE = TheTarget->createCodeEmitter(*TM, Ctx);
+ CE = TheTarget->createCodeEmitter(*TM->getInstrInfo(), STI, Ctx);
TAB = TheTarget->createAsmBackend(Opts.Triple);
}
Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
@@ -297,7 +304,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
} else {
assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
"Invalid file type!");
- MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx);
+ MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM->getInstrInfo(),
+ STI, Ctx);
TargetAsmBackend *TAB = TheTarget->createAsmBackend(Opts.Triple);
Str.reset(TheTarget->createObjectStreamer(Opts.Triple, Ctx, *TAB, *Out,
CE, Opts.RelaxAll,
@@ -307,7 +315,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx,
*Str.get(), *MAI));
- OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*Parser, *TM));
+ OwningPtr<TargetAsmParser>
+ TAP(TheTarget->createAsmParser(const_cast<MCSubtargetInfo&>(STI), *Parser));
if (!TAP) {
Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
return false;
@@ -347,6 +356,9 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd,
InitializeAllTargetInfos();
// FIXME: We shouldn't need to initialize the Target(Machine)s.
InitializeAllTargets();
+ InitializeAllMCAsmInfos();
+ InitializeAllMCInstrInfos();
+ InitializeAllMCSubtargetInfos();
InitializeAllAsmPrinters();
InitializeAllAsmParsers();
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index db72da42ea34..ca8982619e94 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -327,9 +327,11 @@ static void ParseProgName(llvm::SmallVectorImpl<const char *> &ArgVector,
std::string IgnoredError;
if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
- ArgVector.insert(&ArgVector[1],
- SaveStringInSet(SavedStrings, Prefix));
- ArgVector.insert(&ArgVector[1],
+ llvm::SmallVectorImpl<const char *>::iterator it = ArgVector.begin();
+ if (it != ArgVector.end())
+ ++it;
+ ArgVector.insert(it, SaveStringInSet(SavedStrings, Prefix));
+ ArgVector.insert(it,
SaveStringInSet(SavedStrings, std::string("-ccc-host-triple")));
}
}
diff --git a/tools/libclang/ARCMigrate.cpp b/tools/libclang/ARCMigrate.cpp
new file mode 100644
index 000000000000..39c7d84d5190
--- /dev/null
+++ b/tools/libclang/ARCMigrate.cpp
@@ -0,0 +1,98 @@
+//===- ARCMigrate.cpp - Clang-C ARC Migration Library ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the main API hooks in the Clang-C ARC Migration library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-c/Index.h"
+
+#include "CXString.h"
+#include "clang/ARCMigrate/ARCMT.h"
+#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "llvm/Support/FileSystem.h"
+
+using namespace clang;
+using namespace arcmt;
+
+namespace {
+
+struct Remap {
+ std::vector<std::pair<std::string, std::string> > Vec;
+};
+
+} // anonymous namespace.
+
+//===----------------------------------------------------------------------===//
+// libClang public APIs.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+
+CXRemapping clang_getRemappings(const char *migrate_dir_path) {
+ bool Logging = ::getenv("LIBCLANG_LOGGING");
+
+ if (!migrate_dir_path) {
+ if (Logging)
+ llvm::errs() << "clang_getRemappings was called with NULL parameter\n";
+ return 0;
+ }
+
+ bool exists = false;
+ llvm::sys::fs::exists(migrate_dir_path, exists);
+ if (!exists) {
+ if (Logging) {
+ llvm::errs() << "Error by clang_getRemappings(\"" << migrate_dir_path
+ << "\")\n";
+ llvm::errs() << "\"" << migrate_dir_path << "\" does not exist\n";
+ }
+ return 0;
+ }
+
+ TextDiagnosticBuffer diagBuffer;
+ llvm::OwningPtr<Remap> remap(new Remap());
+
+ bool err = arcmt::getFileRemappings(remap->Vec, migrate_dir_path,&diagBuffer);
+
+ if (err) {
+ if (Logging) {
+ llvm::errs() << "Error by clang_getRemappings(\"" << migrate_dir_path
+ << "\")\n";
+ for (TextDiagnosticBuffer::const_iterator
+ I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I)
+ llvm::errs() << I->second << '\n';
+ }
+ return 0;
+ }
+
+ return remap.take();
+}
+
+unsigned clang_remap_getNumFiles(CXRemapping map) {
+ return static_cast<Remap *>(map)->Vec.size();
+
+}
+
+void clang_remap_getFilenames(CXRemapping map, unsigned index,
+ CXString *original, CXString *transformed) {
+ if (original)
+ *original = cxstring::createCXString(
+ static_cast<Remap *>(map)->Vec[index].first,
+ /*DupString =*/ true);
+ if (transformed)
+ *transformed = cxstring::createCXString(
+ static_cast<Remap *>(map)->Vec[index].second,
+ /*DupString =*/ true);
+}
+
+void clang_remap_dispose(CXRemapping map) {
+ delete static_cast<Remap *>(map);
+}
+
+} // end: extern "C"
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 2a9d96db4c35..50d56fccb9c5 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -544,8 +544,8 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
// do so.
PreprocessingRecord::iterator E, EEnd;
for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
- if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
- if (Visit(MakeMacroInstantiationCursor(MI, tu)))
+ if (MacroExpansion *ME = dyn_cast<MacroExpansion>(*E)) {
+ if (Visit(MakeMacroExpansionCursor(ME, tu)))
return true;
continue;
@@ -1330,6 +1330,11 @@ bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
return Visit(MakeCursorTemplateRef(
Name.getAsQualifiedTemplateName()->getDecl(),
Loc, TU));
+
+ case TemplateName::SubstTemplateTemplateParm:
+ return Visit(MakeCursorTemplateRef(
+ Name.getAsSubstTemplateTemplateParm()->getParameter(),
+ Loc, TU));
case TemplateName::SubstTemplateTemplateParmPack:
return Visit(MakeCursorTemplateRef(
@@ -2374,7 +2379,8 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
unsigned clang_defaultEditingTranslationUnitOptions() {
return CXTranslationUnit_PrecompiledPreamble |
CXTranslationUnit_CacheCompletionResults |
- CXTranslationUnit_CXXPrecompiledPreamble;
+ CXTranslationUnit_CXXPrecompiledPreamble |
+ CXTranslationUnit_CXXChainedPCH;
}
CXTranslationUnit
@@ -2385,7 +2391,7 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
unsigned num_unsaved_files,
struct CXUnsavedFile *unsaved_files) {
unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord |
- CXTranslationUnit_NestedMacroInstantiations;
+ CXTranslationUnit_NestedMacroExpansions;
return clang_parseTranslationUnit(CIdx, source_filename,
command_line_args, num_command_line_args,
unsaved_files, num_unsaved_files,
@@ -2490,12 +2496,12 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
Args->push_back(source_filename);
// Do we need the detailed preprocessing record?
- bool NestedMacroInstantiations = false;
+ bool NestedMacroExpansions = false;
if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Args->push_back("-Xclang");
Args->push_back("-detailed-preprocessing-record");
- NestedMacroInstantiations
- = (options & CXTranslationUnit_NestedMacroInstantiations);
+ NestedMacroExpansions
+ = (options & CXTranslationUnit_NestedMacroExpansions);
}
unsigned NumErrors = Diags->getClient()->getNumErrors();
@@ -2515,7 +2521,7 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
CacheCodeCompetionResults,
CXXPrecompilePreamble,
CXXChainedPCH,
- NestedMacroInstantiations));
+ NestedMacroExpansions));
if (NumErrors != Diags->getClient()->getNumErrors()) {
// Make sure to check that 'Unit' is non-NULL.
@@ -2588,9 +2594,9 @@ unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
unsigned options) {
if (!TU)
- return 1;
+ return CXSaveError_InvalidTU;
- int result = static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
+ CXSaveError result = static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
if (getenv("LIBCLANG_RESOURCE_USAGE"))
PrintLibclangResourceUsage(TU);
return result;
@@ -2800,7 +2806,7 @@ void clang_getInstantiationLocation(CXSourceLocation location,
*static_cast<const SourceManager*>(location.ptr_data[0]);
SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
- // Check that the FileID is invalid on the instantiation location.
+ // Check that the FileID is invalid on the expansion location.
// This can manifest in invalid code.
FileID fileID = SM.getFileID(InstLoc);
bool Invalid = false;
@@ -3145,8 +3151,8 @@ CXString clang_getCursorSpelling(CXCursor C) {
return createCXString("");
}
- if (C.kind == CXCursor_MacroInstantiation)
- return createCXString(getCursorMacroInstantiation(C)->getName()
+ if (C.kind == CXCursor_MacroExpansion)
+ return createCXString(getCursorMacroExpansion(C)->getName()
->getNameStart());
if (C.kind == CXCursor_MacroDefinition)
@@ -3346,8 +3352,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return createCXString("preprocessing directive");
case CXCursor_MacroDefinition:
return createCXString("macro definition");
- case CXCursor_MacroInstantiation:
- return createCXString("macro instantiation");
+ case CXCursor_MacroExpansion:
+ return createCXString("macro expansion");
case CXCursor_InclusionDirective:
return createCXString("inclusion directive");
case CXCursor_Namespace:
@@ -3392,11 +3398,34 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return createCXString((const char*) 0);
}
+struct GetCursorData {
+ SourceLocation TokenBeginLoc;
+ CXCursor &BestCursor;
+
+ GetCursorData(SourceLocation tokenBegin, CXCursor &outputCursor)
+ : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) { }
+};
+
enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
CXCursor parent,
CXClientData client_data) {
- CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
-
+ GetCursorData *Data = static_cast<GetCursorData *>(client_data);
+ CXCursor *BestCursor = &Data->BestCursor;
+
+ if (clang_isExpression(cursor.kind) &&
+ clang_isDeclaration(BestCursor->kind)) {
+ Decl *D = getCursorDecl(*BestCursor);
+
+ // Avoid having the cursor of an expression replace the declaration cursor
+ // when the expression source range overlaps the declaration range.
+ // This can happen for C++ constructor expressions whose range generally
+ // include the variable declaration, e.g.:
+ // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
+ if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
+ D->getLocation() == Data->TokenBeginLoc)
+ return CXChildVisit_Break;
+ }
+
// If our current best cursor is the construction of a temporary object,
// don't replace that cursor with a type reference, because we want
// clang_getCursor() to point at the constructor.
@@ -3440,8 +3469,9 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
// FIXME: Would be great to have a "hint" cursor, then walk from that
// hint cursor upward until we find a cursor whose source range encloses
// the region of interest, rather than starting from the translation unit.
+ GetCursorData ResultData(SLoc, Result);
CXCursor Parent = clang_getTranslationUnitCursor(TU);
- CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
+ CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Decl::MaxPCHLevel, true, SourceLocation(SLoc));
CursorVis.VisitChildren(Parent);
}
@@ -3532,6 +3562,10 @@ unsigned clang_isStatement(enum CXCursorKind K) {
return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
}
+unsigned clang_isAttribute(enum CXCursorKind K) {
+ return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
+}
+
unsigned clang_isTranslationUnit(enum CXCursorKind K) {
return K == CXCursor_TranslationUnit;
}
@@ -3638,9 +3672,9 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
return cxloc::translateSourceLocation(getCursorContext(C), L);
}
- if (C.kind == CXCursor_MacroInstantiation) {
+ if (C.kind == CXCursor_MacroExpansion) {
SourceLocation L
- = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
+ = cxcursor::getCursorMacroExpansion(C)->getSourceRange().getBegin();
return cxloc::translateSourceLocation(getCursorContext(C), L);
}
@@ -3725,8 +3759,8 @@ static SourceRange getRawCursorExtent(CXCursor C) {
if (C.kind == CXCursor_PreprocessingDirective)
return cxcursor::getCursorPreprocessingDirective(C);
- if (C.kind == CXCursor_MacroInstantiation)
- return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
+ if (C.kind == CXCursor_MacroExpansion)
+ return cxcursor::getCursorMacroExpansion(C)->getSourceRange();
if (C.kind == CXCursor_MacroDefinition)
return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
@@ -3842,8 +3876,8 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
return clang_getNullCursor();
}
- if (C.kind == CXCursor_MacroInstantiation) {
- if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
+ if (C.kind == CXCursor_MacroExpansion) {
+ if (MacroDefinition *Def = getCursorMacroExpansion(C)->getDefinition())
return MakeMacroDefinitionCursor(Def, tu);
}
@@ -3911,7 +3945,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
WasReference = true;
}
- if (C.kind == CXCursor_MacroInstantiation)
+ if (C.kind == CXCursor_MacroExpansion)
return clang_getCursorReferenced(C);
if (!clang_isDeclaration(C.kind))
@@ -4107,8 +4141,17 @@ CXCursor clang_getCanonicalCursor(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return C;
- if (Decl *D = getCursorDecl(C))
+ if (Decl *D = getCursorDecl(C)) {
+ if (ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
+ if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
+ return MakeCXCursor(CatD, getCursorTU(C));
+
+ if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
+ if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
+ return MakeCXCursor(IFD, getCursorTU(C));
+
return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
+ }
return C;
}
@@ -4507,9 +4550,9 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
}
if (clang_isPreprocessing(cursor.kind)) {
- // For macro instantiations, just note where the beginning of the macro
- // instantiation occurs.
- if (cursor.kind == CXCursor_MacroInstantiation) {
+ // For macro expansions, just note where the beginning of the macro
+ // expansion occurs.
+ if (cursor.kind == CXCursor_MacroExpansion) {
Annotated[Loc.int_data] = cursor;
return CXChildVisit_Recurse;
}
@@ -4626,6 +4669,24 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
break;
}
+ // Avoid having the cursor of an expression "overwrite" the annotation of the
+ // variable declaration that it belongs to.
+ // 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)) {
+ Expr *E = getCursorExpr(cursor);
+ if (Decl *D = getCursorParentDecl(cursor)) {
+ const unsigned I = NextToken();
+ if (E->getLocStart().isValid() && D->getLocation().isValid() &&
+ E->getLocStart() == D->getLocation() &&
+ E->getLocStart() == GetTokenLoc(I)) {
+ Cursors[I] = updateC;
+ AdvanceToken();
+ }
+ }
+ }
+
// Visit children to get their cursor information.
const unsigned BeforeChildren = NextToken();
VisitChildren(cursor);
@@ -4797,6 +4858,7 @@ static void clang_annotateTokensImpl(void *UserData) {
llvm::StringSwitch<bool>(II->getName())
.Case("readonly", true)
.Case("assign", true)
+ .Case("unsafe_unretained", true)
.Case("readwrite", true)
.Case("retain", true)
.Case("copy", true)
@@ -4804,6 +4866,8 @@ static void clang_annotateTokensImpl(void *UserData) {
.Case("atomic", true)
.Case("getter", true)
.Case("setter", true)
+ .Case("strong", true)
+ .Case("weak", true)
.Default(false))
Tokens[I].int_data[0] = CXToken_Keyword;
}
@@ -5354,10 +5418,9 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
// How much memory is being used by the Preprocessor?
Preprocessor &pp = astUnit->getPreprocessor();
- const llvm::BumpPtrAllocator &ppAlloc = pp.getPreprocessorAllocator();
createCXTUResourceUsageEntry(*entries,
CXTUResourceUsage_Preprocessor,
- ppAlloc.getTotalMemory());
+ pp.getTotalMemory());
if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
createCXTUResourceUsageEntry(*entries,
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 0c8317e4461f..832e2f2f7147 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -235,6 +235,13 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// \brief Allocator used to store code completion results.
clang::CodeCompletionAllocator CodeCompletionAllocator;
+
+ /// \brief Context under which completion occurred.
+ enum clang::CodeCompletionContext::Kind ContextKind;
+
+ /// \brief A bitfield representing the acceptable completions for the
+ /// current context.
+ unsigned long long Contexts;
};
/// \brief Tracks the number of code-completion result objects that are
@@ -273,6 +280,177 @@ AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
} // end extern "C"
+static unsigned long long getContextsForContextKind(
+ enum CodeCompletionContext::Kind kind,
+ Sema &S) {
+ unsigned long long contexts = 0;
+ switch (kind) {
+ case CodeCompletionContext::CCC_OtherWithMacros: {
+ //We can allow macros here, but we don't know what else is permissible
+ //So we'll say the only thing permissible are macros
+ contexts = CXCompletionContext_MacroName;
+ break;
+ }
+ case CodeCompletionContext::CCC_TopLevel:
+ case CodeCompletionContext::CCC_ObjCIvarList:
+ case CodeCompletionContext::CCC_ClassStructUnion:
+ case CodeCompletionContext::CCC_Type: {
+ contexts = CXCompletionContext_AnyType |
+ CXCompletionContext_ObjCInterface;
+ if (S.getLangOptions().CPlusPlus) {
+ contexts |= CXCompletionContext_EnumTag |
+ CXCompletionContext_UnionTag |
+ CXCompletionContext_StructTag |
+ CXCompletionContext_ClassTag |
+ CXCompletionContext_NestedNameSpecifier;
+ }
+ break;
+ }
+ case CodeCompletionContext::CCC_Statement: {
+ contexts = CXCompletionContext_AnyType |
+ CXCompletionContext_ObjCInterface |
+ CXCompletionContext_AnyValue;
+ if (S.getLangOptions().CPlusPlus) {
+ contexts |= CXCompletionContext_EnumTag |
+ CXCompletionContext_UnionTag |
+ CXCompletionContext_StructTag |
+ CXCompletionContext_ClassTag |
+ CXCompletionContext_NestedNameSpecifier;
+ }
+ break;
+ }
+ case CodeCompletionContext::CCC_Expression: {
+ contexts = CXCompletionContext_AnyValue;
+ if (S.getLangOptions().CPlusPlus) {
+ contexts |= CXCompletionContext_AnyType |
+ CXCompletionContext_ObjCInterface |
+ CXCompletionContext_EnumTag |
+ CXCompletionContext_UnionTag |
+ CXCompletionContext_StructTag |
+ CXCompletionContext_ClassTag |
+ CXCompletionContext_NestedNameSpecifier;
+ }
+ break;
+ }
+ case CodeCompletionContext::CCC_ObjCMessageReceiver: {
+ contexts = CXCompletionContext_ObjCObjectValue |
+ CXCompletionContext_ObjCSelectorValue |
+ CXCompletionContext_ObjCInterface;
+ if (S.getLangOptions().CPlusPlus) {
+ contexts |= CXCompletionContext_CXXClassTypeValue |
+ CXCompletionContext_AnyType |
+ CXCompletionContext_EnumTag |
+ CXCompletionContext_UnionTag |
+ CXCompletionContext_StructTag |
+ CXCompletionContext_ClassTag |
+ CXCompletionContext_NestedNameSpecifier;
+ }
+ break;
+ }
+ case CodeCompletionContext::CCC_DotMemberAccess: {
+ contexts = CXCompletionContext_DotMemberAccess;
+ break;
+ }
+ case CodeCompletionContext::CCC_ArrowMemberAccess: {
+ contexts = CXCompletionContext_ArrowMemberAccess;
+ break;
+ }
+ case CodeCompletionContext::CCC_ObjCPropertyAccess: {
+ contexts = CXCompletionContext_ObjCPropertyAccess;
+ break;
+ }
+ case CodeCompletionContext::CCC_EnumTag: {
+ contexts = CXCompletionContext_EnumTag |
+ CXCompletionContext_NestedNameSpecifier;
+ break;
+ }
+ case CodeCompletionContext::CCC_UnionTag: {
+ contexts = CXCompletionContext_UnionTag |
+ CXCompletionContext_NestedNameSpecifier;
+ break;
+ }
+ case CodeCompletionContext::CCC_ClassOrStructTag: {
+ contexts = CXCompletionContext_StructTag |
+ CXCompletionContext_ClassTag |
+ CXCompletionContext_NestedNameSpecifier;
+ break;
+ }
+ case CodeCompletionContext::CCC_ObjCProtocolName: {
+ contexts = CXCompletionContext_ObjCProtocol;
+ break;
+ }
+ case CodeCompletionContext::CCC_Namespace: {
+ contexts = CXCompletionContext_Namespace;
+ break;
+ }
+ case CodeCompletionContext::CCC_PotentiallyQualifiedName: {
+ contexts = CXCompletionContext_NestedNameSpecifier;
+ break;
+ }
+ case CodeCompletionContext::CCC_MacroNameUse: {
+ contexts = CXCompletionContext_MacroName;
+ break;
+ }
+ case CodeCompletionContext::CCC_NaturalLanguage: {
+ contexts = CXCompletionContext_NaturalLanguage;
+ break;
+ }
+ case CodeCompletionContext::CCC_SelectorName: {
+ contexts = CXCompletionContext_ObjCSelectorName;
+ break;
+ }
+ case CodeCompletionContext::CCC_ParenthesizedExpression: {
+ contexts = CXCompletionContext_AnyType |
+ CXCompletionContext_ObjCInterface |
+ CXCompletionContext_AnyValue;
+ if (S.getLangOptions().CPlusPlus) {
+ contexts |= CXCompletionContext_EnumTag |
+ CXCompletionContext_UnionTag |
+ CXCompletionContext_StructTag |
+ CXCompletionContext_ClassTag |
+ CXCompletionContext_NestedNameSpecifier;
+ }
+ break;
+ }
+ case CodeCompletionContext::CCC_ObjCInstanceMessage: {
+ contexts = CXCompletionContext_ObjCInstanceMessage;
+ break;
+ }
+ case CodeCompletionContext::CCC_ObjCClassMessage: {
+ contexts = CXCompletionContext_ObjCClassMessage;
+ break;
+ }
+ case CodeCompletionContext::CCC_ObjCSuperclass: {
+ contexts = CXCompletionContext_ObjCInterface;
+ break;
+ }
+ case CodeCompletionContext::CCC_ObjCCategoryName: {
+ contexts = CXCompletionContext_ObjCCategory;
+ break;
+ }
+ case CodeCompletionContext::CCC_Other:
+ case CodeCompletionContext::CCC_ObjCInterface:
+ case CodeCompletionContext::CCC_ObjCImplementation:
+ case CodeCompletionContext::CCC_Name:
+ case CodeCompletionContext::CCC_MacroName:
+ case CodeCompletionContext::CCC_PreprocessorExpression:
+ case CodeCompletionContext::CCC_PreprocessorDirective:
+ case CodeCompletionContext::CCC_TypeQualifiers: {
+ //Only Clang results should be accepted, so we'll set all of the other
+ //context bits to 0 (i.e. the empty set)
+ contexts = CXCompletionContext_Unexposed;
+ break;
+ }
+ case CodeCompletionContext::CCC_Recovery: {
+ //We don't know what the current context is, so we'll return unknown
+ //This is the equivalent of setting all of the other context bits
+ contexts = CXCompletionContext_Unknown;
+ break;
+ }
+ }
+ return contexts;
+}
+
namespace {
class CaptureCompletionResults : public CodeCompleteConsumer {
AllocatedCXCodeCompleteResults &AllocatedResults;
@@ -298,6 +476,11 @@ namespace {
R.CompletionString = StoredCompletion;
StoredResults.push_back(R);
}
+
+ enum CodeCompletionContext::Kind kind = Context.getKind();
+
+ AllocatedResults.ContextKind = kind;
+ AllocatedResults.Contexts = getContextsForContextKind(kind, S);
}
virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
@@ -538,6 +721,15 @@ clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
}
+unsigned long long
+clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
+ AllocatedCXCodeCompleteResults *Results
+ = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
+ if (!Results)
+ return 0;
+
+ return Results->Contexts;
+}
} // end extern "C"
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index 7a6270d17647..f45389f0b9f4 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -1,4 +1,6 @@
set(LLVM_USED_LIBS
+ clangARCMigrate
+ clangRewrite
clangFrontend
clangDriver
clangSerialization
@@ -14,6 +16,7 @@ set( LLVM_LINK_COMPONENTS
)
set(SOURCES
+ ARCMigrate.cpp
CIndex.cpp
CIndexCXX.cpp
CIndexCodeCompletion.cpp
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index b34370d2e652..b3c57dc9344f 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -92,6 +92,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
case Stmt::ObjCAtFinallyStmtClass:
case Stmt::ObjCAtThrowStmtClass:
case Stmt::ObjCAtSynchronizedStmtClass:
+ case Stmt::ObjCAutoreleasePoolStmtClass:
case Stmt::ObjCForCollectionStmtClass:
case Stmt::CXXCatchStmtClass:
case Stmt::CXXTryStmtClass:
@@ -99,6 +100,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
case Stmt::SEHTryStmtClass:
case Stmt::SEHExceptStmtClass:
case Stmt::SEHFinallyStmtClass:
+ case Stmt::MaterializeTemporaryExprClass:
K = CXCursor_UnexposedStmt;
break;
@@ -167,7 +169,9 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
case Stmt::ObjCEncodeExprClass:
case Stmt::ObjCSelectorExprClass:
case Stmt::ObjCProtocolExprClass:
- case Stmt::ObjCIsaExprClass:
+ case Stmt::ObjCIsaExprClass:
+ case Stmt::ObjCIndirectCopyRestoreExprClass:
+ case Stmt::ObjCBridgedCastExprClass:
case Stmt::ShuffleVectorExprClass:
case Stmt::BlockExprClass:
case Stmt::OpaqueValueExprClass:
@@ -179,6 +183,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
case Stmt::DeclRefExprClass:
case Stmt::BlockDeclRefExprClass:
+ case Stmt::SubstNonTypeTemplateParmExprClass:
case Stmt::SubstNonTypeTemplateParmPackExprClass:
// FIXME: UnresolvedLookupExpr?
// FIXME: DependentScopeDeclRefExpr?
@@ -374,15 +379,15 @@ MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
return static_cast<MacroDefinition *>(C.data[0]);
}
-CXCursor cxcursor::MakeMacroInstantiationCursor(MacroInstantiation *MI,
- CXTranslationUnit TU) {
- CXCursor C = { CXCursor_MacroInstantiation, { MI, 0, TU } };
+CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
+ CXTranslationUnit TU) {
+ CXCursor C = { CXCursor_MacroExpansion, { MI, 0, TU } };
return C;
}
-MacroInstantiation *cxcursor::getCursorMacroInstantiation(CXCursor C) {
- assert(C.kind == CXCursor_MacroInstantiation);
- return static_cast<MacroInstantiation *>(C.data[0]);
+MacroExpansion *cxcursor::getCursorMacroExpansion(CXCursor C) {
+ assert(C.kind == CXCursor_MacroExpansion);
+ return static_cast<MacroExpansion *>(C.data[0]);
}
CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
@@ -480,6 +485,10 @@ Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
return (Attr *)Cursor.data[1];
}
+Decl *cxcursor::getCursorParentDecl(CXCursor Cursor) {
+ return (Decl *)Cursor.data[0];
+}
+
ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
return getCursorASTUnit(Cursor)->getASTContext();
}
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index 11f2500fb144..68d09e76c1c0 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -31,7 +31,7 @@ class FieldDecl;
class InclusionDirective;
class LabelStmt;
class MacroDefinition;
-class MacroInstantiation;
+class MacroExpansion;
class NamedDecl;
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
@@ -134,13 +134,13 @@ CXCursor MakeMacroDefinitionCursor(MacroDefinition *, CXTranslationUnit TU);
/// source range.
MacroDefinition *getCursorMacroDefinition(CXCursor C);
-/// \brief Create a macro instantiation cursor.
-CXCursor MakeMacroInstantiationCursor(MacroInstantiation *,
- CXTranslationUnit TU);
+/// \brief Create a macro expansion cursor.
+CXCursor MakeMacroExpansionCursor(MacroExpansion *,
+ CXTranslationUnit TU);
-/// \brief Unpack a given macro instantiation cursor to retrieve its
+/// \brief Unpack a given macro expansion cursor to retrieve its
/// source range.
-MacroInstantiation *getCursorMacroInstantiation(CXCursor C);
+MacroExpansion *getCursorMacroExpansion(CXCursor C);
/// \brief Create an inclusion directive cursor.
CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
@@ -184,6 +184,7 @@ Decl *getCursorDecl(CXCursor Cursor);
Expr *getCursorExpr(CXCursor Cursor);
Stmt *getCursorStmt(CXCursor Cursor);
Attr *getCursorAttr(CXCursor Cursor);
+Decl *getCursorParentDecl(CXCursor Cursor);
ASTContext &getCursorContext(CXCursor Cursor);
ASTUnit *getCursorASTUnit(CXCursor Cursor);
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 5af955357bb2..45c73468d971 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -366,7 +366,11 @@ unsigned clang_isPODType(CXType X) {
QualType T = GetQualType(X);
if (!T.getTypePtrOrNull())
return 0;
- return T->isPODType() ? 1 : 0;
+
+ CXTranslationUnit TU = GetTU(X);
+ ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
+
+ return T.isPODType(AU->getASTContext()) ? 1 : 0;
}
CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
index e684652aa4ca..375f7f20fe00 100644
--- a/tools/libclang/Makefile
+++ b/tools/libclang/Makefile
@@ -16,8 +16,9 @@ LINK_LIBS_IN_SHARED = 1
SHARED_LIBRARY = 1
LINK_COMPONENTS := support mc
-USEDLIBS = clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
- clangSema.a clangAnalysis.a clangAST.a clangLex.a clangBasic.a
+USEDLIBS = clangARCMigrate.a clangRewrite.a clangFrontend.a clangDriver.a \
+ clangSerialization.a \
+ clangParse.a clangSema.a clangAnalysis.a clangAST.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile
diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports
index 85dfcb68685c..bfc5be9c078b 100644
--- a/tools/libclang/libclang.darwin.exports
+++ b/tools/libclang/libclang.darwin.exports
@@ -6,6 +6,7 @@ _clang_annotateTokens
_clang_codeCompleteAt
_clang_codeCompleteGetDiagnostic
_clang_codeCompleteGetNumDiagnostics
+_clang_codeCompleteGetContexts
_clang_constructUSR_ObjCCategory
_clang_constructUSR_ObjCClass
_clang_constructUSR_ObjCIvar
@@ -112,6 +113,7 @@ _clang_getTranslationUnitSpelling
_clang_getTypeDeclaration
_clang_getTypeKindSpelling
_clang_hashCursor
+_clang_isAttribute
_clang_isConstQualifiedType
_clang_isCursorDefinition
_clang_isDeclaration
@@ -135,3 +137,7 @@ _clang_toggleCrashRecovery
_clang_tokenize
_clang_visitChildren
_clang_visitChildrenWithBlock
+_clang_getRemappings
+_clang_remap_getNumFiles
+_clang_remap_getFilenames
+_clang_remap_dispose
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 403cd67538c5..47b703011c76 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -6,6 +6,7 @@ clang_annotateTokens
clang_codeCompleteAt
clang_codeCompleteGetDiagnostic
clang_codeCompleteGetNumDiagnostics
+clang_codeCompleteGetContexts
clang_constructUSR_ObjCCategory
clang_constructUSR_ObjCClass
clang_constructUSR_ObjCIvar
@@ -112,6 +113,7 @@ clang_getTranslationUnitSpelling
clang_getTypeDeclaration
clang_getTypeKindSpelling
clang_hashCursor
+clang_isAttribute
clang_isConstQualifiedType
clang_isCursorDefinition
clang_isDeclaration
@@ -135,3 +137,7 @@ clang_toggleCrashRecovery
clang_tokenize
clang_visitChildren
clang_visitChildrenWithBlock
+clang_getRemappings
+clang_remap_getNumFiles
+clang_remap_getFilenames
+clang_remap_dispose
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index 7793a8db49b1..5697b214a2d7 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -365,11 +365,9 @@ my %LangMap = (
'cp' => 'c++',
'cpp' => 'c++',
'cc' => 'c++',
- 'ii' => 'c++',
'i' => 'c-cpp-output',
'm' => 'objective-c',
- 'mi' => 'objective-c-cpp-output',
- 'mm' => 'objective-c++'
+ 'mi' => 'objective-c-cpp-output'
);
my %UniqueOptions = (
@@ -382,11 +380,14 @@ my %UniqueOptions = (
my %LangsAccepted = (
"objective-c" => 1,
- "c" => 1,
- "c++" => 1,
- "objective-c++" => 1
+ "c" => 1
);
+if (defined $ENV{'CCC_ANALYZER_CPLUSPLUS'}) {
+ $LangsAccepted{"c++"} = 1;
+ $LangsAccepted{"objective-c++"} = 1;
+}
+
##----------------------------------------------------------------------------##
# Main Logic.
##----------------------------------------------------------------------------##
@@ -620,9 +621,9 @@ if ($Action eq 'compile' or $Action eq 'link') {
push @AnalyzeArgs, "-analyzer-constraints=$ConstraintsModel";
}
- if (defined $Analyses) {
- push @AnalyzeArgs, split '\s+', $Analyses;
- }
+# if (defined $Analyses) {
+# push @AnalyzeArgs, split '\s+', $Analyses;
+# }
if (defined $OutputFormat) {
push @AnalyzeArgs, "-analyzer-output=" . $OutputFormat;