Vendor import of clang trunk r304659:
https://llvm.org/svn/llvm-project/cfe/trunk@304659
This commit is contained in:
parent
416ada0f75
commit
551c698530
@ -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.
|
||||
|
@ -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 "
|
||||
|
@ -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<
|
||||
|
@ -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
|
||||
|
||||
|
@ -154,11 +154,19 @@ class Module {
|
||||
/// \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;
|
||||
|
@ -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
|
||||
|
@ -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">;
|
||||
|
@ -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.
|
||||
|
@ -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 @@ class ModuleMap {
|
||||
// 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 @@ class ModuleMap {
|
||||
/// \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 @@ class ModuleMap {
|
||||
/// 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 @@ class ModuleMap {
|
||||
/// 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.
|
||||
|
@ -78,6 +78,7 @@ class RetainReleaseDeallocRemover :
|
||||
}
|
||||
}
|
||||
// Pass through.
|
||||
LLVM_FALLTHROUGH;
|
||||
case OMF_retain:
|
||||
case OMF_release:
|
||||
if (E->getReceiverKind() == ObjCMessageExpr::Instance)
|
||||
|
@ -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);
|
||||
|
@ -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: {
|
||||
|
@ -360,6 +360,7 @@ void clang::FormatASTNodeDiagnosticArgument(
|
||||
Modifier = StringRef();
|
||||
Argument = StringRef();
|
||||
// Fall through
|
||||
LLVM_FALLTHROUGH;
|
||||
}
|
||||
case DiagnosticsEngine::ak_qualtype: {
|
||||
assert(Modifier.empty() && Argument.empty() &&
|
||||
|
@ -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: {
|
||||
|
@ -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 << ", ...";
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
|
||||
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) {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -109,6 +109,7 @@ void PseudoConstantAnalysis::RunAnalysis() {
|
||||
// Do not visit the children
|
||||
continue;
|
||||
|
||||
LLVM_FALLTHROUGH;
|
||||
}
|
||||
case BO_AddAssign:
|
||||
case BO_SubAssign:
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -4259,6 +4259,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
|
||||
Builder.CreateStore(elt, eltAddr);
|
||||
}
|
||||
// FALLTHROUGH
|
||||
LLVM_FALLTHROUGH;
|
||||
}
|
||||
|
||||
case ABIArgInfo::InAlloca:
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -367,7 +367,7 @@ class CGDebugInfo {
|
||||
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.
|
||||
|
@ -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),
|
||||
|
@ -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)) {
|
||||
|
@ -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 '}'.
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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 @@ bool Lexer::LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine) {
|
||||
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':
|
||||
|
@ -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;
|
||||
|
@ -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,18 +985,63 @@ 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,
|
||||
@ -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 @@ SourceLocation ModuleMapParser::consumeToken() {
|
||||
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();
|
||||
|
||||
// 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;
|
||||
}
|
||||
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;
|
||||
|
||||
// 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());
|
||||
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;
|
||||
|
||||
case Unknown:
|
||||
Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
|
||||
skipUntil(MMToken::RBrace);
|
||||
break;
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
// 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:
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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 ']'
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -203,6 +203,7 @@ Parser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts,
|
||||
}
|
||||
|
||||
// Fall through
|
||||
LLVM_FALLTHROUGH;
|
||||
}
|
||||
|
||||
default: {
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -51,6 +51,9 @@ class CoroutineStmtBuilder : public CoroutineBodyStmt::CtorArgs {
|
||||
/// name lookup.
|
||||
bool buildDependentStatements();
|
||||
|
||||
/// \brief Build just parameter moves. To use for rebuilding in TreeTransform.
|
||||
bool buildParameterMoves();
|
||||
|
||||
bool isInvalid() const { return !this->IsValid; }
|
||||
|
||||
private:
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
} else {
|
||||
PDiag << (unsigned)Decls.size();
|
||||
for (auto *VD : Decls)
|
||||
PDiag << VD->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();
|
||||
for (auto Range : Ranges)
|
||||
PDiag << Range;
|
||||
|
||||
S.Diag(Ranges.begin()->getBegin(), PDiag);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -6959,6 +6959,8 @@ TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
|
||||
Builder.ReturnStmt = Res.get();
|
||||
}
|
||||
}
|
||||
if (!Builder.buildParameterMoves())
|
||||
return StmtError();
|
||||
|
||||
return getDerived().RebuildCoroutineBodyStmt(Builder);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -189,6 +189,7 @@ class DeadStoreObs : public LiveVariables::Observer {
|
||||
|
||||
case DeadIncrement:
|
||||
BugType = "Dead increment";
|
||||
LLVM_FALLTHROUGH;
|
||||
case Standard:
|
||||
if (!BugType) BugType = "Dead assignment";
|
||||
os << "Value stored to '" << *V << "' is never read";
|
||||
|
@ -1176,6 +1176,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
||||
}
|
||||
}
|
||||
// FALLTHROUGH
|
||||
LLVM_FALLTHROUGH;
|
||||
}
|
||||
case Stmt::CallExprClass:
|
||||
case Stmt::CXXMemberCallExprClass:
|
||||
|
@ -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.
|
||||
|
@ -163,6 +163,7 @@ SVal SimpleSValBuilder::evalCastFromLoc(Loc val, QualType castTy) {
|
||||
return nonloc::SymbolVal(SymR->getSymbol());
|
||||
|
||||
// FALL-THROUGH
|
||||
LLVM_FALLTHROUGH;
|
||||
}
|
||||
|
||||
case loc::GotoLabelKind:
|
||||
|
12
test/CodeGen/pr26099.c
Normal file
12
test/CodeGen/pr26099.c
Normal file
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
33
test/CodeGenCXX/pr33080.cpp
Normal file
33
test/CodeGenCXX/pr33080.cpp
Normal file
@ -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_(
|
@ -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++;
|
||||
}
|
||||
|
20
test/CodeGenCXX/unaligned-member-qualifier.cpp
Normal file
20
test/CodeGenCXX/unaligned-member-qualifier.cpp
Normal file
@ -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(
|
@ -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{});
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
6
test/Frontend/rewrite-includes-filenotfound.c
Normal file
6
test/Frontend/rewrite-includes-filenotfound.c
Normal file
@ -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
|
@ -1,4 +1,5 @@
|
||||
// RUN: %clang -fsyntax-only %s
|
||||
// REQUIRES: macos-sdk-10.12
|
||||
#ifdef __APPLE__
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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: - (void)MethI __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))) {
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: - (void)methodWithArg:(int)x andAnotherOne:(int)y {
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: @end
|
||||
|
5
test/Modules/Inputs/check-for-sanitizer-feature/check.h
Normal file
5
test/Modules/Inputs/check-for-sanitizer-feature/check.h
Normal file
@ -0,0 +1,5 @@
|
||||
#if __has_feature(address_sanitizer)
|
||||
#define HAS_ASAN 1
|
||||
#else
|
||||
#define HAS_ASAN 0
|
||||
#endif
|
3
test/Modules/Inputs/check-for-sanitizer-feature/map
Normal file
3
test/Modules/Inputs/check-for-sanitizer-feature/map
Normal file
@ -0,0 +1,3 @@
|
||||
module check_feature {
|
||||
header "check.h"
|
||||
}
|
1
test/Modules/Inputs/header-attribs/bar.h
Normal file
1
test/Modules/Inputs/header-attribs/bar.h
Normal file
@ -0,0 +1 @@
|
||||
extern int b;
|
1
test/Modules/Inputs/header-attribs/baz.h
Normal file
1
test/Modules/Inputs/header-attribs/baz.h
Normal file
@ -0,0 +1 @@
|
||||
extern int c;
|
1
test/Modules/Inputs/header-attribs/foo.h
Normal file
1
test/Modules/Inputs/header-attribs/foo.h
Normal file
@ -0,0 +1 @@
|
||||
extern int a;
|
5
test/Modules/Inputs/header-attribs/modular.modulemap
Normal file
5
test/Modules/Inputs/header-attribs/modular.modulemap
Normal file
@ -0,0 +1,5 @@
|
||||
module A {
|
||||
header "foo.h" { size 13 }
|
||||
header "bar.h" { size 1000 }
|
||||
header "baz.h" { mtime 1 }
|
||||
}
|
5
test/Modules/Inputs/header-attribs/textual.modulemap
Normal file
5
test/Modules/Inputs/header-attribs/textual.modulemap
Normal file
@ -0,0 +1,5 @@
|
||||
module A {
|
||||
textual header "foo.h" { size 13 }
|
||||
textual header "bar.h" { size 1000 }
|
||||
textual header "baz.h" { mtime 1 }
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user