|
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