|
61 | 61 | #include "clang/AST/DeclCXX.h"
|
62 | 62 | #include "clang/AST/DeclObjCCommon.h"
|
63 | 63 | #include "clang/AST/PrettyPrinter.h"
|
| 64 | +#include "clang/AST/DeclTemplate.h" |
64 | 65 | #include "clang/AST/Type.h"
|
65 | 66 | #include "clang/Basic/Specifiers.h"
|
66 | 67 | #include "clang/Basic/TargetInfo.h"
|
@@ -2178,6 +2179,29 @@ namespace {
|
2178 | 2179 | dc);
|
2179 | 2180 | Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;
|
2180 | 2181 |
|
| 2182 | + // We have to do this after populating ImportedDecls to avoid importing |
| 2183 | + // the same multiple times. |
| 2184 | + if (Impl.SwiftContext.LangOpts.hasFeature(Feature::SafeInterop) && |
| 2185 | + Impl.SwiftContext.LangOpts.hasFeature( |
| 2186 | + Feature::AllowUnsafeAttribute)) { |
| 2187 | + if (const auto *ctsd = |
| 2188 | + dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) { |
| 2189 | + for (auto arg : ctsd->getTemplateArgs().asArray()) { |
| 2190 | + if (arg.getKind() != clang::TemplateArgument::Type) |
| 2191 | + continue; |
| 2192 | + auto SwiftType = Impl.importTypeIgnoreIUO( |
| 2193 | + arg.getAsType(), ImportTypeKind::Abstract, |
| 2194 | + [](Diagnostic &&diag) {}, false, Bridgeability::None, |
| 2195 | + ImportTypeAttrs()); |
| 2196 | + if (SwiftType && SwiftType->isUnsafe()) { |
| 2197 | + auto attr = new (Impl.SwiftContext) UnsafeAttr(/*implicit=*/true); |
| 2198 | + result->getAttrs().add(attr); |
| 2199 | + break; |
| 2200 | + } |
| 2201 | + } |
| 2202 | + } |
| 2203 | + } |
| 2204 | + |
2181 | 2205 | if (recordHasMoveOnlySemantics(decl)) {
|
2182 | 2206 | if (decl->isInStdNamespace() && decl->getName() == "promise") {
|
2183 | 2207 | // Do not import std::promise.
|
@@ -3001,14 +3025,14 @@ namespace {
|
3001 | 3025 | bool isSpecializationDepthGreaterThan(
|
3002 | 3026 | const clang::ClassTemplateSpecializationDecl *decl, unsigned maxDepth) {
|
3003 | 3027 | for (auto arg : decl->getTemplateArgs().asArray()) {
|
3004 |
| - if (arg.getKind() == clang::TemplateArgument::Type) { |
3005 |
| - if (auto classSpec = |
3006 |
| - dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>( |
3007 |
| - arg.getAsType()->getAsCXXRecordDecl())) { |
3008 |
| - if (maxDepth == 0 || |
3009 |
| - isSpecializationDepthGreaterThan(classSpec, maxDepth - 1)) |
3010 |
| - return true; |
3011 |
| - } |
| 3028 | + if (arg.getKind() != clang::TemplateArgument::Type) |
| 3029 | + continue; |
| 3030 | + if (auto classSpec = |
| 3031 | + dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>( |
| 3032 | + arg.getAsType()->getAsCXXRecordDecl())) { |
| 3033 | + if (maxDepth == 0 || |
| 3034 | + isSpecializationDepthGreaterThan(classSpec, maxDepth - 1)) |
| 3035 | + return true; |
3012 | 3036 | }
|
3013 | 3037 | }
|
3014 | 3038 | return false;
|
@@ -8387,6 +8411,13 @@ static bool importAsUnsafe(ClangImporter::Implementation &impl,
|
8387 | 8411 | if (isa<ClassDecl>(MappedDecl))
|
8388 | 8412 | return false;
|
8389 | 8413 |
|
| 8414 | + // Most STL containers have std::allocator as their default allocator. We need |
| 8415 | + // to consider std::allocator safe for the STL containers to be ever |
| 8416 | + // considered safe. |
| 8417 | + if (decl->isInStdNamespace() && decl->getIdentifier() && |
| 8418 | + decl->getName() == "allocator") |
| 8419 | + return false; |
| 8420 | + |
8390 | 8421 | if (const auto *record = dyn_cast<clang::RecordDecl>(decl))
|
8391 | 8422 | return evaluateOrDefault(
|
8392 | 8423 | context.evaluator,
|
|
0 commit comments