r193151 - Allow a header to be part of multiple modules.

Daniel Jasper djasper at google.com
Tue Oct 22 01:09:48 PDT 2013


Author: djasper
Date: Tue Oct 22 03:09:47 2013
New Revision: 193151

URL: http://llvm.org/viewvc/llvm-project?rev=193151&view=rev
Log:
Allow a header to be part of multiple modules.

This patch changes two things:

a) Allow a header to be part of multiple modules. The reasoning is that
in existing codebases that have a module-like build system, the same
headers might be used in several build targets. Simple reasons might be
that they defined different classes that are declared in the same
header. Supporting a header as a part of multiple modules will make the
transistion easier for those cases. A later step in clang can then
determine whether the two modules are actually compatible and can be
merged and error out appropriately. The later check is similar to what
needs to be done for template specializations anyway.

b) Allow modules to be stored in a directory tree separate from the
headers they describe.

Review: http://llvm-reviews.chandlerc.com/D1951

Added:
    cfe/trunk/test/Modules/Inputs/modular_maps/common.h
    cfe/trunk/test/Modules/Inputs/separate_map_tree/
    cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/
    cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/modulea.map
    cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/moduleb.map
    cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/modulec.map
    cfe/trunk/test/Modules/Inputs/separate_map_tree/src/
    cfe/trunk/test/Modules/Inputs/separate_map_tree/src/common.h
    cfe/trunk/test/Modules/Inputs/separate_map_tree/src/private-in-c.h
    cfe/trunk/test/Modules/Inputs/separate_map_tree/src/public-in-b.h
    cfe/trunk/test/Modules/Inputs/separate_map_tree/src/public-in-c.h
    cfe/trunk/test/Modules/separate_map_tree.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/include/clang/Lex/ModuleMap.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Lex/HeaderSearch.cpp
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/test/Modules/Inputs/modular_maps/modulea.map
    cfe/trunk/test/Modules/Inputs/modular_maps/moduleb.map
    cfe/trunk/test/Modules/modular_maps.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=193151&r1=193150&r2=193151&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Tue Oct 22 03:09:47 2013
@@ -551,8 +551,6 @@ def err_mmap_expected_mmap_file : Error<
 def err_mmap_module_redefinition : Error<
   "redefinition of module '%0'">;
 def note_mmap_prev_definition : Note<"previously defined here">;
-def err_mmap_header_conflict : Error<
-  "header '%0' is already part of module '%1'">;
 def err_mmap_header_not_found : Error<
   "%select{|umbrella }0header '%1' not found">;
 def err_mmap_umbrella_dir_not_found : Error<

Modified: cfe/trunk/include/clang/Lex/ModuleMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=193151&r1=193150&r2=193151&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ModuleMap.h (original)
+++ cfe/trunk/include/clang/Lex/ModuleMap.h Tue Oct 22 03:09:47 2013
@@ -106,7 +106,8 @@ public:
   };
 
 private:
-  typedef llvm::DenseMap<const FileEntry *, KnownHeader> HeadersMap;
+  typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1> >
+  HeadersMap;
 
   /// \brief Mapping from each header to the module that owns the contents of
   /// that header.
@@ -208,10 +209,15 @@ public:
   ///
   /// \param File The header file that is likely to be included.
   ///
+  /// \param RequestingModule Specifies the module the header is intended to be
+  /// used from.  Used to disambiguate if a header is present in multiple
+  /// modules.
+  ///
   /// \returns The module KnownHeader, which provides the module that owns the
   /// given header file.  The KnownHeader is default constructed to indicate
   /// that no module owns this header file.
-  KnownHeader findModuleForHeader(const FileEntry *File);
+  KnownHeader findModuleForHeader(const FileEntry *File,
+                                  Module *RequestingModule = NULL);
 
   /// \brief Determine whether the given header is part of a module
   /// marked 'unavailable'.

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=193151&r1=193150&r2=193151&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Tue Oct 22 03:09:47 2013
@@ -1461,10 +1461,9 @@ private:
   /// \brief Verify that it is legal for the source file that \p FilenameLoc
   /// points to to include the file \p Filename.
   ///
-  /// Tries to reuse \p IncFileEnt and \p SuggestedModule.
+  /// Tries to reuse \p IncFileEnt.
   void verifyModuleInclude(SourceLocation FilenameLoc, StringRef Filename,
-                           const FileEntry *IncFileEnt,
-                           ModuleMap::KnownHeader *SuggestedModule);
+                           const FileEntry *IncFileEnt);
 
   // Macro handling.
   void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);

Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=193151&r1=193150&r2=193151&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Tue Oct 22 03:09:47 2013
@@ -247,16 +247,18 @@ const FileEntry *DirectoryLookup::Lookup
     
     // If we have a module map that might map this header, load it and
     // check whether we'll have a suggestion for a module.
