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