|
36 | 36 | #include "swift/AST/NameLookupRequests.h" |
37 | 37 | #include "swift/AST/PrettyStackTrace.h" |
38 | 38 | #include "swift/AST/SourceFile.h" |
| 39 | +#include "swift/AST/Type.h" |
39 | 40 | #include "swift/AST/TypeCheckRequests.h" |
40 | 41 | #include "swift/AST/Types.h" |
41 | 42 | #include "swift/Basic/Assertions.h" |
|
51 | 52 | #include "swift/Strings.h" |
52 | 53 | #include "swift/Subsystems.h" |
53 | 54 | #include "clang/AST/ASTContext.h" |
| 55 | +#include "clang/AST/DeclBase.h" |
54 | 56 | #include "clang/AST/DeclCXX.h" |
55 | 57 | #include "clang/AST/DeclTemplate.h" |
56 | 58 | #include "clang/AST/Mangle.h" |
@@ -5080,31 +5082,41 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator, |
5080 | 5082 | importer::getConditionalEscapableAttrParams(recordDecl); |
5081 | 5083 | if (!conditionalParams.empty()) { |
5082 | 5084 | auto specDecl = cast<clang::ClassTemplateSpecializationDecl>(recordDecl); |
5083 | | - auto templateDecl = specDecl->getSpecializedTemplate(); |
5084 | 5085 | SmallVector<std::pair<unsigned, StringRef>, 4> argumentsToCheck; |
5085 | | - for (auto [idx, param] : |
5086 | | - llvm::enumerate(*templateDecl->getTemplateParameters())) { |
5087 | | - if (conditionalParams.erase(param->getName())) |
5088 | | - argumentsToCheck.push_back(std::make_pair(idx, param->getName())); |
5089 | | - } |
5090 | 5086 | HeaderLoc loc{recordDecl->getLocation()}; |
5091 | | - for (auto name : conditionalParams) |
5092 | | - desc.impl.diagnose(loc, diag::unknown_template_parameter, name); |
5093 | | - |
5094 | | - auto &argList = specDecl->getTemplateArgs(); |
5095 | | - for (auto argToCheck : argumentsToCheck) { |
5096 | | - auto arg = argList[argToCheck.first]; |
5097 | | - if (arg.getKind() != clang::TemplateArgument::Type) { |
5098 | | - desc.impl.diagnose(loc, diag::type_template_parameter_expected, |
5099 | | - argToCheck.second); |
5100 | | - return CxxEscapability::Unknown; |
| 5087 | + while (specDecl) { |
| 5088 | + auto templateDecl = specDecl->getSpecializedTemplate(); |
| 5089 | + for (auto [idx, param] : |
| 5090 | + llvm::enumerate(*templateDecl->getTemplateParameters())) { |
| 5091 | + if (conditionalParams.erase(param->getName())) |
| 5092 | + argumentsToCheck.push_back(std::make_pair(idx, param->getName())); |
5101 | 5093 | } |
| 5094 | + auto &argList = specDecl->getTemplateArgs(); |
| 5095 | + for (auto argToCheck : argumentsToCheck) { |
| 5096 | + auto arg = argList[argToCheck.first]; |
| 5097 | + if (arg.getKind() != clang::TemplateArgument::Type) { |
| 5098 | + desc.impl.diagnose(loc, diag::type_template_parameter_expected, |
| 5099 | + argToCheck.second); |
| 5100 | + return CxxEscapability::Unknown; |
| 5101 | + } |
5102 | 5102 |
|
5103 | | - auto argEscapability = evaluateEscapability( |
5104 | | - arg.getAsType()->getUnqualifiedDesugaredType()); |
5105 | | - if (argEscapability == CxxEscapability::NonEscapable) |
5106 | | - return CxxEscapability::NonEscapable; |
| 5103 | + auto argEscapability = evaluateEscapability( |
| 5104 | + arg.getAsType()->getUnqualifiedDesugaredType()); |
| 5105 | + if (argEscapability == CxxEscapability::NonEscapable) |
| 5106 | + return CxxEscapability::NonEscapable; |
| 5107 | + } |
| 5108 | + clang::DeclContext *rec = specDecl; |
| 5109 | + specDecl = nullptr; |
| 5110 | + while ((rec = rec->getParent())) { |
| 5111 | + specDecl = dyn_cast<clang::ClassTemplateSpecializationDecl>(rec); |
| 5112 | + if (specDecl) |
| 5113 | + break; |
| 5114 | + } |
5107 | 5115 | } |
| 5116 | + |
| 5117 | + for (auto name : conditionalParams) |
| 5118 | + desc.impl.diagnose(loc, diag::unknown_template_parameter, name); |
| 5119 | + |
5108 | 5120 | return hadUnknown ? CxxEscapability::Unknown : CxxEscapability::Escapable; |
5109 | 5121 | } |
5110 | 5122 | if (desc.annotationOnly) |
|
0 commit comments