//===-- SourceLanguage-Unknown.cpp - Implement itf for unknown languages --===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// If the LLVM debugger does not have a module for a particular language, it
// falls back on using this one to perform the source-language interface.  This
// interface is not wonderful, but it gets the job done.
//
//===----------------------------------------------------------------------===//

#include "llvm/Debugger/SourceLanguage.h"
#include "llvm/Debugger/ProgramInfo.h"
#include "llvm/Support/Streams.h"
#include <cassert>
#include <ostream>
using namespace llvm;

//===----------------------------------------------------------------------===//
// Implement the SourceLanguage cache for the Unknown language.
//

namespace {
  /// SLUCache - This cache allows for efficient lookup of source functions by
  /// name.
  ///
  struct SLUCache : public SourceLanguageCache {
    ProgramInfo &PI;
    std::multimap<std::string, SourceFunctionInfo*> FunctionMap;
  public:
    SLUCache(ProgramInfo &pi);

    typedef std::multimap<std::string, SourceFunctionInfo*>::const_iterator
       fm_iterator;

    std::pair<fm_iterator, fm_iterator>
    getFunction(const std::string &Name) const {
      return FunctionMap.equal_range(Name);
    }

    SourceFunctionInfo *addSourceFunction(SourceFunctionInfo *SF) {
      FunctionMap.insert(std::make_pair(SF->getSymbolicName(), SF));
      return SF;
    }
  };
}

SLUCache::SLUCache(ProgramInfo &pi) : PI(pi) {
}


//===----------------------------------------------------------------------===//
// Implement SourceLanguageUnknown class, which is used to handle unrecognized
// languages.
//

namespace {
  struct SLU : public SourceLanguage {
    //===------------------------------------------------------------------===//
    // Implement the miscellaneous methods...
    //
    virtual const char *getSourceLanguageName() const {
      return "unknown";
    }

    /// lookupFunction - Given a textual function name, return the
    /// SourceFunctionInfo descriptor for that function, or null if it cannot be
    /// found.  If the program is currently running, the RuntimeInfo object
    /// provides information about the current evaluation context, otherwise it
    /// will be null.
    ///
    virtual SourceFunctionInfo *lookupFunction(const std::string &FunctionName,
                                               ProgramInfo &PI,
                                               RuntimeInfo *RI = 0) const;

    //===------------------------------------------------------------------===//
    // We do use a cache for information...
    //
    typedef SLUCache CacheType;
    SLUCache *createSourceLanguageCache(ProgramInfo &PI) const {
      return new SLUCache(PI);
    }

    /// createSourceFunctionInfo - Create the new object and inform the cache of
    /// the new function.
    virtual SourceFunctionInfo *
    createSourceFunctionInfo(const GlobalVariable *Desc, ProgramInfo &PI) const;

  } TheUnknownSourceLanguageInstance;
}

const SourceLanguage &SourceLanguage::getUnknownLanguageInstance() {
  return TheUnknownSourceLanguageInstance;
}


SourceFunctionInfo *
SLU::createSourceFunctionInfo(const GlobalVariable *Desc,
                              ProgramInfo &PI) const {
  SourceFunctionInfo *Result = new SourceFunctionInfo(PI, Desc);
  return PI.getLanguageCache(this).addSourceFunction(Result);
}


/// lookupFunction - Given a textual function name, return the
/// SourceFunctionInfo descriptor for that function, or null if it cannot be
/// found.  If the program is currently running, the RuntimeInfo object
/// provides information about the current evaluation context, otherwise it will
/// be null.
///
SourceFunctionInfo *SLU::lookupFunction(const std::string &FunctionName,
                                        ProgramInfo &PI, RuntimeInfo *RI) const{
  SLUCache &Cache = PI.getLanguageCache(this);
  std::pair<SLUCache::fm_iterator, SLUCache::fm_iterator> IP
    = Cache.getFunction(FunctionName);

  if (IP.first == IP.second) {
    if (PI.allSourceFunctionsRead())
      return 0;  // Nothing found

    // Otherwise, we might be able to find the function if we read all of them
    // in.  Do so now.
    PI.getSourceFunctions();
    assert(PI.allSourceFunctionsRead() && "Didn't read in all functions?");
    return lookupFunction(FunctionName, PI, RI);
  }

  SourceFunctionInfo *Found = IP.first->second;
  ++IP.first;
  if (IP.first != IP.second)
    cout << "Whoa, found multiple functions with the same name.  I should"
         << " ask the user which one to use: FIXME!\n";
  return Found;
}