-    if (SuggestedModule &&
-        HS.hasModuleMap(TmpDir, getDir(), isSystemHeaderDirectory())) {
-      const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(), 
+    HS.hasModuleMap(TmpDir, getDir(), isSystemHeaderDirectory());
+    if (SuggestedModule) {
+      const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(),
                                                       /*openFile=*/false);
       if (!File)
         return File;
       
-      // If there is a module that corresponds to this header, 
-      // suggest it.
+      // If there is a module that corresponds to this header, suggest it.
       *SuggestedModule = HS.findModuleForHeader(File);
+      if (!SuggestedModule->getModule() &&
+          HS.hasModuleMap(TmpDir, getDir(), isSystemHeaderDirectory()))
+        *SuggestedModule = HS.findModuleForHeader(File);
       return File;
     }
     
@@ -503,6 +505,24 @@ const FileEntry *HeaderSearch::LookupFil
     ModuleMap::KnownHeader *SuggestedModule,
     bool SkipCache)
 {
+  if (!HSOpts->ModuleMapFiles.empty()) {
+    // Preload all explicitly specified module map files. This enables modules
+    // map files lying in a directory structure separate from the header files
+    // that they describe. These cannot be loaded lazily upon encountering a
+    // header file, as there is no other knwon mapping from a header file to its
+    // module map file.
+    for (llvm::SetVector<std::string>::iterator
+             I = HSOpts->ModuleMapFiles.begin(),
+             E = HSOpts->ModuleMapFiles.end();
+         I != E; ++I) {
+      const FileEntry *File = FileMgr.getFile(*I);
+      if (!File)
+        continue;
+      loadModuleMapFile(File, /*IsSystem=*/false);
+    }
+    HSOpts->ModuleMapFiles.clear();
+  }
+
   if (SuggestedModule)
     *SuggestedModule = ModuleMap::KnownHeader();
     
@@ -946,43 +966,20 @@ bool HeaderSearch::hasModuleMap(StringRe
     const DirectoryEntry *Dir = FileMgr.getDirectory(DirName);
     if (!Dir)
       return false;
-    
-    // Load user-specified module map files in 'Dir'.
-    bool ModuleMapFound = false;
-    for (llvm::SetVector<std::string>::iterator
-             I = HSOpts->ModuleMapFiles.begin(),
-             E = HSOpts->ModuleMapFiles.end();
-         I != E; ++I) {
-      StringRef ModuleMapFileDir = llvm::sys::path::parent_path(*I);
-      if (!llvm::sys::fs::equivalent(ModuleMapFileDir, DirName))
-        continue;
-
-      const FileEntry *File = FileMgr.getFile(*I);
-      if (!File)
-        continue;
-
-      loadModuleMapFile(File, /*IsSystem=*/false);
-      ModuleMapFound = true;
-    }
 
     // Try to load the "module.map" file in this directory.
     switch (loadModuleMapFile(Dir, IsSystem)) {
     case LMM_NewlyLoaded:
     case LMM_AlreadyLoaded:
-      ModuleMapFound = true;
-      break;
-
-    case LMM_NoDirectory:
-    case LMM_InvalidModuleMap:
-      break;
-    }
-
-    if (ModuleMapFound) {
       // Success. All of the directories we stepped through inherit this module
       // map file.
       for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
         DirectoryHasModuleMap[FixUpDirectories[I]] = true;
       return true;
+
+    case LMM_NoDirectory:
+    case LMM_InvalidModuleMap:
+      break;
     }
 
     // If we hit the top of our search, we're done.

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=193151&r1=193150&r2=193151&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Tue Oct 22 03:09:47 2013
@@ -168,14 +168,41 @@ static bool isBuiltinHeader(StringRef Fi
            .Default(false);
 }
 
-ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
+ModuleMap::KnownHeader
+ModuleMap::findModuleForHeader(const FileEntry *File,
+                               Module *RequestingModule) {
   HeadersMap::iterator Known = Headers.find(File);
   if (Known != Headers.end()) {
-    // If a header is not available, don't report that it maps to anything.
-    if (!Known->second.isAvailable())
-      return KnownHeader();
+    ModuleMap::KnownHeader Result = KnownHeader();
 
-    return Known->second;
+    // Iterate over all modules that 'File' is part of to find the best fit.
+    for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
+                                                E = Known->second.end();
+         I != E; ++I) {
+      // Cannot use a module if the header is excluded or unavailable in it.
+      if (I->getRole() == ModuleMap::ExcludedHeader ||
+          !I->getModule()->isAvailable())
+        continue;
+
+      // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
+      // module we are looking for.
+      if (I->getModule() == RequestingModule)
+        return *I;
+
+      // If uses need to be specified explicitly, we are only allowed to return
+      // modules that are explicitly used by the requesting module.
+      if (RequestingModule && LangOpts.ModulesDeclUse &&
+          std::find(RequestingModule->DirectUses.begin(),
+                    RequestingModule->DirectUses.end(),
+                    I->getModule()) == RequestingModule->DirectUses.end())
+        continue;
+      Result = *I;
+      // If 'File' is a public header of this module, this is as good as we
+      // are going to get.
+      if (I->getRole() == ModuleMap::NormalHeader)
+        break;
+    }
+    return Result;
   }
 
   // If we've found a builtin header within Clang's builtin include directory,
@@ -186,14 +213,8 @@ ModuleMap::KnownHeader ModuleMap::findMo
     HeaderInfo.loadTopLevelSystemModules();
 
     // Check again.
-    Known = Headers.find(File);
-    if (Known != Headers.end()) {
-      // If a header is not available, don't report that it maps to anything.
-      if (!Known->second.isAvailable())
-        return KnownHeader();
-
-      return Known->second;
-    }
+    if (Headers.find(File) != Headers.end())
+      return findModuleForHeader(File, RequestingModule);
   }
   
   const DirectoryEntry *Dir = File->getDir();
@@ -262,14 +283,14 @@ ModuleMap::KnownHeader ModuleMap::findMo
           UmbrellaDirs[SkippedDirs[I]] = Result;
       }
       
