| //===-- SourceLanguage-Unknown.cpp - Implement itf for unknown languages --===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file was developed by the LLVM research group and 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 <iostream> | |
| #include <cassert> | |
| 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) | |
| std::cout << "Whoa, found multiple functions with the same name. I should" | |
| << " ask the user which one to use: FIXME!\n"; | |
| return Found; | |
| } |