|
52 | 52 | #include "swift/Strings.h" |
53 | 53 | #include "swift/Subsystems.h" |
54 | 54 | #include "clang/AST/ASTContext.h" |
| 55 | +#include "clang/AST/DeclCXX.h" |
55 | 56 | #include "clang/AST/Mangle.h" |
| 57 | +#include "clang/AST/Type.h" |
56 | 58 | #include "clang/Basic/DiagnosticOptions.h" |
57 | 59 | #include "clang/Basic/FileEntry.h" |
58 | 60 | #include "clang/Basic/IdentifierTable.h" |
@@ -5018,6 +5020,74 @@ TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate( |
5018 | 5020 | return result; |
5019 | 5021 | } |
5020 | 5022 |
|
| 5023 | +CxxEscapability |
| 5024 | +ClangTypeEscapability::evaluate(Evaluator &evaluator, |
| 5025 | + EscapabilityLookupDescriptor desc) const { |
| 5026 | + auto desugared = desc.type->getUnqualifiedDesugaredType(); |
| 5027 | + if (const auto *recordType = desugared->getAs<clang::RecordType>()) { |
| 5028 | + if (importer::hasNonEscapableAttr(recordType->getDecl())) |
| 5029 | + return CxxEscapability::NonEscapable; |
| 5030 | + if (importer::hasEscapableAttr(recordType->getDecl())) |
| 5031 | + return CxxEscapability::Escapable; |
| 5032 | + auto recordDecl = recordType->getDecl(); |
| 5033 | + auto cxxRecordDecl = dyn_cast<clang::CXXRecordDecl>(recordDecl); |
| 5034 | + if (!cxxRecordDecl || cxxRecordDecl->isAggregate()) { |
| 5035 | + bool hadUnknown = false; |
| 5036 | + auto evaluateEscapability = [&](const clang::Type *type) { |
| 5037 | + auto escapability = evaluateOrDefault( |
| 5038 | + evaluator, ClangTypeEscapability({type}), CxxEscapability::Unknown); |
| 5039 | + if (escapability == CxxEscapability::Unknown) |
| 5040 | + hadUnknown = true; |
| 5041 | + return escapability; |
| 5042 | + }; |
| 5043 | + |
| 5044 | + if (cxxRecordDecl) { |
| 5045 | + for (auto base : cxxRecordDecl->bases()) { |
| 5046 | + auto baseEscapability = evaluateEscapability( |
| 5047 | + base.getType()->getUnqualifiedDesugaredType()); |
| 5048 | + if (baseEscapability == CxxEscapability::NonEscapable) |
| 5049 | + return CxxEscapability::NonEscapable; |
| 5050 | + } |
| 5051 | + } |
| 5052 | + |
| 5053 | + for (auto field : recordDecl->fields()) { |
| 5054 | + auto fieldEscapability = evaluateEscapability( |
| 5055 | + field->getType()->getUnqualifiedDesugaredType()); |
| 5056 | + if (fieldEscapability == CxxEscapability::NonEscapable) |
| 5057 | + return CxxEscapability::NonEscapable; |
| 5058 | + } |
| 5059 | + |
| 5060 | + return hadUnknown ? CxxEscapability::Unknown : CxxEscapability::Escapable; |
| 5061 | + } |
| 5062 | + } |
| 5063 | + if (desugared->isArrayType()) { |
| 5064 | + auto elemTy = cast<clang::ArrayType>(desugared) |
| 5065 | + ->getElementType() |
| 5066 | + ->getUnqualifiedDesugaredType(); |
| 5067 | + return evaluateOrDefault(evaluator, ClangTypeEscapability({elemTy}), |
| 5068 | + CxxEscapability::Unknown); |
| 5069 | + } |
| 5070 | + |
| 5071 | + // Base cases |
| 5072 | + if (desugared->isAnyPointerType() || desugared->isBlockPointerType() || |
| 5073 | + desugared->isMemberPointerType() || desugared->isReferenceType()) |
| 5074 | + return CxxEscapability::NonEscapable; |
| 5075 | + if (desugared->isScalarType()) |
| 5076 | + return CxxEscapability::Escapable; |
| 5077 | + return CxxEscapability::Unknown; |
| 5078 | +} |
| 5079 | + |
| 5080 | +void swift::simple_display(llvm::raw_ostream &out, |
| 5081 | + EscapabilityLookupDescriptor desc) { |
| 5082 | + out << "Computing escapability for type '"; |
| 5083 | + out << clang::QualType(desc.type, 0).getAsString(); |
| 5084 | + out << "'"; |
| 5085 | +} |
| 5086 | + |
| 5087 | +SourceLoc swift::extractNearestSourceLoc(EscapabilityLookupDescriptor) { |
| 5088 | + return SourceLoc(); |
| 5089 | +} |
| 5090 | + |
5021 | 5091 | // Just create a specialized function decl for "__swift_interopStaticCast" |
5022 | 5092 | // using the types base and derived. |
5023 | 5093 | static |
|
0 commit comments