aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/arcmt-test/arcmt-test.cpp7
-rw-r--r--tools/c-arcmt-test/CMakeLists.txt12
-rw-r--r--tools/c-arcmt-test/Makefile1
-rw-r--r--tools/c-index-test/CMakeLists.txt10
-rw-r--r--tools/c-index-test/Makefile1
-rw-r--r--tools/c-index-test/c-index-test.c48
-rw-r--r--tools/clang-check/ClangCheck.cpp74
-rw-r--r--tools/clang-format-vs/CMakeLists.txt7
-rw-r--r--tools/clang-format-vs/ClangFormat/ClangFormat.csproj5
-rw-r--r--tools/clang-format-vs/README.txt11
-rw-r--r--tools/clang-format-vs/source.extension.vsixmanifest.in5
-rw-r--r--tools/clang-format/CMakeLists.txt3
-rw-r--r--tools/clang-format/ClangFormat.cpp12
-rw-r--r--tools/clang-format/Makefile4
-rwxr-xr-xtools/clang-format/clang-format-diff.py8
-rw-r--r--tools/clang-format/clang-format.el209
-rw-r--r--tools/clang-format/clang-format.py7
-rwxr-xr-xtools/clang-format/git-clang-format2
-rw-r--r--tools/diagtool/DiagTool.cpp2
-rw-r--r--tools/diagtool/DiagTool.h4
-rw-r--r--tools/diagtool/DiagnosticNames.h4
-rw-r--r--tools/diagtool/ListWarnings.cpp9
-rw-r--r--tools/diagtool/ShowEnabledWarnings.cpp2
-rw-r--r--tools/driver/cc1_main.cpp10
-rw-r--r--tools/driver/cc1as_main.cpp42
-rw-r--r--tools/driver/driver.cpp394
-rw-r--r--tools/libclang/ARCMigrate.cpp4
-rw-r--r--tools/libclang/CIndex.cpp203
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp4
-rw-r--r--tools/libclang/CIndexDiagnostic.cpp29
-rw-r--r--tools/libclang/CIndexDiagnostic.h27
-rw-r--r--tools/libclang/CIndexUSRs.cpp2
-rw-r--r--tools/libclang/CIndexer.h4
-rw-r--r--tools/libclang/CLog.h4
-rw-r--r--tools/libclang/CMakeLists.txt2
-rw-r--r--tools/libclang/CXComment.cpp2
-rw-r--r--tools/libclang/CXComment.h6
-rw-r--r--tools/libclang/CXCompilationDatabase.cpp6
-rw-r--r--tools/libclang/CXCursor.cpp167
-rw-r--r--tools/libclang/CXCursor.h4
-rw-r--r--tools/libclang/CXLoadedDiagnostic.cpp591
-rw-r--r--tools/libclang/CXLoadedDiagnostic.h4
-rw-r--r--tools/libclang/CXSourceLocation.h4
-rw-r--r--tools/libclang/CXString.h4
-rw-r--r--tools/libclang/CXTranslationUnit.h4
-rw-r--r--tools/libclang/CXType.cpp1
-rw-r--r--tools/libclang/CXType.h4
-rw-r--r--tools/libclang/CursorVisitor.h4
-rw-r--r--tools/libclang/IndexBody.cpp2
-rw-r--r--tools/libclang/IndexTypeSourceInfo.cpp1
-rw-r--r--tools/libclang/Index_Internal.h4
-rw-r--r--tools/libclang/Indexing.cpp21
-rw-r--r--tools/libclang/IndexingContext.h5
-rw-r--r--tools/libclang/Makefile4
-rw-r--r--tools/libclang/libclang.exports8
-rw-r--r--tools/scan-build/c++-analyzer.bat1
-rwxr-xr-xtools/scan-build/ccc-analyzer24
-rw-r--r--tools/scan-build/ccc-analyzer.bat1
-rwxr-xr-xtools/scan-build/scan-build171
59 files changed, 1253 insertions, 962 deletions
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
index a59a869c225c..7be4ed6e2a21 100644
--- a/tools/arcmt-test/arcmt-test.cpp
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -269,14 +269,11 @@ static bool verifyTransformedFiles(ArrayRef<std::string> resultFiles) {
return true;
}
- bool exists = false;
- sys::fs::exists(It->second, exists);
- if (!exists) {
+ if (!sys::fs::exists(It->second)) {
errs() << "error: '" << It->second << "' does not exist\n";
return true;
}
- sys::fs::exists(inputResultFname, exists);
- if (!exists) {
+ if (!sys::fs::exists(inputResultFname)) {
errs() << "error: '" << inputResultFname << "' does not exist\n";
return true;
}
diff --git a/tools/c-arcmt-test/CMakeLists.txt b/tools/c-arcmt-test/CMakeLists.txt
index 9014ccc309f2..8914607358fc 100644
--- a/tools/c-arcmt-test/CMakeLists.txt
+++ b/tools/c-arcmt-test/CMakeLists.txt
@@ -2,9 +2,15 @@ add_clang_executable(c-arcmt-test
c-arcmt-test.c
)
-target_link_libraries(c-arcmt-test
- libclang
- )
+if (LLVM_BUILD_STATIC)
+ target_link_libraries(c-arcmt-test
+ libclang_static
+ )
+else()
+ target_link_libraries(c-arcmt-test
+ libclang
+ )
+endif()
set_target_properties(c-arcmt-test
PROPERTIES
diff --git a/tools/c-arcmt-test/Makefile b/tools/c-arcmt-test/Makefile
index e7d5be7658b8..fff05f828254 100644
--- a/tools/c-arcmt-test/Makefile
+++ b/tools/c-arcmt-test/Makefile
@@ -30,6 +30,7 @@ USEDLIBS = clang.a \
clangIndex.a \
clangFormat.a \
clangTooling.a \
+ clangToolingCore.a \
clangRewriteFrontend.a \
clangRewrite.a \
clangFrontend.a clangDriver.a \
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index 113172ad157c..d0872fd2eff3 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -9,9 +9,15 @@ if(NOT MSVC)
)
endif()
-target_link_libraries(c-index-test
- libclang
+if (LLVM_BUILD_STATIC)
+ target_link_libraries(c-index-test
+ libclang_static
)
+else()
+ target_link_libraries(c-index-test
+ libclang
+ )
+endif()
set_target_properties(c-index-test
PROPERTIES
diff --git a/tools/c-index-test/Makefile b/tools/c-index-test/Makefile
index 42bfbb05839c..62bc9348dbf5 100644
--- a/tools/c-index-test/Makefile
+++ b/tools/c-index-test/Makefile
@@ -30,6 +30,7 @@ USEDLIBS = clang.a \
clangIndex.a clangFormat.a clangRewrite.a \
clangFrontend.a clangDriver.a \
clangTooling.a \
+ clangToolingCore.a \
clangSerialization.a clangParse.a clangSema.a \
clangAnalysis.a clangEdit.a clangAST.a clangLex.a \
clangBasic.a
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 07be22a5e940..56e4101399a5 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -796,15 +796,42 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
printf(" [access=%s isVirtual=%s]", accessStr,
isVirtual ? "true" : "false");
}
-
+
SpecializationOf = clang_getSpecializedCursorTemplate(Cursor);
if (!clang_equalCursors(SpecializationOf, clang_getNullCursor())) {
CXSourceLocation Loc = clang_getCursorLocation(SpecializationOf);
CXString Name = clang_getCursorSpelling(SpecializationOf);
clang_getSpellingLocation(Loc, 0, &line, &column, 0);
- printf(" [Specialization of %s:%d:%d]",
+ printf(" [Specialization of %s:%d:%d]",
clang_getCString(Name), line, column);
clang_disposeString(Name);
+
+ if (Cursor.kind == CXCursor_FunctionDecl) {
+ /* Collect the template parameter kinds from the base template. */
+ unsigned NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
+ unsigned I;
+ for (I = 0; I < NumTemplateArgs; I++) {
+ enum CXTemplateArgumentKind TAK =
+ clang_Cursor_getTemplateArgumentKind(Cursor, I);
+ switch(TAK) {
+ case CXTemplateArgumentKind_Type:
+ {
+ CXType T = clang_Cursor_getTemplateArgumentType(Cursor, I);
+ CXString S = clang_getTypeSpelling(T);
+ printf(" [Template arg %d: kind: %d, type: %s]",
+ I, TAK, clang_getCString(S));
+ clang_disposeString(S);
+ }
+ break;
+ case CXTemplateArgumentKind_Integral:
+ printf(" [Template arg %d: kind: %d, intval: %lld]",
+ I, TAK, clang_Cursor_getTemplateArgumentValue(Cursor, I));
+ break;
+ default:
+ printf(" [Template arg %d: kind: %d]\n", I, TAK);
+ }
+ }
+ }
}
clang_getOverriddenCursors(Cursor, &overridden, &num_overridden);
@@ -1363,6 +1390,20 @@ static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
}
/******************************************************************************/
+/* Mangling testing. */
+/******************************************************************************/
+
+static enum CXChildVisitResult PrintMangledName(CXCursor cursor, CXCursor p,
+ CXClientData d) {
+ CXString MangledName;
+ PrintCursor(cursor, NULL);
+ MangledName = clang_Cursor_getMangling(cursor);
+ printf(" [mangled=%s]\n", clang_getCString(MangledName));
+ clang_disposeString(MangledName);
+ return CXChildVisit_Continue;
+}
+
+/******************************************************************************/
/* Bitwidth testing. */
/******************************************************************************/
@@ -1629,6 +1670,7 @@ static int perform_file_scan(const char *ast_file, const char *source_file,
if ((fp = fopen(source_file, "r")) == NULL) {
fprintf(stderr, "Could not open '%s'\n", source_file);
+ clang_disposeTranslationUnit(TU);
return 1;
}
@@ -4081,6 +4123,8 @@ int cindextest_main(int argc, const char **argv) {
else if (argc > 2 && strcmp(argv[1], "-test-print-bitwidth") == 0)
return perform_test_load_source(argc - 2, argv + 2, "all",
PrintBitWidth, 0);
+ else if (argc > 2 && strcmp(argv[1], "-test-print-mangle") == 0)
+ return perform_test_load_tu(argv[2], "all", NULL, PrintMangledName, NULL);
else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) {
if (argc > 2)
return print_usrs(argv + 2, argv + argc);
diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp
index cc8d43cec221..7992026a7ccf 100644
--- a/tools/clang-check/ClangCheck.cpp
+++ b/tools/clang-check/ClangCheck.cpp
@@ -25,6 +25,7 @@
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
@@ -77,15 +78,6 @@ static cl::opt<bool> FixWhatYouCan(
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"),
- 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 {
// FIXME: Move FixItRewriteInPlace from lib/Rewrite/Frontend/FrontendActions.cpp
@@ -139,57 +131,21 @@ public:
}
};
-class InsertAdjuster: public clang::tooling::ArgumentsAdjuster {
-public:
- enum Position { BEGIN, END };
-
- InsertAdjuster(const CommandLineArguments &Extra, Position Pos)
- : Extra(Extra), Pos(Pos) {
- }
-
- InsertAdjuster(const char *Extra, Position Pos)
- : Extra(1, std::string(Extra)), Pos(Pos) {
- }
-
- virtual CommandLineArguments
- Adjust(const CommandLineArguments &Args) override {
- CommandLineArguments Return(Args);
-
- CommandLineArguments::iterator I;
- if (Pos == END) {
- I = Return.end();
- } else {
- I = Return.begin();
- ++I; // To leave the program name in place
- }
-
- Return.insert(I, Extra.begin(), Extra.end());
- return Return;
- }
-
-private:
- const CommandLineArguments Extra;
- const Position Pos;
-};
-
-} // namespace
-
-// Anonymous namespace here causes problems with gcc <= 4.4 on MacOS 10.6.
-// "Non-global symbol: ... can't be a weak_definition"
-namespace clang_check {
class ClangCheckActionFactory {
public:
- clang::ASTConsumer *newASTConsumer() {
+ std::unique_ptr<clang::ASTConsumer> newASTConsumer() {
if (ASTList)
return clang::CreateASTDeclNodeLister();
if (ASTDump)
- return clang::CreateASTDumper(ASTDumpFilter);
+ return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls=*/true,
+ /*DumpLookups=*/false);
if (ASTPrint)
return clang::CreateASTPrinter(&llvm::outs(), ASTDumpFilter);
- return new clang::ASTConsumer();
+ return llvm::make_unique<clang::ASTConsumer>();
}
};
-}
+
+} // namespace
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
@@ -199,22 +155,14 @@ int main(int argc, const char **argv) {
// Clear adjusters because -fsyntax-only is inserted by the default chain.
Tool.clearArgumentsAdjusters();
- Tool.appendArgumentsAdjuster(new ClangStripOutputAdjuster());
- if (ArgsAfter.size() > 0) {
- Tool.appendArgumentsAdjuster(new InsertAdjuster(ArgsAfter,
- InsertAdjuster::END));
- }
- if (ArgsBefore.size() > 0) {
- Tool.appendArgumentsAdjuster(new InsertAdjuster(ArgsBefore,
- InsertAdjuster::BEGIN));
- }
+ Tool.appendArgumentsAdjuster(getClangStripOutputAdjuster());
// Running the analyzer requires --analyze. Other modes can work with the
// -fsyntax-only option.
- Tool.appendArgumentsAdjuster(new InsertAdjuster(
- Analyze ? "--analyze" : "-fsyntax-only", InsertAdjuster::BEGIN));
+ Tool.appendArgumentsAdjuster(getInsertArgumentAdjuster(
+ Analyze ? "--analyze" : "-fsyntax-only", ArgumentInsertPosition::BEGIN));
- clang_check::ClangCheckActionFactory CheckFactory;
+ ClangCheckActionFactory CheckFactory;
std::unique_ptr<FrontendActionFactory> FrontendFactory;
// Choose the correct factory based on the selected mode.
diff --git a/tools/clang-format-vs/CMakeLists.txt b/tools/clang-format-vs/CMakeLists.txt
index b1101928aa51..0a50a6a8c426 100644
--- a/tools/clang-format-vs/CMakeLists.txt
+++ b/tools/clang-format-vs/CMakeLists.txt
@@ -6,6 +6,11 @@ if (BUILD_CLANG_FORMAT_VS_PLUGIN)
"${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/clang-format.exe"
DEPENDS clang-format)
+ add_custom_target(clang_format_license
+ ${CMAKE_COMMAND} -E copy_if_different
+ "${CLANG_SOURCE_DIR}/LICENSE.TXT"
+ "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/license.txt")
+
if (NOT CLANG_FORMAT_VS_VERSION)
set(CLANG_FORMAT_VS_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
endif()
@@ -19,5 +24,5 @@ if (BUILD_CLANG_FORMAT_VS_PLUGIN)
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)
+ DEPENDS clang_format_exe_for_vsix clang_format_license)
endif()
diff --git a/tools/clang-format-vs/ClangFormat/ClangFormat.csproj b/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
index 2f49221d14b3..709b33d6fa22 100644
--- a/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
+++ b/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
@@ -181,6 +181,9 @@
<Content Include="clang-format.exe">
<IncludeInVSIX>true</IncludeInVSIX>
</Content>
+ <Content Include="license.txt">
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
<Content Include="Resources\Package.ico" />
</ItemGroup>
<ItemGroup>
@@ -227,4 +230,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project> \ No newline at end of file
+</Project>
diff --git a/tools/clang-format-vs/README.txt b/tools/clang-format-vs/README.txt
index b87df6e92379..636b89f3c673 100644
--- a/tools/clang-format-vs/README.txt
+++ b/tools/clang-format-vs/README.txt
@@ -6,8 +6,11 @@ Build prerequisites are:
- 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 is built using CMake by setting BUILD_CLANG_FORMAT_VS_PLUGIN=ON
+when configuring a Clang build, and building the clang_format_vsix target.
-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.
+The CMake build will copy clang-format.exe and LICENSE.TXT into the ClangFormat/
+directory so they can be bundled with the plug-in, as well as creating
+ClangFormat/source.extension.vsixmanifest. Once the plug-in has been built with
+CMake once, it can be built manually from the ClangFormat.sln solution in Visual
+Studio.
diff --git a/tools/clang-format-vs/source.extension.vsixmanifest.in b/tools/clang-format-vs/source.extension.vsixmanifest.in
index ed0e72e35512..496fa40063b7 100644
--- a/tools/clang-format-vs/source.extension.vsixmanifest.in
+++ b/tools/clang-format-vs/source.extension.vsixmanifest.in
@@ -6,6 +6,8 @@
<Version>@CLANG_FORMAT_VS_VERSION@</Version>
<Description xml:space="preserve">A tool to format C/C++/Obj-C code.</Description>
<Locale>1033</Locale>
+ <MoreInfoUrl>http://clang.llvm.org/docs/ClangFormat.html</MoreInfoUrl>
+ <License>license.txt</License>
<InstalledByMsi>false</InstalledByMsi>
<SupportedProducts>
<VisualStudio Version="10.0">
@@ -17,6 +19,9 @@
<VisualStudio Version="12.0">
<Edition>Pro</Edition>
</VisualStudio>
+ <VisualStudio Version="14.0">
+ <Edition>Pro</Edition>
+ </VisualStudio>
</SupportedProducts>
<SupportedFrameworkRuntimeEdition MinVersion="4.0" MaxVersion="4.0" />
</Identifier>
diff --git a/tools/clang-format/CMakeLists.txt b/tools/clang-format/CMakeLists.txt
index f80a3ec9c91f..6a24e138efcf 100644
--- a/tools/clang-format/CMakeLists.txt
+++ b/tools/clang-format/CMakeLists.txt
@@ -7,9 +7,8 @@ add_clang_executable(clang-format
target_link_libraries(clang-format
clangBasic
clangFormat
- clangLex
clangRewrite
- clangTooling
+ clangToolingCore
)
install(TARGETS clang-format RUNTIME DESTINATION bin)
diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
index cebb2757d4da..d44d407aa86c 100644
--- a/tools/clang-format/ClangFormat.cpp
+++ b/tools/clang-format/ClangFormat.cpp
@@ -19,9 +19,9 @@
#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/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Signals.h"
@@ -76,7 +76,7 @@ static cl::opt<std::string>
AssumeFilename("assume-filename",
cl::desc("When reading from stdin, clang-format assumes this\n"
"filename to look for a style config file (with\n"
- "-style=file)."),
+ "-style=file) and to determine the language."),
cl::cat(ClangFormatCategory));
static cl::opt<bool> Inplace("i",
@@ -225,12 +225,14 @@ static bool format(StringRef 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);
+ tooling::Replacements Replaces = reformat(FormatStyle, Sources, ID, Ranges);
if (OutputXML) {
llvm::outs()
<< "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
+ if (Cursor.getNumOccurrences() != 0)
+ llvm::outs() << "<cursor>"
+ << tooling::shiftedCodePosition(Replaces, Cursor)
+ << "</cursor>\n";
for (tooling::Replacements::const_iterator I = Replaces.begin(),
E = Replaces.end();
I != E; ++I) {
diff --git a/tools/clang-format/Makefile b/tools/clang-format/Makefile
index a26ef59822be..76e31cc1a072 100644
--- a/tools/clang-format/Makefile
+++ b/tools/clang-format/Makefile
@@ -16,9 +16,7 @@ TOOL_NO_EXPORTS = 1
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
-USEDLIBS = clangFormat.a clangTooling.a clangFrontend.a clangSerialization.a \
- clangDriver.a clangParse.a clangSema.a clangAnalysis.a \
- clangRewriteFrontend.a clangRewrite.a clangEdit.a clangAST.a \
+USEDLIBS = clangFormat.a clangToolingCore.a clangDriver.a clangRewrite.a \
clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile
diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py
index d6d0d44a06bb..23adb077c953 100755
--- a/tools/clang-format/clang-format-diff.py
+++ b/tools/clang-format/clang-format-diff.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
#
#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
#
@@ -49,9 +49,11 @@ def main():
'(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)',
+ r'|protodevel|java)',
help='custom pattern selecting file paths to reformat '
'(case insensitive, overridden by -regex)')
+ parser.add_argument('-v', '--verbose', action='store_true',
+ help='be more verbose, ineffective without -i')
parser.add_argument(
'-style',
help=
@@ -89,6 +91,8 @@ def main():
# Reformat files containing changes in place.
for filename, lines in lines_by_file.iteritems():
+ if args.i and args.verbose:
+ print 'Formatting', filename
command = [binary, filename]
if args.i:
command.append('-i')
diff --git a/tools/clang-format/clang-format.el b/tools/clang-format/clang-format.el
index 520a3e250cf5..ab0991b2df1c 100644
--- a/tools/clang-format/clang-format.el
+++ b/tools/clang-format/clang-format.el
@@ -1,56 +1,167 @@
-;;; Clang-format emacs integration for use with C/Objective-C/C++.
+;;; clang-format.el --- Format code using clang-format
-;; This defines a function clang-format-region that you can bind to a key.
-;; A minimal .emacs would contain:
+;; Keywords: tools, c
+;; Package-Requires: ((cl-lib "0.3"))
+
+;;; Commentary:
+
+;; This package allows to filter code through clang-format to fix its formatting.
+;; clang-format is a tool that formats C/C++/Obj-C code according to a set of
+;; style options, see <http://clang.llvm.org/docs/ClangFormatStyleOptions.html>.
+;; Note that clang-format 3.4 or newer is required.
+
+;; clang-format.el is available via MELPA and can be installed via
;;
-;; (load "<path-to-clang>/tools/clang-format/clang-format.el")
-;; (global-set-key [C-M-tab] 'clang-format-region)
+;; M-x package-install clang-format
+;;
+;; when ("melpa" . "http://melpa.org/packages/") is included in
+;; `package-archives'. Alternatively, ensure the directory of this
+;; file is in your `load-path' and add
+;;
+;; (require 'clang-format)
+;;
+;; to your .emacs configuration.
+
+;; You may also want to bind `clang-format-region' to a key:
;;
-;; Depending on your configuration and coding style, you might need to modify
-;; 'style' in clang-format, below.
+;; (global-set-key [C-M-tab] 'clang-format-region)
-(require 'json)
+;;; Code:
-;; *Location of the clang-format binary. If it is on your PATH, a full path name
-;; need not be specified.
-(defvar clang-format-binary "clang-format")
+(require 'cl-lib)
+(require 'xml)
-(defun clang-format-region ()
- "Use clang-format to format the currently active region."
- (interactive)
- (let ((beg (if mark-active
- (region-beginning)
- (min (line-beginning-position) (1- (point-max)))))
- (end (if mark-active
- (region-end)
- (line-end-position))))
- (clang-format beg end)))
-
-(defun clang-format-buffer ()
- "Use clang-format to format the current buffer."
- (interactive)
- (clang-format (point-min) (point-max)))
-
-(defun clang-format (begin end)
- "Use clang-format to format the code between BEGIN and END."
- (let* ((orig-windows (get-buffer-window-list (current-buffer)))
- (orig-window-starts (mapcar #'window-start orig-windows))
- (orig-point (point))
- (style "file"))
+(defgroup clang-format nil
+ "Format code using clang-format."
+ :group 'tools)
+
+(defcustom clang-format-executable
+ (or (executable-find "clang-format")
+ "clang-format")
+ "Location of the clang-format executable.
+
+A string containing the name or the full path of the executable."
+ :group 'clang-format
+ :type 'string
+ :risky t)
+
+(defcustom clang-format-style "file"
+ "Style argument to pass to clang-format.
+
+By default clang-format will load the style configuration from
+a file named .clang-format located in one of the parent directories
+of the buffer."
+ :group 'clang-format
+ :type 'string
+ :safe #'stringp)
+(make-variable-buffer-local 'clang-format-style)
+
+(defun clang-format--extract (xml-node)
+ "Extract replacements and cursor information from XML-NODE."
+ (unless (and (listp xml-node) (eq (xml-node-name xml-node) 'replacements))
+ (error "Expected <replacements> node"))
+ (let ((nodes (xml-node-children xml-node))
+ replacements
+ cursor)
+ (dolist (node nodes)
+ (when (listp node)
+ (let* ((children (xml-node-children node))
+ (text (car children)))
+ (cl-case (xml-node-name node)
+ ('replacement
+ (let* ((offset (xml-get-attribute-or-nil node 'offset))
+ (length (xml-get-attribute-or-nil node 'length)))
+ (when (or (null offset) (null length))
+ (error "<replacement> node does not have offset and length attributes"))
+ (when (cdr children)
+ (error "More than one child node in <replacement> node"))
+
+ (setq offset (1+ (string-to-number offset)))
+ (setq length (string-to-number length))
+ (push (list offset length text) replacements)))
+ ('cursor
+ (setq cursor (1+ (string-to-number text))))))))
+
+ ;; Sort by decreasing offset, length.
+ (setq replacements (sort (delq nil replacements)
+ (lambda (a b)
+ (or (> (car a) (car b))
+ (and (= (car a) (car b))
+ (> (cadr a) (cadr b)))))))
+
+ (cons replacements cursor)))
+
+(defun clang-format--replace (offset length &optional text)
+ (goto-char offset)
+ (delete-char length)
+ (when text
+ (insert text)))
+
+;;;###autoload
+(defun clang-format-region (start end &optional style)
+ "Use clang-format to format the code between START and END according to STYLE.
+If called interactively uses the region or the current statement if there
+is no active region. If no style is given uses `clang-format-style'."
+ (interactive
+ (if (use-region-p)
+ (list (region-beginning) (region-end))
+ (list (point) (point))))
+
+ (unless style
+ (setq style clang-format-style))
+
+ (let ((temp-buffer (generate-new-buffer " *clang-format-temp*"))
+ (temp-file (make-temp-file "clang-format")))
(unwind-protect
- (call-process-region (point-min) (point-max) clang-format-binary
- t (list t nil) nil
- "-offset" (number-to-string (1- begin))
- "-length" (number-to-string (- end begin))
- "-cursor" (number-to-string (1- (point)))
- "-assume-filename" (buffer-file-name)
- "-style" style)
- (goto-char (point-min))
- (let ((json-output (json-read-from-string
- (buffer-substring-no-properties
- (point-min) (line-beginning-position 2)))))
- (delete-region (point-min) (line-beginning-position 2))
- (goto-char (1+ (cdr (assoc 'Cursor json-output))))
- (dotimes (index (length orig-windows))
- (set-window-start (nth index orig-windows)
- (nth index orig-window-starts)))))))
+ (let (status stderr operations)
+ (setq status
+ (call-process-region
+ (point-min) (point-max) clang-format-executable
+ nil `(,temp-buffer ,temp-file) nil
+
+ "-output-replacements-xml"
+ "-assume-filename" (or (buffer-file-name) "")
+ "-style" style
+ "-offset" (number-to-string (1- start))
+ "-length" (number-to-string (- end start))
+ "-cursor" (number-to-string (1- (point)))))
+ (setq stderr
+ (with-temp-buffer
+ (insert-file-contents temp-file)
+ (when (> (point-max) (point-min))
+ (insert ": "))
+ (buffer-substring-no-properties
+ (point-min) (line-end-position))))
+
+ (cond
+ ((stringp status)
+ (error "(clang-format killed by signal %s%s)" status stderr))
+ ((not (equal 0 status))
+ (error "(clang-format failed with code %d%s)" status stderr))
+ (t (message "(clang-format succeeded%s)" stderr)))
+
+ (with-current-buffer temp-buffer
+ (setq operations (clang-format--extract (car (xml-parse-region)))))
+
+ (let ((replacements (car operations))
+ (cursor (cdr operations)))
+ (save-excursion
+ (mapc (lambda (rpl)
+ (apply #'clang-format--replace rpl))
+ replacements))
+ (when cursor
+ (goto-char cursor))))
+ (delete-file temp-file)
+ (when (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
+
+;;;###autoload
+(defun clang-format-buffer (&optional style)
+ "Use clang-format to format the current buffer according to STYLE."
+ (interactive)
+ (clang-format-region (point-min) (point-max) style))
+
+;;;###autoload
+(defalias 'clang-format 'clang-format-region)
+
+(provide 'clang-format)
+;;; clang-format.el ends here
diff --git a/tools/clang-format/clang-format.py b/tools/clang-format/clang-format.py
index 16a187910832..a79205a6dfe8 100644
--- a/tools/clang-format/clang-format.py
+++ b/tools/clang-format/clang-format.py
@@ -2,8 +2,8 @@
# - Change 'binary' if clang-format is not on the path (see below).
# - Add to your .vimrc:
#
-# map <C-I> :pyf <path-to-this-file>/clang-format.py<CR>
-# imap <C-I> <ESC>:pyf <path-to-this-file>/clang-format.py<CR>i
+# map <C-I> :pyf <path-to-this-file>/clang-format.py<cr>
+# imap <C-I> <c-o>:pyf <path-to-this-file>/clang-format.py<cr>
#
# The first line enables clang-format for NORMAL and VISUAL mode, the second
# line adds support for INSERT mode. Change "C-I" to another binding if you
@@ -23,8 +23,11 @@ import subprocess
import sys
import vim
+# set g:clang_format_path to the path to clang-format if it is not on the path
# Change this to the full path if clang-format is not on the path.
binary = 'clang-format'
+if vim.eval('exists("g:clang_format_path")') == "1":
+ binary = vim.eval('g:clang_format_path')
# Change this to format according to other formatting styles. See the output of
# 'clang-format --help' for a list of supported styles. The default looks for
diff --git a/tools/clang-format/git-clang-format b/tools/clang-format/git-clang-format
index c40b74dae4ba..6a0db27fa9f6 100755
--- a/tools/clang-format/git-clang-format
+++ b/tools/clang-format/git-clang-format
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
#
#===- git-clang-format - ClangFormat Git Integration ---------*- python -*--===#
#
diff --git a/tools/diagtool/DiagTool.cpp b/tools/diagtool/DiagTool.cpp
index 44bc83e5455f..0e4d8088c6c2 100644
--- a/tools/diagtool/DiagTool.cpp
+++ b/tools/diagtool/DiagTool.cpp
@@ -36,7 +36,7 @@ DiagTool *DiagTools::getTool(llvm::StringRef toolCmd) {
}
void DiagTools::registerTool(DiagTool *tool) {
- getTools(tools)->GetOrCreateValue(tool->getName(), tool);
+ (*getTools(tools))[tool->getName()] = tool;
}
void DiagTools::printCommands(llvm::raw_ostream &out) {
diff --git a/tools/diagtool/DiagTool.h b/tools/diagtool/DiagTool.h
index b1e69f38c323..04b926df3b60 100644
--- a/tools/diagtool/DiagTool.h
+++ b/tools/diagtool/DiagTool.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef DIAGTOOL_DIAGTOOL_H
-#define DIAGTOOL_DIAGTOOL_H
+#ifndef LLVM_CLANG_TOOLS_DIAGTOOL_DIAGTOOL_H
+#define LLVM_CLANG_TOOLS_DIAGTOOL_DIAGTOOL_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ManagedStatic.h"
diff --git a/tools/diagtool/DiagnosticNames.h b/tools/diagtool/DiagnosticNames.h
index 2571b1996918..ac1a09857952 100644
--- a/tools/diagtool/DiagnosticNames.h
+++ b/tools/diagtool/DiagnosticNames.h
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_TOOLS_DIAGTOOL_DIAGNOSTICNAMES_H
+#define LLVM_CLANG_TOOLS_DIAGTOOL_DIAGNOSTICNAMES_H
+
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
@@ -112,3 +115,4 @@ namespace diagtool {
}
} // end namespace diagtool
+#endif
diff --git a/tools/diagtool/ListWarnings.cpp b/tools/diagtool/ListWarnings.cpp
index 16837a158495..3e6e88306e24 100644
--- a/tools/diagtool/ListWarnings.cpp
+++ b/tools/diagtool/ListWarnings.cpp
@@ -73,7 +73,7 @@ int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
Unflagged.push_back(entry);
else {
Flagged.push_back(entry);
- flagHistogram.GetOrCreateValue(entry.Flag).getValue().push_back(diagID);
+ flagHistogram[entry.Flag].push_back(diagID);
}
}
@@ -97,11 +97,10 @@ int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
double avgDiagsPerFlag = (double) Flagged.size() / flagHistogram.size();
out << " Average number of diagnostics per flag: "
<< llvm::format("%.4g", avgDiagsPerFlag) << '\n';
-
+
out << " Number in -Wpedantic (not covered by other -W flags): "
- << flagHistogram.GetOrCreateValue("pedantic").getValue().size()
- << '\n';
-
+ << flagHistogram["pedantic"].size() << '\n';
+
out << '\n';
return 0;
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
index 903d1f16f992..06f74320b7fc 100644
--- a/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -65,7 +65,7 @@ createDiagnostics(unsigned int argc, char **argv) {
// Try to build a CompilerInvocation.
std::unique_ptr<CompilerInvocation> Invocation(
- createInvocationFromCommandLine(ArrayRef<const char *>(argv, argc),
+ createInvocationFromCommandLine(llvm::makeArrayRef(argv, argc),
InterimDiags));
if (!Invocation)
return nullptr;
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index 990c4fc3c84e..fa1a10e96356 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -63,8 +63,7 @@ void initializePollyPasses(llvm::PassRegistry &Registry);
}
#endif
-int cc1_main(const char **ArgBegin, const char **ArgEnd,
- const char *Argv0, void *MainAddr) {
+int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
@@ -84,9 +83,8 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd,
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
- bool Success;
- Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(),
- ArgBegin, ArgEnd, Diags);
+ bool Success = CompilerInvocation::CreateFromArgs(
+ Clang->getInvocation(), Argv.begin(), Argv.end(), Diags);
// Infer the builtin include path if unspecified.
if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
@@ -124,7 +122,7 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd,
if (Clang->getFrontendOpts().DisableFree) {
if (llvm::AreStatisticsEnabled() || Clang->getFrontendOpts().ShowStats)
llvm::PrintStatistics();
- BuryPointer(Clang.release());
+ BuryPointer(std::move(Clang));
return !Success;
}
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index e41bc9f824e8..55c9fe602fa3 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -123,6 +123,7 @@ struct AssemblerInvocation {
unsigned RelaxAll : 1;
unsigned NoExecStack : 1;
+ unsigned FatalWarnings : 1;
/// @}
@@ -138,18 +139,19 @@ public:
ShowEncoding = 0;
RelaxAll = 0;
NoExecStack = 0;
+ FatalWarnings = 0;
DwarfVersion = 3;
}
- static bool CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin,
- const char **ArgEnd, DiagnosticsEngine &Diags);
+ static bool CreateFromArgs(AssemblerInvocation &Res,
+ ArrayRef<const char *> Argv,
+ DiagnosticsEngine &Diags);
};
}
bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
- const char **ArgBegin,
- const char **ArgEnd,
+ ArrayRef<const char *> Argv,
DiagnosticsEngine &Diags) {
bool Success = true;
@@ -159,7 +161,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
const unsigned IncludedFlagsBitmask = options::CC1AsOption;
unsigned MissingArgIndex, MissingArgCount;
std::unique_ptr<InputArgList> Args(
- OptTbl->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount,
+ OptTbl->ParseArgs(Argv.begin(), Argv.end(), MissingArgIndex, MissingArgCount,
IncludedFlagsBitmask));
// Check for missing argument error.
@@ -246,7 +248,8 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
// Assemble Options
Opts.RelaxAll = Args->hasArg(OPT_mrelax_all);
- Opts.NoExecStack = Args->hasArg(OPT_mno_exec_stack);
+ Opts.NoExecStack = Args->hasArg(OPT_mno_exec_stack);
+ Opts.FatalWarnings = Args->hasArg(OPT_massembler_fatal_warnings);
return Success;
}
@@ -262,13 +265,12 @@ static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts,
if (Opts.OutputPath != "-")
sys::RemoveFileOnSignal(Opts.OutputPath);
- std::string Error;
- raw_fd_ostream *Out =
- new raw_fd_ostream(Opts.OutputPath.c_str(), Error,
- (Binary ? sys::fs::F_None : sys::fs::F_Text));
- if (!Error.empty()) {
- Diags.Report(diag::err_fe_unable_to_open_output)
- << Opts.OutputPath << Error;
+ std::error_code EC;
+ raw_fd_ostream *Out = new raw_fd_ostream(
+ Opts.OutputPath, EC, (Binary ? sys::fs::F_None : sys::fs::F_Text));
+ if (EC) {
+ Diags.Report(diag::err_fe_unable_to_open_output) << Opts.OutputPath
+ << EC.message();
delete Out;
return nullptr;
}
@@ -295,7 +297,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
SourceMgr SrcMgr;
// Tell SrcMgr about this buffer, which is what the parser will pick up.
- SrcMgr.AddNewSourceBuffer(Buffer->release(), SMLoc());
+ SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());
// Record the location of the include directories so that the lexer can find
// it later.
@@ -378,9 +380,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
Opts.CPU);
Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out,
- CE, *STI, Opts.RelaxAll,
- Opts.NoExecStack));
- Str.get()->InitSections();
+ CE, *STI, Opts.RelaxAll));
+ Str.get()->InitSections(Opts.NoExecStack);
}
bool Failed = false;
@@ -420,11 +421,10 @@ static void LLVMErrorHandler(void *UserData, const std::string &Message,
exit(1);
}
-int cc1as_main(const char **ArgBegin, const char **ArgEnd,
- const char *Argv0, void *MainAddr) {
+int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
- PrettyStackTraceProgram X(ArgEnd - ArgBegin, ArgBegin);
+ PrettyStackTraceProgram X(Argv.size(), Argv.data());
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
// Initialize targets and assembly printers/parsers.
@@ -447,7 +447,7 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd,
// Parse the arguments.
AssemblerInvocation Asm;
- if (!AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags))
+ if (!AssemblerInvocation::CreateFromArgs(Asm, Argv, Diags))
return 1;
if (Asm.ShowHelp) {
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 9f93837c2c75..e1f9367b0f5c 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -18,7 +18,9 @@
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
+#include "clang/Frontend/ChainedDiagnosticConsumer.h"
#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/SerializedDiagnosticPrinter.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
#include "llvm/ADT/ArrayRef.h"
@@ -61,8 +63,8 @@ std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
return llvm::sys::fs::getMainExecutable(Argv0, P);
}
-static const char *SaveStringInSet(std::set<std::string> &SavedStrings,
- StringRef S) {
+static const char *GetStableCStr(std::set<std::string> &SavedStrings,
+ StringRef S) {
return SavedStrings.insert(S).first->c_str();
}
@@ -101,12 +103,12 @@ static void ApplyOneQAOverride(raw_ostream &OS,
if (Edit[0] == '^') {
const char *Str =
- SaveStringInSet(SavedStrings, Edit.substr(1));
+ GetStableCStr(SavedStrings, Edit.substr(1));
OS << "### Adding argument " << Str << " at beginning\n";
Args.insert(Args.begin() + 1, Str);
} else if (Edit[0] == '+') {
const char *Str =
- SaveStringInSet(SavedStrings, Edit.substr(1));
+ GetStableCStr(SavedStrings, Edit.substr(1));
OS << "### Adding argument " << Str << " at end\n";
Args.push_back(Str);
} else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") &&
@@ -116,11 +118,14 @@ static void ApplyOneQAOverride(raw_ostream &OS,
ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1);
for (unsigned i = 1, e = Args.size(); i != e; ++i) {
+ // Ignore end-of-line response file markers
+ if (Args[i] == nullptr)
+ continue;
std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
if (Repl != Args[i]) {
OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n";
- Args[i] = SaveStringInSet(SavedStrings, Repl);
+ Args[i] = GetStableCStr(SavedStrings, Repl);
}
}
} else if (Edit[0] == 'x' || Edit[0] == 'X') {
@@ -142,6 +147,9 @@ static void ApplyOneQAOverride(raw_ostream &OS,
} else if (Edit[0] == 'O') {
for (unsigned i = 1; i < Args.size();) {
const char *A = Args[i];
+ // Ignore end-of-line response file markers
+ if (A == nullptr)
+ continue;
if (A[0] == '-' && A[1] == 'O' &&
(A[2] == '\0' ||
(A[3] == '\0' && (A[2] == 's' || A[2] == 'z' ||
@@ -152,7 +160,7 @@ static void ApplyOneQAOverride(raw_ostream &OS,
++i;
}
OS << "### Adding argument " << Edit << " at end\n";
- Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit.str()));
+ Args.push_back(GetStableCStr(SavedStrings, '-' + Edit.str()));
} else {
OS << "### Unrecognized edit: " << Edit << "\n";
}
@@ -187,97 +195,98 @@ static void ApplyQAOverride(SmallVectorImpl<const char*> &Args,
}
}
-extern int cc1_main(const char **ArgBegin, const char **ArgEnd,
- const char *Argv0, void *MainAddr);
-extern int cc1as_main(const char **ArgBegin, const char **ArgEnd,
- const char *Argv0, void *MainAddr);
+extern int cc1_main(ArrayRef<const char *> Argv, const char *Argv0,
+ void *MainAddr);
+extern int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0,
+ void *MainAddr);
+
+struct DriverSuffix {
+ const char *Suffix;
+ const char *ModeFlag;
+};
+
+static const DriverSuffix *FindDriverSuffix(StringRef ProgName) {
+ // A list of known driver suffixes. Suffixes are compared against the
+ // program name in order. If there is a match, the frontend type if updated as
+ // necessary by applying the ModeFlag.
+ static const DriverSuffix DriverSuffixes[] = {
+ {"clang", nullptr},
+ {"clang++", "--driver-mode=g++"},
+ {"clang-c++", "--driver-mode=g++"},
+ {"clang-cc", nullptr},
+ {"clang-cpp", "--driver-mode=cpp"},
+ {"clang-g++", "--driver-mode=g++"},
+ {"clang-gcc", nullptr},
+ {"clang-cl", "--driver-mode=cl"},
+ {"cc", nullptr},
+ {"cpp", "--driver-mode=cpp"},
+ {"cl", "--driver-mode=cl"},
+ {"++", "--driver-mode=g++"},
+ };
+
+ for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i)
+ if (ProgName.endswith(DriverSuffixes[i].Suffix))
+ return &DriverSuffixes[i];
+ return nullptr;
+}
static void ParseProgName(SmallVectorImpl<const char *> &ArgVector,
- std::set<std::string> &SavedStrings,
- Driver &TheDriver)
-{
- // Try to infer frontend type and default target from the program name.
-
- // suffixes[] contains the list of known driver suffixes.
- // Suffixes are compared against the program name in order.
- // If there is a match, the frontend type is updated as necessary (CPP/C++).
- // If there is no match, a second round is done after stripping the last
- // hyphen and everything following it. This allows using something like
- // "clang++-2.9".
-
- // If there is a match in either the first or second round,
- // the function tries to identify a target as prefix. E.g.
- // "x86_64-linux-clang" as interpreted as suffix "clang" with
- // target prefix "x86_64-linux". If such a target prefix is found,
- // is gets added via -target as implicit first argument.
- static const struct {
- const char *Suffix;
- const char *ModeFlag;
- } suffixes [] = {
- { "clang", nullptr },
- { "clang++", "--driver-mode=g++" },
- { "clang-c++", "--driver-mode=g++" },
- { "clang-cc", nullptr },
- { "clang-cpp", "--driver-mode=cpp" },
- { "clang-g++", "--driver-mode=g++" },
- { "clang-gcc", nullptr },
- { "clang-cl", "--driver-mode=cl" },
- { "cc", nullptr },
- { "cpp", "--driver-mode=cpp" },
- { "cl" , "--driver-mode=cl" },
- { "++", "--driver-mode=g++" },
- };
- std::string ProgName(llvm::sys::path::stem(ArgVector[0]));
+ std::set<std::string> &SavedStrings) {
+ // Try to infer frontend type and default target from the program name by
+ // comparing it against DriverSuffixes in order.
+
+ // If there is a match, the function tries to identify a target as prefix.
+ // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
+ // prefix "x86_64-linux". If such a target prefix is found, is gets added via
+ // -target as implicit first argument.
+
+ 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);
+ ProgName = StringRef(ProgName).lower();
#endif
- StringRef ProgNameRef(ProgName);
- StringRef Prefix;
-
- for (int Components = 2; Components; --Components) {
- bool FoundMatch = false;
- size_t i;
-
- for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
- if (ProgNameRef.endswith(suffixes[i].Suffix)) {
- FoundMatch = true;
- SmallVectorImpl<const char *>::iterator it = ArgVector.begin();
- if (it != ArgVector.end())
- ++it;
- if (suffixes[i].ModeFlag)
- ArgVector.insert(it, suffixes[i].ModeFlag);
- break;
- }
- }
- if (FoundMatch) {
- StringRef::size_type LastComponent = ProgNameRef.rfind('-',
- ProgNameRef.size() - strlen(suffixes[i].Suffix));
- if (LastComponent != StringRef::npos)
- Prefix = ProgNameRef.slice(0, LastComponent);
- break;
- }
+ StringRef ProgNameRef = ProgName;
+ const DriverSuffix *DS = FindDriverSuffix(ProgNameRef);
- StringRef::size_type LastComponent = ProgNameRef.rfind('-');
- if (LastComponent == StringRef::npos)
- break;
- ProgNameRef = ProgNameRef.slice(0, LastComponent);
+ if (!DS) {
+ // Try again after stripping any trailing version number:
+ // clang++3.5 -> clang++
+ ProgNameRef = ProgNameRef.rtrim("0123456789.");
+ DS = FindDriverSuffix(ProgNameRef);
}
- if (Prefix.empty())
- return;
-
- std::string IgnoredError;
- if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
- SmallVectorImpl<const char *>::iterator it = ArgVector.begin();
- if (it != ArgVector.end())
- ++it;
- const char* Strings[] =
- { SaveStringInSet(SavedStrings, std::string("-target")),
- SaveStringInSet(SavedStrings, Prefix) };
- ArgVector.insert(it, Strings, Strings + llvm::array_lengthof(Strings));
+ if (!DS) {
+ // Try again after stripping trailing -component.
+ // clang++-tot -> clang++
+ ProgNameRef = ProgNameRef.slice(0, ProgNameRef.rfind('-'));
+ DS = FindDriverSuffix(ProgNameRef);
+ }
+
+ if (DS) {
+ if (const char *Flag = DS->ModeFlag) {
+ // Add Flag to the arguments.
+ auto it = ArgVector.begin();
+ if (it != ArgVector.end())
+ ++it;
+ ArgVector.insert(it, Flag);
+ }
+
+ StringRef::size_type LastComponent = ProgNameRef.rfind(
+ '-', ProgNameRef.size() - strlen(DS->Suffix));
+ if (LastComponent == StringRef::npos)
+ return;
+
+ // Infer target from the prefix.
+ StringRef Prefix = ProgNameRef.slice(0, LastComponent);
+ std::string IgnoredError;
+ if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
+ auto it = ArgVector.begin();
+ if (it != ArgVector.end())
+ ++it;
+ const char *arr[] = { "-target", GetStableCStr(SavedStrings, Prefix) };
+ ArgVector.insert(it, std::begin(arr), std::end(arr));
+ }
}
}
@@ -286,21 +295,97 @@ namespace {
public:
StringSetSaver(std::set<std::string> &Storage) : Storage(Storage) {}
const char *SaveString(const char *Str) override {
- return SaveStringInSet(Storage, Str);
+ return GetStableCStr(Storage, Str);
}
private:
std::set<std::string> &Storage;
};
}
+static void SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) {
+ // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE.
+ TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS");
+ if (TheDriver.CCPrintOptions)
+ TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE");
+
+ // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE.
+ TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS");
+ if (TheDriver.CCPrintHeaders)
+ TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE");
+
+ // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE.
+ TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS");
+ if (TheDriver.CCLogDiagnostics)
+ TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE");
+}
+
+static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient,
+ const std::string &Path) {
+ // If the clang binary happens to be named cl.exe for compatibility reasons,
+ // use clang-cl.exe as the prefix to avoid confusion between clang and MSVC.
+ StringRef ExeBasename(llvm::sys::path::filename(Path));
+ if (ExeBasename.equals_lower("cl.exe"))
+ ExeBasename = "clang-cl.exe";
+ DiagClient->setPrefix(ExeBasename);
+}
+
+// This lets us create the DiagnosticsEngine with a properly-filled-out
+// DiagnosticOptions instance.
+static DiagnosticOptions *
+CreateAndPopulateDiagOpts(SmallVectorImpl<const char *> &argv) {
+ auto *DiagOpts = new DiagnosticOptions;
+ std::unique_ptr<OptTable> Opts(createDriverOptTable());
+ unsigned 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.
+ (void) ParseDiagnosticArgs(*DiagOpts, *Args);
+ return DiagOpts;
+}
+
+static void SetInstallDir(SmallVectorImpl<const char *> &argv,
+ Driver &TheDriver) {
+ // Attempt to find the original path used to invoke the driver, to determine
+ // the installed path. We do this manually, because we want to support that
+ // path being a symlink.
+ SmallString<128> InstalledPath(argv[0]);
+
+ // Do a PATH lookup, if there are no directory components.
+ if (llvm::sys::path::filename(InstalledPath) == InstalledPath)
+ if (llvm::ErrorOr<std::string> Tmp = llvm::sys::findProgramByName(
+ llvm::sys::path::filename(InstalledPath.str())))
+ InstalledPath = *Tmp;
+ llvm::sys::fs::make_absolute(InstalledPath);
+ InstalledPath = llvm::sys::path::parent_path(InstalledPath);
+ if (llvm::sys::fs::exists(InstalledPath.c_str()))
+ TheDriver.setInstalledDir(InstalledPath);
+}
+
+static int ExecuteCC1Tool(ArrayRef<const char *> argv, StringRef Tool) {
+ void *GetExecutablePathVP = (void *)(intptr_t) GetExecutablePath;
+ if (Tool == "")
+ return cc1_main(argv.slice(2), argv[0], GetExecutablePathVP);
+ if (Tool == "as")
+ return cc1as_main(argv.slice(2), argv[0], GetExecutablePathVP);
+
+ // Reject unknown tools.
+ llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n";
+ return 1;
+}
+
int main(int argc_, const char **argv_) {
llvm::sys::PrintStackTraceOnErrorSignal();
llvm::PrettyStackTraceProgram X(argc_, argv_);
+ if (llvm::sys::Process::FixupStandardFileDescriptors())
+ return 1;
+
SmallVector<const char *, 256> argv;
llvm::SpecificBumpPtrAllocator<char> ArgAllocator;
std::error_code EC = llvm::sys::Process::GetArgumentVector(
- argv, ArrayRef<const char *>(argv_, argc_), ArgAllocator);
+ argv, llvm::makeArrayRef(argv_, argc_), ArgAllocator);
if (EC) {
llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';
return 1;
@@ -308,26 +393,33 @@ int main(int argc_, const char **argv_) {
std::set<std::string> SavedStrings;
StringSetSaver Saver(SavedStrings);
- llvm::cl::ExpandResponseFiles(Saver, llvm::cl::TokenizeGNUCommandLine, argv);
-
- // Handle -cc1 integrated tools.
- if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) {
- StringRef Tool = argv[1] + 4;
-
- if (Tool == "")
- return cc1_main(argv.data()+2, argv.data()+argv.size(), argv[0],
- (void*) (intptr_t) GetExecutablePath);
- if (Tool == "as")
- return cc1as_main(argv.data()+2, argv.data()+argv.size(), argv[0],
- (void*) (intptr_t) GetExecutablePath);
- // Reject unknown tools.
- llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n";
- return 1;
+ // Determines whether we want nullptr markers in argv to indicate response
+ // files end-of-lines. We only use this for the /LINK driver argument.
+ bool MarkEOLs = true;
+ if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1"))
+ MarkEOLs = false;
+ llvm::cl::ExpandResponseFiles(Saver, llvm::cl::TokenizeGNUCommandLine, argv,
+ MarkEOLs);
+
+ // Handle -cc1 integrated tools, even if -cc1 was expanded from a response
+ // file.
+ auto FirstArg = std::find_if(argv.begin() + 1, argv.end(),
+ [](const char *A) { return A != nullptr; });
+ if (FirstArg != argv.end() && StringRef(*FirstArg).startswith("-cc1")) {
+ // If -cc1 came from a response file, remove the EOL sentinels.
+ if (MarkEOLs) {
+ auto newEnd = std::remove(argv.begin(), argv.end(), nullptr);
+ argv.resize(newEnd - argv.begin());
+ }
+ return ExecuteCC1Tool(argv, argv[1] + 4);
}
bool CanonicalPrefixes = true;
for (int i = 1, size = argv.size(); i < size; ++i) {
+ // Skip end-of-line response file markers
+ if (argv[i] == nullptr)
+ continue;
if (StringRef(argv[i]) == "-no-canonical-prefixes") {
CanonicalPrefixes = false;
break;
@@ -343,73 +435,34 @@ int main(int argc_, const char **argv_) {
std::string Path = GetExecutablePath(argv[0], CanonicalPrefixes);
- IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions;
- {
- std::unique_ptr<OptTable> Opts(createDriverOptTable());
- unsigned 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.
- (void) ParseDiagnosticArgs(*DiagOpts, *Args);
- }
- // Now we can create the DiagnosticsEngine with a properly-filled-out
- // DiagnosticOptions instance.
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
+ CreateAndPopulateDiagOpts(argv);
+
TextDiagnosticPrinter *DiagClient
= new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
-
- // If the clang binary happens to be named cl.exe for compatibility reasons,
- // use clang-cl.exe as the prefix to avoid confusion between clang and MSVC.
- StringRef ExeBasename(llvm::sys::path::filename(Path));
- if (ExeBasename.equals_lower("cl.exe"))
- ExeBasename = "clang-cl.exe";
- DiagClient->setPrefix(ExeBasename);
+ FixupDiagPrefixExeName(DiagClient, Path);
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
- ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
-
- Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
- // Attempt to find the original path used to invoke the driver, to determine
- // the installed path. We do this manually, because we want to support that
- // path being a symlink.
- {
- SmallString<128> InstalledPath(argv[0]);
-
- // Do a PATH lookup, if there are no directory components.
- if (llvm::sys::path::filename(InstalledPath) == InstalledPath) {
- std::string Tmp = llvm::sys::FindProgramByName(
- llvm::sys::path::filename(InstalledPath.str()));
- if (!Tmp.empty())
- InstalledPath = Tmp;
- }
- llvm::sys::fs::make_absolute(InstalledPath);
- InstalledPath = llvm::sys::path::parent_path(InstalledPath);
- bool exists;
- if (!llvm::sys::fs::exists(InstalledPath.str(), exists) && exists)
- TheDriver.setInstalledDir(InstalledPath);
+ if (!DiagOpts->DiagnosticSerializationFile.empty()) {
+ auto SerializedConsumer =
+ clang::serialized_diags::create(DiagOpts->DiagnosticSerializationFile,
+ &*DiagOpts, /*MergeChildRecords=*/true);
+ Diags.setClient(new ChainedDiagnosticConsumer(
+ Diags.takeClient(), std::move(SerializedConsumer)));
}
- llvm::InitializeAllTargets();
- ParseProgName(argv, SavedStrings, TheDriver);
+ ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
- // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE.
- TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS");
- if (TheDriver.CCPrintOptions)
- TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE");
+ Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
+ SetInstallDir(argv, TheDriver);
- // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE.
- TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS");
- if (TheDriver.CCPrintHeaders)
- TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE");
+ llvm::InitializeAllTargets();
+ ParseProgName(argv, SavedStrings);
- // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE.
- TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS");
- if (TheDriver.CCLogDiagnostics)
- TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE");
+ SetBackdoorDriverOutputsFromEnvVars(TheDriver);
std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
int Res = 0;
@@ -420,14 +473,17 @@ int main(int argc_, const char **argv_) {
// Force a crash to test the diagnostics.
if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) {
Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH";
- const Command *FailingCommand = nullptr;
- FailingCommands.push_back(std::make_pair(-1, FailingCommand));
+
+ // Pretend that every command failed.
+ FailingCommands.clear();
+ for (const auto &J : C->getJobs())
+ if (const Command *C = dyn_cast<Command>(&J))
+ FailingCommands.push_back(std::make_pair(-1, C));
}
- for (SmallVectorImpl< std::pair<int, const Command *> >::iterator it =
- FailingCommands.begin(), ie = FailingCommands.end(); it != ie; ++it) {
- int CommandRes = it->first;
- const Command *FailingCommand = it->second;
+ for (const auto &P : FailingCommands) {
+ int CommandRes = P.first;
+ const Command *FailingCommand = P.second;
if (!Res)
Res = CommandRes;
@@ -440,15 +496,17 @@ int main(int argc_, const char **argv_) {
DiagnoseCrash |= CommandRes == 3;
#endif
if (DiagnoseCrash) {
- TheDriver.generateCompilationDiagnostics(*C, FailingCommand);
+ TheDriver.generateCompilationDiagnostics(*C, *FailingCommand);
break;
}
}
+ Diags.getClient()->finish();
+
// If any timers were active but haven't been destroyed yet, print their
// results now. This happens in -disable-free mode.
llvm::TimerGroup::printAll(llvm::errs());
-
+
llvm::llvm_shutdown();
#ifdef LLVM_ON_WIN32
diff --git a/tools/libclang/ARCMigrate.cpp b/tools/libclang/ARCMigrate.cpp
index 375c5f40c21b..b0b869ba900b 100644
--- a/tools/libclang/ARCMigrate.cpp
+++ b/tools/libclang/ARCMigrate.cpp
@@ -47,9 +47,7 @@ CXRemapping clang_getRemappings(const char *migrate_dir_path) {
return nullptr;
}
- bool exists = false;
- llvm::sys::fs::exists(migrate_dir_path, exists);
- if (!exists) {
+ if (!llvm::sys::fs::exists(migrate_dir_path)) {
if (Logging) {
llvm::errs() << "Error by clang_getRemappings(\"" << migrate_dir_path
<< "\")\n";
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index fc8703aface1..00ef8c0bf424 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -22,10 +22,12 @@
#include "CXType.h"
#include "CursorVisitor.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/Mangle.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticCategories.h"
#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
@@ -40,6 +42,8 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Mangler.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Format.h"
@@ -1256,6 +1260,7 @@ bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
case NestedNameSpecifier::TypeSpecWithTemplate:
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Super:
break;
}
@@ -1297,6 +1302,7 @@ CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Super:
break;
}
}
@@ -1828,6 +1834,7 @@ public:
void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
void VisitCXXCatchStmt(const CXXCatchStmt *S);
+ void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
void VisitDeclRefExpr(const DeclRefExpr *D);
void VisitDeclStmt(const DeclStmt *S);
void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
@@ -1856,21 +1863,28 @@ public:
void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
void VisitLambdaExpr(const LambdaExpr *E);
void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
+ void VisitOMPLoopDirective(const OMPLoopDirective *D);
void VisitOMPParallelDirective(const OMPParallelDirective *D);
void VisitOMPSimdDirective(const OMPSimdDirective *D);
void VisitOMPForDirective(const OMPForDirective *D);
+ void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
void VisitOMPSectionDirective(const OMPSectionDirective *D);
void VisitOMPSingleDirective(const OMPSingleDirective *D);
void VisitOMPMasterDirective(const OMPMasterDirective *D);
void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
+ void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
void VisitOMPTaskDirective(const OMPTaskDirective *D);
void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
void VisitOMPFlushDirective(const OMPFlushDirective *D);
+ void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
+ void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
+ void VisitOMPTargetDirective(const OMPTargetDirective *D);
+ void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
private:
void AddDeclarationNameInfo(const Stmt *S);
@@ -1979,14 +1993,28 @@ void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
+void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
+
+void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
+
+void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
+
+void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
+
+void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
+
template<typename T>
void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
- for (const auto *I : Node->varlists())
+ for (const auto *I : Node->varlists()) {
Visitor->AddStmt(I);
+ }
}
void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
VisitOMPClauseList(C);
+ for (const auto *E : C->private_copies()) {
+ Visitor->AddStmt(E);
+ }
}
void OMPClauseEnqueue::VisitOMPFirstprivateClause(
const OMPFirstprivateClause *C) {
@@ -2127,6 +2155,12 @@ void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
AddDecl(S->getExceptionDecl());
}
+void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
+ AddStmt(S->getBody());
+ AddStmt(S->getRangeInit());
+ AddDecl(S->getLoopVariable());
+}
+
void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
if (DR->hasExplicitTemplateArgs()) {
AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
@@ -2309,16 +2343,24 @@ void EnqueueVisitor::VisitOMPExecutableDirective(
EnqueueChildren(*I);
}
+void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
VisitOMPExecutableDirective(D);
}
void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
- VisitOMPExecutableDirective(D);
+ VisitOMPLoopDirective(D);
}
void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
- VisitOMPExecutableDirective(D);
+ VisitOMPLoopDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
+ VisitOMPLoopDirective(D);
}
void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
@@ -2344,7 +2386,12 @@ void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
void
EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
- VisitOMPExecutableDirective(D);
+ VisitOMPLoopDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPParallelForSimdDirective(
+ const OMPParallelForSimdDirective *D) {
+ VisitOMPLoopDirective(D);
}
void EnqueueVisitor::VisitOMPParallelSectionsDirective(
@@ -2373,6 +2420,22 @@ void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
VisitOMPExecutableDirective(D);
}
+void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
}
@@ -2755,13 +2818,14 @@ enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
FileSystemOptions FileSystemOpts;
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
- ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
- CXXIdx->getOnlyLocalDecls(), None,
- /*CaptureDiagnostics=*/true,
- /*AllowPCHWithCompilerErrors=*/true,
- /*UserFilesAreVolatile=*/true);
- *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+ CompilerInstance::createDiagnostics(new DiagnosticOptions());
+ std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
+ ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
+ /*CaptureDiagnostics=*/true,
+ /*AllowPCHWithCompilerErrors=*/true,
+ /*UserFilesAreVolatile=*/true);
+ *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
return *out_TU ? CXError_Success : CXError_Failure;
}
@@ -2847,9 +2911,9 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
for (auto &UF : PTUI->unsaved_files) {
- llvm::MemoryBuffer *MB =
+ std::unique_ptr<llvm::MemoryBuffer> MB =
llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
- RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
+ RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
}
std::unique_ptr<std::vector<const char *>> Args(
@@ -3131,9 +3195,9 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) {
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
for (auto &UF : RTUI->unsaved_files) {
- llvm::MemoryBuffer *MB =
+ std::unique_ptr<llvm::MemoryBuffer> MB =
llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
- RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
+ RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
}
if (!CXXUnit->Reparse(*RemappedFiles.get()))
@@ -3259,6 +3323,18 @@ int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
return 0;
}
+int clang_File_isEqual(CXFile file1, CXFile file2) {
+ if (file1 == file2)
+ return true;
+
+ if (!file1 || !file2)
+ return false;
+
+ FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
+ FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
+ return FEnt1->getUniqueID() == FEnt2->getUniqueID();
+}
+
} // end: extern "C"
//===----------------------------------------------------------------------===//
@@ -3628,6 +3704,18 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
return clang_getNullRange();
}
+ if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
+ C.kind == CXCursor_ConversionFunction) {
+ if (pieceIndex > 0)
+ return clang_getNullRange();
+ if (const FunctionDecl *FD =
+ dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
+ DeclarationNameInfo FunctionName = FD->getNameInfo();
+ return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
+ }
+ return clang_getNullRange();
+ }
+
// FIXME: A CXCursor_InclusionDirective should give the location of the
// filename, but we don't keep track of this.
@@ -3647,6 +3735,37 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
return cxloc::translateSourceRange(Ctx, Loc);
}
+CXString clang_Cursor_getMangling(CXCursor C) {
+ if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
+ return cxstring::createEmpty();
+
+ // Mangling only works for functions and variables.
+ const Decl *D = getCursorDecl(C);
+ if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
+ return cxstring::createEmpty();
+
+ // First apply frontend mangling.
+ const NamedDecl *ND = cast<NamedDecl>(D);
+ ASTContext &Ctx = ND->getASTContext();
+ std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
+
+ std::string FrontendBuf;
+ llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
+ MC->mangleName(ND, FrontendBufOS);
+
+ // Now apply backend mangling.
+ std::unique_ptr<llvm::DataLayout> DL(
+ new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
+ llvm::Mangler BackendMangler(DL.get());
+
+ std::string FinalBuf;
+ llvm::raw_string_ostream FinalBufOS(FinalBuf);
+ BackendMangler.getNameWithPrefix(FinalBufOS,
+ llvm::Twine(FrontendBufOS.str()));
+
+ return cxstring::createDup(FinalBufOS.str());
+}
+
CXString clang_getCursorDisplayName(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getCursorSpelling(C);
@@ -3997,6 +4116,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("attribute(global)");
case CXCursor_CUDAHostAttr:
return cxstring::createRef("attribute(host)");
+ case CXCursor_CUDASharedAttr:
+ return cxstring::createRef("attribute(shared)");
case CXCursor_PreprocessingDirective:
return cxstring::createRef("preprocessing directive");
case CXCursor_MacroDefinition:
@@ -4051,6 +4172,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("OMPSimdDirective");
case CXCursor_OMPForDirective:
return cxstring::createRef("OMPForDirective");
+ case CXCursor_OMPForSimdDirective:
+ return cxstring::createRef("OMPForSimdDirective");
case CXCursor_OMPSectionsDirective:
return cxstring::createRef("OMPSectionsDirective");
case CXCursor_OMPSectionDirective:
@@ -4063,6 +4186,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("OMPCriticalDirective");
case CXCursor_OMPParallelForDirective:
return cxstring::createRef("OMPParallelForDirective");
+ case CXCursor_OMPParallelForSimdDirective:
+ return cxstring::createRef("OMPParallelForSimdDirective");
case CXCursor_OMPParallelSectionsDirective:
return cxstring::createRef("OMPParallelSectionsDirective");
case CXCursor_OMPTaskDirective:
@@ -4075,6 +4200,14 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("OMPTaskwaitDirective");
case CXCursor_OMPFlushDirective:
return cxstring::createRef("OMPFlushDirective");
+ case CXCursor_OMPOrderedDirective:
+ return cxstring::createRef("OMPOrderedDirective");
+ case CXCursor_OMPAtomicDirective:
+ return cxstring::createRef("OMPAtomicDirective");
+ case CXCursor_OMPTargetDirective:
+ return cxstring::createRef("OMPTargetDirective");
+ case CXCursor_OMPTeamsDirective:
+ return cxstring::createRef("OMPTeamsDirective");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -6296,6 +6429,40 @@ static const Decl *maybeGetTemplateCursor(const Decl *D) {
return D;
}
+
+enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
+ StorageClass sc = SC_None;
+ const Decl *D = getCursorDecl(C);
+ if (D) {
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ sc = FD->getStorageClass();
+ } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ sc = VD->getStorageClass();
+ } else {
+ return CX_SC_Invalid;
+ }
+ } else {
+ return CX_SC_Invalid;
+ }
+ switch (sc) {
+ case SC_None:
+ return CX_SC_None;
+ case SC_Extern:
+ return CX_SC_Extern;
+ case SC_Static:
+ return CX_SC_Static;
+ case SC_PrivateExtern:
+ return CX_SC_PrivateExtern;
+ case SC_OpenCLWorkGroupLocal:
+ return CX_SC_OpenCLWorkGroupLocal;
+ case SC_Auto:
+ return CX_SC_Auto;
+ case SC_Register:
+ return CX_SC_Register;
+ }
+ llvm_unreachable("Unhandled storage class!");
+}
+
CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
if (clang_isDeclaration(cursor.kind)) {
if (const Decl *D = getCursorDecl(cursor)) {
@@ -6490,11 +6657,7 @@ CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
- if (Module *Mod = Header.getModule()) {
- if (Header.getRole() != ModuleMap::ExcludedHeader)
- return Mod;
- }
- return nullptr;
+ return Header.getModule();
}
CXFile clang_Module_getASTFile(CXModule CXMod) {
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 0d88003a1f6c..b6f71d20de2b 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -692,9 +692,9 @@ void clang_codeCompleteAt_Impl(void *UserData) {
SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
for (auto &UF : CCAI->unsaved_files) {
- llvm::MemoryBuffer *MB =
+ std::unique_ptr<llvm::MemoryBuffer> MB =
llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
- RemappedFiles.push_back(std::make_pair(UF.Filename, MB));
+ RemappedFiles.push_back(std::make_pair(UF.Filename, MB.release()));
}
if (EnableLogging) {
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 0d97ebd9335b..4d646f0cf828 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -30,13 +30,11 @@ using namespace clang::cxloc;
using namespace clang::cxdiag;
using namespace llvm;
+CXDiagnosticSetImpl::~CXDiagnosticSetImpl() {}
-CXDiagnosticSetImpl::~CXDiagnosticSetImpl() {
- for (std::vector<CXDiagnosticImpl *>::iterator it = Diagnostics.begin(),
- et = Diagnostics.end();
- it != et; ++it) {
- delete *it;
- }
+void
+CXDiagnosticSetImpl::appendDiagnostic(std::unique_ptr<CXDiagnosticImpl> D) {
+ Diagnostics.push_back(std::move(D));
}
CXDiagnosticImpl::~CXDiagnosticImpl() {}
@@ -105,12 +103,13 @@ public:
if (Level != DiagnosticsEngine::Note)
CurrentSet = MainSet;
-
- CXStoredDiagnostic *CD = new CXStoredDiagnostic(*SD, LangOpts);
- CurrentSet->appendDiagnostic(CD);
-
+
+ auto Owner = llvm::make_unique<CXStoredDiagnostic>(*SD, LangOpts);
+ CXStoredDiagnostic &CD = *Owner;
+ CurrentSet->appendDiagnostic(std::move(Owner));
+
if (Level != DiagnosticsEngine::Note)
- CurrentSet = &CD->getChildDiagnostics();
+ CurrentSet = &CD.getChildDiagnostics();
}
void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
@@ -127,8 +126,8 @@ public:
L = translateSourceLocation(*SM, LangOpts, Loc);
else
L = clang_getNullLocation();
- CXDiagnosticImpl *CD = new CXDiagnosticCustomNoteImpl(Message, L);
- CurrentSet->appendDiagnostic(CD);
+ CurrentSet->appendDiagnostic(
+ llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
}
void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
@@ -149,8 +148,8 @@ public:
L = translateSourceLocation(*SM, LangOpts, Loc);
else
L = clang_getNullLocation();
- CurrentSet->appendDiagnostic(new CXDiagnosticCustomNoteImpl(Message,
- L));
+ CurrentSet->appendDiagnostic(
+ llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
}
CXDiagnosticSetImpl *CurrentSet;
diff --git a/tools/libclang/CIndexDiagnostic.h b/tools/libclang/CIndexDiagnostic.h
index 31ae902eac4e..4347fb75f4a5 100644
--- a/tools/libclang/CIndexDiagnostic.h
+++ b/tools/libclang/CIndexDiagnostic.h
@@ -10,10 +10,11 @@
|* Implements the diagnostic functions of the Clang C interface. *|
|* *|
\*===----------------------------------------------------------------------===*/
-#ifndef LLVM_CLANG_CINDEX_DIAGNOSTIC_H
-#define LLVM_CLANG_CINDEX_DIAGNOSTIC_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CINDEXDIAGNOSTIC_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CINDEXDIAGNOSTIC_H
#include "clang-c/Index.h"
+#include <memory>
#include <vector>
#include <assert.h>
@@ -24,27 +25,25 @@ class StoredDiagnostic;
class CXDiagnosticImpl;
class CXDiagnosticSetImpl {
- std::vector<CXDiagnosticImpl *> Diagnostics;
+ std::vector<std::unique_ptr<CXDiagnosticImpl>> Diagnostics;
const bool IsExternallyManaged;
public:
CXDiagnosticSetImpl(bool isManaged = false)
: IsExternallyManaged(isManaged) {}
virtual ~CXDiagnosticSetImpl();
-
+
size_t getNumDiagnostics() const {
return Diagnostics.size();
}
CXDiagnosticImpl *getDiagnostic(unsigned i) const {
assert(i < getNumDiagnostics());
- return Diagnostics[i];
+ return Diagnostics[i].get();
}
-
- void appendDiagnostic(CXDiagnosticImpl *D) {
- Diagnostics.push_back(D);
- }
-
+
+ void appendDiagnostic(std::unique_ptr<CXDiagnosticImpl> D);
+
bool empty() const {
return Diagnostics.empty();
}
@@ -99,9 +98,9 @@ public:
protected:
CXDiagnosticImpl(Kind k) : K(k) {}
CXDiagnosticSetImpl ChildDiags;
-
- void append(CXDiagnosticImpl *D) {
- ChildDiags.appendDiagnostic(D);
+
+ void append(std::unique_ptr<CXDiagnosticImpl> D) {
+ ChildDiags.appendDiagnostic(std::move(D));
}
private:
@@ -163,4 +162,4 @@ CXDiagnosticSetImpl *lazyCreateDiags(CXTranslationUnit TU,
} // end namespace clang
-#endif // LLVM_CLANG_CINDEX_DIAGNOSTIC_H
+#endif
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 25881c3ef062..d7b65852844e 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -15,9 +15,9 @@
#include "CXCursor.h"
#include "CXString.h"
#include "CXTranslationUnit.h"
+#include "clang/Frontend/ASTUnit.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"
diff --git a/tools/libclang/CIndexer.h b/tools/libclang/CIndexer.h
index 95d8115a2eee..7a8dbd37d022 100644
--- a/tools/libclang/CIndexer.h
+++ b/tools/libclang/CIndexer.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CINDEXER_H
-#define LLVM_CLANG_CINDEXER_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CINDEXER_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CINDEXER_H
#include "clang-c/Index.h"
#include "llvm/ADT/StringRef.h"
diff --git a/tools/libclang/CLog.h b/tools/libclang/CLog.h
index e7419b71f83f..b9309ed19239 100644
--- a/tools/libclang/CLog.h
+++ b/tools/libclang/CLog.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBCLANG_CLOG_H
-#define LLVM_LIBCLANG_CLOG_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CLOG_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CLOG_H
#include "clang-c/Index.h"
#include "clang/Basic/LLVM.h"
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index e7ab63f7b99d..f1c3f4ca8b23 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -86,7 +86,7 @@ add_clang_library(libclang ${ENABLE_SHARED} ${ENABLE_STATIC}
${LIBS}
LINK_COMPONENTS
- BitReader
+ Core
Support
)
diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp
index 454703149c9d..9cc05ed4e127 100644
--- a/tools/libclang/CXComment.cpp
+++ b/tools/libclang/CXComment.cpp
@@ -12,10 +12,10 @@
//===----------------------------------------------------------------------===//
#include "clang-c/Index.h"
-#include "clang-c/Documentation.h"
#include "CXComment.h"
#include "CXCursor.h"
#include "CXString.h"
+#include "clang-c/Documentation.h"
#include "clang/AST/Decl.h"
#include "clang/Index/CommentToXML.h"
#include "llvm/ADT/StringExtras.h"
diff --git a/tools/libclang/CXComment.h b/tools/libclang/CXComment.h
index d9d2bdef4127..a937a8034636 100644
--- a/tools/libclang/CXComment.h
+++ b/tools/libclang/CXComment.h
@@ -11,12 +11,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CXCOMMENT_H
-#define LLVM_CLANG_CXCOMMENT_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXCOMMENT_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CXCOMMENT_H
#include "CXTranslationUnit.h"
-#include "clang-c/Index.h"
#include "clang-c/Documentation.h"
+#include "clang-c/Index.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Comment.h"
#include "clang/Frontend/ASTUnit.h"
diff --git a/tools/libclang/CXCompilationDatabase.cpp b/tools/libclang/CXCompilationDatabase.cpp
index 51677e721035..1e4a2cd44aab 100644
--- a/tools/libclang/CXCompilationDatabase.cpp
+++ b/tools/libclang/CXCompilationDatabase.cpp
@@ -16,8 +16,8 @@ clang_CompilationDatabase_fromDirectory(const char *BuildDir,
std::string ErrorMsg;
CXCompilationDatabase_Error Err = CXCompilationDatabase_NoError;
- CompilationDatabase *db = CompilationDatabase::loadFromDirectory(BuildDir,
- ErrorMsg);
+ std::unique_ptr<CompilationDatabase> db =
+ CompilationDatabase::loadFromDirectory(BuildDir, ErrorMsg);
if (!db) {
fprintf(stderr, "LIBCLANG TOOLING ERROR: %s\n", ErrorMsg.c_str());
@@ -27,7 +27,7 @@ clang_CompilationDatabase_fromDirectory(const char *BuildDir,
if (ErrorCode)
*ErrorCode = Err;
- return db;
+ return db.release();
}
void
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 432190390b7f..7834181d4781 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -57,6 +57,7 @@ static CXCursorKind GetCursorKind(const Attr *A) {
case attr::CUDADevice: return CXCursor_CUDADeviceAttr;
case attr::CUDAGlobal: return CXCursor_CUDAGlobalAttr;
case attr::CUDAHost: return CXCursor_CUDAHostAttr;
+ case attr::CUDAShared: return CXCursor_CUDASharedAttr;
}
return CXCursor_UnexposedAttr;
@@ -228,6 +229,7 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::CXXBindTemporaryExprClass:
case Stmt::CXXDefaultArgExprClass:
case Stmt::CXXDefaultInitExprClass:
+ case Stmt::CXXFoldExprClass:
case Stmt::CXXStdInitializerListExprClass:
case Stmt::CXXScalarValueInitExprClass:
case Stmt::CXXUuidofExprClass:
@@ -468,6 +470,7 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::SubstNonTypeTemplateParmPackExprClass:
case Stmt::FunctionParmPackExprClass:
case Stmt::UnresolvedLookupExprClass:
+ case Stmt::TypoExprClass: // A typo could actually be a DeclRef or a MemberRef
K = CXCursor_DeclRefExpr;
break;
@@ -526,6 +529,9 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::OMPForDirectiveClass:
K = CXCursor_OMPForDirective;
break;
+ case Stmt::OMPForSimdDirectiveClass:
+ K = CXCursor_OMPForSimdDirective;
+ break;
case Stmt::OMPSectionsDirectiveClass:
K = CXCursor_OMPSectionsDirective;
break;
@@ -544,6 +550,9 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::OMPParallelForDirectiveClass:
K = CXCursor_OMPParallelForDirective;
break;
+ case Stmt::OMPParallelForSimdDirectiveClass:
+ K = CXCursor_OMPParallelForSimdDirective;
+ break;
case Stmt::OMPParallelSectionsDirectiveClass:
K = CXCursor_OMPParallelSectionsDirective;
break;
@@ -562,6 +571,18 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::OMPFlushDirectiveClass:
K = CXCursor_OMPFlushDirective;
break;
+ case Stmt::OMPOrderedDirectiveClass:
+ K = CXCursor_OMPOrderedDirective;
+ break;
+ case Stmt::OMPAtomicDirectiveClass:
+ K = CXCursor_OMPAtomicDirective;
+ break;
+ case Stmt::OMPTargetDirectiveClass:
+ K = CXCursor_OMPTargetDirective;
+ break;
+ case Stmt::OMPTeamsDirectiveClass:
+ K = CXCursor_OMPTeamsDirective;
+ break;
}
CXCursor C = { K, 0, { Parent, S, TU } };
@@ -1055,6 +1076,140 @@ CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
return clang_getNullCursor();
}
+int clang_Cursor_getNumTemplateArguments(CXCursor C) {
+ if (clang_getCursorKind(C) != CXCursor_FunctionDecl) {
+ return -1;
+ }
+
+ const FunctionDecl *FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(
+ getCursorDecl(C));
+ if (!FD) {
+ return -1;
+ }
+
+ const FunctionTemplateSpecializationInfo* SpecInfo =
+ FD->getTemplateSpecializationInfo();
+ if (!SpecInfo) {
+ return -1;
+ }
+
+ return SpecInfo->TemplateArguments->size();
+}
+
+enum CXGetTemplateArgumentStatus {
+ /** \brief The operation completed successfully */
+ CXGetTemplateArgumentStatus_Success = 0,
+
+ /** \brief The specified cursor did not represent a FunctionDecl. */
+ CXGetTemplateArgumentStatus_CursorNotFunctionDecl = -1,
+
+ /** \brief The specified cursor was not castable to a FunctionDecl. */
+ CXGetTemplateArgumentStatus_BadFunctionDeclCast = -2,
+
+ /** \brief A NULL FunctionTemplateSpecializationInfo was retrieved. */
+ CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3,
+
+ /** \brief An invalid (OOB) argument index was specified */
+ CXGetTemplateArgumentStatus_InvalidIndex = -4
+};
+
+static int clang_Cursor_getTemplateArgument(
+ CXCursor C, unsigned I, TemplateArgument *TA) {
+ if (clang_getCursorKind(C) != CXCursor_FunctionDecl) {
+ return CXGetTemplateArgumentStatus_CursorNotFunctionDecl;
+ }
+
+ const FunctionDecl *FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(
+ getCursorDecl(C));
+ if (!FD) {
+ return CXGetTemplateArgumentStatus_BadFunctionDeclCast;
+ }
+
+ const FunctionTemplateSpecializationInfo* SpecInfo =
+ FD->getTemplateSpecializationInfo();
+ if (!SpecInfo) {
+ return CXGetTemplateArgumentStatus_NullTemplSpecInfo;
+ }
+
+ if (I >= SpecInfo->TemplateArguments->size()) {
+ return CXGetTemplateArgumentStatus_InvalidIndex;
+ }
+
+ *TA = SpecInfo->TemplateArguments->get(I);
+ return 0;
+}
+
+enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C,
+ unsigned I) {
+ TemplateArgument TA;
+ if (clang_Cursor_getTemplateArgument(C, I, &TA)) {
+ return CXTemplateArgumentKind_Invalid;
+ }
+
+ switch (TA.getKind()) {
+ case TemplateArgument::Null: return CXTemplateArgumentKind_Null;
+ case TemplateArgument::Type: return CXTemplateArgumentKind_Type;
+ case TemplateArgument::Declaration:
+ return CXTemplateArgumentKind_Declaration;
+ case TemplateArgument::NullPtr: return CXTemplateArgumentKind_NullPtr;
+ case TemplateArgument::Integral: return CXTemplateArgumentKind_Integral;
+ case TemplateArgument::Template: return CXTemplateArgumentKind_Template;
+ case TemplateArgument::TemplateExpansion:
+ return CXTemplateArgumentKind_TemplateExpansion;
+ case TemplateArgument::Expression: return CXTemplateArgumentKind_Expression;
+ case TemplateArgument::Pack: return CXTemplateArgumentKind_Pack;
+ }
+
+ return CXTemplateArgumentKind_Invalid;
+}
+
+CXType clang_Cursor_getTemplateArgumentType(CXCursor C, unsigned I) {
+ TemplateArgument TA;
+ if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
+ CXGetTemplateArgumentStatus_Success) {
+ return cxtype::MakeCXType(QualType(), getCursorTU(C));
+ }
+
+ if (TA.getKind() != TemplateArgument::Type) {
+ return cxtype::MakeCXType(QualType(), getCursorTU(C));
+ }
+
+ return cxtype::MakeCXType(TA.getAsType(), getCursorTU(C));
+}
+
+long long clang_Cursor_getTemplateArgumentValue(CXCursor C, unsigned I) {
+ TemplateArgument TA;
+ if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
+ CXGetTemplateArgumentStatus_Success) {
+ assert(0 && "Unable to retrieve TemplateArgument");
+ return 0;
+ }
+
+ if (TA.getKind() != TemplateArgument::Integral) {
+ assert(0 && "Passed template argument is not Integral");
+ return 0;
+ }
+
+ return TA.getAsIntegral().getSExtValue();
+}
+
+unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C,
+ unsigned I) {
+ TemplateArgument TA;
+ if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
+ CXGetTemplateArgumentStatus_Success) {
+ assert(0 && "Unable to retrieve TemplateArgument");
+ return 0;
+ }
+
+ if (TA.getKind() != TemplateArgument::Integral) {
+ assert(0 && "Passed template argument is not Integral");
+ return 0;
+ }
+
+ return TA.getAsIntegral().getZExtValue();
+}
+
} // end: extern "C"
//===----------------------------------------------------------------------===//
@@ -1262,8 +1417,16 @@ int clang_Cursor_isDynamicCall(CXCursor C) {
if (!E)
return 0;
- if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E))
- return MsgE->getReceiverKind() == ObjCMessageExpr::Instance;
+ if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
+ if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
+ return false;
+ if (auto *RecE = dyn_cast<ObjCMessageExpr>(
+ MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
+ if (RecE->getMethodFamily() == OMF_alloc)
+ return false;
+ }
+ return true;
+ }
const MemberExpr *ME = nullptr;
if (isa<MemberExpr>(E))
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index fee3bac95379..931d112766ed 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CXCURSOR_H
-#define LLVM_CLANG_CXCURSOR_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H
#include "clang-c/Index.h"
#include "clang/Basic/SourceLocation.h"
diff --git a/tools/libclang/CXLoadedDiagnostic.cpp b/tools/libclang/CXLoadedDiagnostic.cpp
index ddf374903a93..fe5599a3abc9 100644
--- a/tools/libclang/CXLoadedDiagnostic.cpp
+++ b/tools/libclang/CXLoadedDiagnostic.cpp
@@ -16,7 +16,8 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Frontend/SerializedDiagnosticPrinter.h"
+#include "clang/Frontend/SerializedDiagnosticReader.h"
+#include "clang/Frontend/SerializedDiagnostics.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -183,475 +184,207 @@ void CXLoadedDiagnostic::decodeLocation(CXSourceLocation location,
// Deserialize diagnostics.
//===----------------------------------------------------------------------===//
-enum { MaxSupportedVersion = 2 };
-typedef SmallVector<uint64_t, 64> RecordData;
-enum LoadResult { Failure = 1, Success = 0 };
-enum StreamResult { Read_EndOfStream,
- Read_BlockBegin,
- Read_Failure,
- Read_Record,
- Read_BlockEnd };
-
namespace {
-class DiagLoader {
+class DiagLoader : serialized_diags::SerializedDiagnosticReader {
enum CXLoadDiag_Error *error;
CXString *errorString;
-
- void reportBad(enum CXLoadDiag_Error code, llvm::StringRef err) {
+ std::unique_ptr<CXLoadedDiagnosticSetImpl> TopDiags;
+ SmallVector<std::unique_ptr<CXLoadedDiagnostic>, 8> CurrentDiags;
+
+ std::error_code reportBad(enum CXLoadDiag_Error code, llvm::StringRef err) {
if (error)
*error = code;
if (errorString)
*errorString = cxstring::createDup(err);
+ return serialized_diags::SDError::HandlerFailed;
}
- void reportInvalidFile(llvm::StringRef err) {
+ std::error_code reportInvalidFile(llvm::StringRef err) {
return reportBad(CXLoadDiag_InvalidFile, err);
}
- LoadResult readMetaBlock(llvm::BitstreamCursor &Stream);
-
- LoadResult readDiagnosticBlock(llvm::BitstreamCursor &Stream,
- CXDiagnosticSetImpl &Diags,
- CXLoadedDiagnosticSetImpl &TopDiags);
-
- StreamResult readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
- llvm::StringRef errorContext,
- unsigned &BlockOrRecordID,
- bool atTopLevel = false);
-
-
- LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
- Strings &strings, llvm::StringRef errorContext,
- RecordData &Record,
- StringRef Blob,
- bool allowEmptyString = false);
-
- LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
- const char *&RetStr,
- llvm::StringRef errorContext,
- RecordData &Record,
- StringRef Blob,
- bool allowEmptyString = false);
-
- LoadResult readRange(CXLoadedDiagnosticSetImpl &TopDiags,
- RecordData &Record, unsigned RecStartIdx,
- CXSourceRange &SR);
-
- LoadResult readLocation(CXLoadedDiagnosticSetImpl &TopDiags,
- RecordData &Record, unsigned &offset,
- CXLoadedDiagnostic::Location &Loc);
-
-public:
- DiagLoader(enum CXLoadDiag_Error *e, CXString *es)
- : error(e), errorString(es) {
- if (error)
- *error = CXLoadDiag_None;
- if (errorString)
- *errorString = cxstring::createEmpty();
- }
+ std::error_code readRange(const serialized_diags::Location &SDStart,
+ const serialized_diags::Location &SDEnd,
+ CXSourceRange &SR);
- CXDiagnosticSet load(const char *file);
-};
-}
+ std::error_code readLocation(const serialized_diags::Location &SDLoc,
+ CXLoadedDiagnostic::Location &LoadedLoc);
-CXDiagnosticSet DiagLoader::load(const char *file) {
- // Open the diagnostics file.
- std::string ErrStr;
- FileSystemOptions FO;
- FileManager FileMgr(FO);
+protected:
+ std::error_code visitStartOfDiagnostic() override;
+ std::error_code visitEndOfDiagnostic() override;
- std::unique_ptr<llvm::MemoryBuffer> Buffer;
- Buffer.reset(FileMgr.getBufferForFile(file));
+ std::error_code visitCategoryRecord(unsigned ID, StringRef Name) override;
- if (!Buffer) {
- reportBad(CXLoadDiag_CannotLoad, ErrStr);
- return nullptr;
- }
+ std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) override;
- llvm::BitstreamReader StreamFile;
- StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
- (const unsigned char *)Buffer->getBufferEnd());
-
- llvm::BitstreamCursor Stream;
- Stream.init(StreamFile);
-
- // Sniff for the signature.
- if (Stream.Read(8) != 'D' ||
- Stream.Read(8) != 'I' ||
- Stream.Read(8) != 'A' ||
- Stream.Read(8) != 'G') {
- reportBad(CXLoadDiag_InvalidFile,
- "Bad header in diagnostics file");
- return nullptr;
- }
+ std::error_code visitDiagnosticRecord(
+ unsigned Severity, const serialized_diags::Location &Location,
+ unsigned Category, unsigned Flag, StringRef Message) override;
- std::unique_ptr<CXLoadedDiagnosticSetImpl> Diags(
- new CXLoadedDiagnosticSetImpl());
-
- while (true) {
- unsigned BlockID = 0;
- StreamResult Res = readToNextRecordOrBlock(Stream, "Top-level",
- BlockID, true);
- switch (Res) {
- case Read_EndOfStream:
- return (CXDiagnosticSet)Diags.release();
- case Read_Failure:
- return nullptr;
- case Read_Record:
- llvm_unreachable("Top-level does not have records");
- case Read_BlockEnd:
- continue;
- case Read_BlockBegin:
- break;
- }
-
- switch (BlockID) {
- case serialized_diags::BLOCK_META:
- if (readMetaBlock(Stream))
- return nullptr;
- break;
- case serialized_diags::BLOCK_DIAG:
- if (readDiagnosticBlock(Stream, *Diags.get(), *Diags.get()))
- return nullptr;
- break;
- default:
- if (!Stream.SkipBlock()) {
- reportInvalidFile("Malformed block at top-level of diagnostics file");
- return nullptr;
- }
- break;
- }
+ std::error_code visitFilenameRecord(unsigned ID, unsigned Size,
+ unsigned Timestamp,
+ StringRef Name) override;
+
+ std::error_code visitFixitRecord(const serialized_diags::Location &Start,
+ const serialized_diags::Location &End,
+ StringRef CodeToInsert) override;
+
+ std::error_code
+ visitSourceRangeRecord(const serialized_diags::Location &Start,
+ const serialized_diags::Location &End) override;
+
+public:
+ DiagLoader(enum CXLoadDiag_Error *e, CXString *es)
+ : SerializedDiagnosticReader(), error(e), errorString(es) {
+ if (error)
+ *error = CXLoadDiag_None;
+ if (errorString)
+ *errorString = cxstring::createEmpty();
}
+
+ CXDiagnosticSet load(const char *file);
+};
}
-StreamResult DiagLoader::readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
- llvm::StringRef errorContext,
- unsigned &blockOrRecordID,
- bool atTopLevel) {
-
- blockOrRecordID = 0;
-
- while (!Stream.AtEndOfStream()) {
- unsigned Code = Stream.ReadCode();
-
- // Handle the top-level specially.
- if (atTopLevel) {
- if (Code == llvm::bitc::ENTER_SUBBLOCK) {
- unsigned BlockID = Stream.ReadSubBlockID();
- if (BlockID == llvm::bitc::BLOCKINFO_BLOCK_ID) {
- if (Stream.ReadBlockInfoBlock()) {
- reportInvalidFile("Malformed BlockInfoBlock in diagnostics file");
- return Read_Failure;
- }
- continue;
- }
- blockOrRecordID = BlockID;
- return Read_BlockBegin;
- }
- reportInvalidFile("Only blocks can appear at the top of a "
- "diagnostic file");
- return Read_Failure;
- }
-
- switch ((llvm::bitc::FixedAbbrevIDs)Code) {
- case llvm::bitc::ENTER_SUBBLOCK:
- blockOrRecordID = Stream.ReadSubBlockID();
- return Read_BlockBegin;
-
- case llvm::bitc::END_BLOCK:
- if (Stream.ReadBlockEnd()) {
- reportInvalidFile("Cannot read end of block");
- return Read_Failure;
- }
- return Read_BlockEnd;
-
- case llvm::bitc::DEFINE_ABBREV:
- Stream.ReadAbbrevRecord();
- continue;
-
- case llvm::bitc::UNABBREV_RECORD:
- reportInvalidFile("Diagnostics file should have no unabbreviated "
- "records");
- return Read_Failure;
-
- default:
- // We found a record.
- blockOrRecordID = Code;
- return Read_Record;
+CXDiagnosticSet DiagLoader::load(const char *file) {
+ TopDiags = llvm::make_unique<CXLoadedDiagnosticSetImpl>();
+
+ std::error_code EC = readDiagnostics(file);
+ if (EC) {
+ switch (EC.value()) {
+ case static_cast<int>(serialized_diags::SDError::HandlerFailed):
+ // We've already reported the problem.
+ break;
+ case static_cast<int>(serialized_diags::SDError::CouldNotLoad):
+ reportBad(CXLoadDiag_CannotLoad, EC.message());
+ break;
+ default:
+ reportInvalidFile(EC.message());
+ break;
}
+ return 0;
}
-
- if (atTopLevel)
- return Read_EndOfStream;
-
- reportInvalidFile(Twine("Premature end of diagnostics file within ").str() +
- errorContext.str());
- return Read_Failure;
+
+ return (CXDiagnosticSet)TopDiags.release();
}
-LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
- if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_META)) {
- reportInvalidFile("Malformed metadata block");
- return Failure;
- }
-
- bool versionChecked = false;
-
- while (true) {
- unsigned blockOrCode = 0;
- StreamResult Res = readToNextRecordOrBlock(Stream, "Metadata Block",
- blockOrCode);
-
- switch(Res) {
- case Read_EndOfStream:
- llvm_unreachable("EndOfStream handled by readToNextRecordOrBlock");
- case Read_Failure:
- return Failure;
- case Read_Record:
- break;
- case Read_BlockBegin:
- if (Stream.SkipBlock()) {
- reportInvalidFile("Malformed metadata block");
- return Failure;
- }
- case Read_BlockEnd:
- if (!versionChecked) {
- reportInvalidFile("Diagnostics file does not contain version"
- " information");
- return Failure;
- }
- return Success;
- }
-
- RecordData Record;
- unsigned recordID = Stream.readRecord(blockOrCode, Record);
-
- if (recordID == serialized_diags::RECORD_VERSION) {
- if (Record.size() < 1) {
- reportInvalidFile("malformed VERSION identifier in diagnostics file");
- return Failure;
- }
- if (Record[0] > MaxSupportedVersion) {
- reportInvalidFile("diagnostics file is a newer version than the one "
- "supported");
- return Failure;
- }
- versionChecked = true;
- }
+std::error_code
+DiagLoader::readLocation(const serialized_diags::Location &SDLoc,
+ CXLoadedDiagnostic::Location &LoadedLoc) {
+ unsigned FileID = SDLoc.FileID;
+ if (FileID == 0)
+ LoadedLoc.file = nullptr;
+ else {
+ LoadedLoc.file = const_cast<FileEntry *>(TopDiags->Files[FileID]);
+ if (!LoadedLoc.file)
+ return reportInvalidFile("Corrupted file entry in source location");
}
+ LoadedLoc.line = SDLoc.Line;
+ LoadedLoc.column = SDLoc.Col;
+ LoadedLoc.offset = SDLoc.Offset;
+ return std::error_code();
}
-LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
- const char *&RetStr,
- llvm::StringRef errorContext,
- RecordData &Record,
- StringRef Blob,
- bool allowEmptyString) {
+std::error_code
+DiagLoader::readRange(const serialized_diags::Location &SDStart,
+ const serialized_diags::Location &SDEnd,
+ CXSourceRange &SR) {
+ CXLoadedDiagnostic::Location *Start, *End;
+ Start = TopDiags->Alloc.Allocate<CXLoadedDiagnostic::Location>();
+ End = TopDiags->Alloc.Allocate<CXLoadedDiagnostic::Location>();
+
+ std::error_code EC;
+ if ((EC = readLocation(SDStart, *Start)))
+ return EC;
+ if ((EC = readLocation(SDEnd, *End)))
+ return EC;
- // Basic buffer overflow check.
- if (Blob.size() > 65536) {
- reportInvalidFile(std::string("Out-of-bounds string in ") +
- std::string(errorContext));
- return Failure;
- }
+ CXSourceLocation startLoc = makeLocation(Start);
+ CXSourceLocation endLoc = makeLocation(End);
+ SR = clang_getRange(startLoc, endLoc);
+ return std::error_code();
+}
- if (allowEmptyString && Record.size() >= 1 && Blob.size() == 0) {
- RetStr = "";
- return Success;
- }
-
- if (Record.size() < 1 || Blob.size() == 0) {
- reportInvalidFile(std::string("Corrupted ") + std::string(errorContext)
- + std::string(" entry"));
- return Failure;
- }
-
- RetStr = TopDiags.copyString(Blob);
- return Success;
+std::error_code DiagLoader::visitStartOfDiagnostic() {
+ CurrentDiags.push_back(llvm::make_unique<CXLoadedDiagnostic>());
+ return std::error_code();
}
-LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
- Strings &strings,
- llvm::StringRef errorContext,
- RecordData &Record,
- StringRef Blob,
- bool allowEmptyString) {
- const char *RetStr;
- if (readString(TopDiags, RetStr, errorContext, Record, Blob,
- allowEmptyString))
- return Failure;
- strings[Record[0]] = RetStr;
- return Success;
+std::error_code DiagLoader::visitEndOfDiagnostic() {
+ auto D = CurrentDiags.pop_back_val();
+ if (CurrentDiags.empty())
+ TopDiags->appendDiagnostic(std::move(D));
+ else
+ CurrentDiags.back()->getChildDiagnostics().appendDiagnostic(std::move(D));
+ return std::error_code();
}
-LoadResult DiagLoader::readLocation(CXLoadedDiagnosticSetImpl &TopDiags,
- RecordData &Record, unsigned &offset,
- CXLoadedDiagnostic::Location &Loc) {
- if (Record.size() < offset + 3) {
- reportInvalidFile("Corrupted source location");
- return Failure;
- }
-
- unsigned fileID = Record[offset++];
- if (fileID == 0) {
- // Sentinel value.
- Loc.file = nullptr;
- Loc.line = 0;
- Loc.column = 0;
- Loc.offset = 0;
- return Success;
- }
+std::error_code DiagLoader::visitCategoryRecord(unsigned ID, StringRef Name) {
+ // FIXME: Why do we care about long strings?
+ if (Name.size() > 65536)
+ return reportInvalidFile("Out-of-bounds string in category");
+ TopDiags->Categories[ID] = TopDiags->copyString(Name);
+ return std::error_code();
+}
- const FileEntry *FE = TopDiags.Files[fileID];
- if (!FE) {
- reportInvalidFile("Corrupted file entry in source location");
- return Failure;
- }
- Loc.file = const_cast<FileEntry *>(FE);
- Loc.line = Record[offset++];
- Loc.column = Record[offset++];
- Loc.offset = Record[offset++];
- return Success;
+std::error_code DiagLoader::visitDiagFlagRecord(unsigned ID, StringRef Name) {
+ // FIXME: Why do we care about long strings?
+ if (Name.size() > 65536)
+ return reportInvalidFile("Out-of-bounds string in warning flag");
+ TopDiags->WarningFlags[ID] = TopDiags->copyString(Name);
+ return std::error_code();
}
-LoadResult DiagLoader::readRange(CXLoadedDiagnosticSetImpl &TopDiags,
- RecordData &Record,
- unsigned int RecStartIdx,
- CXSourceRange &SR) {
- CXLoadedDiagnostic::Location *Start, *End;
- Start = TopDiags.Alloc.Allocate<CXLoadedDiagnostic::Location>();
- End = TopDiags.Alloc.Allocate<CXLoadedDiagnostic::Location>();
-
- if (readLocation(TopDiags, Record, RecStartIdx, *Start))
- return Failure;
- if (readLocation(TopDiags, Record, RecStartIdx, *End))
- return Failure;
-
- CXSourceLocation startLoc = makeLocation(Start);
- CXSourceLocation endLoc = makeLocation(End);
- SR = clang_getRange(startLoc, endLoc);
- return Success;
+std::error_code DiagLoader::visitFilenameRecord(unsigned ID, unsigned Size,
+ unsigned Timestamp,
+ StringRef Name) {
+ // FIXME: Why do we care about long strings?
+ if (Name.size() > 65536)
+ return reportInvalidFile("Out-of-bounds string in filename");
+ TopDiags->FileNames[ID] = TopDiags->copyString(Name);
+ TopDiags->Files[ID] =
+ TopDiags->FakeFiles.getVirtualFile(Name, Size, Timestamp);
+ return std::error_code();
}
-LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
- CXDiagnosticSetImpl &Diags,
- CXLoadedDiagnosticSetImpl &TopDiags){
+std::error_code
+DiagLoader::visitSourceRangeRecord(const serialized_diags::Location &Start,
+ const serialized_diags::Location &End) {
+ CXSourceRange SR;
+ if (std::error_code EC = readRange(Start, End, SR))
+ return EC;
+ CurrentDiags.back()->Ranges.push_back(SR);
+ return std::error_code();
+}
- if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_DIAG)) {
- reportInvalidFile("malformed diagnostic block");
- return Failure;
- }
+std::error_code
+DiagLoader::visitFixitRecord(const serialized_diags::Location &Start,
+ const serialized_diags::Location &End,
+ StringRef CodeToInsert) {
+ CXSourceRange SR;
+ if (std::error_code EC = readRange(Start, End, SR))
+ return EC;
+ // FIXME: Why do we care about long strings?
+ if (CodeToInsert.size() > 65536)
+ return reportInvalidFile("Out-of-bounds string in FIXIT");
+ CurrentDiags.back()->FixIts.push_back(
+ std::make_pair(SR, TopDiags->copyString(CodeToInsert)));
+ return std::error_code();
+}
- std::unique_ptr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic());
- RecordData Record;
-
- while (true) {
- unsigned blockOrCode = 0;
- StreamResult Res = readToNextRecordOrBlock(Stream, "Diagnostic Block",
- blockOrCode);
- switch (Res) {
- case Read_EndOfStream:
- llvm_unreachable("EndOfStream handled in readToNextRecordOrBlock");
- case Read_Failure:
- return Failure;
- case Read_BlockBegin: {
- // The only blocks we care about are subdiagnostics.
- if (blockOrCode != serialized_diags::BLOCK_DIAG) {
- if (!Stream.SkipBlock()) {
- reportInvalidFile("Invalid subblock in Diagnostics block");
- return Failure;
- }
- } else if (readDiagnosticBlock(Stream, D->getChildDiagnostics(),
- TopDiags)) {
- return Failure;
- }
-
- continue;
- }
- case Read_BlockEnd:
- Diags.appendDiagnostic(D.release());
- return Success;
- case Read_Record:
- break;
- }
-
- // Read the record.
- Record.clear();
- StringRef Blob;
- unsigned recID = Stream.readRecord(blockOrCode, Record, &Blob);
-
- if (recID < serialized_diags::RECORD_FIRST ||
- recID > serialized_diags::RECORD_LAST)
- continue;
-
- switch ((serialized_diags::RecordIDs)recID) {
- case serialized_diags::RECORD_VERSION:
- continue;
- case serialized_diags::RECORD_CATEGORY:
- if (readString(TopDiags, TopDiags.Categories, "category", Record,
- Blob, /* allowEmptyString */ true))
- return Failure;
- continue;
-
- case serialized_diags::RECORD_DIAG_FLAG:
- if (readString(TopDiags, TopDiags.WarningFlags, "warning flag", Record,
- Blob))
- return Failure;
- continue;
-
- case serialized_diags::RECORD_FILENAME: {
- if (readString(TopDiags, TopDiags.FileNames, "filename", Record,
- Blob))
- return Failure;
-
- if (Record.size() < 3) {
- reportInvalidFile("Invalid file entry");
- return Failure;
- }
-
- const FileEntry *FE =
- TopDiags.FakeFiles.getVirtualFile(TopDiags.FileNames[Record[0]],
- /* size */ Record[1],
- /* time */ Record[2]);
-
- TopDiags.Files[Record[0]] = FE;
- continue;
- }
-
- case serialized_diags::RECORD_SOURCE_RANGE: {
- CXSourceRange SR;
- if (readRange(TopDiags, Record, 0, SR))
- return Failure;
- D->Ranges.push_back(SR);
- continue;
- }
-
- case serialized_diags::RECORD_FIXIT: {
- CXSourceRange SR;
- if (readRange(TopDiags, Record, 0, SR))
- return Failure;
- const char *RetStr;
- if (readString(TopDiags, RetStr, "FIXIT", Record, Blob,
- /* allowEmptyString */ true))
- return Failure;
- D->FixIts.push_back(std::make_pair(SR, RetStr));
- continue;
- }
-
- case serialized_diags::RECORD_DIAG: {
- D->severity = Record[0];
- unsigned offset = 1;
- if (readLocation(TopDiags, Record, offset, D->DiagLoc))
- return Failure;
- D->category = Record[offset++];
- unsigned diagFlag = Record[offset++];
- D->DiagOption = diagFlag ? TopDiags.WarningFlags[diagFlag] : "";
- D->CategoryText = D->category ? TopDiags.Categories[D->category] : "";
- D->Spelling = TopDiags.copyString(Blob);
- continue;
- }
- }
- }
+std::error_code DiagLoader::visitDiagnosticRecord(
+ unsigned Severity, const serialized_diags::Location &Location,
+ unsigned Category, unsigned Flag, StringRef Message) {
+ CXLoadedDiagnostic &D = *CurrentDiags.back();
+ D.severity = Severity;
+ if (std::error_code EC = readLocation(Location, D.DiagLoc))
+ return EC;
+ D.category = Category;
+ D.DiagOption = Flag ? TopDiags->WarningFlags[Flag] : "";
+ D.CategoryText = Category ? TopDiags->Categories[Category] : "";
+ D.Spelling = TopDiags->copyString(Message);
+ return std::error_code();
}
extern "C" {
diff --git a/tools/libclang/CXLoadedDiagnostic.h b/tools/libclang/CXLoadedDiagnostic.h
index c281f9be3e87..54261be6cf46 100644
--- a/tools/libclang/CXLoadedDiagnostic.h
+++ b/tools/libclang/CXLoadedDiagnostic.h
@@ -11,8 +11,8 @@
|* *|
\*===----------------------------------------------------------------------===*/
-#ifndef LLVM_CLANG_CINDEX_LOADED_DIAGNOSTIC_H
-#define LLVM_CLANG_CINDEX_LOADED_DIAGNOSTIC_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXLOADEDDIAGNOSTIC_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CXLOADEDDIAGNOSTIC_H
#include "CIndexDiagnostic.h"
#include "llvm/ADT/StringRef.h"
diff --git a/tools/libclang/CXSourceLocation.h b/tools/libclang/CXSourceLocation.h
index f97ac1f3aff8..f0b3f4954919 100644
--- a/tools/libclang/CXSourceLocation.h
+++ b/tools/libclang/CXSourceLocation.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CXSOURCELOCATION_H
-#define LLVM_CLANG_CXSOURCELOCATION_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXSOURCELOCATION_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CXSOURCELOCATION_H
#include "clang-c/Index.h"
#include "clang/AST/ASTContext.h"
diff --git a/tools/libclang/CXString.h b/tools/libclang/CXString.h
index ed3ed4ad2d52..f6b46f76a443 100644
--- a/tools/libclang/CXString.h
+++ b/tools/libclang/CXString.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CXSTRING_H
-#define LLVM_CLANG_CXSTRING_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXSTRING_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CXSTRING_H
#include "clang-c/Index.h"
#include "clang/Basic/LLVM.h"
diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index d86ed2b8d342..6022c9dab1b5 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CXTRANSLATIONUNIT_H
-#define LLVM_CLANG_CXTRANSLATIONUNIT_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXTRANSLATIONUNIT_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CXTRANSLATIONUNIT_H
#include "CLog.h"
#include "CXString.h"
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index fe45899ad548..81cff5abb4f5 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -520,6 +520,7 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
TCALLINGCONV(X86FastCall);
TCALLINGCONV(X86ThisCall);
TCALLINGCONV(X86Pascal);
+ TCALLINGCONV(X86VectorCall);
TCALLINGCONV(X86_64Win64);
TCALLINGCONV(X86_64SysV);
TCALLINGCONV(AAPCS);
diff --git a/tools/libclang/CXType.h b/tools/libclang/CXType.h
index 7660bebf041b..941cc0a9fd7e 100644
--- a/tools/libclang/CXType.h
+++ b/tools/libclang/CXType.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CXTYPES_H
-#define LLVM_CLANG_CXTYPES_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXTYPE_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CXTYPE_H
#include "clang-c/Index.h"
#include "clang/AST/Type.h"
diff --git a/tools/libclang/CursorVisitor.h b/tools/libclang/CursorVisitor.h
index c4ec7b693766..1b2a922204f8 100644
--- a/tools/libclang/CursorVisitor.h
+++ b/tools/libclang/CursorVisitor.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
-#define LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H
#include "CXCursor.h"
#include "CXTranslationUnit.h"
diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp
index 7dc53a627533..5539971f04a7 100644
--- a/tools/libclang/IndexBody.cpp
+++ b/tools/libclang/IndexBody.cpp
@@ -150,7 +150,7 @@ public:
}
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
- if (C->capturesThis())
+ if (C->capturesThis() || C->capturesVLAType())
return true;
if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
diff --git a/tools/libclang/IndexTypeSourceInfo.cpp b/tools/libclang/IndexTypeSourceInfo.cpp
index f13c0aff0da3..706870e514b8 100644
--- a/tools/libclang/IndexTypeSourceInfo.cpp
+++ b/tools/libclang/IndexTypeSourceInfo.cpp
@@ -129,6 +129,7 @@ void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
switch (NNS.getNestedNameSpecifier()->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Super:
break;
case NestedNameSpecifier::Namespace:
diff --git a/tools/libclang/Index_Internal.h b/tools/libclang/Index_Internal.h
index 2d42cb83c970..98f069c88738 100644
--- a/tools/libclang/Index_Internal.h
+++ b/tools/libclang/Index_Internal.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBCLANG_INDEX_INTERNAL_H
-#define LLVM_LIBCLANG_INDEX_INTERNAL_H
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_INDEX_INTERNAL_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_INDEX_INTERNAL_H
#include "clang-c/Index.h"
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 58af61811bf5..20f4474a1ee8 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -414,8 +414,8 @@ public:
: IndexCtx(clientData, indexCallbacks, indexOptions, cxTU),
CXTU(cxTU), SKData(skData) { }
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override {
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override {
PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
if (!PPOpts.ImplicitPCHInclude.empty()) {
@@ -425,17 +425,16 @@ public:
IndexCtx.setASTContext(CI.getASTContext());
Preprocessor &PP = CI.getPreprocessor();
- PP.addPPCallbacks(new IndexPPCallbacks(PP, IndexCtx));
+ PP.addPPCallbacks(llvm::make_unique<IndexPPCallbacks>(PP, IndexCtx));
IndexCtx.setPreprocessor(PP);
if (SKData) {
- PPConditionalDirectiveRecord *
- PPRec = new PPConditionalDirectiveRecord(PP.getSourceManager());
- PP.addPPCallbacks(PPRec);
- SKCtrl.reset(new TUSkipBodyControl(*SKData, *PPRec, PP));
+ auto *PPRec = new PPConditionalDirectiveRecord(PP.getSourceManager());
+ PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(PPRec));
+ SKCtrl = llvm::make_unique<TUSkipBodyControl>(*SKData, *PPRec, PP);
}
- return new IndexingConsumer(IndexCtx, SKCtrl.get());
+ return llvm::make_unique<IndexingConsumer>(IndexCtx, SKCtrl.get());
}
void EndSourceFileAction() override {
@@ -576,10 +575,10 @@ static void clang_indexSourceFile_Impl(void *UserData) {
BufOwner.get());
for (auto &UF : ITUI->unsaved_files) {
- llvm::MemoryBuffer *MB =
+ std::unique_ptr<llvm::MemoryBuffer> MB =
llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
- BufOwner->push_back(std::unique_ptr<llvm::MemoryBuffer>(MB));
- CInvok->getPreprocessorOpts().addRemappedFile(UF.Filename, MB);
+ CInvok->getPreprocessorOpts().addRemappedFile(UF.Filename, MB.get());
+ BufOwner->push_back(std::move(MB));
}
// Since libclang is primarily used by batch tools dealing with
diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h
index c3851cd7e95e..31fddfb09cd4 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_INDEXINGCONTEXT_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_INDEXINGCONTEXT_H
+
#include "CXCursor.h"
#include "Index_Internal.h"
#include "clang/AST/DeclGroup.h"
@@ -517,3 +520,5 @@ inline T *ScratchAlloc::allocate() {
}
}} // end clang::cxindex
+
+#endif
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
index db3d4f86244a..97f663cde478 100644
--- a/tools/libclang/Makefile
+++ b/tools/libclang/Makefile
@@ -16,11 +16,11 @@ LINK_LIBS_IN_SHARED = 1
SHARED_LIBRARY = 1
include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
+LINK_COMPONENTS := AsmParser BitReader Core MC MCParser Option Support
USEDLIBS = clangIndex.a clangARCMigrate.a \
clangRewriteFrontend.a \
clangFormat.a \
- clangTooling.a \
+ clangTooling.a clangToolingCore.a \
clangFrontend.a clangDriver.a \
clangSerialization.a \
clangParse.a clangSema.a \
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 48eec2576743..fa2c0e70bf32 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -7,8 +7,14 @@ clang_CXXMethod_isPureVirtual
clang_CXXMethod_isStatic
clang_CXXMethod_isVirtual
clang_Cursor_getArgument
+clang_Cursor_getNumTemplateArguments
+clang_Cursor_getTemplateArgumentKind
+clang_Cursor_getTemplateArgumentType
+clang_Cursor_getTemplateArgumentValue
+clang_Cursor_getTemplateArgumentUnsignedValue
clang_Cursor_getBriefCommentText
clang_Cursor_getCommentRange
+clang_Cursor_getMangling
clang_Cursor_getParsedComment
clang_Cursor_getRawCommentText
clang_Cursor_getNumArguments
@@ -24,6 +30,8 @@ clang_Cursor_isNull
clang_Cursor_isObjCOptional
clang_Cursor_isVariadic
clang_Cursor_getModule
+clang_Cursor_getStorageClass
+clang_File_isEqual
clang_Module_getASTFile
clang_Module_getParent
clang_Module_getName
diff --git a/tools/scan-build/c++-analyzer.bat b/tools/scan-build/c++-analyzer.bat
new file mode 100644
index 000000000000..69f048a91671
--- /dev/null
+++ b/tools/scan-build/c++-analyzer.bat
@@ -0,0 +1 @@
+perl -S c++-analyzer %*
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index 4c8f6482a153..9de38d42aafa 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -42,9 +42,17 @@ my $DefaultCCompiler;
my $DefaultCXXCompiler;
my $IsCXX;
+# If on OSX, use xcrun to determine the SDK root.
+my $UseXCRUN = 0;
+
if (`uname -a` =~ m/Darwin/) {
$DefaultCCompiler = 'clang';
$DefaultCXXCompiler = 'clang++';
+ # Older versions of OSX do not have xcrun to
+ # query the SDK location.
+ if (-x "/usr/bin/xcrun") {
+ $UseXCRUN = 1;
+ }
} else {
$DefaultCCompiler = 'gcc';
$DefaultCXXCompiler = 'g++';
@@ -478,6 +486,7 @@ my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'};
my %DisabledArchs = ('ppc' => 1, 'ppc64' => 1);
my %ArchsSeen;
my $HadArch = 0;
+my $HasSDK = 0;
# Process the arguments.
foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
@@ -500,6 +509,12 @@ foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
next;
}
+ # On OSX/iOS, record if an SDK path was specified. This
+ # is innocuous for other platforms, so the check just happens.
+ if ($Arg =~ /^-isysroot/) {
+ $HasSDK = 1;
+ }
+
# Options with possible arguments that should pass through to compiler.
if (defined $CompileOptionMap{$ArgKey}) {
my $Cnt = $CompileOptionMap{$ArgKey};
@@ -644,6 +659,15 @@ foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
}
}
+# If we are on OSX and have an installation where the
+# default SDK is inferred by xcrun use xcrun to infer
+# the SDK.
+if (not $HasSDK and $UseXCRUN) {
+ my $sdk = `/usr/bin/xcrun --show-sdk-path -sdk macosx`;
+ chomp $sdk;
+ push @CompileOpts, "-isysroot", $sdk;
+}
+
if ($Action eq 'compile' or $Action eq 'link') {
my @Archs = keys %ArchsSeen;
# Skip the file if we don't support the architectures specified.
diff --git a/tools/scan-build/ccc-analyzer.bat b/tools/scan-build/ccc-analyzer.bat
new file mode 100644
index 000000000000..2a85376eb82b
--- /dev/null
+++ b/tools/scan-build/ccc-analyzer.bat
@@ -0,0 +1 @@
+perl -S ccc-analyzer %*
diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build
index 153be2dca1c9..d52d8f5f655c 100755
--- a/tools/scan-build/scan-build
+++ b/tools/scan-build/scan-build
@@ -1056,7 +1056,7 @@ sub RunBuildCommand {
shift @$Args;
unshift @$Args, $CXXAnalyzer;
}
- elsif ($Cmd eq "make" or $Cmd eq "gmake") {
+ elsif ($Cmd eq "make" or $Cmd eq "gmake" or $Cmd eq "mingw32-make") {
AddIfNotPresent($Args, "CC=$CCAnalyzer");
AddIfNotPresent($Args, "CXX=$CXXAnalyzer");
if ($IgnoreErrors) {
@@ -1221,104 +1221,104 @@ LOADING CHECKERS:
-load-plugin [plugin library]
ENDTEXT
-# Query clang for list of checkers that are enabled.
-
-# create a list to load the plugins via the 'Xclang' command line
-# argument
-my @PluginLoadCommandline_xclang;
-foreach my $param ( @PluginsToLoad ) {
- push ( @PluginLoadCommandline_xclang, "-Xclang" );
- push ( @PluginLoadCommandline_xclang, $param );
-}
-my %EnabledCheckers;
-foreach my $lang ("c", "objective-c", "objective-c++", "c++") {
- pipe(FROM_CHILD, TO_PARENT);
- my $pid = fork();
- if ($pid == 0) {
- close FROM_CHILD;
- open(STDOUT,">&", \*TO_PARENT);
- open(STDERR,">&", \*TO_PARENT);
- exec $Clang, ( @PluginLoadCommandline_xclang, '--analyze', '-x', $lang, '-', '-###');
- }
- close(TO_PARENT);
- while(<FROM_CHILD>) {
- foreach my $val (split /\s+/) {
- $val =~ s/\"//g;
- if ($val =~ /-analyzer-checker\=([^\s]+)/) {
- $EnabledCheckers{$1} = 1;
+ # Query clang for list of checkers that are enabled.
+
+ # create a list to load the plugins via the 'Xclang' command line
+ # argument
+ my @PluginLoadCommandline_xclang;
+ foreach my $param ( @PluginsToLoad ) {
+ push ( @PluginLoadCommandline_xclang, "-Xclang" );
+ push ( @PluginLoadCommandline_xclang, $param );
+ }
+ my %EnabledCheckers;
+ foreach my $lang ("c", "objective-c", "objective-c++", "c++") {
+ pipe(FROM_CHILD, TO_PARENT);
+ my $pid = fork();
+ if ($pid == 0) {
+ close FROM_CHILD;
+ open(STDOUT,">&", \*TO_PARENT);
+ open(STDERR,">&", \*TO_PARENT);
+ exec $Clang, ( @PluginLoadCommandline_xclang, '--analyze', '-x', $lang, '-', '-###');
+ }
+ close(TO_PARENT);
+ while(<FROM_CHILD>) {
+ foreach my $val (split /\s+/) {
+ $val =~ s/\"//g;
+ if ($val =~ /-analyzer-checker\=([^\s]+)/) {
+ $EnabledCheckers{$1} = 1;
+ }
}
}
- }
- waitpid($pid,0);
- close(FROM_CHILD);
-}
-
-# Query clang for complete list of checkers.
-if (defined $Clang && -x $Clang) {
- pipe(FROM_CHILD, TO_PARENT);
- my $pid = fork();
- if ($pid == 0) {
- close FROM_CHILD;
- open(STDOUT,">&", \*TO_PARENT);
- open(STDERR,">&", \*TO_PARENT);
- exec $Clang, ('-cc1', @PluginsToLoad , '-analyzer-checker-help');
- }
- close(TO_PARENT);
- my $foundCheckers = 0;
- while(<FROM_CHILD>) {
- if (/CHECKERS:/) {
- $foundCheckers = 1;
- last;
+ waitpid($pid,0);
+ close(FROM_CHILD);
+ }
+
+ # Query clang for complete list of checkers.
+ if (defined $Clang && -x $Clang) {
+ pipe(FROM_CHILD, TO_PARENT);
+ my $pid = fork();
+ if ($pid == 0) {
+ close FROM_CHILD;
+ open(STDOUT,">&", \*TO_PARENT);
+ open(STDERR,">&", \*TO_PARENT);
+ exec $Clang, ('-cc1', @PluginsToLoad , '-analyzer-checker-help');
}
- }
- if (!$foundCheckers) {
- print " *** Could not query Clang for the list of available checkers.";
- }
- else {
- print("\nAVAILABLE CHECKERS:\n\n");
- my $skip = 0;
+ close(TO_PARENT);
+ my $foundCheckers = 0;
while(<FROM_CHILD>) {
- if (/experimental/) {
- $skip = 1;
- next;
- }
- if ($skip) {
- next if (!/^\s\s[^\s]/);
- $skip = 0;
+ if (/CHECKERS:/) {
+ $foundCheckers = 1;
+ last;
}
- s/^\s\s//;
- if (/^([^\s]+)/) {
- # Is the checker enabled?
- my $checker = $1;
- my $enabled = 0;
- my $aggregate = "";
- foreach my $domain (split /\./, $checker) {
- $aggregate .= $domain;
- if ($EnabledCheckers{$aggregate}) {
- $enabled =1;
- last;
- }
- # append a dot, if an additional domain is added in the next iteration
- $aggregate .= ".";
+ }
+ if (!$foundCheckers) {
+ print " *** Could not query Clang for the list of available checkers.";
+ }
+ else {
+ print("\nAVAILABLE CHECKERS:\n\n");
+ my $skip = 0;
+ while(<FROM_CHILD>) {
+ if (/experimental/) {
+ $skip = 1;
+ next;
+ }
+ if ($skip) {
+ next if (!/^\s\s[^\s]/);
+ $skip = 0;
}
+ s/^\s\s//;
+ if (/^([^\s]+)/) {
+ # Is the checker enabled?
+ my $checker = $1;
+ my $enabled = 0;
+ my $aggregate = "";
+ foreach my $domain (split /\./, $checker) {
+ $aggregate .= $domain;
+ if ($EnabledCheckers{$aggregate}) {
+ $enabled =1;
+ last;
+ }
+ # append a dot, if an additional domain is added in the next iteration
+ $aggregate .= ".";
+ }
- if ($enabled) {
- print " + ";
+ if ($enabled) {
+ print " + ";
+ }
+ else {
+ print " ";
+ }
}
else {
print " ";
}
+ print $_;
}
- else {
- print " ";
- }
- print $_;
+ print "\nNOTE: \"+\" indicates that an analysis is enabled by default.\n"
}
- print "\nNOTE: \"+\" indicates that an analysis is enabled by default.\n"
+ waitpid($pid,0);
+ close(FROM_CHILD);
}
- waitpid($pid,0);
- close(FROM_CHILD);
-}
print <<ENDTEXT
@@ -1533,6 +1533,7 @@ while (@ARGV) {
}
if ($arg eq "-no-failure-reports") {
+ shift @ARGV;
$ENV{"CCC_REPORT_FAILURES"} = 0;
next;
}