1 //===-- SourceLanguage-Unknown.cpp - Implement itf for unknown languages --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // If the LLVM debugger does not have a module for a particular language, it
11 // falls back on using this one to perform the source-language interface. This
12 // interface is not wonderful, but it gets the job done.
14 //===----------------------------------------------------------------------===//
16 #include "llvm/Debugger/SourceLanguage.h"
17 #include "llvm/Debugger/ProgramInfo.h"
18 #include "llvm/Support/raw_ostream.h"
22 //===----------------------------------------------------------------------===//
23 // Implement the SourceLanguage cache for the Unknown language.
27 /// SLUCache - This cache allows for efficient lookup of source functions by
30 struct SLUCache
: public SourceLanguageCache
{
32 std::multimap
<std::string
, SourceFunctionInfo
*> FunctionMap
;
34 SLUCache(ProgramInfo
&pi
);
36 typedef std::multimap
<std::string
, SourceFunctionInfo
*>::const_iterator
39 std::pair
<fm_iterator
, fm_iterator
>
40 getFunction(const std::string
&Name
) const {
41 return FunctionMap
.equal_range(Name
);
44 SourceFunctionInfo
*addSourceFunction(SourceFunctionInfo
*SF
) {
45 FunctionMap
.insert(std::make_pair(SF
->getSymbolicName(), SF
));
51 SLUCache::SLUCache(ProgramInfo
&pi
) : PI(pi
) {
55 //===----------------------------------------------------------------------===//
56 // Implement SourceLanguageUnknown class, which is used to handle unrecognized
61 static struct SLU
: public SourceLanguage
{
62 //===------------------------------------------------------------------===//
63 // Implement the miscellaneous methods...
65 virtual const char *getSourceLanguageName() const {
69 /// lookupFunction - Given a textual function name, return the
70 /// SourceFunctionInfo descriptor for that function, or null if it cannot be
71 /// found. If the program is currently running, the RuntimeInfo object
72 /// provides information about the current evaluation context, otherwise it
75 virtual SourceFunctionInfo
*lookupFunction(const std::string
&FunctionName
,
77 RuntimeInfo
*RI
= 0) const;
79 //===------------------------------------------------------------------===//
80 // We do use a cache for information...
82 typedef SLUCache CacheType
;
83 SLUCache
*createSourceLanguageCache(ProgramInfo
&PI
) const {
84 return new SLUCache(PI
);
87 /// createSourceFunctionInfo - Create the new object and inform the cache of
89 virtual SourceFunctionInfo
*
90 createSourceFunctionInfo(const GlobalVariable
*Desc
, ProgramInfo
&PI
) const;
92 } TheUnknownSourceLanguageInstance
;
95 const SourceLanguage
&SourceLanguage::getUnknownLanguageInstance() {
96 return TheUnknownSourceLanguageInstance
;
101 SLU::createSourceFunctionInfo(const GlobalVariable
*Desc
,
102 ProgramInfo
&PI
) const {
103 SourceFunctionInfo
*Result
= new SourceFunctionInfo(PI
, Desc
);
104 return PI
.getLanguageCache(this).addSourceFunction(Result
);
108 /// lookupFunction - Given a textual function name, return the
109 /// SourceFunctionInfo descriptor for that function, or null if it cannot be
110 /// found. If the program is currently running, the RuntimeInfo object
111 /// provides information about the current evaluation context, otherwise it will
114 SourceFunctionInfo
*SLU::lookupFunction(const std::string
&FunctionName
,
115 ProgramInfo
&PI
, RuntimeInfo
*RI
) const{
116 SLUCache
&Cache
= PI
.getLanguageCache(this);
117 std::pair
<SLUCache::fm_iterator
, SLUCache::fm_iterator
> IP
118 = Cache
.getFunction(FunctionName
);
120 if (IP
.first
== IP
.second
) {
121 if (PI
.allSourceFunctionsRead())
122 return 0; // Nothing found
124 // Otherwise, we might be able to find the function if we read all of them
126 PI
.getSourceFunctions();
127 assert(PI
.allSourceFunctionsRead() && "Didn't read in all functions?");
128 return lookupFunction(FunctionName
, PI
, RI
);
131 SourceFunctionInfo
*Found
= IP
.first
->second
;
133 if (IP
.first
!= IP
.second
)
134 outs() << "Whoa, found multiple functions with the same name. I should"
135 << " ask the user which one to use: FIXME!\n";