It's my bug. I forgot to deserialize the new Module bit in the submodule definition. I'm AFK but can fix in a few hours ;(
Sent from my iPhone On Mar 19, 2013, at 5:52 PM, David Blaikie <[email protected]> wrote: > On Tue, Mar 19, 2013 at 5:22 PM, Douglas Gregor <[email protected]> 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 @@ >> +@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}} >> +@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}} >> +@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 >> +@import config; // okay >> + >> +#define WANT_BAR 1 // expected-note{{macro was defined here}} >> +@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 >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
