<div dir="ltr">Thanks, fixed.</div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 27, 2015 at 5:23 PM, Alexey Samsonov <span dir="ltr"><<a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Richard,<div><br></div><div>Looks like this broke down ASan bootstrap: <a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/3434/steps/check-clang%20asan/logs/stdio" target="_blank">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/3434/steps/check-clang%20asan/logs/stdio</a></div></div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">On Mon, Apr 27, 2015 at 4:21 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Mon Apr 27 18:21:38 2015<br>
New Revision: 235941<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=235941&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=235941&view=rev</a><br>
Log:<br>
[modules] Incrementally compute the list of overridden module macros based on<br>
the active module macros at the point of definition, rather than reconstructing<br>
it from the macro history. No functionality change intended.<br>
<br>
Modified:<br>
cfe/trunk/include/clang/Lex/Preprocessor.h<br>
cfe/trunk/lib/Lex/PPDirectives.cpp<br>
cfe/trunk/lib/Lex/PPLexerChange.cpp<br>
cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br>
cfe/trunk/lib/Lex/Preprocessor.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=235941&r1=235940&r2=235941&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=235941&r1=235940&r2=235941&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)<br>
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Mon Apr 27 18:21:38 2015<br>
@@ -364,57 +364,104 @@ class Preprocessor : public RefCountedBa<br>
};<br>
SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;<br>
<br>
+ /// Information about a name that has been used to define a module macro.<br>
+ struct ModuleMacroInfo {<br>
+ ModuleMacroInfo(MacroDirective *MD)<br>
+ : MD(MD), ActiveModuleMacrosGeneration(0) {}<br>
+<br>
+ /// The most recent macro directive for this identifier.<br>
+ MacroDirective *MD;<br>
+ /// The active module macros for this identifier.<br>
+ llvm::TinyPtrVector<ModuleMacro*> ActiveModuleMacros;<br>
+ /// The generation number at which we last updated ActiveModuleMacros.<br>
+ /// \see Preprocessor::MacroVisibilityGeneration.<br>
+ unsigned ActiveModuleMacrosGeneration;<br>
+ /// Whether this macro name is ambiguous.<br>
+ bool IsAmbiguous;<br>
+ /// The module macros that are overridden by this macro.<br>
+ llvm::TinyPtrVector<ModuleMacro*> OverriddenMacros;<br>
+ };<br>
+<br>
/// The state of a macro for an identifier.<br>
class MacroState {<br>
- struct ExtInfo {<br>
- ExtInfo(MacroDirective *MD) : MD(MD) {}<br>
-<br>
- // The most recent macro directive for this identifier.<br>
- MacroDirective *MD;<br>
- // The module macros that are overridden by this macro.<br>
- SmallVector<ModuleMacro*, 4> OverriddenMacros;<br>
- };<br>
+ mutable llvm::PointerUnion<MacroDirective *, ModuleMacroInfo *> State;<br>
<br>
- llvm::PointerUnion<MacroDirective *, ExtInfo *> State;<br>
-<br>
- ExtInfo &getExtInfo(Preprocessor &PP) {<br>
- auto *Ext = State.dyn_cast<ExtInfo*>();<br>
- if (!Ext) {<br>
- Ext = new (PP.getPreprocessorAllocator())<br>
- ExtInfo(State.get<MacroDirective *>());<br>
- State = Ext;<br>
+ ModuleMacroInfo *getModuleInfo(Preprocessor &PP, IdentifierInfo *II) const {<br>
+ // FIXME: Find a spare bit on IdentifierInfo and store a<br>
+ // HasModuleMacros flag.<br>
+ if (!II->hasMacroDefinition() || !PP.getLangOpts().Modules ||<br>
+ !PP.MacroVisibilityGeneration)<br>
+ return nullptr;<br>
+<br>
+ auto *Info = State.dyn_cast<ModuleMacroInfo*>();<br>
+ if (!Info) {<br>
+ Info = new (PP.getPreprocessorAllocator())<br>
+ ModuleMacroInfo(State.get<MacroDirective *>());<br>
+ State = Info;<br>
}<br>
- return *Ext;<br>
+<br>
+ if (PP.MacroVisibilityGeneration != Info->ActiveModuleMacrosGeneration)<br>
+ PP.updateModuleMacroInfo(II, *Info);<br>
+ return Info;<br>
}<br>
<br>
public:<br>
MacroState() : MacroState(nullptr) {}<br>
MacroState(MacroDirective *MD) : State(MD) {}<br>
MacroDirective *getLatest() const {<br>
- if (auto *Ext = State.dyn_cast<ExtInfo*>())<br>
- return Ext->MD;<br>
+ if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())<br>
+ return Info->MD;<br>
return State.get<MacroDirective*>();<br>
}<br>
void setLatest(MacroDirective *MD) {<br>
- if (auto *Ext = State.dyn_cast<ExtInfo*>())<br>
- Ext->MD = MD;<br>
+ if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())<br>
+ Info->MD = MD;<br>
else<br>
State = MD;<br>
}<br>
<br>
+ bool isAmbiguous(Preprocessor &PP, IdentifierInfo *II) const {<br>
+ auto *Info = getModuleInfo(PP, II);<br>
+ return Info ? Info->IsAmbiguous : false;<br>
+ }<br>
+ ArrayRef<ModuleMacro *> getActiveModuleMacros(Preprocessor &PP,<br>
+ IdentifierInfo *II) const {<br>
+ if (auto *Info = getModuleInfo(PP, II))<br>
+ return Info->ActiveModuleMacros;<br>
+ return None;<br>
+ }<br>
+<br>
MacroDirective::DefInfo findDirectiveAtLoc(SourceLocation Loc,<br>
SourceManager &SourceMgr) const {<br>
+ // FIXME: Incorporate module macros into the result of this.<br>
return getLatest()->findDirectiveAtLoc(Loc, SourceMgr);<br>
}<br>
<br>
- void addOverriddenMacro(Preprocessor &PP, ModuleMacro *MM) {<br>
- getExtInfo(PP).OverriddenMacros.push_back(MM);<br>
+ void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) {<br>
+ if (auto *Info = getModuleInfo(PP, II)) {<br>
+ for (auto *Active : Info->ActiveModuleMacros)<br>
+ Info->OverriddenMacros.push_back(Active);<br>
+ Info->ActiveModuleMacros.clear();<br>
+ Info->IsAmbiguous = false;<br>
+ }<br>
}<br>
ArrayRef<ModuleMacro*> getOverriddenMacros() const {<br>
- if (auto *Ext = State.dyn_cast<ExtInfo*>())<br>
- return Ext->OverriddenMacros;<br>
+ if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())<br>
+ return Info->OverriddenMacros;<br>
return None;<br>
}<br>
+ void setOverriddenMacros(ArrayRef<ModuleMacro*> Overrides) {<br>
+ auto *Info = State.dyn_cast<ModuleMacroInfo*>();<br>
+ if (!Info) {<br>
+ assert(Overrides.empty() &&<br>
+ "have overrides but never had module macro");<br>
+ return;<br>
+ }<br>
+ Info->OverriddenMacros.clear();<br>
+ Info->OverriddenMacros.insert(Info->OverriddenMacros.end(),<br>
+ Overrides.begin(), Overrides.end());<br>
+ Info->ActiveModuleMacrosGeneration = 0;<br>
+ }<br>
};<br>
<br>
typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap;<br>
@@ -435,8 +482,13 @@ class Preprocessor : public RefCountedBa<br>
Module *M;<br>
/// The location at which the module was included.<br>
SourceLocation ImportLoc;<br>
+<br>
+ struct SavedMacroInfo {<br>
+ MacroDirective *Latest;<br>
+ llvm::TinyPtrVector<ModuleMacro*> Overridden;<br>
+ };<br>
/// The macros that were visible before we entered the module.<br>
- MacroMap Macros;<br>
+ llvm::DenseMap<const IdentifierInfo*, SavedMacroInfo> Macros;<br>
<br>
// FIXME: VisibleModules?<br>
// FIXME: CounterValue?<br>
@@ -447,6 +499,10 @@ class Preprocessor : public RefCountedBa<br>
void EnterSubmodule(Module *M, SourceLocation ImportLoc);<br>
void LeaveSubmodule();<br>
<br>
+ /// Update the set of active module macros and ambiguity flag for a module<br>
+ /// macro name.<br>
+ void updateModuleMacroInfo(IdentifierInfo *II, ModuleMacroInfo &Info);<br>
+<br>
/// The set of known macros exported from modules.<br>
llvm::FoldingSet<ModuleMacro> ModuleMacros;<br>
<br>
@@ -455,6 +511,10 @@ class Preprocessor : public RefCountedBa<br>
llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>><br>
LeafModuleMacros;<br>
<br>
+ /// The generation number for module macros. Incremented each time the set<br>
+ /// of modules with visible macros changes.<br>
+ unsigned MacroVisibilityGeneration;<br>
+<br>
/// \brief Macros that we want to warn because they are not used at the end<br>
/// of the translation unit.<br>
///<br>
<br>
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=235941&r1=235940&r2=235941&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=235941&r1=235940&r2=235941&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)<br>
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Mon Apr 27 18:21:38 2015<br>
@@ -1693,6 +1693,7 @@ void Preprocessor::HandleIncludeDirectiv<br>
ModuleLoadResult Imported<br>
= TheModuleLoader.loadModule(IncludeTok.getLocation(), Path, Visibility,<br>
/*IsIncludeDirective=*/true);<br>
+ ++MacroVisibilityGeneration;<br>
assert((Imported == nullptr || Imported == SuggestedModule.getModule()) &&<br>
"the imported module is different than the suggested one");<br>
<br>
<br>
Modified: cfe/trunk/lib/Lex/PPLexerChange.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=235941&r1=235940&r2=235941&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=235941&r1=235940&r2=235941&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/PPLexerChange.cpp (original)<br>
+++ cfe/trunk/lib/Lex/PPLexerChange.cpp Mon Apr 27 18:21:38 2015<br>
@@ -616,7 +616,13 @@ void Preprocessor::EnterSubmodule(Module<br>
auto &Info = BuildingSubmoduleStack.back();<br>
// Copy across our macros and start the submodule with the current state.<br>
// FIXME: We should start each submodule with just the predefined macros.<br>
- Info.Macros = Macros;<br>
+ for (auto &M : Macros) {<br>
+ BuildingSubmoduleInfo::SavedMacroInfo SMI;<br>
+ SMI.Latest = M.second.getLatest();<br>
+ auto O = M.second.getOverriddenMacros();<br>
+ SMI.Overridden.insert(SMI.Overridden.end(), O.begin(), O.end());<br>
+ Info.Macros.insert(std::make_pair(M.first, SMI));<br>
+ }<br>
}<br>
<br>
void Preprocessor::LeaveSubmodule() {<br>
@@ -625,12 +631,12 @@ void Preprocessor::LeaveSubmodule() {<br>
// Create ModuleMacros for any macros defined in this submodule.<br>
for (auto &Macro : Macros) {<br>
auto *II = const_cast<IdentifierInfo*>(Macro.first);<br>
- MacroState State = Info.Macros.lookup(II);<br>
+ auto SavedInfo = Info.Macros.lookup(II);<br>
<br>
// This module may have exported a new macro. If so, create a ModuleMacro<br>
// representing that fact.<br>
bool ExplicitlyPublic = false;<br>
- for (auto *MD = Macro.second.getLatest(); MD != State.getLatest();<br>
+ for (auto *MD = Macro.second.getLatest(); MD != SavedInfo.Latest;<br>
MD = MD->getPrevious()) {<br>
// Skip macros defined in other submodules we #included along the way.<br>
Module *Mod = getModuleContainingLocation(MD->getLocation());<br>
@@ -659,11 +665,15 @@ void Preprocessor::LeaveSubmodule() {<br>
}<br>
}<br>
<br>
- // Update the macro to refer to the latest directive in the chain.<br>
- State.setLatest(Macro.second.getLatest());<br>
+ // Restore the macro's overrides list.<br>
+ Macro.second.setOverriddenMacros(SavedInfo.Overridden);<br>
+ }<br>
<br>
- // Restore the old macro state.<br>
- Macro.second = State;<br>
+ if (Info.M->NameVisibility < Module::MacrosVisible) {<br>
+ Info.M->NameVisibility = Module::MacrosVisible;<br>
+ Info.M->MacroVisibilityLoc = Info.ImportLoc;<br>
+ ++MacroVisibilityGeneration;<br>
+ // FIXME: Also mark any exported macros as visible, and check for conflicts.<br>
}<br>
<br>
BuildingSubmoduleStack.pop_back();<br>
<br>
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=235941&r1=235940&r2=235941&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=235941&r1=235940&r2=235941&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)<br>
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Mon Apr 27 18:21:38 2015<br>
@@ -50,6 +50,7 @@ void Preprocessor::appendMacroDirective(<br>
auto *OldMD = StoredMD.getLatest();<br>
MD->setPrevious(OldMD);<br>
StoredMD.setLatest(MD);<br>
+ StoredMD.overrideActiveModuleMacros(*this, II);<br>
<br>
// Set up the identifier as having associated macro history.<br>
II->setHasMacroDefinition(true);<br>
@@ -57,43 +58,6 @@ void Preprocessor::appendMacroDirective(<br>
II->setHasMacroDefinition(false);<br>
if (II->isFromAST() && !MD->isImported())<br>
II->setChangedSinceDeserialization();<br>
-<br>
- // Accumulate any overridden imported macros.<br>
- if (!MD->isImported() && getCurrentModule()) {<br>
- Module *OwningMod = getModuleContainingLocation(MD->getLocation());<br>
- if (!OwningMod)<br>
- return;<br>
-<br>
- for (auto *PrevMD = OldMD; PrevMD; PrevMD = PrevMD->getPrevious()) {<br>
- Module *DirectiveMod = getModuleContainingLocation(PrevMD->getLocation());<br>
- if (ModuleMacro *PrevMM = PrevMD->getOwningModuleMacro())<br>
- StoredMD.addOverriddenMacro(*this, PrevMM);<br>
- else if (ModuleMacro *PrevMM = getModuleMacro(DirectiveMod, II))<br>
- // The previous macro was from another submodule that we #included.<br>
- // FIXME: Create an import directive when importing a macro from a local<br>
- // submodule.<br>
- StoredMD.addOverriddenMacro(*this, PrevMM);<br>
- else<br>
- // We're still within the module defining the previous macro. We don't<br>
- // override it.<br>
- break;<br>
-<br>
- // Stop once we leave the original macro's submodule.<br>
- //<br>
- // Either this submodule #included another submodule of the same<br>
- // module or it just happened to be built after the other module.<br>
- // In the former case, we override the submodule's macro.<br>
- //<br>
- // FIXME: In the latter case, we shouldn't do so, but we can't tell<br>
- // these cases apart.<br>
- //<br>
- // FIXME: We can leave this submodule and re-enter it if it #includes a<br>
- // header within a different submodule of the same module. In such cases<br>
- // the overrides list will be incomplete.<br>
- if (DirectiveMod != OwningMod || !PrevMD->isImported())<br>
- break;<br>
- }<br>
- }<br>
}<br>
<br>
void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,<br>
@@ -157,6 +121,71 @@ ModuleMacro *Preprocessor::getModuleMacr<br>
return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);<br>
}<br>
<br>
+void Preprocessor::updateModuleMacroInfo(IdentifierInfo *II,<br>
+ ModuleMacroInfo &Info) {<br>
+ assert(Info.ActiveModuleMacrosGeneration != MacroVisibilityGeneration &&<br>
+ "don't need to update this macro name info");<br>
+ Info.ActiveModuleMacrosGeneration = MacroVisibilityGeneration;<br>
+<br>
+ auto Leaf = LeafModuleMacros.find(II);<br>
+ if (Leaf == LeafModuleMacros.end()) {<br>
+ // No imported macros at all: nothing to do.<br>
+ return;<br>
+ }<br>
+<br>
+ Info.ActiveModuleMacros.clear();<br>
+<br>
+ // Every macro that's locally overridden is overridden by a visible macro.<br>
+ llvm::DenseMap<ModuleMacro *, int> NumHiddenOverrides;<br>
+ for (auto *O : Info.OverriddenMacros)<br>
+ NumHiddenOverrides[O] = -1;<br>
+<br>
+ // Collect all macros that are not overridden by a visible macro.<br>
+ llvm::SmallVector<ModuleMacro *, 16> Worklist(Leaf->second.begin(),<br>
+ Leaf->second.end());<br>
+ while (!Worklist.empty()) {<br>
+ auto *MM = Worklist.pop_back_val();<br>
+ if (MM->getOwningModule()->NameVisibility >= Module::MacrosVisible) {<br>
+ // We only care about collecting definitions; undefinitions only act<br>
+ // to override other definitions.<br>
+ if (MM->getMacroInfo())<br>
+ Info.ActiveModuleMacros.push_back(MM);<br>
+ } else {<br>
+ for (auto *O : MM->overrides())<br>
+ if ((unsigned)++NumHiddenOverrides[O] == O->getNumOverridingMacros())<br>
+ Worklist.push_back(O);<br>
+ }<br>
+ }<br>
+<br>
+ // Determine whether the macro name is ambiguous.<br>
+ Info.IsAmbiguous = false;<br>
+ MacroInfo *MI = nullptr;<br>
+ bool IsSystemMacro = false;<br>
+ if (auto *DMD = dyn_cast<DefMacroDirective>(Info.MD)) {<br>
+ MI = DMD->getInfo();<br>
+ IsSystemMacro = SourceMgr.isInSystemHeader(DMD->getLocation());<br>
+ }<br>
+ for (auto *Active : Info.ActiveModuleMacros) {<br>
+ auto *NewMI = Active->getMacroInfo();<br>
+<br>
+ // Before marking the macro as ambiguous, check if this is a case where<br>
+ // both macros are in system headers. If so, we trust that the system<br>
+ // did not get it wrong. This also handles cases where Clang's own<br>
+ // headers have a different spelling of certain system macros:<br>
+ // #define LONG_MAX __LONG_MAX__ (clang's limits.h)<br>
+ // #define LONG_MAX 0x7fffffffffffffffL (system's limits.h)<br>
+ //<br>
+ // FIXME: Remove the defined-in-system-headers check. clang's limits.h<br>
+ // overrides the system limits.h's macros, so there's no conflict here.<br>
+ IsSystemMacro &= Active->getOwningModule()->IsSystem;<br>
+ if (MI && NewMI != MI && !IsSystemMacro &&<br>
+ !MI->isIdenticalTo(*NewMI, *this, /*Syntactically=*/true)) {<br>
+ Info.IsAmbiguous = true;<br>
+ break;<br>
+ }<br>
+ }<br>
+}<br>
+<br>
/// RegisterBuiltinMacro - Register the specified identifier in the identifier<br>
/// table and mark it as a builtin macro to be expanded.<br>
static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){<br>
<br>
Modified: cfe/trunk/lib/Lex/Preprocessor.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=235941&r1=235940&r2=235941&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=235941&r1=235940&r2=235941&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)<br>
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Mon Apr 27 18:21:38 2015<br>
@@ -73,7 +73,8 @@ Preprocessor::Preprocessor(IntrusiveRefC<br>
ModuleImportExpectsIdentifier(false), CodeCompletionReached(0),<br>
MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr),<br>
CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr),<br>
- Callbacks(nullptr), MacroArgCache(nullptr), Record(nullptr),<br>
+ Callbacks(nullptr), MacroVisibilityGeneration(0),<br>
+ MacroArgCache(nullptr), Record(nullptr),<br>
MIChainHead(nullptr), DeserialMIChainHead(nullptr) {<br>
OwnsHeaderSearch = OwnsHeaders;<br>
<br>
@@ -748,11 +749,13 @@ void Preprocessor::LexAfterModuleImport(<br>
// If we have a non-empty module path, load the named module.<br>
if (!ModuleImportPath.empty()) {<br>
Module *Imported = nullptr;<br>
- if (getLangOpts().Modules)<br>
+ if (getLangOpts().Modules) {<br>
Imported = TheModuleLoader.loadModule(ModuleImportLoc,<br>
ModuleImportPath,<br>
Module::MacrosVisible,<br>
/*IsIncludeDirective=*/false);<br>
+ ++MacroVisibilityGeneration;<br>
+ }<br>
if (Callbacks && (getLangOpts().Modules || getLangOpts().DebuggerSupport))<br>
Callbacks->moduleImport(ModuleImportLoc, ModuleImportPath, Imported);<br>
}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div></div></div><span class="HOEnZb"><font color="#888888">-- <br><div><div dir="ltr">Alexey Samsonov<br><a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a></div></div>
</font></span></div>
</blockquote></div><br></div>