summaryrefslogtreecommitdiff
path: root/lib/Debugger/SourceLanguage-Unknown.cpp
blob: b806fc779ef7e9065e4cce711e7aa4e6db8fd94a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//===-- 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;
}