blob: b806fc779ef7e9065e4cce711e7aa4e6db8fd94a [file] [log] [blame]
//===-- 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 {
static 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;
}