diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-10-21 13:31:11 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-08 17:35:41 +0000 |
commit | bdb86d1a853a919764f65fdedcea76d76e4d619b (patch) | |
tree | 9192288f53762443b0d7453fd2d49bbbe0e344eb /contrib/llvm-project/clang | |
parent | 3bd749dbd90cc3b95719b65393df5ca8a0fe919d (diff) | |
parent | cd255c5cf2441442b46200d298c0cbccf83caba5 (diff) |
Diffstat (limited to 'contrib/llvm-project/clang')
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"; |