// \brief A list of late parsed template function data.
SmallVector<uint64_t, 1> LateParsedTemplates;
+ struct ImportedSubmodule {
+ serialization::SubmoduleID ID;
+ SourceLocation ImportLoc;
+ };
+
/// \brief A list of modules that were imported by precompiled headers or
/// any other non-module AST file.
- SmallVector<serialization::SubmoduleID, 2> ImportedModules;
+ SmallVector<ImportedSubmodule, 2> ImportedModules;
//@}
/// \brief The directory that the PCH we are reading is stored in.
// Use the location at which the containing module file was first imported
// for now.
ImportLoc = MMI->F->DirectImportLoc;
+ assert(ImportLoc.isValid() && "no import location for a visible macro?");
}
llvm::SmallVectorImpl<DefMacroDirective*> *Prev =
// If we aren't loading a module (which has its own exports), make
// all of the imported modules visible.
// FIXME: Deal with macros-only imports.
- for (unsigned I = 0, N = Record.size(); I != N; ++I) {
- if (unsigned GlobalID = getGlobalSubmoduleID(F, Record[I]))
- ImportedModules.push_back(GlobalID);
+ for (unsigned I = 0, N = Record.size(); I != N; /**/) {
+ unsigned GlobalID = getGlobalSubmoduleID(F, Record[I++]);
+ SourceLocation Loc = ReadSourceLocation(F, Record, I);
+ if (GlobalID)
+ ImportedModules.push_back({GlobalID, Loc});
}
}
break;
Context.setcudaConfigureCallDecl(
cast<FunctionDecl>(GetDecl(CUDASpecialDeclRefs[0])));
}
-
+
// Re-export any modules that were imported by a non-module AST file.
- for (unsigned I = 0, N = ImportedModules.size(); I != N; ++I) {
- if (Module *Imported = getSubmodule(ImportedModules[I]))
+ // FIXME: This does not make macro-only imports visible again. It also doesn't
+ // make #includes mapped to module imports visible.
+ for (auto &Import : ImportedModules) {
+ if (Module *Imported = getSubmodule(Import.ID))
makeModuleVisible(Imported, Module::AllVisible,
- /*ImportLoc=*/SourceLocation(),
+ /*ImportLoc=*/Import.ImportLoc,
/*Complain=*/false);
}
ImportedModules.clear();
if (!WritingModule) {
// Write the submodules that were imported, if any.
- RecordData ImportedModules;
+ struct ModuleInfo { uint64_t ID; Module *M; };
+ llvm::SmallVector<ModuleInfo, 64> Imports;
for (const auto *I : Context.local_imports()) {
assert(SubmoduleIDs.find(I->getImportedModule()) != SubmoduleIDs.end());
- ImportedModules.push_back(SubmoduleIDs[I->getImportedModule()]);
+ Imports.push_back({SubmoduleIDs[I->getImportedModule()],
+ I->getImportedModule()});
}
- if (!ImportedModules.empty()) {
- // Sort module IDs.
- llvm::array_pod_sort(ImportedModules.begin(), ImportedModules.end());
-
- // Unique module IDs.
- ImportedModules.erase(std::unique(ImportedModules.begin(),
- ImportedModules.end()),
- ImportedModules.end());
-
+
+ if (!Imports.empty()) {
+ auto Cmp = [](const ModuleInfo &A, const ModuleInfo &B) {
+ return A.ID < B.ID;
+ };
+
+ // Sort and deduplicate module IDs.
+ std::sort(Imports.begin(), Imports.end(), Cmp);
+ Imports.erase(std::unique(Imports.begin(), Imports.end(), Cmp),
+ Imports.end());
+
+ RecordData ImportedModules;
+ for (const auto &Import : Imports) {
+ ImportedModules.push_back(Import.ID);
+ // FIXME: If the module has macros imported then later has declarations
+ // imported, this location won't be the right one as a location for the
+ // declaration imports.
+ AddSourceLocation(Import.M->MacroVisibilityLoc, ImportedModules);
+ }
+
Stream.EmitRecord(IMPORTED_MODULES, ImportedModules);
}
}
--- /dev/null
+#define AB
+#undef AB
--- /dev/null
+@import A;
--- /dev/null
+module A {
+ header "A.h"
+}
--- /dev/null
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c-header -fmodules -fmodules-cache-path=%t \
+// RUN: -I%S/Inputs/macro-undef-through-pch -emit-pch \
+// RUN: %S/Inputs/macro-undef-through-pch/foo.h -o %t.pch
+// RUN: %clang_cc1 -x objective-c -fmodules -fmodules-cache-path=%t -include-pch %t.pch %s
+
+// PR19215
+#undef AB