@@ -5381,11 +5381,12 @@ static const llvm::StringMap<std::vector<int>> STLConditionalParams{
53815381};
53825382
53835383template <typename Kind>
5384- static std::optional<Kind> checkConditionalParams (
5385- clang::RecordDecl *recordDecl, const std::vector<int > &STLParams,
5386- std::set<StringRef> &conditionalParams,
5387- std::function<std::optional<Kind>(clang::TemplateArgument &, StringRef)>
5388- &checkArg) {
5384+ static bool checkConditionalParams (
5385+ clang::RecordDecl *recordDecl, ClangImporter::Implementation *impl,
5386+ const std::vector<int > &STLParams, std::set<StringRef> &conditionalParams,
5387+ std::function<void (const clang::Type *)> &maybePushToStack) {
5388+ HeaderLoc loc{recordDecl->getLocation ()};
5389+ bool foundErrors = false ;
53895390 auto specDecl = cast<clang::ClassTemplateSpecializationDecl>(recordDecl);
53905391 SmallVector<std::pair<unsigned , StringRef>, 4 > argumentsToCheck;
53915392 bool hasInjectedSTLAnnotation = !STLParams.empty ();
@@ -5413,9 +5414,15 @@ static std::optional<Kind> checkConditionalParams(
54135414 } else
54145415 nonPackArgs.push_back (arg);
54155416 for (auto nonPackArg : nonPackArgs) {
5416- auto result = checkArg (nonPackArg, argToCheck.second );
5417- if (result.has_value ())
5418- return result.value ();
5417+ if (nonPackArg.getKind () != clang::TemplateArgument::Type) {
5418+ if (impl)
5419+ impl->diagnose (loc, diag::type_template_parameter_expected,
5420+ argToCheck.second );
5421+ foundErrors = true ;
5422+ } else {
5423+ maybePushToStack (
5424+ nonPackArg.getAsType ()->getUnqualifiedDesugaredType ());
5425+ }
54195426 }
54205427 }
54215428 if (hasInjectedSTLAnnotation)
@@ -5428,7 +5435,7 @@ static std::optional<Kind> checkConditionalParams(
54285435 break ;
54295436 }
54305437 }
5431- return std:: nullopt ;
5438+ return foundErrors ;
54325439}
54335440
54345441static std::set<StringRef>
@@ -5479,7 +5486,7 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
54795486 // Keep track of Decls we've seen to avoid cycles
54805487 llvm::SmallDenseSet<const clang::Type *, 4 > seen;
54815488
5482- auto maybePushToStack = [&](const clang::Type *type) {
5489+ std::function maybePushToStack = [&](const clang::Type *type) {
54835490 auto desugared = type->getUnqualifiedDesugaredType ();
54845491 if (seen.insert (desugared).second )
54855492 stack.push_back (desugared);
@@ -5505,28 +5512,15 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
55055512 auto conditionalParams = getConditionalEscapableAttrParams (recordDecl);
55065513
55075514 if (!STLParams.empty () || !conditionalParams.empty ()) {
5508- HeaderLoc loc{recordDecl->getLocation ()};
5509- std::function checkArgEscapability =
5510- [&](clang::TemplateArgument &arg,
5511- StringRef argToCheck) -> std::optional<CxxEscapability> {
5512- if (arg.getKind () != clang::TemplateArgument::Type) {
5513- if (desc.impl )
5514- desc.impl ->diagnose (loc, diag::type_template_parameter_expected,
5515- argToCheck);
5516- hasUnknown = true ;
5517- return std::nullopt ;
5518- }
5519- maybePushToStack (arg.getAsType ()->getUnqualifiedDesugaredType ());
5520- // FIXME don't return anything
5521- return std::nullopt ;
5522- };
5523-
5524- checkConditionalParams<CxxEscapability>(
5525- recordDecl, STLParams, conditionalParams, checkArgEscapability);
5515+ hasUnknown &= checkConditionalParams<CxxEscapability>(
5516+ recordDecl, desc.impl , STLParams, conditionalParams,
5517+ maybePushToStack);
55265518
5527- if (desc.impl )
5519+ if (desc.impl ) {
5520+ HeaderLoc loc{recordDecl->getLocation ()};
55285521 for (auto name : conditionalParams)
55295522 desc.impl ->diagnose (loc, diag::unknown_template_parameter, name);
5523+ }
55305524
55315525 continue ;
55325526 }
@@ -5538,11 +5532,9 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
55385532 if (recordDecl->getDefinition () &&
55395533 (!cxxRecordDecl || cxxRecordDecl->isAggregate ())) {
55405534 if (cxxRecordDecl) {
5541- // TODO llvm::foreach ?
55425535 for (auto base : cxxRecordDecl->bases ())
55435536 maybePushToStack (base.getType ()->getUnqualifiedDesugaredType ());
55445537 }
5545-
55465538 for (auto field : recordDecl->fields ())
55475539 maybePushToStack (field->getType ()->getUnqualifiedDesugaredType ());
55485540 continue ;
@@ -8464,7 +8456,7 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
84648456 // Keep track of Decls we've seen to avoid cycles
84658457 llvm::SmallDenseSet<clang::RecordDecl *, 4 > seen;
84668458
8467- auto maybePushToStack = [&](const clang::Type *type) {
8459+ std::function maybePushToStack = [&](const clang::Type *type) {
84688460 auto recordDecl = type->getAsRecordDecl ();
84698461 if (!recordDecl)
84708462 return ;
@@ -8519,11 +8511,14 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
85198511 };
85208512
85218513 checkConditionalParams<CxxValueSemanticsKind>(
8522- recordDecl, STLParams, conditionalParams, checkArgValueSemantics);
8514+ recordDecl, importerImpl, STLParams, conditionalParams,
8515+ maybePushToStack);
85238516
8524- if (importerImpl)
8517+ if (importerImpl) {
8518+ HeaderLoc loc{recordDecl->getLocation ()};
85258519 for (auto name : conditionalParams)
85268520 importerImpl->diagnose (loc, diag::unknown_template_parameter, name);
8521+ }
85278522
85288523 continue ;
85298524 }
0 commit comments