aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-10-21 13:31:11 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-08 17:35:41 +0000
commitbdb86d1a853a919764f65fdedcea76d76e4d619b (patch)
tree9192288f53762443b0d7453fd2d49bbbe0e344eb /contrib/llvm-project/clang
parent3bd749dbd90cc3b95719b65393df5ca8a0fe919d (diff)
parentcd255c5cf2441442b46200d298c0cbccf83caba5 (diff)
Diffstat (limited to 'contrib/llvm-project/clang')
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp24
-rw-r--r--contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h11
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp25
-rw-r--r--contrib/llvm-project/clang/utils/TableGen/ClangAttrEmitter.cpp17
5 files changed, 60 insertions, 19 deletions
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp
index eaec1d22e6e5..503dbf3f0dea 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -699,6 +699,8 @@ void toolchains::MinGW::addClangTargetOptions(
}
}
+ CC1Args.push_back("-fno-use-init-array");
+
for (auto Opt : {options::OPT_mthreads, options::OPT_mwindows,
options::OPT_mconsole, options::OPT_mdll}) {
if (Arg *A = DriverArgs.getLastArgNoClaim(Opt))
diff --git a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
index 852437b9390f..07ff86bc50a2 100644
--- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
@@ -173,10 +173,12 @@ void UnwrappedLineParser::reset() {
CommentsBeforeNextToken.clear();
FormatTok = nullptr;
MustBreakBeforeNextToken = false;
+ IsDecltypeAutoFunction = false;
PreprocessorDirectives.clear();
CurrentLines = &Lines;
DeclarationScopeStack.clear();
NestedTooDeep.clear();
+ NestedLambdas.clear();
PPStack.clear();
Line->FirstStartColumn = FirstStartColumn;
@@ -1757,6 +1759,17 @@ void UnwrappedLineParser::parseStructuralElement(
if (parseStructLike())
return;
break;
+ case tok::kw_decltype:
+ nextToken();
+ if (FormatTok->is(tok::l_paren)) {
+ parseParens();
+ assert(FormatTok->Previous);
+ if (FormatTok->Previous->endsSequence(tok::r_paren, tok::kw_auto,
+ tok::l_paren)) {
+ Line->SeenDecltypeAuto = true;
+ }
+ }
+ break;
case tok::period:
nextToken();
// In Java, classes have an implicit static member "class".
@@ -1818,6 +1831,7 @@ void UnwrappedLineParser::parseStructuralElement(
if (NextLBracesType != TT_Unknown)
FormatTok->setFinalizedType(NextLBracesType);
if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
+ IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
// A block outside of parentheses must be the last part of a
// structural element.
// FIXME: Figure out cases where this is not true, and add projections
@@ -1835,6 +1849,7 @@ void UnwrappedLineParser::parseStructuralElement(
}
FormatTok->setFinalizedType(TT_FunctionLBrace);
parseBlock();
+ IsDecltypeAutoFunction = false;
addUnwrappedLine();
return;
}
@@ -2249,9 +2264,15 @@ bool UnwrappedLineParser::tryToParseLambda() {
return true;
}
}
+
FormatTok->setFinalizedType(TT_LambdaLBrace);
LSquare.setFinalizedType(TT_LambdaLSquare);
+
+ NestedLambdas.push_back(Line->SeenDecltypeAuto);
parseChildBlock();
+ assert(!NestedLambdas.empty());
+ NestedLambdas.pop_back();
+
return true;
}
@@ -2471,6 +2492,8 @@ bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) {
PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
const bool ReturnParens =
Style.RemoveParentheses == FormatStyle::RPS_ReturnStatement &&
+ ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
+ (!NestedLambdas.empty() && !NestedLambdas.back())) &&
Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
Next->is(tok::semi);
if ((DoubleParens && !Blacklisted) || ReturnParens) {
@@ -4386,6 +4409,7 @@ void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
Line->MatchingOpeningBlockLineIndex = UnwrappedLine::kInvalidIndex;
Line->FirstStartColumn = 0;
Line->IsContinuation = false;
+ Line->SeenDecltypeAuto = false;
if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
--Line->Level;
diff --git a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h
index 57515af64a3e..96248d130ddb 100644
--- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h
+++ b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h
@@ -61,6 +61,9 @@ struct UnwrappedLine {
bool MustBeDeclaration;
+ /// Whether the parser has seen \c decltype(auto) in this line.
+ bool SeenDecltypeAuto = false;
+
/// \c True if this line should be indented by ContinuationIndent in
/// addition to the normal indention level.
bool IsContinuation = false;
@@ -341,6 +344,14 @@ private:
// statement contains more than some predefined number of nested statements).
SmallVector<bool, 8> NestedTooDeep;
+ // Keeps a stack of the states of nested lambdas (true if the return type of
+ // the lambda is `decltype(auto)`).
+ SmallVector<bool, 4> NestedLambdas;
+
+ // Whether the parser is parsing the body of a function whose return type is
+ // `decltype(auto)`.
+ bool IsDecltypeAutoFunction = false;
+
// Represents preprocessor branch type, so we can find matching
// #if/#else/#endif directives.
enum PPBranchKind {
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp
index 8626fc6ea16f..a94f009f3fa6 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp
@@ -11166,12 +11166,15 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
ImplicitMatch == ArgType::NoMatchTypeConfusion)
Match = ImplicitMatch;
assert(Match != ArgType::MatchPromotion);
+
// Look through unscoped enums to their underlying type.
bool IsEnum = false;
bool IsScopedEnum = false;
+ QualType IntendedTy = ExprTy;
if (auto EnumTy = ExprTy->getAs<EnumType>()) {
+ IntendedTy = EnumTy->getDecl()->getIntegerType();
if (EnumTy->isUnscopedEnumerationType()) {
- ExprTy = EnumTy->getDecl()->getIntegerType();
+ ExprTy = IntendedTy;
// This controls whether we're talking about the underlying type or not,
// which we only want to do when it's an unscoped enum.
IsEnum = true;
@@ -11183,7 +11186,6 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
// %C in an Objective-C context prints a unichar, not a wchar_t.
// If the argument is an integer of some kind, believe the %C and suggest
// a cast instead of changing the conversion specifier.
- QualType IntendedTy = ExprTy;
if (isObjCContext() &&
FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {
if (ExprTy->isIntegralOrUnscopedEnumerationType() &&
@@ -11219,8 +11221,10 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
std::tie(CastTy, CastTyName) = shouldNotPrintDirectly(S.Context, IntendedTy, E);
if (!CastTy.isNull()) {
// %zi/%zu and %td/%tu are OK to use for NSInteger/NSUInteger of type int
- // (long in ASTContext). Only complain to pedants.
- if ((CastTyName == "NSInteger" || CastTyName == "NSUInteger") &&
+ // (long in ASTContext). Only complain to pedants or when they're the
+ // underlying type of a scoped enum (which always needs a cast).
+ if (!IsScopedEnum &&
+ (CastTyName == "NSInteger" || CastTyName == "NSUInteger") &&
(AT.isSizeT() || AT.isPtrdiffT()) &&
AT.matchesType(S.Context, CastTy))
Match = ArgType::NoMatchPedantic;
@@ -11275,20 +11279,15 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
// should be printed as 'long' for 64-bit compatibility.)
// Rather than emitting a normal format/argument mismatch, we want to
// add a cast to the recommended type (and correct the format string
- // if necessary).
+ // if necessary). We should also do so for scoped enumerations.
SmallString<16> CastBuf;
llvm::raw_svector_ostream CastFix(CastBuf);
CastFix << (S.LangOpts.CPlusPlus ? "static_cast<" : "(");
- if (IsScopedEnum) {
- CastFix << AT.getRepresentativeType(S.Context).getAsString(
- S.Context.getPrintingPolicy());
- } else {
- IntendedTy.print(CastFix, S.Context.getPrintingPolicy());
- }
+ IntendedTy.print(CastFix, S.Context.getPrintingPolicy());
CastFix << (S.LangOpts.CPlusPlus ? ">" : ")");
SmallVector<FixItHint,4> Hints;
- if ((!AT.matchesType(S.Context, IntendedTy) && !IsScopedEnum) ||
+ if (AT.matchesType(S.Context, IntendedTy) != ArgType::Match ||
ShouldNotPrintDirectly)
Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str()));
@@ -11316,7 +11315,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
Hints.push_back(FixItHint::CreateInsertion(After, ")"));
}
- if (ShouldNotPrintDirectly) {
+ if (ShouldNotPrintDirectly && !IsScopedEnum) {
// The expression has a type that should not be printed directly.
// We extract the name from the typedef because we don't want to show
// the underlying type in the diagnostic.
diff --git a/contrib/llvm-project/clang/utils/TableGen/ClangAttrEmitter.cpp b/contrib/llvm-project/clang/utils/TableGen/ClangAttrEmitter.cpp
index 8ef728f86c6b..b5813c6abc2b 100644
--- a/contrib/llvm-project/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/contrib/llvm-project/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2639,7 +2639,8 @@ static void emitAttributes(RecordKeeper &Records, raw_ostream &OS,
OS << ", ";
emitFormInitializer(OS, Spellings[0], "0");
} else {
- OS << ", (\n";
+ OS << ", [&]() {\n";
+ OS << " switch (S) {\n";
std::set<std::string> Uniques;
unsigned Idx = 0;
for (auto I = Spellings.begin(), E = Spellings.end(); I != E;
@@ -2647,15 +2648,19 @@ static void emitAttributes(RecordKeeper &Records, raw_ostream &OS,
const FlattenedSpelling &S = *I;
const auto &Name = SemanticToSyntacticMap[Idx];
if (Uniques.insert(Name).second) {
- OS << " S == " << Name << " ? AttributeCommonInfo::Form";
+ OS << " case " << Name << ":\n";
+ OS << " return AttributeCommonInfo::Form";
emitFormInitializer(OS, S, Name);
- OS << " :\n";
+ OS << ";\n";
}
}
- OS << " (llvm_unreachable(\"Unknown attribute spelling!\"), "
- << " AttributeCommonInfo::Form";
+ OS << " default:\n";
+ OS << " llvm_unreachable(\"Unknown attribute spelling!\");\n"
+ << " return AttributeCommonInfo::Form";
emitFormInitializer(OS, Spellings[0], "0");
- OS << "))";
+ OS << ";\n"
+ << " }\n"
+ << " }()";
}
OS << ");\n";