r177466 - <rdar://problem/10796651> Introduce configuration macros into module maps.
David Blaikie
dblaikie at gmail.com
Tue Mar 19 17:52:22 PDT 2013
On Tue, Mar 19, 2013 at 5:22 PM, Douglas Gregor <dgregor at apple.com> wrote:
> Author: dgregor
> Date: Tue Mar 19 19:22:05 2013
> New Revision: 177466
>
> URL: http://llvm.org/viewvc/llvm-project?rev=177466&view=rev
> Log:
> <rdar://problem/10796651> Introduce configuration macros into module maps.
>
> Configuration macros are macros that are intended to alter how a
> module works, such that we need to build different module variants
> for different values of these macros. A module can declare its
> configuration macros, in which case we will complain if the definition
> of a configation macro on the command line (or lack thereof) differs
> from the current preprocessor state at the point where the module is
> imported. This should eliminate some surprises when enabling modules,
> because "#define CONFIG_MACRO ..." followed by "#include
> <module/header.h>" would silently ignore the CONFIG_MACRO setting. At
> least it will no longer be silent about it.
>
> Configuration macros are eventually intended to help reduce the number
> of module variants that need to be built. When the list of
> configuration macros for a module is exhaustive, we only need to
> consider the settings for those macros when building/finding the
> module, which can help isolate modules for various project-specific -D
> flags that should never affect how modules are build (but currently do).
Looks like this might be breaking some things
http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-debian-fast/builds/542
(though my revision was blamed, the previous build was from before
your commit - not sure what went wrong with the blame range there)
> Added:
> cfe/trunk/test/Modules/Inputs/config.h
> cfe/trunk/test/Modules/config_macros.m
> Modified:
> cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
> cfe/trunk/include/clang/Basic/DiagnosticGroups.td
> cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
> cfe/trunk/include/clang/Basic/Module.h
> cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> cfe/trunk/lib/Basic/Module.cpp
> cfe/trunk/lib/Frontend/CompilerInstance.cpp
> cfe/trunk/lib/Lex/ModuleMap.cpp
> cfe/trunk/lib/Serialization/ASTReader.cpp
> cfe/trunk/lib/Serialization/ASTWriter.cpp
> cfe/trunk/test/Modules/Inputs/module.map
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td Tue Mar 19 19:22:05 2013
> @@ -137,5 +137,11 @@ def warn_missing_submodule : Warning<"mi
> def err_module_map_temp_file : Error<
> "unable to write temporary module map file '%0'">, DefaultFatal;
> def err_module_unavailable : Error<"module '%0' requires feature '%1'">;
> -
> +def warn_module_config_macro_undef : Warning<
> + "%select{definition|#undef}0 of configuration macro '%1' has no effect on "
> + "the import of '%2'; pass '%select{-D%1=...|-U%1}0' on the command line "
> + "to configure the module">,
> + InGroup<ConfigMacros>;
> +def note_module_def_undef_here : Note<
> + "macro was %select{defined|#undef'd}0 here">;
> }
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Mar 19 19:22:05 2013
> @@ -47,6 +47,7 @@ def CastAlign : DiagGroup<"cast-align">;
> def : DiagGroup<"cast-qual">;
> def : DiagGroup<"char-align">;
> def Comment : DiagGroup<"comment">;
> +def ConfigMacros : DiagGroup<"config-macros">;
> def : DiagGroup<"ctor-dtor-privacy">;
> def GNUDesignator : DiagGroup<"gnu-designator">;
>
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Tue Mar 19 19:22:05 2013
> @@ -532,6 +532,10 @@ def err_mmap_export_module_id : Error<
> "expected an exported module name or '*'">;
> def err_mmap_expected_library_name : Error<
> "expected %select{library|framework}0 name as a string">;
> +def err_mmap_config_macro_submodule : Error<
> + "configuration macros are only allowed on top-level modules">;
> +def err_mmap_expected_config_macro : Error<
> + "expected configuration macro name after ','">;
> def err_mmap_missing_module_unqualified : Error<
> "no module named '%0' visible from '%1'">;
> def err_mmap_missing_module_qualified : Error<
>
> Modified: cfe/trunk/include/clang/Basic/Module.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Module.h (original)
> +++ cfe/trunk/include/clang/Basic/Module.h Tue Mar 19 19:22:05 2013
> @@ -119,7 +119,14 @@ public:
> /// \brief Whether, when inferring submodules, the inferr submodules should
> /// export all modules they import (e.g., the equivalent of "export *").
> unsigned InferExportWildcard : 1;
> -
> +
> + /// \brief Whether the set of configuration macros is exhaustive.
> + ///
> + /// When the set of configuration macros is exhaustive, meaning
> + /// that no identifier not in this list should affect how the module is
> + /// built.
> + unsigned ConfigMacrosExhaustive : 1;
> +
> /// \brief Describes the visibility of the various names within a
> /// particular module.
> enum NameVisibilityKind {
> @@ -190,6 +197,10 @@ public:
> /// an entity from this module is used.
> llvm::SmallVector<LinkLibrary, 2> LinkLibraries;
>
> + /// \brief The set of "configuration macros", which are macros that
> + /// (intentionally) change how this module is built.
> + std::vector<std::string> ConfigMacros;
> +
> /// \brief Construct a top-level module.
> explicit Module(StringRef Name, SourceLocation DefinitionLoc,
> bool IsFramework)
> @@ -197,7 +208,8 @@ public:
> IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
> IsExplicit(false), IsSystem(false),
> InferSubmodules(false), InferExplicitSubmodules(false),
> - InferExportWildcard(false), NameVisibility(Hidden) { }
> + InferExportWildcard(false), ConfigMacrosExhaustive(false),
> + NameVisibility(Hidden) { }
>
> /// \brief Construct a new module or submodule.
> Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
> @@ -328,7 +340,7 @@ public:
> ///
> /// \returns The submodule if found, or NULL otherwise.
> Module *findSubmodule(StringRef Name) const;
> -
> +
> typedef std::vector<Module *>::iterator submodule_iterator;
> typedef std::vector<Module *>::const_iterator submodule_const_iterator;
>
>
> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Mar 19 19:22:05 2013
> @@ -609,7 +609,9 @@ namespace clang {
> /// from this submodule.
> SUBMODULE_EXCLUDED_HEADER = 9,
> /// \brief Specifies a library or framework to link against.
> - SUBMODULE_LINK_LIBRARY = 10
> + SUBMODULE_LINK_LIBRARY = 10,
> + /// \brief Specifies a configuration macro for this module.
> + SUBMODULE_CONFIG_MACRO = 11
> };
>
> /// \brief Record types used within a comments block.
>
> Modified: cfe/trunk/lib/Basic/Module.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Basic/Module.cpp (original)
> +++ cfe/trunk/lib/Basic/Module.cpp Tue Mar 19 19:22:05 2013
> @@ -279,7 +279,19 @@ void Module::print(raw_ostream &OS, unsi
> OS.write_escaped(UmbrellaDir->getName());
> OS << "\"\n";
> }
> -
> +
> + if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
> + OS.indent(Indent + 2);
> + OS << "config_macros ";
> + if (ConfigMacrosExhaustive)
> + OS << "[exhausive]";
> + for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
> + if (I)
> + OS << ", ";
> + OS << ConfigMacros[I];
> + }
> + }
> +
> for (unsigned I = 0, N = Headers.size(); I != N; ++I) {
> OS.indent(Indent + 2);
> OS << "header \"";
>
> Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
> +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Tue Mar 19 19:22:05 2013
> @@ -905,6 +905,96 @@ static void compileModule(CompilerInstan
> }
> }
>
> +/// \brief Diagnose differences between the current definition of the given
> +/// configuration macro and the definition provided on the command line.
> +static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
> + Module *Mod, SourceLocation ImportLoc) {
> + IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro);
> + SourceManager &SourceMgr = PP.getSourceManager();
> +
> + // If this identifier has never had a macro definition, then it could
> + // not have changed.
> + if (!Id->hadMacroDefinition())
> + return;
> +
> + // If this identifier does not currently have a macro definition,
> + // check whether it had one on the command line.
> + if (!Id->hasMacroDefinition()) {
> + MacroDirective *UndefMD = PP.getMacroDirectiveHistory(Id);
> + for (MacroDirective *MD = UndefMD; MD; MD = MD->getPrevious()) {
> +
> + FileID FID = SourceMgr.getFileID(MD->getLocation());
> + if (FID.isInvalid())
> + continue;
> +
> + const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(FID);
> + if (!Buffer)
> + continue;
> +
> + // We only care about the predefines buffer.
> + if (!StringRef(Buffer->getBufferIdentifier()).equals("<built-in>"))
> + continue;
> +
> + // This macro was defined on the command line, then #undef'd later.
> + // Complain.
> + PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
> + << true << ConfigMacro << Mod->getFullModuleName();
> + if (UndefMD->getUndefLoc().isValid())
> + PP.Diag(UndefMD->getUndefLoc(), diag::note_module_def_undef_here)
> + << true;
> + return;
> + }
> +
> + // Okay: no definition in the predefines buffer.
> + return;
> + }
> +
> + // This identifier has a macro definition. Check whether we had a definition
> + // on the command line.
> + MacroDirective *DefMD = PP.getMacroDirective(Id);
> + MacroDirective *PredefinedMD = 0;
> + for (MacroDirective *MD = DefMD; MD; MD = MD->getPrevious()) {
> + FileID FID = SourceMgr.getFileID(MD->getLocation());
> + if (FID.isInvalid())
> + continue;
> +
> + const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(FID);
> + if (!Buffer)
> + continue;
> +
> + // We only care about the predefines buffer.
> + if (!StringRef(Buffer->getBufferIdentifier()).equals("<built-in>"))
> + continue;
> +
> + PredefinedMD = MD;
> + break;
> + }
> +
> + // If there was no definition for this macro in the predefines buffer,
> + // complain.
> + if (!PredefinedMD ||
> + (!PredefinedMD->getLocation().isValid() &&
> + PredefinedMD->getUndefLoc().isValid())) {
> + PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
> + << false << ConfigMacro << Mod->getFullModuleName();
> + PP.Diag(DefMD->getLocation(), diag::note_module_def_undef_here)
> + << false;
> + return;
> + }
> +
> + // If the current macro definition is the same as the predefined macro
> + // definition, it's okay.
> + if (DefMD == PredefinedMD ||
> + DefMD->getInfo()->isIdenticalTo(*PredefinedMD->getInfo(), PP))
> + return;
> +
> + // The macro definitions differ.
> + PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
> + << false << ConfigMacro << Mod->getFullModuleName();
> + PP.Diag(DefMD->getLocation(), diag::note_module_def_undef_here)
> + << false;
> +}
> +
> ModuleLoadResult
> CompilerInstance::loadModule(SourceLocation ImportLoc,
> ModuleIdPath Path,
> @@ -1177,7 +1267,14 @@ CompilerInstance::loadModule(SourceLocat
>
> ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc);
> }
> -
> +
> + // Check for any configuration macros that have changed.
> + clang::Module *TopModule = Module->getTopLevelModule();
> + for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) {
> + checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I],
> + Module, ImportLoc);
> + }
> +
> // If this module import was due to an inclusion directive, create an
> // implicit import declaration to capture it in the AST.
> if (IsInclusionDirective && hasASTContext()) {
>
> Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
> +++ cfe/trunk/lib/Lex/ModuleMap.cpp Tue Mar 19 19:22:05 2013
> @@ -643,6 +643,7 @@ namespace clang {
> struct MMToken {
> enum TokenKind {
> Comma,
> + ConfigMacros,
> EndOfFile,
> HeaderKeyword,
> Identifier,
> @@ -687,10 +688,13 @@ namespace clang {
>
> /// \brief The set of attributes that can be attached to a module.
> struct Attributes {
> - Attributes() : IsSystem() { }
> + Attributes() : IsSystem(), IsExhaustive() { }
>
> /// \brief Whether this is a system module.
> unsigned IsSystem : 1;
> +
> + /// \brief Whether this is an exhaustive set of configuration macros.
> + unsigned IsExhaustive : 1;
> };
>
>
> @@ -739,6 +743,7 @@ namespace clang {
> void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
> void parseExportDecl();
> void parseLinkDecl();
> + void parseConfigMacros();
> void parseInferredModuleDecl(bool Framework, bool Explicit);
> bool parseOptionalAttributes(Attributes &Attrs);
>
> @@ -776,11 +781,12 @@ retry:
> Tok.StringData = LToken.getRawIdentifierData();
> Tok.StringLength = LToken.getLength();
> Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
> - .Case("header", MMToken::HeaderKeyword)
> + .Case("config_macros", MMToken::ConfigMacros)
> .Case("exclude", MMToken::ExcludeKeyword)
> .Case("explicit", MMToken::ExplicitKeyword)
> .Case("export", MMToken::ExportKeyword)
> .Case("framework", MMToken::FrameworkKeyword)
> + .Case("header", MMToken::HeaderKeyword)
> .Case("link", MMToken::LinkKeyword)
> .Case("module", MMToken::ModuleKeyword)
> .Case("requires", MMToken::RequiresKeyword)
> @@ -937,7 +943,9 @@ namespace {
> /// \brief An unknown attribute.
> AT_unknown,
> /// \brief The 'system' attribute.
> - AT_system
> + AT_system,
> + /// \brief The 'exhaustive' attribute.
> + AT_exhaustive
> };
> }
>
> @@ -1094,7 +1102,11 @@ void ModuleMapParser::parseModuleDecl()
> case MMToken::RBrace:
> Done = true;
> break;
> -
> +
> + case MMToken::ConfigMacros:
> + parseConfigMacros();
> + break;
> +
> case MMToken::ExplicitKeyword:
> case MMToken::FrameworkKeyword:
> case MMToken::ModuleKeyword:
> @@ -1489,6 +1501,59 @@ void ModuleMapParser::parseLinkDecl() {
> IsFramework));
> }
>
> +/// \brief Parse a configuration macro declaration.
> +///
> +/// module-declaration:
> +/// 'config_macros' attributes[opt] config-macro-list?
> +///
> +/// config-macro-list:
> +/// identifier (',' identifier)?
> +void ModuleMapParser::parseConfigMacros() {
> + assert(Tok.is(MMToken::ConfigMacros));
> + SourceLocation ConfigMacrosLoc = consumeToken();
> +
> + // Only top-level modules can have configuration macros.
> + if (ActiveModule->Parent) {
> + Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
> + }
> +
> + // Parse the optional attributes.
> + Attributes Attrs;
> + parseOptionalAttributes(Attrs);
> + if (Attrs.IsExhaustive && !ActiveModule->Parent) {
> + ActiveModule->ConfigMacrosExhaustive = true;
> + }
> +
> + // If we don't have an identifier, we're done.
> + if (!Tok.is(MMToken::Identifier))
> + return;
> +
> + // Consume the first identifier.
> + if (!ActiveModule->Parent) {
> + ActiveModule->ConfigMacros.push_back(Tok.getString().str());
> + }
> + consumeToken();
> +
> + do {
> + // If there's a comma, consume it.
> + if (!Tok.is(MMToken::Comma))
> + break;
> + consumeToken();
> +
> + // We expect to see a macro name here.
> + if (!Tok.is(MMToken::Identifier)) {
> + Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
> + break;
> + }
> +
> + // Consume the macro name.
> + if (!ActiveModule->Parent) {
> + ActiveModule->ConfigMacros.push_back(Tok.getString().str());
> + }
> + consumeToken();
> + } while (true);
> +}
> +
> /// \brief Parse an inferred module declaration (wildcard modules).
> ///
> /// module-declaration:
> @@ -1668,6 +1733,7 @@ bool ModuleMapParser::parseOptionalAttri
> // Decode the attribute name.
> AttributeKind Attribute
> = llvm::StringSwitch<AttributeKind>(Tok.getString())
> + .Case("exhaustive", AT_exhaustive)
> .Case("system", AT_system)
> .Default(AT_unknown);
> switch (Attribute) {
> @@ -1679,6 +1745,10 @@ bool ModuleMapParser::parseOptionalAttri
> case AT_system:
> Attrs.IsSystem = true;
> break;
> +
> + case AT_exhaustive:
> + Attrs.IsExhaustive = true;
> + break;
> }
> consumeToken();
>
> @@ -1730,6 +1800,7 @@ bool ModuleMapParser::parseModuleMapFile
> break;
>
> case MMToken::Comma:
> + case MMToken::ConfigMacros:
> case MMToken::ExcludeKeyword:
> case MMToken::ExportKeyword:
> case MMToken::HeaderKeyword:
>
> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Mar 19 19:22:05 2013
> @@ -3718,6 +3718,18 @@ bool ASTReader::ReadSubmoduleBlock(Modul
> CurrentModule->LinkLibraries.push_back(
> Module::LinkLibrary(Blob, Record[0]));
> break;
> +
> + case SUBMODULE_CONFIG_MACRO:
> + if (First) {
> + Error("missing submodule metadata record at beginning of block");
> + return true;
> + }
> +
> + if (!CurrentModule)
> + break;
> +
> + CurrentModule->ConfigMacros.push_back(Blob.str());
> + break;
> }
> }
> }
>
> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Mar 19 19:22:05 2013
> @@ -2135,6 +2135,7 @@ void ASTWriter::WriteSubmodules(Module *
> Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferSubmodules...
> Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit...
> Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild...
> + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ConfigMacrosExh...
> Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
> unsigned DefinitionAbbrev = Stream.EmitAbbrev(Abbrev);
>
> @@ -2174,6 +2175,11 @@ void ASTWriter::WriteSubmodules(Module *
> Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
> unsigned LinkLibraryAbbrev = Stream.EmitAbbrev(Abbrev);
>
> + Abbrev = new BitCodeAbbrev();
> + Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_CONFIG_MACRO));
> + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Macro name
> + unsigned ConfigMacroAbbrev = Stream.EmitAbbrev(Abbrev);
> +
> // Write the submodule metadata block.
> RecordData Record;
> Record.push_back(getNumberOfModules(WritingModule));
> @@ -2204,6 +2210,7 @@ void ASTWriter::WriteSubmodules(Module *
> Record.push_back(Mod->InferSubmodules);
> Record.push_back(Mod->InferExplicitSubmodules);
> Record.push_back(Mod->InferExportWildcard);
> + Record.push_back(Mod->ConfigMacrosExhaustive);
> Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name);
>
> // Emit the requirements.
> @@ -2288,6 +2295,14 @@ void ASTWriter::WriteSubmodules(Module *
> Mod->LinkLibraries[I].Library);
> }
>
> + // Emit the configuration macros.
> + for (unsigned I = 0, N = Mod->ConfigMacros.size(); I != N; ++I) {
> + Record.clear();
> + Record.push_back(SUBMODULE_CONFIG_MACRO);
> + Stream.EmitRecordWithBlob(ConfigMacroAbbrev, Record,
> + Mod->ConfigMacros[I]);
> + }
> +
> // Queue up the submodules of this module.
> for (Module::submodule_iterator Sub = Mod->submodule_begin(),
> SubEnd = Mod->submodule_end();
>
> Added: cfe/trunk/test/Modules/Inputs/config.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/config.h?rev=177466&view=auto
> ==============================================================================
> --- cfe/trunk/test/Modules/Inputs/config.h (added)
> +++ cfe/trunk/test/Modules/Inputs/config.h Tue Mar 19 19:22:05 2013
> @@ -0,0 +1,7 @@
> +#ifdef WANT_FOO
> +int* foo();
> +#endif
> +
> +#ifdef WANT_BAR
> +char *bar();
> +#endif
>
> Modified: cfe/trunk/test/Modules/Inputs/module.map
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=177466&r1=177465&r2=177466&view=diff
> ==============================================================================
> --- cfe/trunk/test/Modules/Inputs/module.map (original)
> +++ cfe/trunk/test/Modules/Inputs/module.map Tue Mar 19 19:22:05 2013
> @@ -183,3 +183,8 @@ module cxx_inline_namespace {
> module cxx_linkage_cache {
> header "cxx-linkage-cache.h"
> }
> +
> +module config {
> + header "config.h"
> + config_macros [exhaustive] WANT_FOO, WANT_BAR
> +}
>
> Added: cfe/trunk/test/Modules/config_macros.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/config_macros.m?rev=177466&view=auto
> ==============================================================================
> --- cfe/trunk/test/Modules/config_macros.m (added)
> +++ cfe/trunk/test/Modules/config_macros.m Tue Mar 19 19:22:05 2013
> @@ -0,0 +1,28 @@
> + at import config;
> +
> +int *test_foo() {
> + return foo();
> +}
> +
> +char *test_bar() {
> + return bar(); // expected-warning{{implicit declaration of function 'bar' is invalid in C99}} \
> + // expected-warning{{incompatible integer to pointer conversion}}
> +}
> +
> +#undef WANT_FOO // expected-note{{macro was #undef'd here}}
> + at import config; // expected-warning{{#undef of configuration macro 'WANT_FOO' has no effect on the import of 'config'; pass '-UWANT_FOO' on the command line to configure the module}}
> +
> +#define WANT_FOO 2 // expected-note{{macro was defined here}}
> + at import config; // expected-warning{{definition of configuration macro 'WANT_FOO' has no effect on the import of 'config'; pass '-DWANT_FOO=...' on the command line to configure the module}}
> +
> +#undef WANT_FOO
> +#define WANT_FOO 1
> + at import config; // okay
> +
> +#define WANT_BAR 1 // expected-note{{macro was defined here}}
> + at import config; // expected-warning{{definition of configuration macro 'WANT_BAR' has no effect on the import of 'config'; pass '-DWANT_BAR=...' on the command line to configure the module}}
> +
> +// RUN: rm -rf %t
> +// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config %S/Inputs/module.map
> +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -DWANT_FOO=1 %s -verify
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list