|
77 | 77 | #include "llvm/Support/Path.h"
|
78 | 78 | #include "llvm/Support/VirtualFileSystem.h"
|
79 | 79 | #include "llvm/Support/VirtualOutputBackend.h"
|
80 |
| -#include "llvm/Support/YAMLParser.h" |
| 80 | +#include "llvm/TextAPI/InterfaceFile.h" |
| 81 | +#include "llvm/TextAPI/TextAPIReader.h" |
81 | 82 | #include <algorithm>
|
82 | 83 | #include <memory>
|
83 | 84 | #include <string>
|
@@ -1934,9 +1935,29 @@ bool ClangImporter::isModuleImported(const clang::Module *M) {
|
1934 | 1935 | return M->NameVisibility == clang::Module::NameVisibilityKind::AllVisible;
|
1935 | 1936 | }
|
1936 | 1937 |
|
1937 |
| -static std::string getScalaNodeText(llvm::yaml::Node *N) { |
1938 |
| - SmallString<32> Buffer; |
1939 |
| - return cast<llvm::yaml::ScalarNode>(N)->getValue(Buffer).str(); |
| 1938 | +static llvm::VersionTuple getCurrentVersionFromTBD(StringRef path, |
| 1939 | + StringRef moduleName) { |
| 1940 | + std::string fwName = (moduleName + ".framework").str(); |
| 1941 | + auto pos = path.find(fwName); |
| 1942 | + if (pos == StringRef::npos) |
| 1943 | + return {}; |
| 1944 | + llvm::SmallString<256> buffer(path.substr(0, pos + fwName.size())); |
| 1945 | + llvm::sys::path::append(buffer, moduleName + ".tbd"); |
| 1946 | + auto tbdPath = buffer.str(); |
| 1947 | + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> tbdBufOrErr = |
| 1948 | + llvm::MemoryBuffer::getFile(tbdPath); |
| 1949 | + // .tbd file doesn't exist, exit. |
| 1950 | + if (!tbdBufOrErr) |
| 1951 | + return {}; |
| 1952 | + auto tbdFileOrErr = |
| 1953 | + llvm::MachO::TextAPIReader::get(tbdBufOrErr.get()->getMemBufferRef()); |
| 1954 | + if (auto err = tbdFileOrErr.takeError()) { |
| 1955 | + consumeError(std::move(err)); |
| 1956 | + return {}; |
| 1957 | + } |
| 1958 | + auto tbdCV = (*tbdFileOrErr)->getCurrentVersion(); |
| 1959 | + return llvm::VersionTuple(tbdCV.getMajor(), tbdCV.getMinor(), |
| 1960 | + tbdCV.getSubminor()); |
1940 | 1961 | }
|
1941 | 1962 |
|
1942 | 1963 | bool ClangImporter::canImportModule(ImportPath::Module modulePath,
|
@@ -1988,49 +2009,13 @@ bool ClangImporter::canImportModule(ImportPath::Module modulePath,
|
1988 | 2009 | return true;
|
1989 | 2010 |
|
1990 | 2011 | assert(available);
|
1991 |
| - llvm::VersionTuple currentVersion; |
1992 | 2012 | StringRef path = getClangASTContext().getSourceManager()
|
1993 | 2013 | .getFilename(clangModule->DefinitionLoc);
|
| 2014 | + |
1994 | 2015 | // Look for the .tbd file inside .framework dir to get the project version
|
1995 | 2016 | // number.
|
1996 |
| - std::string fwName = (llvm::Twine(topModule.Item.str()) + ".framework").str(); |
1997 |
| - auto pos = path.find(fwName); |
1998 |
| - while (pos != StringRef::npos) { |
1999 |
| - llvm::SmallString<256> buffer(path.substr(0, pos + fwName.size())); |
2000 |
| - llvm::sys::path::append(buffer, llvm::Twine(topModule.Item.str()) + ".tbd"); |
2001 |
| - auto tbdPath = buffer.str(); |
2002 |
| - llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> tbdBufOrErr = |
2003 |
| - llvm::MemoryBuffer::getFile(tbdPath); |
2004 |
| - // .tbd file doesn't exist, break. |
2005 |
| - if (!tbdBufOrErr) { |
2006 |
| - break; |
2007 |
| - } |
2008 |
| - StringRef tbdBuffer = tbdBufOrErr->get()->getBuffer(); |
2009 |
| - |
2010 |
| - // Use a new source manager instead of the one from ASTContext because we |
2011 |
| - // don't want the Json file to be persistent. |
2012 |
| - SourceManager SM; |
2013 |
| - llvm::yaml::Stream Stream(llvm::MemoryBufferRef(tbdBuffer, tbdPath), |
2014 |
| - SM.getLLVMSourceMgr()); |
2015 |
| - auto DI = Stream.begin(); |
2016 |
| - assert(DI != Stream.end() && "Failed to read a document"); |
2017 |
| - llvm::yaml::Node *N = DI->getRoot(); |
2018 |
| - assert(N && "Failed to find a root"); |
2019 |
| - auto *pairs = dyn_cast_or_null<llvm::yaml::MappingNode>(N); |
2020 |
| - if (!pairs) |
2021 |
| - break; |
2022 |
| - for (auto &keyValue: *pairs) { |
2023 |
| - auto key = getScalaNodeText(keyValue.getKey()); |
2024 |
| - // Look for field "current-version" in the .tbd file. |
2025 |
| - if (key == "current-version") { |
2026 |
| - auto ver = getScalaNodeText(keyValue.getValue()); |
2027 |
| - currentVersion.tryParse(ver); |
2028 |
| - break; |
2029 |
| - } |
2030 |
| - } |
2031 |
| - break; |
2032 |
| - } |
2033 |
| - |
| 2017 | + llvm::VersionTuple currentVersion = |
| 2018 | + getCurrentVersionFromTBD(path, topModule.Item.str()); |
2034 | 2019 | versionInfo->setVersion(currentVersion,
|
2035 | 2020 | ModuleVersionSourceKind::ClangModuleTBD);
|
2036 | 2021 | return true;
|
|
0 commit comments