|  | //===-- 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; | 
|  | } |