@@ -5402,11 +5402,12 @@ static const llvm::StringMap<std::vector<int>> STLConditionalParams{
54025402};
54035403
54045404template <typename Kind>
5405- static std::optional<Kind> checkConditionalParams (
5406- clang::RecordDecl *recordDecl, const std::vector<int > &STLParams,
5407- std::set<StringRef> &conditionalParams,
5408- std::function<std::optional<Kind>(clang::TemplateArgument &, StringRef)>
5409- &checkArg) {
5405+ static bool checkConditionalParams (
5406+ clang::RecordDecl *recordDecl, ClangImporter::Implementation *impl,
5407+ const std::vector<int > &STLParams, std::set<StringRef> &conditionalParams,
5408+ std::function<void (const clang::Type *)> &maybePushToStack) {
5409+ HeaderLoc loc{recordDecl->getLocation ()};
5410+ bool foundErrors = false ;
54105411 auto specDecl = cast<clang::ClassTemplateSpecializationDecl>(recordDecl);
54115412 SmallVector<std::pair<unsigned , StringRef>, 4 > argumentsToCheck;
54125413 bool hasInjectedSTLAnnotation = !STLParams.empty ();
@@ -5434,9 +5435,15 @@ static std::optional<Kind> checkConditionalParams(
54345435 } else
54355436 nonPackArgs.push_back (arg);
54365437 for (auto nonPackArg : nonPackArgs) {
5437- auto result = checkArg (nonPackArg, argToCheck.second );
5438- if (result.has_value ())
5439- return result.value ();
5438+ if (nonPackArg.getKind () != clang::TemplateArgument::Type) {
5439+ if (impl)
5440+ impl->diagnose (loc, diag::type_template_parameter_expected,
5441+ argToCheck.second );
5442+ foundErrors = true ;
5443+ } else {
5444+ maybePushToStack (
5445+ nonPackArg.getAsType ()->getUnqualifiedDesugaredType ());
5446+ }
54405447 }
54415448 }
54425449 if (hasInjectedSTLAnnotation)
@@ -5449,7 +5456,7 @@ static std::optional<Kind> checkConditionalParams(
54495456 break ;
54505457 }
54515458 }
5452- return std:: nullopt ;
5459+ return foundErrors ;
54535460}
54545461
54555462static std::set<StringRef>
@@ -5500,7 +5507,7 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
55005507 // Keep track of Decls we've seen to avoid cycles
55015508 llvm::SmallDenseSet<const clang::Type *, 4 > seen;
55025509
5503- auto maybePushToStack = [&](const clang::Type *type) {
5510+ std::function maybePushToStack = [&](const clang::Type *type) {
55045511 auto desugared = type->getUnqualifiedDesugaredType ();
55055512 if (seen.insert (desugared).second )
55065513 stack.push_back (desugared);
@@ -5526,28 +5533,15 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
55265533 auto conditionalParams = getConditionalEscapableAttrParams (recordDecl);
55275534
55285535 if (!STLParams.empty () || !conditionalParams.empty ()) {
5529- HeaderLoc loc{recordDecl->getLocation ()};
5530- std::function checkArgEscapability =
5531- [&](clang::TemplateArgument &arg,
5532- StringRef argToCheck) -> std::optional<CxxEscapability> {
5533- if (arg.getKind () != clang::TemplateArgument::Type) {
5534- if (desc.impl )
5535- desc.impl ->diagnose (loc, diag::type_template_parameter_expected,
5536- argToCheck);
5537- hasUnknown = true ;
5538- return std::nullopt ;
5539- }
5540- maybePushToStack (arg.getAsType ()->getUnqualifiedDesugaredType ());
5541- // FIXME don't return anything
5542- return std::nullopt ;
5543- };
5544-
5545- checkConditionalParams<CxxEscapability>(
5546- recordDecl, STLParams, conditionalParams, checkArgEscapability);
5536+ hasUnknown &= checkConditionalParams<CxxEscapability>(
5537+ recordDecl, desc.impl , STLParams, conditionalParams,
5538+ maybePushToStack);
55475539
5548- if (desc.impl )
5540+ if (desc.impl ) {
5541+ HeaderLoc loc{recordDecl->getLocation ()};
55495542 for (auto name : conditionalParams)
55505543 desc.impl ->diagnose (loc, diag::unknown_template_parameter, name);
5544+ }
55515545
55525546 continue ;
55535547 }
@@ -5559,11 +5553,9 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
55595553 if (recordDecl->getDefinition () &&
55605554 (!cxxRecordDecl || cxxRecordDecl->isAggregate ())) {
55615555 if (cxxRecordDecl) {
5562- // TODO llvm::foreach ?
55635556 for (auto base : cxxRecordDecl->bases ())
55645557 maybePushToStack (base.getType ()->getUnqualifiedDesugaredType ());
55655558 }
5566-
55675559 for (auto field : recordDecl->fields ())
55685560 maybePushToStack (field->getType ()->getUnqualifiedDesugaredType ());
55695561 continue ;
@@ -8485,7 +8477,7 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
84858477 // Keep track of Decls we've seen to avoid cycles
84868478 llvm::SmallDenseSet<clang::RecordDecl *, 4 > seen;
84878479
8488- auto maybePushToStack = [&](const clang::Type *type) {
8480+ std::function maybePushToStack = [&](const clang::Type *type) {
84898481 auto recordDecl = type->getAsRecordDecl ();
84908482 if (!recordDecl)
84918483 return ;
@@ -8540,11 +8532,14 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
85408532 };
85418533
85428534 checkConditionalParams<CxxValueSemanticsKind>(
8543- recordDecl, STLParams, conditionalParams, checkArgValueSemantics);
8535+ recordDecl, importerImpl, STLParams, conditionalParams,
8536+ maybePushToStack);
85448537
8545- if (importerImpl)
8538+ if (importerImpl) {
8539+ HeaderLoc loc{recordDecl->getLocation ()};
85468540 for (auto name : conditionalParams)
85478541 importerImpl->diagnose (loc, diag::unknown_template_parameter, name);
8542+ }
85488543
85498544 continue ;
85508545 }
0 commit comments