forked from OSchip/llvm-project
Inherit attributes when infering a framework module
If a module map contains framework module * [extern_c] {} We will now infer [extern_c] on the inferred framework modules (we already inferred [system] as a special case). llvm-svn: 225803
This commit is contained in:
parent
7615f00e51
commit
c1d88ea5a7
|
@ -127,15 +127,29 @@ private:
|
|||
/// header.
|
||||
llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
|
||||
|
||||
/// \brief The set of attributes that can be attached to a module.
|
||||
struct Attributes {
|
||||
Attributes() : IsSystem(), IsExternC(), IsExhaustive() {}
|
||||
|
||||
/// \brief Whether this is a system module.
|
||||
unsigned IsSystem : 1;
|
||||
|
||||
/// \brief Whether this is an extern "C" module.
|
||||
unsigned IsExternC : 1;
|
||||
|
||||
/// \brief Whether this is an exhaustive set of configuration macros.
|
||||
unsigned IsExhaustive : 1;
|
||||
};
|
||||
|
||||
/// \brief A directory for which framework modules can be inferred.
|
||||
struct InferredDirectory {
|
||||
InferredDirectory() : InferModules(), InferSystemModules() { }
|
||||
InferredDirectory() : InferModules() {}
|
||||
|
||||
/// \brief Whether to infer modules from this directory.
|
||||
unsigned InferModules : 1;
|
||||
|
||||
/// \brief Whether the modules we infer are [system] modules.
|
||||
unsigned InferSystemModules : 1;
|
||||
/// \brief The attributes to use for inferred modules.
|
||||
Attributes Attrs;
|
||||
|
||||
/// \brief If \c InferModules is non-zero, the module map file that allowed
|
||||
/// inferred modules. Otherwise, nullptr.
|
||||
|
@ -214,6 +228,10 @@ private:
|
|||
return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs));
|
||||
}
|
||||
|
||||
Module *inferFrameworkModule(StringRef ModuleName,
|
||||
const DirectoryEntry *FrameworkDir,
|
||||
Attributes Attrs, Module *Parent);
|
||||
|
||||
public:
|
||||
/// \brief Construct a new module map.
|
||||
///
|
||||
|
|
|
@ -585,6 +585,15 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
|
|||
const DirectoryEntry *FrameworkDir,
|
||||
bool IsSystem,
|
||||
Module *Parent) {
|
||||
Attributes Attrs;
|
||||
Attrs.IsSystem = IsSystem;
|
||||
return inferFrameworkModule(ModuleName, FrameworkDir, Attrs, Parent);
|
||||
}
|
||||
|
||||
Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
|
||||
const DirectoryEntry *FrameworkDir,
|
||||
Attributes Attrs, Module *Parent) {
|
||||
|
||||
// Check whether we've already found this module.
|
||||
if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
|
||||
return Mod;
|
||||
|
@ -625,7 +634,7 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
|
|||
bool IsFrameworkDir = Parent.endswith(".framework");
|
||||
if (const FileEntry *ModMapFile =
|
||||
HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
|
||||
parseModuleMapFile(ModMapFile, IsSystem, ParentDir);
|
||||
parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
|
||||
inferred = InferredDirectories.find(ParentDir);
|
||||
}
|
||||
|
||||
|
@ -642,8 +651,9 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
|
|||
inferred->second.ExcludedModules.end(),
|
||||
Name) == inferred->second.ExcludedModules.end();
|
||||
|
||||
if (inferred->second.InferSystemModules)
|
||||
IsSystem = true;
|
||||
Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
|
||||
Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
|
||||
Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
|
||||
ModuleMapFile = inferred->second.ModuleMapFile;
|
||||
}
|
||||
}
|
||||
|
@ -675,9 +685,11 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
|
|||
SourceModule = Result;
|
||||
SourceModuleName = ModuleName;
|
||||
}
|
||||
if (IsSystem)
|
||||
Result->IsSystem = IsSystem;
|
||||
|
||||
|
||||
Result->IsSystem |= Attrs.IsSystem;
|
||||
Result->IsExternC |= Attrs.IsExternC;
|
||||
Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
|
||||
|
||||
if (!Parent)
|
||||
Modules[ModuleName] = Result;
|
||||
|
||||
|
@ -732,8 +744,8 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
|
|||
// FIXME: Do we want to warn about subframeworks without umbrella headers?
|
||||
SmallString<32> NameBuf;
|
||||
inferFrameworkModule(sanitizeFilenameAsIdentifier(
|
||||
llvm::sys::path::stem(Dir->path()), NameBuf),
|
||||
SubframeworkDir, IsSystem, Result);
|
||||
llvm::sys::path::stem(Dir->path()), NameBuf),
|
||||
SubframeworkDir, Attrs, Result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -972,21 +984,6 @@ namespace clang {
|
|||
}
|
||||
};
|
||||
|
||||
/// \brief The set of attributes that can be attached to a module.
|
||||
struct Attributes {
|
||||
Attributes() : IsSystem(), IsExternC(), IsExhaustive() { }
|
||||
|
||||
/// \brief Whether this is a system module.
|
||||
unsigned IsSystem : 1;
|
||||
|
||||
/// \brief Whether this is an extern "C" module.
|
||||
unsigned IsExternC : 1;
|
||||
|
||||
/// \brief Whether this is an exhaustive set of configuration macros.
|
||||
unsigned IsExhaustive : 1;
|
||||
};
|
||||
|
||||
|
||||
class ModuleMapParser {
|
||||
Lexer &L;
|
||||
SourceManager &SourceMgr;
|
||||
|
@ -1045,6 +1042,8 @@ namespace clang {
|
|||
void parseConfigMacros();
|
||||
void parseConflict();
|
||||
void parseInferredModuleDecl(bool Framework, bool Explicit);
|
||||
|
||||
typedef ModuleMap::Attributes Attributes;
|
||||
bool parseOptionalAttributes(Attributes &Attrs);
|
||||
|
||||
public:
|
||||
|
@ -2117,7 +2116,7 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
|
|||
} else {
|
||||
// We'll be inferring framework modules for this directory.
|
||||
Map.InferredDirectories[Directory].InferModules = true;
|
||||
Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
|
||||
Map.InferredDirectories[Directory].Attrs = Attrs;
|
||||
Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
|
||||
// FIXME: Handle the 'framework' keyword.
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
// InferredExternC.h
|
|
@ -0,0 +1 @@
|
|||
framework module * [extern_c] { }
|
|
@ -0,0 +1,6 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -F %S/Inputs/inferred-attr -fsyntax-only -verify %s
|
||||
// expected-no-diagnostics
|
||||
extern "C" {
|
||||
@import InferredExternC;
|
||||
}
|
Loading…
Reference in New Issue