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