-      Headers[File] = KnownHeader(Result, NormalHeader);
+      Headers[File].push_back(KnownHeader(Result, NormalHeader));
 
       // If a header corresponds to an unavailable module, don't report
       // that it maps to anything.
       if (!Result->isAvailable())
         return KnownHeader();
 
-      return Headers[File];
+      return Headers[File].back();
     }
     
     SkippedDirs.push_back(Dir);
@@ -288,8 +309,16 @@ ModuleMap::KnownHeader ModuleMap::findMo
 
 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
   HeadersMap::const_iterator Known = Headers.find(Header);
-  if (Known != Headers.end())
-    return !Known->second.isAvailable();
+  if (Known != Headers.end()) {
+    for (SmallVectorImpl<KnownHeader>::const_iterator
+             I = Known->second.begin(),
+             E = Known->second.end();
+         I != E; ++I) {
+      if (I->isAvailable())
+        return false;
+    }
+    return true;
+  }
   
   const DirectoryEntry *Dir = Header->getDir();
   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
@@ -534,7 +563,7 @@ ModuleMap::inferFrameworkModule(StringRe
   
   // umbrella header "umbrella-header-name"
   Result->Umbrella = UmbrellaHeader;
-  Headers[UmbrellaHeader] = KnownHeader(Result, NormalHeader);
+  Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
   
   // export *
@@ -598,7 +627,7 @@ ModuleMap::inferFrameworkModule(StringRe
 }
 
 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
-  Headers[UmbrellaHeader] = KnownHeader(Mod, NormalHeader);
+  Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
   Mod->Umbrella = UmbrellaHeader;
   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
 }
@@ -620,7 +649,7 @@ void ModuleMap::addHeader(Module *Mod, c
     bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
     HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
   }
-  Headers[Header] = KnownHeader(Mod, Role);
+  Headers[Header].push_back(KnownHeader(Mod, Role));
 }
 
 const FileEntry *
@@ -642,8 +671,15 @@ void ModuleMap::dump() {
   llvm::errs() << "Headers:";
   for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
        H != HEnd; ++H) {
-    llvm::errs() << "  \"" << H->first->getName() << "\" -> " 
-                 << H->second.getModule()->getFullModuleName() << "\n";
+    llvm::errs() << "  \"" << H->first->getName() << "\" -> ";
+    for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
+                                                      E = H->second.end();
+         I != E; ++I) {
+      if (I != H->second.begin())
+        llvm::errs() << ",";
+      llvm::errs() << I->getModule()->getFullModuleName();
+    }
+    llvm::errs() << "\n";
   }
 }
 
