aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-06-03 15:20:48 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-06-03 15:20:48 +0000
commit551c698530debaae81139c7c76a29fb762793362 (patch)
tree547e0e59163c33f2142998714eb5f957e65d1a57
parent416ada0f75bab22b084a1776deb229cd4a669c4d (diff)
downloadsrc-551c698530debaae81139c7c76a29fb762793362.tar.gz
src-551c698530debaae81139c7c76a29fb762793362.zip
Vendor import of clang trunk r304659:vendor/clang/clang-trunk-r304659
Notes
Notes: svn path=/vendor/clang/dist/; revision=319525 svn path=/vendor/clang/clang-trunk-r304659/; revision=319526; tag=vendor/clang/clang-trunk-r304659
-rw-r--r--docs/Modules.rst25
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td6
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td12
-rw-r--r--include/clang/Basic/Module.h10
-rw-r--r--include/clang/Basic/Sanitizers.h10
-rw-r--r--include/clang/Driver/CC1Options.td3
-rw-r--r--include/clang/Frontend/CodeGenOptions.def1
-rw-r--r--include/clang/Lex/ModuleMap.h45
-rw-r--r--lib/ARCMigrate/TransRetainReleaseDealloc.cpp1
-rw-r--r--lib/ARCMigrate/TransformActions.cpp1
-rw-r--r--lib/AST/ASTContext.cpp2
-rw-r--r--lib/AST/ASTDiagnostic.cpp1
-rw-r--r--lib/AST/ASTStructuralEquivalence.cpp1
-rw-r--r--lib/AST/DeclPrinter.cpp6
-rw-r--r--lib/AST/Expr.cpp2
-rw-r--r--lib/AST/ExprConstant.cpp3
-rw-r--r--lib/AST/ItaniumMangle.cpp23
-rw-r--r--lib/AST/NestedNameSpecifier.cpp1
-rw-r--r--lib/Analysis/PrintfFormatString.cpp1
-rw-r--r--lib/Analysis/PseudoConstantAnalysis.cpp1
-rw-r--r--lib/Analysis/ScanfFormatString.cpp2
-rw-r--r--lib/Basic/IdentifierTable.cpp1
-rw-r--r--lib/Basic/LangOptions.cpp4
-rw-r--r--lib/Basic/Module.cpp21
-rw-r--r--lib/Basic/TargetInfo.cpp2
-rw-r--r--lib/CodeGen/BackendUtil.cpp25
-rw-r--r--lib/CodeGen/CGBuiltin.cpp3
-rw-r--r--lib/CodeGen/CGCall.cpp1
-rw-r--r--lib/CodeGen/CGCoroutine.cpp1
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp8
-rw-r--r--lib/CodeGen/CGDebugInfo.h2
-rw-r--r--lib/CodeGen/CGExpr.cpp4
-rw-r--r--lib/CodeGen/CGExprScalar.cpp2
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp2
-rw-r--r--lib/CodeGen/CodeGenModule.cpp1
-rw-r--r--lib/Driver/SanitizerArgs.cpp10
-rw-r--r--lib/Edit/RewriteObjCFoundationAPI.cpp4
-rw-r--r--lib/Frontend/CompilerInstance.cpp1
-rw-r--r--lib/Frontend/CompilerInvocation.cpp9
-rw-r--r--lib/Frontend/FrontendAction.cpp26
-rw-r--r--lib/Frontend/FrontendActions.cpp7
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp2
-rw-r--r--lib/Frontend/Rewrite/FrontendActions.cpp7
-rw-r--r--lib/Frontend/Rewrite/InclusionRewriter.cpp7
-rw-r--r--lib/Frontend/SerializedDiagnosticReader.cpp1
-rw-r--r--lib/Lex/HeaderSearch.cpp2
-rw-r--r--lib/Lex/Lexer.cpp2
-rw-r--r--lib/Lex/LiteralSupport.cpp15
-rw-r--r--lib/Lex/ModuleMap.cpp334
-rw-r--r--lib/Lex/PPDirectives.cpp2
-rw-r--r--lib/Parse/ParseDecl.cpp4
-rw-r--r--lib/Parse/ParseDeclCXX.cpp1
-rw-r--r--lib/Parse/ParseExpr.cpp5
-rw-r--r--lib/Parse/ParseInit.cpp3
-rw-r--r--lib/Parse/ParseOpenMP.cpp4
-rw-r--r--lib/Parse/ParseStmt.cpp1
-rw-r--r--lib/Parse/ParseTentative.cpp2
-rw-r--r--lib/Parse/Parser.cpp2
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp1
-rw-r--r--lib/Sema/CoroutineStmtBuilder.h3
-rw-r--r--lib/Sema/SemaCodeComplete.cpp2
-rw-r--r--lib/Sema/SemaCoroutine.cpp19
-rw-r--r--lib/Sema/SemaDecl.cpp5
-rw-r--r--lib/Sema/SemaDeclCXX.cpp1
-rw-r--r--lib/Sema/SemaExpr.cpp2
-rw-r--r--lib/Sema/SemaLambda.cpp1
-rw-r--r--lib/Sema/SemaLookup.cpp1
-rw-r--r--lib/Sema/SemaStmt.cpp51
-rw-r--r--lib/Sema/SemaStmtAsm.cpp1
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp4
-rw-r--r--lib/Sema/SemaType.cpp50
-rw-r--r--lib/Sema/TreeTransform.h2
-rw-r--r--lib/Serialization/ASTReader.cpp29
-rw-r--r--lib/Serialization/ASTWriter.cpp157
-rw-r--r--lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp1
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp1
-rw-r--r--lib/StaticAnalyzer/Core/SValBuilder.cpp1
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp1
-rw-r--r--test/CodeGen/pr26099.c12
-rw-r--r--test/CodeGen/thin_link_bitcode.c5
-rw-r--r--test/CodeGen/ubsan-pointer-overflow.m12
-rw-r--r--test/CodeGenCXX/pr33080.cpp33
-rw-r--r--test/CodeGenCXX/unaligned-duplicated-mangle-name.cpp20
-rw-r--r--test/CodeGenCXX/unaligned-member-qualifier.cpp20
-rw-r--r--test/CodeGenCoroutines/coro-params.cpp34
-rw-r--r--test/CodeGenObjCXX/arc-mangle.mm10
-rw-r--r--test/Driver/fsanitize-coverage.c3
-rw-r--r--test/Frontend/rewrite-includes-filenotfound.c6
-rw-r--r--test/Integration/carbon.c1
-rw-r--r--test/Integration/cocoa-pch.m1
-rw-r--r--test/Integration/cocoa.m1
-rw-r--r--test/Misc/ast-print-objectivec.m15
-rw-r--r--test/Modules/Inputs/check-for-sanitizer-feature/check.h5
-rw-r--r--test/Modules/Inputs/check-for-sanitizer-feature/map3
-rw-r--r--test/Modules/Inputs/header-attribs/bar.h1
-rw-r--r--test/Modules/Inputs/header-attribs/baz.h1
-rw-r--r--test/Modules/Inputs/header-attribs/foo.h1
-rw-r--r--test/Modules/Inputs/header-attribs/modular.modulemap5
-rw-r--r--test/Modules/Inputs/header-attribs/textual.modulemap5
-rw-r--r--test/Modules/check-for-sanitizer-feature.cpp66
-rw-r--r--test/Modules/diagnostics.modulemap14
-rw-r--r--test/Modules/header-attribs.cpp10
-rw-r--r--test/Modules/lookup.m4
-rw-r--r--test/Modules/preprocess-missing.modulemap7
-rw-r--r--test/Modules/preprocess-module.cpp15
-rw-r--r--test/Sema/warn-strict-prototypes.m11
-rw-r--r--test/SemaCXX/coroutines.cpp13
-rw-r--r--test/SemaOpenCL/func.cl7
-rw-r--r--test/SemaTemplate/deduction-crash.cpp36
-rw-r--r--test/lit.cfg3
-rw-r--r--unittests/AST/DeclPrinterTest.cpp2
112 files changed, 1101 insertions, 303 deletions
diff --git a/docs/Modules.rst b/docs/Modules.rst
index 7bd2adf8af52..ed6f81715731 100644
--- a/docs/Modules.rst
+++ b/docs/Modules.rst
@@ -469,9 +469,16 @@ A header declaration specifies that a particular header is associated with the e
.. parsed-literal::
*header-declaration*:
- ``private``:sub:`opt` ``textual``:sub:`opt` ``header`` *string-literal*
- ``umbrella`` ``header`` *string-literal*
- ``exclude`` ``header`` *string-literal*
+ ``private``:sub:`opt` ``textual``:sub:`opt` ``header`` *string-literal* *header-attrs*:sub:`opt`
+ ``umbrella`` ``header`` *string-literal* *header-attrs*:sub:`opt`
+ ``exclude`` ``header`` *string-literal* *header-attrs*:sub:`opt`
+
+ *header-attrs*:
+ '{' *header-attr** '}'
+
+ *header-attr*:
+ ``size`` *integer-literal*
+ ``mtime`` *integer-literal*
A header declaration that does not contain ``exclude`` nor ``textual`` specifies a header that contributes to the enclosing module. Specifically, when the module is built, the named header will be parsed and its declarations will be (logically) placed into the enclosing submodule.
@@ -504,6 +511,18 @@ A header with the ``exclude`` specifier is excluded from the module. It will not
A given header shall not be referenced by more than one *header-declaration*.
+Two *header-declaration*\s, or a *header-declaration* and a ``#include``, are
+considered to refer to the same file if the paths resolve to the same file
+and the specified *header-attr*\s (if any) match the attributes of that file,
+even if the file is named differently (for instance, by a relative path or
+via symlinks).
+
+.. note::
+ The use of *header-attr*\s avoids the need for Clang to speculatively
+ ``stat`` every header referenced by a module map. It is recommended that
+ *header-attr*\s only be used in machine-generated module maps, to avoid
+ mismatches between attribute values and the corresponding files.
+
Umbrella directory declaration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An umbrella directory declaration specifies that all of the headers in the specified directory should be included within the module.
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index b393ce5f1545..447f06945660 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -664,6 +664,12 @@ def warn_mmap_mismatched_top_level_private : Warning<
InGroup<PrivateModule>;
def note_mmap_rename_top_level_private_as_submodule : Note<
"make '%0' a submodule of '%1' to ensure it can be found by name">;
+def err_mmap_duplicate_header_attribute : Error<
+ "header attribute '%0' specified multiple times">;
+def err_mmap_invalid_header_attribute_value : Error<
+ "expected integer literal as value for header attribute '%0'">;
+def err_mmap_expected_header_attribute : Error<
+ "expected a header attribute name ('size' or 'mtime')">;
def warn_auto_module_import : Warning<
"treating #%select{include|import|include_next|__include_macros}0 as an "
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 4de4f47b8a5a..a5a5c74afe69 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4584,7 +4584,7 @@ def warn_missing_prototype : Warning<
def note_declaration_not_a_prototype : Note<
"this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function">;
def warn_strict_prototypes : Warning<
- "this %select{function declaration is not|"
+ "this %select{function declaration is not|block declaration is not|"
"old-style function definition is not preceded by}0 a prototype">,
InGroup<DiagGroup<"strict-prototypes">>, DefaultIgnore;
def warn_missing_variable_declarations : Warning<
@@ -7268,7 +7268,7 @@ def err_invalid_conversion_between_vector_and_integer : Error<
"invalid conversion between vector type %0 and integer type %1 "
"of different size">;
-def err_opencl_function_pointer_variable : Error<
+def err_opencl_function_pointer : Error<
"pointers to functions are not allowed">;
def err_opencl_taking_function_address : Error<
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 35e2f67e24b6..f9e7b8fa9b56 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -174,10 +174,6 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
"method %2 with %ordinal3 parameter of type %4%select{| decayed from %6}5|"
"method %2 with %ordinal3 parameter named %4}1">;
-def warn_module_uses_date_time : Warning<
- "%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
- InGroup<DiagGroup<"pch-date-time">>;
-
def warn_duplicate_module_file_extension : Warning<
"duplicate module file extension block name '%0'">,
InGroup<ModuleFileExtension>;
@@ -186,7 +182,15 @@ def warn_module_system_bit_conflict : Warning<
"module file '%0' was validated as a system module and is now being imported "
"as a non-system module; any difference in diagnostic options will be ignored">,
InGroup<ModuleConflict>;
+} // let CategoryName
+let CategoryName = "AST Serialization Issue" in {
+def warn_module_uses_date_time : Warning<
+ "%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
+ InGroup<DiagGroup<"pch-date-time">>;
+def err_module_no_size_mtime_for_header : Error<
+ "cannot emit module %0: %select{size|mtime}1 must be explicitly specified "
+ "for missing header file \"%2\"">;
} // let CategoryName
} // let Component
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 326d84eeb6c2..1e52b29367b2 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -154,11 +154,19 @@ public:
/// \brief Stored information about a header directive that was found in the
/// module map file but has not been resolved to a file.
struct UnresolvedHeaderDirective {
+ HeaderKind Kind = HK_Normal;
SourceLocation FileNameLoc;
std::string FileName;
- bool IsUmbrella;
+ bool IsUmbrella = false;
+ bool HasBuiltinHeader = false;
+ Optional<off_t> Size;
+ Optional<time_t> ModTime;
};
+ /// Headers that are mentioned in the module map file but that we have not
+ /// yet attempted to resolve to a file on the file system.
+ SmallVector<UnresolvedHeaderDirective, 1> UnresolvedHeaders;
+
/// \brief Headers that are mentioned in the module map file but could not be
/// found on the file system.
SmallVector<UnresolvedHeaderDirective, 1> MissingHeaders;
diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h
index bfa8e516edd3..5317720095e0 100644
--- a/include/clang/Basic/Sanitizers.h
+++ b/include/clang/Basic/Sanitizers.h
@@ -61,8 +61,8 @@ struct SanitizerSet {
Mask = Value ? (Mask | K) : (Mask & ~K);
}
- /// \brief Disable all sanitizers.
- void clear() { Mask = 0; }
+ /// Disable the sanitizers specified in \p K.
+ void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }
/// \brief Returns true if at least one sanitizer is enabled.
bool empty() const { return Mask == 0; }
@@ -79,6 +79,12 @@ SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
/// this group enables.
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
+/// Return the sanitizers which do not affect preprocessing.
+static inline SanitizerMask getPPTransparentSanitizers() {
+ return SanitizerKind::CFI | SanitizerKind::Integer |
+ SanitizerKind::Nullability | SanitizerKind::Undefined;
+}
+
} // end namespace clang
#endif
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index b55289dc35a1..1132d1345f60 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -293,6 +293,9 @@ def fsanitize_coverage_trace_gep
def fsanitize_coverage_8bit_counters
: Flag<["-"], "fsanitize-coverage-8bit-counters">,
HelpText<"Enable frequency counters in sanitizer coverage">;
+def fsanitize_coverage_inline_8bit_counters
+ : Flag<["-"], "fsanitize-coverage-inline-8bit-counters">,
+ HelpText<"Enable inline 8-bit counters in sanitizer coverage">;
def fsanitize_coverage_trace_pc
: Flag<["-"], "fsanitize-coverage-trace-pc">,
HelpText<"Enable PC tracing in sanitizer coverage">;
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 9a13854671d2..d7cd805fa10a 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -163,6 +163,7 @@ CODEGENOPT(SanitizeCoverageTracePC, 1, 0) ///< Enable PC tracing
///< in sanitizer coverage.
CODEGENOPT(SanitizeCoverageTracePCGuard, 1, 0) ///< Enable PC tracing with guard
///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageInline8bitCounters, 1, 0) ///< Use inline 8bit counters.
CODEGENOPT(SanitizeCoverageNoPrune, 1, 0) ///< Disable coverage pruning.
CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers.
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index c05faa4a8201..11506939f9b1 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -26,6 +26,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/Twine.h"
#include <algorithm>
#include <memory>
@@ -116,6 +117,11 @@ public:
// Adjust ModuleMap::addHeader.
};
+ /// Convert a header kind to a role. Requires Kind to not be HK_Excluded.
+ static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind);
+ /// Convert a header role to a kind.
+ static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role);
+
/// \brief A header that is known to reside within a given module,
/// whether it was included or excluded.
class KnownHeader {
@@ -165,7 +171,13 @@ private:
/// \brief Mapping from each header to the module that owns the contents of
/// that header.
HeadersMap Headers;
-
+
+ /// Map from file sizes to modules with lazy header directives of that size.
+ mutable llvm::DenseMap<off_t, llvm::TinyPtrVector<Module*>> LazyHeadersBySize;
+ /// Map from mtimes to modules with lazy header directives with those mtimes.
+ mutable llvm::DenseMap<time_t, llvm::TinyPtrVector<Module*>>
+ LazyHeadersByModTime;
+
/// \brief Mapping from directories with umbrella headers to the module
/// that is generated from the umbrella header.
///
@@ -257,22 +269,30 @@ private:
/// resolved.
Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const;
- /// Resolve the given header directive to an actual header file.
+ /// Add an unresolved header to a module.
+ void addUnresolvedHeader(Module *Mod,
+ Module::UnresolvedHeaderDirective Header);
+
+ /// Look up the given header directive to find an actual header file.
///
/// \param M The module in which we're resolving the header directive.
/// \param Header The header directive to resolve.
/// \param RelativePathName Filled in with the relative path name from the
/// module to the resolved header.
/// \return The resolved file, if any.
- const FileEntry *resolveHeader(Module *M,
- Module::UnresolvedHeaderDirective Header,
- SmallVectorImpl<char> &RelativePathName);
+ const FileEntry *findHeader(Module *M,
+ const Module::UnresolvedHeaderDirective &Header,
+ SmallVectorImpl<char> &RelativePathName);
+
+ /// Resolve the given header directive.
+ void resolveHeader(Module *M,
+ const Module::UnresolvedHeaderDirective &Header);
/// Attempt to resolve the specified header directive as naming a builtin
/// header.
- const FileEntry *
- resolveAsBuiltinHeader(Module *M, Module::UnresolvedHeaderDirective Header,
- SmallVectorImpl<char> &BuiltinPathName);
+ /// \return \c true if a corresponding builtin header was found.
+ bool resolveAsBuiltinHeader(Module *M,
+ const Module::UnresolvedHeaderDirective &Header);
/// \brief Looks up the modules that \p File corresponds to.
///
@@ -368,6 +388,15 @@ public:
/// the preferred module for the header.
ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File) const;
+ /// Resolve all lazy header directives for the specified file.
+ ///
+ /// This ensures that the HeaderFileInfo on HeaderSearch is up to date. This
+ /// is effectively internal, but is exposed so HeaderSearch can call it.
+ void resolveHeaderDirectives(const FileEntry *File) const;
+
+ /// Resolve all lazy header directives for the specified module.
+ void resolveHeaderDirectives(Module *Mod) const;
+
/// \brief Reports errors if a module must not include a specific file.
///
/// \param RequestingModule The module including a file.
diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
index f81133f3aad3..389f3655aa52 100644
--- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -78,6 +78,7 @@ public:
}
}
// Pass through.
+ LLVM_FALLTHROUGH;
case OMF_retain:
case OMF_release:
if (E->getReceiverKind() == ObjCMessageExpr::Instance)
diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp
index c628b54ed414..4f3fb5845925 100644
--- a/lib/ARCMigrate/TransformActions.cpp
+++ b/lib/ARCMigrate/TransformActions.cpp
@@ -539,6 +539,7 @@ void TransformActionsImpl::addRemoval(CharSourceRange range) {
return;
case Range_Contains:
RI->End = newRange.End;
+ LLVM_FALLTHROUGH;
case Range_ExtendsBegin:
newRange.End = RI->End;
Removals.erase(RI);
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 29d970e66d71..34c4d2617ec9 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -6240,6 +6240,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += "{objc_class=}";
return;
}
+ // TODO: Double check to make sure this intentially falls through.
+ LLVM_FALLTHROUGH;
}
case Type::ObjCInterface: {
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 03e6115a0dba..b43c28deb362 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -360,6 +360,7 @@ void clang::FormatASTNodeDiagnosticArgument(
Modifier = StringRef();
Argument = StringRef();
// Fall through
+ LLVM_FALLTHROUGH;
}
case DiagnosticsEngine::ak_qualtype: {
assert(Modifier.empty() && Argument.empty() &&
diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp
index 9376ee1d4ee4..eff1aa5e323d 100644
--- a/lib/AST/ASTStructuralEquivalence.cpp
+++ b/lib/AST/ASTStructuralEquivalence.cpp
@@ -424,6 +424,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
// Fall through to check the bits common with FunctionNoProtoType.
+ LLVM_FALLTHROUGH;
}
case Type::FunctionNoProto: {
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index bc8a34c93653..6eeba88e4033 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -1189,7 +1189,9 @@ void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
for (const auto *PI : OMD->parameters()) {
// FIXME: selector is missing here!
pos = name.find_first_of(':', lastPos);
- Out << " " << name.substr(lastPos, pos - lastPos) << ':';
+ if (lastPos != 0)
+ Out << " ";
+ Out << name.substr(lastPos, pos - lastPos) << ':';
PrintObjCMethodType(OMD->getASTContext(),
PI->getObjCDeclQualifier(),
PI->getType());
@@ -1198,7 +1200,7 @@ void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
}
if (OMD->param_begin() == OMD->param_end())
- Out << " " << name;
+ Out << name;
if (OMD->isVariadic())
Out << ", ...";
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index d523a0f93cf6..c21cd3f65bd4 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1576,6 +1576,7 @@ bool CastExpr::CastConsistency() const {
getSubExpr()->getType()->isBlockPointerType());
assert(getType()->getPointeeType().getAddressSpace() !=
getSubExpr()->getType()->getPointeeType().getAddressSpace());
+ LLVM_FALLTHROUGH;
// These should not have an inheritance path.
case CK_Dynamic:
case CK_ToUnion:
@@ -2102,6 +2103,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
}
// Fallthrough for generic call handling.
+ LLVM_FALLTHROUGH;
}
case CallExprClass:
case CXXMemberCallExprClass:
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index c19812e341c0..17d0ce67dcf9 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -736,6 +736,7 @@ namespace {
if (!HasFoldFailureDiagnostic)
break;
// We've already failed to fold something. Keep that diagnostic.
+ LLVM_FALLTHROUGH;
case EM_ConstantExpression:
case EM_PotentialConstantExpression:
case EM_ConstantExpressionUnevaluated:
@@ -10374,6 +10375,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
}
// OffsetOf falls through here.
+ LLVM_FALLTHROUGH;
}
case Expr::OffsetOfExprClass: {
// Note that per C99, offsetof must be an ICE. And AFAIK, using
@@ -10476,6 +10478,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
return Worst(LHSResult, RHSResult);
}
}
+ LLVM_FALLTHROUGH;
}
case Expr::ImplicitCastExprClass:
case Expr::CStyleCastExprClass:
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 7db0b4d8e4ff..c9bb45a37eb5 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1459,8 +1459,6 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
// We do not consider restrict a distinguishing attribute for overloading
// purposes so we must not mangle it.
MethodQuals.removeRestrict();
- // __unaligned is not currently mangled in any way, so remove it.
- MethodQuals.removeUnaligned();
mangleQualifiers(MethodQuals);
mangleRefQualifier(Method->getRefQualifier());
}
@@ -2140,7 +2138,8 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
}
void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
- // Vendor qualifiers come first.
+ // Vendor qualifiers come first and if they are order-insensitive they must
+ // be emitted in reversed alphabetical order, see Itanium ABI 5.1.5.
// Address space qualifiers start with an ordinary letter.
if (Quals.hasAddressSpace()) {
@@ -2176,17 +2175,28 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
}
// The ARC ownership qualifiers start with underscores.
- switch (Quals.getObjCLifetime()) {
// Objective-C ARC Extension:
//
// <type> ::= U "__strong"
// <type> ::= U "__weak"
// <type> ::= U "__autoreleasing"
+ //
+ // Note: we emit __weak first to preserve the order as
+ // required by the Itanium ABI.
+ if (Quals.getObjCLifetime() == Qualifiers::OCL_Weak)
+ mangleVendorQualifier("__weak");
+
+ // __unaligned (from -fms-extensions)
+ if (Quals.hasUnaligned())
+ mangleVendorQualifier("__unaligned");
+
+ // Remaining ARC ownership qualifiers.
+ switch (Quals.getObjCLifetime()) {
case Qualifiers::OCL_None:
break;
case Qualifiers::OCL_Weak:
- mangleVendorQualifier("__weak");
+ // Do nothing as we already handled this case above.
break;
case Qualifiers::OCL_Strong:
@@ -3775,6 +3785,7 @@ recurse:
Out << "v1U" << Kind.size() << Kind;
}
// Fall through to mangle the cast itself.
+ LLVM_FALLTHROUGH;
case Expr::CStyleCastExprClass:
mangleCastExpression(E, "cv");
@@ -4327,7 +4338,7 @@ bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) {
/// substitutions.
static bool hasMangledSubstitutionQualifiers(QualType T) {
Qualifiers Qs = T.getQualifiers();
- return Qs.getCVRQualifiers() || Qs.hasAddressSpace();
+ return Qs.getCVRQualifiers() || Qs.hasAddressSpace() || Qs.hasUnaligned();
}
bool CXXNameMangler::mangleSubstitution(QualType T) {
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index 514c7c9f5b33..e2e0dbeec0dd 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -290,6 +290,7 @@ NestedNameSpecifier::print(raw_ostream &OS,
case TypeSpecWithTemplate:
OS << "template ";
// Fall through to print the type.
+ LLVM_FALLTHROUGH;
case TypeSpec: {
const Type *T = getAsType();
diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp
index ed7193ecb437..60556697113a 100644
--- a/lib/Analysis/PrintfFormatString.cpp
+++ b/lib/Analysis/PrintfFormatString.cpp
@@ -441,6 +441,7 @@ ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
case LengthModifier::AsShort:
if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
return Ctx.IntTy;
+ LLVM_FALLTHROUGH;
default:
return ArgType::Invalid();
}
diff --git a/lib/Analysis/PseudoConstantAnalysis.cpp b/lib/Analysis/PseudoConstantAnalysis.cpp
index 614f676fb193..83b545a7be83 100644
--- a/lib/Analysis/PseudoConstantAnalysis.cpp
+++ b/lib/Analysis/PseudoConstantAnalysis.cpp
@@ -109,6 +109,7 @@ void PseudoConstantAnalysis::RunAnalysis() {
// Do not visit the children
continue;
+ LLVM_FALLTHROUGH;
}
case BO_AddAssign:
case BO_SubAssign:
diff --git a/lib/Analysis/ScanfFormatString.cpp b/lib/Analysis/ScanfFormatString.cpp
index 3b93f1a57f1f..534225985460 100644
--- a/lib/Analysis/ScanfFormatString.cpp
+++ b/lib/Analysis/ScanfFormatString.cpp
@@ -341,6 +341,7 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const {
case LengthModifier::AsShort:
if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
return ArgType::PtrTo(ArgType::AnyCharTy);
+ LLVM_FALLTHROUGH;
default:
return ArgType::Invalid();
}
@@ -357,6 +358,7 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const {
case LengthModifier::AsShort:
if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
return ArgType::PtrTo(ArgType::AnyCharTy);
+ LLVM_FALLTHROUGH;
default:
return ArgType::Invalid();
}
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index 74c85376c7db..372e0c417fd4 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -551,6 +551,7 @@ ObjCInstanceTypeFamily Selector::getInstTypeMethodFamily(Selector sel) {
case 's':
if (startsWithWord(name, "shared")) return OIT_ReturnsSelf;
if (startsWithWord(name, "standard")) return OIT_Singleton;
+ break;
case 'i':
if (startsWithWord(name, "init")) return OIT_Init;
default:
diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp
index c8a774311efe..db81507aa209 100644
--- a/lib/Basic/LangOptions.cpp
+++ b/lib/Basic/LangOptions.cpp
@@ -29,9 +29,7 @@ void LangOptions::resetNonModularOptions() {
Name = Default;
#include "clang/Basic/LangOptions.def"
- // FIXME: This should not be reset; modules can be different with different
- // sanitizer options (this affects __has_feature(address_sanitizer) etc).
- Sanitize.clear();
+ // These options do not affect AST generation.
SanitizerBlacklistFiles.clear();
XRayAlwaysInstrumentFiles.clear();
XRayNeverInstrumentFiles.clear();
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index ac3d7c559679..83c524877ab0 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -394,11 +394,30 @@ void Module::print(raw_ostream &OS, unsigned Indent) const {
{"exclude ", HK_Excluded}};
for (auto &K : Kinds) {
+ assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
for (auto &H : Headers[K.Kind]) {
OS.indent(Indent + 2);
OS << K.Prefix << "header \"";
OS.write_escaped(H.NameAsWritten);
- OS << "\"\n";
+ OS << "\" { size " << H.Entry->getSize()
+ << " mtime " << H.Entry->getModificationTime() << " }\n";
+ }
+ }
+ for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
+ for (auto &U : *Unresolved) {
+ OS.indent(Indent + 2);
+ OS << Kinds[U.Kind].Prefix << "header \"";
+ OS.write_escaped(U.FileName);
+ OS << "\"";
+ if (U.Size || U.ModTime) {
+ OS << " {";
+ if (U.Size)
+ OS << " size " << *U.Size;
+ if (U.ModTime)
+ OS << " mtime " << *U.ModTime;
+ OS << " }";
+ }
+ OS << "\n";
}
}
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index e19404dc54cb..8cfd8bde9cbb 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -143,9 +143,11 @@ const char *TargetInfo::getTypeConstantSuffix(IntType T) const {
case UnsignedChar:
if (getCharWidth() < getIntWidth())
return "";
+ LLVM_FALLTHROUGH;
case UnsignedShort:
if (getShortWidth() < getIntWidth())
return "";
+ LLVM_FALLTHROUGH;
case UnsignedInt: return "U";
case UnsignedLong: return "UL";
case UnsignedLongLong: return "ULL";
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 0f07169ac8b0..fd193bcf1a69 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -49,6 +49,7 @@
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Scalar.h"
@@ -186,6 +187,7 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
Opts.TracePC = CGOpts.SanitizeCoverageTracePC;
Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;
Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;
+ Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
PM.add(createSanitizerCoverageModulePass(Opts));
}
@@ -897,6 +899,7 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
// create that pass manager here and use it as needed below.
legacy::PassManager CodeGenPasses;
bool NeedCodeGen = false;
+ Optional<raw_fd_ostream> ThinLinkOS;
// Append any output we need to the pass manager.
switch (Action) {
@@ -904,9 +907,24 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
break;
case Backend_EmitBC:
- MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
- CodeGenOpts.EmitSummaryIndex,
- CodeGenOpts.EmitSummaryIndex));
+ if (CodeGenOpts.EmitSummaryIndex) {
+ if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
+ std::error_code EC;
+ ThinLinkOS.emplace(CodeGenOpts.ThinLinkBitcodeFile, EC,
+ llvm::sys::fs::F_None);
+ if (EC) {
+ Diags.Report(diag::err_fe_unable_to_open_output)
+ << CodeGenOpts.ThinLinkBitcodeFile << EC.message();
+ return;
+ }
+ }
+ MPM.addPass(
+ ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &*ThinLinkOS : nullptr));
+ } else {
+ MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
+ CodeGenOpts.EmitSummaryIndex,
+ CodeGenOpts.EmitSummaryIndex));
+ }
break;
case Backend_EmitLL:
@@ -1029,6 +1047,7 @@ static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M,
Conf.CGOptLevel = getCGOptLevel(CGOpts);
initTargetOptions(Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts);
Conf.SampleProfile = std::move(SampleProfile);
+ Conf.UseNewPM = CGOpts.ExperimentalNewPassManager;
switch (Action) {
case Backend_EmitNothing:
Conf.PreCodeGenModuleHook = [](size_t Task, const Module &Mod) {
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 2134fb9e03e4..3b4f8854a9ca 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -2659,6 +2659,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
llvm::ArrayRef<llvm::Value *>(Args)));
}
+ LLVM_FALLTHROUGH;
}
// OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block
// parameter.
@@ -3813,6 +3814,7 @@ Value *CodeGenFunction::EmitCommonNeonBuiltinExpr(
case NEON::BI__builtin_neon_vcalt_v:
case NEON::BI__builtin_neon_vcaltq_v:
std::swap(Ops[0], Ops[1]);
+ LLVM_FALLTHROUGH;
case NEON::BI__builtin_neon_vcage_v:
case NEON::BI__builtin_neon_vcageq_v:
case NEON::BI__builtin_neon_vcagt_v:
@@ -5056,6 +5058,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
case NEON::BI__builtin_neon_vsri_n_v:
case NEON::BI__builtin_neon_vsriq_n_v:
rightShift = true;
+ LLVM_FALLTHROUGH;
case NEON::BI__builtin_neon_vsli_n_v:
case NEON::BI__builtin_neon_vsliq_n_v:
Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift);
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 8f405eee6e52..079064733585 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -4259,6 +4259,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
Builder.CreateStore(elt, eltAddr);
}
// FALLTHROUGH
+ LLVM_FALLTHROUGH;
}
case ABIArgInfo::InAlloca:
diff --git a/lib/CodeGen/CGCoroutine.cpp b/lib/CodeGen/CGCoroutine.cpp
index f65fb5b9232a..bc5f6327c9a0 100644
--- a/lib/CodeGen/CGCoroutine.cpp
+++ b/lib/CodeGen/CGCoroutine.cpp
@@ -625,6 +625,7 @@ RValue CodeGenFunction::EmitCoroutineIntrinsic(const CallExpr *E,
CGM.Error(E->getLocStart(), "this builtin expect that __builtin_coro_id has"
" been used earlier in this function");
// Fallthrough to the next case to add TokenNone as the first argument.
+ LLVM_FALLTHROUGH;
}
// @llvm.coro.suspend takes a token parameter. Add token 'none' as the first
// argument.
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 0a1dc09211c2..02db79159b58 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -2781,6 +2781,7 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
// them distinct if they are ODR-uniqued.
if (FullName.empty())
break;
+ LLVM_FALLTHROUGH;
case llvm::dwarf::DW_TAG_structure_type:
case llvm::dwarf::DW_TAG_union_type:
@@ -3263,7 +3264,7 @@ void CGDebugInfo::EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD) {
void CGDebugInfo::EmitInlineFunctionEnd(CGBuilderTy &Builder) {
assert(CurInlinedAt && "unbalanced inline scope stack");
- EmitFunctionEnd(Builder);
+ EmitFunctionEnd(Builder, nullptr);
setInlinedAt(llvm::DebugLoc(CurInlinedAt).getInlinedAt());
}
@@ -3332,7 +3333,7 @@ void CGDebugInfo::EmitLexicalBlockEnd(CGBuilderTy &Builder,
LexicalBlockStack.pop_back();
}
-void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {
+void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn) {
assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
unsigned RCount = FnBeginRegionCount.back();
assert(RCount <= LexicalBlockStack.size() && "Region stack mismatch");
@@ -3344,6 +3345,9 @@ void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {
LexicalBlockStack.pop_back();
}
FnBeginRegionCount.pop_back();
+
+ if (Fn && Fn->getSubprogram())
+ DBuilder.finalizeSubprogram(Fn->getSubprogram());
}
llvm::DIType *CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 7de48f278994..39249c7cf4da 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -367,7 +367,7 @@ public:
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType);
/// Constructs the debug code for exiting a function.
- void EmitFunctionEnd(CGBuilderTy &Builder);
+ void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn);
/// Emit metadata to indicate the beginning of a new lexical block
/// and push the block onto the stack.
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 84ce896506d5..2aa045879213 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1487,9 +1487,9 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
// Handle vectors differently to get better performance.
if (Ty->isVectorType()) {
llvm::Type *SrcTy = Value->getType();
- auto *VecTy = cast<llvm::VectorType>(SrcTy);
+ auto *VecTy = dyn_cast<llvm::VectorType>(SrcTy);
// Handle vec3 special.
- if (VecTy->getNumElements() == 3) {
+ if (VecTy && VecTy->getNumElements() == 3) {
// Our source is a vec3, do a shuffle vector to make it a vec4.
llvm::Constant *Mask[] = {Builder.getInt32(0), Builder.getInt32(1),
Builder.getInt32(2),
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index d604b4130a23..f9d1fe468748 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -3887,7 +3887,7 @@ Value *CodeGenFunction::EmitCheckedInBoundsGEP(Value *Ptr,
/// Return the result of the given binary operation.
auto eval = [&](BinaryOperator::Opcode Opcode, llvm::Value *LHS,
llvm::Value *RHS) -> llvm::Value * {
- assert(Opcode == BO_Add || Opcode == BO_Mul && "Can't eval binop");
+ assert((Opcode == BO_Add || Opcode == BO_Mul) && "Can't eval binop");
// If the operands are constants, return a constant result.
if (auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 85da3ae47db0..b6d7f0255017 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -348,7 +348,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// Emit debug descriptor for function end.
if (CGDebugInfo *DI = getDebugInfo())
- DI->EmitFunctionEnd(Builder);
+ DI->EmitFunctionEnd(Builder, CurFn);
// Reset the debug location to that of the simple 'return' expression, if any
// rather than that of the end of the function's scope '}'.
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index c61a5f6ffa71..dde8f2e36920 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -3841,6 +3841,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
// Skip variable templates
if (cast<VarDecl>(D)->getDescribedVarTemplate())
return;
+ LLVM_FALLTHROUGH;
case Decl::VarTemplateSpecialization:
EmitGlobal(cast<VarDecl>(D));
if (auto *DD = dyn_cast<DecompositionDecl>(D))
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index 9ab2e176845c..ad2b4ada9a83 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -48,13 +48,14 @@ enum CoverageFeature {
CoverageBB = 1 << 1,
CoverageEdge = 1 << 2,
CoverageIndirCall = 1 << 3,
- CoverageTraceBB = 1 << 4,
+ CoverageTraceBB = 1 << 4, // Deprecated.
CoverageTraceCmp = 1 << 5,
CoverageTraceDiv = 1 << 6,
CoverageTraceGep = 1 << 7,
- Coverage8bitCounters = 1 << 8,
+ Coverage8bitCounters = 1 << 8, // Deprecated.
CoverageTracePC = 1 << 9,
CoverageTracePCGuard = 1 << 10,
+ CoverageInline8bitCounters = 1 << 12,
CoverageNoPrune = 1 << 11,
};
@@ -530,7 +531,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
}
// trace-pc w/o func/bb/edge implies edge.
- if ((CoverageFeatures & (CoverageTracePC | CoverageTracePCGuard)) &&
+ if ((CoverageFeatures &
+ (CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters)) &&
!(CoverageFeatures & InsertionPointTypes))
CoverageFeatures |= CoverageEdge;
@@ -637,6 +639,7 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard"),
+ std::make_pair(CoverageInline8bitCounters, "-fsanitize-coverage-inline-8bit-counters"),
std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune")};
for (auto F : CoverageFlags) {
if (CoverageFeatures & F.first)
@@ -798,6 +801,7 @@ int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
.Case("trace-pc", CoverageTracePC)
.Case("trace-pc-guard", CoverageTracePCGuard)
.Case("no-prune", CoverageNoPrune)
+ .Case("inline-8bit-counters", CoverageInline8bitCounters)
.Default(0);
if (F == 0)
D.Diag(clang::diag::err_drv_unsupported_option_argument)
diff --git a/lib/Edit/RewriteObjCFoundationAPI.cpp b/lib/Edit/RewriteObjCFoundationAPI.cpp
index 2148316532de..dc501b564eea 100644
--- a/lib/Edit/RewriteObjCFoundationAPI.cpp
+++ b/lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -798,24 +798,28 @@ static bool rewriteToNumberLiteral(const ObjCMessageExpr *Msg,
case NSAPI::NSNumberWithUnsignedInt:
case NSAPI::NSNumberWithUnsignedInteger:
CallIsUnsigned = true;
+ LLVM_FALLTHROUGH;
case NSAPI::NSNumberWithInt:
case NSAPI::NSNumberWithInteger:
break;
case NSAPI::NSNumberWithUnsignedLong:
CallIsUnsigned = true;
+ LLVM_FALLTHROUGH;
case NSAPI::NSNumberWithLong:
CallIsLong = true;
break;
case NSAPI::NSNumberWithUnsignedLongLong:
CallIsUnsigned = true;
+ LLVM_FALLTHROUGH;
case NSAPI::NSNumberWithLongLong:
CallIsLongLong = true;
break;
case NSAPI::NSNumberWithDouble:
CallIsDouble = true;
+ LLVM_FALLTHROUGH;
case NSAPI::NSNumberWithFloat:
CallIsFloating = true;
break;
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index a7b5fa7dfd29..e92672a785da 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -1727,6 +1727,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
diag::warn_module_config_mismatch)
<< ModuleFileName;
// Fall through to error out.
+ LLVM_FALLTHROUGH;
case ASTReader::VersionMismatch:
case ASTReader::HadErrors:
ModuleLoader::HadFatalFailure = true;
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 47c763d29357..adb15f1730bf 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -768,6 +768,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.SanitizeCoverageTracePCGuard =
Args.hasArg(OPT_fsanitize_coverage_trace_pc_guard);
Opts.SanitizeCoverageNoPrune = Args.hasArg(OPT_fsanitize_coverage_no_prune);
+ Opts.SanitizeCoverageInline8bitCounters =
+ Args.hasArg(OPT_fsanitize_coverage_inline_8bit_counters);
Opts.SanitizeMemoryTrackOrigins =
getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
Opts.SanitizeMemoryUseAfterDtor =
@@ -2700,6 +2702,13 @@ std::string CompilerInvocation::getModuleHash() const {
code = ext->hashExtension(code);
}
+ // Extend the signature with the enabled sanitizers, if at least one is
+ // enabled. Sanitizers which cannot affect AST generation aren't hashed.
+ SanitizerSet SanHash = LangOpts->Sanitize;
+ SanHash.clear(getPPTransparentSanitizers());
+ if (!SanHash.empty())
+ code = hash_combine(code, SanHash.Mask);
+
return llvm::APInt(64, code).toString(36, /*Signed=*/false);
}
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index cd67e469ddad..e2fbe965349f 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -289,14 +289,28 @@ static void addHeaderInclude(StringRef HeaderName,
///
/// \param Includes Will be augmented with the set of \#includes or \#imports
/// needed to load all of the named headers.
-static std::error_code
-collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
- ModuleMap &ModMap, clang::Module *Module,
- SmallVectorImpl<char> &Includes) {
+static std::error_code collectModuleHeaderIncludes(
+ const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag,
+ ModuleMap &ModMap, clang::Module *Module, SmallVectorImpl<char> &Includes) {
// Don't collect any headers for unavailable modules.
if (!Module->isAvailable())
return std::error_code();
+ // Resolve all lazy header directives to header files.
+ ModMap.resolveHeaderDirectives(Module);
+
+ // If any headers are missing, we can't build this module. In most cases,
+ // diagnostics for this should have already been produced; we only get here
+ // if explicit stat information was provided.
+ // FIXME: If the name resolves to a file with different stat information,
+ // produce a better diagnostic.
+ if (!Module->MissingHeaders.empty()) {
+ auto &MissingHeader = Module->MissingHeaders.front();
+ Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
+ << MissingHeader.IsUmbrella << MissingHeader.FileName;
+ return std::error_code();
+ }
+
// Add includes for each of these headers.
for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
for (Module::Header &H : Module->Headers[HK]) {
@@ -367,7 +381,7 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
SubEnd = Module->submodule_end();
Sub != SubEnd; ++Sub)
if (std::error_code Err = collectModuleHeaderIncludes(
- LangOpts, FileMgr, ModMap, *Sub, Includes))
+ LangOpts, FileMgr, Diag, ModMap, *Sub, Includes))
return Err;
return std::error_code();
@@ -494,7 +508,7 @@ getInputBufferForModule(CompilerInstance &CI, Module *M) {
addHeaderInclude(UmbrellaHeader.NameAsWritten, HeaderContents,
CI.getLangOpts(), M->IsExternC);
Err = collectModuleHeaderIncludes(
- CI.getLangOpts(), FileMgr,
+ CI.getLangOpts(), FileMgr, CI.getDiagnostics(),
CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), M,
HeaderContents);
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index baaf93b167bc..89ac385ca45d 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -546,8 +546,11 @@ void PrintPreprocessedAction::ExecuteAction() {
// module itself before switching to the input buffer.
auto &Input = getCurrentInput();
if (Input.getKind().getFormat() == InputKind::ModuleMap) {
- if (Input.isFile())
- (*OS) << "# 1 \"" << Input.getFile() << "\"\n";
+ if (Input.isFile()) {
+ (*OS) << "# 1 \"";
+ OS->write_escaped(Input.getFile());
+ (*OS) << "\"\n";
+ }
// FIXME: Include additional information here so that we don't need the
// original source files to exist on disk.
getCurrentModule()->print(*OS);
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index d50fb6d788a4..1d7c8a0c871b 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -221,6 +221,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
case llvm::Triple::Win32:
if (triple.getEnvironment() != llvm::Triple::Cygnus)
break;
+ LLVM_FALLTHROUGH;
default:
// FIXME: temporary hack: hard-coded paths.
AddPath("/usr/local/include", System, false);
@@ -343,6 +344,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
AddPath(BaseSDKPath + "/target/include", System, false);
if (triple.isPS4CPU())
AddPath(BaseSDKPath + "/target/include_common", System, false);
+ LLVM_FALLTHROUGH;
}
default:
AddPath("/usr/include", ExternCSystem, false);
diff --git a/lib/Frontend/Rewrite/FrontendActions.cpp b/lib/Frontend/Rewrite/FrontendActions.cpp
index 8c5eb161b5ab..b2dfd2941130 100644
--- a/lib/Frontend/Rewrite/FrontendActions.cpp
+++ b/lib/Frontend/Rewrite/FrontendActions.cpp
@@ -200,8 +200,11 @@ void RewriteIncludesAction::ExecuteAction() {
// module itself before switching to the input buffer.
auto &Input = getCurrentInput();
if (Input.getKind().getFormat() == InputKind::ModuleMap) {
- if (Input.isFile())
- (*OS) << "# 1 \"" << Input.getFile() << "\"\n";
+ if (Input.isFile()) {
+ (*OS) << "# 1 \"";
+ OS->write_escaped(Input.getFile());
+ (*OS) << "\"\n";
+ }
// FIXME: Include additional information here so that we don't need the
// original source files to exist on disk.
getCurrentModule()->print(*OS);
diff --git a/lib/Frontend/Rewrite/InclusionRewriter.cpp b/lib/Frontend/Rewrite/InclusionRewriter.cpp
index d45cbc01df8c..3564cebba8a8 100644
--- a/lib/Frontend/Rewrite/InclusionRewriter.cpp
+++ b/lib/Frontend/Rewrite/InclusionRewriter.cpp
@@ -177,7 +177,9 @@ void InclusionRewriter::FileSkipped(const FileEntry &/*SkippedFile*/,
/// directives. It does not say whether the file has been included, but it
/// provides more information about the directive (hash location instead
/// of location inside the included file). It is assumed that the matching
-/// FileChanged() or FileSkipped() is called after this.
+/// FileChanged() or FileSkipped() is called after this (or neither is
+/// called if this #include results in an error or does not textually include
+/// anything).
void InclusionRewriter::InclusionDirective(SourceLocation HashLoc,
const Token &/*IncludeTok*/,
StringRef /*FileName*/,
@@ -187,9 +189,6 @@ void InclusionRewriter::InclusionDirective(SourceLocation HashLoc,
StringRef /*SearchPath*/,
StringRef /*RelativePath*/,
const Module *Imported) {
- assert(LastInclusionLocation.isInvalid() &&
- "Another inclusion directive was found before the previous one "
- "was processed");
if (Imported) {
auto P = ModuleIncludes.insert(
std::make_pair(HashLoc.getRawEncoding(), Imported));
diff --git a/lib/Frontend/SerializedDiagnosticReader.cpp b/lib/Frontend/SerializedDiagnosticReader.cpp
index c4461d452e7b..8a8161488f44 100644
--- a/lib/Frontend/SerializedDiagnosticReader.cpp
+++ b/lib/Frontend/SerializedDiagnosticReader.cpp
@@ -125,6 +125,7 @@ SerializedDiagnosticReader::readMetaBlock(llvm::BitstreamCursor &Stream) {
case Cursor::BlockBegin:
if (Stream.SkipBlock())
return SDError::MalformedMetadataBlock;
+ LLVM_FALLTHROUGH;
case Cursor::BlockEnd:
if (!VersionChecked)
return SDError::MissingVersion;
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index 9084bc352f76..1ebcc0a1c657 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -1114,6 +1114,8 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
auto TryEnterImported = [&](void) -> bool {
if (!ModulesEnabled)
return false;
+ // Ensure FileInfo bits are up to date.
+ ModMap.resolveHeaderDirectives(File);
// Modules with builtins are special; multiple modules use builtins as
// modular headers, example:
//
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index f5a35e97d6e1..447ff212f06e 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -2498,6 +2498,7 @@ void Lexer::ReadToEndOfLine(SmallVectorImpl<char> *Result) {
break;
}
// FALL THROUGH.
+ LLVM_FALLTHROUGH;
case '\r':
case '\n':
// Okay, we found the end of the line. First, back up past the \0, \r, \n.
@@ -3247,6 +3248,7 @@ LexNextToken:
return LexCharConstant(Result, ConsumeChar(CurPtr, SizeTmp, Result),
tok::wide_char_constant);
// FALL THROUGH, treating L like the start of an identifier.
+ LLVM_FALLTHROUGH;
// C99 6.4.2: Identifiers.
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index 1e2cbde825f5..a598a467816a 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -456,10 +456,17 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
// Finally, we write the bytes into ResultBuf.
ResultBuf += bytesToWrite;
switch (bytesToWrite) { // note: everything falls through.
- case 4: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
- case 3: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
- case 2: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
- case 1: *--ResultBuf = (UTF8) (UcnVal | firstByteMark[bytesToWrite]);
+ case 4:
+ *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
+ LLVM_FALLTHROUGH;
+ case 3:
+ *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
+ LLVM_FALLTHROUGH;
+ case 2:
+ *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
+ LLVM_FALLTHROUGH;
+ case 1:
+ *--ResultBuf = (UTF8) (UcnVal | firstByteMark[bytesToWrite]);
}
// Update the buffer.
ResultBuf += bytesToWrite;
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 8c57931e47b7..018d59e5e871 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -36,6 +36,37 @@
#endif
using namespace clang;
+Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) {
+ switch ((int)Role) {
+ default: llvm_unreachable("unknown header role");
+ case NormalHeader:
+ return Module::HK_Normal;
+ case PrivateHeader:
+ return Module::HK_Private;
+ case TextualHeader:
+ return Module::HK_Textual;
+ case PrivateHeader | TextualHeader:
+ return Module::HK_PrivateTextual;
+ }
+}
+
+ModuleMap::ModuleHeaderRole
+ModuleMap::headerKindToRole(Module::HeaderKind Kind) {
+ switch ((int)Kind) {
+ case Module::HK_Normal:
+ return NormalHeader;
+ case Module::HK_Private:
+ return PrivateHeader;
+ case Module::HK_Textual:
+ return TextualHeader;
+ case Module::HK_PrivateTextual:
+ return ModuleHeaderRole(PrivateHeader | TextualHeader);
+ case Module::HK_Excluded:
+ llvm_unreachable("unexpected header kind");
+ }
+ llvm_unreachable("unknown header kind");
+}
+
Module::ExportDecl
ModuleMap::resolveExport(Module *Mod,
const Module::UnresolvedExportDecl &Unresolved,
@@ -104,12 +135,22 @@ static void appendSubframeworkPaths(Module *Mod,
}
const FileEntry *
-ModuleMap::resolveHeader(Module *M, Module::UnresolvedHeaderDirective Header,
- SmallVectorImpl<char> &RelativePathName) {
+ModuleMap::findHeader(Module *M,
+ const Module::UnresolvedHeaderDirective &Header,
+ SmallVectorImpl<char> &RelativePathName) {
+ auto GetFile = [&](StringRef Filename) -> const FileEntry * {
+ auto *File = SourceMgr.getFileManager().getFile(Filename);
+ if (!File ||
+ (Header.Size && File->getSize() != *Header.Size) ||
+ (Header.ModTime && File->getModificationTime() != *Header.ModTime))
+ return nullptr;
+ return File;
+ };
+
if (llvm::sys::path::is_absolute(Header.FileName)) {
RelativePathName.clear();
RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
- return SourceMgr.getFileManager().getFile(Header.FileName);
+ return GetFile(Header.FileName);
}
// Search for the header file within the module's home directory.
@@ -124,7 +165,7 @@ ModuleMap::resolveHeader(Module *M, Module::UnresolvedHeaderDirective Header,
// Check whether this file is in the public headers.
llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
llvm::sys::path::append(FullPathName, RelativePathName);
- if (auto *File = SourceMgr.getFileManager().getFile(FullPathName))
+ if (auto *File = GetFile(FullPathName))
return File;
// Check whether this file is in the private headers.
@@ -141,31 +182,74 @@ ModuleMap::resolveHeader(Module *M, Module::UnresolvedHeaderDirective Header,
llvm::sys::path::append(RelativePathName, "PrivateHeaders",
Header.FileName);
llvm::sys::path::append(FullPathName, RelativePathName);
- return SourceMgr.getFileManager().getFile(FullPathName);
+ return GetFile(FullPathName);
}
// Lookup for normal headers.
llvm::sys::path::append(RelativePathName, Header.FileName);
llvm::sys::path::append(FullPathName, RelativePathName);
- return SourceMgr.getFileManager().getFile(FullPathName);
+ return GetFile(FullPathName);
}
-const FileEntry *
-ModuleMap::resolveAsBuiltinHeader(Module *M,
- Module::UnresolvedHeaderDirective Header,
- SmallVectorImpl<char> &BuiltinPathName) {
- if (llvm::sys::path::is_absolute(Header.FileName) || M->isPartOfFramework() ||
- !M->IsSystem || Header.IsUmbrella || !BuiltinIncludeDir ||
- BuiltinIncludeDir == M->Directory || !isBuiltinHeader(Header.FileName))
- return nullptr;
+void ModuleMap::resolveHeader(Module *Mod,
+ const Module::UnresolvedHeaderDirective &Header) {
+ SmallString<128> RelativePathName;
+ if (const FileEntry *File = findHeader(Mod, Header, RelativePathName)) {
+ if (Header.IsUmbrella) {
+ const DirectoryEntry *UmbrellaDir = File->getDir();
+ if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
+ Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
+ << UmbrellaMod->getFullModuleName();
+ else
+ // Record this umbrella header.
+ setUmbrellaHeader(Mod, File, RelativePathName.str());
+ } else {
+ Module::Header H = {RelativePathName.str(), File};
+ if (Header.Kind == Module::HK_Excluded)
+ excludeHeader(Mod, H);
+ else
+ addHeader(Mod, H, headerKindToRole(Header.Kind));
+ }
+ } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {
+ // There's a builtin header but no corresponding on-disk header. Assume
+ // this was supposed to modularize the builtin header alone.
+ } else if (Header.Kind == Module::HK_Excluded) {
+ // Ignore missing excluded header files. They're optional anyway.
+ } else {
+ // If we find a module that has a missing header, we mark this module as
+ // unavailable and store the header directive for displaying diagnostics.
+ Mod->MissingHeaders.push_back(Header);
+ // A missing header with stat information doesn't make the module
+ // unavailable; this keeps our behavior consistent as headers are lazily
+ // resolved. (Such a module still can't be built though, except from
+ // preprocessed source.)
+ if (!Header.Size && !Header.ModTime)
+ Mod->markUnavailable();
+ }
+}
+
+bool ModuleMap::resolveAsBuiltinHeader(
+ Module *Mod, const Module::UnresolvedHeaderDirective &Header) {
+ if (Header.Kind == Module::HK_Excluded ||
+ llvm::sys::path::is_absolute(Header.FileName) ||
+ Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
+ !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
+ !isBuiltinHeader(Header.FileName))
+ return false;
// This is a system module with a top-level header. This header
// may have a counterpart (or replacement) in the set of headers
// supplied by Clang. Find that builtin header.
- llvm::sys::path::append(BuiltinPathName, BuiltinIncludeDir->getName(),
- Header.FileName);
- return SourceMgr.getFileManager().getFile(
- StringRef(BuiltinPathName.data(), BuiltinPathName.size()));
+ SmallString<128> Path;
+ llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
+ auto *File = SourceMgr.getFileManager().getFile(Path);
+ if (!File)
+ return false;
+
+ auto Role = headerKindToRole(Header.Kind);
+ Module::Header H = {Path.str(), File};
+ addHeader(Mod, H, Role);
+ return true;
}
ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
@@ -246,6 +330,7 @@ bool ModuleMap::isBuiltinHeader(StringRef FileName) {
ModuleMap::HeadersMap::iterator
ModuleMap::findKnownHeader(const FileEntry *File) {
+ resolveHeaderDirectives(File);
HeadersMap::iterator Known = Headers.find(File);
if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
@@ -328,8 +413,10 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
return;
- if (RequestingModule)
+ if (RequestingModule) {
resolveUses(RequestingModule, /*Complain=*/false);
+ resolveHeaderDirectives(RequestingModule);
+ }
bool Excluded = false;
Module *Private = nullptr;
@@ -511,6 +598,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
ArrayRef<ModuleMap::KnownHeader>
ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
+ resolveHeaderDirectives(File);
auto It = Headers.find(File);
if (It == Headers.end())
return None;
@@ -524,6 +612,7 @@ bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
bool
ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
const Module *RequestingModule) const {
+ resolveHeaderDirectives(Header);
HeadersMap::const_iterator Known = Headers.find(Header);
if (Known != Headers.end()) {
for (SmallVectorImpl<KnownHeader>::const_iterator
@@ -896,20 +985,65 @@ void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
UmbrellaDirs[UmbrellaDir] = Mod;
}
-static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
- switch ((int)Role) {
- default: llvm_unreachable("unknown header role");
- case ModuleMap::NormalHeader:
- return Module::HK_Normal;
- case ModuleMap::PrivateHeader:
- return Module::HK_Private;
- case ModuleMap::TextualHeader:
- return Module::HK_Textual;
- case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
- return Module::HK_PrivateTextual;
+void ModuleMap::addUnresolvedHeader(Module *Mod,
+ Module::UnresolvedHeaderDirective Header) {
+ // If there is a builtin counterpart to this file, add it now so it can
+ // wrap the system header.
+ if (resolveAsBuiltinHeader(Mod, Header)) {
+ // If we have both a builtin and system version of the file, the
+ // builtin version may want to inject macros into the system header, so
+ // force the system header to be treated as a textual header in this
+ // case.
+ Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole(
+ headerKindToRole(Header.Kind) | ModuleMap::TextualHeader));
+ Header.HasBuiltinHeader = true;
+ }
+
+ // If possible, don't stat the header until we need to. This requires the
+ // user to have provided us with some stat information about the file.
+ // FIXME: Add support for lazily stat'ing umbrella headers and excluded
+ // headers.
+ if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&
+ Header.Kind != Module::HK_Excluded) {
+ // We expect more variation in mtime than size, so if we're given both,
+ // use the mtime as the key.
+ if (Header.ModTime)
+ LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
+ else
+ LazyHeadersBySize[*Header.Size].push_back(Mod);
+ Mod->UnresolvedHeaders.push_back(Header);
+ return;
+ }
+
+ // We don't have stat information or can't defer looking this file up.
+ // Perform the lookup now.
+ resolveHeader(Mod, Header);
+}
+
+void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const {
+ auto BySize = LazyHeadersBySize.find(File->getSize());
+ if (BySize != LazyHeadersBySize.end()) {
+ for (auto *M : BySize->second)
+ resolveHeaderDirectives(M);
+ LazyHeadersBySize.erase(BySize);
+ }
+
+ auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
+ if (ByModTime != LazyHeadersByModTime.end()) {
+ for (auto *M : ByModTime->second)
+ resolveHeaderDirectives(M);
+ LazyHeadersByModTime.erase(ByModTime);
}
}
+void ModuleMap::resolveHeaderDirectives(Module *Mod) const {
+ for (auto &Header : Mod->UnresolvedHeaders)
+ // This operation is logically const; we're just changing how we represent
+ // the header information for this file.
+ const_cast<ModuleMap*>(this)->resolveHeader(Mod, Header);
+ Mod->UnresolvedHeaders.clear();
+}
+
void ModuleMap::addHeader(Module *Mod, Module::Header Header,
ModuleHeaderRole Role, bool Imported) {
KnownHeader KH(Mod, Role);
@@ -1063,6 +1197,7 @@ namespace clang {
RequiresKeyword,
Star,
StringLiteral,
+ IntegerLiteral,
TextualKeyword,
LBrace,
RBrace,
@@ -1072,7 +1207,12 @@ namespace clang {
unsigned Location;
unsigned StringLength;
- const char *StringData;
+ union {
+ // If Kind != IntegerLiteral.
+ const char *StringData;
+ // If Kind == IntegerLiteral.
+ uint64_t IntegerValue;
+ };
void clear() {
Kind = EndOfFile;
@@ -1086,9 +1226,14 @@ namespace clang {
SourceLocation getLocation() const {
return SourceLocation::getFromRawEncoding(Location);
}
+
+ uint64_t getInteger() const {
+ return Kind == IntegerLiteral ? IntegerValue : 0;
+ }
StringRef getString() const {
- return StringRef(StringData, StringLength);
+ return Kind == IntegerLiteral ? StringRef()
+ : StringRef(StringData, StringLength);
}
};
@@ -1278,6 +1423,25 @@ retry:
Tok.StringLength = Length;
break;
}
+
+ case tok::numeric_constant: {
+ // We don't support any suffixes or other complications.
+ SmallString<32> SpellingBuffer;
+ SpellingBuffer.resize(LToken.getLength() + 1);
+ const char *Start = SpellingBuffer.data();
+ unsigned Length =
+ Lexer::getSpelling(LToken, Start, SourceMgr, L.getLangOpts());
+ uint64_t Value;
+ if (StringRef(Start, Length).getAsInteger(0, Value)) {
+ Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
+ HadError = true;
+ goto retry;
+ }
+
+ Tok.Kind = MMToken::IntegerLiteral;
+ Tok.IntegerValue = Value;
+ break;
+ }
case tok::comment:
goto retry;
@@ -1904,6 +2068,9 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
Header.FileName = Tok.getString();
Header.FileNameLoc = consumeToken();
Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
+ Header.Kind =
+ (LeadingToken == MMToken::ExcludeKeyword ? Module::HK_Excluded
+ : Map.headerRoleToKind(Role));
// Check whether we already have an umbrella.
if (Header.IsUmbrella && ActiveModule->Umbrella) {
@@ -1913,64 +2080,62 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
return;
}
- // Look for this file by name if we don't have any stat information.
- SmallString<128> RelativePathName, BuiltinPathName;
- const FileEntry *File =
- Map.resolveHeader(ActiveModule, Header, RelativePathName);
- const FileEntry *BuiltinFile =
- Map.resolveAsBuiltinHeader(ActiveModule, Header, BuiltinPathName);
+ // If we were given stat information, parse it so we can skip looking for
+ // the file.
+ if (Tok.is(MMToken::LBrace)) {
+ SourceLocation LBraceLoc = consumeToken();
+
+ while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) {
+ enum Attribute { Size, ModTime, Unknown };
+ StringRef Str = Tok.getString();
+ SourceLocation Loc = consumeToken();
+ switch (llvm::StringSwitch<Attribute>(Str)
+ .Case("size", Size)
+ .Case("mtime", ModTime)
+ .Default(Unknown)) {
+ case Size:
+ if (Header.Size)
+ Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
+ if (!Tok.is(MMToken::IntegerLiteral)) {
+ Diags.Report(Tok.getLocation(),
+ diag::err_mmap_invalid_header_attribute_value) << Str;
+ skipUntil(MMToken::RBrace);
+ break;
+ }
+ Header.Size = Tok.getInteger();
+ consumeToken();
+ break;
- // If Clang supplies this header but the underlying system does not,
- // just silently swap in our builtin version. Otherwise, we'll end
- // up adding both (later).
- if (BuiltinFile && !File) {
- RelativePathName = BuiltinPathName;
- File = BuiltinFile;
- BuiltinFile = nullptr;
- }
+ case ModTime:
+ if (Header.ModTime)
+ Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
+ if (!Tok.is(MMToken::IntegerLiteral)) {
+ Diags.Report(Tok.getLocation(),
+ diag::err_mmap_invalid_header_attribute_value) << Str;
+ skipUntil(MMToken::RBrace);
+ break;
+ }
+ Header.ModTime = Tok.getInteger();
+ consumeToken();
+ break;
- // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
- // Come up with a lazy way to do this.
- if (File) {
- if (Header.IsUmbrella) {
- const DirectoryEntry *UmbrellaDir = File->getDir();
- if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
- Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
- << UmbrellaModule->getFullModuleName();
- HadError = true;
- } else {
- // Record this umbrella header.
- Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
- }
- } else if (LeadingToken == MMToken::ExcludeKeyword) {
- Module::Header H = {RelativePathName.str(), File};
- Map.excludeHeader(ActiveModule, H);
- } else {
- // If there is a builtin counterpart to this file, add it now so it can
- // wrap the system header.
- if (BuiltinFile) {
- Module::Header H = { BuiltinPathName.str(), BuiltinFile };
- Map.addHeader(ActiveModule, H, Role);
-
- // If we have both a builtin and system version of the file, the
- // builtin version may want to inject macros into the system header, so
- // force the system header to be treated as a textual header in this
- // case.
- Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
+ case Unknown:
+ Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
+ skipUntil(MMToken::RBrace);
+ break;
}
-
- // Record this header.
- Module::Header H = { RelativePathName.str(), File };
- Map.addHeader(ActiveModule, H, Role);
}
- } else if (LeadingToken != MMToken::ExcludeKeyword) {
- // Ignore excluded header files. They're optional anyway.
- // If we find a module that has a missing header, we mark this module as
- // unavailable and store the header directive for displaying diagnostics.
- ActiveModule->markUnavailable();
- ActiveModule->MissingHeaders.push_back(Header);
+ if (Tok.is(MMToken::RBrace))
+ consumeToken();
+ else {
+ Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
+ Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
+ HadError = true;
+ }
}
+
+ Map.addUnresolvedHeader(ActiveModule, std::move(Header));
}
static int compareModuleHeaders(const Module::Header *A,
@@ -2521,6 +2686,7 @@ bool ModuleMapParser::parseModuleMapFile() {
case MMToken::RequiresKeyword:
case MMToken::Star:
case MMToken::StringLiteral:
+ case MMToken::IntegerLiteral:
case MMToken::TextualKeyword:
case MMToken::UmbrellaKeyword:
case MMToken::UseKeyword:
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 8b5877934f61..2d3ad690987e 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -689,6 +689,8 @@ Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
while (!Loc.isInvalid() && !SM.isInMainFile(Loc)) {
auto ID = SM.getFileID(SM.getExpansionLoc(Loc));
auto *FE = SM.getFileEntryForID(ID);
+ if (!FE)
+ break;
bool InTextualHeader = false;
for (auto Header : HeaderInfo.getModuleMap().findAllModulesForHeader(FE)) {
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index b785f5f7d2e6..22696a957a10 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2552,6 +2552,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
}
}
// Fall through.
+ LLVM_FALLTHROUGH;
}
case tok::comma:
case tok::equal:
@@ -3678,6 +3679,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
isInvalid = true;
break;
};
+ LLVM_FALLTHROUGH;
case tok::kw___private:
case tok::kw___global:
case tok::kw___local:
@@ -5045,6 +5047,7 @@ void Parser::ParseTypeQualifierListOpt(
if (TryKeywordIdentFallback(false))
continue;
}
+ LLVM_FALLTHROUGH;
case tok::kw___sptr:
case tok::kw___w64:
case tok::kw___ptr64:
@@ -5094,6 +5097,7 @@ void Parser::ParseTypeQualifierListOpt(
continue; // do *not* consume the next token!
}
// otherwise, FALL THROUGH!
+ LLVM_FALLTHROUGH;
default:
DoneWithTypeQuals:
// If this is not a type-qualifier token, we're done reading type
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 527d45b1e203..4c117f531ef1 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -4215,6 +4215,7 @@ void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
<< Result.IsIfExists;
// Fall through to skip.
+ LLVM_FALLTHROUGH;
case IEB_Skip:
Braces.skipToEnd();
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index c739a50f0b38..aacb00e8be64 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1314,6 +1314,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
}
// Fall through to treat the template-id as an id-expression.
+ LLVM_FALLTHROUGH;
}
case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
@@ -1484,9 +1485,9 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
nullptr, LHS.get());
break;
}
-
// Fall through; this isn't a message send.
-
+ LLVM_FALLTHROUGH;
+
default: // Not a postfix-expression suffix.
return LHS;
case tok::l_square: { // postfix-expression: p-e '[' expression ']'
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
index f48d01e0f630..90f3561cb963 100644
--- a/lib/Parse/ParseInit.cpp
+++ b/lib/Parse/ParseInit.cpp
@@ -501,7 +501,8 @@ bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
<< Result.IsIfExists;
// Fall through to skip.
-
+ LLVM_FALLTHROUGH;
+
case IEB_Skip:
Braces.skipToEnd();
return false;
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index b925dd7053dc..2e5e36242ed5 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -192,6 +192,7 @@ static DeclarationName parseOpenMPReductionId(Parser &P) {
case tok::identifier: // identifier
if (!WithOperator)
break;
+ LLVM_FALLTHROUGH;
default:
P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
@@ -869,6 +870,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
// pseudo-clause OMPFlushClause.
PP.EnterToken(Tok);
}
+ LLVM_FALLTHROUGH;
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
@@ -883,6 +885,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
}
HasAssociatedStatement = false;
// Fall through for further analysis.
+ LLVM_FALLTHROUGH;
case OMPD_parallel:
case OMPD_simd:
case OMPD_for:
@@ -1184,6 +1187,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
ErrorFound = true;
}
+ LLVM_FALLTHROUGH;
case OMPC_if:
Clause = ParseOpenMPSingleExprWithArgClause(CKind);
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index d147ab0a5674..b1fbb20c721b 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -203,6 +203,7 @@ Retry:
}
// Fall through
+ LLVM_FALLTHROUGH;
}
default: {
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 0d783131dd6e..d6684c39aa73 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -1450,6 +1450,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
return TPResult::False;
}
// If that succeeded, fallthrough into the generic simple-type-id case.
+ LLVM_FALLTHROUGH;
// The ambiguity resides in a simple-type-specifier/typename-specifier
// followed by a '('. The '(' could either be the start of:
@@ -1492,6 +1493,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
return TPResult::True;
}
+ LLVM_FALLTHROUGH;
case tok::kw_char:
case tok::kw_wchar_t:
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 4fe038d271ad..af29b5e9c673 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -763,6 +763,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
}
// This must be 'export template'. Parse it so we can diagnose our lack
// of support.
+ LLVM_FALLTHROUGH;
case tok::kw_using:
case tok::kw_namespace:
case tok::kw_typedef:
@@ -1875,6 +1876,7 @@ bool Parser::isTokenEqualOrEqualTypo() {
Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal)
<< Kind
<< FixItHint::CreateReplacement(SourceRange(Tok.getLocation()), "=");
+ LLVM_FALLTHROUGH;
case tok::equal:
return true;
}
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index 27bb976a6e1a..9e307f31be11 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -409,6 +409,7 @@ void html::SyntaxHighlight(Rewriter &R, FileID FID, const Preprocessor &PP) {
++TokOffs;
--TokLen;
// FALL THROUGH to chop the 8
+ LLVM_FALLTHROUGH;
case tok::wide_string_literal:
case tok::utf16_string_literal:
case tok::utf32_string_literal:
diff --git a/lib/Sema/CoroutineStmtBuilder.h b/lib/Sema/CoroutineStmtBuilder.h
index 954a0f100ebb..33a368d92ff4 100644
--- a/lib/Sema/CoroutineStmtBuilder.h
+++ b/lib/Sema/CoroutineStmtBuilder.h
@@ -51,6 +51,9 @@ public:
/// name lookup.
bool buildDependentStatements();
+ /// \brief Build just parameter moves. To use for rebuilding in TreeTransform.
+ bool buildParameterMoves();
+
bool isInvalid() const { return !this->IsValid; }
private:
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 8fb2f4139236..224d9e9a0ee2 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1866,6 +1866,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
case Sema::PCC_Condition:
AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
// Fall through: conditions and statements can have expressions.
+ LLVM_FALLTHROUGH;
case Sema::PCC_ParenthesizedExpression:
if (SemaRef.getLangOpts().ObjCAutoRefCount &&
@@ -1895,6 +1896,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Results.AddResult(Result(Builder.TakeString()));
}
// Fall through
+ LLVM_FALLTHROUGH;
case Sema::PCC_Expression: {
if (SemaRef.getLangOpts().CPlusPlus) {
diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp
index 8a548c0ab861..06ae66076e8a 100644
--- a/lib/Sema/SemaCoroutine.cpp
+++ b/lib/Sema/SemaCoroutine.cpp
@@ -832,6 +832,12 @@ bool CoroutineStmtBuilder::buildDependentStatements() {
return this->IsValid;
}
+bool CoroutineStmtBuilder::buildParameterMoves() {
+ assert(this->IsValid && "coroutine already invalid");
+ assert(this->ParamMoves.empty() && "param moves already built");
+ return this->IsValid = makeParamMoves();
+}
+
bool CoroutineStmtBuilder::makePromiseStmt() {
// Form a declaration statement for the promise declaration, so that AST
// visitors can more easily find it.
@@ -1244,14 +1250,13 @@ static Expr *castForMoving(Sema &S, Expr *E, QualType T = QualType()) {
.get();
}
+
/// \brief Build a variable declaration for move parameter.
static VarDecl *buildVarDecl(Sema &S, SourceLocation Loc, QualType Type,
- StringRef Name) {
- DeclContext *DC = S.CurContext;
- IdentifierInfo *II = &S.PP.getIdentifierTable().get(Name);
+ IdentifierInfo *II) {
TypeSourceInfo *TInfo = S.Context.getTrivialTypeSourceInfo(Type, Loc);
VarDecl *Decl =
- VarDecl::Create(S.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
+ VarDecl::Create(S.Context, S.CurContext, Loc, Loc, II, Type, TInfo, SC_None);
Decl->setImplicit();
return Decl;
}
@@ -1264,9 +1269,6 @@ bool CoroutineStmtBuilder::makeParamMoves() {
// No need to copy scalars, llvm will take care of them.
if (Ty->getAsCXXRecordDecl()) {
- if (!paramDecl->getIdentifier())
- continue;
-
ExprResult ParamRef =
S.BuildDeclRefExpr(paramDecl, paramDecl->getType(),
ExprValueKind::VK_LValue, Loc); // FIXME: scope?
@@ -1275,8 +1277,7 @@ bool CoroutineStmtBuilder::makeParamMoves() {
Expr *RCast = castForMoving(S, ParamRef.get());
- auto D = buildVarDecl(S, Loc, Ty, paramDecl->getIdentifier()->getName());
-
+ auto D = buildVarDecl(S, Loc, Ty, paramDecl->getIdentifier());
S.AddInitializerToDecl(D, RCast, /*DirectInit=*/true);
// Convert decl to a statement.
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index ea1f7526a832..ef6dfaa2f28c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -404,6 +404,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
}
}
// If typo correction failed or was not performed, fall through
+ LLVM_FALLTHROUGH;
case LookupResult::FoundOverloaded:
case LookupResult::FoundUnresolvedValue:
Result.suppressDiagnostics();
@@ -6160,7 +6161,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
QualType NR = R;
while (NR->isPointerType()) {
if (NR->isFunctionPointerType()) {
- Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer_variable);
+ Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer);
D.setInvalidType();
break;
}
@@ -12309,7 +12310,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
TypeSourceInfo *TI = FD->getTypeSourceInfo();
TypeLoc TL = TI->getTypeLoc();
FunctionTypeLoc FTL = TL.getAsAdjusted<FunctionTypeLoc>();
- Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 1;
+ Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 2;
}
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index d9528be2d383..acacdc263c08 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -14639,6 +14639,7 @@ bool Sema::checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method) {
case EST_ComputedNoexcept:
if (!Finder.TraverseStmt(Proto->getNoexceptExpr()))
return true;
+ LLVM_FALLTHROUGH;
case EST_Dynamic:
for (const auto &E : Proto->exceptions()) {
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index b1a07ffb7206..4e7fb19b282b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -11462,6 +11462,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
break;
case BO_And:
checkObjCPointerIntrospection(*this, LHS, RHS, OpLoc);
+ LLVM_FALLTHROUGH;
case BO_Xor:
case BO_Or:
ResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc, Opc);
@@ -11504,6 +11505,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
case BO_AndAssign:
case BO_OrAssign: // fallthrough
DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc);
+ LLVM_FALLTHROUGH;
case BO_XorAssign:
CompResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc, Opc);
CompLHSTy = CompResultTy;
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 4b1d7fd3cf23..a6239283b47b 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -337,6 +337,7 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC,
return nullptr;
}
// Fall through to get the current context.
+ LLVM_FALLTHROUGH;
case DataMember:
// -- the in-class initializers of class members
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index c97da740e4d2..1d32e5796812 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -2594,6 +2594,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
for (const auto &Arg : Proto->param_types())
Queue.push_back(Arg.getTypePtr());
// fallthrough
+ LLVM_FALLTHROUGH;
}
case Type::FunctionNoProto: {
const FunctionType *FnType = cast<FunctionType>(T);
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 33a8f9c4afa3..dcb2c11c73c7 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -1288,17 +1288,22 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
}
namespace {
+ // Use SetVector since the diagnostic cares about the ordering of the Decl's.
+ using DeclSetVector =
+ llvm::SetVector<VarDecl *, llvm::SmallVector<VarDecl *, 8>,
+ llvm::SmallPtrSet<VarDecl *, 8>>;
+
// This visitor will traverse a conditional statement and store all
// the evaluated decls into a vector. Simple is set to true if none
// of the excluded constructs are used.
class DeclExtractor : public EvaluatedExprVisitor<DeclExtractor> {
- llvm::SmallPtrSetImpl<VarDecl*> &Decls;
+ DeclSetVector &Decls;
SmallVectorImpl<SourceRange> &Ranges;
bool Simple;
public:
typedef EvaluatedExprVisitor<DeclExtractor> Inherited;
- DeclExtractor(Sema &S, llvm::SmallPtrSetImpl<VarDecl*> &Decls,
+ DeclExtractor(Sema &S, DeclSetVector &Decls,
SmallVectorImpl<SourceRange> &Ranges) :
Inherited(S.Context),
Decls(Decls),
@@ -1370,14 +1375,13 @@ namespace {
// DeclMatcher checks to see if the decls are used in a non-evaluated
// context.
class DeclMatcher : public EvaluatedExprVisitor<DeclMatcher> {
- llvm::SmallPtrSetImpl<VarDecl*> &Decls;
+ DeclSetVector &Decls;
bool FoundDecl;
public:
typedef EvaluatedExprVisitor<DeclMatcher> Inherited;
- DeclMatcher(Sema &S, llvm::SmallPtrSetImpl<VarDecl*> &Decls,
- Stmt *Statement) :
+ DeclMatcher(Sema &S, DeclSetVector &Decls, Stmt *Statement) :
Inherited(S.Context), Decls(Decls), FoundDecl(false) {
if (!Statement) return;
@@ -1459,7 +1463,7 @@ namespace {
return;
PartialDiagnostic PDiag = S.PDiag(diag::warn_variables_not_in_loop_body);
- llvm::SmallPtrSet<VarDecl*, 8> Decls;
+ DeclSetVector Decls;
SmallVector<SourceRange, 10> Ranges;
DeclExtractor DE(S, Decls, Ranges);
DE.Visit(Second);
@@ -1471,11 +1475,9 @@ namespace {
if (Decls.size() == 0) return;
// Don't warn on volatile, static, or global variables.
- for (llvm::SmallPtrSetImpl<VarDecl*>::iterator I = Decls.begin(),
- E = Decls.end();
- I != E; ++I)
- if ((*I)->getType().isVolatileQualified() ||
- (*I)->hasGlobalStorage()) return;
+ for (auto *VD : Decls)
+ if (VD->getType().isVolatileQualified() || VD->hasGlobalStorage())
+ return;
if (DeclMatcher(S, Decls, Second).FoundDeclInUse() ||
DeclMatcher(S, Decls, Third).FoundDeclInUse() ||
@@ -1483,25 +1485,16 @@ namespace {
return;
// Load decl names into diagnostic.
- if (Decls.size() > 4)
+ if (Decls.size() > 4) {
PDiag << 0;
- else {
- PDiag << Decls.size();
- for (llvm::SmallPtrSetImpl<VarDecl*>::iterator I = Decls.begin(),
- E = Decls.end();
- I != E; ++I)
- PDiag << (*I)->getDeclName();
- }
-
- // Load SourceRanges into diagnostic if there is room.
- // Otherwise, load the SourceRange of the conditional expression.
- if (Ranges.size() <= PartialDiagnostic::MaxArguments)
- for (SmallVectorImpl<SourceRange>::iterator I = Ranges.begin(),
- E = Ranges.end();
- I != E; ++I)
- PDiag << *I;
- else
- PDiag << Second->getSourceRange();
+ } else {
+ PDiag << (unsigned)Decls.size();
+ for (auto *VD : Decls)
+ PDiag << VD->getDeclName();
+ }
+
+ for (auto Range : Ranges)
+ PDiag << Range;
S.Diag(Ranges.begin()->getBegin(), PDiag);
}
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index 5f91cac14a38..c182b35bfad4 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -277,6 +277,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
if (RequireCompleteType(OutputExpr->getLocStart(), Exprs[i]->getType(),
diag::err_dereference_incomplete_type))
return StmtError();
+ LLVM_FALLTHROUGH;
default:
return StmtError(Diag(OutputExpr->getLocStart(),
diag::err_asm_invalid_lvalue_in_output)
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index ebdf6dd57fc5..75b69ae04f56 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -2383,7 +2383,8 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments(
bool HasDefaultArg = false;
TemplateDecl *TD = dyn_cast<TemplateDecl>(Template);
if (!TD) {
- assert(isa<ClassTemplatePartialSpecializationDecl>(Template));
+ assert(isa<ClassTemplatePartialSpecializationDecl>(Template) ||
+ isa<VarTemplatePartialSpecializationDecl>(Template));
return Sema::TDK_Incomplete;
}
@@ -5093,6 +5094,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
cast<DependentSizedArrayType>(T)->getSizeExpr(),
OnlyDeduced, Depth, Used);
// Fall through to check the element type
+ LLVM_FALLTHROUGH;
case Type::ConstantArray:
case Type::IncompleteArray:
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index e7315934b515..c189112e3455 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -643,6 +643,7 @@ static void distributeTypeAttrsFromDeclarator(TypeProcessingState &state,
if (!state.getSema().getLangOpts().ObjCAutoRefCount)
break;
// fallthrough
+ LLVM_FALLTHROUGH;
FUNCTION_TYPE_ATTRS_CASELIST:
distributeFunctionTypeAttrFromDeclarator(state, *attr, declSpecType);
@@ -1881,6 +1882,11 @@ QualType Sema::BuildPointerType(QualType T,
return QualType();
}
+ if (T->isFunctionType() && getLangOpts().OpenCL) {
+ Diag(Loc, diag::err_opencl_function_pointer);
+ return QualType();
+ }
+
if (checkQualifiedFunction(*this, T, Loc, QFK_Pointer))
return QualType();
@@ -4347,19 +4353,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
if (FTI.isAmbiguous)
warnAboutAmbiguousFunction(S, D, DeclType, T);
- // GNU warning -Wstrict-prototypes
- // Warn if a function declaration is without a prototype.
- // This warning is issued for all kinds of unprototyped function
- // declarations (i.e. function type typedef, function pointer etc.)
- // C99 6.7.5.3p14:
- // The empty list in a function declarator that is not part of a
- // definition of that function specifies that no information
- // about the number or types of the parameters is supplied.
- if (D.getFunctionDefinitionKind() == FDK_Declaration &&
- FTI.NumParams == 0 && !LangOpts.CPlusPlus)
- S.Diag(DeclType.Loc, diag::warn_strict_prototypes)
- << 0 << FixItHint::CreateInsertion(FTI.getRParenLoc(), "void");
-
FunctionType::ExtInfo EI(getCCForDeclaratorChunk(S, D, FTI, chunkIndex));
if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus) {
@@ -4602,6 +4595,36 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
const_cast<AttributeList *>(DeclType.getAttrs()));
}
+ // GNU warning -Wstrict-prototypes
+ // Warn if a function declaration is without a prototype.
+ // This warning is issued for all kinds of unprototyped function
+ // declarations (i.e. function type typedef, function pointer etc.)
+ // C99 6.7.5.3p14:
+ // The empty list in a function declarator that is not part of a definition
+ // of that function specifies that no information about the number or types
+ // of the parameters is supplied.
+ if (!LangOpts.CPlusPlus && D.getFunctionDefinitionKind() == FDK_Declaration) {
+ bool IsBlock = false;
+ for (const DeclaratorChunk &DeclType : D.type_objects()) {
+ switch (DeclType.Kind) {
+ case DeclaratorChunk::BlockPointer:
+ IsBlock = true;
+ break;
+ case DeclaratorChunk::Function: {
+ const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
+ if (FTI.NumParams == 0)
+ S.Diag(DeclType.Loc, diag::warn_strict_prototypes)
+ << IsBlock
+ << FixItHint::CreateInsertion(FTI.getRParenLoc(), "void");
+ IsBlock = false;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
assert(!T.isNull() && "T must not be null after this point");
if (LangOpts.CPlusPlus && T->isFunctionType()) {
@@ -6925,6 +6948,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
if (!state.getSema().getLangOpts().ObjCAutoRefCount)
break;
// fallthrough into the function attrs
+ LLVM_FALLTHROUGH;
FUNCTION_TYPE_ATTRS_CASELIST:
attr.setUsedAsTypeAttr();
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index a65584e3c912..7aa8f64d5081 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -6959,6 +6959,8 @@ TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
Builder.ReturnStmt = Res.get();
}
}
+ if (!Builder.buildParameterMoves())
+ return StmtError();
return getDerived().RebuildCoroutineBodyStmt(Builder);
}
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index b7bbb9dc7be1..e16a9b3ee3b5 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -292,6 +292,33 @@ static bool checkLanguageOptions(const LangOptions &LangOpts,
return true;
}
+ // Sanitizer feature mismatches are treated as compatible differences. If
+ // compatible differences aren't allowed, we still only want to check for
+ // mismatches of non-modular sanitizers (the only ones which can affect AST
+ // generation).
+ if (!AllowCompatibleDifferences) {
+ SanitizerMask ModularSanitizers = getPPTransparentSanitizers();
+ SanitizerSet ExistingSanitizers = ExistingLangOpts.Sanitize;
+ SanitizerSet ImportedSanitizers = LangOpts.Sanitize;
+ ExistingSanitizers.clear(ModularSanitizers);
+ ImportedSanitizers.clear(ModularSanitizers);
+ if (ExistingSanitizers.Mask != ImportedSanitizers.Mask) {
+ const std::string Flag = "-fsanitize=";
+ if (Diags) {
+#define SANITIZER(NAME, ID) \
+ { \
+ bool InExistingModule = ExistingSanitizers.has(SanitizerKind::ID); \
+ bool InImportedModule = ImportedSanitizers.has(SanitizerKind::ID); \
+ if (InExistingModule != InImportedModule) \
+ Diags->Report(diag::err_pch_targetopt_feature_mismatch) \
+ << InExistingModule << (Flag + NAME); \
+ }
+#include "clang/Basic/Sanitizers.def"
+ }
+ return true;
+ }
+ }
+
return false;
}
@@ -3670,6 +3697,8 @@ static void updateModuleTimestamp(ModuleFile &MF) {
if (EC)
return;
OS << "Timestamp file\n";
+ OS.close();
+ OS.clear_error(); // Avoid triggering a fatal error.
}
/// \brief Given a cursor at the start of an AST file, scan ahead and drop the
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 95cb54f944e4..044a26433a93 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1856,24 +1856,31 @@ namespace {
// Trait used for the on-disk hash table of header search information.
class HeaderFileInfoTrait {
ASTWriter &Writer;
- const HeaderSearch &HS;
// Keep track of the framework names we've used during serialization.
SmallVector<char, 128> FrameworkStringData;
llvm::StringMap<unsigned> FrameworkNameOffset;
public:
- HeaderFileInfoTrait(ASTWriter &Writer, const HeaderSearch &HS)
- : Writer(Writer), HS(HS) { }
-
+ HeaderFileInfoTrait(ASTWriter &Writer) : Writer(Writer) {}
+
struct key_type {
- const FileEntry *FE;
StringRef Filename;
+ off_t Size;
+ time_t ModTime;
};
typedef const key_type &key_type_ref;
+
+ using UnresolvedModule =
+ llvm::PointerIntPair<Module *, 2, ModuleMap::ModuleHeaderRole>;
- typedef HeaderFileInfo data_type;
+ struct data_type {
+ const HeaderFileInfo &HFI;
+ ArrayRef<ModuleMap::KnownHeader> KnownHeaders;
+ UnresolvedModule Unresolved;
+ };
typedef const data_type &data_type_ref;
+
typedef unsigned hash_value_type;
typedef unsigned offset_type;
@@ -1881,8 +1888,7 @@ namespace {
// The hash is based only on size/time of the file, so that the reader can
// match even when symlinking or excess path elements ("foo/../", "../")
// change the form of the name. However, complete path is still the key.
- return llvm::hash_combine(key.FE->getSize(),
- Writer.getTimestampForOutput(key.FE));
+ return llvm::hash_combine(key.Size, key.ModTime);
}
std::pair<unsigned,unsigned>
@@ -1892,68 +1898,74 @@ namespace {
unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
LE.write<uint16_t>(KeyLen);
unsigned DataLen = 1 + 2 + 4 + 4;
- for (auto ModInfo : HS.getModuleMap().findAllModulesForHeader(key.FE))
+ for (auto ModInfo : Data.KnownHeaders)
if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
DataLen += 4;
+ if (Data.Unresolved.getPointer())
+ DataLen += 4;
LE.write<uint8_t>(DataLen);
return std::make_pair(KeyLen, DataLen);
}
-
+
void EmitKey(raw_ostream& Out, key_type_ref key, unsigned KeyLen) {
using namespace llvm::support;
endian::Writer<little> LE(Out);
- LE.write<uint64_t>(key.FE->getSize());
+ LE.write<uint64_t>(key.Size);
KeyLen -= 8;
- LE.write<uint64_t>(Writer.getTimestampForOutput(key.FE));
+ LE.write<uint64_t>(key.ModTime);
KeyLen -= 8;
Out.write(key.Filename.data(), KeyLen);
}
-
+
void EmitData(raw_ostream &Out, key_type_ref key,
data_type_ref Data, unsigned DataLen) {
using namespace llvm::support;
endian::Writer<little> LE(Out);
uint64_t Start = Out.tell(); (void)Start;
- unsigned char Flags = (Data.isImport << 4)
- | (Data.isPragmaOnce << 3)
- | (Data.DirInfo << 1)
- | Data.IndexHeaderMapHeader;
+ unsigned char Flags = (Data.HFI.isImport << 4)
+ | (Data.HFI.isPragmaOnce << 3)
+ | (Data.HFI.DirInfo << 1)
+ | Data.HFI.IndexHeaderMapHeader;
LE.write<uint8_t>(Flags);
- LE.write<uint16_t>(Data.NumIncludes);
+ LE.write<uint16_t>(Data.HFI.NumIncludes);
- if (!Data.ControllingMacro)
- LE.write<uint32_t>(Data.ControllingMacroID);
+ if (!Data.HFI.ControllingMacro)
+ LE.write<uint32_t>(Data.HFI.ControllingMacroID);
else
- LE.write<uint32_t>(Writer.getIdentifierRef(Data.ControllingMacro));
-
+ LE.write<uint32_t>(Writer.getIdentifierRef(Data.HFI.ControllingMacro));
+
unsigned Offset = 0;
- if (!Data.Framework.empty()) {
+ if (!Data.HFI.Framework.empty()) {
// If this header refers into a framework, save the framework name.
llvm::StringMap<unsigned>::iterator Pos
- = FrameworkNameOffset.find(Data.Framework);
+ = FrameworkNameOffset.find(Data.HFI.Framework);
if (Pos == FrameworkNameOffset.end()) {
Offset = FrameworkStringData.size() + 1;
- FrameworkStringData.append(Data.Framework.begin(),
- Data.Framework.end());
+ FrameworkStringData.append(Data.HFI.Framework.begin(),
+ Data.HFI.Framework.end());
FrameworkStringData.push_back(0);
- FrameworkNameOffset[Data.Framework] = Offset;
+ FrameworkNameOffset[Data.HFI.Framework] = Offset;
} else
Offset = Pos->second;
}
LE.write<uint32_t>(Offset);
- // FIXME: If the header is excluded, we should write out some
- // record of that fact.
- for (auto ModInfo : HS.getModuleMap().findAllModulesForHeader(key.FE)) {
- if (uint32_t ModID =
- Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule())) {
- uint32_t Value = (ModID << 2) | (unsigned)ModInfo.getRole();
+ auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
+ if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
+ uint32_t Value = (ModID << 2) | (unsigned)Role;
assert((Value >> 2) == ModID && "overflow in header module info");
LE.write<uint32_t>(Value);
}
- }
+ };
+
+ // FIXME: If the header is excluded, we should write out some
+ // record of that fact.
+ for (auto ModInfo : Data.KnownHeaders)
+ EmitModule(ModInfo.getModule(), ModInfo.getRole());
+ if (Data.Unresolved.getPointer())
+ EmitModule(Data.Unresolved.getPointer(), Data.Unresolved.getInt());
assert(Out.tell() - Start == DataLen && "Wrong data length");
}
@@ -1968,16 +1980,72 @@ namespace {
///
/// \param HS The header search structure to save.
void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+ HeaderFileInfoTrait GeneratorTrait(*this);
+ llvm::OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator;
+ SmallVector<const char *, 4> SavedStrings;
+ unsigned NumHeaderSearchEntries = 0;
+
+ // Find all unresolved headers for the current module. We generally will
+ // have resolved them before we get here, but not necessarily: we might be
+ // compiling a preprocessed module, where there is no requirement for the
+ // original files to exist any more.
+ const HeaderFileInfo Empty; // So we can take a reference.
+ if (WritingModule) {
+ llvm::SmallVector<Module *, 16> Worklist(1, WritingModule);
+ while (!Worklist.empty()) {
+ Module *M = Worklist.pop_back_val();
+ if (!M->isAvailable())
+ continue;
+
+ // Map to disk files where possible, to pick up any missing stat
+ // information. This also means we don't need to check the unresolved
+ // headers list when emitting resolved headers in the first loop below.
+ // FIXME: It'd be preferable to avoid doing this if we were given
+ // sufficient stat information in the module map.
+ HS.getModuleMap().resolveHeaderDirectives(M);
+
+ // If the file didn't exist, we can still create a module if we were given
+ // enough information in the module map.
+ for (auto U : M->MissingHeaders) {
+ // Check that we were given enough information to build a module
+ // without this file existing on disk.
+ if (!U.Size || (!U.ModTime && IncludeTimestamps)) {
+ PP->Diag(U.FileNameLoc, diag::err_module_no_size_mtime_for_header)
+ << WritingModule->getFullModuleName() << U.Size.hasValue()
+ << U.FileName;
+ continue;
+ }
+
+ // Form the effective relative pathname for the file.
+ SmallString<128> Filename(M->Directory->getName());
+ llvm::sys::path::append(Filename, U.FileName);
+ PreparePathForOutput(Filename);
+
+ StringRef FilenameDup = strdup(Filename.c_str());
+ SavedStrings.push_back(FilenameDup.data());
+
+ HeaderFileInfoTrait::key_type Key = {
+ FilenameDup, *U.Size, IncludeTimestamps ? *U.ModTime : 0
+ };
+ HeaderFileInfoTrait::data_type Data = {
+ Empty, {}, {M, ModuleMap::headerKindToRole(U.Kind)}
+ };
+ // FIXME: Deal with cases where there are multiple unresolved header
+ // directives in different submodules for the same header.
+ Generator.insert(Key, Data, GeneratorTrait);
+ ++NumHeaderSearchEntries;
+ }
+
+ Worklist.append(M->submodule_begin(), M->submodule_end());
+ }
+ }
+
SmallVector<const FileEntry *, 16> FilesByUID;
HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
if (FilesByUID.size() > HS.header_file_size())
FilesByUID.resize(HS.header_file_size());
-
- HeaderFileInfoTrait GeneratorTrait(*this, HS);
- llvm::OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator;
- SmallVector<const char *, 4> SavedStrings;
- unsigned NumHeaderSearchEntries = 0;
+
for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
const FileEntry *File = FilesByUID[UID];
if (!File)
@@ -2004,11 +2072,16 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
SavedStrings.push_back(Filename.data());
}
- HeaderFileInfoTrait::key_type key = { File, Filename };
- Generator.insert(key, *HFI, GeneratorTrait);
+ HeaderFileInfoTrait::key_type Key = {
+ Filename, File->getSize(), getTimestampForOutput(File)
+ };
+ HeaderFileInfoTrait::data_type Data = {
+ *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+ };
+ Generator.insert(Key, Data, GeneratorTrait);
++NumHeaderSearchEntries;
}
-
+
// Create the on-disk hash table in a buffer.
SmallString<4096> TableData;
uint32_t BucketOffset;
diff --git a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
index 8ca2a24cffe7..f7b5f61cfb8a 100644
--- a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
@@ -189,6 +189,7 @@ public:
case DeadIncrement:
BugType = "Dead increment";
+ LLVM_FALLTHROUGH;
case Standard:
if (!BugType) BugType = "Dead assignment";
os << "Value stored to '" << *V << "' is never read";
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 8ee34190891a..f84c0ee800a3 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1176,6 +1176,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
}
}
// FALLTHROUGH
+ LLVM_FALLTHROUGH;
}
case Stmt::CallExprClass:
case Stmt::CXXMemberCallExprClass:
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp
index ffaa0eda918a..04452e3e7cc2 100644
--- a/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -325,6 +325,7 @@ Optional<SVal> SValBuilder::getConstantVal(const Expr *E) {
}
}
// FALLTHROUGH
+ LLVM_FALLTHROUGH;
}
// If we don't have a special case, fall back to the AST's constant evaluator.
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index 82ce8b45fe78..9c28457b2139 100644
--- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -163,6 +163,7 @@ SVal SimpleSValBuilder::evalCastFromLoc(Loc val, QualType castTy) {
return nonloc::SymbolVal(SymR->getSymbol());
// FALL-THROUGH
+ LLVM_FALLTHROUGH;
}
case loc::GotoLabelKind:
diff --git a/test/CodeGen/pr26099.c b/test/CodeGen/pr26099.c
new file mode 100644
index 000000000000..15b73b832e9d
--- /dev/null
+++ b/test/CodeGen/pr26099.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -ffreestanding %s -triple=i686-apple-darwin -target-feature +mmx -emit-llvm -o - -Wall -Werror
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +mmx -emit-llvm -o - -Wall -Werror
+// REQUIRES: asserts
+
+#include <x86intrin.h>
+
+int __attribute__ ((__vector_size__ (8))) b;
+
+void bar(int a)
+{
+ b = __builtin_ia32_vec_init_v2si (0, a);
+} \ No newline at end of file
diff --git a/test/CodeGen/thin_link_bitcode.c b/test/CodeGen/thin_link_bitcode.c
index 4cb5f798a568..52c5715ba561 100644
--- a/test/CodeGen/thin_link_bitcode.c
+++ b/test/CodeGen/thin_link_bitcode.c
@@ -1,6 +1,11 @@
+// REQUIRES: x86-registered-target
+//
// RUN: %clang_cc1 -o %t -flto=thin -fthin-link-bitcode=%t.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited %s
// RUN: llvm-bcanalyzer -dump %t | FileCheck %s
// RUN: llvm-bcanalyzer -dump %t.nodebug | FileCheck %s --check-prefix=NO_DEBUG
+// RUN: %clang_cc1 -o %t.newpm -flto=thin -fexperimental-new-pass-manager -fthin-link-bitcode=%t.newpm.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited %s
+// RUN: llvm-bcanalyzer -dump %t.newpm | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t.newpm.nodebug | FileCheck %s --check-prefix=NO_DEBUG
int main (void) {
return 0;
}
diff --git a/test/CodeGen/ubsan-pointer-overflow.m b/test/CodeGen/ubsan-pointer-overflow.m
index c83d527e624e..56df95baff55 100644
--- a/test/CodeGen/ubsan-pointer-overflow.m
+++ b/test/CodeGen/ubsan-pointer-overflow.m
@@ -37,9 +37,9 @@ void binary_arith(char *p, int i) {
// CHECK-NEXT: [[POSVALID:%.*]] = icmp uge i64 [[COMPGEP]], [[BASE]], !nosanitize
// CHECK-NEXT: [[NEGVALID:%.*]] = icmp ult i64 [[COMPGEP]], [[BASE]], !nosanitize
// CHECK-NEXT: [[POSOFFSET:%.*]] = icmp sge i64 [[SMULVAL]], 0, !nosanitize
- // CHECK-NEXT: [[OFFSETVALID:%.*]] = xor i1 [[OFFSETOFLOW]], true, !nosanitize
- // CHECK-NEXT: [[DIFFVALID:%.*]] = select i1 [[POSOFFSET]], i1 [[POSVALID]], i1 [[NEGVALID]], !nosanitize
- // CHECK-NEXT: [[VALID:%.*]] = and i1 [[OFFSETVALID]], [[DIFFVALID]], !nosanitize
+ // CHECK-DAG: [[OFFSETVALID:%.*]] = xor i1 [[OFFSETOFLOW]], true, !nosanitize
+ // CHECK-DAG: [[DIFFVALID:%.*]] = select i1 [[POSOFFSET]], i1 [[POSVALID]], i1 [[NEGVALID]], !nosanitize
+ // CHECK: [[VALID:%.*]] = and i1 [[OFFSETVALID]], [[DIFFVALID]], !nosanitize
// CHECK-NEXT: br i1 [[VALID]]{{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}, i64 [[BASE]], i64 [[COMPGEP]]){{.*}}, !nosanitize
p + i;
@@ -62,9 +62,9 @@ void fixed_len_array(int k) {
// CHECK-NEXT: [[POSVALID:%.*]] = icmp uge i64 [[COMPGEP]], [[BASE]], !nosanitize
// CHECK-NEXT: [[NEGVALID:%.*]] = icmp ult i64 [[COMPGEP]], [[BASE]], !nosanitize
// CHECK-NEXT: [[POSOFFSET:%.*]] = icmp sge i64 [[SMULVAL]], 0, !nosanitize
- // CHECK-NEXT: [[OFFSETVALID:%.*]] = xor i1 [[OFFSETOFLOW]], true, !nosanitize
- // CHECK-NEXT: [[DIFFVALID:%.*]] = select i1 [[POSOFFSET]], i1 [[POSVALID]], i1 [[NEGVALID]], !nosanitize
- // CHECK-NEXT: [[VALID:%.*]] = and i1 [[OFFSETVALID]], [[DIFFVALID]], !nosanitize
+ // CHECK-DAG: [[OFFSETVALID:%.*]] = xor i1 [[OFFSETOFLOW]], true, !nosanitize
+ // CHECK-DAG: [[DIFFVALID:%.*]] = select i1 [[POSOFFSET]], i1 [[POSVALID]], i1 [[NEGVALID]], !nosanitize
+ // CHECK: [[VALID:%.*]] = and i1 [[OFFSETVALID]], [[DIFFVALID]], !nosanitize
// CHECK-NEXT: br i1 [[VALID]]{{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}, i64 [[BASE]], i64 [[COMPGEP]]){{.*}}, !nosanitize
diff --git a/test/CodeGenCXX/pr33080.cpp b/test/CodeGenCXX/pr33080.cpp
new file mode 100644
index 000000000000..a744bca18986
--- /dev/null
+++ b/test/CodeGenCXX/pr33080.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fms-extensions -emit-llvm -o- %s | FileCheck %s
+
+void fa(__unaligned struct A *) {}
+// CHECK: define void @_Z2faPU11__unaligned1A(
+
+void ga(struct A *, struct A *) {}
+// CHECK: define void @_Z2gaP1AS0_(
+
+void gb(__unaligned struct A *, struct A *) {}
+// CHECK: define void @_Z2gbPU11__unaligned1APS_(
+
+void gc(struct A *, __unaligned struct A *) {}
+// CHECK: define void @_Z2gcP1APU11__unalignedS_(
+
+void gd(__unaligned struct A *, __unaligned struct A *) {}
+// CHECK: define void @_Z2gdPU11__unaligned1AS1_(
+
+void hb(__unaligned struct A *, __unaligned const struct A *) {}
+// CHECK: define void @_Z2hbPU11__unaligned1APU11__unalignedKS_(
+
+void ja(__unaligned struct A *, __unaligned struct A *__unaligned *, __unaligned struct A *__unaligned *__unaligned *) {}
+// CHECK: define void @_Z2jaPU11__unaligned1APU11__unalignedS1_PU11__unalignedS3_(
+
+void jb(__unaligned struct A *, __unaligned struct A **, __unaligned struct A *__unaligned *__unaligned *) {}
+// CHECK: @_Z2jbPU11__unaligned1APS1_PU11__unalignedPU11__unalignedS1_(
+
+template <typename T, typename Q>
+void ta(T &, Q *) {}
+
+void ia(__unaligned struct A &a) {
+ ta(a, &a);
+}
+// CHECK: @_Z2taIU11__unaligned1AS1_EvRT_PT0_(
diff --git a/test/CodeGenCXX/unaligned-duplicated-mangle-name.cpp b/test/CodeGenCXX/unaligned-duplicated-mangle-name.cpp
deleted file mode 100644
index a23e6a47ab05..000000000000
--- a/test/CodeGenCXX/unaligned-duplicated-mangle-name.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -fms-extensions -emit-llvm-only %s -verify
-
-struct A
-{
- int x;
- void foo() __unaligned;
- void foo();
-};
-
-void A::foo() __unaligned
-{
- this->x++;
-}
-
-void A::foo() // expected-error {{definition with same mangled name as another definition}}
- // expected-note@-6 {{previous definition is here}}
-{
- this->x++;
-}
-
diff --git a/test/CodeGenCXX/unaligned-member-qualifier.cpp b/test/CodeGenCXX/unaligned-member-qualifier.cpp
new file mode 100644
index 000000000000..0d326a666830
--- /dev/null
+++ b/test/CodeGenCXX/unaligned-member-qualifier.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fms-extensions -emit-llvm %s -o- | FileCheck %s
+
+struct A {
+ void foo() __unaligned;
+ void foo() const __unaligned;
+ void foo() volatile __unaligned;
+ void foo() const volatile __unaligned;
+};
+
+void A::foo() __unaligned {}
+// CHECK: define [[THISCALL:(x86_thiscallcc )?]]void @_ZNU11__unaligned1A3fooEv(
+
+void A::foo() const __unaligned {}
+// CHECK: define [[THISCALL]]void @_ZNU11__unalignedK1A3fooEv(
+
+void A::foo() volatile __unaligned {}
+// CHECK: define [[THISCALL]]void @_ZNU11__unalignedV1A3fooEv(
+
+void A::foo() const volatile __unaligned {}
+// CHECK: define [[THISCALL]]void @_ZNU11__unalignedVK1A3fooEv(
diff --git a/test/CodeGenCoroutines/coro-params.cpp b/test/CodeGenCoroutines/coro-params.cpp
index c88e503a651c..540f84585c8e 100644
--- a/test/CodeGenCoroutines/coro-params.cpp
+++ b/test/CodeGenCoroutines/coro-params.cpp
@@ -93,3 +93,37 @@ void f(int val, MoveOnly moParam, MoveAndCopy mcParam) {
// CHECK-NEXT: call void @_ZN8MoveOnlyD1Ev(%struct.MoveOnly* %[[MoCopy]]
// CHECK-NEXT: call i8* @llvm.coro.free(
}
+
+// CHECK-LABEL: void @_Z16dependent_paramsI1A1BEvT_T0_S3_(%struct.A* %x, %struct.B*, %struct.B* %y)
+template <typename T, typename U>
+void dependent_params(T x, U, U y) {
+ // CHECK: %[[x_copy:.+]] = alloca %struct.A
+ // CHECK-NEXT: %[[unnamed_copy:.+]] = alloca %struct.B
+ // CHECK-NEXT: %[[y_copy:.+]] = alloca %struct.B
+
+ // CHECK: call i8* @llvm.coro.begin
+ // CHECK-NEXT: call void @_ZN1AC1EOS_(%struct.A* %[[x_copy]], %struct.A* dereferenceable(512) %x)
+ // CHECK-NEXT: call void @_ZN1BC1EOS_(%struct.B* %[[unnamed_copy]], %struct.B* dereferenceable(512) %0)
+ // CHECK-NEXT: call void @_ZN1BC1EOS_(%struct.B* %[[y_copy]], %struct.B* dereferenceable(512) %y)
+ // CHECK-NEXT: invoke void @_ZNSt12experimental16coroutine_traitsIJv1A1BS2_EE12promise_typeC1Ev(
+
+ co_return;
+}
+
+struct A {
+ int WontFitIntoRegisterForSure[128];
+ A();
+ A(A&&) noexcept;
+ ~A();
+};
+
+struct B {
+ int WontFitIntoRegisterForSure[128];
+ B();
+ B(B&&) noexcept;
+ ~B();
+};
+
+void call_dependent_params() {
+ dependent_params(A{}, B{}, B{});
+}
diff --git a/test/CodeGenObjCXX/arc-mangle.mm b/test/CodeGenObjCXX/arc-mangle.mm
index 82e37556ec30..b39aa7bbbf00 100644
--- a/test/CodeGenObjCXX/arc-mangle.mm
+++ b/test/CodeGenObjCXX/arc-mangle.mm
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -triple %itanium_abi_triple -emit-llvm -fblocks -o - %s | FileCheck %s
+// RUN: %clang_cc1 -DTEST_UNALIGNED -fms-extensions -fobjc-arc -fobjc-runtime-has-weak -triple %itanium_abi_triple -emit-llvm -fblocks -o - %s | FileCheck %s --check-prefix=UNALIGNED
// CHECK-LABEL: define {{.*}}void @_Z1fPU8__strongP11objc_object(i8**)
void f(__strong id *) {}
@@ -32,3 +33,12 @@ template<unsigned N> struct unsigned_c { };
// CHECK-LABEL: define weak_odr {{.*}}void @_Z1gIKvEvP10unsigned_cIXplszv1U8__bridgecvPT_v1U8__bridgecvP11objc_objectcvS3_Li0ELi1EEE
template<typename T>void g(unsigned_c<sizeof((__bridge T*)(__bridge id)(T*)0) + 1>*) {}
template void g<const void>(unsigned_c<sizeof(id) + 1> *);
+
+#if TEST_UNALIGNED
+// UNALIGNED-LABEL: define {{.*}}void @_Z1gPU6__weakU11__unalignedP11objc_object(i8**)
+void g(__weak __unaligned id *) {}
+// UNALIGNED-LABEL: define {{.*}}void @_Z1gPU11__unalignedU8__strongP11objc_object(i8**)
+void g(__strong __unaligned id *) {}
+// UNALIGNED-LABEL: define {{.*}}void @_Z1gPU11__unalignedU15__autoreleasingP11objc_object(i8**)
+void g(__autoreleasing __unaligned id *) {}
+#endif // TEST_UNALIGNED
diff --git a/test/Driver/fsanitize-coverage.c b/test/Driver/fsanitize-coverage.c
index cf0941477bba..0516b6db524c 100644
--- a/test/Driver/fsanitize-coverage.c
+++ b/test/Driver/fsanitize-coverage.c
@@ -84,6 +84,9 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=no-prune,func,trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_NOPRUNE
// CHECK_NOPRUNE: -fsanitize-coverage-no-prune
+// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE8BIT
+// CHECK_INLINE8BIT: -fsanitize-coverage-inline-8bit-counters
+
// RUN: %clang_cl --target=i386-pc-win32 -fsanitize=address -fsanitize-coverage=func,trace-pc-guard -c -### -- %s 2>&1 | FileCheck %s -check-prefix=CLANG-CL-COVERAGE
// CLANG-CL-COVERAGE-NOT: error:
// CLANG-CL-COVERAGE-NOT: warning:
diff --git a/test/Frontend/rewrite-includes-filenotfound.c b/test/Frontend/rewrite-includes-filenotfound.c
new file mode 100644
index 000000000000..203dbde54516
--- /dev/null
+++ b/test/Frontend/rewrite-includes-filenotfound.c
@@ -0,0 +1,6 @@
+// RUN: not %clang_cc1 -E -frewrite-includes %s -o - 2>&1 | FileCheck %s
+
+#include "this file does not exist.foo"
+#include "this file also does not exist.foo"
+
+CHECK: fatal error: {{.*}} file not found
diff --git a/test/Integration/carbon.c b/test/Integration/carbon.c
index 0498116dd181..3cae39122685 100644
--- a/test/Integration/carbon.c
+++ b/test/Integration/carbon.c
@@ -1,4 +1,5 @@
// RUN: %clang -fsyntax-only %s
+// REQUIRES: macos-sdk-10.12
#ifdef __APPLE__
#include <Carbon/Carbon.h>
#endif
diff --git a/test/Integration/cocoa-pch.m b/test/Integration/cocoa-pch.m
index 0159b3201492..fa3ccea37896 100644
--- a/test/Integration/cocoa-pch.m
+++ b/test/Integration/cocoa-pch.m
@@ -1,6 +1,7 @@
// RUN: %clang -arch x86_64 -x objective-c-header %s -o %t.h.pch
// RUN: touch %t.empty.m
// RUN: %clang -arch x86_64 -fsyntax-only %t.empty.m -include %t.h -Xclang -ast-dump 2>&1 > /dev/null
+// REQUIRES: macos-sdk-10.12
#ifdef __APPLE__
#include <Cocoa/Cocoa.h>
#endif
diff --git a/test/Integration/cocoa.m b/test/Integration/cocoa.m
index d814b3ee21bc..91d868250845 100644
--- a/test/Integration/cocoa.m
+++ b/test/Integration/cocoa.m
@@ -1,4 +1,5 @@
// RUN: %clang -arch x86_64 %s -fsyntax-only -Xclang -print-stats
+// REQUIRES: macos-sdk-10.12
#ifdef __APPLE__
#include <Cocoa/Cocoa.h>
#endif
diff --git a/test/Misc/ast-print-objectivec.m b/test/Misc/ast-print-objectivec.m
index e419237bbbac..cb5aacc06a49 100644
--- a/test/Misc/ast-print-objectivec.m
+++ b/test/Misc/ast-print-objectivec.m
@@ -17,25 +17,30 @@
@implementation I
- (void)MethP __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))) {}
- (void)MethI __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))) {}
+
+- (void)methodWithArg:(int)x andAnotherOne:(int)y { }
@end
// CHECK: @protocol P
-// CHECK: - (void) MethP __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2)));
+// CHECK: - (void)MethP __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2)));
// CHECK: @end
// CHECK: @interface I : NSObject<P>
-// CHECK: - (void) MethI __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2)));
+// CHECK: - (void)MethI __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2)));
// CHECK: @end
// CHECK: @interface I(CAT)
-// CHECK: - (void) MethCAT __attribute__((availability(macos, introduced=10_1_0, deprecated=10_2)));
+// CHECK: - (void)MethCAT __attribute__((availability(macos, introduced=10_1_0, deprecated=10_2)));
// CHECK: @end
// CHECK: @implementation I
-// CHECK: - (void) MethP __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))) {
+// CHECK: - (void)MethP __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))) {
+// CHECK: }
+
+// CHECK: - (void)MethI __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))) {
// CHECK: }
-// CHECK: - (void) MethI __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))) {
+// CHECK: - (void)methodWithArg:(int)x andAnotherOne:(int)y {
// CHECK: }
// CHECK: @end
diff --git a/test/Modules/Inputs/check-for-sanitizer-feature/check.h b/test/Modules/Inputs/check-for-sanitizer-feature/check.h
new file mode 100644
index 000000000000..74b4628d1230
--- /dev/null
+++ b/test/Modules/Inputs/check-for-sanitizer-feature/check.h
@@ -0,0 +1,5 @@
+#if __has_feature(address_sanitizer)
+#define HAS_ASAN 1
+#else
+#define HAS_ASAN 0
+#endif
diff --git a/test/Modules/Inputs/check-for-sanitizer-feature/map b/test/Modules/Inputs/check-for-sanitizer-feature/map
new file mode 100644
index 000000000000..95f2da95020e
--- /dev/null
+++ b/test/Modules/Inputs/check-for-sanitizer-feature/map
@@ -0,0 +1,3 @@
+module check_feature {
+ header "check.h"
+}
diff --git a/test/Modules/Inputs/header-attribs/bar.h b/test/Modules/Inputs/header-attribs/bar.h
new file mode 100644
index 000000000000..796b4ebcc731
--- /dev/null
+++ b/test/Modules/Inputs/header-attribs/bar.h
@@ -0,0 +1 @@
+extern int b;
diff --git a/test/Modules/Inputs/header-attribs/baz.h b/test/Modules/Inputs/header-attribs/baz.h
new file mode 100644
index 000000000000..566a522b2474
--- /dev/null
+++ b/test/Modules/Inputs/header-attribs/baz.h
@@ -0,0 +1 @@
+extern int c;
diff --git a/test/Modules/Inputs/header-attribs/foo.h b/test/Modules/Inputs/header-attribs/foo.h
new file mode 100644
index 000000000000..a54d4a7067ee
--- /dev/null
+++ b/test/Modules/Inputs/header-attribs/foo.h
@@ -0,0 +1 @@
+extern int a; \ No newline at end of file
diff --git a/test/Modules/Inputs/header-attribs/modular.modulemap b/test/Modules/Inputs/header-attribs/modular.modulemap
new file mode 100644
index 000000000000..945d7150fd2f
--- /dev/null
+++ b/test/Modules/Inputs/header-attribs/modular.modulemap
@@ -0,0 +1,5 @@
+module A {
+ header "foo.h" { size 13 }
+ header "bar.h" { size 1000 }
+ header "baz.h" { mtime 1 }
+}
diff --git a/test/Modules/Inputs/header-attribs/textual.modulemap b/test/Modules/Inputs/header-attribs/textual.modulemap
new file mode 100644
index 000000000000..b73f3698aa02
--- /dev/null
+++ b/test/Modules/Inputs/header-attribs/textual.modulemap
@@ -0,0 +1,5 @@
+module A {
+ textual header "foo.h" { size 13 }
+ textual header "bar.h" { size 1000 }
+ textual header "baz.h" { mtime 1 }
+}
diff --git a/test/Modules/check-for-sanitizer-feature.cpp b/test/Modules/check-for-sanitizer-feature.cpp
new file mode 100644
index 000000000000..40ae46c64684
--- /dev/null
+++ b/test/Modules/check-for-sanitizer-feature.cpp
@@ -0,0 +1,66 @@
+// RUN: rm -rf %t.1 %t.2
+// RUN: mkdir %t.1 %t.2
+
+// Build and use an ASan-enabled module.
+// RUN: %clang_cc1 -fsanitize=address -fmodules -fmodules-cache-path=%t.1 \
+// RUN: -fmodule-map-file=%S/Inputs/check-for-sanitizer-feature/map \
+// RUN: -I %S/Inputs/check-for-sanitizer-feature -verify %s
+// RUN: ls %t.1 | count 2
+
+// Force a module rebuild by disabling ASan.
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t.1 \
+// RUN: -fmodule-map-file=%S/Inputs/check-for-sanitizer-feature/map \
+// RUN: -I %S/Inputs/check-for-sanitizer-feature -verify %s
+// RUN: ls %t.1 | count 3
+
+// Enable ASan again: check that there is no import failure, and no rebuild.
+// RUN: %clang_cc1 -fsanitize=address -fmodules -fmodules-cache-path=%t.1 \
+// RUN: -fmodule-map-file=%S/Inputs/check-for-sanitizer-feature/map \
+// RUN: -I %S/Inputs/check-for-sanitizer-feature -verify %s
+// RUN: ls %t.1 | count 3
+
+// Some sanitizers can not affect AST generation when enabled. Check that
+// module rebuilds don't occur when these sanitizers are enabled.
+//
+// First, build without any sanitization.
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t.2 \
+// RUN: -fmodule-map-file=%S/Inputs/check-for-sanitizer-feature/map \
+// RUN: -I %S/Inputs/check-for-sanitizer-feature -verify %s
+// RUN: ls %t.2 | count 2
+//
+// Next, build with sanitization, and check that a new module isn't built.
+// RUN: %clang_cc1 -fsanitize=cfi-vcall,unsigned-integer-overflow,nullability-arg,null -fmodules \
+// RUN: -fmodules-cache-path=%t.2 \
+// RUN: -fmodule-map-file=%S/Inputs/check-for-sanitizer-feature/map \
+// RUN: -I %S/Inputs/check-for-sanitizer-feature -verify %s
+// RUN: ls %t.2 | count 2
+
+// Finally, test that including enabled sanitizers in the module hash isn't
+// required to ensure correctness of module imports.
+//
+// Emit a PCH with ASan enabled.
+// RUN: %clang_cc1 -x c -fsanitize=address %S/Inputs/check-for-sanitizer-feature/check.h -emit-pch -o %t.asan_pch
+//
+// Import the PCH without ASan enabled (we expect an error).
+// RUN: not %clang_cc1 -x c -include-pch %t.asan_pch %s -verify 2>&1 | FileCheck %s --check-prefix=PCH_MISMATCH
+// PCH_MISMATCH: AST file was compiled with the target feature'-fsanitize=address' but the current translation unit is not
+//
+// Emit a PCH with UBSan enabled.
+// RUN: %clang_cc1 -x c -fsanitize=null %S/Inputs/check-for-sanitizer-feature/check.h -emit-pch -o %t.ubsan_pch
+//
+// Import the PCH without UBSan enabled (should work just fine).
+// RUN: %clang_cc1 -x c -include-pch %t.ubsan_pch %s -I %S/Inputs/check-for-sanitizer-feature -verify
+
+#include "check.h"
+
+#if __has_feature(address_sanitizer)
+#if HAS_ASAN != 1
+#error Module doesn't have the address_sanitizer feature, but main program does.
+#endif
+#else
+#if HAS_ASAN != 0
+#error Module has the address_sanitizer feature, but main program doesn't.
+#endif
+#endif
+
+// expected-no-diagnostics
diff --git a/test/Modules/diagnostics.modulemap b/test/Modules/diagnostics.modulemap
index 3b5b6a5c0396..865892b53b28 100644
--- a/test/Modules/diagnostics.modulemap
+++ b/test/Modules/diagnostics.modulemap
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/diagnostics-aux.modulemap -fmodule-map-file=%s -fsyntax-only -x c++ /dev/null 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/diagnostics-aux.modulemap -fmodule-map-file=%s -fsyntax-only -x c++ /dev/null 2>&1 | FileCheck %s --implicit-check-not error:
// CHECK: In file included from {{.*}}diagnostics-aux.modulemap:3:
// CHECK: diagnostics-aux-2.modulemap:2:3: error: expected
@@ -15,3 +15,15 @@ module bad_use {
// CHECK: diagnostics.modulemap:[[@LINE+1]]:22: error: use declarations are only allowed in top-level modules
module submodule { use foo }
}
+
+module header_attr {
+ // CHECK: diagnostics.modulemap:[[@LINE+1]]:20: error: expected a header attribute name
+ header "foo.h" { x }
+ // CHECK: diagnostics.modulemap:[[@LINE+1]]:27: error: header attribute 'size' specified multiple times
+ header "bar.h" { size 1 size 2 }
+ // CHECK: diagnostics.modulemap:[[@LINE+1]]:25: error: expected integer literal as value for header attribute 'size'
+ header "baz.h" { size "30 kilobytes" }
+
+ header "quux.h" { size 1 mtime 2 }
+ header "no_attrs.h" {}
+}
diff --git a/test/Modules/header-attribs.cpp b/test/Modules/header-attribs.cpp
new file mode 100644
index 000000000000..292a94561e45
--- /dev/null
+++ b/test/Modules/header-attribs.cpp
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -I%S/Inputs/header-attribs -fmodule-map-file=%S/Inputs/header-attribs/textual.modulemap -fmodules-cache-path=%t -verify %s -fmodule-name=A -fmodules-strict-decluse
+// RUN: not %clang_cc1 -fmodules -I%S/Inputs/header-attribs -emit-module -x c++-module-map %S/Inputs/header-attribs/modular.modulemap -fmodules-cache-path=%t -fmodule-name=A 2>&1 | FileCheck %s --check-prefix BUILD-MODULAR
+
+#include "foo.h" // ok, stats match
+#include "bar.h" // expected-error {{does not depend on a module exporting 'bar.h'}}
+#include "baz.h" // expected-error {{does not depend on a module exporting 'baz.h'}}
+
+// FIXME: Explain why the 'bar.h' found on disk doesn't match the module map.
+// BUILD-MODULAR: error: header 'bar.h' not found
diff --git a/test/Modules/lookup.m b/test/Modules/lookup.m
index edf70639e5cc..b22e41f84594 100644
--- a/test/Modules/lookup.m
+++ b/test/Modules/lookup.m
@@ -14,7 +14,7 @@ void test(id x) {
// expected-note@Inputs/lookup_right.h:3{{also found}}
}
-// CHECK-PRINT: - (int) method;
-// CHECK-PRINT: - (double) method
+// CHECK-PRINT: - (int)method;
+// CHECK-PRINT: - (double)method
// CHECK-PRINT: void test(id x)
diff --git a/test/Modules/preprocess-missing.modulemap b/test/Modules/preprocess-missing.modulemap
new file mode 100644
index 000000000000..300494672f2c
--- /dev/null
+++ b/test/Modules/preprocess-missing.modulemap
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fmodules -fmodule-name=A -x c++-module-map %s -emit-module -o /dev/null -verify
+module A {
+ header "does not exist" { size 12345 } // ok, do not need mtime for explicit module build
+ header "also does not exist" { mtime 12345 }
+}
+#pragma clang module contents
+// expected-error@4 {{cannot emit module A: size must be explicitly specified for missing header file "also does not exist"}}
diff --git a/test/Modules/preprocess-module.cpp b/test/Modules/preprocess-module.cpp
index 9d1a2bb6801f..1e9458e667e1 100644
--- a/test/Modules/preprocess-module.cpp
+++ b/test/Modules/preprocess-module.cpp
@@ -28,12 +28,21 @@
// RUN: %clang_cc1 -fmodules -fmodule-file=%t/no-rewrite.pcm %s -I%t -verify -fno-modules-error-recovery -DINCLUDE -I%S/Inputs/preprocess
// RUN: %clang_cc1 -fmodules -fmodule-file=%t/rewrite.pcm %s -I%t -verify -fno-modules-error-recovery -DREWRITE -DINCLUDE -I%S/Inputs/preprocess
+// Now try building the module when the header files are missing.
+// RUN: cp %S/Inputs/preprocess/fwd.h %S/Inputs/preprocess/file.h %S/Inputs/preprocess/file2.h %S/Inputs/preprocess/module.modulemap %t
+// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -I%t -x c++-module-map %t/module.modulemap -E -frewrite-includes -o %t/copy.ii
+// RUN: rm %t/fwd.h %t/file.h %t/file2.h %t/module.modulemap
+// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -x c++-module-map-cpp-output %t/copy.ii -emit-module -o %t/copy.pcm
+
+// Finally, check that our module contains correct mapping information for the headers.
+// RUN: cp %S/Inputs/preprocess/fwd.h %S/Inputs/preprocess/file.h %S/Inputs/preprocess/file2.h %S/Inputs/preprocess/module.modulemap %t
+// RUN: %clang_cc1 -fmodules -fmodule-file=%t/copy.pcm %s -I%t -verify -fno-modules-error-recovery -DCOPY -DINCLUDE
// == module map
// CHECK: # 1 "{{.*}}module.modulemap"
// CHECK: module file {
-// CHECK: header "file.h"
-// CHECK: header "file2.h"
+// CHECK: header "file.h" { size
+// CHECK: header "file2.h" { size
// CHECK: }
// == file.h
@@ -98,6 +107,8 @@
__FILE *a; // expected-error {{declaration of '__FILE' must be imported}}
#ifdef REWRITE
// expected-note@rewrite.ii:1 {{here}}
+#elif COPY
+// expected-note@copy.ii:1 {{here}}
#else
// expected-note@no-rewrite.ii:1 {{here}}
#endif
diff --git a/test/Sema/warn-strict-prototypes.m b/test/Sema/warn-strict-prototypes.m
index 4567dab01930..66d574f75f80 100644
--- a/test/Sema/warn-strict-prototypes.m
+++ b/test/Sema/warn-strict-prototypes.m
@@ -2,16 +2,16 @@
@interface Foo
-@property (nonatomic, copy) void (^noProtoBlock)(); // expected-warning {{this function declaration is not a prototype}}
+@property (nonatomic, copy) void (^noProtoBlock)(); // expected-warning {{this block declaration is not a prototype}}
@property (nonatomic, copy) void (^block)(void); // no warning
-- doStuff:(void (^)()) completionHandler; // expected-warning {{this function declaration is not a prototype}}
+- doStuff:(void (^)()) completionHandler; // expected-warning {{this block declaration is not a prototype}}
- doOtherStuff:(void (^)(void)) completionHandler; // no warning
@end
void foo() {
- void (^block)() = // expected-warning {{this function declaration is not a prototype}}
+ void (^block)() = // expected-warning {{this block declaration is not a prototype}}
^void(int arg) { // no warning
};
void (^block2)(void) = ^void() { // no warning
@@ -19,3 +19,8 @@ void foo() {
void (^block3)(void) = ^ { // no warning
};
}
+
+void (*(^(*(^block4)()) // expected-warning {{this block declaration is not a prototype}}
+ ()) // expected-warning {{this function declaration is not a prototype}}
+ ()) // expected-warning {{this block declaration is not a prototype}}
+ (); // expected-warning {{this function declaration is not a prototype}}
diff --git a/test/SemaCXX/coroutines.cpp b/test/SemaCXX/coroutines.cpp
index a867cf68a6e1..4eedc2162f07 100644
--- a/test/SemaCXX/coroutines.cpp
+++ b/test/SemaCXX/coroutines.cpp
@@ -892,3 +892,16 @@ void test_bad_suspend() {
co_await d; // OK
}
}
+
+template <int ID = 0>
+struct NoCopy {
+ NoCopy(NoCopy const&) = delete; // expected-note 2 {{deleted here}}
+};
+template <class T, class U>
+void test_dependent_param(T t, U) {
+ // expected-error@-1 {{call to deleted constructor of 'NoCopy<0>'}}
+ // expected-error@-2 {{call to deleted constructor of 'NoCopy<1>'}}
+ ((void)t);
+ co_return 42;
+}
+template void test_dependent_param(NoCopy<0>, NoCopy<1>); // expected-note {{requested here}}
diff --git a/test/SemaOpenCL/func.cl b/test/SemaOpenCL/func.cl
index ea3bab6c514c..dc5b44057b19 100644
--- a/test/SemaOpenCL/func.cl
+++ b/test/SemaOpenCL/func.cl
@@ -4,8 +4,15 @@
void vararg_f(int, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}}
void __vararg_f(int, ...);
typedef void (*vararg_fptr_t)(int, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}}
+ // expected-error@-1{{pointers to functions are not allowed}}
int printf(__constant const char *st, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}}
+// Struct type with function pointer field
+typedef struct s
+{
+ void (*f)(struct s *self, int *i); // expected-error{{pointers to functions are not allowed}}
+} s_t;
+
//Function pointer
void foo(void*);
diff --git a/test/SemaTemplate/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp
index c94c9db94e06..74a25865aa20 100644
--- a/test/SemaTemplate/deduction-crash.cpp
+++ b/test/SemaTemplate/deduction-crash.cpp
@@ -1,14 +1,10 @@
-// RUN: not %clang_cc1 -fsyntax-only %s -std=c++11 2>&1| FileCheck %s
-
-// Note that the error count below doesn't matter. We just want to
-// make sure that the parser doesn't crash.
-// CHECK: 17 errors
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++1z -verify
// PR7511
-template<a>
+template<a> // expected-error +{{}}
struct int_;
-template<a>
+template<a> // expected-error +{{}}
template<int,typename T1,typename>
struct ac
{
@@ -17,7 +13,7 @@ struct ac
template<class>struct aaa
{
- typedef ac<1,int,int>::ae ae
+ typedef ac<1,int,int>::ae ae // expected-error +{{}}
};
template<class>
@@ -36,19 +32,19 @@ struct state_machine
struct In;
template<int my>
- struct In<a::int_<aaa::a>,my>;
+ struct In<a::int_<aaa::a>,my>; // expected-error +{{}}
template<class Event>
int process(Event)
{
- In<a::int_<0> > a;
+ In<a::int_<0> > a; // expected-error +{{}}
}
- }
+ } // expected-error +{{}}
template<class Event>
int ant(Event)
{
region_processing_helper<int>* helper;
- helper->process(0)
+ helper->process(0) // expected-error +{{}}
}
};
@@ -81,21 +77,21 @@ void endl( ) ;
extern basic_ostream<char> cout;
-int operator<<( basic_ostream<char> , pair ) ;
+int operator<<( basic_ostream<char> , pair ) ; // expected-note +{{}}
void register_object_imp ( )
{
-cout << endl<1>;
+cout << endl<1>; // expected-error +{{}}
}
// PR12933
-namespacae PR12933 {
- template<typename S>
+namespace PR12933 {
+ template<typename S> // expected-error +{{}}
template<typename T>
void function(S a, T b) {}
int main() {
- function(0, 1);
+ function(0, 1); // expected-error +{{}}
return 0;
}
}
@@ -142,3 +138,9 @@ namespace PR14281_part3 {
template <class T, int* i> struct B {};
A<B<int, &some_decl>, &some_decl>::type x;
}
+
+namespace var_template_partial_spec_incomplete {
+ template<typename T> int n;
+ template<typename T, typename U = void> int n<T *>; // expected-error +{{}} expected-note {{}}
+ int k = n<void *>;
+}
diff --git a/test/lit.cfg b/test/lit.cfg
index a5e8b9de994b..e72eca6bd397 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -529,3 +529,6 @@ if run_console_tests != 0:
config.available_features.add('console')
lit.util.usePlatformSdkOnDarwin(config, lit_config)
+macOSSDKVersion = lit.util.findPlatformSdkVersionOnMacOS(config, lit_config)
+if macOSSDKVersion is not None:
+ config.available_features.add('macos-sdk-' + macOSSDKVersion)
diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp
index e5a09a31f69f..ae6d0f0dd2e2 100644
--- a/unittests/AST/DeclPrinterTest.cpp
+++ b/unittests/AST/DeclPrinterTest.cpp
@@ -1228,7 +1228,7 @@ TEST(DeclPrinter, TestObjCMethod1) {
"@end\n",
namedDecl(hasName("A:inRange:"),
hasDescendant(namedDecl(hasName("printThis")))).bind("id"),
- "- (int) A:(id)anObject inRange:(long)range"));
+ "- (int)A:(id)anObject inRange:(long)range"));
}
TEST(DeclPrinter, TestObjCProtocol1) {