Пример #1
0
bool ModuleLinker::run() {
  assert(DstM && "Null destination module");
  assert(SrcM && "Null source module");

  // Inherit the target data from the source module if the destination module
  // doesn't have one already.
  if (DstM->getDataLayout().empty() && !SrcM->getDataLayout().empty())
    DstM->setDataLayout(SrcM->getDataLayout());

  // Copy the target triple from the source to dest if the dest's is empty.
  if (DstM->getTargetTriple().empty() && !SrcM->getTargetTriple().empty())
    DstM->setTargetTriple(SrcM->getTargetTriple());

  if (!SrcM->getDataLayout().empty() && !DstM->getDataLayout().empty() &&
      SrcM->getDataLayout() != DstM->getDataLayout())
    errs() << "WARNING: Linking two modules of different data layouts!\n";
  if (!SrcM->getTargetTriple().empty() &&
      DstM->getTargetTriple() != SrcM->getTargetTriple()) {
    errs() << "WARNING: Linking two modules of different target triples: ";
    if (!SrcM->getModuleIdentifier().empty())
      errs() << SrcM->getModuleIdentifier() << ": ";
    errs() << "'" << SrcM->getTargetTriple() << "' and '" 
           << DstM->getTargetTriple() << "'\n";
  }

  // Append the module inline asm string.
  if (!SrcM->getModuleInlineAsm().empty()) {
    if (DstM->getModuleInlineAsm().empty())
      DstM->setModuleInlineAsm(SrcM->getModuleInlineAsm());
    else
      DstM->setModuleInlineAsm(DstM->getModuleInlineAsm()+"\n"+
                               SrcM->getModuleInlineAsm());
  }

  // Update the destination module's dependent libraries list with the libraries
  // from the source module. There's no opportunity for duplicates here as the
  // Module ensures that duplicate insertions are discarded.
  for (Module::lib_iterator SI = SrcM->lib_begin(), SE = SrcM->lib_end();
       SI != SE; ++SI)
    DstM->addLibrary(*SI);
  
  // If the source library's module id is in the dependent library list of the
  // destination library, remove it since that module is now linked in.
  StringRef ModuleId = SrcM->getModuleIdentifier();
  if (!ModuleId.empty())
    DstM->removeLibrary(sys::path::stem(ModuleId));
  
  // Loop over all of the linked values to compute type mappings.
  computeTypeMapping();

  // Insert all of the globals in src into the DstM module... without linking
  // initializers (which could refer to functions not yet mapped over).
  for (Module::global_iterator I = SrcM->global_begin(),
       E = SrcM->global_end(); I != E; ++I)
    if (linkGlobalProto(I))
      return true;

  // Link the functions together between the two modules, without doing function
  // bodies... this just adds external function prototypes to the DstM
  // function...  We do this so that when we begin processing function bodies,
  // all of the global values that may be referenced are available in our
  // ValueMap.
  for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I)
    if (linkFunctionProto(I))
      return true;

  // If there were any aliases, link them now.
  for (Module::alias_iterator I = SrcM->alias_begin(),
       E = SrcM->alias_end(); I != E; ++I)
    if (linkAliasProto(I))
      return true;

  for (unsigned i = 0, e = AppendingVars.size(); i != e; ++i)
    linkAppendingVarInit(AppendingVars[i]);
  
  // Update the initializers in the DstM module now that all globals that may
  // be referenced are in DstM.
  linkGlobalInits();

  // Link in the function bodies that are defined in the source module into
  // DstM.
  for (Module::iterator SF = SrcM->begin(), E = SrcM->end(); SF != E; ++SF) {
    // Skip if not linking from source.
    if (DoNotLinkFromSource.count(SF)) continue;
    
    // Skip if no body (function is external) or materialize.
    if (SF->isDeclaration()) {
      if (!SF->isMaterializable())
        continue;
      if (SF->Materialize(&ErrorMsg))
        return true;
    }
    
    linkFunctionBody(cast<Function>(ValueMap[SF]), SF);
  }

  // Resolve all uses of aliases with aliasees.
  linkAliasBodies();

  // Remap all of the named MDNodes in Src into the DstM module. We do this
  // after linking GlobalValues so that MDNodes that reference GlobalValues
  // are properly remapped.
  linkNamedMDNodes();

  // Merge the module flags into the DstM module.
  if (linkModuleFlagsMetadata())
    return true;

  // Process vector of lazily linked in functions.
  bool LinkedInAnyFunctions;
  do {
    LinkedInAnyFunctions = false;
    
    for(std::vector<Function*>::iterator I = LazilyLinkFunctions.begin(),
        E = LazilyLinkFunctions.end(); I != E; ++I) {
      if (!*I)
        continue;
      
      Function *SF = *I;
      Function *DF = cast<Function>(ValueMap[SF]);
      
      if (!DF->use_empty()) {
        
        // Materialize if necessary.
        if (SF->isDeclaration()) {
          if (!SF->isMaterializable())
            continue;
          if (SF->Materialize(&ErrorMsg))
            return true;
        }
        
        // Link in function body.
        linkFunctionBody(DF, SF);
        
        // "Remove" from vector by setting the element to 0.
        *I = 0;
        
        // Set flag to indicate we may have more functions to lazily link in
        // since we linked in a function.
        LinkedInAnyFunctions = true;
      }
    }
  } while (LinkedInAnyFunctions);
  
  // Remove any prototypes of functions that were not actually linked in.
  for(std::vector<Function*>::iterator I = LazilyLinkFunctions.begin(),
      E = LazilyLinkFunctions.end(); I != E; ++I) {
    if (!*I)
      continue;
    
    Function *SF = *I;
    Function *DF = cast<Function>(ValueMap[SF]);
    if (DF->use_empty())
      DF->eraseFromParent();
  }
  
  // Now that all of the types from the source are used, resolve any structs
  // copied over to the dest that didn't exist there.
  TypeMap.linkDefinedTypeBodies();
  
  return false;
}