@@ -1494,11 +1530,7 @@ void ModuleMapParser::parseHeaderDecl(MM
   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
   // Come up with a lazy way to do this.
   if (File) {
-    if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
-      Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
-        << FileName << OwningModule.getModule()->getFullModuleName();
-      HadError = true;
-    } else if (LeadingToken == MMToken::UmbrellaKeyword) {
+    if (LeadingToken == MMToken::UmbrellaKeyword) {
       const DirectoryEntry *UmbrellaDir = File->getDir();
       if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
         Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=193151&r1=193150&r2=193151&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Tue Oct 22 03:09:47 2013
@@ -583,33 +583,33 @@ bool Preprocessor::violatesUseDeclaratio
   return Declared == AllowedUses.end();
 }
 
-void Preprocessor::verifyModuleInclude(
-    SourceLocation FilenameLoc,
-    StringRef Filename,
-    const FileEntry *IncFileEnt,
-    ModuleMap::KnownHeader *SuggestedModule) {
+void Preprocessor::verifyModuleInclude(SourceLocation FilenameLoc,
+                                       StringRef Filename,
+                                       const FileEntry *IncFileEnt) {
   Module *RequestingModule = getModuleForLocation(FilenameLoc);
-  Module *RequestedModule = SuggestedModule->getModule();
-  if (!RequestedModule)
-    RequestedModule = HeaderInfo.findModuleForHeader(IncFileEnt).getModule();
+  if (RequestingModule)
+    HeaderInfo.getModuleMap().resolveUses(RequestingModule, /*Complain=*/false);
+  ModuleMap::KnownHeader RequestedModule =
+      HeaderInfo.getModuleMap().findModuleForHeader(IncFileEnt,
+                                                    RequestingModule);
 
-  if (RequestingModule == RequestedModule)
+  if (RequestingModule == RequestedModule.getModule())
     return; // No faults wihin a module, or between files both not in modules.
 
   if (RequestingModule != HeaderInfo.getModuleMap().SourceModule)
     return; // No errors for indirect modules.
             // This may be a bit of a problem for modules with no source files.
 
-  if (RequestedModule &&
-      violatesPrivateInclude(RequestingModule, IncFileEnt,
-                             SuggestedModule->getRole(), RequestedModule))
+  if (RequestedModule && violatesPrivateInclude(RequestingModule, IncFileEnt,
+                                                RequestedModule.getRole(),
+                                                RequestedModule.getModule()))
     Diag(FilenameLoc, diag::error_use_of_private_header_outside_module)
         << Filename;
 
   // FIXME: Add support for FixIts in module map files and offer adding the
   // required use declaration.
   if (RequestingModule && getLangOpts().ModulesDeclUse &&
-      violatesUseDeclarations(RequestingModule, RequestedModule))
+      violatesUseDeclarations(RequestingModule, RequestedModule.getModule()))
     Diag(FilenameLoc, diag::error_undeclared_use_of_module)
         << Filename;
 }
@@ -650,7 +650,7 @@ const FileEntry *Preprocessor::LookupFil
       SearchPath, RelativePath, SuggestedModule, SkipCache);
   if (FE) {
     if (SuggestedModule)
-      verifyModuleInclude(FilenameLoc, Filename, FE, SuggestedModule);
+      verifyModuleInclude(FilenameLoc, Filename, FE);
     return FE;
   }
 

Added: cfe/trunk/test/Modules/Inputs/modular_maps/common.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modular_maps/common.h?rev=193151&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/modular_maps/common.h (added)
+++ cfe/trunk/test/Modules/Inputs/modular_maps/common.h Tue Oct 22 03:09:47 2013
@@ -0,0 +1,4 @@
+#ifndef COMMON_H
+#define COMMON_H
+const int c = 2;
+#endif

Modified: cfe/trunk/test/Modules/Inputs/modular_maps/modulea.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modular_maps/modulea.map?rev=193151&r1=193150&r2=193151&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/modular_maps/modulea.map (original)
+++ cfe/trunk/test/Modules/Inputs/modular_maps/modulea.map Tue Oct 22 03:09:47 2013
@@ -1,4 +1,5 @@
 module A {
+  header "common.h"
   header "a.h"
 }
 

Modified: cfe/trunk/test/Modules/Inputs/modular_maps/moduleb.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modular_maps/moduleb.map?rev=193151&r1=193150&r2=193151&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/modular_maps/moduleb.map (original)
+++ cfe/trunk/test/Modules/Inputs/modular_maps/moduleb.map Tue Oct 22 03:09:47 2013
@@ -1,3 +1,4 @@
 module B {
+  header "common.h"
   private header "b.h"
 }

Added: cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/modulea.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/modulea.map?rev=193151&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/modulea.map (added)
+++ cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/modulea.map Tue Oct 22 03:09:47 2013
@@ -0,0 +1,12 @@
+module D {
+  header "../src/common.h"
+}
+
+module A {
+  header "../src/common.h"
+  use C
+}
+
+extern module B "moduleb.map"
+extern module C "modulec.map"
+

Added: cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/moduleb.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/moduleb.map?rev=193151&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/moduleb.map (added)
+++ cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/moduleb.map Tue Oct 22 03:09:47 2013
@@ -0,0 +1,4 @@
+module B {
+  header "../src/public-in-b.h"
+  private header "../src/public-in-c.h"
+}

Added: cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/modulec.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/modulec.map?rev=193151&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/modulec.map (added)
+++ cfe/trunk/test/Modules/Inputs/separate_map_tree/maps/modulec.map Tue Oct 22 03:09:47 2013
@@ -0,0 +1,5 @@
+module C {
+  header "../src/public-in-c.h"
+  private header "../src/public-in-b.h"
+  private header "../src/private-in-c.h"
+}

Added: cfe/trunk/test/Modules/Inputs/separate_map_tree/src/common.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/separate_map_tree/src/common.h?rev=193151&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/separate_map_tree/src/common.h (added)
+++ cfe/trunk/test/Modules/Inputs/separate_map_tree/src/common.h Tue Oct 22 03:09:47 2013
@@ -0,0 +1,4 @@
+#ifndef COMMON_H
+#define COMMON_H
+const int common = 2;
+#endif

Added: cfe/trunk/test/Modules/Inputs/separate_map_tree/src/private-in-c.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/separate_map_tree/src/private-in-c.h?rev=193151&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/separate_map_tree/src/private-in-c.h (added)
+++ cfe/trunk/test/Modules/Inputs/separate_map_tree/src/private-in-c.h Tue Oct 22 03:09:47 2013
@@ -0,0 +1,4 @@
+#ifndef PRIVATE_IN_C_H
+#define PRIVATE_IN_C_H
+const int c_ = 2;
+#endif

Added: cfe/trunk/test/Modules/Inputs/separate_map_tree/src/public-in-b.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/separate_map_tree/src/public-in-b.h?rev=193151&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/separate_map_tree/src/public-in-b.h (added)
+++ cfe/trunk/test/Modules/Inputs/separate_map_tree/src/public-in-b.h Tue Oct 22 03:09:47 2013
@@ -0,0 +1,4 @@
+#ifndef PUBLIC_IN_B_H
+#define PUBLIC_IN_B_H
+const int b = 3;
+#endif

Added: cfe/trunk/test/Modules/Inputs/separate_map_tree/src/public-in-c.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/separate_map_tree/src/public-in-c.h?rev=193151&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/separate_map_tree/src/public-in-c.h (added)
+++ cfe/trunk/test/Modules/Inputs/separate_map_tree/src/public-in-c.h Tue Oct 22 03:09:47 2013
@@ -0,0 +1,4 @@
+#ifndef PUBLIC_IN_C_H
+#define PUBLIC_IN_C_H
+const int c = 2;
+#endif

Modified: cfe/trunk/test/Modules/modular_maps.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/modular_maps.cpp?rev=193151&r1=193150&r2=193151&view=diff
==============================================================================
--- cfe/trunk/test/Modules/modular_maps.cpp (original)
+++ cfe/trunk/test/Modules/modular_maps.cpp Tue Oct 22 03:09:47 2013
@@ -1,6 +1,8 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodule-map-file=%S/Inputs/modular_maps/modulea.map -I %S/Inputs/modular_maps %s -verify
 
+#include "common.h"
 #include "a.h"
 #include "b.h" // expected-error {{private header}}
-const int val = a + b; // expected-error {{undeclared identifier}}
+const int v = a + c;
+const int val = a + b + c; // expected-error {{undeclared identifier}}

Added: cfe/trunk/test/Modules/separate_map_tree.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/separate_map_tree.cpp?rev=193151&view=auto
==============================================================================
--- cfe/trunk/test/Modules/separate_map_tree.cpp (added)
+++ cfe/trunk/test/Modules/separate_map_tree.cpp Tue Oct 22 03:09:47 2013
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fmodules-decluse -fmodule-name=A -fmodule-map-file=%S/Inputs/separate_map_tree/maps/modulea.map -I %S/Inputs/separate_map_tree/src %s -verify
+
+#include "common.h"
+#include "public-in-b.h" // expected-error {{private header}}
+#include "public-in-c.h"
+#include "private-in-c.h" // expected-error {{private header}}
+const int val = common + b + c + c_; // expected-error {{undeclared identifier}}





More information about the cfe-commits mailing list