Index: lib/Sema/SemaCodeComplete.cpp =================================================================== --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -8371,10 +8371,31 @@ }; // Helper: scans IncludeDir for nice files, and adds results for each. - auto AddFilesFromIncludeDir = [&](StringRef IncludeDir, bool IsSystem) { + auto AddFilesFromIncludeDir = [&](StringRef IncludeDir, bool IsSystem, + bool isFramework) { + bool stripFrameworkSuffix = false; llvm::SmallString<128> Dir = IncludeDir; - if (!NativeRelDir.empty()) + if (isFramework) { + if (NativeRelDir.empty()) { + stripFrameworkSuffix = true; + } else { + auto Begin = llvm::sys::path::begin(NativeRelDir); + auto End = llvm::sys::path::end(NativeRelDir); + + if (Begin != End) { + SmallString<32> Framework = *Begin; + Framework += ".framework"; + llvm::sys::path::append(Dir, Framework, "Headers"); + llvm::sys::path::append(Dir, ++Begin, End); + } else { + SmallString<32> Framework(NativeRelDir); + Framework += ".framework"; + llvm::sys::path::append(Dir, Framework, "Headers"); + } + } + } else if (!NativeRelDir.empty()) { llvm::sys::path::append(Dir, NativeRelDir); + } std::error_code EC; unsigned Count = 0; @@ -8385,7 +8406,12 @@ StringRef Filename = llvm::sys::path::filename(It->path()); switch (It->type()) { case llvm::sys::fs::file_type::directory_file: - AddCompletion(Filename, /*IsDirectory=*/true); + if (stripFrameworkSuffix && Filename.endswith(".framework")) { + auto FrameworkName = Filename.substr(0, Filename.size() - 10); + AddCompletion(FrameworkName, /*IsDirectory=*/true); + } else { + AddCompletion(Filename, /*IsDirectory=*/true); + } break; case llvm::sys::fs::file_type::regular_file: // Only files that really look like headers. (Except in system dirs). @@ -8413,10 +8439,12 @@ // header maps are not (currently) enumerable. break; case DirectoryLookup::LT_NormalDir: - AddFilesFromIncludeDir(IncludeDir.getDir()->getName(), IsSystem); + AddFilesFromIncludeDir(IncludeDir.getDir()->getName(), IsSystem, + /*IsFramework*/false); break; case DirectoryLookup::LT_Framework: - AddFilesFromIncludeDir(IncludeDir.getFrameworkDir()->getName(), IsSystem); + AddFilesFromIncludeDir(IncludeDir.getFrameworkDir()->getName(), IsSystem, + /*IsFramework*/true); break; } }; @@ -8430,7 +8458,7 @@ // The current directory is on the include path for "quoted" includes. auto *CurFile = PP.getCurrentFileLexer()->getFileEntry(); if (CurFile && CurFile->getDir()) - AddFilesFromIncludeDir(CurFile->getDir()->getName(), false); + AddFilesFromIncludeDir(CurFile->getDir()->getName(), false, false); for (const auto &D : make_range(S.quoted_dir_begin(), S.quoted_dir_end())) AddFilesFromDirLookup(D, false); }