summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt1
-rw-r--r--tools/c-index-test/c-index-test.c59
-rw-r--r--tools/clang-format-vs/CMakeLists.txt4
-rw-r--r--tools/clang-format-vs/ClangFormat/ClangFormat.csproj6
-rw-r--r--tools/clang-format-vs/ClangFormat/Resources.Designer.cs3
-rw-r--r--tools/clang-format/CMakeLists.txt10
-rw-r--r--tools/clang-format/ClangFormat.cpp28
-rwxr-xr-xtools/clang-format/clang-format-diff.py2
-rw-r--r--tools/clang-format/clang-format.el42
-rw-r--r--tools/clang-format/clang-format.py5
-rw-r--r--tools/clang-format/fuzzer/CMakeLists.txt11
-rw-r--r--tools/clang-format/fuzzer/ClangFormatFuzzer.cpp25
-rw-r--r--tools/clang-fuzzer/CMakeLists.txt20
-rw-r--r--tools/clang-fuzzer/ClangFuzzer.cpp43
-rw-r--r--tools/driver/CMakeLists.txt2
-rw-r--r--tools/driver/cc1as_main.cpp51
-rw-r--r--tools/libclang/CIndex.cpp125
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp9
-rw-r--r--tools/libclang/CIndexDiagnostic.cpp6
-rw-r--r--tools/libclang/CIndexDiagnostic.h6
-rw-r--r--tools/libclang/CIndexer.h39
-rw-r--r--tools/libclang/CMakeLists.txt5
-rw-r--r--tools/libclang/CXCursor.cpp32
-rw-r--r--tools/libclang/CXCursor.h21
-rw-r--r--tools/libclang/CXLoadedDiagnostic.cpp3
-rw-r--r--tools/libclang/CXLoadedDiagnostic.h4
-rw-r--r--tools/libclang/CXString.h2
-rw-r--r--tools/libclang/CXType.cpp81
-rw-r--r--tools/libclang/Indexing.cpp11
-rw-r--r--tools/libclang/IndexingContext.h4
-rw-r--r--tools/libclang/libclang.exports3
-rwxr-xr-xtools/scan-build/ccc-analyzer8
32 files changed, 482 insertions, 189 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 90b2225a1d2d0..b2b2f6aa954c7 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -2,6 +2,7 @@ add_subdirectory(diagtool)
add_subdirectory(driver)
add_subdirectory(clang-format)
add_subdirectory(clang-format-vs)
+add_subdirectory(clang-fuzzer)
add_subdirectory(c-index-test)
add_subdirectory(libclang)
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 56e4101399a53..56f39c2e12cb5 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1250,6 +1250,12 @@ static void PrintTypeAndTypeKind(CXType T, const char *Format) {
clang_disposeString(TypeKindSpelling);
}
+static enum CXVisitorResult FieldVisitor(CXCursor C,
+ CXClientData client_data) {
+ (*(int *) client_data)+=1;
+ return CXVisit_Continue;
+}
+
static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
CXClientData d) {
if (!clang_isInvalid(clang_getCursorKind(cursor))) {
@@ -1320,6 +1326,22 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
PrintTypeAndTypeKind(PT, " [pointeetype=%s] [pointeekind=%s]");
}
}
+ /* Print the number of fields if they exist. */
+ {
+ int numFields = 0;
+ if (clang_Type_visitFields(T, FieldVisitor, &numFields)){
+ if (numFields != 0) {
+ printf(" [nbFields=%d]", numFields);
+ }
+ /* Print if it is an anonymous record. */
+ {
+ unsigned isAnon = clang_Cursor_isAnonymous(cursor);
+ if (isAnon != 0) {
+ printf(" [isAnon=%d]", isAnon);
+ }
+ }
+ }
+ }
printf("\n");
}
@@ -1353,28 +1375,29 @@ static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
{
CXString FieldSpelling = clang_getCursorSpelling(cursor);
const char *FieldName = clang_getCString(FieldSpelling);
- /* recurse to get the root anonymous record parent */
- CXCursor Parent, Root;
+ /* recurse to get the first parent record that is not anonymous. */
+ CXCursor Parent, Record;
+ unsigned RecordIsAnonymous = 0;
if (clang_getCursorKind(cursor) == CXCursor_FieldDecl) {
- CXString RootParentSpelling;
- const char *RootParentName = 0;
- Parent = p;
+ Record = Parent = p;
do {
- if (RootParentName != 0)
- clang_disposeString(RootParentSpelling);
-
- Root = Parent;
- RootParentSpelling = clang_getCursorSpelling(Root);
- RootParentName = clang_getCString(RootParentSpelling);
- Parent = clang_getCursorSemanticParent(Root);
- } while (clang_getCursorType(Parent).kind == CXType_Record &&
- !strcmp(RootParentName, ""));
- clang_disposeString(RootParentSpelling);
- /* if RootParentName is "", record is anonymous. */
+ Record = Parent;
+ Parent = clang_getCursorSemanticParent(Record);
+ RecordIsAnonymous = clang_Cursor_isAnonymous(Record);
+ /* Recurse as long as the parent is a CXType_Record and the Record
+ is anonymous */
+ } while ( clang_getCursorType(Parent).kind == CXType_Record &&
+ RecordIsAnonymous > 0);
{
- long long Offset = clang_Type_getOffsetOf(clang_getCursorType(Root),
+ long long Offset = clang_Type_getOffsetOf(clang_getCursorType(Record),
FieldName);
- printf(" [offsetof=%lld]", Offset);
+ long long Offset2 = clang_Cursor_getOffsetOfField(cursor);
+ if (Offset == Offset2){
+ printf(" [offsetof=%lld]", Offset);
+ } else {
+ /* Offsets will be different in anonymous records. */
+ printf(" [offsetof=%lld/%lld]", Offset, Offset2);
+ }
}
}
clang_disposeString(FieldSpelling);
diff --git a/tools/clang-format-vs/CMakeLists.txt b/tools/clang-format-vs/CMakeLists.txt
index 0a50a6a8c4269..fd0d6b028c66b 100644
--- a/tools/clang-format-vs/CMakeLists.txt
+++ b/tools/clang-format-vs/CMakeLists.txt
@@ -2,7 +2,7 @@ option(BUILD_CLANG_FORMAT_VS_PLUGIN "Build clang-format VS plugin" OFF)
if (BUILD_CLANG_FORMAT_VS_PLUGIN)
add_custom_target(clang_format_exe_for_vsix
${CMAKE_COMMAND} -E copy_if_different
- "${LLVM_TOOLS_BINARY_DIR}/${CMAKE_CFG_INTDIR}/clang-format.exe"
+ "${LLVM_TOOLS_BINARY_DIR}/clang-format.exe"
"${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/clang-format.exe"
DEPENDS clang-format)
@@ -23,6 +23,6 @@ if (BUILD_CLANG_FORMAT_VS_PLUGIN)
DEPENDS clang_format_exe_for_vsix "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/source.extension.vsixmanifest"
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"
+ "${LLVM_TOOLS_BINARY_DIR}/ClangFormat.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 709b33d6fa229..a61e431cc0b9a 100644
--- a/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
+++ b/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
@@ -14,7 +14,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
@@ -219,9 +219,7 @@
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\VSSDK\Microsoft.VsSDK.targets" Condition="false" />
<PropertyGroup>
- <PreBuildEvent>if not exist $(ProjectDir)Key.snk (
- "$(FrameworkSDKDir)Bin\NETFX 4.0 Tools\sn.exe" -k $(ProjectDir)Key.snk
-)</PreBuildEvent>
+ <PreBuildEvent>if not exist $(ProjectDir)Key.snk ("$(FrameworkSDKDir)Bin\NETFX 4.5.1 Tools\sn.exe" -k $(ProjectDir)Key.snk)</PreBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/tools/clang-format-vs/ClangFormat/Resources.Designer.cs b/tools/clang-format-vs/ClangFormat/Resources.Designer.cs
index efec031e16e48..a90251771da9b 100644
--- a/tools/clang-format-vs/ClangFormat/Resources.Designer.cs
+++ b/tools/clang-format-vs/ClangFormat/Resources.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:4.0.30319.18408
+// Runtime Version:4.0.30319.34209
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -59,6 +59,5 @@ namespace LLVM.ClangFormat {
resourceCulture = value;
}
}
-
}
}
diff --git a/tools/clang-format/CMakeLists.txt b/tools/clang-format/CMakeLists.txt
index 6a24e138efcf1..6ef0c2280f4e4 100644
--- a/tools/clang-format/CMakeLists.txt
+++ b/tools/clang-format/CMakeLists.txt
@@ -4,13 +4,21 @@ add_clang_executable(clang-format
ClangFormat.cpp
)
-target_link_libraries(clang-format
+set(CLANG_FORMAT_LIB_DEPS
clangBasic
clangFormat
clangRewrite
clangToolingCore
)
+target_link_libraries(clang-format
+ ${CLANG_FORMAT_LIB_DEPS}
+ )
+
+if( LLVM_USE_SANITIZE_COVERAGE )
+ add_subdirectory(fuzzer)
+endif()
+
install(TARGETS clang-format RUNTIME DESTINATION bin)
install(PROGRAMS clang-format-bbedit.applescript DESTINATION share/clang)
install(PROGRAMS clang-format-diff.py DESTINATION share/clang)
diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
index d44d407aa86c9..5037e901f3b41 100644
--- a/tools/clang-format/ClangFormat.cpp
+++ b/tools/clang-format/ClangFormat.cpp
@@ -225,14 +225,18 @@ static bool format(StringRef FileName) {
FormatStyle FormatStyle = getStyle(
Style, (FileName == "-") ? AssumeFilename : FileName, FallbackStyle);
- tooling::Replacements Replaces = reformat(FormatStyle, Sources, ID, Ranges);
+ bool IncompleteFormat = false;
+ tooling::Replacements Replaces =
+ reformat(FormatStyle, Sources, ID, Ranges, &IncompleteFormat);
if (OutputXML) {
- llvm::outs()
- << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
+ llvm::outs() << "<?xml version='1.0'?>\n<replacements "
+ "xml:space='preserve' incomplete_format='"
+ << (IncompleteFormat ? "true" : "false") << "'>\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) {
@@ -247,12 +251,16 @@ static bool format(StringRef FileName) {
Rewriter Rewrite(Sources, LangOptions());
tooling::applyAllReplacements(Replaces, Rewrite);
if (Inplace) {
- if (Rewrite.overwriteChangedFiles())
+ if (FileName == "-")
+ llvm::errs() << "error: cannot use -i when reading from stdin.\n";
+ else if (Rewrite.overwriteChangedFiles())
return true;
} else {
if (Cursor.getNumOccurrences() != 0)
outs() << "{ \"Cursor\": "
- << tooling::shiftedCodePosition(Replaces, Cursor) << " }\n";
+ << tooling::shiftedCodePosition(Replaces, Cursor)
+ << ", \"IncompleteFormat\": "
+ << (IncompleteFormat ? "true" : "false") << " }\n";
Rewrite.getEditBuffer(ID).write(outs());
}
}
@@ -270,15 +278,7 @@ static void PrintVersion() {
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
- // Hide unrelated options.
- StringMap<cl::Option*> Options;
- cl::getRegisteredOptions(Options);
- for (StringMap<cl::Option *>::iterator I = Options.begin(), E = Options.end();
- I != E; ++I) {
- if (I->second->Category != &ClangFormatCategory && I->first() != "help" &&
- I->first() != "version")
- I->second->setHiddenFlag(cl::ReallyHidden);
- }
+ cl::HideUnrelatedOptions(ClangFormatCategory);
cl::SetVersionPrinter(PrintVersion);
cl::ParseCommandLineOptions(
diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py
index 23adb077c9534..64efb83a8c19e 100755
--- a/tools/clang-format/clang-format-diff.py
+++ b/tools/clang-format/clang-format-diff.py
@@ -48,7 +48,7 @@ def main():
help='custom pattern selecting file paths to reformat '
'(case sensitive, overrides -iregex)')
parser.add_argument('-iregex', metavar='PATTERN', default=
- r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc|js|proto'
+ r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc|js|ts|proto'
r'|protodevel|java)',
help='custom pattern selecting file paths to reformat '
'(case insensitive, overridden by -regex)')
diff --git a/tools/clang-format/clang-format.el b/tools/clang-format/clang-format.el
index ab0991b2df1cb..ca461444e2268 100644
--- a/tools/clang-format/clang-format.el
+++ b/tools/clang-format/clang-format.el
@@ -61,6 +61,7 @@ of the buffer."
(unless (and (listp xml-node) (eq (xml-node-name xml-node) 'replacements))
(error "Expected <replacements> node"))
(let ((nodes (xml-node-children xml-node))
+ (incomplete-format (xml-get-attribute xml-node 'incomplete_format))
replacements
cursor)
(dolist (node nodes)
@@ -76,11 +77,11 @@ of the buffer."
(when (cdr children)
(error "More than one child node in <replacement> node"))
- (setq offset (1+ (string-to-number offset)))
+ (setq offset (string-to-number offset))
(setq length (string-to-number length))
(push (list offset length text) replacements)))
('cursor
- (setq cursor (1+ (string-to-number text))))))))
+ (setq cursor (string-to-number text)))))))
;; Sort by decreasing offset, length.
(setq replacements (sort (delq nil replacements)
@@ -89,16 +90,18 @@ of the buffer."
(and (= (car a) (car b))
(> (cadr a) (cadr b)))))))
- (cons replacements cursor)))
+ (list replacements cursor (string= incomplete-format "true"))))
(defun clang-format--replace (offset length &optional text)
- (goto-char offset)
- (delete-char length)
- (when text
- (insert text)))
+ (let ((start (byte-to-position (1+ offset)))
+ (end (byte-to-position (+ 1 offset length))))
+ (goto-char start)
+ (delete-region start end)
+ (when text
+ (insert text))))
;;;###autoload
-(defun clang-format-region (start end &optional style)
+(defun clang-format-region (char-start char-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'."
@@ -110,7 +113,10 @@ is no active region. If no style is given uses `clang-format-style'."
(unless style
(setq style clang-format-style))
- (let ((temp-buffer (generate-new-buffer " *clang-format-temp*"))
+ (let ((start (1- (position-bytes char-start)))
+ (end (1- (position-bytes char-end)))
+ (cursor (1- (position-bytes (point))))
+ (temp-buffer (generate-new-buffer " *clang-format-temp*"))
(temp-file (make-temp-file "clang-format")))
(unwind-protect
(let (status stderr operations)
@@ -122,9 +128,9 @@ is no active region. If no style is given uses `clang-format-style'."
"-output-replacements-xml"
"-assume-filename" (or (buffer-file-name) "")
"-style" style
- "-offset" (number-to-string (1- start))
+ "-offset" (number-to-string start)
"-length" (number-to-string (- end start))
- "-cursor" (number-to-string (1- (point)))))
+ "-cursor" (number-to-string cursor)))
(setq stderr
(with-temp-buffer
(insert-file-contents temp-file)
@@ -137,20 +143,24 @@ is no active region. If no style is given uses `clang-format-style'."
((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)))
+ (error "(clang-format failed with code %d%s)" status stderr)))
(with-current-buffer temp-buffer
(setq operations (clang-format--extract (car (xml-parse-region)))))
- (let ((replacements (car operations))
- (cursor (cdr operations)))
+ (let ((replacements (nth 0 operations))
+ (cursor (nth 1 operations))
+ (incomplete-format (nth 2 operations)))
(save-excursion
(mapc (lambda (rpl)
(apply #'clang-format--replace rpl))
replacements))
(when cursor
- (goto-char cursor))))
+ (goto-char (byte-to-position (1+ cursor))))
+ (message "%s" incomplete-format)
+ (if incomplete-format
+ (message "(clang-format: incomplete (syntax errors)%s)" stderr)
+ (message "(clang-format: success%s)" stderr))))
(delete-file temp-file)
(when (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
diff --git a/tools/clang-format/clang-format.py b/tools/clang-format/clang-format.py
index a79205a6dfe83..56a6e5d86bf43 100644
--- a/tools/clang-format/clang-format.py
+++ b/tools/clang-format/clang-format.py
@@ -34,6 +34,9 @@ if vim.eval('exists("g:clang_format_path")') == "1":
# a '.clang-format' or '_clang-format' file to indicate the style that should be
# used.
style = 'file'
+fallback_style = None
+if vim.eval('exists("g:clang_format_fallback_style")') == "1":
+ fallback_style = vim.eval('g:clang_format_fallback_style')
def main():
# Get the current text.
@@ -58,6 +61,8 @@ def main():
# Call formatter.
command = [binary, '-lines', lines, '-style', style, '-cursor', str(cursor)]
+ if fallback_style:
+ command.extend(['-fallback-style', fallback_style])
if vim.current.buffer.name:
command.extend(['-assume-filename', vim.current.buffer.name])
p = subprocess.Popen(command,
diff --git a/tools/clang-format/fuzzer/CMakeLists.txt b/tools/clang-format/fuzzer/CMakeLists.txt
new file mode 100644
index 0000000000000..c7772fcb2f016
--- /dev/null
+++ b/tools/clang-format/fuzzer/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_executable(clang-format-fuzzer
+ EXCLUDE_FROM_ALL
+ ClangFormatFuzzer.cpp
+ )
+
+target_link_libraries(clang-format-fuzzer
+ ${CLANG_FORMAT_LIB_DEPS}
+ LLVMFuzzer
+ )
diff --git a/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp b/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp
new file mode 100644
index 0000000000000..fe4941a5ba1a0
--- /dev/null
+++ b/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp
@@ -0,0 +1,25 @@
+//===-- ClangFormatFuzzer.cpp - Fuzz the Clang format tool ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements a function that runs Clang format on a single
+/// input. This function is then linked into the Fuzzer library.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Format/Format.h"
+
+extern "C" void LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
+ // FIXME: fuzz more things: different styles, different style features.
+ std::string s((const char *)data, size);
+ auto Style = getGoogleStyle(clang::format::FormatStyle::LK_Cpp);
+ Style.ColumnLimit = 60;
+ applyAllReplacements(s, clang::format::reformat(
+ Style, s, {clang::tooling::Range(0, s.size())}));
+}
diff --git a/tools/clang-fuzzer/CMakeLists.txt b/tools/clang-fuzzer/CMakeLists.txt
new file mode 100644
index 0000000000000..87d21c6bf116b
--- /dev/null
+++ b/tools/clang-fuzzer/CMakeLists.txt
@@ -0,0 +1,20 @@
+if( LLVM_USE_SANITIZE_COVERAGE )
+ set(LLVM_LINK_COMPONENTS support)
+
+ add_clang_executable(clang-fuzzer
+ EXCLUDE_FROM_ALL
+ ClangFuzzer.cpp
+ )
+
+ target_link_libraries(clang-fuzzer
+ ${CLANG_FORMAT_LIB_DEPS}
+ clangAST
+ clangBasic
+ clangDriver
+ clangFrontend
+ clangRewriteFrontend
+ clangStaticAnalyzerFrontend
+ clangTooling
+ LLVMFuzzer
+ )
+endif()
diff --git a/tools/clang-fuzzer/ClangFuzzer.cpp b/tools/clang-fuzzer/ClangFuzzer.cpp
new file mode 100644
index 0000000000000..17ef0521e3c38
--- /dev/null
+++ b/tools/clang-fuzzer/ClangFuzzer.cpp
@@ -0,0 +1,43 @@
+//===-- ClangFuzzer.cpp - Fuzz Clang --------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements a function that runs Clang on a single
+/// input. This function is then linked into the Fuzzer library.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Tooling.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "llvm/Option/Option.h"
+
+using namespace clang;
+
+extern "C" void LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
+ std::string s((const char *)data, size);
+ llvm::opt::ArgStringList CC1Args;
+ CC1Args.push_back("-cc1");
+ CC1Args.push_back("./test.cc");
+ llvm::IntrusiveRefCntPtr<FileManager> Files(
+ new FileManager(FileSystemOptions()));
+ IgnoringDiagConsumer Diags;
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+ DiagnosticsEngine Diagnostics(
+ IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
+ &Diags, false);
+ std::unique_ptr<clang::CompilerInvocation> Invocation(
+ tooling::newInvocation(&Diagnostics, CC1Args));
+ std::unique_ptr<llvm::MemoryBuffer> Input =
+ llvm::MemoryBuffer::getMemBuffer(s);
+ Invocation->getPreprocessorOpts().addRemappedFile("./test.cc", Input.release());
+ std::unique_ptr<tooling::ToolAction> action(
+ tooling::newFrontendActionFactory<clang::SyntaxOnlyAction>());
+ action->runInvocation(Invocation.release(), Files.get(), &Diags);
+}
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index 805aebfac3a73..e592acadf17f1 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -42,7 +42,7 @@ set_target_properties(clang PROPERTIES VERSION ${CLANG_EXECUTABLE_VERSION})
# Support plugins.
if(CLANG_PLUGIN_SUPPORT)
- set_target_properties(clang PROPERTIES ENABLE_EXPORTS 1)
+ export_executable_symbols(clang)
endif()
add_dependencies(clang clang-headers)
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 55c9fe602fa35..6feffa8a63d5d 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -19,6 +19,7 @@
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/DataLayout.h"
@@ -254,9 +255,9 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
return Success;
}
-static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts,
- DiagnosticsEngine &Diags,
- bool Binary) {
+static std::unique_ptr<raw_fd_ostream>
+getOutputStream(AssemblerInvocation &Opts, DiagnosticsEngine &Diags,
+ bool Binary) {
if (Opts.OutputPath.empty())
Opts.OutputPath = "-";
@@ -266,16 +267,15 @@ static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts,
sys::RemoveFileOnSignal(Opts.OutputPath);
std::error_code EC;
- raw_fd_ostream *Out = new raw_fd_ostream(
+ auto Out = llvm::make_unique<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;
}
- return new formatted_raw_ostream(*Out, formatted_raw_ostream::DELETE_STREAM);
+ return Out;
}
static bool ExecuteAssembler(AssemblerInvocation &Opts,
@@ -315,9 +315,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
MAI->setCompressDebugSections(true);
bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
- std::unique_ptr<formatted_raw_ostream> Out(
- GetOutputStream(Opts, Diags, IsBinary));
- if (!Out)
+ std::unique_ptr<raw_fd_ostream> FDOS = getOutputStream(Opts, Diags, IsBinary);
+ if (!FDOS)
return true;
// FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
@@ -356,31 +355,40 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
std::unique_ptr<MCSubtargetInfo> STI(
TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
+ raw_pwrite_stream *Out = FDOS.get();
+ std::unique_ptr<buffer_ostream> BOS;
+
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
- MCInstPrinter *IP =
- TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI,
- *STI);
+ MCInstPrinter *IP = TheTarget->createMCInstPrinter(
+ llvm::Triple(Opts.Triple), Opts.OutputAsmVariant, *MAI, *MCII, *MRI);
MCCodeEmitter *CE = nullptr;
MCAsmBackend *MAB = nullptr;
if (Opts.ShowEncoding) {
- CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
+ CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU);
}
- Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
- /*useDwarfDirectory*/ true,
- IP, CE, MAB,
- Opts.ShowInst));
+ auto FOut = llvm::make_unique<formatted_raw_ostream>(*Out);
+ Str.reset(TheTarget->createAsmStreamer(
+ Ctx, std::move(FOut), /*asmverbose*/ true,
+ /*useDwarfDirectory*/ true, IP, CE, MAB, Opts.ShowInst));
} else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
Str.reset(createNullStreamer(Ctx));
} else {
assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
"Invalid file type!");
- MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
+ if (!FDOS->supportsSeeking()) {
+ BOS = make_unique<buffer_ostream>(*FDOS);
+ Out = BOS.get();
+ }
+
+ MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
Opts.CPU);
- Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out,
- CE, *STI, Opts.RelaxAll));
+ Triple T(Opts.Triple);
+ Str.reset(TheTarget->createMCObjectStreamer(T, Ctx, *MAB, *Out, CE, *STI,
+ Opts.RelaxAll,
+ /*DWARFMustBeAtTheEnd*/ true));
Str.get()->InitSections(Opts.NoExecStack);
}
@@ -402,7 +410,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
}
// Close the output stream early.
- Out.reset();
+ BOS.reset();
+ FDOS.reset();
// Delete output file if there were errors.
if (Failed && Opts.OutputPath != "-")
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 00ef8c0bf424b..05287bd856e82 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -240,9 +240,8 @@ static bool visitPreprocessedEntitiesInRange(SourceRange R,
FID = FileID();
}
- std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
- Entities = PPRec.getPreprocessedEntitiesInRange(R);
- return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
+ const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
+ return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
PPRec, FID);
}
@@ -455,14 +454,14 @@ bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
if (Visit(MakeMacroExpansionCursor(ME, TU)))
return true;
-
+
continue;
}
-
- if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
+
+ if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
if (Visit(MakeMacroDefinitionCursor(MD, TU)))
return true;
-
+
continue;
}
@@ -569,8 +568,8 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
const MacroInfo *MI =
getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
- if (MacroDefinition *MacroDef =
- checkForMacroInMacroDefinition(MI, Loc, TU))
+ if (MacroDefinitionRecord *MacroDef =
+ checkForMacroInMacroDefinition(MI, Loc, TU))
return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
}
@@ -1719,7 +1718,7 @@ public:
return VJ->getKind() == DeclVisitKind;
}
const Decl *get() const { return static_cast<const Decl *>(data[0]); }
- bool isFirst() const { return data[1] ? true : false; }
+ bool isFirst() const { return data[1] != nullptr; }
};
class TypeLocVisit : public VisitorJob {
public:
@@ -1983,6 +1982,7 @@ void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Visitor->AddStmt(C->getChunkSize());
+ Visitor->AddStmt(C->getHelperChunkSize());
}
void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
@@ -2023,16 +2023,47 @@ void OMPClauseEnqueue::VisitOMPFirstprivateClause(
void OMPClauseEnqueue::VisitOMPLastprivateClause(
const OMPLastprivateClause *C) {
VisitOMPClauseList(C);
+ for (auto *E : C->private_copies()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->source_exprs()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->destination_exprs()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->assignment_ops()) {
+ Visitor->AddStmt(E);
+ }
}
void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
VisitOMPClauseList(C);
+ for (auto *E : C->lhs_exprs()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->rhs_exprs()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->reduction_ops()) {
+ Visitor->AddStmt(E);
+ }
}
void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
VisitOMPClauseList(C);
+ for (const auto *E : C->inits()) {
+ Visitor->AddStmt(E);
+ }
+ for (const auto *E : C->updates()) {
+ Visitor->AddStmt(E);
+ }
+ for (const auto *E : C->finals()) {
+ Visitor->AddStmt(E);
+ }
Visitor->AddStmt(C->getStep());
+ Visitor->AddStmt(C->getCalcStep());
}
void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
VisitOMPClauseList(C);
@@ -2040,10 +2071,28 @@ void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
}
void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
VisitOMPClauseList(C);
+ for (auto *E : C->source_exprs()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->destination_exprs()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->assignment_ops()) {
+ Visitor->AddStmt(E);
+ }
}
void
OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
VisitOMPClauseList(C);
+ for (auto *E : C->source_exprs()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->destination_exprs()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->assignment_ops()) {
+ Visitor->AddStmt(E);
+ }
}
void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
VisitOMPClauseList(C);
@@ -2239,8 +2288,21 @@ void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
// visit it.
// FIXME: If we ever want to show these implicit accesses, this will be
// unfortunate. However, clang_getCursor() relies on this behavior.
- if (!M->isImplicitAccess())
- AddStmt(M->getBase());
+ if (M->isImplicitAccess())
+ return;
+
+ // Ignore base anonymous struct/union fields, otherwise they will shadow the
+ // real field that that we are interested in.
+ if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
+ if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
+ if (FD->isAnonymousStructOrUnion()) {
+ AddStmt(SubME->getBase());
+ return;
+ }
+ }
+ }
+
+ AddStmt(M->getBase());
}
void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
AddTypeLoc(E->getEncodedTypeSourceInfo());
@@ -4208,6 +4270,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("OMPTargetDirective");
case CXCursor_OMPTeamsDirective:
return cxstring::createRef("OMPTeamsDirective");
+ case CXCursor_OverloadCandidate:
+ return cxstring::createRef("OverloadCandidate");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -4824,9 +4888,10 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
return clang_getNullCursor();
}
-
+
if (C.kind == CXCursor_MacroExpansion) {
- if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
+ if (const MacroDefinitionRecord *Def =
+ getCursorMacroExpansion(C).getDefinition())
return MakeMacroDefinitionCursor(Def, tu);
}
@@ -4950,6 +5015,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
// nonetheless harmless.
case Decl::Empty:
case Decl::TranslationUnit:
+ case Decl::ExternCContext:
break;
// Declaration kinds for which the definition is not resolvable.
@@ -6000,11 +6066,12 @@ static void annotatePreprocessorTokens(CXTranslationUnit TU,
if (MI) {
SourceLocation SaveLoc = Tok.getLocation();
Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
- MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
+ MacroDefinitionRecord *MacroDef =
+ checkForMacroInMacroDefinition(MI, Tok, TU);
Tok.setLocation(SaveLoc);
if (MacroDef)
- Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
- Tok.getLocation(), TU);
+ Cursors[NextIdx - 1] =
+ MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
}
} while (!Tok.isAtStartOfLine());
@@ -6943,7 +7010,7 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
CXTUResourceUsage usage = { (void*) entries.get(),
(unsigned) entries->size(),
- entries->size() ? &(*entries)[0] : nullptr };
+ !entries->empty() ? &(*entries)[0] : nullptr };
entries.release();
return usage;
}
@@ -7080,7 +7147,7 @@ MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
ASTUnit *Unit = cxtu::getASTUnit(TU);
Preprocessor &PP = Unit->getPreprocessor();
- MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
+ MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
if (MD) {
for (MacroDirective::DefInfo
Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
@@ -7092,7 +7159,7 @@ MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
return nullptr;
}
-const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
+const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
CXTranslationUnit TU) {
if (!MacroDef || !TU)
return nullptr;
@@ -7103,9 +7170,9 @@ const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
return getMacroInfo(*II, MacroDef->getLocation(), TU);
}
-MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
- const Token &Tok,
- CXTranslationUnit TU) {
+MacroDefinitionRecord *
+cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
+ CXTranslationUnit TU) {
if (!MI || !TU)
return nullptr;
if (Tok.isNot(tok::raw_identifier))
@@ -7137,16 +7204,16 @@ MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
return nullptr;
- MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
+ MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
if (!InnerMD)
return nullptr;
return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
}
-MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
- SourceLocation Loc,
- CXTranslationUnit TU) {
+MacroDefinitionRecord *
+cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
+ CXTranslationUnit TU) {
if (Loc.isInvalid() || !MI || !TU)
return nullptr;
@@ -7266,10 +7333,10 @@ cxindex::Logger::~Logger() {
llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
- OS << Msg.str() << '\n';
+ OS << Msg << '\n';
if (Trace) {
- llvm::sys::PrintStackTrace(stderr);
+ llvm::sys::PrintStackTrace(OS);
OS << "--------------------------------------------------\n";
}
}
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index b6f71d20de2b3..ca167e8b2e701 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -533,7 +533,7 @@ namespace {
: CodeCompleteConsumer(Opts, false),
AllocatedResults(Results), CCTUInfo(Results.CodeCompletionAllocator),
TU(TranslationUnit) { }
- ~CaptureCompletionResults() { Finish(); }
+ ~CaptureCompletionResults() override { Finish(); }
void ProcessCodeCompleteResults(Sema &S,
CodeCompletionContext Context,
@@ -619,10 +619,11 @@ namespace {
for (unsigned I = 0; I != NumCandidates; ++I) {
CodeCompletionString *StoredCompletion
= Candidates[I].CreateSignatureString(CurrentArg, S, getAllocator(),
- getCodeCompletionTUInfo());
+ getCodeCompletionTUInfo(),
+ includeBriefComments());
CXCompletionResult R;
- R.CursorKind = CXCursor_NotImplemented;
+ R.CursorKind = CXCursor_OverloadCandidate;
R.CompletionString = StoredCompletion;
StoredResults.push_back(R);
}
@@ -655,7 +656,7 @@ struct CodeCompleteAtInfo {
unsigned options;
CXCodeCompleteResults *result;
};
-void clang_codeCompleteAt_Impl(void *UserData) {
+static void clang_codeCompleteAt_Impl(void *UserData) {
CodeCompleteAtInfo *CCAI = static_cast<CodeCompleteAtInfo*>(UserData);
CXTranslationUnit TU = CCAI->TU;
const char *complete_filename = CCAI->complete_filename;
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 4d646f0cf8281..9ba36a6a0f8a6 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -48,7 +48,7 @@ public:
: CXDiagnosticImpl(CustomNoteDiagnosticKind),
Message(Msg), Loc(L) {}
- virtual ~CXDiagnosticCustomNoteImpl() {}
+ ~CXDiagnosticCustomNoteImpl() override {}
CXDiagnosticSeverity getSeverity() const override {
return CXDiagnostic_Note;
@@ -91,8 +91,8 @@ public:
CXDiagnosticSetImpl *mainSet)
: DiagnosticNoteRenderer(LangOpts, DiagOpts),
CurrentSet(mainSet), MainSet(mainSet) {}
-
- virtual ~CXDiagnosticRenderer() {}
+
+ ~CXDiagnosticRenderer() override {}
void beginDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) override {
diff --git a/tools/libclang/CIndexDiagnostic.h b/tools/libclang/CIndexDiagnostic.h
index 4347fb75f4a5b..9f406987ebf1a 100644
--- a/tools/libclang/CIndexDiagnostic.h
+++ b/tools/libclang/CIndexDiagnostic.h
@@ -116,9 +116,9 @@ struct CXStoredDiagnostic : public CXDiagnosticImpl {
const LangOptions &LangOpts)
: CXDiagnosticImpl(StoredDiagnosticKind),
Diag(Diag), LangOpts(LangOpts) { }
-
- virtual ~CXStoredDiagnostic() {}
-
+
+ ~CXStoredDiagnostic() override {}
+
/// \brief Return the severity of the diagnostic.
CXDiagnosticSeverity getSeverity() const override;
diff --git a/tools/libclang/CIndexer.h b/tools/libclang/CIndexer.h
index 7a8dbd37d022a..cb7c62e4b565a 100644
--- a/tools/libclang/CIndexer.h
+++ b/tools/libclang/CIndexer.h
@@ -25,12 +25,12 @@ namespace llvm {
}
namespace clang {
- class ASTUnit;
- class MacroInfo;
- class MacroDefinition;
- class SourceLocation;
- class Token;
- class IdentifierInfo;
+class ASTUnit;
+class MacroInfo;
+class MacroDefinitionRecord;
+class SourceLocation;
+class Token;
+class IdentifierInfo;
class CIndexer {
bool OnlyLocalDecls;
@@ -92,27 +92,26 @@ public:
/// \brief If \c MacroDefLoc points at a macro definition with \c II as
/// its name, this retrieves its MacroInfo.
MacroInfo *getMacroInfo(const IdentifierInfo &II,
- SourceLocation MacroDefLoc,
- CXTranslationUnit TU);
+ SourceLocation MacroDefLoc, CXTranslationUnit TU);
- /// \brief Retrieves the corresponding MacroInfo of a MacroDefinition.
- const MacroInfo *getMacroInfo(const MacroDefinition *MacroDef,
+ /// \brief Retrieves the corresponding MacroInfo of a MacroDefinitionRecord.
+ const MacroInfo *getMacroInfo(const MacroDefinitionRecord *MacroDef,
CXTranslationUnit TU);
/// \brief If \c Loc resides inside the definition of \c MI and it points at
/// an identifier that has ever been a macro name, this returns the latest
- /// MacroDefinition for that name, otherwise it returns NULL.
- MacroDefinition *checkForMacroInMacroDefinition(const MacroInfo *MI,
- SourceLocation Loc,
- CXTranslationUnit TU);
+ /// MacroDefinitionRecord for that name, otherwise it returns NULL.
+ MacroDefinitionRecord *checkForMacroInMacroDefinition(const MacroInfo *MI,
+ SourceLocation Loc,
+ CXTranslationUnit TU);
/// \brief If \c Tok resides inside the definition of \c MI and it points at
/// an identifier that has ever been a macro name, this returns the latest
- /// MacroDefinition for that name, otherwise it returns NULL.
- MacroDefinition *checkForMacroInMacroDefinition(const MacroInfo *MI,
- const Token &Tok,
- CXTranslationUnit TU);
- }
-}
+ /// MacroDefinitionRecord for that name, otherwise it returns NULL.
+ MacroDefinitionRecord *checkForMacroInMacroDefinition(const MacroInfo *MI,
+ const Token &Tok,
+ CXTranslationUnit TU);
+ }
+ }
#endif
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index f1c3f4ca8b23f..26f88a97c5744 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -51,6 +51,11 @@ if (CLANG_ENABLE_ARCMT)
list(APPEND LIBS clangARCMigrate)
endif ()
+find_library(DL_LIBRARY_PATH dl)
+if (DL_LIBRARY_PATH)
+ list(APPEND LIBS dl)
+endif()
+
option(LIBCLANG_BUILD_STATIC
"Build libclang as a static library (in addition to a shared one)" OFF)
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 7834181d47810..b0446fd0da9e5 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -750,28 +750,28 @@ SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
return TU->mapRangeFromPreamble(Range);
}
-CXCursor cxcursor::MakeMacroDefinitionCursor(const MacroDefinition *MI,
+CXCursor cxcursor::MakeMacroDefinitionCursor(const MacroDefinitionRecord *MI,
CXTranslationUnit TU) {
- CXCursor C = { CXCursor_MacroDefinition, 0, { MI, nullptr, TU } };
+ CXCursor C = {CXCursor_MacroDefinition, 0, {MI, nullptr, TU}};
return C;
}
-const MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
+const MacroDefinitionRecord *cxcursor::getCursorMacroDefinition(CXCursor C) {
assert(C.kind == CXCursor_MacroDefinition);
- return static_cast<const MacroDefinition *>(C.data[0]);
+ return static_cast<const MacroDefinitionRecord *>(C.data[0]);
}
-CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
+CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
CXTranslationUnit TU) {
CXCursor C = { CXCursor_MacroExpansion, 0, { MI, nullptr, TU } };
return C;
}
-CXCursor cxcursor::MakeMacroExpansionCursor(MacroDefinition *MI,
+CXCursor cxcursor::MakeMacroExpansionCursor(MacroDefinitionRecord *MI,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(Loc.isValid());
- CXCursor C = { CXCursor_MacroExpansion, 0, { MI, Loc.getPtrEncoding(), TU } };
+ CXCursor C = {CXCursor_MacroExpansion, 0, {MI, Loc.getPtrEncoding(), TU}};
return C;
}
@@ -780,7 +780,8 @@ const IdentifierInfo *cxcursor::MacroExpansionCursor::getName() const {
return getAsMacroDefinition()->getName();
return getAsMacroExpansion()->getName();
}
-const MacroDefinition *cxcursor::MacroExpansionCursor::getDefinition() const {
+const MacroDefinitionRecord *
+cxcursor::MacroExpansionCursor::getDefinition() const {
if (isPseudo())
return getAsMacroDefinition();
return getAsMacroExpansion()->getDefinition();
@@ -1291,18 +1292,15 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
true);
return String;
}
- }
- else if (kind == CXCursor_MacroDefinition) {
- const MacroDefinition *definition = getCursorMacroDefinition(cursor);
+ } else if (kind == CXCursor_MacroDefinition) {
+ const MacroDefinitionRecord *definition = getCursorMacroDefinition(cursor);
const IdentifierInfo *MacroInfo = definition->getName();
ASTUnit *unit = getCursorASTUnit(cursor);
CodeCompletionResult Result(MacroInfo);
- CodeCompletionString *String
- = Result.CreateCodeCompletionString(unit->getASTContext(),
- unit->getPreprocessor(),
- unit->getCodeCompletionTUInfo().getAllocator(),
- unit->getCodeCompletionTUInfo(),
- false);
+ CodeCompletionString *String = Result.CreateCodeCompletionString(
+ unit->getASTContext(), unit->getPreprocessor(),
+ unit->getCodeCompletionTUInfo().getAllocator(),
+ unit->getCodeCompletionTUInfo(), false);
return String;
}
return nullptr;
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index 931d112766ed8..083b86934d165 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -30,7 +30,7 @@ class Expr;
class FieldDecl;
class InclusionDirective;
class LabelStmt;
-class MacroDefinition;
+class MacroDefinitionRecord;
class MacroExpansion;
class NamedDecl;
class ObjCInterfaceDecl;
@@ -145,20 +145,19 @@ CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
SourceRange getCursorPreprocessingDirective(CXCursor C);
/// \brief Create a macro definition cursor.
-CXCursor MakeMacroDefinitionCursor(const MacroDefinition *,
+CXCursor MakeMacroDefinitionCursor(const MacroDefinitionRecord *,
CXTranslationUnit TU);
/// \brief Unpack a given macro definition cursor to retrieve its
/// source range.
-const MacroDefinition *getCursorMacroDefinition(CXCursor C);
+const MacroDefinitionRecord *getCursorMacroDefinition(CXCursor C);
/// \brief Create a macro expansion cursor.
-CXCursor MakeMacroExpansionCursor(MacroExpansion *,
- CXTranslationUnit TU);
+CXCursor MakeMacroExpansionCursor(MacroExpansion *, CXTranslationUnit TU);
/// \brief Create a "pseudo" macro expansion cursor, using a macro definition
/// and a source location.
-CXCursor MakeMacroExpansionCursor(MacroDefinition *, SourceLocation Loc,
+CXCursor MakeMacroExpansionCursor(MacroDefinitionRecord *, SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Wraps a macro expansion cursor and provides a common interface
@@ -171,12 +170,10 @@ CXCursor MakeMacroExpansionCursor(MacroDefinition *, SourceLocation Loc,
class MacroExpansionCursor {
CXCursor C;
- bool isPseudo() const {
- return C.data[1] != nullptr;
- }
- const MacroDefinition *getAsMacroDefinition() const {
+ bool isPseudo() const { return C.data[1] != nullptr; }
+ const MacroDefinitionRecord *getAsMacroDefinition() const {
assert(isPseudo());
- return static_cast<const MacroDefinition *>(C.data[0]);
+ return static_cast<const MacroDefinitionRecord *>(C.data[0]);
}
const MacroExpansion *getAsMacroExpansion() const {
assert(!isPseudo());
@@ -193,7 +190,7 @@ public:
}
const IdentifierInfo *getName() const;
- const MacroDefinition *getDefinition() const;
+ const MacroDefinitionRecord *getDefinition() const;
SourceRange getSourceRange() const;
};
diff --git a/tools/libclang/CXLoadedDiagnostic.cpp b/tools/libclang/CXLoadedDiagnostic.cpp
index fe5599a3abc93..754ad55a66040 100644
--- a/tools/libclang/CXLoadedDiagnostic.cpp
+++ b/tools/libclang/CXLoadedDiagnostic.cpp
@@ -19,6 +19,7 @@
#include "clang/Frontend/SerializedDiagnosticReader.h"
#include "clang/Frontend/SerializedDiagnostics.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/BitstreamReader.h"
@@ -36,7 +37,7 @@ namespace {
class CXLoadedDiagnosticSetImpl : public CXDiagnosticSetImpl {
public:
CXLoadedDiagnosticSetImpl() : CXDiagnosticSetImpl(true), FakeFiles(FO) {}
- virtual ~CXLoadedDiagnosticSetImpl() {}
+ ~CXLoadedDiagnosticSetImpl() override {}
llvm::BumpPtrAllocator Alloc;
Strings Categories;
diff --git a/tools/libclang/CXLoadedDiagnostic.h b/tools/libclang/CXLoadedDiagnostic.h
index 54261be6cf461..d5006a4444a43 100644
--- a/tools/libclang/CXLoadedDiagnostic.h
+++ b/tools/libclang/CXLoadedDiagnostic.h
@@ -26,8 +26,8 @@ public:
CXLoadedDiagnostic() : CXDiagnosticImpl(LoadedDiagnosticKind),
severity(0), category(0) {}
- virtual ~CXLoadedDiagnostic();
-
+ ~CXLoadedDiagnostic() override;
+
/// \brief Return the severity of the diagnostic.
CXDiagnosticSeverity getSeverity() const override;
diff --git a/tools/libclang/CXString.h b/tools/libclang/CXString.h
index f6b46f76a4436..72ac0cf46914a 100644
--- a/tools/libclang/CXString.h
+++ b/tools/libclang/CXString.h
@@ -63,7 +63,7 @@ CXString createDup(StringRef String);
// In this case, call \c createRef(String.c_str()).
//
// If you need to make a copy, call \c createDup(StringRef(String)).
-CXString createRef(std::string String) LLVM_DELETED_FUNCTION;
+CXString createRef(std::string String) = delete;
/// \brief Create a CXString object that is backed by a string buffer.
CXString createCXString(CXStringBuf *buf);
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 81cff5abb4f5f..015dd6e57af04 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -525,8 +525,10 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
TCALLINGCONV(X86_64SysV);
TCALLINGCONV(AAPCS);
TCALLINGCONV(AAPCS_VFP);
- TCALLINGCONV(PnaclCall);
TCALLINGCONV(IntelOclBicc);
+ case CC_SpirFunction: return CXCallingConv_Unexposed;
+ case CC_SpirKernel: return CXCallingConv_Unexposed;
+ break;
}
#undef TCALLINGCONV
}
@@ -773,13 +775,12 @@ static long long visitRecordForValidation(const RecordDecl *RD) {
return 0;
}
-long long clang_Type_getOffsetOf(CXType PT, const char *S) {
- // check that PT is not incomplete/dependent
- CXCursor PC = clang_getTypeDeclaration(PT);
+static long long validateFieldParentType(CXCursor PC, CXType PT){
if (clang_isInvalid(PC.kind))
return CXTypeLayoutError_Invalid;
const RecordDecl *RD =
dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
+ // validate parent declaration
if (!RD || RD->isInvalidDecl())
return CXTypeLayoutError_Invalid;
RD = RD->getDefinition();
@@ -787,6 +788,7 @@ long long clang_Type_getOffsetOf(CXType PT, const char *S) {
return CXTypeLayoutError_Incomplete;
if (RD->isInvalidDecl())
return CXTypeLayoutError_Invalid;
+ // validate parent type
QualType RT = GetQualType(PT);
if (RT->isIncompleteType())
return CXTypeLayoutError_Incomplete;
@@ -796,13 +798,26 @@ long long clang_Type_getOffsetOf(CXType PT, const char *S) {
long long Error = visitRecordForValidation(RD);
if (Error < 0)
return Error;
+ return 0;
+}
+
+long long clang_Type_getOffsetOf(CXType PT, const char *S) {
+ // check that PT is not incomplete/dependent
+ CXCursor PC = clang_getTypeDeclaration(PT);
+ long long Error = validateFieldParentType(PC,PT);
+ if (Error < 0)
+ return Error;
if (!S)
return CXTypeLayoutError_InvalidFieldName;
// lookup field
ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
IdentifierInfo *II = &Ctx.Idents.get(S);
DeclarationName FieldName(II);
- RecordDecl::lookup_const_result Res = RD->lookup(FieldName);
+ const RecordDecl *RD =
+ dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
+ // verified in validateFieldParentType
+ RD = RD->getDefinition();
+ RecordDecl::lookup_result Res = RD->lookup(FieldName);
// If a field of the parent record is incomplete, lookup will fail.
// and we would return InvalidFieldName instead of Incomplete.
// But this erroneous results does protects again a hidden assertion failure
@@ -817,6 +832,25 @@ long long clang_Type_getOffsetOf(CXType PT, const char *S) {
return CXTypeLayoutError_InvalidFieldName;
}
+long long clang_Cursor_getOffsetOfField(CXCursor C) {
+ if (clang_isDeclaration(C.kind)) {
+ // we need to validate the parent type
+ CXCursor PC = clang_getCursorSemanticParent(C);
+ CXType PT = clang_getCursorType(PC);
+ long long Error = validateFieldParentType(PC,PT);
+ if (Error < 0)
+ return Error;
+ // proceed with the offset calculation
+ const Decl *D = cxcursor::getCursorDecl(C);
+ ASTContext &Ctx = cxcursor::getCursorContext(C);
+ if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
+ return Ctx.getFieldOffset(FD);
+ if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
+ return Ctx.getFieldOffset(IFD);
+ }
+ return -1;
+}
+
enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
QualType QT = GetQualType(T);
if (QT.isNull())
@@ -906,4 +940,41 @@ CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) {
return MakeCXType(A.getAsType(), GetTU(CT));
}
+unsigned clang_Type_visitFields(CXType PT,
+ CXFieldVisitor visitor,
+ CXClientData client_data){
+ CXCursor PC = clang_getTypeDeclaration(PT);
+ if (clang_isInvalid(PC.kind))
+ return false;
+ const RecordDecl *RD =
+ dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
+ if (!RD || RD->isInvalidDecl())
+ return false;
+ RD = RD->getDefinition();
+ if (!RD || RD->isInvalidDecl())
+ return false;
+
+ for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+ I != E; ++I){
+ const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
+ // Callback to the client.
+ switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
+ case CXVisit_Break:
+ return true;
+ case CXVisit_Continue:
+ break;
+ }
+ }
+ return true;
+}
+
+unsigned clang_Cursor_isAnonymous(CXCursor C){
+ if (!clang_isDeclaration(C.kind))
+ return 0;
+ const Decl *D = cxcursor::getCursorDecl(C);
+ if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
+ return FD->isAnonymousStructOrUnion();
+ return 0;
+}
+
} // end: extern "C"
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 20f4474a1ee81..0ede684a18e40 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -284,10 +284,10 @@ public:
/// MacroUndefined - This hook is called whenever a macro #undef is seen.
/// MI is released immediately following this callback.
void MacroUndefined(const Token &MacroNameTok,
- const MacroDirective *MD) override {}
+ const MacroDefinition &MD) override {}
/// MacroExpands - This is called by when a macro invocation is found.
- void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
+ void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range, const MacroArgs *Args) override {}
/// SourceRangeSkipped - This hook is called when a source range is skipped.
@@ -697,13 +697,8 @@ static void indexPreprocessingRecord(ASTUnit &Unit, IndexingContext &IdxCtx) {
// FIXME: Only deserialize inclusion directives.
- PreprocessingRecord::iterator I, E;
- std::tie(I, E) = Unit.getLocalPreprocessingEntities();
-
bool isModuleFile = Unit.isModuleFile();
- for (; I != E; ++I) {
- PreprocessedEntity *PPE = *I;
-
+ for (PreprocessedEntity *PPE : Unit.getLocalPreprocessingEntities()) {
if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
SourceLocation Loc = ID->getSourceRange().getBegin();
// Modules have synthetic main files as input, give an invalid location
diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h
index 31fddfb09cd42..4da6aebaf6480 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -245,8 +245,8 @@ class AttrListInfo {
SmallVector<CXIdxAttrInfo *, 2> CXAttrs;
unsigned ref_cnt;
- AttrListInfo(const AttrListInfo &) LLVM_DELETED_FUNCTION;
- void operator=(const AttrListInfo &) LLVM_DELETED_FUNCTION;
+ AttrListInfo(const AttrListInfo &) = delete;
+ void operator=(const AttrListInfo &) = delete;
public:
AttrListInfo(const Decl *D, IndexingContext &IdxCtx);
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index fa2c0e70bf321..f78f9981a98bd 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -21,9 +21,11 @@ clang_Cursor_getNumArguments
clang_Cursor_getObjCDeclQualifiers
clang_Cursor_getObjCPropertyAttributes
clang_Cursor_getObjCSelectorIndex
+clang_Cursor_getOffsetOfField
clang_Cursor_getSpellingNameRange
clang_Cursor_getTranslationUnit
clang_Cursor_getReceiverType
+clang_Cursor_isAnonymous
clang_Cursor_isBitField
clang_Cursor_isDynamicCall
clang_Cursor_isNull
@@ -77,6 +79,7 @@ clang_Type_getOffsetOf
clang_Type_getNumTemplateArguments
clang_Type_getTemplateArgumentAsType
clang_Type_getCXXRefQualifier
+clang_Type_visitFields
clang_VerbatimBlockLineComment_getText
clang_VerbatimLineComment_getText
clang_HTMLTagComment_getAsString
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index 9de38d42aafad..4549b29a806e8 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -353,7 +353,6 @@ my %CompileOptionMap = (
'-imacros' => 1,
'-iprefix' => 1,
'-iquote' => 1,
- '-isystem' => 1,
'-iwithprefix' => 1,
'-iwithprefixbefore' => 1
);
@@ -493,6 +492,11 @@ foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
my $Arg = $ARGV[$i];
my ($ArgKey) = split /=/,$Arg,2;
+ # Be friendly to "" in the argument list.
+ if (!defined($ArgKey)) {
+ next;
+ }
+
# Modes ccc-analyzer supports
if ($Arg =~ /^-(E|MM?)$/) { $Action = 'preprocess'; }
elsif ($Arg eq '-c') { $Action = 'compile'; }
@@ -572,7 +576,7 @@ foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
}
# Compile mode flags.
- if ($Arg =~ /^-[D,I,U](.*)$/) {
+ if ($Arg =~ /^-[D,I,U,isystem](.*)$/) {
my $Tmp = $Arg;
if ($1 eq '') {
# FIXME: Check if we are going off the end.