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
