aboutsummaryrefslogtreecommitdiff
path: root/lib
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 /lib
parent416ada0f75bab22b084a1776deb229cd4a669c4d (diff)
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
Diffstat (limited to 'lib')
-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
70 files changed, 680 insertions, 226 deletions
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: